1 /*
2 * config file parser
3 *
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include "parseconfig.h"
10
11 struct CFG_ENTRIES {
12 int ent_count;
13 char **ent_names;
14 char **ent_values;
15 int **ent_seen;
16 };
17
18 struct CFG_SECTIONS {
19 int sec_count;
20 char **sec_names;
21 struct CFG_ENTRIES **sec_entries;
22 };
23
24 /* ------------------------------------------------------------------------ */
25
26 static struct CFG_SECTIONS *c;
27
28 /* ------------------------------------------------------------------------ */
29
30 #define ALLOC_SIZE 16
31
32 static struct CFG_SECTIONS*
33 cfg_init_sections(void)
34 {
35 struct CFG_SECTIONS *c;
36 c = malloc(sizeof(struct CFG_SECTIONS));
37 memset(c,0,sizeof(struct CFG_SECTIONS));
38 c->sec_names = malloc(ALLOC_SIZE*sizeof(char*));
39 c->sec_names[0] = NULL;
40 c->sec_entries = malloc(ALLOC_SIZE*sizeof(struct CFG_ENTRIES*));
41 c->sec_entries[0] = NULL;
42 return c;
43 }
44
45 static struct CFG_ENTRIES*
46 cfg_init_entries(void)
47 {
48 struct CFG_ENTRIES *e;
49 e = malloc(sizeof(struct CFG_ENTRIES));
50 memset(e,0,sizeof(struct CFG_ENTRIES));
51 e->ent_names = malloc(ALLOC_SIZE*sizeof(char*));
52 e->ent_names[0] = NULL;
53 e->ent_values = malloc(ALLOC_SIZE*sizeof(char*));
54 e->ent_values[0] = NULL;
55 e->ent_seen = malloc(ALLOC_SIZE*sizeof(int*));
56 e->ent_seen[0] = 0;
57 return e;
58 }
59
60 static struct CFG_ENTRIES*
61 cfg_find_section(struct CFG_SECTIONS *c, char *name)
62 {
63 struct CFG_ENTRIES* e;
64 int i;
65
66 for (i = 0; i < c->sec_count; i++)
67 if (0 == strcasecmp(c->sec_names[i],name))
68 return c->sec_entries[i];
69
70 /* 404 not found => create a new one */
71 if ((c->sec_count % ALLOC_SIZE) == (ALLOC_SIZE-2)) {
72 c->sec_names = realloc(c->sec_names,(c->sec_count+2+ALLOC_SIZE)*sizeof(char*));
73 c->sec_entries = realloc(c->sec_entries,(c->sec_count+2+ALLOC_SIZE)*sizeof(struct CFG_ENTRIES*));
74 }
75 e = cfg_init_entries();
76 c->sec_names[c->sec_count] = strdup(name);
77 c->sec_entries[c->sec_count] = e;
78 c->sec_count++;
79 c->sec_names[c->sec_count] = NULL;
80 c->sec_entries[c->sec_count] = NULL;
81 return e;
82 }
83
84 static void
85 cfg_set_entry(struct CFG_ENTRIES *e, char *name, char *value)
86 {
87 int i;
88
89 for (i = 0; i < e->ent_count; i++)
90 if (0 == strcasecmp(e->ent_names[i],name))
91 break;
92 if (i == e->ent_count) {
93 /* 404 not found => create a new one */
94 if ((e->ent_count % ALLOC_SIZE) == (ALLOC_SIZE-2)) {
95 e->ent_names = realloc(e->ent_names,(e->ent_count+2+ALLOC_SIZE)*sizeof(char*));
96 e->ent_values = realloc(e->ent_values,(e->ent_count+2+ALLOC_SIZE)*sizeof(char*));
97 e->ent_seen = realloc(e->ent_seen,(e->ent_count+2+ALLOC_SIZE)*sizeof(int*));
98 }
99 e->ent_count++;
100 e->ent_names[e->ent_count] = NULL;
101 e->ent_values[e->ent_count] = NULL;
102 e->ent_seen[e->ent_count] = 0;
103 }
104 e->ent_names[i] = strdup(name);
105 e->ent_values[i] = strdup(value);
106 }
107
108 /* ------------------------------------------------------------------------ */
109
110 int
111 cfg_parse_file(char *filename)
112 {
113 struct CFG_ENTRIES *e = NULL;
114 char line[256],tag[64],value[192];
115 FILE *fp;
116 int nr;
117
118 if (NULL == c)
119 c = cfg_init_sections();
120 if (NULL == (fp = fopen(filename,"r")))
121 return -1;
122
123 nr = 0;
124 while (NULL != fgets(line,255,fp)) {
125 nr++;
126 if (line[0] == '\n' || line[0] == '#' || line[0] == '%')
127 continue;
128 if (1 == sscanf(line,"[%99[^]]]",value)) {
129 /* [section] */
130 e = cfg_find_section(c,value);
131 } else if (2 == sscanf(line," %63[^= ] = %191[^\n]",tag,value)) {
132 /* foo = bar */
133 if (NULL == e) {
134 fprintf(stderr,"%s:%d: error: no section\n",filename,nr);
135 } else {
136 char *c = value + strlen(value)-1;
137 while (c > value && (*c == ' ' || *c == '\t'))
138 *(c--) = 0;
139 cfg_set_entry(e,tag,value);
140 }
141 } else {
142 /* Huh ? */
143 fprintf(stderr,"%s:%d: syntax error\n",filename,nr);
144 }
145 }
146 fclose(fp);
147 return 0;
148 }
149
150 /* ------------------------------------------------------------------------ */
151
152 void
153 cfg_parse_option(char *section, char *tag, char *value)
154 {
155 struct CFG_ENTRIES *e = NULL;
156
157 if (NULL == c)
158 c = cfg_init_sections();
159 e = cfg_find_section(c,section);
160 cfg_set_entry(e,tag,value);
161 }
162
163 void
164 cfg_parse_options(int *argc, char **argv)
165 {
166 char section[64], tag[64];
167 int i,j;
168
169 for (i = 1; i+1 < *argc;) {
170 if (2 == sscanf(argv[i],"-%63[^:]:%63s",section,tag)) {
171 cfg_parse_option(section,tag,argv[i+1]);
172 for (j = i; j < *argc-1; j++)
173 argv[j] = argv[j+2];
174 (*argc) -= 2;
175 } else {
176 i++;
177 }
178 }
179 }
180
181 /* ------------------------------------------------------------------------ */
182
183 char**
184 cfg_list_sections()
185 {
186 return c->sec_names;
187 }
188
189 char**
190 cfg_list_entries(char *name)
191 {
192 int i;
193
194 if (NULL == c)
195 return NULL;
196 for (i = 0; i < c->sec_count; i++)
197 if (0 == strcasecmp(c->sec_names[i],name))
198 return c->sec_entries[i]->ent_names;
199 return NULL;
200 }
201
202 char*
203 cfg_get_str(char *sec, char *ent)
204 {
205 struct CFG_ENTRIES* e = NULL;
206 char *v = NULL;
207 int i;
208
209 for (i = 0; i < c->sec_count; i++)
210 if (0 == strcasecmp(c->sec_names[i],sec))
211 e = c->sec_entries[i];
212 if (NULL == e)
213 return NULL;
214 for (i = 0; i < e->ent_count; i++)
215 if (0 == strcasecmp(e->ent_names[i],ent)) {
216 v = e->ent_values[i];
217 e->ent_seen[i]++;
218 }
219 return v;
220 }
221
222 int
223 cfg_get_int(char *sec, char *ent)
224 {
225 char *val;
226
227 val = cfg_get_str(sec,ent);
228 if (NULL == val)
229 return -1;
230 return atoi(val);
231 }
232
233 int
234 cfg_get_signed_int(char *sec, char *ent)
235 {
236 char *val;
237
238 val = cfg_get_str(sec,ent);
239 if (NULL == val)
240 return 0;
241 return atoi(val);
242 }
243
244 float
245 cfg_get_float(char *sec, char *ent)
246 {
247 char *val;
248
249 val = cfg_get_str(sec,ent);
250 if (NULL == val)
251 return -1;
252 return atof(val);
253 }
254
|
This page was automatically generated by the
LXR engine.
|