00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "symbol.hh"
00023 #include "compatibility.hh"
00024 #include <cstring>
00025 #include <iostream>
00026 #include <cstdio>
00027 using namespace std;
00028
00033 Symbol* Symbol::gSymbolTable[kHashTableSize];
00034
00035
00042 Symbol* Symbol::get(const string& str)
00043 {
00044 char buf[1024];
00045 int i;
00046 int n = str.length();
00047
00048 if (n>1023) n = 1023;
00049 for (i = 0; i < n; i++) { buf[i] = str[i]; }
00050 buf[i] = 0;
00051
00052 return Symbol::get(buf);
00053 }
00054
00055
00056
00063 Symbol* Symbol::get(const char* str)
00064 {
00065 unsigned int hsh = calcHashKey(str);
00066 int bckt = hsh % kHashTableSize;
00067 Symbol* item = gSymbolTable[bckt];
00068
00069 while ( item && !item->equiv(hsh,str) ) item = item->fNext;
00070 Symbol* r = item ? item : gSymbolTable[bckt] = new Symbol(str, hsh, gSymbolTable[bckt]);
00071 return r;
00072 }
00073
00074
00081 bool Symbol::isnew(const char* str)
00082 {
00083 unsigned int hsh = calcHashKey(str);
00084 int bckt = hsh % kHashTableSize;
00085 Symbol* item = gSymbolTable[bckt];
00086
00087 while ( item && !item->equiv(hsh,str) ) item = item->fNext;
00088 return item == 0;
00089 }
00090
00091
00098 Symbol* Symbol::prefix (const char* str)
00099 {
00100 char name[256];
00101
00102 for (int n = 0; n<10000; n++) {
00103 snprintf(name, 256, "%s%d", str, n);
00104 if (isnew(name)) return get(name);
00105 }
00106 return get("UNIQUEOVERFLOW");
00107 }
00108
00109
00120 bool Symbol::equiv (unsigned int hash, const char *str) const
00121 {
00122 return (fHash == hash) && (strcmp(fName,str) == 0);
00123 }
00124
00125
00126
00133 unsigned int Symbol::calcHashKey (const char* str)
00134 {
00135 unsigned int h = 0;
00136
00137 while (*str) h = (h << 1) ^ (h >> 20) ^ (*str++);
00138 return h;
00139 }
00140
00141
00142
00151 Symbol::Symbol(const char* str, unsigned int hsh, Symbol* nxt)
00152 {
00153 int len = strlen(str);
00154
00155 fName = new char [len+1];
00156 memcpy(fName, str, len+1);
00157 fHash = hsh;
00158 fNext = nxt;
00159 fData = 0;
00160 }
00161
00162
00163
00164 ostream& Symbol::print (ostream& fout) const
00165 {
00166 return fout << fName;
00167 }