diff options
-rwxr-xr-x | ChangeLog | 7 | ||||
-rw-r--r-- | awkgram.c | 14 | ||||
-rw-r--r-- | awkgram.y | 14 | ||||
-rw-r--r-- | builtin.c | 22 | ||||
-rw-r--r-- | doc/ChangeLog | 4 | ||||
-rw-r--r-- | doc/gawk.texi | 9 | ||||
-rw-r--r-- | doc/gawktexi.in | 9 | ||||
-rw-r--r-- | test/ChangeLog | 5 | ||||
-rw-r--r-- | test/Makefile.am | 3 | ||||
-rw-r--r-- | test/Makefile.in | 8 | ||||
-rw-r--r-- | test/Maketests | 5 | ||||
-rw-r--r-- | test/arraytype.awk | 35 | ||||
-rw-r--r-- | test/arraytype.ok | 16 |
13 files changed, 147 insertions, 4 deletions
@@ -1,3 +1,10 @@ +2019-01-09 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * awkgram.y (tokentab): Indicate that typeof may take 2 arguments. + (snode): Add support for typeof's optional 2nd array argument. + * builtin.c (do_typeof): Add support for optional 2nd array arg, + returning flag info for scalars and backend array type for arrays. + 2019-01-08 Arnold D. Robbins <arnold@skeeve.com> * interpret.h (r_interpret): For a translatable string, only copy @@ -4745,7 +4745,7 @@ static const struct token tokentab[] = { {"systime", Op_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime, 0}, {"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower, 0}, {"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper, 0}, -{"typeof", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_typeof, 0}, +{"typeof", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_typeof, 0}, {"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0, 0}, {"xor", Op_builtin, LEX_BUILTIN, GAWKX, do_xor, MPF(xor)}, }; @@ -7034,10 +7034,20 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) arg->nexti->opcode = Op_push_arg; /* argument may be array */ } - } else if (r->builtin == do_isarray || r->builtin == do_typeof) { + } else if (r->builtin == do_isarray) { arg = subn->nexti; if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */ + } else if (r->builtin == do_typeof) { + arg = subn->nexti; + if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) + arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */ + if (nexp == 2) { /* 2nd argument there */ + arg = subn->nexti->lasti->nexti; /* 2nd arg list */ + ip = arg->lasti; + if (ip->opcode == Op_push) + ip->opcode = Op_push_array; + } #ifdef SUPPLY_INTDIV } else if (r->builtin == do_intdiv #ifdef HAVE_MPFR @@ -2280,7 +2280,7 @@ static const struct token tokentab[] = { {"systime", Op_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime, 0}, {"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower, 0}, {"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper, 0}, -{"typeof", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_typeof, 0}, +{"typeof", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_typeof, 0}, {"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0, 0}, {"xor", Op_builtin, LEX_BUILTIN, GAWKX, do_xor, MPF(xor)}, }; @@ -4569,10 +4569,20 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) arg->nexti->opcode = Op_push_arg; /* argument may be array */ } - } else if (r->builtin == do_isarray || r->builtin == do_typeof) { + } else if (r->builtin == do_isarray) { arg = subn->nexti; if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */ + } else if (r->builtin == do_typeof) { + arg = subn->nexti; + if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push) + arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */ + if (nexp == 2) { /* 2nd argument there */ + arg = subn->nexti->lasti->nexti; /* 2nd arg list */ + ip = arg->lasti; + if (ip->opcode == Op_push) + ip->opcode = Op_push_array; + } #ifdef SUPPLY_INTDIV } else if (r->builtin == do_intdiv #ifdef HAVE_MPFR @@ -4069,13 +4069,28 @@ do_typeof(int nargs) NODE *arg; char *res = NULL; bool deref = true; + NODE *dbg; + if (nargs == 2) { /* 2nd optional arg for debugging */ + dbg = POP_PARAM(); + if (dbg->type != Node_var_array) + fatal(_("typeof: second argument is not an array")); + assoc_clear(dbg); + } + else + dbg = NULL; arg = POP(); switch (arg->type) { case Node_var_array: /* Node_var_array is never UPREF'ed */ res = "array"; deref = false; + if (dbg) { + NODE *sub = make_string("array_type", 10); + NODE **lhs = assoc_lookup(dbg, sub); + unref(*lhs); + *lhs = make_string(arg->array_funcs->name, strlen(arg->array_funcs->name)); + } break; case Node_val: switch (fixtype(arg)->flags & (STRING|NUMBER|USER_INPUT|REGEX)) { @@ -4104,6 +4119,13 @@ do_typeof(int nargs) } break; } + if (dbg) { + const char *s = flags2str(arg->flags); + NODE *sub = make_string("flags", 5); + NODE **lhs = assoc_lookup(dbg, sub); + unref(*lhs); + *lhs = make_string(s, strlen(s)); + } break; case Node_var_new: res = "untyped"; diff --git a/doc/ChangeLog b/doc/ChangeLog index 4bbc906c..287f2cd1 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2019-01-09 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * gawktexi.in (Undocumented): Discuss typeof's optional 2nd argument. + 2019-01-08 Arnold D. Robbins <arnold@skeeve.com> * gawktexi.in (I18N Example): Add more explanation of how to diff --git a/doc/gawk.texi b/doc/gawk.texi index e661c6fa..44c00d00 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -4997,6 +4997,15 @@ NaN and Infinity values, instead of the special values @command{gawk} usually produces, as described in @ref{POSIX Floating Point Problems}. This is mainly useful for the included unit tests. +The @code{typeof()} built-in function +(@pxref{Type Functions}) +takes an optional second array argument that, if present, will be cleared +and populated with some information about the internal implementation of +the variable. This can be useful for debugging. At the moment, this +returns a textual version of the flags for scalar variables, and the +array back-end implementation type for arrays. This interface is subject +to change and may not be stable. + @end ignore @node Invoking Summary diff --git a/doc/gawktexi.in b/doc/gawktexi.in index f8850d9a..ac099ccc 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -4907,6 +4907,15 @@ NaN and Infinity values, instead of the special values @command{gawk} usually produces, as described in @ref{POSIX Floating Point Problems}. This is mainly useful for the included unit tests. +The @code{typeof()} built-in function +(@pxref{Type Functions}) +takes an optional second array argument that, if present, will be cleared +and populated with some information about the internal implementation of +the variable. This can be useful for debugging. At the moment, this +returns a textual version of the flags for scalar variables, and the +array back-end implementation type for arrays. This interface is subject +to change and may not be stable. + @end ignore @node Invoking Summary diff --git a/test/ChangeLog b/test/ChangeLog index b1d2e340..7f17f725 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2019-01-09 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * Makefile.am (EXTRA_DIST): New test: arraytype. + * arraytype.awk, arraytype.ok: New files. + 2018-12-24 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (inetdayt, inetdayu, inetecht, inetechu): Add diff --git a/test/Makefile.am b/test/Makefile.am index 7b42f8db..b4f50cec 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -76,6 +76,8 @@ EXTRA_DIST = \ arraysort.ok \ arraysort2.awk \ arraysort2.ok \ + arraytype.awk \ + arraytype.ok \ arrdbg.awk \ arrymem1.awk \ arrymem1.ok \ @@ -1294,6 +1296,7 @@ UNIX_TESTS = \ GAWK_EXT_TESTS = \ aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort arraysort2 \ + arraytype \ backw badargs beginfile1 beginfile2 binmode1 \ charasbytes colonwarn clos1way clos1way2 clos1way3 clos1way4 clos1way5 \ clos1way6 crlf \ diff --git a/test/Makefile.in b/test/Makefile.in index f2fa6c8e..b6adabdd 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -334,6 +334,8 @@ EXTRA_DIST = \ arraysort.ok \ arraysort2.awk \ arraysort2.ok \ + arraytype.awk \ + arraytype.ok \ arrdbg.awk \ arrymem1.awk \ arrymem1.ok \ @@ -1552,6 +1554,7 @@ UNIX_TESTS = \ GAWK_EXT_TESTS = \ aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort arraysort2 \ + arraytype \ backw badargs beginfile1 beginfile2 binmode1 \ charasbytes colonwarn clos1way clos1way2 clos1way3 clos1way4 clos1way5 \ clos1way6 crlf \ @@ -3945,6 +3948,11 @@ arraysort2: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +arraytype: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + backw: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index 08d92ba3..9ad8ade9 100644 --- a/test/Maketests +++ b/test/Maketests @@ -1269,6 +1269,11 @@ arraysort2: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +arraytype: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + backw: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/arraytype.awk b/test/arraytype.awk new file mode 100644 index 00000000..70fd72b0 --- /dev/null +++ b/test/arraytype.awk @@ -0,0 +1,35 @@ +BEGIN { + # N.B. This relies upon the undocumented 2nd argument to typeof + x[0] = 0 + print typeof(x, a) + print a["array_type"] + + # make sure it resets + delete x[0] + print typeof(x, a) + print a["array_type"] + + x["fubar"] = 0 + print typeof(x, a) + print a["array_type"] + + delete x["fubar"] + print typeof(x, a) + print a["array_type"] + + x[-2] = 0 + print typeof(x, a) + print a["array_type"] + + delete x[-2] + print typeof(x, a) + print a["array_type"] + + x[2] = 0 + print typeof(x, a) + print a["array_type"] + + delete x + print typeof(x, a) + print a["array_type"] +} diff --git a/test/arraytype.ok b/test/arraytype.ok new file mode 100644 index 00000000..6595bb89 --- /dev/null +++ b/test/arraytype.ok @@ -0,0 +1,16 @@ +array +cint +array +null +array +str +array +null +array +int +array +null +array +cint +array +null |