Mercurial > repo
diff src/ploki/mars.c @ 4223:ac0403686959
<oerjan> rm -rf src/ploki; mv ploki src
author | HackBot |
---|---|
date | Fri, 20 Dec 2013 22:18:50 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ploki/mars.c Fri Dec 20 22:18:50 2013 +0000 @@ -0,0 +1,85 @@ +#include "Str.h" +#include "mars.h" +#include "op.h" +#include "xmalloc.h" + +enum {MAGIC = 128}; + +static void null(struct mars **p, size_t n) { + for (; n; --n) { + p[n - 1] = NULL; + } +} + +void ma_init(struct mars *m) { + m->data = NULL; + m->table = xmalloc(m->size = MAGIC, sizeof *m->table); + null(m->table, m->size); +} + +void ma_end(struct mars *m) { + for (; m->size; --m->size) { + if (m->table[m->size - 1]) { + ma_end(m->table[m->size - 1]); + xfree(m->table[m->size - 1]); + } + } + xfree(m->table); +} + +int ma_enter(struct mars *m, const String *key, struct op *value) { + size_t p; + + for (p = 0; p < St_len(key); ++p) { + size_t tmp = ST_INDEX(key, p); + if (m->size <= tmp) { + m->table = xrealloc(m->table, m->size * 2); + null(m->table + m->size, m->size); + m->size *= 2; + } + if (!m->table[tmp]) { + m->table[tmp] = xmalloc(1, sizeof *m->table[tmp]); + ma_init(m->table[tmp]); + } + m = m->table[tmp]; + } + + if (m->data) { + return -1; + } + m->data = value; + return 0; +} + +int ma_exists(const struct mars *m, const String *key) { + size_t p; + const struct op *ret = NULL; + + for (p = 0; p < St_len(key); ++p) { + size_t tmp = ST_INDEX(key, p); + ret = m->data; + if (tmp >= m->size || !m->table[tmp]) { + return 0; + } + m = m->table[tmp]; + } + return ret != NULL; +} + +struct op *ma_find(const struct mars *m, String *key) { + size_t p; + struct op *ret = NULL; + + for (p = 0; p < St_len(key); ++p) { + size_t tmp = ST_INDEX(key, p); + ret = m->data; + if (tmp >= m->size || !m->table[tmp]) { + break; + } + m = m->table[tmp]; + } + if (ret) { + St_del(key, 0, p); + } + return ret; +}