/[m4]/m4/m4/symtab.c
ViewVC logotype

Diff of /m4/m4/symtab.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.21 by gary, Sat Sep 8 01:56:34 2001 UTC revision 1.22 by gary, Thu Sep 20 03:48:05 2001 UTC
# Line 18  Line 18 
18     02111-1307  USA     02111-1307  USA
19  */  */
20    
21    #include "m4private.h"
22    
23    #define DEBUG_SYM               /* Define this to see runtime debug info.  */
24    #undef DEBUG_SYM
25    
26  /* This file handles all the low level work around the symbol table.  The  /* This file handles all the low level work around the symbol table.  The
27     symbol table is an abstract hash table type implemented in hash.c.  Each     symbol table is an abstract hash table type implemented in hash.c.  Each
28     symbol is represented by `struct m4_symbol', which is stored in the hash     symbol is represented by `struct m4_symbol', which is stored in the hash
# Line 27  Line 32 
32     simply ordered on the stack by age.  The most recently pushed definition     simply ordered on the stack by age.  The most recently pushed definition
33     will then always be the first found.  */     will then always be the first found.  */
34    
 #include "m4private.h"  
   
35  static size_t   m4_symtab_hash          (const void *key);  static size_t   m4_symtab_hash          (const void *key);
36  static int      m4_symtab_cmp           (const void *key, const void *try);  static int      m4_symtab_cmp           (const void *key, const void *try);
37  static void     m4_token_data_delete    (m4_token_data *data);  static void     m4_token_data_delete    (m4_symbol *data);
38  static void     m4_symbol_pop           (m4_symbol *symbol);  static void     m4_symbol_pop           (m4_symbol **psymbol);
39  static void     m4_symbol_del           (m4_symbol *symbol);  static void     m4_symbol_del           (m4_symbol **psymbol);
40    static int      m4_symbol_destroy       (const char *name, m4_symbol *symbol,
41                                             void *data);
42    
43    
44  /* Pointer to symbol table.  */  /* Pointer to symbol table.  */
# Line 47  m4_symtab_init (void) Line 52  m4_symtab_init (void)
52    m4_symtab = m4_hash_new (m4_symtab_hash, m4_symtab_cmp);    m4_symtab = m4_hash_new (m4_symtab_hash, m4_symtab_cmp);
53  }  }
54    
55    int
56    m4_symbol_destroy (const char *name, m4_symbol *symbol, void *data)
57    {
58      m4_symbol_delete (name);
59      return 0;
60    }
61    
62    void
63    m4_symtab_exit (void)
64    {
65      m4_symtab_apply (m4_symbol_destroy, NULL);
66      m4_hash_delete (m4_symtab);
67      m4_hash_exit ();
68    }
69    
70  /* Return a hashvalue for a string, from GNU-emacs.  */  /* Return a hashvalue for a string, from GNU-emacs.  */
71  size_t  size_t
72  m4_symtab_hash (const void *key)  m4_symtab_hash (const void *key)
# Line 74  m4_symtab_cmp (const void *key, const vo Line 94  m4_symtab_cmp (const void *key, const vo
94    
95    
96  void  void
97  m4_token_data_delete (m4_token_data *data)  m4_token_data_delete (m4_symbol *data)
98  {  {
99    assert (data);    assert (data);
100    assert (M4_TOKEN_DATA_NEXT (data) == 0);    assert (M4_SYMBOL_NEXT (data) == 0);
101    
102    if (M4_TOKEN_DATA_TYPE (data) == M4_TOKEN_TEXT)    if (M4_SYMBOL_TYPE (data) == M4_TOKEN_TEXT)
103      XFREE (M4_TOKEN_DATA_TEXT (data));      XFREE (M4_SYMBOL_TEXT (data));
104    
105    XFREE (data);    XFREE (data);
106  }  }
107    
108    
109  void  void
110  m4_symbol_pop (m4_symbol *symbol)  m4_symbol_pop (m4_symbol **psymbol)
111  {  {
112    m4_token_data *stale;    m4_symbol *stale;
113    
114    assert (symbol);    assert (psymbol);
115    assert (M4_SYMBOL_DATA_NEXT (symbol));    assert (*psymbol);
116    
117    stale                         = M4_SYMBOL_DATA (symbol);    stale  = *psymbol;
118    M4_SYMBOL_DATA (symbol)       = M4_TOKEN_DATA_NEXT (stale);    *psymbol = M4_SYMBOL_NEXT (stale);
119    
120  #ifndef NDEBUG  #ifndef NDEBUG
121    M4_TOKEN_DATA_NEXT (stale) = 0;    M4_SYMBOL_NEXT (stale) = 0;
122  #endif  #endif
123    m4_token_data_delete (stale);    m4_token_data_delete (stale);
124  }  }
125    
126    
127  /* Free all storage associated with a symbol.  */  /* Free all storage associated with a symbol.  */
128  void  void
129  m4_symbol_del (m4_symbol *symbol)  m4_symbol_del (m4_symbol **psymbol)
130  {  {
131    assert (symbol);    assert (psymbol);
132      assert (*psymbol);
   while (M4_SYMBOL_DATA_NEXT (symbol))  
     m4_symbol_pop (symbol);  
   
   assert (M4_SYMBOL_DATA_NEXT (symbol) == 0);  
   
   if (M4_SYMBOL_TYPE (symbol) == M4_TOKEN_TEXT)  
     XFREE (M4_SYMBOL_TEXT (symbol));  
133    
134    XFREE (M4_SYMBOL_DATA (symbol));    while (*psymbol)
135    XFREE (symbol);      m4_symbol_pop (psymbol);
136  }  }
137    
138    
# Line 142  m4_symbol_pushdef (const char *name) Line 157  m4_symbol_pushdef (const char *name)
157    /* Insert a name in the symbol table.  If there is already a symbol    /* Insert a name in the symbol table.  If there is already a symbol
158       with the name, push the new value on top of the value stack for       with the name, push the new value on top of the value stack for
159       this symbol.  */       this symbol.  */
160    m4_symbol *symbol    = 0;    m4_symbol *symbol         = XCALLOC (m4_symbol, 1);;
161    m4_token_data *value = XCALLOC (m4_token_data, 1);    M4_SYMBOL_TYPE (symbol)       = M4_TOKEN_VOID;
162    
163    if (psymbol)    if (psymbol)
164      {      {
165        symbol = *psymbol;        M4_SYMBOL_NEXT (symbol) = *psymbol;
166        M4_TOKEN_DATA_NEXT (value) = M4_SYMBOL_DATA (symbol);        *psymbol = symbol;
167      }      }
168    else    else
     symbol = XCALLOC (m4_symbol, 1);  
   
   M4_SYMBOL_DATA (symbol)       = value;  
   M4_SYMBOL_TYPE (symbol)       = M4_TOKEN_VOID;  
   
   if (!psymbol)  
