diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | awkgram.c | 49 | ||||
-rw-r--r-- | awkgram.y | 49 | ||||
-rw-r--r-- | eval.c | 8 | ||||
-rw-r--r-- | test/ChangeLog | 11 | ||||
-rw-r--r-- | test/Makefile.am | 10 | ||||
-rw-r--r-- | test/Makefile.in | 20 | ||||
-rw-r--r-- | test/Maketests | 10 | ||||
-rw-r--r-- | test/inpref.awk | 9 | ||||
-rw-r--r-- | test/inpref.in | 2 | ||||
-rw-r--r-- | test/inpref.ok | 2 | ||||
-rw-r--r-- | test/regexpbrack2.awk | 2 | ||||
-rw-r--r-- | test/regexpbrack2.in | 2 | ||||
-rw-r--r-- | test/regexpbrack2.ok | 2 |
14 files changed, 146 insertions, 47 deletions
@@ -1,3 +1,20 @@ +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 + work better. Thanks to Nelson Beebe. + 2015-04-26 Arnold D. Robbins <arnold@skeeve.com> * dfa.c: Sync with grep. @@ -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[-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[-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 b84345f9..fda382c1 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,14 @@ +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. + * regexpbrack2.awk, regexpbrack2.in, regexpbrack2.ok: New files. + Thanks to Nelson Beebe. + 2015-04-16 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (shadowbuiltin): New test. diff --git a/test/Makefile.am b/test/Makefile.am index d700f475..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 \ @@ -783,6 +786,9 @@ EXTRA_DIST = \ regexpbrack.awk \ regexpbrack.in \ regexpbrack.ok \ + regexpbrack2.awk \ + regexpbrack2.in \ + regexpbrack2.ok \ regexprange.awk \ regexprange.ok \ reginttrad.awk \ @@ -1034,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 \ @@ -1045,7 +1051,7 @@ BASIC_TESTS = \ paramdup paramres paramtyp paramuninitglobal parse1 parsefld parseme \ pcntplus posix2008sub prdupval prec printf0 printf1 prmarscl prmreuse \ prt1eval prtoeval \ - rand randtest range1 rebt8b1 redfilnm regeq regexpbrack regexprange regrange reindops \ + rand randtest range1 rebt8b1 redfilnm regeq regexpbrack regexpbrack2 regexprange regrange reindops \ reparse resplit rri1 rs rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 \ rstest3 rstest4 rstest5 rswhite \ scalar sclforin sclifin sortempty sortglos splitargv splitarr splitdef \ diff --git a/test/Makefile.in b/test/Makefile.in index b3a07283..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 \ @@ -1040,6 +1043,9 @@ EXTRA_DIST = \ regexpbrack.awk \ regexpbrack.in \ regexpbrack.ok \ + regexpbrack2.awk \ + regexpbrack2.in \ + regexpbrack2.ok \ regexprange.awk \ regexprange.ok \ reginttrad.awk \ @@ -1290,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 \ @@ -1301,7 +1307,7 @@ BASIC_TESTS = \ paramdup paramres paramtyp paramuninitglobal parse1 parsefld parseme \ pcntplus posix2008sub prdupval prec printf0 printf1 prmarscl prmreuse \ prt1eval prtoeval \ - rand randtest range1 rebt8b1 redfilnm regeq regexpbrack regexprange regrange reindops \ + rand randtest range1 rebt8b1 redfilnm regeq regexpbrack regexpbrack2 regexprange regrange reindops \ reparse resplit rri1 rs rsnul1nl rsnulbig rsnulbig2 rstest1 rstest2 \ rstest3 rstest4 rstest5 rswhite \ scalar sclforin sclifin sortempty sortglos splitargv splitarr splitdef \ @@ -2947,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: $$? >>_$@ @@ -3254,6 +3265,11 @@ regexpbrack: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +regexpbrack2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + regexprange: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index aa328bf7..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: $$? >>_$@ @@ -712,6 +717,11 @@ regexpbrack: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +regexpbrack2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + regexprange: @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 diff --git a/test/regexpbrack2.awk b/test/regexpbrack2.awk new file mode 100644 index 00000000..81424844 --- /dev/null +++ b/test/regexpbrack2.awk @@ -0,0 +1,2 @@ +NR == 1 { gsub(/\\\\[;?!,()<>|+@%\]\[]/, " ") ; print "\"" $0 "\"" } +NR == 2 { gsub(/\\\\[;?!,()<>|+@%\]\[^]/, " ") ; print "\"" $0 "\"" } diff --git a/test/regexpbrack2.in b/test/regexpbrack2.in new file mode 100644 index 00000000..42888dd0 --- /dev/null +++ b/test/regexpbrack2.in @@ -0,0 +1,2 @@ +test: \\; \\? \\! +test: \\; \\? \\! diff --git a/test/regexpbrack2.ok b/test/regexpbrack2.ok new file mode 100644 index 00000000..9c2a2922 --- /dev/null +++ b/test/regexpbrack2.ok @@ -0,0 +1,2 @@ +"test: " +"test: " |