/*
* symtable.c -- part of ZilUtils/ZilAsm
*
- * Copyright (C) 2016 Jason Self <j@jxself.org>
+ * Copyright (C) 2016, 2019 Jason Self <j@jxself.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
*/
#include <string.h>
+#include "strings.h"
#include <stdlib.h>
#include <assert.h>
#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 */