[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] -F/--force-define and relative %define/-D/--define priorities.
From: |
Joel E. Denny |
Subject: |
[PATCH] -F/--force-define and relative %define/-D/--define priorities. |
Date: |
Sat, 23 May 2009 00:43:22 -0400 (EDT) |
I pushed this to branch-2.5 and a similar patch to master.
>From 34d419381579dd30642e5646aaeaece36207be94 Mon Sep 17 00:00:00 2001
From: Joel E. Denny <address@hidden>
Date: Fri, 22 May 2009 17:14:08 -0400
Subject: [PATCH] -F/--force-define and relative %define/-D/--define priorities.
* NEWS (2.5): Add documentation to -D/--define entry.
* build-aux/cross-options.pl: Hard-code association of
--force-define with %define.
* doc/bison.texinfo (Decl Summary): In %define entry,
cross-reference command-line options.
(Bison Options): Add documentation to -D/--define entry.
(Option Cross Key): Widen column for --force-define row.
* src/getargs.c (usage): Document -F/--force-define. Realign
options in output.
(short_options, long_options, getargs): Parse -F/--force-define,
and update muscle_percent_define_insert invocation.
* src/muscle_tab.h (muscle_percent_define_how): New enum type.
(muscle_percent_define_insert): Add argument with that type.
* src/muscle_tab.c (muscle_percent_define_insert): Implement
-F/--force-define behavior and priorities.
* src/parse-gram.y (prologue_declaration): Update
muscle_percent_define_insert invocations.
* tests/input.at (`%define, --define'): Rename to...
(`%define, --define, --force-define'): ... this and extend.
diff --git a/NEWS b/NEWS
index 6578160..ed8819f 100644
--- a/NEWS
+++ b/NEWS
@@ -35,17 +35,22 @@ Bison News
** %define can now be invoked via the command line.
- Each of these bison command-line options
+ Each of these command-line options
- -D NAME=VALUE
- --define=NAME=VALUE
+ -D NAME[=VALUE]
+ --define=NAME[=VALUE]
+
+ -F NAME[=VALUE]
+ --force-define=NAME[=VALUE]
is equivalent to this grammar file declaration
- %define NAME "VALUE"
+ %define NAME ["VALUE"]
- for any NAME and VALUE. Omitting `=VALUE' on the command line is
- equivalent to omitting `"VALUE"' in the declaration.
+ except that the manner in which Bison processes multiple definitions
+ for the same NAME differs. Most importantly, -F and --force-define
+ quietly override %define, but -D and --define do not. For further
+ details, see the section "Bison Options" in the Bison manual.
** %define variables renamed.
diff --git a/build-aux/cross-options.pl b/build-aux/cross-options.pl
index 241c741..7762e27 100755
--- a/build-aux/cross-options.pl
+++ b/build-aux/cross-options.pl
@@ -22,7 +22,11 @@ while (<STDIN>)
$short = '' if ! defined $short;
$short = '-d' if $long eq '--defines' && ! $short;
my $dir = '%' . substr($long, 2);
- $dir = '' if index ($scanner, "\"$dir\"") < 0;
+ if (index ($scanner, "\"$dir\"") < 0)
+ {
+ if ($long eq '--force-define') { $dir = '%define'; }
+ else { $dir = ''; }
+ }
if ($arg)
{
# if $opt, $arg contains the closing ].
diff --git a/doc/bison.texinfo b/doc/bison.texinfo
index 1a66edc..d377b5c 100644
--- a/doc/bison.texinfo
+++ b/doc/bison.texinfo
@@ -4837,7 +4837,8 @@ The possible choices for @var{variable}, as well as their
meanings, depend on
the selected target language and/or the parser skeleton (@pxref{Decl
Summary,,%language}, @pxref{Decl Summary,,%skeleton}).
-Bison will warn if a @var{variable} is defined multiple times.
+Bison will warn if a @var{variable} is defined by @code{%define}
+multiple times, but @ref{Bison Options,,-D @address@hidden
Omitting @code{"@var{value}"} is always equivalent to specifying it as
@code{""}.
@@ -7982,8 +7983,29 @@ already defined, so that the debugging facilities are
compiled.
@item -D @address@hidden
@itemx address@hidden@var{value}]
-Same as running @samp{%define @var{name} "@var{value}"} (@pxref{Decl
-Summary, ,%define}).
address@hidden -F @address@hidden
address@hidden address@hidden@var{value}]
+Each of these is equivalent to @samp{%define @var{name} "@var{value}"}
+(@pxref{Decl Summary, ,%define}) except that Bison processes multiple
+definitions for the same @var{name} as follows:
+
address@hidden
address@hidden
+Bison processes all command-line definitions in order and then processes
+all @code{%define} definitions in order.
address@hidden
+Later definitions override earlier definitions except that Bison quietly
+ignores all @code{%define} definitions if the last command-line
+definition is specified by @code{-F} or @code{--force-define}.
address@hidden
+Bison never warns when a command-line definition overrides another
+definition, but Bison always warns when a @code{%define} definition
+overrides a command-line or @code{%define} definition.
address@hidden itemize
+
+You should avoid using @code{-F} and @code{--force-define} in your
+makefiles unless you are confident that it is safe to quietly ignore any
+conflicting @code{%define} that may be added to the grammar file.
@item -L @var{language}
@itemx address@hidden
@@ -8109,9 +8131,9 @@ More user feedback will help to stabilize it.)
@section Option Cross Key
Here is a list of options, alphabetized by long option, to help you find
-the corresponding short option.
+the corresponding short option and directive.
address@hidden address@hidden@var{defines-file}}} address@hidden
@address@hidden address@hidden
address@hidden address@hidden@address@hidden address@hidden @address@hidden
address@hidden
@headitem Long Option @tab Short Option @tab Bison Directive
@include cross-options.texi
@end multitable
diff --git a/src/getargs.c b/src/getargs.c
index 3852de0..322e0b4 100644
--- a/src/getargs.c
+++ b/src/getargs.c
@@ -272,26 +272,27 @@ The same is true for optional arguments.\n\
fputs (_("\
\n\
Operation modes:\n\
- -h, --help display this help and exit\n\
- -V, --version output version information and exit\n\
- --print-localedir output directory containing locale-dependent
data\n\
- --print-datadir output directory containing skeletons and XSLT\n\
- -y, --yacc emulate POSIX Yacc\n\
- -W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
+ -h, --help display this help and exit\n\
+ -V, --version output version information and exit\n\
+ --print-localedir output directory of locale-dependent data\n\
+ --print-datadir output directory of skeletons and XSLT\n\
+ -y, --yacc emulate POSIX Yacc\n\
+ -W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\
\n\
"), stdout);
fputs (_("\
Parser:\n\
- -L, --language=LANGUAGE specify the output programming language\n\
- (this is an experimental feature)\n\
- -S, --skeleton=FILE specify the skeleton to use\n\
- -t, --debug instrument the parser for debugging\n\
- --locations enable location support\n\
- -D, --define=NAME[=VALUE] same as `%define NAME \"VALUE\"'\n\
- -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
- -l, --no-lines don't generate `#line' directives\n\
- -k, --token-table include a table of token names\n\
+ -L, --language=LANGUAGE specify the output programming language\n\
+ (this is an experimental feature)\n\
+ -S, --skeleton=FILE specify the skeleton to use\n\
+ -t, --debug instrument the parser for debugging\n\
+ --locations enable location support\n\
+ -D, --define=NAME[=VALUE] similar to `%define NAME \"VALUE\"'\n\
+ -F, --force-define=NAME[=VALUE] override `%define NAME \"VALUE\"'\n\
+ -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\
+ -l, --no-lines don't generate `#line' directives\n\
+ -k, --token-table include a table of token names\n\
\n\
"), stdout);
@@ -299,16 +300,16 @@ Parser:\n\
* won't assume that -d also takes an argument. */
fputs (_("\
Output:\n\
- --defines[=FILE] also produce a header file\n\
- -d likewise but cannot specify FILE (for POSIX
Yacc)\n\
- -r, --report=THINGS also produce details on the automaton\n\
- --report-file=FILE write report to FILE\n\
- -v, --verbose same as `--report=state'\n\
- -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
- -o, --output=FILE leave output to FILE\n\
- -g, --graph[=FILE] also output a graph of the automaton\n\
- -x, --xml[=FILE] also output an XML report of the automaton\n\
- (the XML schema is experimental)\n\
+ --defines[=FILE] also produce a header file\n\
+ -d likewise but cannot specify FILE (for
POSIX)\n\
+ -r, --report=THINGS also produce details on the automaton\n\
+ --report-file=FILE write report to FILE\n\
+ -v, --verbose same as `--report=state'\n\
+ -b, --file-prefix=PREFIX specify a PREFIX for output files\n\
+ -o, --output=FILE leave output to FILE\n\
+ -g, --graph[=FILE] also output a graph of the automaton\n\
+ -x, --xml[=FILE] also output an XML report of the
automaton\n\
+ (the XML schema is experimental)\n\
\n\
"), stdout);
@@ -415,6 +416,7 @@ language_argmatch (char const *arg, int prio, location loc)
Should be computed from long_options. */
static char const short_options[] =
"D:"
+ "F:"
"L:"
"S:"
"T::"
@@ -482,6 +484,7 @@ static struct option const long_options[] =
/* Parser. */
{ "debug", no_argument, 0, 't' },
{ "define", required_argument, 0, 'D' },
+ { "force-define", required_argument, 0, 'F' },
{ "locations", no_argument, 0, LOCATIONS_OPTION },
{ "no-lines", no_argument, 0, 'l' },
{ "raw", no_argument, 0, 0 },
@@ -530,13 +533,16 @@ getargs (int argc, char *argv[])
break;
case 'D': /* -DNAME[=VALUE]. */
+ case 'F': /* -FNAME[=VALUE]. */
{
char* name = optarg;
char* value = strchr (optarg, '=');
if (value)
*value++ = 0;
muscle_percent_define_insert (name, command_line_location (),
- value ? value : "");
+ value ? value : "",
+ c == 'D' ? MUSCLE_PERCENT_DEFINE_D
+ : MUSCLE_PERCENT_DEFINE_F);
}
break;
diff --git a/src/muscle_tab.c b/src/muscle_tab.c
index 764ea93..fdb03c2 100644
--- a/src/muscle_tab.c
+++ b/src/muscle_tab.c
@@ -401,12 +401,14 @@ do {
\
void
muscle_percent_define_insert (char const *variable, location variable_loc,
- char const *value)
+ char const *value,
+ muscle_percent_define_how how)
{
char *variable_tr = NULL;
char const *name;
char const *loc_name;
char const *syncline_name;
+ char const *how_name;
/* Permit certain names with underscores for backward compatibility. */
if (0 == strcmp (variable, "api.push_pull")
@@ -421,22 +423,33 @@ muscle_percent_define_insert (char const *variable,
location variable_loc,
MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")");
MUSCLE_USER_NAME_CONVERT (syncline_name,
"percent_define_syncline(", variable, ")");
+ MUSCLE_USER_NAME_CONVERT (how_name, "percent_define_how(", variable, ")");
- if (muscle_find_const (name))
+ /* Command-line options are processed before the grammar file. */
+ if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
+ && muscle_find_const (name))
{
+ muscle_percent_define_how how_old =
+ atoi (muscle_find_const (how_name));
+ if (how_old == MUSCLE_PERCENT_DEFINE_F)
+ {
+ free (variable_tr);
+ return;
+ }
warn_at (variable_loc, _("%s `%s' redefined"),
"%define variable", variable);
warn_at (muscle_percent_define_get_loc (variable),
- _("previous definition"));
+ _("previous definition"));
}
- MUSCLE_INSERT_STRING (name, value);
+ MUSCLE_INSERT_STRING (name, value);
muscle_insert (loc_name, "");
muscle_location_grow (loc_name, variable_loc);
muscle_insert (syncline_name, "");
muscle_syncline_grow (syncline_name, variable_loc);
muscle_user_name_list_grow ("percent_define_user_variables", variable,
variable_loc);
+ MUSCLE_INSERT_INT (how_name, how);
free (variable_tr);
}
diff --git a/src/muscle_tab.h b/src/muscle_tab.h
index 21249b7..6edcbbb 100644
--- a/src/muscle_tab.h
+++ b/src/muscle_tab.h
@@ -123,12 +123,25 @@ void muscle_boundary_grow (char const *key, boundary
bound);
void muscle_user_name_list_grow (char const *key, char const *user_name,
location loc);
-/* Define the muscle for the %define variable VARIABLE appearing at
- VARIABLE_LOC with value VALUE. Warn if VARIABLE is already defined.
- Record this as a user occurrence of VARIABLE by invoking
+/* Indicates whether a variable's value was specified with -D/--define, with
+ -F/--force-define, or in the grammar file. */
+typedef enum {
+ MUSCLE_PERCENT_DEFINE_D = 0, MUSCLE_PERCENT_DEFINE_F,
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
+} muscle_percent_define_how;
+
+/* Define the muscles for %define variable VARIABLE with VALUE specified
+ at VARIABLE_LOC in the manner HOW unless it was specified in the
+ grammar file while the previous definition for VARIABLE was specified
+ with -F/--force-define. Warn if a previous definition is being
+ overridden and the new definition is specified in the grammar file.
+ (These rules support the documented behavior as long as command-line
+ definitions are processed before grammar file definitions.) Record
+ this as a user occurrence of VARIABLE by invoking
muscle_user_name_list_grow. */
void muscle_percent_define_insert (char const *variable, location variable_loc,
- char const *value);
+ char const *value,
+ muscle_percent_define_how how);
/* Mimic b4_percent_define_get in ../data/bison.m4 exactly. That is, if the
%define variable VARIABLE is defined, return its value. Otherwise, return
diff --git a/src/parse-gram.y b/src/parse-gram.y
index 5af473c..b05ce2b 100644
--- a/src/parse-gram.y
+++ b/src/parse-gram.y
@@ -227,7 +227,8 @@ prologue_declaration:
| "%debug" { debug_flag = true; }
| "%define" variable content.opt
{
- muscle_percent_define_insert ($2, @2, $3);
+ muscle_percent_define_insert ($2, @2, $3,
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
}
| "%defines" { defines_flag = true; }
| "%defines" STRING
@@ -270,12 +271,14 @@ prologue_declaration:
`%define api.pure' in a backward-compatible manner here. First, don't
complain if %pure-parser is specified multiple times. */
if (!muscle_find_const ("percent_define(api.pure)"))
- muscle_percent_define_insert ("api.pure", @1, "");
+ muscle_percent_define_insert ("api.pure", @1, "",
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
/* In all cases, use api.pure now so that the backend doesn't complain if
the skeleton ignores api.pure, but do warn now if there's a previous
conflicting definition from an actual %define. */
if (!muscle_percent_define_flag_if ("api.pure"))
- muscle_percent_define_insert ("api.pure", @1, "");
+ muscle_percent_define_insert ("api.pure", @1, "",
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
}
| "%require" STRING { version_check (&@2, $2); }
| "%skeleton" STRING
diff --git a/tests/input.at b/tests/input.at
index 1eaf482..911f998 100644
--- a/tests/input.at
+++ b/tests/input.at
@@ -918,27 +918,49 @@ input.y:5.9-16: warning: %define variable `special2' is
not used
AT_CLEANUP
-## ------------------- ##
-## %define, --define. ##
-## ------------------- ##
+## ----------------------------------- ##
+## %define, --define, --force-define. ##
+## ----------------------------------- ##
-AT_SETUP([%define, --define])
+AT_SETUP([%define, --define, --force-define])
+
+AT_DATA([skel.c],
+[[m4@&address@hidden(0)@
address@hidden(b4_parser_file_name@)@
+[var-dd: ]b4_percent_define_get([[var-dd]])[
+var-ff: ]b4_percent_define_get([[var-ff]])[
+var-dg: ]b4_percent_define_get([[var-dg]])[
+var-dfg: ]b4_percent_define_get([[var-dfg]])[
+var-fd: ]b4_percent_define_get([[var-fd]])
+m4@&address@hidden(0)
+]])
AT_DATA([input.y],
-[[%define var "value1"
+[[%define var-dg "gram"
+%define var-dfg "gram"
%%
start: ;
]])
-AT_BISON_CHECK([[-DFOO -DFOO -Dvar=value input.y]], [0], [],
-[[<command line>:3: warning: %define variable `FOO' redefined
-<command line>:2: warning: previous definition
-input.y:1.9-11: warning: %define variable `var' redefined
-<command line>:4: warning: previous definition
-<command line>:2: warning: %define variable `FOO' is not used
-<command line>:3: warning: %define variable `FOO' is not used
-<command line>:4: warning: %define variable `var' is not used
-input.y:1.9-11: warning: %define variable `var' is not used
+AT_BISON_CHECK([[-Dvar-dd=cmd-d1 -Dvar-dd=cmd-d2 \
+ -Fvar-ff=cmd-f1 -Fvar-ff=cmd-f2 \
+ -Dvar-dg=cmd-d \
+ -Dvar-dfg=cmd-d -Fvar-dfg=cmd-f \
+ -Fvar-fd=cmd-f -Dvar-fd=cmd-d \
+ -Dunused-d -Funused-f \
+ --skeleton ./skel.c input.y]], [0], [],
+[[input.y:1.9-14: warning: %define variable `var-dg' redefined
+<command line>:6: warning: previous definition
+<command line>:11: warning: %define variable `unused-d' is not used
+<command line>:12: warning: %define variable `unused-f' is not used
+]])
+
+AT_CHECK([[cat input.tab.c]], [[0]],
+[[var-dd: cmd-d2
+var-ff: cmd-f2
+var-dg: gram
+var-dfg: cmd-f
+var-fd: cmd-d
]])
AT_CLEANUP
--
1.5.4.3
- [PATCH] -F/--force-define and relative %define/-D/--define priorities.,
Joel E. Denny <=