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:
Akim Demaille
2021-11-07 09:27:52 +01:00
parent c95d0dd5f5
commit 6571c2d1b1
6 changed files with 94 additions and 25 deletions

View File

@@ -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