/* 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, "]]", "");
}
+/** 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;
+}
+
#define MUSCLE_USER_NAME_CONVERT(NAME, PREFIX, USER_NAME, SUFFIX) \
do { \
char *tmp; \
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;
+
+ /* Permit certain names with underscores for backward compatibility. */
+ variable = muscle_percent_variable_update (variable);
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, ")");
+ 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))
{
- 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, _("%s `%s' redefined"),
+ "%define variable", 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"
`%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 *
{
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, ")");
+ MUSCLE_USER_NAME_CONVERT (name, "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);
}
}