>From af73836848da7e391bcfc06008a34db5aa9ad304 Mon Sep 17 00:00:00 2001 From: Assaf Gordon Date: Fri, 15 Sep 2017 00:36:13 -0600 Subject: [PATCH] expr: add detailed syntax error messages Show offending argument instead of a generic 'syntax error' message. Suggested by Bernhard Voelker in https://bugs.gnu.org/28461#13 . * src/expr.c (syntax_error): Remove. (required_more_args): New function. (eval7, main): Replace syntax_error call with detailed die message. * tests/misc/expr.pl: Add tests for new messages. --- src/expr.c | 36 +++++++++++++++++++++++------------- tests/misc/expr.pl | 19 +++++++++++++++++-- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/expr.c b/src/expr.c index 194b54b..a13a29a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -413,12 +413,6 @@ or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred.\n\ exit (status); } -/* Report a syntax error and exit. */ -static void -syntax_error (void) -{ - die (EXPR_INVALID, 0, _("syntax error")); -} #if ! HAVE_GMP /* Report an integer overflow for operation OP and exit. */ @@ -465,7 +459,9 @@ main (int argc, char **argv) v = eval (true); if (!nomoreargs ()) - syntax_error (); + die (EXPR_INVALID, 0, _("syntax error: unexpected argument %s"), + quotearg_n_style (0, locale_quoting_style, *args)); + printv (v); return null (v); @@ -659,6 +655,18 @@ nomoreargs (void) return *args == 0; } +/* Report missing operand. + There is an implicit assumption that there was a previous argument, + and (args-1) is valid. */ +static void +require_more_args (void) +{ + if (nomoreargs ()) + die (EXPR_INVALID, 0, _("syntax error: missing argument after %s"), + quotearg_n_style (0, locale_quoting_style, *(args-1))); +} + + #ifdef EVAL_TRACE /* Print evaluation trace and args remaining. */ @@ -759,19 +767,22 @@ eval7 (bool evaluate) #ifdef EVAL_TRACE trace ("eval7"); #endif - if (nomoreargs ()) - syntax_error (); + require_more_args (); if (nextarg ("(")) { v = eval (evaluate); + if (nomoreargs ()) + die (EXPR_INVALID, 0, _("syntax error: expecting ')' after %s"), + quotearg_n_style (0, locale_quoting_style, *(args-1))); if (!nextarg (")")) - syntax_error (); + die (EXPR_INVALID, 0, _("syntax error: expecting ')' instead of %s"), + quotearg_n_style (0, locale_quoting_style, *args)); return v; } if (nextarg (")")) - syntax_error (); + die (EXPR_INVALID, 0, _("syntax error: unexpected ')'")); return str_value (*args++); } @@ -792,8 +803,7 @@ eval6 (bool evaluate) #endif if (nextarg ("+")) { - if (nomoreargs ()) - syntax_error (); + require_more_args (); return str_value (*args++); } else if (nextarg ("length")) diff --git a/tests/misc/expr.pl b/tests/misc/expr.pl index c0d6f7c..b88914e 100755 --- a/tests/misc/expr.pl +++ b/tests/misc/expr.pl @@ -164,8 +164,8 @@ my @Tests = ['bre61', '"acd" : "a\\(b\\)?c\\1d"', {OUT => ''}, {EXIT => 1}], ['bre62', '-- "-5" : "-\\{0,1\\}[0-9]*\$"', {OUT => '2'}], - ['fail-b', '9 9', {ERR => "$prog: syntax error\n"}, - {EXIT => 2}], + ['fail-b', '9 9', + {ERR => "$prog: syntax error: unexpected argument '9'\n"}, {EXIT => 2}], ['fail-c', {ERR => "$prog: missing operand\n" . "Try '$prog --help' for more information.\n"}, {EXIT => 2}], @@ -176,6 +176,21 @@ my @Tests = ['bignum-sub2', "$big_sum - $big", {OUT => $big_p1}], ['bignum-mul', "$big_p1 '*' $big", {OUT => $big_prod}], ['bignum-div', "$big_prod / $big", {OUT => $big_p1}], + + + # Test syntax error messages + ['se1', "2 a", {EXIT=>2}, + {ERR=>"$prog: syntax error: unexpected argument 'a'\n"}], + ['se2', "2 '+'", {EXIT=>2}, + {ERR=>"$prog: syntax error: missing argument after '+'\n"}], + ['se3', "2 :", {EXIT=>2}, + {ERR=>"$prog: syntax error: missing argument after ':'\n"}], + ['se4', "length", {EXIT=>2}, + {ERR=>"$prog: syntax error: missing argument after 'length'\n"}], + ['se5', "'(' 2 ", {EXIT=>2}, + {ERR=>"$prog: syntax error: expecting ')' after '2'\n"}], + ['se6', "'(' 2 a", {EXIT=>2}, + {ERR=>"$prog: syntax error: expecting ')' instead of 'a'\n"}], ); # If using big numbers fails, remove all /^bignum-/ tests -- 2.7.4