Mercurial > repo
comparison 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 |
comparison
equal
deleted
inserted
replaced
4222:b0f3e267bb1e | 4223:ac0403686959 |
---|---|
1 #include "Str.h" | |
2 #include "mars.h" | |
3 #include "op.h" | |
4 #include "xmalloc.h" | |
5 | |
6 enum {MAGIC = 128}; | |
7 | |
8 static void null(struct mars **p, size_t n) { | |
9 for (; n; --n) { | |
10 p[n - 1] = NULL; | |
11 } | |
12 } | |
13 | |
14 void ma_init(struct mars *m) { | |
15 m->data = NULL; | |
16 m->table = xmalloc(m->size = MAGIC, sizeof *m->table); | |
17 null(m->table, m->size); | |
18 } | |
19 | |
20 void ma_end(struct mars *m) { | |
21 for (; m->size; --m->size) { | |
22 if (m->table[m->size - 1]) { | |
23 ma_end(m->table[m->size - 1]); | |
24 xfree(m->table[m->size - 1]); | |
25 } | |
26 } | |
27 xfree(m->table); | |
28 } | |
29 | |
30 int ma_enter(struct mars *m, const String *key, struct op *value) { | |
31 size_t p; | |
32 | |
33 for (p = 0; p < St_len(key); ++p) { | |
34 size_t tmp = ST_INDEX(key, p); | |
35 if (m->size <= tmp) { | |
36 m->table = xrealloc(m->table, m->size * 2); | |
37 null(m->table + m->size, m->size); | |
38 m->size *= 2; | |
39 } | |
40 if (!m->table[tmp]) { | |
41 m->table[tmp] = xmalloc(1, sizeof *m->table[tmp]); | |
42 ma_init(m->table[tmp]); | |
43 } | |
44 m = m->table[tmp]; | |
45 } | |
46 | |
47 if (m->data) { | |
48 return -1; | |
49 } | |
50 m->data = value; | |
51 return 0; | |
52 } | |
53 | |
54 int ma_exists(const struct mars *m, const String *key) { | |
55 size_t p; | |
56 const struct op *ret = NULL; | |
57 | |
58 for (p = 0; p < St_len(key); ++p) { | |
59 size_t tmp = ST_INDEX(key, p); | |
60 ret = m->data; | |
61 if (tmp >= m->size || !m->table[tmp]) { | |
62 return 0; | |
63 } | |
64 m = m->table[tmp]; | |
65 } | |
66 return ret != NULL; | |
67 } | |
68 | |
69 struct op *ma_find(const struct mars *m, String *key) { | |
70 size_t p; | |
71 struct op *ret = NULL; | |
72 | |
73 for (p = 0; p < St_len(key); ++p) { | |
74 size_t tmp = ST_INDEX(key, p); | |
75 ret = m->data; | |
76 if (tmp >= m->size || !m->table[tmp]) { | |
77 break; | |
78 } | |
79 m = m->table[tmp]; | |
80 } | |
81 if (ret) { | |
82 St_del(key, 0, p); | |
83 } | |
84 return ret; | |
85 } |