Fixed an insidious bug in table lookups

git-svn-id: http://picoc.googlecode.com/svn/trunk@133 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-02-28 22:13:55 +00:00
parent 6be246b846
commit 3c24084d94
2 changed files with 15 additions and 15 deletions

2
lex.c
View file

@ -50,7 +50,7 @@ static struct ReservedWord ReservedWords[] =
{ "return", TokenReturn, NULL }, { "return", TokenReturn, NULL },
{ "short", TokenShortType, NULL }, { "short", TokenShortType, NULL },
{ "signed", TokenSignedType, NULL }, { "signed", TokenSignedType, NULL },
// { "sizeof", TokenSizeof, NULL }, { "sizeof", TokenSizeof, NULL },
{ "struct", TokenStructType, NULL }, { "struct", TokenStructType, NULL },
{ "switch", TokenSwitch, NULL }, { "switch", TokenSwitch, NULL },
{ "typedef", TokenTypedef, NULL }, { "typedef", TokenTypedef, NULL },

28
table.c
View file

@ -39,7 +39,7 @@ void TableInitTable(struct Table *Tbl, struct TableEntry **HashTable, int Size,
} }
/* check a hash table entry for a key */ /* check a hash table entry for a key */
static int TableSearch(struct Table *Tbl, const char *Key, int *AddAt) static struct TableEntry *TableSearch(struct Table *Tbl, const char *Key, int *AddAt)
{ {
struct TableEntry *Entry; struct TableEntry *Entry;
int HashValue = ((unsigned long)Key) % Tbl->Size; /* shared strings have unique addresses so we don't need to hash them */ int HashValue = ((unsigned long)Key) % Tbl->Size; /* shared strings have unique addresses so we don't need to hash them */
@ -47,11 +47,11 @@ static int TableSearch(struct Table *Tbl, const char *Key, int *AddAt)
for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next) for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next)
{ {
if (Entry->p.v.Key == Key) if (Entry->p.v.Key == Key)
return HashValue; /* found */ return Entry; /* found */
} }
*AddAt = HashValue; /* didn't find it in the chain */ *AddAt = HashValue; /* didn't find it in the chain */
return -1; return NULL;
} }
/* set an identifier to a value. returns FALSE if it already exists. /* set an identifier to a value. returns FALSE if it already exists.
@ -59,9 +59,9 @@ static int TableSearch(struct Table *Tbl, const char *Key, int *AddAt)
int TableSet(struct Table *Tbl, char *Key, struct Value *Val) int TableSet(struct Table *Tbl, char *Key, struct Value *Val)
{ {
int AddAt; int AddAt;
int HashPos = TableSearch(Tbl, Key, &AddAt); struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt);
if (HashPos == -1) if (FoundEntry == NULL)
{ /* add it to the table */ { /* add it to the table */
struct TableEntry *NewEntry = VariableAlloc(NULL, sizeof(struct TableEntry), Tbl->OnHeap); struct TableEntry *NewEntry = VariableAlloc(NULL, sizeof(struct TableEntry), Tbl->OnHeap);
NewEntry->p.v.Key = Key; NewEntry->p.v.Key = Key;
@ -79,16 +79,16 @@ int TableSet(struct Table *Tbl, char *Key, struct Value *Val)
int TableGet(struct Table *Tbl, const char *Key, struct Value **Val) int TableGet(struct Table *Tbl, const char *Key, struct Value **Val)
{ {
int AddAt; int AddAt;
int HashPos = TableSearch(Tbl, Key, &AddAt); struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt);
if (HashPos == -1) if (FoundEntry == NULL)
return FALSE; return FALSE;
*Val = Tbl->HashTable[HashPos]->p.v.Val; *Val = FoundEntry->p.v.Val;
return TRUE; return TRUE;
} }
/* check a hash table entry for an identifier */ /* check a hash table entry for an identifier */
static int TableSearchIdentifier(struct Table *Tbl, const char *Key, int Len, int *AddAt) static struct TableEntry *TableSearchIdentifier(struct Table *Tbl, const char *Key, int Len, int *AddAt)
{ {
struct TableEntry *Entry; struct TableEntry *Entry;
int HashValue = TableHash(Key, Len) % Tbl->Size; int HashValue = TableHash(Key, Len) % Tbl->Size;
@ -96,21 +96,21 @@ static int TableSearchIdentifier(struct Table *Tbl, const char *Key, int Len, in
for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next) for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next)
{ {
if (strncmp(&Entry->p.Key[0], Key, Len) == 0 && Entry->p.Key[Len] == '\0') if (strncmp(&Entry->p.Key[0], Key, Len) == 0 && Entry->p.Key[Len] == '\0')
return HashValue; /* found */ return Entry; /* found */
} }
*AddAt = HashValue; /* didn't find it in the chain */ *AddAt = HashValue; /* didn't find it in the chain */
return -1; return NULL;
} }
/* set an identifier and return the identifier. share if possible */ /* set an identifier and return the identifier. share if possible */
char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen) char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen)
{ {
int AddAt; int AddAt;
int HashPos = TableSearchIdentifier(Tbl, Ident, IdentLen, &AddAt); struct TableEntry *FoundEntry = TableSearchIdentifier(Tbl, Ident, IdentLen, &AddAt);
if (HashPos != -1) if (FoundEntry != NULL)
return &Tbl->HashTable[HashPos]->p.Key[0]; return &FoundEntry->p.Key[0];
else else
{ /* add it to the table - we economise by not allocating the whole structure here */ { /* add it to the table - we economise by not allocating the whole structure here */
struct TableEntry *NewEntry = HeapAlloc(sizeof(struct TableEntry *) + IdentLen + 1); struct TableEntry *NewEntry = HeapAlloc(sizeof(struct TableEntry *) + IdentLen + 1);