const char *cfg_find_val(struct config *db, const char *sec, const char *name) { const struct section *s = db ? cfg_find_section(db, sec) : (const struct section *)sec; const struct entry *k = cfg_find_entry(s, name); return k ? k->value : NULL; }
void cfg_insert_entry(Config cfg, char* key, char* value) { ConfigEntry entry, prev, next; entry = cfg_find_entry(cfg, key, &prev, &next); if(entry != NULL) { cfg_destroy_entry(entry); if(entry == cfg->first) cfg->first = next; if(entry == cfg->recent) cfg->recent = prev; } entry = cfg_new_entry(key, value, prev, next); if(prev == NULL) cfg->first = entry; if(cfg->recent == NULL) cfg->recent = entry; }
/* parse the content of a config file. We expect the buffer to be * persistent and writable. */ static int cfg_parse(struct config *db, char *p, const char *basedir) { struct section *cur; struct entry *kcur; DBG(3, "start, db %p content\n%.50s\n...\n", db, p); cur = NULL; kcur = NULL; while (p && *p) { char c; char *start; char *key, *val; start = strsep(&p, "\n"); /* to end of line */ start = skipws(start); /* skip whitespace */ trimws(start, p - 1); switch (*start) { case '\0': /* comment line */ case ';': /* comment line */ case '#': /* comment line */ break ; case '[': /* section delimiter */ key = ++start; /* skip it */ while (isalnum(*key) || index("-_", *key)) key++; c = *key; *key = '\0'; if (c) key++; if (c != ']') { DBG(0, "invalid section name %s %c\n", start, c); break; } DBG(1, "start section %s\n", start); cur = cfg_find_section(db, start); if (!cur) { /* allocate new */ cur = calloc(1, sizeof(struct section)); if (cur == NULL) { DBG(0, "cannot allocate section %s\n", start); return -1; } cur->next = db->sections; db->sections = cur; cur->name = start; } break; default: /* it a a key/value string then */ DBG(3, "key name pair\n"); key = parse_name(&start, "=\r\n"); val = key ? parse_name(&start, "\r\n") : NULL; DBG(2, "after parse name next p %p %d\n", p, *p); if (!val) { if (key) { DBG(0, "cannot parse name %s\n", start); return -1; } break; } DBG(1, "key [%s] val [%s]\n", key, val); if (!strcmp(key, "include")) { DBG(1, "processing include %s\n", val); cfg_read(val, basedir, db); break; } if (!cur) { DBG(0, "key val outside section, ignore\n"); break; } kcur = (struct entry *)cfg_find_entry(cur, start); if (kcur) { DBG(0, "replace val %s\n", kcur->value); // XXX should we add ? } else { kcur = calloc(1, sizeof(struct entry)); if (kcur == NULL) { DBG(0, "cannot allocate key %s\n", start); return -1; } kcur->next = cur->keys; cur->keys = kcur; kcur->key = key; } kcur->value = val; break ; } } DBG(1, "END db %p\n", db); return 0; }
const char* cfg_get(Config cfg, const char* key) { ConfigEntry e = cfg_find_entry(cfg, key, NULL, NULL); return (e == NULL) ? "" : e->value; }
int cfg_has_key(Config cfg, const char* key) { return cfg_find_entry(cfg, key, NULL, NULL) != NULL; }