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