diff options
Diffstat (limited to 'lib/bootconfig.c')
-rw-r--r-- | lib/bootconfig.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/lib/bootconfig.c b/lib/bootconfig.c index 9f8c70a98fcf..44dcdcbd746a 100644 --- a/lib/bootconfig.c +++ b/lib/bootconfig.c @@ -367,6 +367,14 @@ static inline __init struct xbc_node *xbc_last_sibling(struct xbc_node *node) return node; } +static inline __init struct xbc_node *xbc_last_child(struct xbc_node *node) +{ + while (node->child) + node = xbc_node_get_child(node); + + return node; +} + static struct xbc_node * __init xbc_add_sibling(char *data, u32 flag) { struct xbc_node *sib, *node = xbc_add_node(data, flag); @@ -517,17 +525,20 @@ static int __init xbc_parse_array(char **__v) char *next; int c = 0; + if (last_parent->child) + last_parent = xbc_node_get_child(last_parent); + do { c = __xbc_parse_value(__v, &next); if (c < 0) return c; - node = xbc_add_sibling(*__v, XBC_VALUE); + node = xbc_add_child(*__v, XBC_VALUE); if (!node) return -ENOMEM; *__v = next; } while (c == ','); - node->next = 0; + node->child = 0; return c; } @@ -615,8 +626,12 @@ static int __init xbc_parse_kv(char **k, char *v, int op) if (op == ':' && child) { xbc_init_node(child, v, XBC_VALUE); - } else if (!xbc_add_sibling(v, XBC_VALUE)) - return -ENOMEM; + } else { + if (op == '+' && child) + last_parent = xbc_last_child(child); + if (!xbc_add_sibling(v, XBC_VALUE)) + return -ENOMEM; + } if (c == ',') { /* Array */ c = xbc_parse_array(&next); |