mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-22 18:53:04 +00:00
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.
This commit is contained in:
3
NEWS
3
NEWS
@@ -2,6 +2,9 @@ GNU Bison NEWS
|
|||||||
|
|
||||||
* Noteworthy changes in release ?.? (????-??-??) [?]
|
* 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]
|
* Noteworthy changes in release 3.8.2 (2021-09-25) [stable]
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ static struct obstack obstack_for_string;
|
|||||||
# define STRING_GROW() \
|
# define STRING_GROW() \
|
||||||
obstack_grow (&obstack_for_string, yytext, yyleng)
|
obstack_grow (&obstack_for_string, yytext, yyleng)
|
||||||
|
|
||||||
|
# define STRING_SGROW(String) \
|
||||||
|
obstack_sgrow (&obstack_for_string, String)
|
||||||
|
|
||||||
# define STRING_FINISH() \
|
# define STRING_FINISH() \
|
||||||
(last_string = obstack_finish0 (&obstack_for_string))
|
(last_string = obstack_finish0 (&obstack_for_string))
|
||||||
|
|
||||||
|
|||||||
27
src/output.c
27
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_item_number_table, item_number)
|
||||||
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_state_number_table, state_number)
|
GENERATE_MUSCLE_INSERT_TABLE (muscle_insert_state_number_table, state_number)
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------.
|
/*----------------------------------------------------------------.
|
||||||
| Print to OUT a representation of CP quoted and escaped for M4. |
|
| Print to OUT a representation of CP quoted and escaped for M4. |
|
||||||
|
| |
|
||||||
|
| Keep sync'ed with obstack_escape. |
|
||||||
`----------------------------------------------------------------*/
|
`----------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
output_escaped (FILE *out, const char *cp)
|
output_escaped (FILE *out, const char *cp)
|
||||||
{
|
{
|
||||||
for (; *cp; cp++)
|
for (; *cp; ++cp)
|
||||||
switch (*cp)
|
switch (*cp)
|
||||||
{
|
{
|
||||||
case '$': fputs ("$][", out); break;
|
case '$': fputs ("$][", out); break;
|
||||||
case '@': fputs ("@@", out); break;
|
case '@': fputs ("@@", out); break;
|
||||||
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;
|
default: fputc (*cp, out); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,6 +197,9 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$"
|
|||||||
|
|
||||||
<*>
|
<*>
|
||||||
{
|
{
|
||||||
|
"b4_" STRING_SGROW ("b4@'_");
|
||||||
|
"m4_" STRING_SGROW ("m4@'_");
|
||||||
|
|
||||||
/* Escape M4 quoting characters in C code. */
|
/* Escape M4 quoting characters in C code. */
|
||||||
[$@\[\]] obstack_escape (&obstack_for_string, yytext);
|
[$@\[\]] obstack_escape (&obstack_for_string, yytext);
|
||||||
|
|
||||||
|
|||||||
59
src/system.h
59
src/system.h
@@ -204,24 +204,53 @@ max_int (int a, int b)
|
|||||||
} while (0)
|
} 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).
|
characters).
|
||||||
|
|
||||||
For instance "[foo]" -> "@{foo@}", "$$" -> "$][$][". */
|
For instance "[foo]" -> "@{foo@}", "$$" -> "$][$][".
|
||||||
|
|
||||||
# define obstack_escape(Obs, Str) \
|
All the user's input passed to m4 is processed by this function or
|
||||||
do { \
|
by output_escaped, except user actions. Because of the specific
|
||||||
char const *p__; \
|
handling of @$, @1, etc., user actions are processed (and escaped)
|
||||||
for (p__ = Str; *p__; p__++) \
|
by scan-code.l.
|
||||||
switch (*p__) \
|
|
||||||
{ \
|
Keep output_escaped and obstack_escape sync'ed.
|
||||||
case '$': obstack_sgrow (Obs, "$]["); break; \
|
*/
|
||||||
case '@': obstack_sgrow (Obs, "@@" ); break; \
|
|
||||||
case '[': obstack_sgrow (Obs, "@{" ); break; \
|
static inline void
|
||||||
case ']': obstack_sgrow (Obs, "@}" ); break; \
|
obstack_escape (struct obstack* obs, const char *cp)
|
||||||
default: obstack_1grow (Obs, *p__ ); break; \
|
{
|
||||||
} \
|
for (; *cp; ++cp)
|
||||||
} while (0)
|
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
|
/* Output Str both quoted for M4 (i.e., embed in [[...]]), and escaped
|
||||||
|
|||||||
@@ -332,14 +332,18 @@ AT_CLEANUP
|
|||||||
|
|
||||||
AT_SETUP([[Suspicious sequences]])
|
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]],
|
AT_DATA([[skel.c]],
|
||||||
[[m4@&t@_include(b4_skeletonsdir/[c.m4])
|
[[m4@&t@_include(b4_skeletonsdir/[c.m4])
|
||||||
m4@&t@_divert_push(0)d@&t@nl
|
m4@&t@_divert_push(0)d@&t@nl
|
||||||
@output(b4_parser_file_name@)d@&t@nl
|
@output(b4_parser_file_name@)d@&t@nl
|
||||||
]b4_user_pre_prologue[
|
]b4_user_pre_prologue[
|
||||||
]b4_user_post_prologue[
|
]b4_user_post_prologue[
|
||||||
b4_unevaluated
|
b4_poison
|
||||||
m4@&t@_unevaluated
|
m4@&t@_poison
|
||||||
]b4_epilogue[
|
]b4_epilogue[
|
||||||
|
|
||||||
m4@&t@_divert_pop(0)
|
m4@&t@_divert_pop(0)
|
||||||
@@ -348,19 +352,21 @@ m4@&t@_divert_pop(0)
|
|||||||
AT_DATA([[input1.y]],
|
AT_DATA([[input1.y]],
|
||||||
[[%skeleton "./skel.c"
|
[[%skeleton "./skel.c"
|
||||||
%{
|
%{
|
||||||
myb4_unevaluated
|
myb4_user
|
||||||
mym4_unevaluated
|
mym4_user
|
||||||
|
b4_user
|
||||||
|
m4@&t@_user
|
||||||
%}
|
%}
|
||||||
%%
|
%%
|
||||||
start: ;
|
b4_user: "b4_user";
|
||||||
%%
|
%%
|
||||||
myb4_unevaluated
|
b4_user
|
||||||
mym4_unevaluated
|
m4@&t@_user
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK([[input1.y]], [], [],
|
AT_BISON_CHECK([[input1.y]], [], [],
|
||||||
[[input1.tab.c:10: warning: suspicious sequence in the output: b4_unevaluated [-Wother]
|
[[input1.tab.c:12: warning: suspicious sequence in the output: b4_poison [-Wother]
|
||||||
input1.tab.c:11: warning: suspicious sequence in the output: m4@&t@_unevaluated [-Wother]
|
input1.tab.c:13: warning: suspicious sequence in the output: m4@&t@_poison [-Wother]
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user