summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--awkgram.c61
-rw-r--r--awkgram.y3
-rw-r--r--extension/ChangeLog11
-rw-r--r--extension/rwarray.c38
-rw-r--r--extension/testext.c5
-rw-r--r--gawkapi.c17
-rw-r--r--test/ChangeLog6
-rw-r--r--test/Makefile.am4
-rw-r--r--test/id.ok2
-rw-r--r--test/readall.ok8
-rw-r--r--test/readall1.awk4
-rw-r--r--test/readall2.awk10
-rw-r--r--test/testext.ok2
14 files changed, 109 insertions, 69 deletions
diff --git a/ChangeLog b/ChangeLog
index 08e842e4..73654d8b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/awkgram.c b/awkgram.c
index 976e1e02..f4a41011 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -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 {
diff --git a/awkgram.y b/awkgram.y
index ef3720cb..8633d55d 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -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"]
}
*/
diff --git a/gawkapi.c b/gawkapi.c
index b2fb3fd8..ab951591 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/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
diff --git a/test/id.ok b/test/id.ok
index 941d5add..1ddccdd1 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 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