/[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.36 by gary, Mon Jun 16 16:29:06 2003 UTC revision 1.37 by gary, Tue Jun 17 15:17:45 2003 UTC
# Line 42  Line 42 
42     of fluff in these functions to make sure that such symbols (with empty     of fluff in these functions to make sure that such symbols (with empty
43     value stacks) are invisible to the users of this module.  */     value stacks) are invisible to the users of this module.  */
44    
45  #define M4_SYMTAB_DEFAULT_SIZE 2047  #define M4_SYMTAB_DEFAULT_SIZE          2047
46    #define M4_ARG_SIGNATURE_DEFAULT_SIZE   7
47    
48  static int      symbol_destroy          (m4_hash *hash, const void *name,  static m4_symbol *symtab_fetch          (m4_symtab*, const char *);
49    static void       symbol_popval         (m4_symbol *symbol);
50    static int        symbol_destroy        (m4_hash *hash, const void *name,
51                                           void *symbol, void *ignored);                                           void *symbol, void *ignored);
52  static int      arg_destroy             (m4_hash *hash, const void *name,  static int        arg_destroy           (m4_hash *hash, const void *name,
53                                           void *arg, void *ignored);                                           void *arg, void *ignored);
54    static m4_hash *  arg_signature_parse   (const char *name, const char *param);
55    
56    
57    
# Line 71  m4_symtab_delete (m4_symtab *symtab) Line 75  m4_symtab_delete (m4_symtab *symtab)
75    m4_hash_delete ((m4_hash *) symtab);    m4_hash_delete ((m4_hash *) symtab);
76  }  }
77    
78    static m4_symbol *
79    symtab_fetch (m4_symtab *symtab, const char *name)
80    {
81      m4_symbol **psymbol;
82      m4_symbol *symbol;
83    
84      assert (symtab);
85      assert (name);
86    
87      psymbol = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab, name);
88      if (psymbol)
89        {
90          symbol = *psymbol;
91        }
92      else
93        {
94          symbol = XCALLOC (m4_symbol, 1);
95          m4_hash_insert ((m4_hash *) symtab, xstrdup (name), symbol);
96        }
97    
98      return symbol;
99    }
100    
101  /* Remove every symbol that references the given module handle from  /* Remove every symbol that references the given module handle from
102     the symbol table.  */     the symbol table.  */
# Line 155  m4_symbol_lookup (m4_symtab *symtab, con Line 181  m4_symbol_lookup (m4_symtab *symtab, con
181    
182    
183  /* Insert NAME into the symbol table.  If there is already a symbol  /* Insert NAME into the symbol table.  If there is already a symbol
184     associated with NAME, push the new value on top of the value stack     associated with NAME, push the new VALUE on top of the value stack
185     for this symbol.  Otherwise create a new association.  */     for this symbol.  Otherwise create a new association.  */
186  m4_symbol *  m4_symbol *
187  m4_symbol_pushdef (m4_symtab *symtab, const char *name)  m4_symbol_pushdef (m4_symtab *symtab, const char *name, m4_token *value)
188  {  {
189    m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab,    m4_symbol *symbol;
                                                        name);  
   
   m4_symbol *symbol = 0;  
   m4_token *value   = XCALLOC (m4_token, 1);  
190    
191    if (psymbol)    assert (symtab);
192      {    assert (name);
193        symbol = *psymbol;    assert (value);
       TOKEN_NEXT (value) = SYMBOL_TOKEN (symbol);  
     }  
   else  
     symbol = XCALLOC (m4_symbol, 1);  
194    
195      symbol                = symtab_fetch (symtab, name);
196      TOKEN_NEXT (value)    = SYMBOL_TOKEN (symbol);
197    SYMBOL_TOKEN (symbol) = value;    SYMBOL_TOKEN (symbol) = value;
   SYMBOL_TYPE (symbol)  = M4_TOKEN_VOID;  
198    
199    if (!psymbol)    assert (SYMBOL_TOKEN (symbol));
     m4_hash_insert ((m4_hash *) symtab, xstrdup (name), symbol);  
200    
201    return symbol;    return symbol;
202  }  }
203    
   
