2 * Copyright (C) 2004-2008 Kim Woelders
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies of the Software, its documentation and marketing & publicity
13 * materials, and acknowledgment shall be given in the documentation, materials
14 * and software packages that this Software was used.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 * Braindead flat ASCII config file implementation
43 static void CfgItemSetFromString(const CfgItem * ci, const char *str,
47 e16_db_open(const char *name)
52 fs = fopen(name, "w");
56 ecf = ECALLOC(ECfgFile, 1);
69 e16_db_open_read(const char *name)
73 char buf[4096], key[128], *s;
76 fs = fopen(name, "r");
80 ecf = ECALLOC(ECfgFile, 1);
86 s = fgets(buf, sizeof(buf), fs);
90 /* Strip comment and trailing whitespace */
91 i = strcspn(s, "#\r\n");
93 if (!isspace(s[i - 1]))
98 i = sscanf(s, "%100s = %n", key, &len);
99 if (i <= 0 || len <= 0)
100 continue; /* Ignore bad format */
103 ecf->pitms = EREALLOC(ECfgFileItem, ecf->pitms, ecf->nitms);
104 ecf->pitms[i].key = Estrdup(key);
105 ecf->pitms[i].value = Estrdup(s + len);
114 e16_db_close(ECfgFile * ecf)
120 for (i = 0; i < ecf->nitms; i++)
122 Efree(ecf->pitms[i].key);
123 Efree(ecf->pitms[i].value);
138 ECfgFileFindValue(ECfgFile * ecf, const char *key)
142 for (i = 0; i < ecf->nitms; i++)
143 if (!strcmp(key, ecf->pitms[i].key))
144 return ecf->pitms[i].value;
150 * Configuration handling.
154 CfgItemLoad(ECfgFile * ecf, const char *prefix, const CfgItem * ci)
157 const char *name = buf;
161 Esnprintf(buf, sizeof(buf), "%s.%s", prefix, ci->name);
165 if (EDebug(EDBUG_TYPE_CONFIG) > 1)
166 Eprintf("CfgItemLoad %s\n", name);
171 value = (ecf) ? ECfgFileFindValue(ecf, name) : NULL;
172 CfgItemSetFromString(ci, value, 1);
176 CfgItemSave(ECfgFile * ecf, const char *prefix, const CfgItem * ci)
178 char buf[1024], buf2[1024];
179 const char *name = buf;
182 Esnprintf(buf, sizeof(buf), "%s.%s", prefix, ci->name);
186 if (EDebug(EDBUG_TYPE_CONFIG) > 1)
187 Eprintf("CfgItemSave %s\n", name);
192 CfgItemToString(ci, buf2, sizeof(buf2));
193 fprintf(ecf->fs, "%s = %s\n", name, buf2);
197 ConfigurationGetFile(char *buf, int len)
199 Esnprintf(buf, len, "%s.cfg", EGetSavePrefix());
204 ConfigurationLoad(void)
207 const EModule **pml, *pm;
212 if (EDebug(EDBUG_TYPE_CONFIG))
213 Eprintf("ConfigurationLoad\n");
215 memset(&Conf, 0, sizeof(EConf));
217 ecf = e16_db_open_read(ConfigurationGetFile(buf, sizeof(buf)));
218 /* NB! We have to assign the defaults even if it doesn't exist */
220 /* Load module configs */
221 pml = ModuleListGet(&nml);
222 for (i = 0; i < nml; i++)
227 for (j = 0; j < ncl; j++)
228 CfgItemLoad(ecf, pm->name, pcl + j);
237 ConfigurationSave(void)
240 const EModule **pml, *pm;
245 if (EDebug(EDBUG_TYPE_CONFIG))
246 Eprintf("ConfigurationSave\n");
248 ecf = e16_db_open(ConfigurationGetFile(buf, sizeof(buf)));
252 /* Load module configs */
253 pml = ModuleListGet(&nml);
254 for (i = 0; i < nml; i++)
259 for (j = 0; j < ncl; j++)
260 CfgItemSave(ecf, pm->name, pcl + j);
269 CfgItemFind(const CfgItem * pcl, int ncl, const char *name)
273 for (i = 0; i < ncl; i++, pcl++)
274 if (!strcmp(name, pcl->name))
280 CfgItemSetFromString(const CfgItem * ci, const char *str, int set_dflt)
284 #ifdef ITEM_TYPE_FLOAT
294 ival = (str) ? strtoul(str, &ptr, 0) : 0;
299 ival = (ci->dflt) ? 1 : 0;
301 *((char *)ci->ptr) = ival;
305 ival = (str) ? strtoul(str, &ptr, 0) : 0;
312 *((int *)ci->ptr) = ival;
314 #ifdef ITEM_TYPE_FLOAT
315 case ITEM_TYPE_FLOAT:
316 n = (str) ? sscanf(str, "%f", &fval) : 0;
323 *((float *)ci->ptr) = fval;
326 case ITEM_TYPE_STRING:
327 Efree(*(char **)ci->ptr);
328 if (str && *str == '\0')
330 *((char **)ci->ptr) = Estrdup(str);
336 CfgItemToString(const CfgItem * ci, char *buf, int len)
342 Esnprintf(buf, len, "%d", *((char *)ci->ptr));
345 Esnprintf(buf, len, "%d", *((int *)ci->ptr));
348 Esnprintf(buf, len, "%#x", *((unsigned int *)ci->ptr));
350 #ifdef ITEM_TYPE_FLOAT
351 case ITEM_TYPE_FLOAT:
352 Esnprintf(buf, len, "%.3f", *((float *)ci->ptr));
355 case ITEM_TYPE_STRING:
356 if (*((char **)ci->ptr))
357 Esnprintf(buf, len, "%s", *((char **)ci->ptr));
363 CfgItemListNamedItemSet(const CfgItem * pcl, int ncl, const char *item,
368 ci = CfgItemFind(pcl, ncl, item);
373 ci->func(ci->ptr, value);
375 CfgItemSetFromString(ci, value, 0);
382 CfgItemListNamedItemToString(const CfgItem * pcl, int ncl, const char *item,
387 ci = CfgItemFind(pcl, ncl, item);
390 CfgItemToString(ci, buf, len);
397 * Set <module>.<item> <value>
400 ConfigurationSet(const char *params)
410 p = strchr(params, '.');
413 Eprintf("ConfigurationSet - missed: %s\n", params);
418 if (len >= sizeof(name))
419 len = sizeof(name) - 1;
420 memcpy(name, params, len);
424 sscanf(p, "%1000s %n", item, &len);
426 ModuleConfigSet(name, item, p);
428 /* Save changed configuration */
433 * Show <module>.<item> <value>
436 ConfigurationShow(const char *params)
443 /* No parameters - All */
444 if (!params || params[0] == '\0')
450 /* No '.' - All for module */
451 p = strchr(params, '.');
454 ModuleConfigShow(params, NULL);
458 /* Specific module, specific item. */
460 if (len >= sizeof(name))
461 len = sizeof(name) - 1;
462 memcpy(name, params, len);
465 sscanf(p, "%s", item);
466 ModuleConfigShow(name, item);