diff options
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | awk.h | 8 | ||||
-rw-r--r-- | ext.c | 16 | ||||
-rw-r--r-- | gawkapi.c | 6 | ||||
-rw-r--r-- | str_array.c | 22 | ||||
-rw-r--r-- | test/ChangeLog | 6 | ||||
-rw-r--r-- | test/Makefile.am | 4 | ||||
-rw-r--r-- | test/Makefile.in | 9 | ||||
-rw-r--r-- | test/Maketests | 5 | ||||
-rw-r--r-- | test/arrayind2.awk | 8 | ||||
-rw-r--r-- | test/arrayind2.ok | 2 |
11 files changed, 79 insertions, 33 deletions
@@ -1,3 +1,29 @@ +2016-05-26 Arnold D. Robbins <arnold@skeeve.com> + + * awk.h [fatal]: Make parentheses and use of indirection + consistent with warning and lintwarn. Thanks to Andrew Schorr + for pointing this out. + * str_array.c (str_lookup): Move test for MAYBE_NUM to where + we duplicate the subscript. Removing it across the board is + wrong if there are multiple references to the value. Thanks + to Andrew Schorr for discussion and test case. + +2016-05-26 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * awk.h (get_actual_argument): Add an initial argument containing + the (NODE *) previously returned by get_argument. This allows us to + eliminate a call to get_argument from inside get_actual_argument. + (get_scalar_argument, get_array_argument): Change macro definition to + add an initial node argument to pass through to get_actual_argument. + * ext.c (get_actual_argument): Add initial (NODE *) argument to contain + the value previously returned by get_argument. This allows us to + avoid repeating the call to get_argument. We can also eliminate the + check for a NULL value, since the caller did that already. + * gawkapi.c (api_get_argument): Pass (NODE *) returned by get_argument + to get_array_argument and get_scalar_argument. + (api_set_argument): Pass (NODE *) returned by get_argument to + get_array_argument. + 2016-05-25 Manuel Collado <mcollado2011@gmail.com>. * gawkapi.c (api_nonfatal): New function. @@ -1278,7 +1278,7 @@ DEREF(NODE *r) #define efree(p) free(p) -#define fatal set_loc(__FILE__, __LINE__), r_fatal +#define fatal (*(set_loc(__FILE__, __LINE__), r_fatal)) extern jmp_buf fatal_tag; extern bool fatal_tag_valid; @@ -1449,9 +1449,9 @@ extern void close_extensions(void); #ifdef DYNAMIC extern awk_bool_t make_builtin(const awk_ext_func_t *); extern NODE *get_argument(int); -extern NODE *get_actual_argument(int, bool, bool); -#define get_scalar_argument(i, opt) get_actual_argument((i), (opt), false) -#define get_array_argument(i, opt) get_actual_argument((i), (opt), true) +extern NODE *get_actual_argument(NODE *, int, bool, bool); +#define get_scalar_argument(n, i, opt) get_actual_argument((n), (i), (opt), false) +#define get_array_argument(n, i, opt) get_actual_argument((n), (i), (opt), true) #endif /* field.c */ extern void init_fields(void); @@ -187,28 +187,14 @@ get_argument(int i) */ NODE * -get_actual_argument(int i, bool optional, bool want_array) +get_actual_argument(NODE *t, int i, bool optional, bool want_array) { - NODE *t; char *fname; - int pcount; INSTRUCTION *pc; pc = TOP()->code_ptr; /* Op_ext_builtin instruction */ fname = (pc + 1)->func_name; - pcount = (pc + 1)->expr_count; - t = get_argument(i); - if (t == NULL) { - if (i >= pcount) /* must be fatal */ - fatal(_("function `%s' defined to take no more than %d argument(s)"), - fname, pcount); - if (! optional) - fatal(_("function `%s': missing argument #%d"), - fname, i + 1); - return NULL; - } - if (t->type == Node_var_new) { if (want_array) return force_array(t, false); @@ -87,7 +87,7 @@ api_get_argument(awk_ext_id_t id, size_t count, array: /* get the array here */ - arg = get_array_argument(count, false); + arg = get_array_argument(arg, count, false); if (arg == NULL) return awk_false; @@ -95,7 +95,7 @@ array: scalar: /* at this point we have a real type that is not an array */ - arg = get_scalar_argument(count, false); + arg = get_scalar_argument(arg, count, false); if (arg == NULL) return awk_false; @@ -125,7 +125,7 @@ api_set_argument(awk_ext_id_t id, || arg->type != Node_var_new) return awk_false; - arg = get_array_argument(count, false); + arg = get_array_argument(arg, count, false); if (arg == NULL) return awk_false; diff --git a/str_array.c b/str_array.c index c122ab94..7a6b50fe 100644 --- a/str_array.c +++ b/str_array.c @@ -156,7 +156,18 @@ str_lookup(NODE *symbol, NODE *subs) hash1 = code1 % (unsigned long) symbol->array_size; } - if (subs->stfmt != -1) { + + /* + * Repeat after me: "Array indices are always strings." + * "Array indices are always strings." + * "Array indices are always strings." + * "Array indices are always strings." + * .... + * If subs is a STRNUM, copy it; don't clear the MAYBE_NUM + * flag on it since other variables could be using the same + * reference-counted value. + */ + if (subs->stfmt != -1 || (subs->flags & MAYBE_NUM) != 0) { NODE *tmp; /* @@ -187,14 +198,7 @@ str_lookup(NODE *symbol, NODE *subs) subs = dupnode(subs); } - /* - * Repeat after me: "Array indices are always strings." - * "Array indices are always strings." - * "Array indices are always strings." - * "Array indices are always strings." - * .... - */ - subs->flags &= ~MAYBE_NUM; + assert((subs->flags & MAYBE_NUM) == 0); getbucket(b); b->ahnext = symbol->buckets[hash1]; diff --git a/test/ChangeLog b/test/ChangeLog index c395fc69..b9689557 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,9 @@ +2016-05-26 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (arrayind2): New test. + * arrayind2.awk, arrayind2.ok: New files. + Thanks to Andrew J. Schorr <aschorr@telemetry-investments.com>. + 2016-05-25 Arnold D. Robbins <arnold@skeeve.com> * arrayind1.awk: Flush writes to stderr. We hope this helps diff --git a/test/Makefile.am b/test/Makefile.am index 63990647..8d62e802 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -55,6 +55,8 @@ EXTRA_DIST = \ arrayind1.awk \ arrayind1.in \ arrayind1.ok \ + arrayind2.awk \ + arrayind2.ok \ arrayparm.awk \ arrayparm.ok \ arrayprm2.awk \ @@ -1094,7 +1096,7 @@ CLEANFILES = core core.* fmtspcl.ok # try to keep these sorted. each letter starts a new line BASIC_TESTS = \ - addcomma anchgsub argarray arrayind1 arrayparm arrayprm2 arrayprm3 \ + addcomma anchgsub argarray arrayind1 arrayind2 arrayparm arrayprm2 arrayprm3 \ arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 arynasty \ arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \ aryprm8 aryprm9 arysubnm asgext awkpath \ diff --git a/test/Makefile.in b/test/Makefile.in index cc44371c..37e9b9b5 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -312,6 +312,8 @@ EXTRA_DIST = \ arrayind1.awk \ arrayind1.in \ arrayind1.ok \ + arrayind2.awk \ + arrayind2.ok \ arrayparm.awk \ arrayparm.ok \ arrayprm2.awk \ @@ -1350,7 +1352,7 @@ CLEANFILES = core core.* fmtspcl.ok # try to keep these sorted. each letter starts a new line BASIC_TESTS = \ - addcomma anchgsub argarray arrayind1 arrayparm arrayprm2 arrayprm3 \ + addcomma anchgsub argarray arrayind1 arrayind2 arrayparm arrayprm2 arrayprm3 \ arrayref arrymem1 arryref2 arryref3 arryref4 arryref5 arynasty \ arynocls aryprm1 aryprm2 aryprm3 aryprm4 aryprm5 aryprm6 aryprm7 \ aryprm8 aryprm9 arysubnm asgext awkpath \ @@ -2699,6 +2701,11 @@ arrayind1: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +arrayind2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + arrayparm: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index a831496c..0895d23d 100644 --- a/test/Maketests +++ b/test/Maketests @@ -15,6 +15,11 @@ arrayind1: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +arrayind2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + arrayparm: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/arrayind2.awk b/test/arrayind2.awk new file mode 100644 index 00000000..200694eb --- /dev/null +++ b/test/arrayind2.awk @@ -0,0 +1,8 @@ +BEGIN { + pos[0] = 0 + posout[0] = 0 + split("00000779770060", f) # f[1] is a strnum + print typeof(f[1]) + pos[f[1]] = 1 + print typeof(f[1]) +} diff --git a/test/arrayind2.ok b/test/arrayind2.ok new file mode 100644 index 00000000..335b2005 --- /dev/null +++ b/test/arrayind2.ok @@ -0,0 +1,2 @@ +strnum +strnum |