[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
patch for many C- and M4-related quoting problems in Bison
From: |
Paul Eggert |
Subject: |
patch for many C- and M4-related quoting problems in Bison |
Date: |
Mon, 11 Nov 2002 23:37:52 -0800 (PST) |
Jan Hubicka's report that Bison mishandles the Bash grammar prompted
me to write and install the following fixes for various quoting
problems in Bison. I suspect that there are still some other problems
(e.g., if the user specifies a prefix beginning with "b4_"), but I am
quitting while I am ahead. I ran into several problems that I
couldn't see how to handle in M4 (e.g., file names containing commas),
so I stopped using M4 to process tricky things like file names.
2002-11-11 Paul Eggert <address@hidden>
Revamp to fix many (but not all) of the C- and M4-related quoting
problems. Among other things, this fixes the Bison bug reported
by Jan Hubicka when processing the Bash grammar; see:
<http://mail.gnu.org/pipermail/bison-patches/2002-November/001329.html>
Use new @ escapes consistently. Represent brackets with @{ and @}
rather than @<:@ and @:>@, since this works a bit better with dumb
editors like vi. Represent @ with @@, since @ is now consistently
an escape. Use @oline@ and @ofile@ rather than __oline__ and
__ofile__, to avoid unexpected expansions. Similarly, use @output
rather than #output.
* data/c.m4 (b4_copyright): Omit file name from comment, since
the file name could contain "*/".
(b4_synclines_flag): Don't quote the 2nd argument; it should already
be quoted. All uses changed.
* data/glr.c: Use new @ escapes consistently.
(b4_input_suffix, b4_output_parser_suffix, b4_output_parser_name,
b4_output_header_suffix, b4_output_header_name, b4_header_guard):
Remove, since they couldn't handle arbitrary characters in file
names.
* data/lalr1.cc: Likewise.
* data/yacc.c: Likewise.
* src/files.c (output_infix): Remove; all uses removed.
* src/files.h: Likewise.
* data/glr.c: Remove use of "#ifdef b4_header_guard", since it
mishandled funny characters in file names, and anyway it isn't
needed any more.
* data/yacc.c: Likewise.
* data/lalr1.cc: Use YYSLP_NEEDED instead of b4_header_guard.
* data/glr.c (YYSTYPE_IS_TRIVIAL): Define when the .h file would.
* data/yacc.c: Likewise.
* src/muscle_tab.c: Include quotearg.h, since we need to quote C
strings now.
(muscle_init): Quote filename as a C string.
* src/muscle_tab.h (MUSCLE_GROW_STRING_PAIR): Remove; unused.
(MUSCLE_OBSTACK_SGROW, MUSCLE_INSERT_C_STRING): New macros.
* src/output.c (escaped_file_name_output): New function.
(prepare_symbols): Quote tokens for M4.
(prepare): Don't insert output_infix, output_prefix,
output_parser_name, output_header_name; this is now down by scan-skel.
Insert skeleton as a C string.
* src/output.c (user_actions_output, symbol_destructors_output,
symbol_printers_output): Quote filenames for C and M4.
* src/reader.c (prologue_augment, epilogue_set): Likewise.
* src/scan-gram.l (<SC_CHARACTER>): Don't worry about any backslash
escapes other than \\ and \'; this simplifies the code.
(<SC_STRING>): Likewise, for \\ and \".
(<SC_COMMENT,SC_LINE_COMMENT,SC_STRING,SC_CHARACTER,SC_BRACED_CODE,
SC_PROLOGUE,SC_EPILOGUE>): Escape $ and @, too.
Use new escapes @{ and @} for [ and ].
* src/scan-skel.l (yylineno, yyoutname): Remove static vars, replacing
them with auto vars.
Switch to new escape scheme, where @ is the escape character uniformly.
Abort if a stray escape character is found. Avoid unbounded input
buffer when parsing non-escaped text.
* tests/input.at (Torturing the Scanner): Add tests that @oline@,
__oline__, #output, $@, and @{ do not have unintended meanings.
Index: data/c.m4
===================================================================
RCS file: /cvsroot/bison/bison/data/c.m4,v
retrieving revision 1.15
diff -p -u -r1.15 c.m4
--- data/c.m4 6 Nov 2002 14:11:47 -0000 1.15
+++ data/c.m4 12 Nov 2002 06:44:27 -0000
@@ -26,7 +26,7 @@ m4_divert(-1)
# b4_copyright(TITLE, YEARS)
# --------------------------
m4_define([b4_copyright],
-[/* A Bison parser, made from b4_filename, by GNU bison b4_version. */
+[/* A Bison parser, made by GNU Bison b4_version. */
/* $1,
Copyright (C) $2 Free Software Foundation, Inc.
@@ -54,7 +54,7 @@ m4_define([b4_identification],
[#]define YYBISON 1
/* Skeleton name. */
-[#]define YYSKELETON_NAME "b4_skeleton"
+[#]define YYSKELETON_NAME b4_skeleton
/* Pure parsers. */
[#]define YYPURE b4_pure
@@ -311,4 +311,4 @@ m4_define([b4_c_arg],
# -----------------------
m4_define([b4_syncline],
[m4_if(b4_synclines_flag, 1,
- [[#]line $1 "$2"])])
+ [[#]line $1 $2])])
Index: data/glr.c
===================================================================
RCS file: /cvsroot/bison/bison/data/glr.c,v
retrieving revision 1.30
diff -p -u -r1.30 glr.c
--- data/glr.c 10 Nov 2002 04:31:38 -0000 1.30
+++ data/glr.c 12 Nov 2002 06:44:28 -0000
@@ -115,7 +115,7 @@ m4_define([b4_lhs_value],
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([b4_rhs_value],
-[yyvsp@<:@m4_eval([$2 - $1])@:>@.yystate.yysemantics.yysval[]m4_ifval([$3],
[.$3])])
address@hidden([$2 - $1])@}.yystate.yysemantics.yysval[]m4_ifval([$3], [.$3])])
@@ -135,38 +135,13 @@ m4_define([b4_lhs_location],
# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
# on RHS.
m4_define([b4_rhs_location],
-[yyvsp@<:@m4_eval([$2 - $1])@:>@.yystate.yyloc])
-
-
-
-## ------------------- ##
-## Output file names. ##
-## ------------------- ##
-
-m4_define_default([b4_input_suffix], [.y])
-
-m4_define_default([b4_output_parser_suffix],
-[m4_translit(b4_input_suffix, [yY], [cC])])
-
-m4_define_default([b4_output_parser_name],
-[b4_output_prefix[]b4_output_infix[]b4_output_parser_suffix[]])
-
-
-m4_define_default([b4_output_header_suffix],
-[m4_translit(b4_input_suffix, [yY], [hH])])
-
-m4_define_default([b4_output_header_name],
-[b4_output_prefix[]b4_output_infix[]b4_output_header_suffix[]])
-
-m4_define_default([b4_header_guard],
- [m4_bpatsubst(m4_toupper([BISON_]b4_output_header_name),
- [[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]], [_])])
address@hidden([$2 - $1])@}.yystate.yyloc])
# We do want M4 expansion after # for CPP macros.
m4_changecom()
m4_divert(0)dnl
-#output "b4_output_parser_name"
address@hidden @output_parser_name@
b4_copyright([Skeleton parser for GLR parsing with Bison], [2002])
[
/* This is the parser code for GLR (Generalized LR) parser. */
@@ -214,7 +189,7 @@ b4_pre_prologue[
[b4_syncline([b4_stype_line], [b4_filename])
typedef union b4_stype yystype;
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])],
+b4_syncline(address@hidden@], address@hidden@])],
[typedef int yystype;])[
# define YYSTYPE yystype
# define YYSTYPE_IS_TRIVIAL 1
@@ -234,7 +209,7 @@ typedef struct yyltype
/* Default (constant) values used for initialization for null
right-hand sides. Unlike the standard bison.simple template,
- here we set the default values of the $$ and $@ to zeroed-out
+ here we set the default values of $$ and $@@ to zeroed-out
values. Since the default value of these quantities is undefined,
this behavior is technically correct. */
static YYSTYPE yyval_default;
@@ -244,7 +219,7 @@ static YYLTYPE yyloc_default;
]b4_post_prologue[
]/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])
+b4_syncline(address@hidden@], address@hidden@])
[
#if ! defined (__cplusplus)
typedef char bool;
@@ -615,7 +590,7 @@ yytokenName (yySymbol yytoken)
/** Perform user action for rule number YYN, with RHS length YYRHSLEN,
* and top stack item YYVSP. YYLVALP points to place to put semantic
* value ($$), and yylocp points to place for location information
- * (@$). Returns yyok for normal return, yyaccept for YYACCEPT,
+ * (@@$). Returns yyok for normal return, yyaccept for YYACCEPT,
* yyerr for YYERROR, yyabort for YYABORT. */
static YYRESULTTAG
yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
@@ -672,7 +647,7 @@ yyuserAction (yyRuleNum yyn, int yyrhsle
# undef yyclearin
# undef YYRECOVERING
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])
+b4_syncline(address@hidden@], address@hidden@])
}
@@ -1867,7 +1842,7 @@ yy_yypstack (yyGLRState* yys)
yy_yypstack (yys->yypred);
fprintf (stderr, " -> ");
}
- fprintf (stderr, "address@hidden", yys->yylrState, (unsigned long)
yys->yyposn);
+ fprintf (stderr, "%d@@%lu", yys->yylrState, (unsigned long) yys->yyposn);
}
static void
@@ -1927,10 +1902,8 @@ yypdumpstack (yyGLRStack* yystack)
b4_epilogue
m4_if(b4_defines_flag, 0, [],
-[#output "b4_output_header_name"
address@hidden @output_header_name@
b4_copyright([Skeleton parser for GLR parsing with Bison], [2002])
-#ifndef b4_header_guard
-# define b4_header_guard
b4_token_defines(b4_tokens)
@@ -1939,9 +1912,10 @@ m4_ifdef([b4_stype],
[b4_syncline([b4_stype_line], [b4_filename])
typedef union b4_stype yystype;
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])],
+b4_syncline(address@hidden@], address@hidden@])],
[typedef int yystype;])
# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
#endif
b4_pure_if([],
@@ -1962,5 +1936,4 @@ typedef struct yyltype
m4_if(b4_pure, [0],
[extern YYLTYPE b4_prefix[]lloc;])
])
-#endif /* not b4_header_guard */
])
Index: data/lalr1.cc
===================================================================
RCS file: /cvsroot/bison/bison/data/lalr1.cc,v
retrieving revision 1.13
diff -p -u -r1.13 lalr1.cc
--- data/lalr1.cc 6 Nov 2002 14:11:47 -0000 1.13
+++ data/lalr1.cc 12 Nov 2002 06:44:28 -0000
@@ -48,7 +48,7 @@ m4_define([b4_lhs_value],
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([b4_rhs_value],
-[semantic_stack_@<:@m4_eval([$1 - $2])@:>@m4_ifval([$3], [.$3])])
address@hidden([$1 - $2])@}m4_ifval([$3], [.$3])])
m4_define_default([b4_location_type], [Location])
@@ -64,28 +64,9 @@ m4_define([b4_lhs_location],
# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
# on RHS.
m4_define([b4_rhs_location],
-[location_stack_@<:@m4_eval([$1 - $2])@:>@])
address@hidden([$1 - $2])@}])
-m4_define_default([b4_input_suffix], [.y])
-
-m4_define_default([b4_output_parser_suffix],
-[m4_translit(b4_input_suffix, [yY], [cC])])
-
-m4_define_default([b4_output_parser_name],
-[b4_output_prefix[]b4_output_infix[]b4_output_parser_suffix[]])
-
-
-m4_define_default([b4_output_header_suffix],
-[m4_translit(b4_input_suffix, [yY], [hH])])
-
-m4_define_default([b4_output_header_name],
-[b4_output_prefix[]b4_output_infix[]b4_output_header_suffix[]])
-
-m4_define_default([b4_header_guard],
- [m4_bpatsubst(m4_toupper([BISON_]b4_output_header_name),
- [[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]], [_])])
-
m4_define([b4_inherit],
[m4_ifdef([b4_root],
[: public b4_root
@@ -108,11 +89,11 @@ m4_define([b4_constructor],
# We do want M4 expansion after # for CPP macros.
m4_changecom()
m4_divert(0)dnl
-#output "b4_output_header_name"
address@hidden @output_header_name@
b4_copyright([C++ Skeleton parser for LALR(1) parsing with Bison],
[2002])
-#ifndef b4_header_guard
-# define b4_header_guard
+#ifndef YYLSP_NEEDED
+# define YYLSP_NEEDED
#include "stack.hh"
#include "location.hh"
@@ -129,7 +110,7 @@ b4_token_defines(b4_tokens)
b4_pre_prologue
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])
+b4_syncline(address@hidden@], address@hidden@])
/* Enabling traces. */
#ifndef YYDEBUG
@@ -146,7 +127,7 @@ m4_ifdef([b4_stype],
[b4_syncline([b4_stype_line], [b4_filename])
typedef union b4_stype yystype;
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])],
+b4_syncline(address@hidden@], address@hidden@])],
[typedef int yystype;])
# define YYSTYPE yystype
#endif
@@ -155,7 +136,7 @@ b4_syncline([__oline__], [__ofile__])],
b4_post_prologue
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])
+b4_syncline(address@hidden@], address@hidden@])
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N) \
Current.last_line = Rhs[[N]].last_line; \
@@ -291,7 +272,7 @@ namespace yy
SemanticType value;
LocationType location;
- /* @$ and $$. */
+ /* @@$ and $$. */
SemanticType yyval;
LocationType yyloc;
@@ -300,13 +281,13 @@ namespace yy
};
}
-#endif /* not b4_header_guard */
+#endif /* ! defined YYLSP_NEEDED */
dnl
-#output "b4_output_prefix[]b4_output_infix[].cc"
address@hidden @output_parser_name@
b4_copyright([C++ Skeleton parser for LALR(1) parsing with Bison],
[2002])
-#include "b4_output_header_name"
+#include @output_header_name@
/* Enable debugging if requested. */
#if YYDEBUG
@@ -463,7 +444,7 @@ yy::b4_parser_class_name::parse ()
}
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])
+b4_syncline(address@hidden@], address@hidden@])
state_stack_.pop (len_);
semantic_stack_.pop (len_);
@@ -781,7 +762,7 @@ const yy::b4_parser_class_name::TokenNum
b4_epilogue
dnl
-#output "stack.hh"
address@hidden stack.hh
b4_copyright([2002])
#ifndef BISON_STACK_HH
@@ -878,7 +859,7 @@ namespace yy
#endif // not BISON_STACK_HH
dnl
-#output "location.hh"
address@hidden location.hh
b4_copyright([2002])
#ifndef BISON_LOCATION_HH
Index: data/yacc.c
===================================================================
RCS file: /cvsroot/bison/bison/data/yacc.c,v
retrieving revision 1.30
diff -p -u -r1.30 yacc.c
--- data/yacc.c 7 Nov 2002 12:52:19 -0000 1.30
+++ data/yacc.c 12 Nov 2002 06:44:28 -0000
@@ -39,7 +39,7 @@ m4_define_default([b4_location_type], [y
## ------------------------ ##
-# b4_Pure_if(IF-TRUE, IF-FALSE)
+# b4_pure_if(IF-TRUE, IF-FALSE)
# -----------------------------
# Expand IF-TRUE, if %pure-parser and %parse-param, IF-FALSE otherwise.
m4_define([b4_Pure_if],
@@ -105,7 +105,7 @@ m4_define([b4_lhs_value],
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
# symbols on RHS.
m4_define([b4_rhs_value],
-[yyvsp@<:@m4_eval([$2 - $1])@:>@m4_ifval([$3], [.$3])])
address@hidden([$2 - $1])@}m4_ifval([$3], [.$3])])
@@ -125,32 +125,7 @@ m4_define([b4_lhs_location],
# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
# on RHS.
m4_define([b4_rhs_location],
-[yylsp@<:@m4_eval([$2 - $1])@:>@])
-
-
-
-## ------------------- ##
-## Output file names. ##
-## ------------------- ##
-
-m4_define_default([b4_input_suffix], [.y])
-
-m4_define_default([b4_output_parser_suffix],
-[m4_translit(b4_input_suffix, [yY], [cC])])
-
-m4_define_default([b4_output_parser_name],
-[b4_output_prefix[]b4_output_infix[]b4_output_parser_suffix[]])
-
-
-m4_define_default([b4_output_header_suffix],
-[m4_translit(b4_input_suffix, [yY], [hH])])
-
-m4_define_default([b4_output_header_name],
-[b4_output_prefix[]b4_output_infix[]b4_output_header_suffix[]])
-
-m4_define_default([b4_header_guard],
- [m4_bpatsubst(m4_toupper([BISON_]b4_output_header_name),
- [[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]], [_])])
address@hidden([$2 - $1])@}])
@@ -168,7 +143,7 @@ m4_pushdef([b4_at_dollar], [yylocation])
case $4: /* $3 */
b4_syncline([$2], [$1])
$5;
-b4_syncline([__oline__], [__ofile__])
+b4_syncline(address@hidden@], address@hidden@])
break;
m4_popdef([b4_at_dollar])dnl
m4_popdef([b4_dollar_dollar])dnl
@@ -178,7 +153,7 @@ m4_popdef([b4_dollar_dollar])dnl
# We do want M4 expansion after # for CPP macros.
m4_changecom()
m4_divert(0)dnl
-#output "b4_output_parser_name"
address@hidden @output_parser_name@
b4_copyright([Skeleton parser for Yacc-like parsing with Bison],
[1984, 1989, 1990, 2000, 2001, 2002])
@@ -233,7 +208,7 @@ m4_ifdef([b4_stype],
[b4_syncline([b4_stype_line], [b4_filename])
typedef union b4_stype yystype;
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])],
+b4_syncline(address@hidden@], address@hidden@])],
[typedef int yystype;])
# define YYSTYPE yystype
# define YYSTYPE_IS_TRIVIAL 1
@@ -255,7 +230,7 @@ typedef struct yyltype
b4_post_prologue
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])
+b4_syncline(address@hidden@], address@hidden@])
#if ! defined (yyoverflow) || YYERROR_VERBOSE
@@ -1054,7 +1029,7 @@ yyreduce:
}
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])
+b4_syncline(address@hidden@], address@hidden@])
[ yyvsp -= yylen;
yyssp -= yylen;
@@ -1275,7 +1250,7 @@ yyreturn:
b4_epilogue
m4_if(b4_defines_flag, 0, [],
-[#output "b4_output_header_name"
address@hidden @output_header_name@
b4_copyright([Skeleton parser for Yacc-like parsing with Bison],
[1984, 1989, 1990, 2000, 2001, 2002])
@@ -1284,9 +1259,6 @@ b4_copyright([Skeleton parser for Yacc-l
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
-#ifndef b4_header_guard
-# define b4_header_guard
-
b4_token_defines(b4_tokens)
#ifndef YYSTYPE
@@ -1294,9 +1266,10 @@ m4_ifdef([b4_stype],
[b4_syncline([b4_stype_line], [b4_filename])
typedef union b4_stype yystype;
/* Line __line__ of __file__. */
-b4_syncline([__oline__], [__ofile__])],
+b4_syncline(address@hidden@], address@hidden@])],
[typedef int yystype;])
# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
#endif
b4_pure_if([],
@@ -1317,5 +1290,4 @@ typedef struct yyltype
m4_if(b4_pure, [0],
[extern YYLTYPE b4_prefix[]lloc;])
])
-#endif /* not b4_header_guard */
])
Index: src/files.c
===================================================================
RCS file: /cvsroot/bison/bison/src/files.c,v
retrieving revision 1.79
diff -p -u -r1.79 files.c
--- src/files.c 30 Oct 2002 06:19:00 -0000 1.79
+++ src/files.c 12 Nov 2002 06:44:28 -0000
@@ -57,10 +57,6 @@ static char *full_base_name = NULL;
/* Prefix used to generate output file names. */
char *short_base_name = NULL;
-/* Infix used to generate output file names (i.e., `.tab', or `_tab',
- or `'). */
-char *output_infix = NULL;
-
/* C source file extension (the parser source). */
const char *src_extension = NULL;
/* Header file extension (if option ``-d'' is specified). */
@@ -258,10 +254,6 @@ compute_base_names (void)
(strlen (spec_outfile)
- (tab ? strlen (tab) : (ext ? strlen (ext) : 0))));
- if (tab)
- output_infix = xstrndup (tab,
- (strlen (tab) - (ext ? strlen (ext) : 0)));
-
if (ext)
compute_exts_from_src (ext);
}
@@ -292,9 +284,6 @@ compute_base_names (void)
xstrndup (base,
(strlen (base) - (ext ? strlen (ext) : 0)));
}
-
- /* In these cases, always append `.tab'. */
- output_infix = xstrdup (EXT_TAB);
full_base_name = XMALLOC (char,
strlen (short_base_name)
Index: src/files.h
===================================================================
RCS file: /cvsroot/bison/bison/src/files.h,v
retrieving revision 1.35
diff -p -u -r1.35 files.h
--- src/files.h 30 Oct 2002 06:18:19 -0000 1.35
+++ src/files.h 12 Nov 2002 06:44:28 -0000
@@ -67,8 +67,4 @@ char* stringappend (const char* string1,
/* Prefix used to generate output file names. */
extern char *short_base_name;
-/* Infix used to generate output file names (i.e., `.tab', or `_tab',
- or `'). */
-extern char *output_infix;
-
#endif /* !FILES_H_ */
Index: src/muscle_tab.c
===================================================================
RCS file: /cvsroot/bison/bison/src/muscle_tab.c,v
retrieving revision 1.26
diff -p -u -r1.26 muscle_tab.c
--- src/muscle_tab.c 6 Nov 2002 14:11:47 -0000 1.26
+++ src/muscle_tab.c 12 Nov 2002 06:44:28 -0000
@@ -20,6 +20,7 @@
#include "system.h"
#include "hash.h"
+#include "quotearg.h"
#include "files.h"
#include "muscle_tab.h"
#include "getargs.h"
@@ -64,7 +65,7 @@ muscle_init (void)
/* Version and input file. */
MUSCLE_INSERT_STRING ("version", VERSION);
- MUSCLE_INSERT_STRING ("filename", infile);
+ MUSCLE_INSERT_C_STRING ("filename", infile);
}
Index: src/muscle_tab.h
===================================================================
RCS file: /cvsroot/bison/bison/src/muscle_tab.h,v
retrieving revision 1.8
diff -p -u -r1.8 muscle_tab.h
--- src/muscle_tab.h 21 Oct 2002 05:30:50 -0000 1.8
+++ src/muscle_tab.h 12 Nov 2002 06:44:28 -0000
@@ -57,9 +57,25 @@ extern struct obstack muscle_obstack;
muscle_insert (Key, obstack_finish (&muscle_obstack)); \
}
-#define MUSCLE_GROW_STRING_PAIR(Key, Value1, Value2) \
+#define MUSCLE_OBSTACK_SGROW(Obstack, Value) \
{ \
- obstack_sgrow (&muscle_obstack, Value1); \
+ char const *s; \
+ for (s = Value; *s; s++) \
+ switch (*s) \
+ { \
+ case '$': obstack_sgrow (Obstack, "$]["); break; \
+ case '@': obstack_sgrow (Obstack, "@@" ); break; \
+ case '[': obstack_sgrow (Obstack, "@{" ); break; \
+ case ']': obstack_sgrow (Obstack, "@}" ); break; \
+ default: obstack_1grow (Obstack, *s); break; \
+ } \
+}
+
+#define MUSCLE_INSERT_C_STRING(Key, Value) \
+{ \
+ MUSCLE_OBSTACK_SGROW (&muscle_obstack, \
+ quotearg_style (c_quoting_style, \
+ Value)); \
obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \
}
Index: src/output.c
===================================================================
RCS file: /cvsroot/bison/bison/src/output.c,v
retrieving revision 1.207
diff -p -u -r1.207 output.c
--- src/output.c 6 Nov 2002 16:22:04 -0000 1.207
+++ src/output.c 12 Nov 2002 06:44:28 -0000
@@ -107,6 +107,30 @@ GENERATE_MUSCLE_INSERT_TABLE(muscle_inse
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number_t)
+/*----------------------------------------------------------------------.
+| Print to OUT a representation of FILENAME escaped both for C and M4. |
+`----------------------------------------------------------------------*/
+
+static void
+escaped_file_name_output (FILE *out, char const *filename)
+{
+ char const *p;
+ fprintf (out, "[[");
+
+ for (p = quotearg_style (c_quoting_style, filename); *p; p++)
+ switch (*p)
+ {
+ case '$': fputs ("$][", out); break;
+ case '@': fputs ("@@", out); break;
+ case '[': fputs ("@{", out); break;
+ case ']': fputs ("@}", out); break;
+ default: fputc (*p, out); break;
+ }
+
+ fprintf (out, "]]");
+}
+
+
/*------------------------------------------------------------------.
| Prepare the muscles related to the symbols: translate, tname, and |
| toknum. |
@@ -146,14 +170,7 @@ prepare_symbols (void)
j = 2;
}
- for (; *cp; cp++)
- switch (*cp)
- {
- case '[': obstack_sgrow (&format_obstack, "@<:@"); break;
- case ']': obstack_sgrow (&format_obstack, "@:>@"); break;
- default: obstack_1grow (&format_obstack, *cp); break;
- }
-
+ MUSCLE_OBSTACK_SGROW (&format_obstack, cp);
obstack_sgrow (&format_obstack, ", ");
j += strsize;
}
@@ -276,10 +293,10 @@ user_actions_output (FILE *out)
{
fprintf (out, " case %d:\n", r + 1);
- fprintf (out, "]b4_syncline([[%d]], [[%s]])[\n",
- rules[r].action_location.first_line,
- quotearg_style (escape_quoting_style,
- rules[r].action_location.file));
+ fprintf (out, "]b4_syncline([[%d]], ",
+ rules[r].action_location.first_line);
+ escaped_file_name_output (out, rules[r].action_location.file);
+ fprintf (out, ")[\n");
fprintf (out, " %s\n break;\n\n",
rules[r].action);
}
@@ -378,10 +395,10 @@ symbol_destructors_output (FILE *out)
/* Filename, lineno,
Symbol-name, Symbol-number,
destructor, typename. */
- fprintf (out, "%s[[[%s]], [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
- first ? "" : ",\n",
- quotearg_style (escape_quoting_style,
- symbol->destructor_location.file),
+ fprintf (out, "%s[",
+ first ? "" : ",\n");
+ escaped_file_name_output (out, symbol->destructor_location.file);
+ fprintf (out, ", [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
symbol->destructor_location.first_line,
symbol->tag,
symbol->number,
@@ -413,10 +430,10 @@ symbol_printers_output (FILE *out)
/* Filename, lineno,
Symbol-name, Symbol-number,
printer, typename. */
- fprintf (out, "%s[[[%s]], [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
- first ? "" : ",\n",
- quotearg_style (escape_quoting_style,
- symbol->printer_location.file),
+ fprintf (out, "%s[",
+ first ? "" : ",\n");
+ escaped_file_name_output (out, symbol->printer_location.file);
+ fprintf (out, ", [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
symbol->printer_location.first_line,
symbol->tag,
symbol->number,
@@ -577,10 +594,6 @@ prepare (void)
/* FIXME: This is wrong: the muscles should decide whether they hold
a copy or not, but the situation is too obscure currently. */
MUSCLE_INSERT_STRING ("prefix", spec_name_prefix ? spec_name_prefix : "yy");
- MUSCLE_INSERT_STRING ("output_infix", output_infix ? output_infix : "");
- MUSCLE_INSERT_STRING ("output_prefix", short_base_name);
- MUSCLE_INSERT_STRING ("output_parser_name", parser_file_name);
- MUSCLE_INSERT_STRING ("output_header_name", spec_defines_file);
/* User Code. */
obstack_1grow (&pre_prologue_obstack, 0);
@@ -598,7 +611,7 @@ prepare (void)
}
/* Parse the skeleton file and output the needed parsers. */
- MUSCLE_INSERT_STRING ("skeleton", skeleton);
+ MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
}
Index: src/reader.c
===================================================================
RCS file: /cvsroot/bison/bison/src/reader.c,v
retrieving revision 1.218
diff -p -u -r1.218 reader.c
--- src/reader.c 6 Nov 2002 14:11:47 -0000 1.218
+++ src/reader.c 12 Nov 2002 06:44:29 -0000
@@ -69,9 +69,10 @@ prologue_augment (const char *prologue,
struct obstack *oout =
!typed ? &pre_prologue_obstack : &post_prologue_obstack;
- obstack_fgrow2 (oout, "]b4_syncline([[%d]], [[%s]])[\n",
- location.first_line,
- quotearg_style (escape_quoting_style, location.file));
+ obstack_fgrow1 (oout, "]b4_syncline([[%d]], [[",
+ location.first_line);
+ MUSCLE_OBSTACK_SGROW (oout, quotearg_style (c_quoting_style, location.file));
+ obstack_sgrow (oout, "]])[\n");
obstack_sgrow (oout, prologue);
}
@@ -85,9 +86,11 @@ prologue_augment (const char *prologue,
void
epilogue_set (const char *epilogue, location_t location)
{
- obstack_fgrow2 (&muscle_obstack, "]b4_syncline([[%d]], [[%s]])[\n",
- location.first_line,
- quotearg_style (escape_quoting_style, location.file));
+ obstack_fgrow1 (&muscle_obstack, "]b4_syncline([[%d]], [[",
+ location.first_line);
+ MUSCLE_OBSTACK_SGROW (&muscle_obstack,
+ quotearg_style (c_quoting_style, location.file));
+ obstack_sgrow (&muscle_obstack, "]])[\n");
obstack_sgrow (&muscle_obstack, epilogue);
obstack_1grow (&muscle_obstack, 0);
muscle_insert ("epilogue", obstack_finish (&muscle_obstack));
Index: src/scan-gram.l
===================================================================
RCS file: /cvsroot/bison/bison/src/scan-gram.l,v
retrieving revision 1.38
diff -p -u -r1.38 scan-gram.l
--- src/scan-gram.l 10 Nov 2002 05:17:56 -0000 1.38
+++ src/scan-gram.l 12 Nov 2002 06:44:30 -0000
@@ -469,10 +469,9 @@ splice (\\[ \f\t\v]*\n)*
<SC_CHARACTER>
{
- "'" YY_OBS_GROW; BEGIN c_context;
- \\{splice}[^\[\]] YY_OBS_GROW;
- {splice} YY_OBS_GROW;
- <<EOF>> unexpected_end_of_file (yylloc, "'");
+ "'" YY_OBS_GROW; BEGIN c_context;
+ \\{splice}[\'\\] YY_OBS_GROW;
+ <<EOF>> unexpected_end_of_file (yylloc, "'");
}
@@ -483,10 +482,9 @@ splice (\\[ \f\t\v]*\n)*
<SC_STRING>
{
- "\"" YY_OBS_GROW; BEGIN c_context;
- \\{splice}[^\[\]] YY_OBS_GROW;
- {splice} YY_OBS_GROW;
- <<EOF>> unexpected_end_of_file (yylloc, "\"");
+ "\"" YY_OBS_GROW; BEGIN c_context;
+ \\{splice}[\"\\] YY_OBS_GROW;
+ <<EOF>> unexpected_end_of_file (yylloc, "\"");
}
@@ -578,8 +576,10 @@ splice (\\[ \f\t\v]*\n)*
<SC_COMMENT,SC_LINE_COMMENT,SC_STRING,SC_CHARACTER,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
{
- \[ obstack_sgrow (&string_obstack, "@<:@");
- \] obstack_sgrow (&string_obstack, "@:>@");
+ \$ obstack_sgrow (&string_obstack, "$][");
+ \@ obstack_sgrow (&string_obstack, "@@");
+ \[ obstack_sgrow (&string_obstack, "@{");
+ \] obstack_sgrow (&string_obstack, "@}");
.|\n YY_OBS_GROW;
}
Index: src/scan-skel.l
===================================================================
RCS file: /cvsroot/bison/bison/src/scan-skel.l,v
retrieving revision 1.16
diff -p -u -r1.16 scan-skel.l
--- src/scan-skel.l 6 Nov 2002 16:22:04 -0000 1.16
+++ src/scan-skel.l 12 Nov 2002 06:44:30 -0000
@@ -30,30 +30,46 @@
int skel_lex (void);
-static int yylineno = 1;
-static char *yyoutname = NULL;
-
%}
%%
- /* This is an approximation, but we don't need more. */
-^"#output \""[^\"]+\"\n {
- yytext[yyleng - 2] = '\0';
- XFREE (yyoutname);
- yyoutname = xstrdup (yytext + strlen ("#output \""));
- yyout = xfopen (yyoutname, "w");
- yylineno = 1;
- }
-
-"@<:@" fputc ('[', yyout);
-"@:>@" fputc (']', yyout);
-
-"__oline__" fprintf (yyout, "%d", yylineno+1);
-"__ofile__" fprintf (yyout, "%s", quotearg_style (escape_quoting_style,
yyoutname));
address@hidden ECHO;
-\n+ yylineno += yyleng; ECHO;
-. ECHO;
-<<EOF>> xfclose (yyout); free (yyoutname); return EOF;
+%{
+ int lineno IF_LINT (= 0);
+ char *outname = NULL;
+%}
+
+"@output ".*\n {
+ char const *filename = yytext + sizeof "@output " - 1;
+ yytext[yyleng - 1] = '\0';
+
+ if (*filename == '@')
+ {
+ if (strcmp (filename, "@output_header_name@") == 0)
+ filename = spec_defines_file;
+ else if (strcmp (filename, "@output_parser_name@") == 0)
+ filename = parser_file_name;
+ else
+ abort ();
+ }
+
+ XFREE (outname);
+ outname = xstrdup (filename);
+ yyout = xfopen (outname, "w");
+ lineno = 1;
+}
+
+"@@" fputc ('@', yyout);
+"@{" fputc ('[', yyout);
+"@}" fputc (']', yyout);
+
+"@oline@" fprintf (yyout, "%d", lineno);
+"@ofile@" fputs (quotearg_style (c_quoting_style, outname), yyout);
+
+"@" abort ();
+\n lineno++; ECHO;
+. ECHO;
+
+<<EOF>> xfclose (yyout); free (outname); return EOF;
%%
/*------------------------.
Index: tests/input.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/input.at,v
retrieving revision 1.16
diff -p -u -r1.16 input.at
--- tests/input.at 6 Nov 2002 07:01:55 -0000 1.16
+++ tests/input.at 12 Nov 2002 06:44:30 -0000
@@ -151,13 +151,17 @@ static int yylex (void);
%%
/* Exercise M4 quoting: '@:>@@:>@', @<:@, 1. */
-exp: '@<:@' '\1' '\x000000000000000000000000000000000000000000000000002'
+exp: '@<:@' '\1' two '$' '@' '{' oline output
{
/* Exercise quotes in braces. */
char tmp[] = "@<:@%c@:>@,\n";
printf (tmp, $1);
}
;
+
+two: '\x000000000000000000000000000000000000000000000000000000000000000000002';
+oline: '@' 'o' 'l' 'i' 'n' 'e' '@' '_' '_' 'o' 'l' 'i' 'n' 'e' '_' '_';
+output: '#' 'o' 'u' 't' 'p' 'u' 't' ' ';
%%
/* Exercise M4 quoting: '@:>@@:>@', @<:@, 2. */
@@ -172,7 +176,9 @@ value_t_as_yystype (value_t val)
static int
yylex (void)
{
- static const char *input = "@<:@\1\2";
+ static const char *input = "@<:@address@hidden@address@hidden@&address@hidden
+#output "; /* "
+ */
yylval = value_t_as_yystype (*input);
return *input++;
}
- patch for many C- and M4-related quoting problems in Bison,
Paul Eggert <=