diff options
author | Akim Demaille <akim.demaille@gmail.com> | 2021-11-07 09:27:52 +0100 |
---|---|---|
committer | Akim Demaille <akim.demaille@gmail.com> | 2021-11-07 09:52:05 +0100 |
commit | 6571c2d1b134bd04d81f1426c08985407e8c7087 (patch) | |
tree | fe0328628246b1db6b2a661c6738a1940a5bfac1 | |
parent | c95d0dd5f54b98825e4cfe00a807db78a073e376 (diff) | |
download | bison-6571c2d1b134bd04d81f1426c08985407e8c7087.tar.gz |
warnings: don't complain about m4_foo and b4_foo when from the user
Currently, occurrences of these identifiers in the user's input yield
spurious warnings.
To tell the difference between a legitimate m4_foo from the user, and
a bad m4_foo coming from a non-evaluated macro of a skeleton, escape
the user's identifiers as m4@'_foo. We already use @' as a special
sequence to be stripped from the skeleton's output.
See <https://lists.gnu.org/r/bug-bison/2021-10/msg00026.html> and
previous commit ("warnings: be less picky about occurrences of m4_/b4_
in the output").
* src/flex-scanner.h (OBSTACK_SGROW): New.
* src/output.c (output_escaped): Escape m4_ and b4_.
* src/scan-code.l: Likewise.
* src/system.h (obstack_escape): Likewise.
And rewrite as a function.
* tests/skeletons.at (Suspicious sequences): Make sure the user can
use m4_foo/b4_foo without spurious warnings.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | src/flex-scanner.h | 3 | ||||
-rw-r--r-- | src/output.c | 27 | ||||
-rw-r--r-- | src/scan-code.l | 3 | ||||
-rw-r--r-- | src/system.h | 59 | ||||
-rw-r--r-- | tests/skeletons.at | 24 |
6 files changed, 94 insertions, 25 deletions
@@ -2,6 +2,9 @@ GNU Bison NEWS * Noteworthy changes in release ?.? (????-??-??) [?] + Fixed portability issues of the test suite on Solaris. + + Fixed spurious warnings about input containing `m4_` or `b4_`. * Noteworthy changes in release 3.8.2 (2021-09-25) [stable] diff --git a/src/flex-scanner.h b/src/flex-scanner.h index 238ca881..08c0e62c 100644 --- a/src/flex-scanner.h +++ b/src/flex-scanner.h @@ -106,6 +106,9 @@ static struct obstack obstack_for_string; # define STRING_GROW() \ obstack_grow (&obstack_for_string, yytext, yyleng) +# define STRING_SGROW(String) \ + obstack_sgrow (&obstack_for_string, String) + # define STRING_FINISH() \ (last_string = obstack_finish0 (&obstack_for_string)) diff --git a/src/output.c b/src/output.c index 4b1bb0d8..07234f2a 100644 --- a/src/output.c +++ b/src/output.c @@ -104,20 +104,45 @@ GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_symbol_number_table, symbol_number) GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_item_number_table, item_number) GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_state_number_table, state_number) + /*----------------------------------------------------------------. | Print to OUT a representation of CP quoted and escaped for M4. | +| | +| Keep sync'ed with obstack_escape. | `----------------------------------------------------------------*/ static void output_escaped (FILE *out, const char *cp) { - for (; *cp; cp++) + for (; *cp; ++cp) switch (*cp) { case '$': fputs ("$][", out); break; case '@': fputs ("@@", out); break; case '[': fputs ("@{", out); break; case ']': fputs ("@}", out); break; + + case 'b': + if (STRPREFIX_LIT ("b4_", cp)) + { + fputs ("b4@'_", out); + cp += strlen ("b4_") - 1; + break; + } + else + goto append; + + case 'm': + if (STRPREFIX_LIT ("m4_", cp)) + { + fputs ("m4@'_", out); + cp += strlen ("m4_") - 1; + break; + } + else + goto append; + + append: default: fputc (*cp, out); break; } } diff --git a/src/scan-code.l b/src/scan-code.l index fced37d2..e3e765c8 100644 --- a/src/scan-code.l +++ b/src/scan-code.l @@ -197,6 +197,9 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$" <*> { + "b4_" STRING_SGROW ("b4@'_"); + "m4_" STRING_SGROW ("m4@'_"); + /* Escape M4 quoting characters in C code. */ [$@\[\]] obstack_escape (&obstack_for_string, yytext); diff --git a/src/system.h b/src/system.h index bbdf9fd0..630ef646 100644 --- a/src/system.h +++ b/src/system.h @@ -204,24 +204,53 @@ max_int (int a, int b) } while (0) -/* Output Str escaped for our postprocessing (i.e., escape M4 special +/* Output CP escaped for our postprocessing (i.e., escape M4 special characters). - For instance "[foo]" -> "@{foo@}", "$$" -> "$][$][". */ + For instance "[foo]" -> "@{foo@}", "$$" -> "$][$][". -# define obstack_escape(Obs, Str) \ - do { \ - char const *p__; \ - for (p__ = Str; *p__; p__++) \ - switch (*p__) \ - { \ - case '$': obstack_sgrow (Obs, "$]["); break; \ - case '@': obstack_sgrow (Obs, "@@" ); break; \ - case '[': obstack_sgrow (Obs, "@{" ); break; \ - case ']': obstack_sgrow (Obs, "@}" ); break; \ - default: obstack_1grow (Obs, *p__ ); break; \ - } \ - } while (0) + All the user's input passed to m4 is processed by this function or + by output_escaped, except user actions. Because of the specific + handling of @$, @1, etc., user actions are processed (and escaped) + by scan-code.l. + + Keep output_escaped and obstack_escape sync'ed. + */ + +static inline void +obstack_escape (struct obstack* obs, const char *cp) +{ + for (; *cp; ++cp) + switch (*cp) + { + case '$': obstack_sgrow (obs, "$]["); break; + case '@': obstack_sgrow (obs, "@@" ); break; + case '[': obstack_sgrow (obs, "@{" ); break; + case ']': obstack_sgrow (obs, "@}" ); break; + case 'b': + if (STRPREFIX_LIT ("b4_", cp)) + { + obstack_sgrow (obs, "b4@'_"); + cp += strlen ("b4_") - 1; + break; + } + else + goto append; + + case 'm': + if (STRPREFIX_LIT ("m4_", cp)) + { + obstack_sgrow (obs, "m4@'_"); + cp += strlen ("m4_") - 1; + break; + } + else + goto append; + + append: + default: obstack_1grow (obs, *cp); break; + } +} /* Output Str both quoted for M4 (i.e., embed in [[...]]), and escaped diff --git a/tests/skeletons.at b/tests/skeletons.at index 30f25a61..8cd87f96 100644 --- a/tests/skeletons.at +++ b/tests/skeletons.at @@ -332,14 +332,18 @@ AT_CLEANUP AT_SETUP([[Suspicious sequences]]) +# <https://lists.gnu.org/r/bug-bison/2021-10/msg00026.html>. + +# We must escape m4_foo as m4@&t@_foo to avoid Autotest's protection +# against its own suspicious sequences. AT_DATA([[skel.c]], [[m4@&t@_include(b4_skeletonsdir/[c.m4]) m4@&t@_divert_push(0)d@&t@nl @output(b4_parser_file_name@)d@&t@nl ]b4_user_pre_prologue[ ]b4_user_post_prologue[ -b4_unevaluated -m4@&t@_unevaluated +b4_poison +m4@&t@_poison ]b4_epilogue[ m4@&t@_divert_pop(0) @@ -348,19 +352,21 @@ m4@&t@_divert_pop(0) AT_DATA([[input1.y]], [[%skeleton "./skel.c" %{ - myb4_unevaluated - mym4_unevaluated + myb4_user + mym4_user + b4_user + m4@&t@_user %} %% -start: ; +b4_user: "b4_user"; %% -myb4_unevaluated -mym4_unevaluated +b4_user +m4@&t@_user ]]) AT_BISON_CHECK([[input1.y]], [], [], -[[input1.tab.c:10: warning: suspicious sequence in the output: b4_unevaluated [-Wother] -input1.tab.c:11: warning: suspicious sequence in the output: m4@&t@_unevaluated [-Wother] +[[input1.tab.c:12: warning: suspicious sequence in the output: b4_poison [-Wother] +input1.tab.c:13: warning: suspicious sequence in the output: m4@&t@_poison [-Wother] ]]) |