204  /* Return the symbol associated with NAME in the symbol table, creating  /* Return the symbol associated with NAME in the symbol table, creating
205     a new symbol if necessary.  */     a new symbol if necessary.  In either case set the symbol's VALUE.  */
206  m4_symbol *  m4_symbol *
207  m4_symbol_define (m4_symtab *symtab, const char *name)  m4_symbol_define (m4_symtab *symtab, const char *name, m4_token *value)
208  {  {
209    m4_symbol *symbol = m4_symbol_lookup (symtab, name);    m4_symbol *symbol;
210    
211    if (symbol)    assert (symtab);
212      return symbol;    assert (name);
213      assert (value);
214    
215    return m4_symbol_pushdef (symtab, name);    symbol = symtab_fetch (symtab, name);
216      if (SYMBOL_TOKEN (symbol))
217        symbol_popval (symbol);
218    
219      TOKEN_NEXT (value)    = SYMBOL_TOKEN (symbol);
220      SYMBOL_TOKEN (symbol) = value;
221    
222      assert (SYMBOL_TOKEN (symbol));
223    
224      return symbol;
225    }
226    
227    void
228    m4_set_symbol_traced (m4_symtab *symtab, const char *name)
229    {
230      m4_symbol *symbol;
231    
232      assert (symtab);
233      assert (name);
234    
235      symbol = symtab_fetch (symtab, name);
236    
237      SYMBOL_TRACED (symbol) = TRUE;
238  }  }
239    
240    
# Line 206  m4_symbol_popdef (m4_symtab *symtab, con Line 246  m4_symbol_popdef (m4_symtab *symtab, con
246  {  {
247    m4_symbol **psymbol   = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab,    m4_symbol **psymbol   = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab,
248                                                           name);                                                           name);
   m4_token  *stale      = NULL;  
   
249    assert (psymbol);    assert (psymbol);
250    assert (*psymbol);    assert (*psymbol);
251    
252    stale = SYMBOL_TOKEN (*psymbol);    symbol_popval (*psymbol);
253    
254      /* Only remove the hash table entry if the last value in the
255         symbol value stack was successfully removed.  */
256      if (!SYMBOL_TOKEN (*psymbol))
257        if (no_gnu_extensions || !SYMBOL_TRACED (*psymbol))
258          {
259            XFREE (*psymbol);
260            xfree (m4_hash_remove ((m4_hash *) symtab, name));
261          }
262    }
263    
264    
265    static void
266    symbol_popval (m4_symbol *symbol)
267    {
268      m4_token  *stale;
269    
270      assert (symbol);
271    
272      stale = SYMBOL_TOKEN (symbol);
273    
274    if (stale)    if (stale)
275      {      {
276        SYMBOL_TOKEN (*psymbol) = TOKEN_NEXT (stale);        SYMBOL_TOKEN (symbol) = TOKEN_NEXT (stale);
277    
278        if (TOKEN_ARG_SIGNATURE (stale))        if (TOKEN_ARG_SIGNATURE (stale))
279          {          {
# Line 226  m4_symbol_popdef (m4_symtab *symtab, con Line 284  m4_symbol_popdef (m4_symtab *symtab, con
284          XFREE (TOKEN_TEXT (stale));          XFREE (TOKEN_TEXT (stale));
285        XFREE (stale);        XFREE (stale);
286      }      }
   
   /* Only remove the hash table entry if the last value in the  
      symbol value stack was successfully removed.  */  
   if (!SYMBOL_TOKEN (*psymbol))  
     if (no_gnu_extensions || !SYMBOL_TRACED (*psymbol))  
       {  
         XFREE (*psymbol);  
         xfree (m4_hash_remove ((m4_hash *) symtab, name));  
       }  
287  }  }
288    
   
289  /* Callback used by m4_symbol_popdef () to release the memory used  /* Callback used by m4_symbol_popdef () to release the memory used
290     by values in the arg_signature hash.  */     by values in the arg_signature hash.  */
291  static int  static int
# Line 256  arg_destroy (m4_hash *hash, const void * Line 304  arg_destroy (m4_hash *hash, const void *
304    return 0;    return 0;
305  }  }
306    
307    #if 0
 /* Set the type and value of a symbol according to the passed  
    arguments.  This function is usually passed a newly pushdef()d symbol  
    that is already interned in the symbol table.  The traced bit should  
    be appropriately set by the caller.  */  
