diff --git a/awkgram.y b/awkgram.y index ef3720c..3826507 100644 --- a/awkgram.y +++ b/awkgram.y @@ -2163,7 +2163,7 @@ simple_variable { char *arr = $1->lextok; - $1->memory = variable($1->source_line, arr, Node_var_array); + $1->memory = variable($1->source_line, arr, Node_var_new); $1->opcode = Op_push_array; $$ = list_prepend($2, $1); } diff --git a/extension/rwarray.c b/extension/rwarray.c index 1a3a7d1..ab8dc86 100644 --- a/extension/rwarray.c +++ b/extension/rwarray.c @@ -88,10 +88,9 @@ typedef union { typedef int value_storage; // should not be used #endif /* HAVE_MPFR */ -typedef awk_array_t (*array_handle_t)(awk_value_t *); static awk_bool_t read_array(FILE *fp, awk_array_t array); -static awk_bool_t read_elem(FILE *fp, awk_element_t *element, array_handle_t, value_storage *); -static awk_bool_t read_value(FILE *fp, awk_value_t *value, array_handle_t, awk_value_t *idx, value_storage *vs); +static awk_bool_t read_elem(FILE *fp, awk_element_t *element, value_storage *); +static awk_bool_t read_value(FILE *fp, awk_value_t *value, awk_value_t *idx, value_storage *vs); static awk_bool_t read_number(FILE *fp, awk_value_t *value, uint32_t code, value_storage *); /* @@ -487,27 +486,6 @@ do_poke(awk_element_t *e) return awk_true; } -/* regular_array_handle --- array creation hook for normal reada */ - -static awk_array_t -regular_array_handle(awk_value_t *unused) -{ - return create_array(); -} - -/* global_array_handle --- array creation hook for readall */ - -static awk_array_t -global_array_handle(awk_value_t *n) -{ - awk_value_t t; - size_t count; - - /* The array may exist already because it was instantiated during - * program parsing, so we use the existing array if it is empty. */ - return ((n->val_type == AWK_STRING) && sym_lookup(n->str_value.str, AWK_UNDEFINED, &t) && (t.val_type == AWK_ARRAY) && get_element_count(t.array_cookie, & count) && ! count) ? t.array_cookie : create_array(); -} - /* read_global --- read top-level variables dumped from SYMTAB */ static awk_bool_t @@ -524,7 +502,7 @@ read_global(FILE *fp, awk_array_t unused) count = ntohl(count); for (i = 0; i < count; i++) { - if (read_elem(fp, & new_elem, global_array_handle, &vs)) { + if (read_elem(fp, & new_elem, &vs)) { if (! do_poke(& new_elem)) free_value(& new_elem.value); if (new_elem.index.str_value.len) @@ -664,7 +642,7 @@ read_array(FILE *fp, awk_array_t array) count = ntohl(count); for (i = 0; i < count; i++) { - if (read_elem(fp, & new_elem, regular_array_handle, &vs)) { + if (read_elem(fp, & new_elem, &vs)) { /* add to array */ if (! set_array_element_by_elem(array, & new_elem)) { warning(ext_id, _("read_array: set_array_element failed")); @@ -683,7 +661,7 @@ read_array(FILE *fp, awk_array_t array) /* read_elem --- read in a single element */ static awk_bool_t -read_elem(FILE *fp, awk_element_t *element, array_handle_t array_handle, value_storage *vs) +read_elem(FILE *fp, awk_element_t *element, value_storage *vs) { uint32_t index_len; static char *buffer; @@ -721,7 +699,7 @@ read_elem(FILE *fp, awk_element_t *element, array_handle_t array_handle, value_s make_null_string(& element->index); } - if (! read_value(fp, & element->value, array_handle, & element->index, vs)) + if (! read_value(fp, & element->value, & element->index, vs)) return awk_false; return awk_true; @@ -730,7 +708,7 @@ read_elem(FILE *fp, awk_element_t *element, array_handle_t array_handle, value_s /* read_value --- read a number or a string */ static awk_bool_t -read_value(FILE *fp, awk_value_t *value, array_handle_t array_handle, awk_value_t *idx, value_storage *vs) +read_value(FILE *fp, awk_value_t *value, awk_value_t *idx, value_storage *vs) { uint32_t code, len; @@ -740,7 +718,7 @@ read_value(FILE *fp, awk_value_t *value, array_handle_t array_handle, awk_value_ code = ntohl(code); if (code == VT_ARRAY) { - awk_array_t array = (*array_handle)(idx); + awk_array_t array = create_array(); if (! read_array(fp, array)) return awk_false; diff --git a/extension/testext.c b/extension/testext.c index 4f353f1..24fe933 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -673,13 +673,16 @@ out: /* function tfunc(f) { - if (isarray(f)) + if (isarray(f)) { print "good: we have an array" + print "hello element value inside function is", f["hello"] + } } BEGIN { printf "test_array_create returned %d\n", test_array_create("testarr") tfunc(testarr) + print "hello element global scope is", testarr["hello"] } */ diff --git a/gawkapi.c b/gawkapi.c index b2fb3fd..ab95159 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -899,9 +899,20 @@ api_sym_update(awk_ext_id_t id, efree((void *) full_name); - if ((node->type == Node_var && value->val_type != AWK_ARRAY) - || node->type == Node_var_new - || node->type == Node_elem_new) { + if (value->val_type == AWK_ARRAY) { + if (node->type == Node_var_new) { + /* special gymnastics to convert untyped to an array */ + array_node = awk_value_to_node(value); + array_node->vname = node->vname; + unref(node->var_value); + *node = *array_node; + freenode(array_node); + value->array_cookie = node; /* pass new cookie back to extension */ + return awk_true; + } + } else if (node->type == Node_var + || node->type == Node_var_new + || node->type == Node_elem_new) { unref(node->var_value); node->var_value = awk_value_to_node(value); if ((node->type == Node_var_new || node->type == Node_elem_new) diff --git a/test/Makefile.am b/test/Makefile.am index bece95b..5ee35ad 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2418,8 +2418,8 @@ readdir_retest: readall: @echo $@ - @-AWKPATH="$(srcdir)" $(AWK) -lrwarray -f $@1.awk -v "ofile=readall.state" > _$@ - @-AWKPATH="$(srcdir)" $(AWK) -lrwarray -f $@2.awk -v "ifile=readall.state" >> _$@ + @-AWKPATH="$(srcdir)" $(AWK) -lrwarray -f $@1.awk -v "ofile=readall.state" > _$@ 2>&1 + @-AWKPATH="$(srcdir)" $(AWK) -lrwarray -f $@2.awk -v "ifile=readall.state" >> _$@ 2>&1 @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ @-$(RM) -f readall.state diff --git a/test/id.ok b/test/id.ok index 941d5ad..1ddccdd 100644 --- a/test/id.ok +++ b/test/id.ok @@ -28,7 +28,7 @@ RT -> scalar SUBSEP -> scalar SYMTAB -> array TEXTDOMAIN -> scalar -an_array -> array +an_array -> untyped and -> builtin asort -> builtin asorti -> builtin diff --git a/test/readall.ok b/test/readall.ok index 8aa6899..475ca67 100644 --- a/test/readall.ok +++ b/test/readall.ok @@ -2,7 +2,15 @@ 1 5.9 3 -2.327 42 + +a +apple zebra[archie] = banana zebra[0] = apple zebra[3][foo] = bar zebra[3][bar] = foo +array +m[a] = 1 +m[b] = 3 +a 1 +b 3 diff --git a/test/readall1.awk b/test/readall1.awk index 4f90c73..cdb41ee 100644 --- a/test/readall1.awk +++ b/test/readall1.awk @@ -7,5 +7,9 @@ BEGIN { zebra["archie"] = "banana" zebra[3]["foo"] = "bar" zebra[3]["bar"] = "foo" + f[1] = "alpha" + g[1] = "beta" + m["a"] = 1 + m["b"] = 3 print writeall(ofile) } diff --git a/test/readall2.awk b/test/readall2.awk index af45751..1316681 100644 --- a/test/readall2.awk +++ b/test/readall2.awk @@ -8,9 +8,17 @@ function printarray(n, x, i) { } BEGIN { + split("", f) + split("a b c", g) print readall(ifile) print x, y, z print guide::answer - #print zebra[0], zebra[3]["foo"], zebra[3]["bar"] + print f[1] + print g[1] + print zebra[0] printarray("zebra", zebra) + print typeof(m) + printarray("m", m) + for (i in m) + print i, m[i] } diff --git a/test/testext.ok b/test/testext.ok index 1d05830..3e0c132 100644 --- a/test/testext.ok +++ b/test/testext.ok @@ -50,6 +50,8 @@ isarray(a_scalar) = 0 test_array_create returned 1 good: we have an array +hello element value inside function is world +hello element global scope is world Initial value of LINT is 0 print_do_lint: lint = 0 print_do_lint() returned 1