1 /* Muscle table manager for Bison. 
   3    Copyright (C) 2001, 2002 Free Software Foundation, Inc. 
   5    This file is part of Bison, the GNU Compiler Compiler. 
   7    Bison is free software; you can redistribute it and/or modify 
   8    it under the terms of the GNU General Public License as published by 
   9    the Free Software Foundation; either version 2, or (at your option) 
  12    Bison is distributed in the hope that it will be useful, 
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15    GNU General Public License for more details. 
  17    You should have received a copy of the GNU General Public License 
  18    along with Bison; see the file COPYING.  If not, write to 
  19    the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
  20    Boston, MA 02111-1307, USA.  */ 
  28 #include "muscle_tab.h" 
  37 /* An obstack used to create some entries.  */ 
  38 struct obstack muscle_obstack
; 
  40 /* Initial capacity of muscles hash table.  */ 
  41 #define HT_INITIAL_CAPACITY 257 
  43 struct hash_table 
*muscle_table 
= NULL
; 
  46 hash_compare_muscles (void const *x
, void const *y
) 
  48   muscle_entry 
const *m1 
= x
; 
  49   muscle_entry 
const *m2 
= y
; 
  50   return strcmp (m1
->key
, m2
->key
) == 0; 
  54 hash_muscle (const void *x
, unsigned int tablesize
) 
  56   muscle_entry 
const *m 
= x
; 
  57   return hash_string (m
->key
, tablesize
); 
  60 /*-----------------------------------------------------------------. 
  61 | Create the MUSCLE_TABLE, and initialize it with default values.  | 
  62 | Also set up the MUSCLE_OBSTACK.                                  | 
  63 `-----------------------------------------------------------------*/ 
  68   /* Initialize the muscle obstack.  */ 
  69   obstack_init (&muscle_obstack
); 
  71   muscle_table 
= hash_initialize (HT_INITIAL_CAPACITY
, NULL
, hash_muscle
, 
  72                                   hash_compare_muscles
, free
); 
  74   /* Version and input file.  */ 
  75   MUSCLE_INSERT_STRING ("version", VERSION
); 
  76   MUSCLE_INSERT_C_STRING ("filename", grammar_file
); 
  80 /*------------------------------------------------------------. 
  81 | Free all the memory consumed by the muscle machinery only.  | 
  82 `------------------------------------------------------------*/ 
  87   hash_free (muscle_table
); 
  88   obstack_free (&muscle_obstack
, NULL
); 
  93 /*------------------------------------------------------------. 
  94 | Insert (KEY, VALUE).  If KEY already existed, overwrite the | 
  96 `------------------------------------------------------------*/ 
  99 muscle_insert (const char *key
, char *value
) 
 102   muscle_entry 
*entry 
= NULL
; 
 105   entry 
= hash_lookup (muscle_table
, &probe
); 
 109       /* First insertion in the hash. */ 
 112       hash_insert (muscle_table
, entry
); 
 114   entry
->value 
= value
; 
 118 /*-------------------------------------------------------------------. 
 119 | Insert (KEY, VALUE).  If KEY already existed, overwrite the        | 
 120 | previous value.  Uses MUSCLE_OBSTACK.  De-allocates the previously | 
 121 | associated value.  VALUE and SEPARATOR are copied.                 | 
 122 `-------------------------------------------------------------------*/ 
 125 muscle_grow (const char *key
, const char *val
, const char *separator
) 
 128   muscle_entry 
*entry 
= NULL
; 
 131   entry 
= hash_lookup (muscle_table
, &probe
); 
 135       /* First insertion in the hash. */ 
 138       hash_insert (muscle_table
, entry
); 
 139       entry
->value 
= xstrdup (val
); 
 143       /* Grow the current value. */ 
 145       obstack_sgrow (&muscle_obstack
, entry
->value
); 
 147       obstack_sgrow (&muscle_obstack
, separator
); 
 148       obstack_sgrow (&muscle_obstack
, val
); 
 149       obstack_1grow (&muscle_obstack
, 0); 
 150       new_val 
= obstack_finish (&muscle_obstack
); 
 151       entry
->value 
= xstrdup (new_val
); 
 152       obstack_free (&muscle_obstack
, new_val
); 
 157 /*-------------------------------------------------------------------. 
 158 | MUSCLE is an M4 list of pairs.  Create or extend it with the pair  | 
 159 | (A1, A2).  Note that because the muscle values are output *double* | 
 160 | quoted, one needs to strip the first level of quotes to reach the  | 
 162 `-------------------------------------------------------------------*/ 
 164 void muscle_pair_list_grow (const char *muscle
, 
 165                             const char *a1
, const char *a2
) 
 168   obstack_fgrow2 (&muscle_obstack
, "[[[%s]], [[%s]]]", a1
, a2
); 
 169   obstack_1grow (&muscle_obstack
, 0); 
 170   pair 
= obstack_finish (&muscle_obstack
); 
 171   muscle_grow (muscle
, pair
, ",\n"); 
 172   obstack_free (&muscle_obstack
, pair
); 
 175 /*-------------------------------. 
 176 | Find the value of muscle KEY.  | 
 177 `-------------------------------*/ 
 180 muscle_find (const char *key
) 
 183   muscle_entry 
*result 
= NULL
; 
 186   result 
= hash_lookup (muscle_table
, &probe
); 
 187   return result 
? result
->value 
: NULL
; 
 191 /*------------------------------------------------. 
 192 | Output the definition of ENTRY as a m4_define.  | 
 193 `------------------------------------------------*/ 
 196 muscle_m4_output (muscle_entry 
*entry
, FILE *out
) 
 198   fprintf (out
, "m4_define([b4_%s],\n", entry
->key
); 
 199   fprintf (out
, "[[%s]])\n\n\n", entry
->value
); 
 204 muscle_m4_output_processor (void *entry
, void *out
) 
 206   return muscle_m4_output (entry
, out
); 
 210 /*----------------------------------------------------------------. 
 211 | Output the definition of all the current muscles into a list of | 
 213 `----------------------------------------------------------------*/ 
 216 muscles_m4_output (FILE *out
) 
 218   hash_do_for_each (muscle_table
, muscle_m4_output_processor
, out
);