169      m4_hash_insert (m4_symtab, xstrdup (name), symbol);      m4_hash_insert (m4_symtab, xstrdup (name), symbol);
170    
171    return symbol;    return symbol;
# Line 167  m4_symbol_pushdef (const char *name) Line 176  m4_symbol_pushdef (const char *name)
176  m4_symbol *  m4_symbol *
177  m4_symbol_define (const char *name)  m4_symbol_define (const char *name)
178  {  {
179    m4_symbol *res = m4_symbol_lookup (name);    m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (m4_symtab, name);
180    if (res)    if (psymbol)
181      return res;      return *psymbol;
182    else    else
183      m4_symbol_pushdef (name);      return m4_symbol_pushdef (name);
184  }  }
185    
186    
# Line 183  m4_symbol_popdef (const char *name) Line 192  m4_symbol_popdef (const char *name)
192    
193    assert (psymbol);    assert (psymbol);
194    
195    if (M4_SYMBOL_DATA_NEXT (*psymbol))    if (M4_SYMBOL_NEXT (*psymbol))
196      m4_symbol_pop (*psymbol);      m4_symbol_pop (psymbol);
197    else    else
198      {      {
199        xfree (m4_hash_remove (m4_symtab, name));        xfree (m4_hash_remove (m4_symtab, name));
200        m4_symbol_del (*psymbol);        m4_symbol_del (psymbol);
201      }      }
202  }  }
203    
# Line 200  m4_symbol_delete (const char *name) Line 209  m4_symbol_delete (const char *name)
209    m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (m4_symtab, name);    m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (m4_symtab, name);
210    
211    assert (psymbol);    assert (psymbol);
212    
213    #ifdef DEBUG_SYM
214      M4_DEBUG_MESSAGE1("symbol %s recycled.", name);
215    #endif
216    
217    xfree (m4_hash_remove (m4_symtab, name));    xfree (m4_hash_remove (m4_symtab, name));
218    m4_symbol_del (*psymbol);    m4_symbol_del (psymbol);
219  }  }
220    
221    
# Line 253  m4_symtab_remove_module_references (lt_d Line 267  m4_symtab_remove_module_references (lt_d
267    
268    assert (handle);    assert (handle);
269    
270      /* Traverse each symbol name in the hash table.  */
271    while ((place = m4_hash_iterator_next (m4_symtab, place)))    while ((place = m4_hash_iterator_next (m4_symtab, place)))
272      {      {
273        m4_symbol *symbol = (m4_symbol *) m4_hash_iterator_value (place);        m4_symbol **psymbol = (m4_symbol **) m4_hash_iterator_value (place);
274        m4_token_data *data = M4_SYMBOL_DATA (symbol);        m4_symbol *current  = *psymbol;
275    
276        /* Purge any shadowed references.  */        /* Examine each value in the value stack associated with this
277        while (M4_TOKEN_DATA_NEXT (data))           symbol name.  */
278          while (M4_SYMBOL_NEXT (current))
279          {          {
280            m4_token_data *next = M4_TOKEN_DATA_NEXT (data);            m4_symbol *next = M4_SYMBOL_NEXT (current);
281    
282            if (M4_TOKEN_DATA_HANDLE (next) == handle)            if (M4_SYMBOL_HANDLE (next) == handle)
283              {              {
284                M4_TOKEN_DATA_NEXT (data) = M4_TOKEN_DATA_NEXT (next);                M4_SYMBOL_NEXT (current) = M4_SYMBOL_NEXT (next);
285                m4_token_data_delete (next);                m4_token_data_delete (next);
286              }              }
287            else            else
288              data = next;              current = next;
289          }          }
290    
291        /* Purge live reference.  */        /* Purge live reference.
292        if (M4_SYMBOL_HANDLE (symbol) == handle)           This must be performed after the shadowed values have been weeded
293             so that the symbol key can be removed from the hash table if this
294             last value matches too.  */
295          if (M4_SYMBOL_HANDLE (*psymbol) == handle)
296          {          {
297            if (M4_SYMBOL_DATA_NEXT (symbol))            if (!M4_SYMBOL_NEXT (*psymbol))
298              m4_symbol_pop (symbol);              xfree (m4_hash_remove (m4_symtab, m4_hash_iterator_key (place)));
299            else            m4_symbol_pop (psymbol);
             {  
               xfree (m4_hash_remove (m4_symtab, m4_hash_iterator_key (place)));  
               m4_symbol_del (symbol);  
             }  
300          }          }
301      }      }
302  }  }
303    
304  /* The following function is used for the cases, where we want to do  /* The following function is used for the cases where we want to do
305     something to each and every symbol in the table.  The function     something to each and every symbol in the table.  The function
306     hack_all_symbols () traverses the symbol table, and calls a specified     m4_symtab_apply () traverses the symbol table, and calls a specified
307     function FUNC for each symbol in the table.  FUNC is called with a     function FUNC for each symbol in the table.  FUNC is called with a
308     pointer to the symbol, and the DATA argument.  */     pointer to the symbol, and the DATA argument.  */
309  int  int
# Line 301  m4_symtab_apply (m4_symtab_apply_func *f Line 316  m4_symtab_apply (m4_symtab_apply_func *f
316    
317    while ((place = m4_hash_iterator_next (m4_symtab, place)))    while ((place = m4_hash_iterator_next (m4_symtab, place)))
318      {      {
319        const char *name  = (const char *) m4_hash_iterator_key (place);        const char *name    = (const char *) m4_hash_iterator_key (place);
320        m4_symbol *symbol = (m4_symbol *) m4_hash_iterator_value (place);        m4_symbol **psymbol = (m4_symbol **) m4_hash_iterator_value (place);
321        result = (*func) (name, symbol, data);        result = (*func) (name, *psymbol, data);
322    
323        if (result != 0)        if (result != 0)
324          break;          break;
# Line 321  static int symtab_print_list (const char Line 336  static int symtab_print_list (const char
336  static void  static void
337  symtab_debug (void)  symtab_debug (void)
338  {  {
339    m4_token_data_t t;    m4_token_t t;
340    m4_token_data td;    m4_symbol tokenbuf;
341    const char *text;    const char *text;
342    m4_symbol *s;    m4_symbol *s;
343    int delete;    int delete;
344    
345    while ((t = m4_next_token (&td)) != NULL)    while ((t = m4_next_token (&tokenbuf)) != M4_TOKEN_EOF)
346      {      {
347        if (t != M4_TOKEN_WORD)        if (t != M4_TOKEN_WORD)
348          continue;          continue;
349        text = M4_TOKEN_DATA_TEXT (&td);        text = M4_SYMBOL_TEXT (&tokenbuf);
350        if (*text == '_')        if (*text == '_')
351          {          {
352            delete = 1;            delete = 1;

Legend:
Removed from v.1.21  
changed lines
  Added in v.1.22

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26