From f38a8f801496ea91cef7a8507e2919f6586d0694 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 6 Jan 2015 20:17:35 -0500 Subject: Fix bug in API deferred variable creation and add a test case. --- gawkapi.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 5630185c..e8879022 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -579,7 +579,7 @@ api_sym_update(awk_ext_id_t id, if (node == NULL) { /* new value to be installed */ if (value->val_type == AWK_ARRAY) { - unsigned long nel; + bool is_deferred; array_node = awk_value_to_node(value); /* @@ -587,27 +587,35 @@ api_sym_update(awk_ext_id_t id, * case this is a deferred variable such as PROCINFO * or ENVIRON */ - node = variable_create(estrdup((char *) name, strlen(name)), Node_var_array); - array_node->vname = node->vname; - if ((nel = assoc_length(node)) > 0) { - /* merge the 2 arrays */ + node = variable_create(estrdup((char *) name, strlen(name)), Node_var_array, & is_deferred); + if (is_deferred) { + /* + * merge the user-supplied elements into the + * already-existing array. Since ENVIRON + * has special array_funcs, we need to retain + * the auto-created array! + */ + unsigned long nel; NODE **list; NODE akind; unsigned long i; + nel = assoc_length(array_node); akind.flags = (AINDEX|AVALUE); - list = node->alist(node, & akind); + list = array_node->alist(array_node, & akind); for (i = 0; i < nel; i++) { NODE **aptr; - aptr = assoc_lookup(array_node, list[2*i]); + aptr = assoc_lookup(node, list[2*i]); unref(*aptr); unref(list[2*i]); /* alist duped it */ *aptr = dupnode(list[2*i+1]); } efree(list); - assoc_clear(node); + assoc_clear(array_node); + } else { + array_node->vname = node->vname; + *node = *array_node; } - *node = *array_node; freenode(array_node); value->array_cookie = node; /* pass new cookie back to extension */ } else { -- cgit v1.2.3