diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | awkgram.c | 61 | ||||
-rw-r--r-- | awkgram.y | 3 | ||||
-rw-r--r-- | extension/ChangeLog | 11 | ||||
-rw-r--r-- | extension/rwarray.c | 38 | ||||
-rw-r--r-- | extension/testext.c | 5 | ||||
-rw-r--r-- | gawkapi.c | 17 | ||||
-rw-r--r-- | test/ChangeLog | 6 | ||||
-rw-r--r-- | test/Makefile.am | 4 | ||||
-rw-r--r-- | test/id.ok | 2 | ||||
-rw-r--r-- | test/readall.ok | 8 | ||||
-rw-r--r-- | test/readall1.awk | 4 | ||||
-rw-r--r-- | test/readall2.awk | 10 | ||||
-rw-r--r-- | test/testext.ok | 2 |
14 files changed, 109 insertions, 69 deletions
@@ -1,3 +1,10 @@ +2022-10-14 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * awkgram.y: Use Node_var_new instead of Node_var_array for + a subscript expression. + * gawkapi.c (api_sym_update): Make things smarter for dealing + with an untyped variable that needs to become an array. + 2022-10-14 Arnold D. Robbins <arnold@skeeve.com> * symbol.c (make_symbol): Save and restore symbol_table in @@ -969,8 +969,8 @@ static const yytype_int16 yyrline[] = 1861, 1867, 1869, 1871, 1873, 1875, 1877, 1882, 1886, 1918, 1926, 1932, 1938, 1951, 1952, 1953, 1958, 1963, 1967, 1971, 1986, 2007, 2012, 2049, 2086, 2087, 2093, 2094, 2099, 2101, - 2108, 2125, 2142, 2144, 2151, 2156, 2162, 2173, 2185, 2194, - 2198, 2203, 2207, 2211, 2215, 2220, 2221, 2225, 2229, 2233 + 2108, 2125, 2142, 2144, 2151, 2156, 2162, 2174, 2186, 2195, + 2199, 2204, 2208, 2212, 2216, 2221, 2222, 2226, 2230, 2234 }; #endif @@ -4442,15 +4442,16 @@ regular_print: { char *arr = yyvsp[-1]->lextok; - yyvsp[-1]->memory = variable(yyvsp[-1]->source_line, arr, Node_var_array); + // Don't use Node_var_array here; breaks rwarray:readall extension. + yyvsp[-1]->memory = variable(yyvsp[-1]->source_line, arr, Node_var_new); yyvsp[-1]->opcode = Op_push_array; yyval = list_prepend(yyvsp[0], yyvsp[-1]); } -#line 4450 "awkgram.c" +#line 4451 "awkgram.c" break; case 197: /* variable: simple_variable */ -#line 2174 "awkgram.y" +#line 2175 "awkgram.y" { INSTRUCTION *ip = yyvsp[0]->nexti; if (ip->opcode == Op_push @@ -4462,85 +4463,85 @@ regular_print: } else yyval = yyvsp[0]; } -#line 4466 "awkgram.c" +#line 4467 "awkgram.c" break; case 198: /* variable: '$' non_post_simp_exp opt_incdec */ -#line 2186 "awkgram.y" +#line 2187 "awkgram.y" { yyval = list_append(yyvsp[-1], yyvsp[-2]); if (yyvsp[0] != NULL) mk_assignment(yyvsp[-1], NULL, yyvsp[0]); } -#line 4476 "awkgram.c" +#line 4477 "awkgram.c" break; case 199: /* opt_incdec: INCREMENT */ -#line 2195 "awkgram.y" +#line 2196 "awkgram.y" { yyvsp[0]->opcode = Op_postincrement; } -#line 4484 "awkgram.c" +#line 4485 "awkgram.c" break; case 200: /* opt_incdec: DECREMENT */ -#line 2199 "awkgram.y" +#line 2200 "awkgram.y" { yyvsp[0]->opcode = Op_postdecrement; } -#line 4492 "awkgram.c" +#line 4493 "awkgram.c" break; case 201: /* opt_incdec: %empty */ -#line 2203 "awkgram.y" +#line 2204 "awkgram.y" { yyval = NULL; } -#line 4498 "awkgram.c" +#line 4499 "awkgram.c" break; case 202: /* l_brace: '{' opt_nls */ -#line 2207 "awkgram.y" +#line 2208 "awkgram.y" { yyval = yyvsp[0]; } -#line 4504 "awkgram.c" +#line 4505 "awkgram.c" break; case 203: /* r_brace: '}' opt_nls */ -#line 2211 "awkgram.y" +#line 2212 "awkgram.y" { yyval = yyvsp[0]; yyerrok; } -#line 4510 "awkgram.c" +#line 4511 "awkgram.c" break; case 204: /* r_paren: ')' */ -#line 2215 "awkgram.y" +#line 2216 "awkgram.y" { yyerrok; } -#line 4516 "awkgram.c" +#line 4517 "awkgram.c" break; case 205: /* opt_semi: %empty */ -#line 2220 "awkgram.y" +#line 2221 "awkgram.y" { yyval = NULL; } -#line 4522 "awkgram.c" +#line 4523 "awkgram.c" break; case 207: /* semi: ';' */ -#line 2225 "awkgram.y" +#line 2226 "awkgram.y" { yyerrok; } -#line 4528 "awkgram.c" +#line 4529 "awkgram.c" break; case 208: /* colon: ':' */ -#line 2229 "awkgram.y" +#line 2230 "awkgram.y" { yyval = yyvsp[0]; yyerrok; } -#line 4534 "awkgram.c" +#line 4535 "awkgram.c" break; case 209: /* comma: ',' opt_nls */ -#line 2233 "awkgram.y" +#line 2234 "awkgram.y" { yyval = yyvsp[0]; yyerrok; } -#line 4540 "awkgram.c" +#line 4541 "awkgram.c" break; -#line 4544 "awkgram.c" +#line 4545 "awkgram.c" default: break; } @@ -4733,7 +4734,7 @@ yyreturnlab: return yyresult; } -#line 2235 "awkgram.y" +#line 2236 "awkgram.y" struct token { @@ -2163,7 +2163,8 @@ simple_variable { char *arr = $1->lextok; - $1->memory = variable($1->source_line, arr, Node_var_array); + // Don't use Node_var_array here; breaks rwarray:readall extension. + $1->memory = variable($1->source_line, arr, Node_var_new); $1->opcode = Op_push_array; $$ = list_prepend($2, $1); } diff --git a/extension/ChangeLog b/extension/ChangeLog index db568436..259a0c75 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,14 @@ +2022-10-14 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * rwarray.c (array_handle_t): Removed. + (readelem): No longer need the array_handle_t parameter. + All calls adjusted. + (readvalue): No longer need the array_handle_t parameter. + All calls adjusted. Use create_array() instead calling + through the array_handle_t parameter. + (regular_array_handle, global_array_handle): Removed. + * testext.c: Add more prints for array restoration tests. + 2022-09-17 Arnold D. Robbins <arnold@skeeve.com> * rwarray.c (do_poke): Handle namespaced variables (foo::bar). diff --git a/extension/rwarray.c b/extension/rwarray.c index 1a3a7d10..ab8dc86f 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 4f353f14..24fe9338 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"] } */ @@ -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/ChangeLog b/test/ChangeLog index 89a884b2..b5aceb02 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,9 @@ +2022-10-14 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * Makefile.am (readall): Capture stderr from the programs also. + * id.ok, readall.ok, readall1.awk, readall2.awk, testext.ok: + Adjusted after code changes. + 2022-09-25 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am: Rename elemnew tests to mdim: diff --git a/test/Makefile.am b/test/Makefile.am index bece95b6..5ee35ad9 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 @@ -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 8aa6899f..475ca67a 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 4f90c73d..cdb41ee5 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 af45751d..13166810 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 1d058302..3e0c1328 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 |