/* Muscle table manager for Bison.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2001-2011 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
/* First insertion in the hash. */
entry = xmalloc (sizeof *entry);
entry->key = key;
- hash_insert (muscle_table, entry);
+ if (!hash_insert (muscle_table, entry))
+ xalloc_die ();
}
else
free (entry->storage);
/* First insertion in the hash. */
entry = xmalloc (sizeof *entry);
entry->key = key;
- hash_insert (muscle_table, entry);
+ if (!hash_insert (muscle_table, entry))
+ xalloc_die ();
entry->value = entry->storage = xstrdup (val);
}
else
muscle_grow (key, "]]", "");
}
-#define MUSCLE_USER_NAME_CONVERT(NAME, PREFIX, USER_NAME, SUFFIX) \
-do { \
- char *tmp; \
- size_t length = strlen ((USER_NAME)); \
- tmp = xmalloc (sizeof (PREFIX) - 1 + length + sizeof (SUFFIX)); \
- strcpy (tmp, (PREFIX)); \
- strcpy (tmp + sizeof (PREFIX) - 1, (USER_NAME)); \
- strcpy (tmp + sizeof (PREFIX) - 1 + length, (SUFFIX)); \
- (NAME) = uniqstr_new (tmp); \
- free (tmp); \
-} while (0)
+/** If the \a variable name is obsolete, return the name to use,
+ * otherwise \a variable. */
+static
+char const *
+muscle_percent_variable_update (char const *variable)
+{
+ typedef struct
+ {
+ const char *obsolete;
+ const char *updated;
+ } conversion_type;
+ const conversion_type conversion[] =
+ {
+ { "api.push_pull", "api.push-pull", },
+ { "lr.keep_unreachable_states", "lr.keep-unreachable-states", },
+ { "namespace", "api.namespace", },
+ };
+ int i;
+ for (i = 0; i < sizeof conversion / sizeof *conversion; ++i)
+ if (!strcmp (conversion[i].obsolete, variable))
+ return conversion[i].updated;
+ return variable;
+}
void
muscle_percent_define_insert (char const *variable, location variable_loc,
- char const *value)
+ char const *value,
+ muscle_percent_define_how how)
{
char const *name;
char const *loc_name;
char const *syncline_name;
+ char const *how_name;
- MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
- MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")");
- MUSCLE_USER_NAME_CONVERT (syncline_name,
- "percent_define_syncline(", variable, ")");
+ /* Permit certain names with underscores for backward compatibility. */
+ variable = muscle_percent_variable_update (variable);
- if (muscle_find_const (name))
+ name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+ loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
+ syncline_name =
+ UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
+ how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
+
+ /* Command-line options are processed before the grammar file. */
+ if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
+ && muscle_find_const (name))
{
- warn_at (variable_loc, _("%s `%s' redefined"),
- "%define variable", variable);
- warn_at (muscle_percent_define_get_loc (variable),
- _("previous definition"));
+ muscle_percent_define_how how_old =
+ atoi (muscle_find_const (how_name));
+ if (how_old == MUSCLE_PERCENT_DEFINE_F)
+ return;
+ complain_at (variable_loc, _("%%define variable `%s' redefined"),
+ variable);
+ complain_at (muscle_percent_define_get_loc (variable),
+ _("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);
}
/* This is used for backward compatibility, e.g., "%define api.pure"
{
char const *val = value ? "" : "false";
char const *name;
- MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
+ name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
/* %pure-parser is deprecated in favor of `%define api.pure', so use
`%define api.pure' in a backward-compatible manner here. First,
don't complain if %pure-parser is specified multiple times. */
if (!muscle_find_const (name))
- muscle_percent_define_insert (variable, loc, val);
+ muscle_percent_define_insert (variable, loc, val,
+ 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 (variable) != value)
- muscle_percent_define_insert (variable, loc, val);
+ muscle_percent_define_insert (variable, loc, val,
+ MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
}
char *
char const *usage_name;
char *value;
- MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
- MUSCLE_USER_NAME_CONVERT (usage_name, "percent_define_bison_variables(",
- variable, ")");
+ name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+ usage_name = UNIQSTR_CONCAT ("percent_define_bison_variables(",
+ variable, ")");
muscle_insert (usage_name, "");
value = muscle_string_decode (name);
muscle_percent_define_get_loc (char const *variable)
{
char const *loc_name;
- MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")");
+ loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
if (!muscle_find_const (loc_name))
- fatal(_("undefined %%define variable `%s' passed to muscle_percent_define_get_loc"),
- variable);
+ fatal(_("undefined %%define variable `%s' passed to"
+ " muscle_percent_define_get_loc"), variable);
return muscle_location_decode (loc_name);
}
{
char const *syncline_name;
char const *syncline;
- MUSCLE_USER_NAME_CONVERT (syncline_name,
- "percent_define_syncline(", variable, ")");
+ syncline_name =
+ UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
syncline = muscle_find_const (syncline_name);
if (!syncline)
- fatal(_("undefined %%define variable `%s' passed to muscle_percent_define_get_syncline"),
- variable);
+ fatal(_("undefined %%define variable `%s' passed to"
+ " muscle_percent_define_get_syncline"), variable);
return syncline;
}
char const *usage_name;
char const *value;
- MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
- MUSCLE_USER_NAME_CONVERT (usage_name, "percent_define_bison_variables(",
- variable, ")");
+ name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+ usage_name =
+ UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")");
value = muscle_find_const (name);
if (value)
char const *invalid_boolean_name;
bool result = false;
- MUSCLE_USER_NAME_CONVERT (invalid_boolean_name,
- "percent_define_invalid_boolean(", variable, ")");
+ invalid_boolean_name =
+ UNIQSTR_CONCAT ("percent_define_invalid_boolean(", variable, ")");
if (muscle_percent_define_ifdef (variable))
{
char const *name;
char const *loc_name;
char const *syncline_name;
- MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
- MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")");
- MUSCLE_USER_NAME_CONVERT (syncline_name,
- "percent_define_syncline(", variable, ")");
+ name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
+ loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
+ syncline_name =
+ UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
if (!muscle_find_const (name))
{
location loc;
{
for (; *values; ++values)
{
- char const *variable = *values;
+ char const * const *variablep = values;
char const *name;
char *value;
- MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")");
+ name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")");
value = muscle_string_decode (name);
if (value)
{
- bool valid = false;
for (++values; *values; ++values)
{
if (0 == strcmp (value, *values))
- {
- valid = true;
- while (*values)
- ++values;
- break;
- }
+ break;
+ }
+ if (!*values)
+ {
+ location loc = muscle_percent_define_get_loc (*variablep);
+ complain_at(loc,
+ _("invalid value for %%define variable `%s': `%s'"),
+ *variablep, value);
+ for (values = variablep + 1; *values; ++values)
+ complain_at (loc, _("accepted value: `%s'"), *values);
+ }
+ else
+ {
+ while (*values)
+ ++values;
}
- if (!valid)
- complain_at(muscle_percent_define_get_loc (variable),
- _("invalid value for %%define variable `%s': `%s'"),
- variable, value);
free (value);
}
else
- fatal(_("undefined %%define variable `%s' passed to muscle_percent_define_check_values"),
- variable);
+ fatal(_("undefined %%define variable `%s' passed to"
+ " muscle_percent_define_check_values"),
+ *variablep);
}
}
char const *code, location code_loc)
{
char const *name;
- MUSCLE_USER_NAME_CONVERT (name, "percent_code(", qualifier, ")");
+ name = UNIQSTR_CONCAT ("percent_code(", qualifier, ")");
muscle_code_grow (name, code, code_loc);
muscle_user_name_list_grow ("percent_code_user_qualifiers", qualifier,
qualifier_loc);