#include "gmqcc.h"
#include "lexer.h"
+#define HT_MACROS 1024
typedef struct {
bool on;
bool was_on;
bool output_on;
ppcondition *conditions;
- ppmacro **macros;
+ /*ppmacro **macros;*/
+ ht macros; /* hashtable<string, ppmacro*> */
char *output_string;
ftepp = (ftepp_t*)mem_a(sizeof(*ftepp));
memset(ftepp, 0, sizeof(*ftepp));
+ ftepp->macros = util_htnew(HT_MACROS);
ftepp->output_on = true;
return ftepp;
static void ftepp_delete(ftepp_t *self)
{
- size_t i;
ftepp_flush_do(self);
if (self->itemname)
mem_d(self->itemname);
if (self->includename)
vec_free(self->includename);
+
+ /*
for (i = 0; i < vec_size(self->macros); ++i)
ppmacro_delete(self->macros[i]);
+
vec_free(self->macros);
+*/
+
+ util_htrem(self->macros, (void (*)(void*))&ppmacro_delete);
+
vec_free(self->conditions);
if (self->lex)
lex_close(self->lex);
static ppmacro* ftepp_macro_find(ftepp_t *ftepp, const char *name)
{
- size_t i;
- for (i = 0; i < vec_size(ftepp->macros); ++i) {
- if (!strcmp(name, ftepp->macros[i]->name))
- return ftepp->macros[i];
- }
- return NULL;
+ return util_htget(ftepp->macros, name);
}
static void ftepp_macro_delete(ftepp_t *ftepp, const char *name)
{
- size_t i;
- for (i = 0; i < vec_size(ftepp->macros); ++i) {
- if (!strcmp(name, ftepp->macros[i]->name)) {
- vec_remove(ftepp->macros, i, 1);
- return;
- }
- }
+ util_htrm(ftepp->macros, name, NULL);
}
static GMQCC_INLINE int ftepp_next(ftepp_t *ftepp)
return false;
}
+#if 0
if (ftepp->output_on)
vec_push(ftepp->macros, macro);
+#endif
+ if (ftepp->output_on)
+ util_htset(ftepp->macros, macro->name, (void*)macro);
else {
ppmacro_delete(macro);
}
lex_ctx ctx = { "__builtin__", 0 };
ctx.file = source;
macro = ppmacro_new(ctx, name);
- vec_push(ftepp->macros, macro);
+ /*vec_push(ftepp->macros, macro);*/
+ util_htset(ftepp->macros, name, macro);
}
const char *ftepp_get(ftepp_t *ftepp)
* util_htdel(foo);
*/
hash_table_t *util_htnew (size_t size);
+void util_htrem (hash_table_t *ht, void (*callback)(void *data));
void util_htset (hash_table_t *ht, const char *key, void *value);
void util_htdel (hash_table_t *ht);
size_t util_hthash(hash_table_t *ht, const char *key);
void util_htseth(hash_table_t *ht, const char *key, size_t hash, void *value);
+void util_htrmh (hash_table_t *ht, const char *key, size_t bin, void (*cb)(void*));
+void util_htrm (hash_table_t *ht, const char *key, void (*cb)(void*));
void *util_htget (hash_table_t *ht, const char *key);
void *util_htgeth(hash_table_t *ht, const char *key, size_t hash);
* Free all allocated data in a hashtable, this is quite the amount
* of work.
*/
-void util_htdel(hash_table_t *ht) {
+void util_htrem(hash_table_t *ht, void (*callback)(void *data)) {
size_t i = 0;
for (; i < ht->size; i++) {
hash_node_t *n = ht->table[i];
while (n) {
if (n->key)
mem_d(n->key);
+ if (callback)
+ callback(n->value);
p = n;
n = n->next;
mem_d(p);
mem_d(ht);
}
+void util_htrmh(hash_table_t *ht, const char *key, size_t bin, void (*cb)(void*)) {
+ hash_node_t **pair = &ht->table[bin];
+ hash_node_t *tmp;
+
+ while (*pair && (*pair)->key && strcmp(key, (*pair)->key) > 0)
+ pair = &(*pair)->next;
+
+ tmp = *pair;
+ if (!tmp || !tmp->key || strcmp(key, tmp->key) != 0)
+ return;
+
+ if (cb)
+ (*cb)(tmp->value);
+
+ *pair = tmp->next;
+ mem_d(tmp->key);
+ mem_d(tmp);
+}
+
+void util_htrm(hash_table_t *ht, const char *key, void (*cb)(void*)) {
+ util_htrmh(ht, key, util_hthash(ht, key), cb);
+}
+
+void util_htdel(hash_table_t *ht) {
+ util_htrem(ht, NULL);
+}
+
/*
* A basic implementation of a hash-set. Unlike a hashtable, a hash
* set doesn't maintain key-value pairs. It simply maintains a key