133 lines
3.2 KiB
C
133 lines
3.2 KiB
C
/*
|
|
* Copyright (C) 2007 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "symtab.h"
|
|
|
|
#define DEFAULT_TABLE_SIZE 16
|
|
|
|
typedef struct {
|
|
char *symbol;
|
|
const void *cookie;
|
|
unsigned int flags;
|
|
} SymbolTableEntry;
|
|
|
|
struct SymbolTable {
|
|
SymbolTableEntry *table;
|
|
int numEntries;
|
|
int maxSize;
|
|
};
|
|
|
|
SymbolTable *
|
|
createSymbolTable()
|
|
{
|
|
SymbolTable *tab;
|
|
|
|
tab = (SymbolTable *)malloc(sizeof(SymbolTable));
|
|
if (tab != NULL) {
|
|
tab->numEntries = 0;
|
|
tab->maxSize = DEFAULT_TABLE_SIZE;
|
|
tab->table = (SymbolTableEntry *)malloc(
|
|
tab->maxSize * sizeof(SymbolTableEntry));
|
|
if (tab->table == NULL) {
|
|
free(tab);
|
|
tab = NULL;
|
|
}
|
|
}
|
|
return tab;
|
|
}
|
|
|
|
void
|
|
deleteSymbolTable(SymbolTable *tab)
|
|
{
|
|
if (tab != NULL) {
|
|
while (tab->numEntries > 0) {
|
|
free(tab->table[--tab->numEntries].symbol);
|
|
}
|
|
free(tab->table);
|
|
}
|
|
}
|
|
|
|
void *
|
|
findInSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags)
|
|
{
|
|
int i;
|
|
|
|
if (tab == NULL || symbol == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
// TODO: Sort the table and binary search
|
|
for (i = 0; i < tab->numEntries; i++) {
|
|
if (strcmp(tab->table[i].symbol, symbol) == 0 &&
|
|
tab->table[i].flags == flags)
|
|
{
|
|
return (void *)tab->table[i].cookie;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int
|
|
addToSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags,
|
|
const void *cookie)
|
|
{
|
|
if (tab == NULL || symbol == NULL || cookie == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
/* Make sure that this symbol isn't already in the table.
|
|
*/
|
|
if (findInSymbolTable(tab, symbol, flags) != NULL) {
|
|
return -2;
|
|
}
|
|
|
|
/* Make sure there's enough space for the new entry.
|
|
*/
|
|
if (tab->numEntries == tab->maxSize) {
|
|
SymbolTableEntry *newTable;
|
|
int newSize;
|
|
|
|
newSize = tab->numEntries * 2;
|
|
if (newSize < DEFAULT_TABLE_SIZE) {
|
|
newSize = DEFAULT_TABLE_SIZE;
|
|
}
|
|
newTable = (SymbolTableEntry *)realloc(tab->table,
|
|
newSize * sizeof(SymbolTableEntry));
|
|
if (newTable == NULL) {
|
|
return -1;
|
|
}
|
|
tab->maxSize = newSize;
|
|
tab->table = newTable;
|
|
}
|
|
|
|
/* Insert the new entry.
|
|
*/
|
|
symbol = strdup(symbol);
|
|
if (symbol == NULL) {
|
|
return -1;
|
|
}
|
|
// TODO: Sort the table
|
|
tab->table[tab->numEntries].symbol = (char *)symbol;
|
|
tab->table[tab->numEntries].cookie = cookie;
|
|
tab->table[tab->numEntries].flags = flags;
|
|
tab->numEntries++;
|
|
|
|
return 0;
|
|
}
|