+unsigned char **pools;
+unsigned char *poolptr;
+size_t poolat;
+#define C_POOLSIZE (128*1024*1024)
+
+static GMQCC_INLINE void newpool() {
+ poolat = 0;
+ poolptr = mem_a(C_POOLSIZE);
+ vec_push(pools, poolptr);
+}
+
+void correct_init(void) {
+ newpool();
+}
+
+static GMQCC_INLINE void *correct_alloc(size_t _b) {
+ size_t *ptr;
+ size_t b = _b + sizeof(size_t);
+ if (poolat + b >= C_POOLSIZE)
+ newpool();
+ poolat += b;
+ ptr = (size_t*)poolptr;
+ poolptr += b;
+ *ptr = _b;
+ return (void*)(ptr+1);
+}
+
+static GMQCC_INLINE void *correct_realloc(void *_ptr, size_t _b) {
+ size_t *ptr = ((size_t*)_ptr) - 1;
+ size_t oldlen = *ptr;
+ size_t len = (oldlen < _b ? oldlen : _b);
+ size_t b = _b + sizeof(size_t);
+ size_t *newptr;
+
+ newptr = (size_t*)correct_alloc(b);
+ *newptr++ = _b;
+ memcpy(newptr, _ptr, len);
+ return (void*)(newptr);
+}
+
+void correct_delete(void) {
+ size_t i;
+ for (i = 0; i < vec_size(pools); ++i)
+ mem_d(pools[i]);
+ pools = NULL;
+ poolptr = NULL;
+ poolat = 0;
+}
+
+static GMQCC_INLINE char *correct_outstr(const char *s) {
+ char *o = util_strdup(s);
+ correct_delete();
+ return o;
+}
+
+correct_trie_t* correct_trie_new()
+{
+ correct_trie_t *t = (correct_trie_t*)mem_a(sizeof(correct_trie_t));
+ t->value = NULL;
+ t->entries = NULL;
+ return t;
+}
+
+void correct_trie_del_sub(correct_trie_t *t)
+{
+ size_t i;
+ for (i = 0; i < vec_size(t->entries); ++i)
+ correct_trie_del_sub(&t->entries[i]);
+ vec_free(t->entries);
+}
+
+void correct_trie_del(correct_trie_t *t)
+{
+ size_t i;
+ for (i = 0; i < vec_size(t->entries); ++i)
+ correct_trie_del_sub(&t->entries[i]);
+ vec_free(t->entries);
+ mem_d(t);
+}
+
+void* correct_trie_get(const correct_trie_t *t, const char *key)
+{
+ const unsigned char *data = (const unsigned char*)key;
+ while (*data) {
+ unsigned char ch = *data;
+ const size_t vs = vec_size(t->entries);
+ size_t i;
+ const correct_trie_t *entries = t->entries;
+ for (i = 0; i < vs; ++i) {
+ if (entries[i].ch == ch) {
+ t = &entries[i];
+ ++data;
+ break;
+ }
+ }
+ if (i == vs)
+ return NULL;
+ }
+ return t->value;
+}
+
+void correct_trie_set(correct_trie_t *t, const char *key, void * const value)
+{
+ const unsigned char *data = (const unsigned char*)key;
+ while (*data) {
+ unsigned char ch = *data;
+ correct_trie_t *entries = t->entries;
+ const size_t vs = vec_size(t->entries);
+ size_t i;
+ for (i = 0; i < vs; ++i) {
+ if (entries[i].ch == ch) {
+ t = &entries[i];
+ break;
+ }
+ }
+ if (i == vs) {
+ correct_trie_t *elem = (correct_trie_t*)vec_add(t->entries, 1);
+ elem->ch = ch;
+ elem->value = NULL;
+ elem->entries = NULL;
+ t = elem;
+ }
+ ++data;
+ }
+ t->value = value;
+}
+