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:
parent
6be246b846
commit
3c24084d94
2
lex.c
2
lex.c
|
@ -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
28
table.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue