home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume29 / cproto / part02 / symbol.c < prev    next >
C/C++ Source or Header  |  1992-04-06  |  2KB  |  119 lines

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