3 Copyright (C) 2010,2019,2020 Michael Zucchi
5 This program is free software: you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation, either version 3 of
8 the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public
16 License along with this program. If not, see
17 <http://www.gnu.org/licenses/>.
20 /* **********************************************************************
21 * a simple ordered hash/list/stack
34 // hash chain link/stack prev
47 struct node *table[64];
51 static struct node *node_alloc(tree type, const char *name) {
52 struct node *n = (struct node *)xmalloc(sizeof(struct node) + (name ? strlen(name) + 1 : 1));
61 strcpy(n->name, name);
68 static void stack_push(struct list *stack, struct node *node) {
70 stack->head->link = node;
71 node->next = stack->head;
80 static struct node *stack_pull(struct list *stack) {
81 struct node *n = stack->head;
84 stack->head = n->next;
86 stack->head->link = NULL;
94 static unsigned int ez_hash_string(const char *s) {
95 unsigned int hash = 5381;
98 //hash = (*s++) + (hash << 5) + hash;
99 hash = hash * 33 + (*s++);
104 static void list_add(struct list *list, struct node *node) {
107 list->tail->next = node;
115 static struct node *list_remhead(struct list *list) {
116 struct node *node = list->head;
118 if (node && (list->head = node->next) == NULL)
124 static void hash_put(struct hash *hash, struct node *node) {
125 int code = ez_hash_string(node->name) & 63;
127 list_add(&hash->list, node);
129 node->link = hash->table[code];
130 hash->table[code] = node;
133 struct node *hash_lookup(struct hash *hash, const char *name) {
134 int code = ez_hash_string(name) & 63;
136 for (struct node *n = hash->table[code]; n; n=n->link) {
137 if (strcmp(n->name, name) == 0)
144 static void hash_put_bytype(struct hash *hash, struct node *node) {
145 int code = (int)((uintptr_t)node->type >> 5) & 63;
147 list_add(&hash->list, node);
149 node->link = hash->table[code];
150 hash->table[code] = node;
153 struct node *hash_lookup_bytype(struct hash *hash, tree type) {
154 int code = (int)((uintptr_t)type >> 5) & 63;
156 for (struct node *n = hash->table[code]; n; n=n->link) {
164 /* simple growable c buffer */
171 static void buffer_init(struct buffer *b, size_t size) {
174 b->data = (char *)xmalloc(size);
177 static void buffer_room(struct buffer *b, size_t len) {
178 if (b->pos + len >= b->size) {
181 } while (b->pos + len >= b->size);
183 b->data = (char *)xrealloc(b->data, b->size);
187 static void buffer_add(struct buffer *b, const char *v) {
188 size_t len = strlen(v);
191 strcpy(b->data + b->pos, v);