diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2015-06-25 23:12:55 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2015-06-25 23:12:55 +0300 |
commit | 056cd074c60d940d5bb46410f114a6c2584daaae (patch) | |
tree | e2b095b3740b35cc95a8b25fd10ee5d81288565e | |
parent | 5b246a31d63a31180136934adbed361651f325ba (diff) | |
parent | 3712ad29b6cddcf49bf1507f5677a49ccfcff83d (diff) | |
download | egawk-056cd074c60d940d5bb46410f114a6c2584daaae.tar.gz egawk-056cd074c60d940d5bb46410f114a6c2584daaae.tar.bz2 egawk-056cd074c60d940d5bb46410f114a6c2584daaae.zip |
Merge branch 'master' into feature/cmake
-rw-r--r-- | ChangeLog | 51 | ||||
-rw-r--r-- | awk.h | 2 | ||||
-rw-r--r-- | awkgram.c | 4 | ||||
-rw-r--r-- | awkgram.y | 4 | ||||
-rw-r--r-- | builtin.c | 16 | ||||
-rw-r--r-- | debug.c | 9 | ||||
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | interpret.h | 13 | ||||
-rw-r--r-- | profile.c | 1 | ||||
-rw-r--r-- | test/ChangeLog | 19 | ||||
-rw-r--r-- | test/Makefile.am | 20 | ||||
-rw-r--r-- | test/Makefile.in | 35 | ||||
-rw-r--r-- | test/Maketests | 15 | ||||
-rw-r--r-- | test/dbugtypedre.awk | 1 | ||||
-rw-r--r-- | test/dbugtypedre.in | 4 | ||||
-rw-r--r-- | test/dbugtypedre.ok | 17 | ||||
-rw-r--r-- | test/typeof2.awk | 20 | ||||
-rw-r--r-- | test/typeof2.ok | 6 | ||||
-rw-r--r-- | test/typeof3.awk | 19 | ||||
-rw-r--r-- | test/typeof3.ok | 9 | ||||
-rw-r--r-- | test/typeof4.awk | 13 | ||||
-rw-r--r-- | test/typeof4.ok | 1 |
22 files changed, 264 insertions, 16 deletions
@@ -1,3 +1,54 @@ +2015-06-25 Arnold D. Robbins <arnold@skeeve.com> + + Further work straightening out memory management for typeof. + + * awk.h (DEREF): Add an assert. + * builtin.c (do_typeof): Add comments, cases where not to deref. + * debug.c (print_instruction): Add Op_push_arg_untyped. + * interpret.h (r_interpret): Additional comments / tweaks for + Op_push_arg_untyped. + + Unrelated. Make `x = @/foo/ ; print x' print something. + + * builtin.c (do_print): Check for Node_typedregex and handle it. + Needed for adding test code. + + Unrelated. Typo fix. + + * debug.c (initialize_watch_item): Dupnode the right thing. + +2015-06-22 Arnold D. Robbins <arnold@skeeve.com> + + * awkgram.y (snode): Make isarray not scalarize untyped parameters + also. + * profile.c (pprint): Add Op_push_arg_untyped. + + Improve debugger support for typed regexps. + Thanks to Hermann Peifer for the bug report. + + * awkgram.y (valinfo): Add support for Node_typedregex. + * debug.c (watchpoint_triggerred): Handle Node_typedregex. + (initialize_watch_item): Ditto. + (print_memory): Ditto. + + Fix typeof to work on subarrays. Thanks, yet again, to + Hermann Peifer for the bug report. + + * builtin.c (do_typeof): Don't deref Node_var_array. + +2015-06-21 Arnold D. Robbins <arnold@skeeve.com> + + Fixes for typeof - Don't let typeof change an untyped variable + into a scalar. + + * awk.h (opcodeval): Add Op_push_arg_untyped. + * awkgram.y (snode): Separate out case for do_typeof, use + Op_push_arg_untyped. + * builtin.c (do_typeof): Arg will be equal to Nnull_string + if it's untyped. + * eval.c (optypes): Add Op_push_arg_untyped. + * interpret.h (r_interpret): Add Op_push_arg_untyped handling. + 2015-06-19 Arnold D. Robbins <arnold@skeeve.com> * builtin.c (do_isarray): Minor edit to lint warning. @@ -643,6 +643,7 @@ typedef enum opcodeval { Op_push, /* scalar variable */ Op_push_arg, /* variable type (scalar or array) argument to built-in */ + Op_push_arg_untyped, /* like Op_push_arg, but for typeof */ Op_push_i, /* number, string */ Op_push_re, /* regex */ Op_push_array, @@ -1181,6 +1182,7 @@ extern void r_unref(NODE *tmp); static inline void DEREF(NODE *r) { + assert(r->valref > 0); if (--r->valref == 0) r_unref(r); } @@ -6700,7 +6700,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) } else if (r->builtin == do_isarray || r->builtin == do_typeof) { arg = subn->nexti; if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) - arg->nexti->opcode = Op_push_arg; /* argument may be array */ + arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */ } else if (r->builtin == do_intdiv #ifdef HAVE_MPFR || r->builtin == MPF(intdiv) @@ -6895,6 +6895,8 @@ valinfo(NODE *n, Func_print print_func, FILE *fp) { if (n == Nnull_string) print_func(fp, "uninitialized scalar\n"); + else if (n->type == Node_typedregex) + print_func(fp, "@/%.*s/\n", n->re_exp->stlen, n->re_exp->stptr); else if ((n->flags & STRING) != 0) { pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', false); print_func(fp, "\n"); @@ -4280,7 +4280,7 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) } else if (r->builtin == do_isarray || r->builtin == do_typeof) { arg = subn->nexti; if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) - arg->nexti->opcode = Op_push_arg; /* argument may be array */ + arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */ } else if (r->builtin == do_intdiv #ifdef HAVE_MPFR || r->builtin == MPF(intdiv) @@ -4475,6 +4475,8 @@ valinfo(NODE *n, Func_print print_func, FILE *fp) { if (n == Nnull_string) print_func(fp, "uninitialized scalar\n"); + else if (n->type == Node_typedregex) + print_func(fp, "@/%.*s/\n", n->re_exp->stlen, n->re_exp->stptr); else if ((n->flags & STRING) != 0) { pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', false); print_func(fp, "\n"); @@ -2144,7 +2144,9 @@ do_print(int nargs, int redirtype) fatal(_("attempt to use array `%s' in a scalar context"), array_vname(tmp)); } - if ((tmp->flags & (NUMBER|STRING)) == NUMBER) { + if (tmp->type == Node_typedregex) + args_array[i] = force_string(tmp); + else if ((tmp->flags & (NUMBER|STRING)) == NUMBER) { if (OFMTidx == CONVFMTidx) args_array[i] = force_string(tmp); else @@ -3872,19 +3874,23 @@ do_typeof(int nargs) { NODE *arg; char *res = "unknown"; - int null_str_flags = (STRCUR|STRING|NUMCUR|NUMBER); + bool deref = true; arg = POP(); switch (arg->type) { case Node_var_array: + /* Node_var_array is never UPREF'ed */ res = "array"; + deref = false; break; case Node_typedregex: + /* Op_push_re does not UPREF */ res = "regexp"; + deref = false; break; case Node_val: case Node_var: - if ((arg->flags & null_str_flags) == null_str_flags) + if (arg == Nnull_string) res = "untyped"; else if ((arg->flags & STRING) != 0) res = "scalar_s"; @@ -3893,6 +3899,7 @@ do_typeof(int nargs) break; case Node_var_new: res = "untyped"; + deref = false; break; default: fatal(_("typeof: unknown argument type `%s'"), @@ -3900,7 +3907,8 @@ do_typeof(int nargs) break; } - DEREF(arg); + if (deref) + DEREF(arg); return make_string(res, strlen(res)); } @@ -1736,6 +1736,8 @@ watchpoint_triggered(struct list_item *w) /* new != NULL */ if (t2->type == Node_val) w->cur_value = dupnode(t2); + else if (t2->type == Node_typedregex) + w->cur_value = dupnode(t2); else { w->flags |= CUR_IS_ARRAY; w->cur_size = (t2->type == Node_var_array) ? assoc_length(t2) : 0; @@ -1748,6 +1750,7 @@ watchpoint_triggered(struct list_item *w) w->flags |= CUR_IS_ARRAY; w->cur_size = assoc_length(t2); } else + /* works for Node_typedregex too */ w->cur_value = dupnode(t2); } @@ -1790,6 +1793,8 @@ initialize_watch_item(struct list_item *w) } else if (symbol->type == Node_var_array) { w->flags |= CUR_IS_ARRAY; w->cur_size = assoc_length(symbol); + } else if (symbol->type == Node_typedregex) { + w->cur_value = dupnode(symbol); } /* else can't happen */ } @@ -3703,6 +3708,9 @@ print_memory(NODE *m, NODE *func, Func_print print_func, FILE *fp) print_func(fp, " [%s]", flags2str(m->flags)); break; + case Node_typedregex: + print_func(fp, "@"); + /* fall through */ case Node_regex: pp_string_fp(print_func, fp, m->re_exp->stptr, m->re_exp->stlen, '/', false); break; @@ -3982,6 +3990,7 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) case Op_push_i: case Op_push: case Op_push_arg: + case Op_push_arg_untyped: case Op_push_param: case Op_push_array: case Op_push_re: @@ -338,6 +338,7 @@ static struct optypetab { { "Op_indirect_func_call", NULL }, { "Op_push", NULL }, { "Op_push_arg", NULL }, + { "Op_push_arg_untyped", NULL }, { "Op_push_i", NULL }, { "Op_push_re", NULL }, { "Op_push_array", NULL }, diff --git a/interpret.h b/interpret.h index 03532f43..1005174a 100644 --- a/interpret.h +++ b/interpret.h @@ -144,6 +144,7 @@ top: case Op_push: case Op_push_arg: + case Op_push_arg_untyped: { NODE *save_symbol; bool isparam = false; @@ -175,19 +176,23 @@ top: case Node_var_new: uninitialized_scalar: - m->type = Node_var; - m->var_value = dupnode(Nnull_string); + if (op != Op_push_arg_untyped) { + /* convert untyped to scalar */ + m->type = Node_var; + m->var_value = dupnode(Nnull_string); + } if (do_lint) lintwarn(isparam ? _("reference to uninitialized argument `%s'") : _("reference to uninitialized variable `%s'"), save_symbol->vname); - m = dupnode(Nnull_string); + if (op != Op_push_arg_untyped) + m = dupnode(Nnull_string); PUSH(m); break; case Node_var_array: - if (op == Op_push_arg) + if (op == Op_push_arg || op == Op_push_arg_untyped) PUSH(m); else fatal(_("attempt to use array `%s' in a scalar context"), @@ -317,6 +317,7 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header) case Op_push_array: case Op_push: case Op_push_arg: + case Op_push_arg_untyped: m = pc->memory; switch (m->type) { case Node_param_list: diff --git a/test/ChangeLog b/test/ChangeLog index b57a756f..b92d8ae7 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,22 @@ +2015-06-25 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (negtime): Fix out-of-tree test run. + + Unrelated: + + * Makefile.am (typeof3, typeof4): New tests. + * typeof2.awk, typeof2.ok, typeof3.awk, typeof3.ok: New files. + + Unrelated: + + * Makefile.am (dbugtypedre): New tests. + * dbugtypedre.awk, dbugtypedre.in, dbugtypedre.ok: New files. + +2015-06-21 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (typeof2): New test. + * typeof2.awk, typeof2.ok: New files. + 2015-06-19 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (gsubind, typedregex1, typeof1): New tests. diff --git a/test/Makefile.am b/test/Makefile.am index 537a5655..03d28f21 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -177,6 +177,9 @@ EXTRA_DIST = \ datanonl.ok \ dbugeval.in \ dbugeval.ok \ + dbugtypedre.awk \ + dbugtypedre.in \ + dbugtypedre.ok \ defref.awk \ defref.ok \ delargv.awk \ @@ -985,6 +988,12 @@ EXTRA_DIST = \ typedregex1.ok \ typeof1.awk \ typeof1.ok \ + typeof2.awk \ + typeof2.ok \ + typeof3.awk \ + typeof3.ok \ + typeof4.awk \ + typeof4.ok \ uninit2.awk \ uninit2.ok \ uninit3.awk \ @@ -1079,7 +1088,7 @@ UNIX_TESTS = \ GAWK_EXT_TESTS = \ aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \ backw badargs beginfile1 beginfile2 binmode1 charasbytes \ - colonwarn clos1way crlf dbugeval delsub devfd devfd1 devfd2 dumpvars errno exit \ + colonwarn clos1way crlf dbugeval dbugtypedre delsub devfd devfd1 devfd2 dumpvars errno exit \ fieldwdth fpat1 fpat2 fpat3 fpat4 fpatnull fsfwfs funlen \ functab1 functab2 functab3 fwtest fwtest2 fwtest3 \ genpot gensub gensub2 getlndir gnuops2 gnuops3 gnureops gsubind \ @@ -1099,7 +1108,7 @@ GAWK_EXT_TESTS = \ splitarg4 strftime \ strtonum switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \ symtab7 symtab8 symtab9 \ - typedregex1 typeof1 + typedregex1 typeof1 typeof2 typeof3 typeof4 timeout EXTRA_TESTS = inftest regtest @@ -2124,7 +2133,12 @@ paramasfunc2:: negtime:: @echo $@ @TZ=GMT AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ - @AWKPATH="$(srcdir)" $(AWK) -f checknegtime.awk $@.ok _$@ && rm -f _$@ + @AWKPATH="$(srcdir)" $(AWK) -f checknegtime.awk "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +dbugtypedre: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -D -f $@.awk < $@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ # Targets generated for other tests: include Maketests diff --git a/test/Makefile.in b/test/Makefile.in index a8895ed7..294c60c0 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -434,6 +434,9 @@ EXTRA_DIST = \ datanonl.ok \ dbugeval.in \ dbugeval.ok \ + dbugtypedre.awk \ + dbugtypedre.in \ + dbugtypedre.ok \ defref.awk \ defref.ok \ delargv.awk \ @@ -1242,6 +1245,12 @@ EXTRA_DIST = \ typedregex1.ok \ typeof1.awk \ typeof1.ok \ + typeof2.awk \ + typeof2.ok \ + typeof3.awk \ + typeof3.ok \ + typeof4.awk \ + typeof4.ok \ uninit2.awk \ uninit2.ok \ uninit3.awk \ @@ -1335,7 +1344,7 @@ UNIX_TESTS = \ GAWK_EXT_TESTS = \ aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \ backw badargs beginfile1 beginfile2 binmode1 charasbytes \ - colonwarn clos1way crlf dbugeval delsub devfd devfd1 devfd2 dumpvars errno exit \ + colonwarn clos1way crlf dbugeval dbugtypedre delsub devfd devfd1 devfd2 dumpvars errno exit \ fieldwdth fpat1 fpat2 fpat3 fpat4 fpatnull fsfwfs funlen \ functab1 functab2 functab3 fwtest fwtest2 fwtest3 \ genpot gensub gensub2 getlndir gnuops2 gnuops3 gnureops gsubind \ @@ -1355,7 +1364,7 @@ GAWK_EXT_TESTS = \ splitarg4 strftime \ strtonum switch2 symtab1 symtab2 symtab3 symtab4 symtab5 symtab6 \ symtab7 symtab8 symtab9 \ - typedregex1 typeof1 + typedregex1 typeof1 typeof2 typeof3 typeof4 EXTRA_TESTS = inftest regtest INET_TESTS = inetdayu inetdayt inetechu inetecht @@ -2560,7 +2569,12 @@ paramasfunc2:: negtime:: @echo $@ @TZ=GMT AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ - @AWKPATH="$(srcdir)" $(AWK) -f checknegtime.awk $@.ok _$@ && rm -f _$@ + @AWKPATH="$(srcdir)" $(AWK) -f checknegtime.awk "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +dbugtypedre: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -D -f $@.awk < $@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ Gt-dummy: # file Maketests, generated from Makefile.am by the Gentests program addcomma: @@ -3905,6 +3919,21 @@ typeof1: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +typeof2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +typeof3: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +typeof4: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + double1: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index a674d5d0..e4cea0de 100644 --- a/test/Maketests +++ b/test/Maketests @@ -1342,6 +1342,21 @@ typeof1: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +typeof2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +typeof3: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +typeof4: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + double1: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/dbugtypedre.awk b/test/dbugtypedre.awk new file mode 100644 index 00000000..b8c0b6d7 --- /dev/null +++ b/test/dbugtypedre.awk @@ -0,0 +1 @@ +@include "typeof1.awk" diff --git a/test/dbugtypedre.in b/test/dbugtypedre.in new file mode 100644 index 00000000..00158c65 --- /dev/null +++ b/test/dbugtypedre.in @@ -0,0 +1,4 @@ +watch e +run +next +p e diff --git a/test/dbugtypedre.ok b/test/dbugtypedre.ok new file mode 100644 index 00000000..de3c8bcd --- /dev/null +++ b/test/dbugtypedre.ok @@ -0,0 +1,17 @@ +Watchpoint 1: e +Starting program: +scalar_n +untyped +regexp +scalar_s +array scalar_n +Stopping in BEGIN ... +Watchpoint 1: e + Old value: untyped variable + New value: @/foo/ +main() at `typeof1.awk':7 +7 e = @/foo/ ; print typeof(e) +regexp +8 print typeof(@/bar/) +e = @/foo/ +EXIT CODE: 2 diff --git a/test/typeof2.awk b/test/typeof2.awk new file mode 100644 index 00000000..25da02e4 --- /dev/null +++ b/test/typeof2.awk @@ -0,0 +1,20 @@ +BEGIN { + print typeof(x) + x[1] = 3 + print typeof(x) +} + +function test1() { +} + +function test2(p) { + p[1] = 1 +} + +BEGIN { + print typeof(a) + test1(a) + print typeof(a) + test2(a) + print typeof(a) +} diff --git a/test/typeof2.ok b/test/typeof2.ok new file mode 100644 index 00000000..cc032a83 --- /dev/null +++ b/test/typeof2.ok @@ -0,0 +1,6 @@ +untyped +array +untyped +gawk: typeof2.awk:16: warning: function `test1' called with more arguments than declared +untyped +array diff --git a/test/typeof3.awk b/test/typeof3.awk new file mode 100644 index 00000000..d148f373 --- /dev/null +++ b/test/typeof3.awk @@ -0,0 +1,19 @@ +BEGIN { + x = @/xx/ + print typeof(x) + print x +} + +# this set may not really be needed for the test +BEGIN { + x = 4 + print typeof(@/xxx/) + print typeof(3) + print x +} + +BEGIN { + print typeof(x) + print typeof(a[1]) + a[1][2] # fatals on this +} diff --git a/test/typeof3.ok b/test/typeof3.ok new file mode 100644 index 00000000..8186ad9e --- /dev/null +++ b/test/typeof3.ok @@ -0,0 +1,9 @@ +regexp +xx +regexp +scalar_n +4 +scalar_n +untyped +gawk: typeof3.awk:18: fatal: attempt to use scalar `a["1"]' as an array +EXIT CODE: 2 diff --git a/test/typeof4.awk b/test/typeof4.awk new file mode 100644 index 00000000..62c2905c --- /dev/null +++ b/test/typeof4.awk @@ -0,0 +1,13 @@ +BEGIN{ a["x"]["y"]["z"]="scalar" ; walk_array(a, "a")} +function walk_array(arr, name, i, r) +{ + for (i in arr) { + r = typeof(arr[i]) +# printf("typeof(%s[%s]) = %s\n", name, i, r) > "/dev/stderr" + if (r == "array") { + walk_array(arr[i], name "[" i "]") + } else { + printf "%s[%s] = %s\n", name, i, arr[i] + } + } +} diff --git a/test/typeof4.ok b/test/typeof4.ok new file mode 100644 index 00000000..fca0263d --- /dev/null +++ b/test/typeof4.ok @@ -0,0 +1 @@ +a[x][y][z] = scalar |