00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include "symbol.hh"
00026 #include "compatibility.hh"
00027 #include <iostream>
00028 #include <cstring>
00029 #include <assert.h>
00030
00031 using namespace std;
00032
00037 Symbol* Symbol::gSymbolTable[kHashTableSize];
00038
00039
00046 Symbol* Symbol::get(const string& str)
00047 {
00048 char buf[1024];
00049 int i;
00050 int n = str.length();
00051
00052 if (n>1023) n = 1023;
00053 for (i = 0; i < n; i++) { buf[i] = str[i]; }
00054 buf[i] = 0;
00055
00056 return Symbol::get(buf);
00057 }
00058
00059
00060
00067 Symbol* Symbol::get(const char* str)
00068 {
00069 unsigned int hsh = calcHashKey(str);
00070 int bckt = hsh % kHashTableSize;
00071 Symbol* item = gSymbolTable[bckt];
00072
00073 while ( item && !item->equiv(hsh,str) ) item = item->fNext;
00074 Symbol* r = item ? item : gSymbolTable[bckt] = new Symbol(str, hsh, gSymbolTable[bckt]);
00075 return r;
00076 }
00077
00078
00085 bool Symbol::isnew(const char* str)
00086 {
00087 unsigned int hsh = calcHashKey(str);
00088 int bckt = hsh % kHashTableSize;
00089 Symbol* item = gSymbolTable[bckt];
00090
00091 while ( item && !item->equiv(hsh,str) ) item = item->fNext;
00092 return item == 0;
00093 }
00094
00095
00102 Symbol* Symbol::prefix (const char* str)
00103 {
00104 char name[256];
00105
00106 static map<const char*, unsigned int> gPrefixCounters;
00107
00108 for (int n = 0; n<10000; n++) {
00109 snprintf(name, 256, "%s%d", str, gPrefixCounters[str]++);
00110 if (isnew(name)) return get(name);
00111 }
00112 assert(false);
00113 return get("UNIQUEOVERFLOW");
00114 }
00115
00116
00127 bool Symbol::equiv (unsigned int hash, const char *str) const
00128 {
00129 return (fHash == hash) && (strcmp(fName,str) == 0);
00130 }
00131
00132
00133
00140 unsigned int Symbol::calcHashKey (const char* str)
00141 {
00142 unsigned int h = 0;
00143
00144 while (*str) h = (h << 1) ^ (h >> 20) ^ (*str++);
00145 return h;
00146 }
00147
00148
00149
00158 Symbol::Symbol(const char* str, unsigned int hsh, Symbol* nxt)
00159 {
00160 int len = strlen(str);
00161
00162 fName = new char [len+1];
00163 memcpy(fName, str, len+1);
00164 fHash = hsh;
00165 fNext = nxt;
00166 fData = 0;
00167 }
00168
00169 Symbol::~Symbol ()
00170 {
00171 delete [] fName;
00172 }
00173
00174 ostream& Symbol::print (ostream& fout) const
00175 {
00176 return fout << fName;
00177 }