/* 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.
#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
{
- const char *key;
- char *value;
+ char const *key;
+ char const *value;
+ char *storage;
} muscle_entry;
/* An obstack used to create some entries. */
| 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)
{
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);
`------------------------------------------------------------*/
void
-muscle_insert (const char *key, char *value)
+muscle_insert (char const *key, char const *value)
{
muscle_entry probe;
muscle_entry *entry;
entry->key = key;
hash_insert (muscle_table, entry);
}
+ else
+ free (entry->storage);
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
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);
- 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);
- entry->value = xstrdup (new_val);
+ entry->value = entry->storage = xstrdup (new_val);
obstack_free (&muscle_obstack, new_val);
}
}
obstack_1grow (&muscle_obstack, 0);
extension = obstack_finish (&muscle_obstack);
muscle_grow (key, extension, "");
+ obstack_free (&muscle_obstack, extension);
}
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;
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;
}