/[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.22 by gary, Thu Sep 20 03:48:05 2001 UTC revision 1.23 by gary, Sun Sep 30 14:43:38 2001 UTC
# Line 18  Line 18 
18     02111-1307  USA     02111-1307  USA
19  */  */
20    
 #include "m4private.h"  
   
 #define DEBUG_SYM               /* Define this to see runtime debug info.  */  
 #undef DEBUG_SYM  
   
21  /* 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
22     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
23     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 32  Line 27 
27     simply ordered on the stack by age.  The most recently pushed definition     simply ordered on the stack by age.  The most recently pushed definition
28     will then always be the first found.  */     will then always be the first found.  */
29    
30    #include "m4private.h"
31    
32  static size_t   m4_symtab_hash          (const void *key);  static size_t   m4_symtab_hash          (const void *key);
33  static int      m4_symtab_cmp           (const void *key, const void *try);  static int      m4_symtab_cmp           (const void *key, const void *try);
34  static void     m4_token_data_delete    (m4_symbol *data);  static void     m4_token_data_delete    (m4_token_data *data);
35  static void     m4_symbol_pop           (m4_symbol **psymbol);  static void     m4_symbol_pop           (m4_symbol *symbol);
36  static void     m4_symbol_del           (m4_symbol **psymbol);  static void     m4_symbol_del           (m4_symbol *symbol);
 static int      m4_symbol_destroy       (const char *name, m4_symbol *symbol,  
                                          void *data);  
37    
38    
39  /* Pointer to symbol table.  */  /* Pointer to symbol table.  */
# Line 52  m4_symtab_init (void) Line 47  m4_symtab_init (void)
47    m4_symtab = m4_hash_new (m4_symtab_hash, m4_symtab_cmp);    m4_symtab = m4_hash_new (m4_symtab_hash, m4_symtab_cmp);
48  }  }
49    
 int  
 m4_symbol_destroy (const char *name, m4_symbol *symbol, void *data)  
 {  
   m4_symbol_delete (name);  
   return 0;  
 }  
   
 void  
 m4_symtab_exit (void)  
 {  
   m4_symtab_apply (m4_symbol_destroy, NULL);  
   m4_hash_delete (m4_symtab);  
   m4_hash_exit ();  
 }  
   
50  /* Return a hashvalue for a string, from GNU-emacs.  */  /* Return a hashvalue for a string, from GNU-emacs.  */
51  size_t  size_t
52  m4_symtab_hash (const void *key)  m4_symtab_hash (const void *key)
# Line 94  m4_symtab_cmp (const void *key, const vo Line 74  m4_symtab_cmp (const void *key, const vo
74    
75    
76  void  void
77  m4_token_data_delete (m4_symbol *data)  m4_token_data_delete (m4_token_data *data)
78  {  {
79    assert (data);    assert (data);
80    assert (M4_SYMBOL_NEXT (data) == 0);    assert (M4_TOKEN_DATA_NEXT (data) == 0);
81    
82    if (M4_SYMBOL_TYPE (data) == M4_TOKEN_TEXT)    if (M4_TOKEN_DATA_TYPE (data) == M4_TOKEN_TEXT)
83      XFREE (M4_SYMBOL_TEXT (data));      XFREE (M4_TOKEN_DATA_TEXT (data));
84    
85    XFREE (data);    XFREE (data);
86  }  }
87    
   
88  void  void
89  m4_symbol_pop (m4_symbol **psymbol)  m4_symbol_pop (m4_symbol *symbol)
90  {  {
91    m4_symbol *stale;    m4_token_data *stale;
92    
93    assert (psymbol);    assert (symbol);
94    assert (*psymbol);    assert (M4_SYMBOL_DATA_NEXT (symbol));
95    
96    stale  = *psymbol;    stale                         = M4_SYMBOL_DATA (symbol);
97    *psymbol = M4_SYMBOL_NEXT (stale);    M4_SYMBOL_DATA (symbol)       = M4_TOKEN_DATA_NEXT (stale);
98    
99  #ifndef NDEBUG  #ifndef NDEBUG
100    M4_SYMBOL_NEXT (stale) = 0;    M4_TOKEN_DATA_NEXT (stale) = 0;
101  #endif  #endif
102    m4_token_data_delete (stale);    m4_token_data_delete (stale);
103  }  }
104    
   
