|
@@ -651,12 +651,20 @@ bool sym_is_changable(struct symbol *sym)
|
|
|
return sym->visible > sym->rev_dep.tri;
|
|
|
}
|
|
|
|
|
|
+static unsigned strhash(const char *s)
|
|
|
+{
|
|
|
+ /* fnv32 hash */
|
|
|
+ unsigned hash = 2166136261U;
|
|
|
+ for (; *s; s++)
|
|
|
+ hash = (hash ^ *s) * 0x01000193;
|
|
|
+ return hash;
|
|
|
+}
|
|
|
+
|
|
|
struct symbol *sym_lookup(const char *name, int flags)
|
|
|
{
|
|
|
struct symbol *symbol;
|
|
|
- const char *ptr;
|
|
|
char *new_name;
|
|
|
- int hash = 0;
|
|
|
+ int hash;
|
|
|
|
|
|
if (name) {
|
|
|
if (name[0] && !name[1]) {
|
|
@@ -666,12 +674,11 @@ struct symbol *sym_lookup(const char *name, int flags)
|
|
|
case 'n': return &symbol_no;
|
|
|
}
|
|
|
}
|
|
|
- for (ptr = name; *ptr; ptr++)
|
|
|
- hash += *ptr;
|
|
|
- hash &= 0xff;
|
|
|
+ hash = strhash(name) % SYMBOL_HASHSIZE;
|
|
|
|
|
|
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
|
|
|
- if (!strcmp(symbol->name, name) &&
|
|
|
+ if (symbol->name &&
|
|
|
+ !strcmp(symbol->name, name) &&
|
|
|
(flags ? symbol->flags & flags
|
|
|
: !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
|
|
|
return symbol;
|
|
@@ -679,7 +686,7 @@ struct symbol *sym_lookup(const char *name, int flags)
|
|
|
new_name = strdup(name);
|
|
|
} else {
|
|
|
new_name = NULL;
|
|
|
- hash = 256;
|
|
|
+ hash = 0;
|
|
|
}
|
|
|
|
|
|
symbol = malloc(sizeof(*symbol));
|
|
@@ -697,7 +704,6 @@ struct symbol *sym_lookup(const char *name, int flags)
|
|
|
struct symbol *sym_find(const char *name)
|
|
|
{
|
|
|
struct symbol *symbol = NULL;
|
|
|
- const char *ptr;
|
|
|
int hash = 0;
|
|
|
|
|
|
if (!name)
|
|
@@ -710,12 +716,11 @@ struct symbol *sym_find(const char *name)
|
|
|
case 'n': return &symbol_no;
|
|
|
}
|
|
|
}
|
|
|
- for (ptr = name; *ptr; ptr++)
|
|
|
- hash += *ptr;
|
|
|
- hash &= 0xff;
|
|
|
+ hash = strhash(name) % SYMBOL_HASHSIZE;
|
|
|
|
|
|
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
|
|
|
- if (!strcmp(symbol->name, name) &&
|
|
|
+ if (symbol->name &&
|
|
|
+ !strcmp(symbol->name, name) &&
|
|
|
!(symbol->flags & SYMBOL_CONST))
|
|
|
break;
|
|
|
}
|