summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2015-04-28 16:40:51 +0300
committerArnold D. Robbins <arnold@skeeve.com>2015-04-28 16:40:51 +0300
commitb4ef28f58688cf3c3a5878c595b6582144ee2cf1 (patch)
tree215345f53d438d6aa45fdf1a0c20f446ef7be2a8
parent8dedda4944d453e2b9fe3e6d0234f7cae1e894c7 (diff)
parentf088a3efc8aefc47f0bfe7824732aae4283b4c15 (diff)
downloadgawk-b4ef28f58688cf3c3a5878c595b6582144ee2cf1.tar.gz
Merge branch 'gawk-4.1-stable'
-rw-r--r--ChangeLog12
-rw-r--r--awkgram.c49
-rw-r--r--awkgram.y49
-rw-r--r--eval.c8
-rw-r--r--test/ChangeLog5
-rw-r--r--test/Makefile.am5
-rw-r--r--test/Makefile.in10
-rw-r--r--test/Maketests5
-rw-r--r--test/inpref.awk9
-rw-r--r--test/inpref.in2
-rw-r--r--test/inpref.ok2
11 files changed, 111 insertions, 45 deletions
diff --git a/ChangeLog b/ChangeLog
index d656f5c9..171fc155 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/awkgram.c b/awkgram.c
index 68540e88..ea8c48d8 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -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) {
diff --git a/awkgram.y b/awkgram.y
index 1102a572..3b555a6e 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -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) {
diff --git a/eval.c b/eval.c
index 2d820580..b50bcea8 100644
--- a/eval.c
+++ b/eval.c
@@ -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