308  m4_symbol *  m4_symbol *
309  m4__symbol_set_builtin (m4_symbol *symbol, m4_token *token)  m4_symbol_push_token (m4_symtab *symtab, const char *name, m4_token *token)
310  {  {
311    assert (symbol);    m4_token *next;
312    
313      assert (symtab);
314      assert (name);
315    assert (token);    assert (token);
316    assert (TOKEN_FUNC (token));  
317    assert (TOKEN_HANDLE (token));    /* If it's a function, it must have come from a module.  */
318    assert (TOKEN_TYPE (token) == M4_TOKEN_FUNC);    assert ((TOKEN_TYPE (token) != M4_TOKEN_FUNC) || TOKEN_HANDLE (token));
319    
320    if (SYMBOL_TYPE (symbol) == M4_TOKEN_TEXT)  #if M4PARAMS
321      xfree (SYMBOL_TEXT (symbol));    const char *openp  = NULL;
322      const char *params = NULL;
323    SYMBOL_TYPE (symbol)          = TOKEN_TYPE (token);  
324    SYMBOL_FUNC (symbol)          = TOKEN_FUNC (token);    if (!no_gnu_extensions)
325    SYMBOL_HANDLE (symbol)        = TOKEN_HANDLE (token);      {
326    SYMBOL_FLAGS (symbol)         = TOKEN_FLAGS (token);        /* If name contains an open paren, then parse before that paren
327    SYMBOL_ARG_SIGNATURE (symbol) = TOKEN_ARG_SIGNATURE (token);           as the actual name, and the rest as a formal parameter list.  */
328    SYMBOL_MIN_ARGS (symbol)      = TOKEN_MIN_ARGS (token);        size_t len = 0;
329    SYMBOL_MAX_ARGS (symbol)      = TOKEN_MAX_ARGS (token);        for (openp = name; *openp && !M4_IS_OPEN (*openp); ++openp)
330            ++len;
331    
332          if (*openp)
333            {
334              name   = xstrzdup (name, len);
335              params = 1+ openp;
336            }
337        }
338    
339      if (params)
340        {
341          /* Make a hash table to map formal parameter names to
342             argv offsets, and store that in the symbol's token.  */
343          TOKEN_ARG_SIGNATURE (token) = arg_signature_parse (name, params);
344        }
345    #endif
346    
347      SYMBOL_TOKEN (symbol) = token;
348    
349    #if M4PARAMS
350      /* If we split name on open paren, free the copied substring.  */
351      if (params)
352        xfree ((char *) name);
353    #endif
354    
355    return symbol;    return symbol;
356  }  }
357    #endif
358    
359  /* ...and similarly for macro valued symbols.  */  void
360  m4_symbol *  m4_token_copy (m4_token *dest, m4_token *src)
 m4__symbol_set_macro (m4_symbol *symbol, m4_token *token)  
