]> git.saurik.com Git - bison.git/blobdiff - src/muscle_tab.c
Add lib/subpipe.c.
[bison.git] / src / muscle_tab.c
index d487a4a0bface5daf520979b8663aecc8ba55dfb..085b838dfea01864bcda6f0a88505f32ff9dcdcf 100644 (file)
@@ -1,5 +1,5 @@
-/* Macro table manager for Bison,
-   Copyright 1984, 1989, 2000 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.
 
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <string.h>
-
-#include "xalloc.h"
 #include "system.h"
 #include "hash.h"
 #include "files.h"
 #include "muscle_tab.h"
 #include "getargs.h"
 
 #include "system.h"
 #include "hash.h"
 #include "files.h"
 #include "muscle_tab.h"
 #include "getargs.h"
 
-struct hash_table muscle_table;
 
 
-static unsigned long
-mhash1 (const void *item)
-{
-  return_STRING_HASH_1 (((muscle_entry_t *) item)->key);
-}
+/* 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 (((muscle_entry_t *) item)->key);
+  const muscle_entry_t *m1 = x;
+  const muscle_entry_t *m2 = y;
+  return strcmp (m1->key, m2->key) ? FALSE : TRUE;
 }
 
 }
 
-static int
-mcmp (const void *x, const void *y)
+static unsigned int
+hash_muscle (const void *x, unsigned int tablesize)
 {
 {
-  return strcmp (((muscle_entry_t*) x)->key, ((muscle_entry_t *) y)->key);
+  const muscle_entry_t *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_STRING ("filename", infile);
+
+  /* FIXME: there should probably be no default here, only in the
+     skeletons.  */
 
   /* Types.  */
 
   /* Types.  */
-  muscle_insert ("stype", "int");
-  muscle_insert ("ltype", "yyltype");
-
-  /* Tokens.  */
-  muscle_insert ("tokendef", "");
-
-  /* Tables.  */
-  muscle_insert ("rhs", "0");
-  muscle_insert ("pact", "0");
-  muscle_insert ("prhs", "0");
-  muscle_insert ("stos", "0");
-  muscle_insert ("check", "0");
-  muscle_insert ("pgoto", "0");
-  muscle_insert ("table", "0");
-  muscle_insert ("tname", "0");
-  muscle_insert ("defact", "0");
-  muscle_insert ("toknum", "0");
-  muscle_insert ("defgoto", "0");
-  muscle_insert ("translate", "0");
-
-  /* Various macros.  */
-  muscle_insert ("flag", "0");
-  muscle_insert ("last", "0");
-  muscle_insert ("pure", "0");
-  muscle_insert ("nsym", "0");
-  muscle_insert ("debug", "0");
-  muscle_insert ("final", "0");
-  muscle_insert ("maxtok", "0");
-  muscle_insert ("ntbase", "0");
-  muscle_insert ("error-verbose", "0");
-  muscle_insert ("prefix", "yy");
-  /* Default #line formatting.  */
-  muscle_insert ("linef", "#line %d %s\n");
+  MUSCLE_INSERT_STRING ("ltype", "yyltype");
 
 
-  /* No parser macros.  */
-  muscle_insert ("nnts", "0");
-  muscle_insert ("nrules", "0");
-  muscle_insert ("nstates", "0");
-  muscle_insert ("ntokens", "0");
+  /* Default #line formatting.  */
+  MUSCLE_INSERT_STRING ("linef", "#line %d %s\n");
 
   /* Stack parameters.  */
 
   /* Stack parameters.  */
-  muscle_insert ("maxdepth", "10000");
-  muscle_insert ("initdepth", "200");
+  MUSCLE_INSERT_STRING ("maxdepth", "10000");
+  MUSCLE_INSERT_STRING ("initdepth", "200");
 
   /* C++ macros.  */
 
   /* C++ macros.  */
-  muscle_insert ("name", "Parser");
+  MUSCLE_INSERT_STRING ("name", "Parser");
+}
+
+
+/*------------------------------------------------------------.
+| Free all the memory consumed by the muscle machinery only.  |
+`------------------------------------------------------------*/
+
+void
+muscle_free (void)
+{
+  hash_free (muscle_table);
+  obstack_free (&muscle_obstack, NULL);
+}
+
+
+
+/*------------------------------------------------------------.
+| Insert (KEY, VALUE).  If KEY already existed, overwrite the |
+| previous value.                                             |
+`------------------------------------------------------------*/
+
+void
+muscle_insert (const char *key, char *value)
+{
+  muscle_entry_t probe;
+  muscle_entry_t *entry = NULL;
+
+  probe.key = key;
+  entry = hash_lookup (muscle_table, &probe);
+
+  if (!entry)
+    {
+      /* First insertion in the hash. */
+      entry = XMALLOC (muscle_entry_t, 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
+muscle_grow (const char *key, const char *val, const char *separator)
+{
+  muscle_entry_t probe;
+  muscle_entry_t *entry = NULL;
+
+  probe.key = key;
+  entry = hash_lookup (muscle_table, &probe);
+
+  if (!entry)
+    {
+      /* First insertion in the hash. */
+      entry = XMALLOC (muscle_entry_t, 1);
+      entry->key = key;
+      hash_insert (muscle_table, entry);
+      entry->value = xstrdup (val);
+    }
+  else
+    {
+      /* Grow the current value. */
+      char *new_val;
+      fprintf (stderr, "<= %s + %s\n", entry->value, 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);
+      fprintf (stderr, "=> %s\n", new_val);
+      obstack_free (&muscle_obstack, new_val);
+    }
 }
 
 }
 
-void 
-muscle_insert (const char *key, const char *value)
+
+/*-------------------------------------------------------------------.
+| 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)
 {
 {
-  muscle_entry_t *pair = XMALLOC (muscle_entry_t, 1);
-  pair->key = key;
-  pair->value = value;
-  hash_insert (&muscle_table, pair);
+  char *val;
+  obstack_fgrow2 (&muscle_obstack, "[[[%s]], [[%s]]]", a1, a2);
+  obstack_1grow (&muscle_obstack, 0);
+  val = obstack_finish (&muscle_obstack);
+  muscle_grow (muscle, val, ",\n");
+  obstack_free (&muscle_obstack, val);
 }
 
 }
 
-const char*
+/*-------------------------------.
+| 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_t probe;
+  muscle_entry_t *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 int
+muscle_m4_output (muscle_entry_t *entry, FILE *out)
+{
+  fprintf (out, "m4_define([b4_%s],\n", entry->key);
+  fprintf (out, "[[%s]])\n\n\n", entry->value);
+  return 1;
+}
+
+
+/*----------------------------------------------------------------.
+| 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,
+                   (Hash_processor) muscle_m4_output,
+                   out);
 }
 }