/* Muscle table manager for Bison.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
+ Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
You should have received a copy of the GNU General Public License
along with Bison; see the file COPYING. If not, write to
- the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+#include <config.h>
#include "system.h"
#include <hash.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
{
- const char *key;
- char *value;
+ char const *key;
+ char const *value;
+ char *storage;
} muscle_entry;
/* An obstack used to create some entries. */
/* Initial capacity of muscles hash table. */
#define HT_INITIAL_CAPACITY 257
-struct hash_table *muscle_table = NULL;
+static struct hash_table *muscle_table = NULL;
static bool
hash_compare_muscles (void const *x, void const *y)
return strcmp (m1->key, m2->key) == 0;
}
-static unsigned int
-hash_muscle (const void *x, unsigned int tablesize)
+static size_t
+hash_muscle (const void *x, size_t tablesize)
{
muscle_entry const *m = x;
return hash_string (m->key, tablesize);
| 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);
- MUSCLE_INSERT_C_STRING ("filename", grammar_file);
+ MUSCLE_INSERT_C_STRING ("file_name", grammar_file);
}
`------------------------------------------------------------*/
void
-muscle_insert (const char *key, char *value)
+muscle_insert (char const *key, char const *value)
{
muscle_entry probe;
- muscle_entry *entry = NULL;
+ muscle_entry *entry;
probe.key = key;
entry = hash_lookup (muscle_table, &probe);
if (!entry)
{
/* First insertion in the hash. */
- MALLOC (entry, 1);
+ entry = xmalloc (sizeof *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
if (!entry)
{
/* First insertion in the hash. */
- MALLOC (entry, 1);
+ 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);
}
}
muscle_code_grow (const char *key, const char *val, location loc)
{
char *extension = NULL;
- obstack_fgrow1 (&muscle_obstack, "]b4_syncline([[%d]], [[", loc.start.line);
+ obstack_fgrow1 (&muscle_obstack, "]b4_syncline(%d, [[", loc.start.line);
MUSCLE_OBSTACK_SGROW (&muscle_obstack,
quotearg_style (c_quoting_style, loc.start.file));
obstack_sgrow (&muscle_obstack, "]])[\n");
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;
}