105  /* Free all storage associated with a symbol.  */  /* Free all storage associated with a symbol.  */
106  void  void
107  m4_symbol_del (m4_symbol **psymbol)  m4_symbol_del (m4_symbol *symbol)
108  {  {
109    assert (psymbol);    assert (symbol);
110    assert (*psymbol);  
111      while (M4_SYMBOL_DATA_NEXT (symbol))
112        m4_symbol_pop (symbol);
113    
114      assert (M4_SYMBOL_DATA_NEXT (symbol) == 0);
115    
116      if (M4_SYMBOL_TYPE (symbol) == M4_TOKEN_TEXT)
117        XFREE (M4_SYMBOL_TEXT (symbol));
118    
119    while (*psymbol)    XFREE (M4_SYMBOL_DATA (symbol));
120      m4_symbol_pop (psymbol);    XFREE (symbol);
121  }  }
122    
123    
# Line 157  m4_symbol_pushdef (const char *name) Line 142  m4_symbol_pushdef (const char *name)
142    /* 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
143       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
144       this symbol.  */       this symbol.  */
145    m4_symbol *symbol         = XCALLOC (m4_symbol, 1);;    m4_symbol *symbol    = 0;
146    M4_SYMBOL_TYPE (symbol)       = M4_TOKEN_VOID;    m4_token_data *value = XCALLOC (m4_token_data, 1);
147    
148    if (psymbol)    if (psymbol)
149      {      {
150        M4_SYMBOL_NEXT (symbol) = *psymbol;        symbol = *psymbol;
151        *psymbol = symbol;        M4_TOKEN_DATA_NEXT (value) = M4_SYMBOL_DATA (symbol);
152      }      }
153    else    else
154        symbol = XCALLOC (m4_symbol, 1);
155    
156      M4_SYMBOL_DATA (symbol)       = value;
157      M4_SYMBOL_TYPE (symbol)       = M4_TOKEN_VOID;
158    
159      if (!psymbol)
160      m4_hash_insert (m4_symtab, xstrdup (name), symbol);      m4_hash_insert (m4_symtab, xstrdup (name), symbol);
161    
162    return symbol;    return symbol;
# Line 176  m4_symbol_pushdef (const char *name) Line 167  m4_symbol_pushdef (const char *name)
167  m4_symbol *  m4_symbol *
168  m4_symbol_define (const char *name)  m4_symbol_define (const char *name)
169  {  {
170    m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (m4_symtab, name);    m4_symbol *res = m4_symbol_lookup (name);
171    if (psymbol)    if (res)
172      return *psymbol;      return res;
173    else    else
174      return m4_symbol_pushdef (name);      m4_symbol_pushdef (name);
175  }  }
176    
177    
# Line 192  m4_symbol_popdef (const char *name) Line 183  m4_symbol_popdef (const char *name)
183    
184    assert (psymbol);    assert (psymbol);
185    
186    if (M4_SYMBOL_NEXT (*psymbol))    if (M4_SYMBOL_DATA_NEXT (*psymbol))
187      m4_symbol_pop (psymbol);      m4_symbol_pop (*psymbol);
188    else    else
189      {      {
190        xfree (m4_hash_remove (m4_symtab, name));        xfree (m4_hash_remove (m4_symtab, name));
191        m4_symbol_del (psymbol);        m4_symbol_del (*psymbol);
192      }      }
193  }  }
194    
# Line 209  m4_symbol_delete (const char *name) Line 200  m4_symbol_delete (const char *name)
200    m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (m4_symtab, name);    m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (m4_symtab, name);
201    
202    assert (psymbol);    assert (psymbol);
   
 #ifdef DEBUG_SYM  
   M4_DEBUG_MESSAGE1("symbol %s recycled.", name);  
 #endif  
   
203    xfree (m4_hash_remove (m4_symtab, name));    xfree (m4_hash_remove (m4_symtab, name));
204    m4_symbol_del (psymbol);    m4_symbol_del (*psymbol);
205  }  }
206    
207    
# Line 267  m4_symtab_remove_module_references (lt_d Line 253  m4_symtab_remove_module_references (lt_d
253    
254    assert (handle);    assert (handle);
255    
   /* Traverse each symbol name in the hash table.  */  
