Add support for preloading lua modules. This is useful both when
providing lua bindings to applications based on librazor and when
producing static binaries using librazor (where otherwise the lua
POSIX library would need to be included as an additional dynamic
object).
2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (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 License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "razor-internal.h"
26 array_init(struct array *array)
28 memset(array, 0, sizeof *array);
32 array_release(struct array *array)
38 array_add(struct array *array, int size)
48 while (alloc < array->size + size)
51 if (array->alloc < alloc) {
52 data = realloc(array->data, alloc);
59 p = array->data + array->size;
65 /* RAZOR_IMMEDIATE and RAZOR_ENTRY_LAST must have the same value */
66 #define RAZOR_ENTRY_LAST 0x80
67 #define RAZOR_IMMEDIATE 0x80
68 #define RAZOR_EMPTY_LIST 0xff
71 list_set_empty(struct list_head *head)
74 head->flags = RAZOR_EMPTY_LIST;
78 list_set_ptr(struct list_head *head, uint32_t ptr)
85 list_set_array(struct list_head *head, struct array *pool,
86 struct array *items, int force_indirect)
90 if (!force_indirect) {
91 if (items->size == 0) {
94 } else if (items->size == sizeof (uint32_t)) {
95 head->list_ptr = *(uint32_t *) items->data;
96 head->flags = RAZOR_IMMEDIATE;
101 p = array_add(pool, items->size);
102 memcpy(p, items->data, items->size);
103 p[items->size / sizeof *p - 1].flags = RAZOR_ENTRY_LAST;
104 list_set_ptr(head, p - (struct list *) pool->data);
108 list_first(struct list_head *head, struct array *pool)
110 if (head->flags == RAZOR_EMPTY_LIST)
112 else if (head->flags == RAZOR_IMMEDIATE)
113 return (struct list *) head;
115 return (struct list *) pool->data + head->list_ptr;
119 list_next(struct list *list)
127 list_remap_pool(struct array *pool, uint32_t *map)
129 struct list *p, *end;
131 end = pool->data + pool->size;
132 for (p = pool->data; p < end; p++)
133 p->data = map[p->data];
137 list_remap_head(struct list_head *head, uint32_t *map)
139 if (head->flags == RAZOR_IMMEDIATE)
140 head->list_ptr = map[head->list_ptr];
145 hashtable_init(struct hashtable *table, struct array *pool)
147 array_init(&table->buckets);
152 hashtable_release(struct hashtable *table)
154 array_release(&table->buckets);
158 hash_string(const char *key)
161 unsigned int hash = 0;
163 for (p = key; *p; p++)
164 hash = (hash * 617) ^ *p;
170 hashtable_lookup(struct hashtable *table, const char *key)
172 unsigned int mask, start, i;
176 pool = table->pool->data;
177 mask = table->buckets.alloc - 1;
178 start = hash_string(key) * sizeof(uint32_t);
180 for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
181 b = table->buckets.data + ((start + i) & mask);
183 if (*b == 0xFFFFFFFF)
186 if (strcmp(key, &pool[*b]) == 0)
194 do_insert(struct hashtable *table, uint32_t value)
196 unsigned int mask, start, i;
200 key = (char *) table->pool->data + value;
201 mask = table->buckets.alloc - 1;
202 start = hash_string(key) * sizeof(uint32_t);
204 for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
205 b = table->buckets.data + ((start + i) & mask);
206 if (*b == 0xFFFFFFFF) {
214 add_to_string_pool(struct hashtable *table, const char *key)
219 len = strlen(key) + 1;
220 p = array_add(table->pool, len);
223 return p - (char *) table->pool->data;
227 hashtable_insert(struct hashtable *table, const char *key)
229 uint32_t value, *buckets, *b, *end;
232 alloc = table->buckets.alloc;
233 array_add(&table->buckets, 4 * sizeof *buckets);
234 if (alloc != table->buckets.alloc) {
235 end = table->buckets.data + alloc;
236 memset(end, 0xFF, table->buckets.alloc - alloc);
237 for (b = table->buckets.data; b < end; b++) {
239 if (value != 0xFFFFFFFF) {
241 do_insert(table, value);
246 value = add_to_string_pool(table, key);
247 do_insert (table, value);
253 hashtable_tokenize(struct hashtable *table, const char *string)
260 token = hashtable_lookup(table, string);
261 if (token != 0xFFFFFFFF)
264 return hashtable_insert(table, string);