361  {  {
362    assert (symbol);    m4_token *next;
   assert (TOKEN_TEXT (token));  
   assert (TOKEN_TYPE (token) == M4_TOKEN_TEXT);  
363    
364    if (SYMBOL_TYPE (symbol) == M4_TOKEN_TEXT)    assert (dest);
365      xfree (SYMBOL_TEXT (symbol));    assert (src);
366    
367    SYMBOL_TYPE (symbol)          = TOKEN_TYPE (token);    if (TOKEN_TYPE (dest) == M4_TOKEN_TEXT)
368    SYMBOL_TEXT (symbol)          = xstrdup (TOKEN_TEXT (token));      xfree (TOKEN_TEXT (dest));
   SYMBOL_HANDLE (symbol)        = TOKEN_HANDLE (token);  
   SYMBOL_FLAGS (symbol)         = TOKEN_FLAGS (token);  
   SYMBOL_ARG_SIGNATURE (symbol) = TOKEN_ARG_SIGNATURE (token);  
   SYMBOL_MIN_ARGS (symbol)      = TOKEN_MIN_ARGS (token);  
   SYMBOL_MAX_ARGS (symbol)      = TOKEN_MAX_ARGS (token);  
369    
370    return symbol;  #if M4PARAMS
371      if (TOKEN_ARG_SIGNATURE (dest))
372        {
373          m4_hash_apply (TOKEN_ARG_SIGNATURE (dest), arg_destroy, NULL);
374          m4_hash_delete (TOKEN_ARG_SIGNATURE (dest));
375        }
376    #endif
377    
378      /* Copy the token contents over, being careful to preserve
379         the next pointer.  */
380      next = TOKEN_NEXT (dest);
381      bcopy (src, dest, sizeof (m4_token));
382      TOKEN_NEXT (dest) = next;
383    
384      /* Caller is supposed to free text token strings, so we have to
385         copy the string not just its address in that case.  */
386      if (TOKEN_TYPE (src) == M4_TOKEN_TEXT)
387        TOKEN_TEXT (dest) = xstrdup (TOKEN_TEXT (src));
388    
389    #if M4PARAMS
390      if (TOKEN_ARG_SIGNATURE (src))
391        TOKEN_ARG_SIGNATURE (dest) = m4_hash_dup (TOKEN_ARG_SIGNATURE (token));
392    #endif
393  }  }
394    
395    #if M4PARAMS
396    static m4_hash *
397    arg_signature_parse (const char *name, const char *params)
398    {
399      m4_hash *arg_signature;
400      const char *commap;
401      int offset;
402    
403      assert (params);
404    
405      arg_signature = m4_hash_new (M4_ARG_SIGNATURE_DEFAULT_SIZE,
406                            m4_hash_string_hash, m4_hash_string_cmp);
407    
408      for (offset = 1; *params && !M4_IS_CLOSE (*params); ++offset)
409        {
410          size_t len = 0;
411    
412          /* Skip leading whitespace.  */
413          while (M4_IS_SPACE (*params))
414            ++params;
415    
416          for (commap = params; *commap && M4_IS_IDENT (*commap); ++commap)
417            ++len;
418    
419          /* Skip trailing whitespace.  */
420          while (M4_IS_SPACE (*commap))
421            ++commap;
422    
423          if (!M4_IS_COMMA (*commap) && !M4_IS_CLOSE (*commap))
424            M4ERROR ((EXIT_FAILURE, 0,
425                      _("Error: %s: syntax error in parameter list at char `%c'"),
426                      name, *commap));
427    
428          /* Skip parameter delimiter.  */
429          if (M4_IS_COMMA (*commap))
430            ++commap;
431    
432          if (len)
433            {
434              struct m4_token_arg *arg = XCALLOC (struct m4_token_arg, 1);
435    
436              TOKEN_ARG_INDEX (arg) = offset;
437    
438              m4_hash_insert (arg_signature, xstrzdup (params, len), arg);
439    
440              params = commap;
441            }
442        }
443    
444      if (!M4_IS_CLOSE (*commap))
445        M4WARN ((warning_status, 0,
446                 _("Warning: %s: unterminated parameter list"), name));
447    
448      return arg_signature;
449    }
450    #endif
451    
452    
453    
454  #ifdef DEBUG_SYM  #ifdef DEBUG_SYM
455    
456  static int  symtab_print_list (const void *name, void *symbol, void *ignored);  static int  symtab_print_list (m4_hash *hash, const void *name, void *symbol,
457  static void symtab_debug      (void)                                 void *ignored);
458  static void symtab_dump       (void);  static void symtab_debug      (m4_symtab *symtab);
459    static void symtab_dump       (m4_symtab *symtab);
460    
461  static void  static void
462  symtab_dump (void)  symtab_dump (m4_symtab *symtab)
463  {  {
464    m4_hash_iterator *place = 0;    m4_hash_iterator *place = 0;
465    
# Line 385  symtab_debug (m4_symtab *symtab) Line 528  symtab_debug (m4_symtab *symtab)
528          printf (_("Name `%s' is unknown\n"), text);          printf (_("Name `%s' is unknown\n"), text);
529    
530        if (delete)        if (delete)
531          (void) m4_symbol_delete (symtab, text);          m4_symbol_delete (symtab, text);
532        else        else
533          (void) m4_symbol_define (symtab, text);          symtab_fetch (symtab, text);
534      }      }
535    m4_symtab_apply (symtab, symtab_print_list, NULL);    m4_symtab_apply (symtab, symtab_print_list, NULL);
536  }  }

Legend:
Removed from v.1.36  
changed lines
  Added in v.1.37

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