free(this);
}
+/**
+ * callback to find a section by name
+ */
+static bool section_find(section_t *this, char *name)
+{
+ return streq(this->name, name);
+}
+
+/**
+ * callback to find a kv pair by key
+ */
+static bool kv_find(kv_t *this, char *key)
+{
+ return streq(this->key, key);
+}
+
/**
* parse text, truncate "skip" chars, delimited by term respecting brackets.
*
case '{':
if (parse(text, "\t ", "}", "{", &inner))
{
- section_t *sub = section_create(key);
- if (parse_section(&inner, sub))
+ section_t *sub;
+ if (section->sections->find_first(section->sections,
+ (linked_list_match_t)section_find,
+ (void**)&sub, key) != SUCCESS)
{
- section->sections->insert_last(section->sections, sub);
- continue;
+ sub = section_create(key);
+ if (parse_section(&inner, sub))
+ {
+ section->sections->insert_last(section->sections,
+ sub);
+ continue;
+ }
+ section_destroy(sub);
+ }
+ else
+ { /* extend the existing section */
+ if (parse_section(&inner, sub))
+ {
+ continue;
+ }
}
- section_destroy(sub);
DBG1(DBG_LIB, "parsing subsection '%s' failed", key);
break;
}
case '=':
if (parse(text, "\t ", "\n", NULL, &value))
{
- kv_t *kv = malloc_thing(kv_t);
- kv->key = key;
- kv->value = value;
- section->kv->insert_last(section->kv, kv);
+ kv_t *kv;
+ if (section->kv->find_first(section->kv,
+ (linked_list_match_t)kv_find,
+ (void**)&kv, key) != SUCCESS)
+ {
+ INIT(kv,
+ .key = key,
+ .value = value,
+ );
+ section->kv->insert_last(section->kv, kv);
+ }
+ else
+ { /* replace with the most recently read value */
+ kv->value = value;
+ }
continue;
}
DBG1(DBG_LIB, "parsing value failed near %s", *text);