]> git.saurik.com Git - bison.git/blobdiff - src/muscle_tab.c
hash: check insertion for memory exhaustion.
[bison.git] / src / muscle_tab.c
index 0265e45a7b69f3469b00eb46a745c1518cee3ba4..c25b519d1fa9ab92c3e00c11695c7004827265d4 100644 (file)
@@ -120,7 +120,8 @@ muscle_insert (char const *key, char const *value)
       /* 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);
@@ -149,7 +150,8 @@ muscle_grow (const char *key, const char *val, const char *separator)
       /* 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
@@ -401,32 +403,57 @@ 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")
+      || 0 == strcmp (variable, "lr.keep_unreachable_states"))
+    {
+      variable_tr = strdup (variable);
+      tr (variable_tr, '_', '-');
+      variable = variable_tr;
+    }
 
   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)
+        {
+          free (variable_tr);
+          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);
+
+  free (variable_tr);
 }
 
 char *
@@ -553,35 +580,40 @@ muscle_percent_define_check_values (char const * const *values)
 {
   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);
     }
 }