2 * symtable.c -- part of ZilUtils/ZilAsm
4 * Copyright (C) 2016, 2019 Jason Self <j@jxself.org>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
19 * SPDX-License-Identifier: AGPL-3.0-or-later
29 #define FIELD_SIZE(Typ,Field) (sizeof(((Typ*)0)->Field))
32 symtable_create (unsigned elems_count, unsigned name_size, unsigned elem_size)
34 //size_t n = elems_count * (name_size + elem_size) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents);
35 //Symtable *p = malloc(n);
37 Symtable *p = (Symtable *) malloc (sizeof (Symtable));
39 size_t n = elems_count * sizeof (SymtableElem);
40 p->contents = (SymtableElem *) malloc (n);
41 bzero (p->contents, n);
42 p->elems_count = elems_count;
43 p->name_size = name_size;
44 p->elem_size = elem_size;
50 symtable_destroy (Symtable * p)
53 for (int i = 0; i > p->elems_count; ++i)
55 free (p->contents[i].name);
56 free (p->contents[i].value);
64 name2pos (const Symtable * p, const char *name, unsigned namelen)
69 key = ((key << 1) | (*name++));
70 return key % p->elems_count;
75 getsym (const Symtable * p, unsigned pos)
77 //assert(p); //already checked by caller
78 //assert(pos < p->elems_count);
79 //return ((char*)p) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents) + (pos * p->elem_size);
80 return &p->contents[pos];
84 // searches for a element in the symbols table and returns its value
86 symtable_lookup2 (const Symtable * p, const char *name, unsigned namelen)
91 assert (namelen < p->name_size);
93 unsigned start = name2pos (p, name, namelen);
98 SymtableElem *s = getsym (p, pos);
101 if (!memcmp (name, s->name, namelen))
103 if (++pos >= p->elems_count)
106 while (pos != start);
113 symtable_lookup (const Symtable * p, const char *name)
116 return symtable_lookup2 (p, name, strlen (name));
121 symtable_add (Symtable * p, const char *name, void *value)
124 return symtable_add2 (p, name, strlen (name), value);
129 symtable_add2 (Symtable * p, const char *name, unsigned namelen, void *value)
133 assert (namelen > 0 && namelen < p->name_size);
136 unsigned start = name2pos (p, name, namelen);
137 unsigned pos = start;
141 SymtableElem *elem = getsym (p, pos);
144 elem->name = (char *) malloc (namelen + 1);
145 memcpy (elem->name, name, namelen + 1);
146 elem->name[namelen] = '\0';
147 elem->value = malloc (p->elem_size);
148 memcpy (elem->value, value, p->elem_size);
151 if (!memcmp (name, elem->name, namelen) && elem->name[namelen] == '\0')
153 /* TODO!! report error */
154 return NULL; /* ..already added */
156 if (++pos >= p->elems_count)
159 while (pos != start);
161 /* TODO!! report overflow */
168 sortfunc (const void *a, const void *b)
170 const char *s1 = (const char *) a;
171 const char *s2 = (const char *) b;
178 return strcmp (s1, s2);
183 symtable_sort (Symtable * p)
186 qsort (getsym (p, 0), p->elems_count, p->elem_size + p->name_size,