]> git.saurik.com Git - bison.git/blobdiff - src/muscle_tab.c
2007-02-07 Paolo Bonzini <bonzini@gnu.org>
[bison.git] / src / muscle_tab.c
index 6ceb71f332debbe5d339ec36771ebfe175d029fb..5192fc5c940b95ddf1fc062cb8cb488586205d11 100644 (file)
@@ -1,6 +1,6 @@
 /* Muscle table manager for Bison.
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
    Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
@@ -123,9 +123,11 @@ muscle_insert (char const *key, char const *value)
       entry = xmalloc (sizeof *entry);
       entry->key = key;
       hash_insert (muscle_table, entry);
-      entry->storage = NULL;
     }
+  else
+    free (entry->storage);
   entry->value = value;
+  entry->storage = NULL;
 }
 
 
@@ -189,37 +191,61 @@ muscle_code_grow (const char *key, const char *val, location loc)
 }
 
 
-/*-------------------------------------------------------------------.
-| MUSCLE is an M4 list of pairs.  Create or extend it with the pair  |
-| (A1, A2).  Note that because the muscle values are output *double* |
-| quoted, one needs to strip the first level of quotes to reach the  |
-| list itself.                                                       |
-`-------------------------------------------------------------------*/
-
 void muscle_pair_list_grow (const char *muscle,
                            const char *a1, const char *a2)
 {
   char *pair;
-  obstack_fgrow2 (&muscle_obstack, "[[[%s]], [[%s]]]", a1, a2);
+  obstack_sgrow (&muscle_obstack, "[[[");
+  MUSCLE_OBSTACK_SGROW (&muscle_obstack, a1);
+  obstack_sgrow (&muscle_obstack, "]], [[");
+  MUSCLE_OBSTACK_SGROW (&muscle_obstack, a2);
+  obstack_sgrow (&muscle_obstack, "]]]");
   obstack_1grow (&muscle_obstack, 0);
   pair = obstack_finish (&muscle_obstack);
   muscle_grow (muscle, pair, ",\n");
   obstack_free (&muscle_obstack, pair);
 }
 
-/*-------------------------------.
-| Find the value of muscle KEY.  |
-`-------------------------------*/
+
+/*----------------------------------------------------------------------------.
+| Find the value of muscle KEY.  Unlike MUSCLE_FIND, this is always reliable  |
+| to determine whether KEY has a value.                                       |
+`----------------------------------------------------------------------------*/
+
+char const *
+muscle_find_const (char const *key)
+{
+  muscle_entry probe;
+  muscle_entry *result = NULL;
+
+  probe.key = key;
+  result = hash_lookup (muscle_table, &probe);
+  if (result)
+    return result->value;
+  return NULL;
+}
+
+
+/*----------------------------------------------------------------------------.
+| Find the value of muscle KEY.  Abort if muscle_insert was invoked more      |
+| recently than muscle_grow for KEY since muscle_find can't return a          |
+| char const *.                                                               |
+`----------------------------------------------------------------------------*/
 
 char *
-muscle_find (const char *key)
+muscle_find (char const *key)
 {
   muscle_entry probe;
   muscle_entry *result = NULL;
 
   probe.key = key;
   result = hash_lookup (muscle_table, &probe);
-  return result ? result->value : NULL;
+  if (result)
+    {
+      aver (result->value == result->storage);
+      return result->storage;
+    }
+  return NULL;
 }
 
 
@@ -252,3 +278,31 @@ muscles_m4_output (FILE *out)
 {
   hash_do_for_each (muscle_table, muscle_m4_output_processor, out);
 }
+
+void
+muscle_boundary_grow (char const *key, boundary bound)
+{
+  char *extension;
+  MUSCLE_OBSTACK_SGROW (&muscle_obstack, bound.file);
+  obstack_1grow (&muscle_obstack, ':');
+  obstack_fgrow1 (&muscle_obstack, "%d", bound.line);
+  obstack_1grow (&muscle_obstack, '.');
+  obstack_fgrow1 (&muscle_obstack, "%d", bound.column);
+  obstack_1grow (&muscle_obstack, '\0');
+  extension = obstack_finish (&muscle_obstack);
+  muscle_grow (key, extension, "");
+  obstack_free (&muscle_obstack, extension);
+}
+
+void
+muscle_grow_user_name_list (char const *key, char const *user_name,
+                            location loc)
+{
+  muscle_grow (key, "[[[[", ",");
+  muscle_grow (key, user_name, "");
+  muscle_grow (key, "]], [[", "");
+  muscle_boundary_grow (key, loc.start);
+  muscle_grow (key, "]], [[", "");
+  muscle_boundary_grow (key, loc.end);
+  muscle_grow (key, "]]]]", "");
+}