9 #define MEMORY 0x8000000
11 static unsigned char *memory_pool = NULL;
12 static size_t memory_next = 0;
14 static void memory_cleanup(void) {
18 void *memory_allocate(size_t bytes) {
22 memory_pool = malloc(MEMORY);
23 atexit(memory_cleanup);
26 if (memory_next > MEMORY)
29 value = &memory_pool[memory_next];
32 if (memory_next > MEMORY) {
34 fprintf(stderr, "[lice] out of memory");
47 static void string_reallocate(string_t *string) {
48 int size = string->allocated * 2;
49 char *buffer = memory_allocate(size);
51 strcpy(buffer, string->buffer);
52 string->buffer = buffer;
53 string->allocated = size;
56 void string_catf(string_t *string, const char *fmt, ...) {
59 int left = string->allocated - string->length;
63 write = vsnprintf(string->buffer + string->length, left, fmt, va);
67 string_reallocate(string);
70 string->length += write;
75 string_t *string_create(void) {
76 string_t *string = memory_allocate(sizeof(string_t));
77 string->buffer = memory_allocate(8);
78 string->allocated = 8;
80 string->buffer[0] = '\0';
84 char *string_buffer(string_t *string) {
85 return string->buffer;
88 void string_cat(string_t *string, char ch) {
89 if (string->allocated == (string->length + 1))
90 string_reallocate(string);
91 string->buffer[string->length++] = ch;
92 string->buffer[string->length] = '\0';
95 char *string_quote(char *p) {
96 string_t *string = string_create();
98 if (*p == '\"' || *p == '\\')
99 string_catf(string, "\\%c", *p);
101 string_catf(string, "\\n");
103 string_cat(string, *p);
106 return string->buffer;
109 size_t string_length(string_t *string) {
110 return (string) ? string->length : 0;
118 void *table_create(void *parent) {
119 table_t *table = memory_allocate(sizeof(table_t));
120 table->list = list_create();
121 table->parent = parent;
126 void *table_find(table_t *table, const char *key) {
127 for (; table; table = table->parent) {
128 for (list_iterator_t *it = list_iterator(table->list); !list_iterator_end(it); ) {
129 table_entry_t *entry = list_iterator_next(it);
130 if (!strcmp(key, entry->key))
137 void table_insert(table_t *table, char *key, void *value) {
138 table_entry_t *entry = memory_allocate(sizeof(table_entry_t));
140 entry->value = value;
142 list_push(table->list, entry);
145 void *table_parent(table_t *table) {
146 return table->parent;
149 list_t *table_values(table_t *table) {
150 list_t *list = list_create();
151 for (; table; table = table->parent)
152 for (list_iterator_t *it = list_iterator(table->list); !list_iterator_end(it); )
153 list_push(list, ((table_entry_t*)list_iterator_next(it))->value);
157 list_t *table_keys(table_t *table) {
158 list_t *list = list_create();
159 for (; table; table = table->parent)
160 for (list_iterator_t *it = list_iterator(table->list); !list_iterator_end(it); )
161 list_push(list, ((table_entry_t*)list_iterator_next(it))->key);
165 pair_t *pair_create(void *first, void *second) {
166 pair_t *pair = memory_allocate(sizeof(pair_t));
168 pair->second = second;
172 int strcasecmp(const char *s1, const char *s2) {
173 const unsigned char *u1 = (const unsigned char *)s1;
174 const unsigned char *u2 = (const unsigned char *)s2;
176 while (tolower(*u1) == tolower(*u2++))
179 return tolower(*u1) - tolower(*--u2);
182 int strncasecmp(const char *s1, const char *s2, size_t n) {
183 const unsigned char *u1 = (const unsigned char *)s1;
184 const unsigned char *u2 = (const unsigned char *)s2;
190 if (tolower(*u1) != tolower(*u2++))
191 return tolower(*u1) - tolower(*--u2);
199 size_t getline(char **line, size_t *n, FILE *stream) {
216 if ((c = fgetc(stream)) == EOF)
224 if ((p - buf) > (size - 1)) {
226 buf = realloc(buf, size);