blob: 036431ac44c038b08e72c59fc60710171eb53173 [file] [log] [blame]
#ifdef UEMF
#include "uemf.h"
#else
#include "basic/basicInternal.h"
#endif
static int calcPrime(int size);
typedef struct {
int inuse;
int hash_size;
sym_t **hash_table;
} sym_tabent_t;
static int symMax;
static int hashIndex(sym_tabent_t *tp, char_t *name);
static int htIndex;
static sym_t *hash(sym_tabent_t *tp, char_t *name);
static sym_t *next;
static sym_tabent_t **sym;
sym_fd_t symOpen(int hash_size)
{
sym_fd_t sd;
sym_tabent_t *tp;
a_assert(hash_size > 2);
if ((sd = hAlloc((void***) &sym)) < 0) {
return -1;
}
if ((tp = (sym_tabent_t*) balloc(B_L, sizeof(sym_tabent_t))) == NULL) {
symMax = hFree((void***) &sym, sd);
return -1;
}
memset(tp, 0, sizeof(sym_tabent_t));
if (sd >= symMax) {
symMax = sd + 1;
}
a_assert(0 <= sd && sd < symMax);
sym[sd] = tp;
tp->hash_size = calcPrime(hash_size);
tp->hash_table = (sym_t**) balloc(B_L, tp->hash_size * sizeof(sym_t*));
a_assert(tp->hash_table);
if(tp->hash_table)
memset(tp->hash_table, 0, tp->hash_size * sizeof(sym_t*));
return sd;
}
void symClose(sym_fd_t sd)
{
sym_tabent_t *tp;
sym_t *sp, *forw;
int i;
a_assert(0 <= sd && sd < symMax);
tp = sym[sd];
a_assert(tp);
for (i = 0; i < tp->hash_size; i++) {
for (sp = tp->hash_table[i]; sp; sp = forw) {
forw = sp->forw;
valueFree(&sp->name);
valueFree(&sp->content);
bfree(B_L, (void*) sp);
sp = forw;
}
}
bfree(B_L, (void*) tp->hash_table);
symMax = hFree((void***) &sym, sd);
bfree(B_L, (void*) tp);
}
sym_t* symFirst(sym_fd_t sd)
{
sym_tabent_t *tp;
sym_t *sp, *forw;
int i;
a_assert(0 <= sd && sd < symMax);
tp = sym[sd];
a_assert(tp);
for (i = 0; i < tp->hash_size; i++) {
#if 0 // KW 3 cov M
for (sp = tp->hash_table[i]; sp; sp = forw) {
forw = sp->forw;
if (forw == NULL) {
htIndex = i + 1;
next = tp->hash_table[htIndex];
} else {
htIndex = i;
next = forw;
}
return sp;
}
#else
sp = tp->hash_table[i];
if(NULL != sp){
forw = sp->forw;
if (forw == NULL) {
htIndex = i + 1;
next = tp->hash_table[htIndex];
} else {
htIndex = i;
next = forw;
}
return sp;
}
#endif
}
return NULL;
}
sym_t* symNext(sym_fd_t sd)
{
sym_tabent_t *tp;
sym_t *sp, *forw;
int i;
a_assert(0 <= sd && sd < symMax);
tp = sym[sd];
a_assert(tp);
for (i = htIndex; i < tp->hash_size; i++) {
#if 0 // kw 3 cov M
for (sp = next; sp; sp = forw) {
forw = sp->forw;
if (forw == NULL) {
htIndex = i + 1;
next = tp->hash_table[htIndex];
} else {
htIndex = i;
next = forw;
}
return sp;
}
#else
sp = next;
if(NULL != sp) {
forw = sp->forw;
if (forw == NULL) {
htIndex = i + 1;
next = tp->hash_table[htIndex];
} else {
htIndex = i;
next = forw;
}
return sp;
}
#endif
next = tp->hash_table[i + 1];
}
return NULL;
}
sym_t *symEnter(sym_fd_t sd, char_t *name, value_t v, int arg)
{
sym_tabent_t *tp;
sym_t *sp, *last;
char_t *cp;
int hindex;
a_assert(name);
a_assert(0 <= sd && sd < symMax);
tp = sym[sd];
a_assert(tp);
last = NULL;
hindex = hashIndex(tp, name);
if ((sp = tp->hash_table[hindex]) != NULL) {
for (; sp; sp = sp->forw) {
cp = sp->name.value.string;
if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
break;
}
last = sp;
}
if (sp) {
if (sp->content.valid) {
valueFree(&sp->content);
}
sp->content = v;
sp->arg = arg;
return sp;
}
sp = (sym_t*) balloc(B_L, sizeof(sym_t));
if (sp == NULL) {
return NULL;
}
sp->content = v;
sp->forw = (sym_t*) NULL;
sp->name = valueString(name, VALUE_ALLOCATE);
sp->arg = arg;
last->forw = sp;
} else {
sp = (sym_t*) balloc(B_L, sizeof(sym_t));
if (sp == NULL) {
return NULL;
}
tp->hash_table[hindex] = sp;
tp->hash_table[hashIndex(tp, name)] = sp;
sp->arg = arg;
sp->content = v;
sp->name = valueString(name, VALUE_ALLOCATE);
sp->forw = (sym_t*) NULL;
}
return sp;
}
sym_t *symLookup(sym_fd_t sd, char_t *name)
{
sym_tabent_t *tp;
sym_t *sp;
char_t *cp;
a_assert(0 <= sd && sd < symMax);
if ((tp = sym[sd]) == NULL) {
return NULL;
}
if (name == NULL || *name == '\0') {
return NULL;
}
for (sp = hash(tp, name); sp; sp = sp->forw) {
cp = sp->name.value.string;
if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
break;
}
}
return sp;
}
int symDelete(sym_fd_t sd, char_t *name)
{
sym_t *last = NULL;
int hindex;
char_t *cp;
sym_t *sp;
sym_tabent_t *tp;
a_assert(name && *name);
a_assert(0 <= sd && sd < symMax);
tp = sym[sd];
a_assert(tp);
hindex = hashIndex(tp, name);
if ((sp = tp->hash_table[hindex]) != NULL) {
for ( ; sp; sp = sp->forw) {
cp = sp->name.value.string;
if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
break;
}
last = sp;
}
}
if (sp == (sym_t*) NULL) {
return -1;
}
if (last) {
last->forw = sp->forw;
} else {
tp->hash_table[hindex] = sp->forw;
}
valueFree(&sp->name);
valueFree(&sp->content);
bfree(B_L, (void*) sp);
return 0;
}
static int hashIndex(sym_tabent_t *tp, char_t *name)
{
unsigned int sum;
int i;
a_assert(tp);
i = 0;
sum = 0;
while (*name) {
sum += (((int) *name++) << i);
i = (i + 7) % (BITS(int) - BITSPERBYTE);
}
return sum % tp->hash_size;
}
static int isPrime(int n)
{
int i, max;
a_assert(n > 0);
max = n / 2;
for (i = 2; i <= max; i++) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
static sym_t *hash(sym_tabent_t *tp, char_t *name)
{
a_assert(tp);
return tp->hash_table[hashIndex(tp, name)];
}
static int calcPrime(int size)
{
int count;
a_assert(size > 0);
for (count = size; count > 0; count--) {
if (isPrime(count)) {
return count;
}
}
return 1;
}