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;
 | 
						|
}
 |