X-Git-Url: https://jxself.org/git/?p=zilutils.git;a=blobdiff_plain;f=zilasm%2Fsymtable.c;h=a5ff791b864307b80df14bb9088b8097d621c6fe;hp=2c5735f93cebb003ce8241b4ae898c9bf7575bb8;hb=HEAD;hpb=37d32bd49e745a5c1686b6495f60172b24222361 diff --git a/zilasm/symtable.c b/zilasm/symtable.c index 2c5735f..a5ff791 100644 --- a/zilasm/symtable.c +++ b/zilasm/symtable.c @@ -1,7 +1,7 @@ /* * symtable.c -- part of ZilUtils/ZilAsm * - * Copyright (C) 2016 Jason Self + * Copyright (C) 2016, 2019 Jason Self * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,6 +20,7 @@ */ #include +#include "strings.h" #include #include @@ -27,120 +28,163 @@ #define FIELD_SIZE(Typ,Field) (sizeof(((Typ*)0)->Field)) -Symtable* symtable_create(unsigned elems_count, unsigned name_size, unsigned elem_size) +Symtable * +symtable_create (unsigned elems_count, unsigned name_size, unsigned elem_size) { - size_t n = elems_count * (name_size + elem_size) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents); - Symtable *p = malloc(n); - assert(p); - bzero(p, n); - p->elems_count = elems_count; - p->name_size = name_size; - p->elem_size = elem_size; - return p; + //size_t n = elems_count * (name_size + elem_size) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents); + //Symtable *p = malloc(n); + + Symtable *p = (Symtable *) malloc (sizeof (Symtable)); + assert (p); + size_t n = elems_count * sizeof (SymtableElem); + p->contents = (SymtableElem *) malloc (n); + bzero (p->contents, n); + p->elems_count = elems_count; + p->name_size = name_size; + p->elem_size = elem_size; + return p; } -void symtable_destroy(Symtable *p) + +void +symtable_destroy (Symtable * p) { - assert(p); - free(p); + assert (p); + for (int i = 0; i > p->elems_count; ++i) + { + free (p->contents[i].name); + free (p->contents[i].value); + } + free (p->contents); + free (p); } -static unsigned name2pos(const Symtable *p, const char *name, unsigned namelen) + +static unsigned +name2pos (const Symtable * p, const char *name, unsigned namelen) { - assert(p); - unsigned key = 0; - while(namelen--) - key = ((key << 1) | (*name++)); - return key % p->elems_count; + assert (p); + unsigned key = 0; + while (namelen--) + key = ((key << 1) | (*name++)); + return key % p->elems_count; } -static char *getsym(const Symtable *p, unsigned pos) + +static SymtableElem * +getsym (const Symtable * p, unsigned pos) { - //assert(p); //already checked by caller - //assert(pos < p->elems_count); - return ((char*)p) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents) + (pos * p->elem_size); + //assert(p); //already checked by caller + //assert(pos < p->elems_count); + //return ((char*)p) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents) + (pos * p->elem_size); + return &p->contents[pos]; } -void* symtable_lookup2(const Symtable *p, const char *name, unsigned namelen) -{ - assert(p); - assert(name); - assert(namelen > 0); - assert(namelen < p->name_size); - - unsigned start = name2pos(p, name, namelen); - unsigned pos = start; - - do { - char *s = getsym(p, pos); - if (!*s) - return NULL; - if (!memcmp(name, s, namelen)) - return s + p->name_size; - if (++pos >= p->elems_count) - pos = 0; - } while(pos != start); +// searches for a element in the symbols table and returns its value +void * +symtable_lookup2 (const Symtable * p, const char *name, unsigned namelen) +{ + assert (p); + assert (name); + assert (namelen > 0); + assert (namelen < p->name_size); + + unsigned start = name2pos (p, name, namelen); + unsigned pos = start; + + do + { + SymtableElem *s = getsym (p, pos); + if (!s->name) return NULL; + if (!memcmp (name, s->name, namelen)) + return s->value; + if (++pos >= p->elems_count) + pos = 0; + } + while (pos != start); + + return NULL; } -void* symtable_lookup(const Symtable *p, const char *name) + +void * +symtable_lookup (const Symtable * p, const char *name) { - assert(name); - return symtable_lookup2(p, name, strlen(name)); + assert (name); + return symtable_lookup2 (p, name, strlen (name)); } -void* symtable_add(Symtable *p, const char *name, void *contents) + +void * +symtable_add (Symtable * p, const char *name, void *value) { - assert(name); - return symtable_add2(p, name, strlen(name), contents); + assert (name); + return symtable_add2 (p, name, strlen (name), value); } -void* symtable_add2(Symtable *p, const char *name, unsigned namelen, void *contents) + +void * +symtable_add2 (Symtable * p, const char *name, unsigned namelen, void *value) { - assert(p); - assert(name); - assert(namelen > 0 && namelen < p->name_size); - assert(contents); - - unsigned start = name2pos(p, name, namelen); - unsigned pos = start; - - do { - char *s = getsym(p, pos); - if (!*s) { - memcpy(s, name, namelen + 1); - s[namelen] = '\0'; - memcpy(s + p->name_size, contents, p->elem_size); - return s + p->name_size; - } - if (!memcmp(name, s, namelen) && s[namelen] == '\0') { - /* TODO!! report error */ - return NULL; /* ..already added */ - } - if (++pos >= p->elems_count) - pos = 0; - } while(pos != start); - - /* TODO!! report overflow */ - return NULL; - /* TODO!!! */ + assert (p); + assert (name); + assert (namelen > 0 && namelen < p->name_size); + assert (value); + + unsigned start = name2pos (p, name, namelen); + unsigned pos = start; + + do + { + SymtableElem *elem = getsym (p, pos); + if (!elem->name) + { + elem->name = (char *) malloc (namelen + 1); + memcpy (elem->name, name, namelen + 1); + elem->name[namelen] = '\0'; + elem->value = malloc (p->elem_size); + memcpy (elem->value, value, p->elem_size); + return elem; + } + if (!memcmp (name, elem->name, namelen) && elem->name[namelen] == '\0') + { + /* TODO!! report error */ + return NULL; /* ..already added */ + } + if (++pos >= p->elems_count) + pos = 0; + } + while (pos != start); + + /* TODO!! report overflow */ + return NULL; + /* TODO!!! */ } -static int sortfunc(const void *a, const void *b) + +static int +sortfunc (const void *a, const void *b) { - const char *s1 = a; - const char *s2 = b; - if (!*s1 && !*s2) return 0; - if (!*s1) return 1; - if (!*s2) return -1; - return strcmp(s1, s2); + const char *s1 = (const char *) a; + const char *s2 = (const char *) b; + if (!*s1 && !*s2) + return 0; + if (!*s1) + return 1; + if (!*s2) + return -1; + return strcmp (s1, s2); } -void symtable_sort(Symtable *p) + +void +symtable_sort (Symtable * p) { - assert(p); - qsort(getsym(p, 0), p->elems_count, p->elem_size + p->name_size, sortfunc); + assert (p); + qsort (getsym (p, 0), p->elems_count, p->elem_size + p->name_size, + sortfunc); } /* END */