]> git.saurik.com Git - bison.git/blobdiff - src/muscle_tab.c
Remove last commit at the request of Paul Eggert.
[bison.git] / src / muscle_tab.c
index c8c5c79d63faa050126919c2e65ccc3c582b757d..70f12dfbb507b1b8460552f5920682e9e9e09102 100644 (file)
@@ -1,6 +1,6 @@
 /* Muscle table manager for Bison.
 
 /* Muscle table manager for Bison.
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
    Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
    Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 #include "muscle_tab.h"
 #include "getargs.h"
 
 #include "muscle_tab.h"
 #include "getargs.h"
 
+/* A key-value pair, along with storage that can be reclaimed when
+   this pair is no longer needed.  */
 typedef struct
 {
 typedef struct
 {
-  const char *key;
-  char *value;
+  char const *key;
+  char const *value;
+  char *storage;
 } muscle_entry;
 
 /* An obstack used to create some entries.  */
 } muscle_entry;
 
 /* An obstack used to create some entries.  */
@@ -64,6 +67,14 @@ hash_muscle (const void *x, size_t tablesize)
 | Also set up the MUSCLE_OBSTACK.                                  |
 `-----------------------------------------------------------------*/
 
 | Also set up the MUSCLE_OBSTACK.                                  |
 `-----------------------------------------------------------------*/
 
+static void
+muscle_entry_free (void *entry)
+{
+  muscle_entry *mentry = entry;
+  free (mentry->storage);
+  free (mentry);
+}
+
 void
 muscle_init (void)
 {
 void
 muscle_init (void)
 {
@@ -71,7 +82,7 @@ muscle_init (void)
   obstack_init (&muscle_obstack);
 
   muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
   obstack_init (&muscle_obstack);
 
   muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
-                                 hash_compare_muscles, free);
+                                 hash_compare_muscles, muscle_entry_free);
 
   /* Version and input file.  */
   MUSCLE_INSERT_STRING ("version", VERSION);
 
   /* Version and input file.  */
   MUSCLE_INSERT_STRING ("version", VERSION);
@@ -98,7 +109,7 @@ muscle_free (void)
 `------------------------------------------------------------*/
 
 void
 `------------------------------------------------------------*/
 
 void
-muscle_insert (const char *key, char *value)
+muscle_insert (char const *key, char const *value)
 {
   muscle_entry probe;
   muscle_entry *entry;
 {
   muscle_entry probe;
   muscle_entry *entry;
@@ -113,14 +124,17 @@ muscle_insert (const char *key, char *value)
       entry->key = key;
       hash_insert (muscle_table, entry);
     }
       entry->key = key;
       hash_insert (muscle_table, entry);
     }
+  else
+    free (entry->storage);
   entry->value = value;
   entry->value = value;
+  entry->storage = NULL;
 }
 
 
 /*-------------------------------------------------------------------.
 }
 
 
 /*-------------------------------------------------------------------.
-| Insert (KEY, VALUE).  If KEY already existed, overwrite the        |
-| previous value.  Uses MUSCLE_OBSTACK.  De-allocates the previously |
-| associated value.  VALUE and SEPARATOR are copied.                 |
+| Append VALUE to the current value of KEY.  If KEY did not already  |
+| exist, create it.  Use MUSCLE_OBSTACK.  De-allocate the previously |
+| associated value.  Copy VALUE and SEPARATOR.                       |
 `-------------------------------------------------------------------*/
 
 void
 `-------------------------------------------------------------------*/
 
 void
@@ -138,19 +152,19 @@ muscle_grow (const char *key, const char *val, const char *separator)
       entry = xmalloc (sizeof *entry);
       entry->key = key;
       hash_insert (muscle_table, entry);
       entry = xmalloc (sizeof *entry);
       entry->key = key;
       hash_insert (muscle_table, entry);
-      entry->value = xstrdup (val);
+      entry->value = entry->storage = xstrdup (val);
     }
   else
     {
       /* Grow the current value. */
       char *new_val;
       obstack_sgrow (&muscle_obstack, entry->value);
     }
   else
     {
       /* Grow the current value. */
       char *new_val;
       obstack_sgrow (&muscle_obstack, entry->value);
-      free (entry->value);
+      free (entry->storage);
       obstack_sgrow (&muscle_obstack, separator);
       obstack_sgrow (&muscle_obstack, val);
       obstack_1grow (&muscle_obstack, 0);
       new_val = obstack_finish (&muscle_obstack);
       obstack_sgrow (&muscle_obstack, separator);
       obstack_sgrow (&muscle_obstack, val);
       obstack_1grow (&muscle_obstack, 0);
       new_val = obstack_finish (&muscle_obstack);
-      entry->value = xstrdup (new_val);
+      entry->value = entry->storage = xstrdup (new_val);
       obstack_free (&muscle_obstack, new_val);
     }
 }
       obstack_free (&muscle_obstack, new_val);
     }
 }
@@ -173,6 +187,7 @@ muscle_code_grow (const char *key, const char *val, location loc)
   obstack_1grow (&muscle_obstack, 0);
   extension = obstack_finish (&muscle_obstack);
   muscle_grow (key, extension, "");
   obstack_1grow (&muscle_obstack, 0);
   extension = obstack_finish (&muscle_obstack);
   muscle_grow (key, extension, "");
+  obstack_free (&muscle_obstack, extension);
 }
 
 
 }
 
 
@@ -194,11 +209,13 @@ void muscle_pair_list_grow (const char *muscle,
   obstack_free (&muscle_obstack, pair);
 }
 
   obstack_free (&muscle_obstack, pair);
 }
 
-/*-------------------------------.
-| Find the value of muscle KEY.  |
-`-------------------------------*/
+/*----------------------------------------------------------------------------.
+| 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*
+char *
 muscle_find (const char *key)
 {
   muscle_entry probe;
 muscle_find (const char *key)
 {
   muscle_entry probe;
@@ -206,7 +223,12 @@ muscle_find (const char *key)
 
   probe.key = key;
   result = hash_lookup (muscle_table, &probe);
 
   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;
 }
 
 
 }