home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cproto.zip / cproto46 / symbol.c < prev    next >
C/C++ Source or Header  |  1998-01-18  |  3KB  |  126 lines

  1. /* $Id: symbol.c,v 4.3 1998/01/19 00:49:30 cthuang Exp $
  2.  *
  3.  * Implements a symbol table abstract data type.
  4.  */
  5. #include <stdio.h>
  6. #include "cproto.h"
  7. #include "symbol.h"
  8.  
  9. static unsigned hash ARGS((char *name));
  10. static Symbol *search_symbol_list ARGS((Symbol *list, char *name));
  11.  
  12. /* Create a symbol table.
  13.  * Return a pointer to the symbol table or NULL if an error occurs.
  14.  */
  15. SymbolTable *
  16. new_symbol_table ()
  17. {
  18.     SymbolTable *symtab;
  19.     int i;
  20.  
  21.     if ((symtab = NEW(SymbolTable)) != NULL) {
  22.     for (i = 0; i < SYM_MAX_HASH; ++i)
  23.         symtab->bucket[i] = NULL;
  24.     }
  25.     return symtab;
  26. }
  27.  
  28.  
  29. /* Free the memory allocated to the symbol table.
  30.  */
  31. void
  32. free_symbol_table (symtab)
  33. SymbolTable *symtab;
  34. {
  35.     int i;
  36.     Symbol *sym, *next;
  37.  
  38.     for (i = 0; i < SYM_MAX_HASH; ++i) {
  39.     sym = symtab->bucket[i];
  40.     while (sym != NULL) {
  41.         next = sym->next;
  42.         if (sym->name  != 0) free(sym->name);
  43.         if (sym->value != 0) free(sym->value);
  44.         free(sym);
  45.         sym = next;
  46.     }
  47.     }
  48.     free(symtab);
  49. }
  50.  
  51.  
  52. /* This is a simple hash function mapping a symbol name to a hash bucket. */
  53.  
  54. static unsigned
  55. hash (name)
  56. char *name;
  57. {
  58.     char *s;
  59.     unsigned h;
  60.  
  61.     h = 0;
  62.     s = name;
  63.     while (*s != '\0')
  64.     h = (h << 1) ^ *s++;
  65.     return h % SYM_MAX_HASH;
  66. }
  67.  
  68.  
  69. /* Search the list of symbols <list> for the symbol <name>.
  70.  * Return a pointer to the symbol or NULL if not found.
  71.  */
  72. static Symbol *
  73. search_symbol_list (list, name)
  74. Symbol *list;
  75. char *name;
  76. {
  77.     Symbol *sym;
  78.  
  79.     for (sym = list; sym != NULL; sym = sym->next) {
  80.     if (strcmp(sym->name, name) == 0)
  81.         return sym;
  82.     }
  83.     return NULL;
  84. }
  85.  
  86.  
  87. /* Look for symbol <name> in symbol table <symtab>.
  88.  * Return a pointer to the symbol or NULL if not found.
  89.  */
  90. Symbol *
  91. find_symbol (symtab, name)
  92. SymbolTable *symtab;
  93. char *name;
  94. {
  95.     return search_symbol_list(symtab->bucket[hash(name)], name);
  96. }
  97.  
  98.  
  99. /* If the symbol <name> does not already exist in symbol table <symtab>,
  100.  * then add the symbol to the symbol table.
  101.  * Return a pointer to the symbol.
  102.  */
  103. Symbol *
  104. new_symbol (symtab, name, value, flags)
  105. SymbolTable *symtab;    /* symbol table */
  106. char *name;        /* symbol name */
  107. char *value;        /* symbol value */
  108. int flags;        /* symbol attributes */
  109. {
  110.     Symbol *sym;
  111.     int i;
  112.  
  113.     if ((sym = find_symbol(symtab, name)) == NULL) {
  114.     sym = NEW(Symbol);
  115.     sym->name = xstrdup(name);
  116.     i = hash(name);
  117.     sym->next = symtab->bucket[i];
  118.     symtab->bucket[i] = sym;
  119.     } else {
  120.     free(sym->value);
  121.     }
  122.     sym->value = (value != NULL) ? xstrdup(value) : NULL;
  123.     sym->flags = flags;
  124.     return sym;
  125. }
  126.