yml: support multiple merge values

This adds support for merging multiple values, using a list of
dictionaries:

    foo:
      <<: [*foo, *bar]
This commit is contained in:
Daniel Eklöf 2018-12-29 16:06:04 +01:00
parent 36e3bdd9fd
commit b2082e38ed

38
yml.c
View file

@ -161,6 +161,33 @@ post_process(struct yml_node *node)
if (strcmp(it->item.key->scalar.value, "<<") != 0)
continue;
if (it->item.value->type == LIST) {
/*
* Merge value is a list (of dictionaries)
* e.g. <<: [*foo, *bar]
*/
tll_foreach(it->item.value->list.values, v_it) {
assert(v_it->item->type == DICT);
tll_foreach(v_it->item->dict.pairs, vv_it) {
struct dict_pair p = {
.key = vv_it->item.key,
.value = vv_it->item.value,
};
tll_push_back(node->dict.pairs, p);
}
/* Destroy lits, but don't free (since its nodes
* have been moved to this node), *before*
* destroying the key/value nodes. This ensures
* the dict nodes aren't free:d in the
* yml_destroy() below). */
tll_free(v_it->item->dict.pairs);
}
} else {
/*
* Merge value is a dictionary only
* e.g. <<: *foo
*/
assert(it->item.value->type == DICT);
tll_foreach(it->item.value->dict.pairs, v_it) {
struct dict_pair p = {
@ -170,14 +197,17 @@ post_process(struct yml_node *node)
tll_push_back(node->dict.pairs, p);
}
/* Destroy list here, *without* freeing nodes (since nodes
* have been moved to this node), *before* destroying the
* key/value nodes. This ensures the dict nodes aren't
* free:d in the yml_destroy() below */
/* Destroy list here, *without* freeing nodes (since
* nodes have been moved to this node), *before*
* destroying the key/value nodes. This ensures the
* dict nodes aren't free:d in the yml_destroy()
* below */
tll_free(it->item.value->dict.pairs);
}
yml_destroy(it->item.key);
yml_destroy(it->item.value);
tll_remove(node->dict.pairs, it);
}
break;