]> git.saurik.com Git - bison.git/blobdiff - src/muscle_tab.c
(conflicts_print): If the user specifies "%expect N", report an error
[bison.git] / src / muscle_tab.c
index 4330291668b86153840ae3477edf3a023feef112..2e7f70677ea9a6dc6e55ce626af07799b35e248d 100644 (file)
@@ -1,5 +1,6 @@
-/* Macro table manager for Bison,
-   Copyright 2001 Free Software Foundation, Inc.
+/* Muscle table manager for Bison.
+
+   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
    This file is part of Bison, the GNU Compiler Compiler.
 
    Boston, MA 02111-1307, USA.  */
 
 #include "system.h"
    Boston, MA 02111-1307, USA.  */
 
 #include "system.h"
-#include "hash.h"
+
+#include <hash.h>
+#include <quotearg.h>
+
 #include "files.h"
 #include "muscle_tab.h"
 #include "getargs.h"
 
 #include "files.h"
 #include "muscle_tab.h"
 #include "getargs.h"
 
-struct hash_table muscle_table;
-
-static unsigned long
-mhash1 (const void *item)
+typedef struct
 {
 {
-  return_STRING_HASH_1 (((const muscle_entry_t *) item)->key);
-}
+  const char *key;
+  char *value;
+} muscle_entry;
+
+/* An obstack used to create some entries.  */
+struct obstack muscle_obstack;
 
 
-static unsigned long
-mhash2 (const void *item)
+/* Initial capacity of muscles hash table.  */
+#define HT_INITIAL_CAPACITY 257
+
+struct hash_table *muscle_table = NULL;
+
+static bool
+hash_compare_muscles (void const *x, void const *y)
 {
 {
-  return_STRING_HASH_2 (((const muscle_entry_t *) item)->key);
+  muscle_entry const *m1 = x;
+  muscle_entry const *m2 = y;
+  return strcmp (m1->key, m2->key) == 0;
 }
 
 }
 
-static int
-mcmp (const void *x, const void *y)
+static unsigned int
+hash_muscle (const void *x, unsigned int tablesize)
 {
 {
-  return strcmp (((const muscle_entry_t*) x)->key,
-                ((const muscle_entry_t *) y)->key);
+  muscle_entry const *m = x;
+  return hash_string (m->key, tablesize);
 }
 
 }
 
+/*-----------------------------------------------------------------.
+| Create the MUSCLE_TABLE, and initialize it with default values.  |
+| Also set up the MUSCLE_OBSTACK.                                  |
+`-----------------------------------------------------------------*/
+
 void
 muscle_init (void)
 {
 void
 muscle_init (void)
 {
-  hash_init (&muscle_table, MTABSIZE, &mhash1, &mhash2, &mcmp);
+  /* Initialize the muscle obstack.  */
+  obstack_init (&muscle_obstack);
+
+  muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle,
+                                 hash_compare_muscles, free);
 
   /* Version and input file.  */
 
   /* Version and input file.  */
-  muscle_insert ("version", VERSION);
-  muscle_insert ("filename", infile);
+  MUSCLE_INSERT_STRING ("version", VERSION);
+  MUSCLE_INSERT_C_STRING ("filename", grammar_file);
+}
 
 
-  /* Types.  */
-  muscle_insert ("stype", "int");
-  muscle_insert ("ltype", "yyltype");
 
 
-  /* Default #line formatting.  */
-  muscle_insert ("linef", "#line %d %s\n");
+/*------------------------------------------------------------.
+| Free all the memory consumed by the muscle machinery only.  |
+`------------------------------------------------------------*/
+
+void
+muscle_free (void)
+{
+  hash_free (muscle_table);
+  obstack_free (&muscle_obstack, NULL);
+}
+
 
 
-  /* Stack parameters.  */
-  muscle_insert ("maxdepth", "10000");
-  muscle_insert ("initdepth", "200");
 
 
-  /* C++ macros.  */
-  muscle_insert ("name", "Parser");
+/*------------------------------------------------------------.
+| Insert (KEY, VALUE).  If KEY already existed, overwrite the |
+| previous value.                                             |
+`------------------------------------------------------------*/
+
+void
+muscle_insert (const char *key, char *value)
+{
+  muscle_entry probe;
+  muscle_entry *entry = NULL;
+
+  probe.key = key;
+  entry = hash_lookup (muscle_table, &probe);
+
+  if (!entry)
+    {
+      /* First insertion in the hash. */
+      MALLOC (entry, 1);
+      entry->key = key;
+      hash_insert (muscle_table, entry);
+    }
+  entry->value = value;
 }
 
 }
 
+
+/*-------------------------------------------------------------------.
+| 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.                 |
+`-------------------------------------------------------------------*/
+
 void
 void
-muscle_insert (const char *key, const char *value)
+muscle_grow (const char *key, const char *val, const char *separator)
 {
 {
-  muscle_entry_t *pair = XMALLOC (muscle_entry_t, 1);
-  pair->key = key;
-  pair->value = value;
-  hash_insert (&muscle_table, pair);
+  muscle_entry probe;
+  muscle_entry *entry = NULL;
+
+  probe.key = key;
+  entry = hash_lookup (muscle_table, &probe);
+
+  if (!entry)
+    {
+      /* First insertion in the hash. */
+      MALLOC (entry, 1);
+      entry->key = key;
+      hash_insert (muscle_table, entry);
+      entry->value = xstrdup (val);
+    }
+  else
+    {
+      /* Grow the current value. */
+      char *new_val;
+      obstack_sgrow (&muscle_obstack, entry->value);
+      free (entry->value);
+      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);
+      obstack_free (&muscle_obstack, new_val);
+    }
 }
 
 }
 
-const char*
+
+/*-------------------------------------------------------------------.
+| 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_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.  |
+`-------------------------------*/
+
+char*
 muscle_find (const char *key)
 {
 muscle_find (const char *key)
 {
-  muscle_entry_t pair = { key, 0 };
-  muscle_entry_t *result = hash_find_item (&muscle_table, &pair);
-  return result ? result->value : 0;
+  muscle_entry probe;
+  muscle_entry *result = NULL;
+
+  probe.key = key;
+  result = hash_lookup (muscle_table, &probe);
+  return result ? result->value : NULL;
+}
+
+
+/*------------------------------------------------.
+| Output the definition of ENTRY as a m4_define.  |
+`------------------------------------------------*/
+
+static inline bool
+muscle_m4_output (muscle_entry *entry, FILE *out)
+{
+  fprintf (out, "m4_define([b4_%s],\n", entry->key);
+  fprintf (out, "[[%s]])\n\n\n", entry->value);
+  return true;
+}
+
+static bool
+muscle_m4_output_processor (void *entry, void *out)
+{
+  return muscle_m4_output (entry, out);
+}
+
+
+/*----------------------------------------------------------------.
+| Output the definition of all the current muscles into a list of |
+| m4_defines.                                                     |
+`----------------------------------------------------------------*/
+
+void
+muscles_m4_output (FILE *out)
+{
+  hash_do_for_each (muscle_table, muscle_m4_output_processor, out);
 }
 }