#include #include #include "hash.h" #include "header.h" #include "back.h" /* Findsym() manages the symbol table. It can be called in three ways. * 1) findsym( "string", DEFINITION) : look if string is present in the * symol table. If not create a new entry: set index into the * string_area. Return the index to the entry. Symbol_def() will * the fields. * 2) findsym( "string", REFERENCE) : If string is present but never used * (see 3)) make this name extern visible and set on_valu on -1. * We use the on_valu field to distinguish between external visible * names that are defined here and those that are defined in another file. * If the string is not present create a new entry and make the name extern * visible and set on_valu on -1. * If the name is present do nothing special. * 3) findsym( "string", STORE_STRING) : this call is made to save a * copy action. The first time a name is encountered we store it * immediately in the symbol table. If the name is not present we * create a new entry and set the on_valu field on -2. In this * way we can tell later that the name is not used yet. The index * is stored in the global varaible 'index_symbol_table' because it is * very likely that the same string is in the next call to findsym. * (After introducing a new name one does something with this name) */ int string_lengte = 0, index_symbol_table = -1; struct Hashitem *Hashitems ; int Hashtab[ MAXHASH]; int find_sym( sym, isdef) char *sym; int isdef; { register char *p; register struct outname *s; register struct Hashitem *ip; register int h; if ( index_symbol_table != -1 ) { s = symbol_table + index_symbol_table; if ( sym == s->on_foff + string_area) { if ( (s->on_valu == -2) && ( isdef == REFERENCE)) { s->on_type = S_EXT; s->on_valu = -1; } return( index_symbol_table); } } h = Hash(sym); for ( ip = Hashtab[h] + Hashitems ; ip != Hashitems; ip = (ip->hs_next) + Hashitems) { s = symbol_table + ip->hs_nami; if (strcmp(sym, (s->on_foff) + string_area) == 0) { if ( (s->on_valu == -2) && (isdef == REFERENCE)) { s->on_type = S_EXT; s->on_valu = -1; } return ip->hs_nami; } } if ( nname >= size_symbol) mem_symbol_hash(); s = symbol_table + nname; ip = Hashitems + nname + 1; /* skip the first entry */ if (isdef == REFERENCE) { s->on_type = S_EXT; s->on_valu = -1; } if (isdef == STORE_STRING) { s->on_type = S_UND; s->on_valu = -2; } ip->hs_nami = nname; ip->hs_next = Hashtab[h]; Hashtab[h] = ip - Hashitems; if ( sym == string) string += string_lengte; else { /* zie C_fil, C_lin, C_lni */ string_lengte = 0; for( p=sym; *p != '\0' ; p++) { if ( (string - string_area) >= size_string) mem_string(); *string++ = *p; string_lengte++; } } if ( (string - string_area) >= size_string) mem_string(); *string++ = '\0'; s->on_foff = string - (string_lengte + 1) - string_area; return nname++; } int Hash(sym) char *sym; { register unsigned h; register c; h = 0; while (c = *sym++) { h <<= 2; h += c; } return (h % MAXHASH); }