256    while ((place = m4_hash_iterator_next (m4_symtab, place)))    while ((place = m4_hash_iterator_next (m4_symtab, place)))
257      {      {
258        m4_symbol **psymbol = (m4_symbol **) m4_hash_iterator_value (place);        m4_symbol *symbol = (m4_symbol *) m4_hash_iterator_value (place);
259        m4_symbol *current  = *psymbol;        m4_token_data *data = M4_SYMBOL_DATA (symbol);
260    
261        /* Examine each value in the value stack associated with this        /* Purge any shadowed references.  */
262           symbol name.  */        while (M4_TOKEN_DATA_NEXT (data))
       while (M4_SYMBOL_NEXT (current))  
263          {          {
264            m4_symbol *next = M4_SYMBOL_NEXT (current);            m4_token_data *next = M4_TOKEN_DATA_NEXT (data);
265    
266            if (M4_SYMBOL_HANDLE (next) == handle)            if (M4_TOKEN_DATA_HANDLE (next) == handle)
267              {              {
268                M4_SYMBOL_NEXT (current) = M4_SYMBOL_NEXT (next);                M4_TOKEN_DATA_NEXT (data) = M4_TOKEN_DATA_NEXT (next);
269                m4_token_data_delete (next);                m4_token_data_delete (next);
270              }              }
271            else            else
272              current = next;              data = next;
273          }          }
274    
275        /* Purge live reference.        /* Purge live reference.  */
276           This must be performed after the shadowed values have been weeded        if (M4_SYMBOL_HANDLE (symbol) == handle)
          so that the symbol key can be removed from the hash table if this  
          last value matches too.  */  
       if (M4_SYMBOL_HANDLE (*psymbol) == handle)  
277          {          {
278            if (!M4_SYMBOL_NEXT (*psymbol))            if (M4_SYMBOL_DATA_NEXT (symbol))
279              xfree (m4_hash_remove (m4_symtab, m4_hash_iterator_key (place)));              m4_symbol_pop (symbol);
280            m4_symbol_pop (psymbol);            else
281                {
282                  xfree (m4_hash_remove (m4_symtab, m4_hash_iterator_key (place)));
283                  m4_symbol_del (symbol);
284                }
285          }          }
286      }      }
287  }  }
288    
289  /* 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
290     something to each and every symbol in the table.  The function     something to each and every symbol in the table.  The function
291     m4_symtab_apply () traverses the symbol table, and calls a specified     hack_all_symbols () traverses the symbol table, and calls a specified
292     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
293     pointer to the symbol, and the DATA argument.  */     pointer to the symbol, and the DATA argument.  */
294  int  int
# Line 316  m4_symtab_apply (m4_symtab_apply_func *f Line 301  m4_symtab_apply (m4_symtab_apply_func *f
301    
302    while ((place = m4_hash_iterator_next (m4_symtab, place)))    while ((place = m4_hash_iterator_next (m4_symtab, place)))
303      {      {
304        const char *name    = (const char *) m4_hash_iterator_key (place);        const char *name  = (const char *) m4_hash_iterator_key (place);
305        m4_symbol **psymbol = (m4_symbol **) m4_hash_iterator_value (place);        m4_symbol *symbol = (m4_symbol *) m4_hash_iterator_value (place);
306        result = (*func) (name, *psymbol, data);        result = (*func) (name, symbol, data);
307    
308        if (result != 0)        if (result != 0)
309          break;          break;
# Line 336  static int symtab_print_list (const char Line 321  static int symtab_print_list (const char
321  static void  static void
322  symtab_debug (void)  symtab_debug (void)
323  {  {
324    m4_token_t t;    m4_token_data_t t;
325    m4_symbol tokenbuf;    m4_token_data td;
326    const char *text;    const char *text;
327    m4_symbol *s;    m4_symbol *s;
328    int delete;    int delete;
329    
330    while ((t = m4_next_token (&tokenbuf)) != M4_TOKEN_EOF)    while ((t = m4_next_token (&td)) != NULL)
331      {      {
332        if (t != M4_TOKEN_WORD)        if (t != M4_TOKEN_WORD)
333          continue;          continue;
334        text = M4_SYMBOL_TEXT (&tokenbuf);        text = M4_TOKEN_DATA_TEXT (&td);
335        if (*text == '_')        if (*text == '_')
336          {          {
337            delete = 1;            delete = 1;

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

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