1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <alloca.h>
#include <inttypes.h>
#include "AVLTree.h"
#include "symbol.h"
#include "error.h"
static AVLTree symbolset = {
NULL,
NULL,
NULL,
(AVLCompare)strcmp,
};
int symcmp(symbol_t a, symbol_t b) {
uintptr_t a1 = (uintptr_t)a;
uintptr_t b1 = (uintptr_t)b;
if (a1 < b1)
return -1;
if (a1 > b1)
return 1;
return 0;
}
void symbol_dump(void) {
AVLNode *c;
for(c = symbolset.head; c; c = c->next)
fprintf(stderr, "%s\n", (char *)c->item);
}
symbol_t symbol(const char *src) {
AVLNode *node, *newnode;
char *s;
int r;
if(!src)
return errno = EINVAL, (symbol_t)NULL;
r = AVLCloseSearch(&symbolset, src, &node);
if(!r && node)
return node->item;
if((s = xstrdup(src))) {
if((newnode = AVLInitNode(xmalloc(sizeof(AVLNode)), s))) {
switch(r) {
case -1:
AVLInsertNodeBefore(&symbolset, node, newnode);
break;
case 0:
AVLInsertTopNode(&symbolset, newnode);
break;
case 1:
AVLInsertNodeAfter(&symbolset, node, newnode);
break;
}
return s;
}
}
return NULL;
}
symbol_t nsymbol(const char *src, unsigned length) {
if (length > 4096)
error_exit(7, "excessive symbol length\n");
char *p = alloca(length + 1);
memcpy(p, src, length);
p[length] = 0;
return symbol(p);
}
|