aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--profile.c46
-rw-r--r--test/ChangeLog5
-rw-r--r--test/Makefile.am10
-rw-r--r--test/Makefile.in10
-rw-r--r--test/profile6.awk7
-rw-r--r--test/profile6.ok10
7 files changed, 80 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 8f4657a8..a74dadd9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,15 @@
* configure: Regenerated after fix to m4/readline.m4.
+ Unrelated; fixes to profiling. Thanks to Hermann Peifer and
+ Manuel Collado for pointing out problems:
+
+ * profile.c (pprint): For Op_unary_minus, parenthesize -(-x)
+ correctly.
+ (prec_level): Get the levels right (checked the grammar).
+ (is_unary_minus): New function.
+ (pp_concat): Add checks for unary minus; needs to be parenthesized.
+
2014-10-29 Arnold D. Robbins <arnold@skeeve.com>
* dfa.c: Sync with GNU grep. Again, again.
diff --git a/profile.c b/profile.c
index a5ed381b..ed17e62b 100644
--- a/profile.c
+++ b/profile.c
@@ -395,7 +395,8 @@ cleanup:
case Op_unary_minus:
case Op_not:
t1 = pp_pop();
- if (is_binary(t1->type))
+ if (is_binary(t1->type)
+ || (((OPCODE) t1->type) == pc->opcode && pc->opcode == Op_unary_minus))
pp_parenthesize(t1);
/* optypes table (eval.c) includes space after ! */
@@ -1000,25 +1001,25 @@ prec_level(int type)
case Op_func_call:
case Op_K_delete_loop:
case Op_builtin:
- return 15;
+ return 16;
case Op_field_spec:
case Op_field_spec_lhs:
- return 14;
-
- case Op_exp:
- case Op_exp_i:
- return 13;
+ return 15;
case Op_preincrement:
case Op_predecrement:
case Op_postincrement:
case Op_postdecrement:
- return 12;
+ return 14;
+
+ case Op_exp:
+ case Op_exp_i:
+ return 13;
case Op_unary_minus:
case Op_not:
- return 11;
+ return 12;
case Op_times:
case Op_times_i:
@@ -1026,23 +1027,26 @@ prec_level(int type)
case Op_quotient_i:
case Op_mod:
case Op_mod_i:
- return 10;
+ return 11;
case Op_plus:
case Op_plus_i:
case Op_minus:
case Op_minus_i:
- return 9;
+ return 10;
case Op_concat:
case Op_assign_concat:
- return 8;
+ return 9;
case Op_equal:
case Op_notequal:
case Op_greater:
+ case Op_less:
case Op_leq:
case Op_geq:
+ return 8;
+
case Op_match:
case Op_nomatch:
return 7;
@@ -1051,7 +1055,6 @@ prec_level(int type)
case Op_K_getline_redir:
return 6;
- case Op_less:
case Op_in_array:
return 5;
@@ -1360,6 +1363,14 @@ pp_list(int nargs, const char *paren, const char *delim)
return str;
}
+/* is_unary_minus --- return true if string starts with unary minus */
+
+static bool
+is_unary_minus(const char *str)
+{
+ return str[0] == '-' && str[1] != '-';
+}
+
/* pp_concat --- handle concatenation and correct parenthesizing of expressions */
static char *
@@ -1401,7 +1412,12 @@ pp_concat(int nargs)
pl_l = prec_level(pp_args[i]->type);
pl_r = prec_level(pp_args[i+1]->type);
- if (is_scalar(pp_args[i]->type) && is_scalar(pp_args[i+1]->type)) {
+ if (i >= 2 && is_unary_minus(r->pp_str)) {
+ *s++ = '(';
+ memcpy(s, r->pp_str, r->pp_len);
+ s += r->pp_len;
+ *s++ = ')';
+ } else if (is_scalar(pp_args[i]->type) && is_scalar(pp_args[i+1]->type)) {
memcpy(s, r->pp_str, r->pp_len);
s += r->pp_len;
} else if (pl_l <= pl_r || is_scalar(pp_args[i+1]->type)) {
@@ -1423,7 +1439,7 @@ pp_concat(int nargs)
pl_l = prec_level(pp_args[nargs-1]->type);
pl_r = prec_level(pp_args[nargs]->type);
r = pp_args[nargs];
- if (pl_l >= pl_r && ! is_scalar(pp_args[nargs]->type)) {
+ if (is_unary_minus(r->pp_str) || ((pl_l >= pl_r && ! is_scalar(pp_args[nargs]->type)))) {
*s++ = '(';
memcpy(s, r->pp_str, r->pp_len);
s += r->pp_len;
diff --git a/test/ChangeLog b/test/ChangeLog
index f85de800..c9fe4a27 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,8 @@
+2014-10-30 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (profile6): New test.
+ * profile6.awk, profile6.ok: New files.
+
2014-10-17 Andrew J. Schorr <aschorr@telemetry-investments.com>
* Makefile.am (profile1, testext): Use explicit ./foo.awk to avoid
diff --git a/test/Makefile.am b/test/Makefile.am
index f0965d77..15539504 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -706,6 +706,8 @@ EXTRA_DIST = \
profile4.ok \
profile5.awk \
profile5.ok \
+ profile6.awk \
+ profile6.ok \
prt1eval.awk \
prt1eval.ok \
prtoeval.awk \
@@ -1017,7 +1019,7 @@ GAWK_EXT_TESTS = \
manyfiles match1 match2 match3 mbstr1 \
nastyparm next nondec nondec2 \
patsplit posix printfbad1 printfbad2 printfbad3 printhuge procinfs \
- profile1 profile2 profile3 profile4 profile5 pty1 \
+ profile1 profile2 profile3 profile4 profile5 profile6 pty1 \
rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \
rsstart2 rsstart3 rstest6 shadow sortfor sortu split_after_fpat \
splitarg4 strftime \
@@ -1699,6 +1701,12 @@ profile5:
@sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+profile6:
+ @echo $@
+ @GAWK_NO_PP_RUN=1 $(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
+ @sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
posix2008sub:
@echo $@
@$(AWK) --posix -f "$(srcdir)"/$@.awk > _$@ 2>&1
diff --git a/test/Makefile.in b/test/Makefile.in
index 3df34522..9e56dbf3 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -952,6 +952,8 @@ EXTRA_DIST = \
profile4.ok \
profile5.awk \
profile5.ok \
+ profile6.awk \
+ profile6.ok \
prt1eval.awk \
prt1eval.ok \
prtoeval.awk \
@@ -1262,7 +1264,7 @@ GAWK_EXT_TESTS = \
manyfiles match1 match2 match3 mbstr1 \
nastyparm next nondec nondec2 \
patsplit posix printfbad1 printfbad2 printfbad3 printhuge procinfs \
- profile1 profile2 profile3 profile4 profile5 pty1 \
+ profile1 profile2 profile3 profile4 profile5 profile6 pty1 \
rebuf regnul1 regnul2 regx8bit reginttrad reint reint2 rsgetline rsglstdin rsstart1 \
rsstart2 rsstart3 rstest6 shadow sortfor sortu split_after_fpat \
splitarg4 strftime \
@@ -2123,6 +2125,12 @@ profile5:
@sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+profile6:
+ @echo $@
+ @GAWK_NO_PP_RUN=1 $(AWK) --profile=ap-$@.out -f "$(srcdir)"/$@.awk > /dev/null
+ @sed 1,2d < ap-$@.out > _$@; rm ap-$@.out
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
posix2008sub:
@echo $@
@$(AWK) --posix -f "$(srcdir)"/$@.awk > _$@ 2>&1
diff --git a/test/profile6.awk b/test/profile6.awk
new file mode 100644
index 00000000..754f8ae6
--- /dev/null
+++ b/test/profile6.awk
@@ -0,0 +1,7 @@
+BEGIN {
+ x = 3
+ print -(-x)
+ Q = "|"
+ print -3 Q (-4)
+ print -3 Q (-4) (-5)
+}
diff --git a/test/profile6.ok b/test/profile6.ok
new file mode 100644
index 00000000..86ff68a6
--- /dev/null
+++ b/test/profile6.ok
@@ -0,0 +1,10 @@
+ # BEGIN rule(s)
+
+ BEGIN {
+ x = 3
+ print -(-x)
+ Q = "|"
+ print -3 Q (-4)
+ print -3 Q (-4) (-5)
+ }
+