dynwatch

view config_parser.c @ 0:ce3c5e4c75bf

dynwatch DynDNS updater for windows
author John Tsiombikas <nuclear@siggraph.org>
date Wed, 18 May 2011 05:53:29 +0300
parents
children
line source
1 /*
2 This file is part of dynwatch, a win32 system tray applet which
3 updates automatically the dyndns entry of quake.gr.
5 Copyright (c) 2005 John Tsiombikas <nuclear@siggraph.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <ctype.h>
25 #include "config_parser.h"
27 /* state variables */
28 static char sym_assign = '=';
29 static char sym_comment = ';';
30 static char max_line_len = 100;
31 static char seperators[257] = " \t";
32 static struct ConfigOption cfg_opt;
34 static char *config_file, *cfgptr;
36 void SetParserState(enum ParserState state, int value) {
37 switch(state) {
38 case PS_AssignmentSymbol:
39 sym_assign = (char)value;
40 break;
42 case PS_CommentSymbol:
43 sym_comment = (char)value;
44 break;
46 case PS_MaxLineLen:
47 max_line_len = value;
48 break;
50 case PS_Seperators:
51 strncpy(seperators, (char*)value, 257);
52 break;
53 }
54 }
56 int LoadConfigFile(const char *fname) {
57 FILE *fp;
58 int fsize;
59 char *temp;
61 if(!fname) return -1;
62 if(!(fp = fopen(fname, "r"))) return -1;
64 fseek(fp, 0, SEEK_END);
65 fsize = ftell(fp);
66 fseek(fp, 0, SEEK_SET);
68 if(!(temp = realloc(config_file, fsize))) return -1;
69 config_file = temp;
71 cfgptr = config_file;
72 temp = malloc(max_line_len + 1);
73 while(fgets(temp, max_line_len, fp)) {
74 char *ptr = temp;
76 if(*ptr == '\n') continue; /* kill empty lines, they irritate the parser */
78 while(ptr && *ptr && *ptr != sym_comment) {
79 if(!strchr(seperators, *ptr)) { /* not a seperator */
80 *cfgptr++ = *ptr;
81 }
82 ptr++;
83 }
85 if(*ptr == sym_comment && ptr != temp) {
86 *cfgptr++ = '\n';
87 }
88 }
90 *cfgptr = 0;
92 memset(&cfg_opt, 0, sizeof(struct ConfigOption));
93 cfgptr = config_file;
94 free(temp);
95 return 0;
96 }
98 const struct ConfigOption *GetNextOption() {
99 char *tmpbuf = malloc(max_line_len + 1);
100 char *ptr = tmpbuf;
102 if(!(*cfgptr)) {
103 free(tmpbuf);
104 return 0;
105 }
107 while(*cfgptr != '\n') {
108 *ptr++ = *cfgptr++;
109 }
110 *ptr = 0;
111 cfgptr++;
113 if(!(ptr = strchr(tmpbuf, sym_assign))) {
114 free(tmpbuf);
115 return 0;
116 }
117 *ptr++ = 0;
119 cfg_opt.flags = 0;
121 cfg_opt.option = realloc(cfg_opt.option, strlen(tmpbuf) + 1);
122 strcpy(cfg_opt.option, tmpbuf);
124 cfg_opt.str_value = realloc(cfg_opt.str_value, strlen(ptr) + 1);
125 strcpy(cfg_opt.str_value, ptr);
127 if(isdigit(cfg_opt.str_value[0])) {
128 cfg_opt.flags |= CFGOPT_INT;
129 cfg_opt.int_value = atoi(cfg_opt.str_value);
130 cfg_opt.flt_value = atof(cfg_opt.str_value);
131 }
133 free(tmpbuf);
134 return &cfg_opt;
135 }
137 void DestroyConfigParser() {
138 if(cfg_opt.str_value) free(cfg_opt.str_value);
139 if(cfg_opt.option) free(cfg_opt.option);
140 if(config_file) free(config_file);
141 }