diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | awkgram.c | 49 | ||||
-rw-r--r-- | awkgram.y | 49 | ||||
-rw-r--r-- | eval.c | 8 | ||||
-rw-r--r-- | test/ChangeLog | 5 | ||||
-rw-r--r-- | test/Makefile.am | 5 | ||||
-rw-r--r-- | test/Makefile.in | 10 | ||||
-rw-r--r-- | test/Maketests | 5 | ||||
-rw-r--r-- | test/inpref.awk | 9 | ||||
-rw-r--r-- | test/inpref.in | 2 | ||||
-rw-r--r-- | test/inpref.ok | 2 |
11 files changed, 111 insertions, 45 deletions
@@ -1,3 +1,15 @@ +2015-04-28 Arnold D. Robbins <arnold@skeeve.com> + + * awkgram.y (yylex): Rework the bracket handling from zero. + Thanks to Michal Jaegermann for yet another test case. + + Unrelated: + + * eval.c (setup_frame): Restore call-by-value for $0. This was + necessitated by the changes on 2014-11-11 for conserving + memory use. Thanks to Andrew Schorr for the report and isolating + the cause of the problem. + 2015-04-27 Arnold D. Robbins <arnold@skeeve.com> * awkgram.y (yylex): Make change of Jan 7 for parsing regexps @@ -5548,21 +5548,24 @@ yylex(void) thisline = NULL; if (want_regexp) { int in_brack = 0; /* count brackets, [[:alnum:]] allowed */ + int b_index = -1; + int cur_index = 0; + /* - * Counting brackets is non-trivial. [[] is ok, - * and so is [\]], with a point being that /[/]/ as a regexp - * constant has to work. + * Here is what's ok with brackets: + * + * [[] [^[] []] [^]] [.../...] + * [...\[...] [...\]...] [...\/...] + * + * (Remember that all of the above are inside /.../) + * + * The code for \ handles \[, \] and \/. * - * Do not count [ or ] if either one is preceded by a \. - * A `[' should be counted if - * a) it is the first one so far (in_brack == 0) - * b) it is the `[' in `[:' - * A ']' should be counted if not preceded by a \, since - * it is either closing `:]' or just a plain list. - * According to POSIX, []] is how you put a ] into a set. - * Try to handle that too. + * Otherwise, track the first open [ position, and if + * an embedded [ or ] occurs, allow it to pass through + * if it's right after the first [ or after [^. * - * The code for \ handles \[ and \]. + * Whew! */ want_regexp = false; @@ -5572,17 +5575,21 @@ yylex(void) if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) { case '[': - /* one day check for `.' and `=' too */ - if (nextc(false) == ':' || in_brack == 0) - in_brack++; - pushback(); - break; case ']': - if ((tok[-1] == '[' && tok[-2] != '\\') - || (tok[-2] == '[' && tok[-3] != '\\' && tok[-1] == '^')) - /* do nothing */; - else + cur_index = tok - tokstart; + if (in_brack > 0 + && (cur_index == b_index + 1 + || (cur_index == b_index + 2 && tok[-1] == '^'))) + ; /* do nothing */ + else if (c == '[') { + in_brack++; + if (in_brack == 1) + b_index = tok - tokstart; + } else { in_brack--; + if (in_brack == 0) + b_index = -1; + } break; case '\\': if ((c = nextc(false)) == END_FILE) { @@ -3216,21 +3216,24 @@ yylex(void) thisline = NULL; if (want_regexp) { int in_brack = 0; /* count brackets, [[:alnum:]] allowed */ + int b_index = -1; + int cur_index = 0; + /* - * Counting brackets is non-trivial. [[] is ok, - * and so is [\]], with a point being that /[/]/ as a regexp - * constant has to work. + * Here is what's ok with brackets: + * + * [[] [^[] []] [^]] [.../...] + * [...\[...] [...\]...] [...\/...] + * + * (Remember that all of the above are inside /.../) + * + * The code for \ handles \[, \] and \/. * - * Do not count [ or ] if either one is preceded by a \. - * A `[' should be counted if - * a) it is the first one so far (in_brack == 0) - * b) it is the `[' in `[:' - * A ']' should be counted if not preceded by a \, since - * it is either closing `:]' or just a plain list. - * According to POSIX, []] is how you put a ] into a set. - * Try to handle that too. + * Otherwise, track the first open [ position, and if + * an embedded [ or ] occurs, allow it to pass through + * if it's right after the first [ or after [^. * - * The code for \ handles \[ and \]. + * Whew! */ want_regexp = false; @@ -3240,17 +3243,21 @@ yylex(void) if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) { case '[': - /* one day check for `.' and `=' too */ - if (nextc(false) == ':' || in_brack == 0) - in_brack++; - pushback(); - break; case ']': - if ((tok[-1] == '[' && tok[-2] != '\\') - || (tok[-2] == '[' && tok[-3] != '\\' && tok[-1] == '^')) - /* do nothing */; - else + cur_index = tok - tokstart; + if (in_brack > 0 + && (cur_index == b_index + 1 + || (cur_index == b_index + 2 && tok[-1] == '^'))) + ; /* do nothing */ + else if (c == '[') { + in_brack++; + if (in_brack == 1) + b_index = tok - tokstart; + } else { in_brack--; + if (in_brack == 0) + b_index = -1; + } break; case '\\': if ((c = nextc(false)) == END_FILE) { @@ -1328,7 +1328,13 @@ setup_frame(INSTRUCTION *pc) if (m->type == Node_param_list) m = GET_PARAM(m->param_cnt); - + + /* $0 needs to be passed by value to a function */ + if (m == fields_arr[0]) { + DEREF(m); + m = dupnode(m); + } + switch (m->type) { case Node_var_new: case Node_var_array: diff --git a/test/ChangeLog b/test/ChangeLog index ebd1e3b0..fda382c1 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2015-04-27 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * Makefile.am (inpref): New test. + * inpref.awk, inpref.in, inpref.ok: New files. + 2015-04-27 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (regexpbrack2): New test. diff --git a/test/Makefile.am b/test/Makefile.am index 443245f6..c53e65c1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -411,6 +411,9 @@ EXTRA_DIST = \ icasers.awk \ icasers.in \ icasers.ok \ + inpref.awk \ + inpref.in \ + inpref.ok \ id.awk \ id.ok \ igncdym.awk \ @@ -1037,7 +1040,7 @@ BASIC_TESTS = \ gsubasgn gsubtest gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6 \ gsubtst7 gsubtst8 \ hex hsprint \ - inputred intest intprec iobug1 \ + inpref inputred intest intprec iobug1 \ leaddig leadnl litoct longsub longwrds \ manglprm math membug1 messages minusstr mmap8k mtchi18n \ nasty nasty2 negexp negrange nested nfldstr nfloop nfneg nfset nlfldsep \ diff --git a/test/Makefile.in b/test/Makefile.in index c73cfc80..caae2ba5 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -668,6 +668,9 @@ EXTRA_DIST = \ icasers.awk \ icasers.in \ icasers.ok \ + inpref.awk \ + inpref.in \ + inpref.ok \ id.awk \ id.ok \ igncdym.awk \ @@ -1293,7 +1296,7 @@ BASIC_TESTS = \ gsubasgn gsubtest gsubtst2 gsubtst3 gsubtst4 gsubtst5 gsubtst6 \ gsubtst7 gsubtst8 \ hex hsprint \ - inputred intest intprec iobug1 \ + inpref inputred intest intprec iobug1 \ leaddig leadnl litoct longsub longwrds \ manglprm math membug1 messages minusstr mmap8k mtchi18n \ nasty nasty2 negexp negrange nested nfldstr nfloop nfneg nfset nlfldsep \ @@ -2950,6 +2953,11 @@ hsprint: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +inpref: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + inputred: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index 75b9c0a6..61b0ec8e 100644 --- a/test/Maketests +++ b/test/Maketests @@ -405,6 +405,11 @@ hsprint: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +inpref: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + inputred: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/inpref.awk b/test/inpref.awk new file mode 100644 index 00000000..d64ffe7f --- /dev/null +++ b/test/inpref.awk @@ -0,0 +1,9 @@ +function test(x) { + print x + getline + print x +} + +{ + test($0) +} diff --git a/test/inpref.in b/test/inpref.in new file mode 100644 index 00000000..a32119c8 --- /dev/null +++ b/test/inpref.in @@ -0,0 +1,2 @@ +hello +goodbye diff --git a/test/inpref.ok b/test/inpref.ok new file mode 100644 index 00000000..317e9677 --- /dev/null +++ b/test/inpref.ok @@ -0,0 +1,2 @@ +hello +hello |