+proc preamble_trie {ofilehandle} {
+ set f $ofilehandle
+
+ set totype {unsigned short}
+
+ puts $f "\#include <string.h>"
+ puts $f "
+ struct yaz_iconv_trie_flat {
+ char from\[6\];
+ unsigned combining : 1;
+ $totype to;
+ };
+ struct yaz_iconv_trie_dir {
+ short ptr : 15;
+ unsigned combining : 1;
+ $totype to;
+ };
+
+ struct yaz_iconv_trie {
+ struct yaz_iconv_trie_flat *flat;
+ struct yaz_iconv_trie_dir *dir;
+ };
+ "
+ puts $f {
+ static unsigned long lookup(struct yaz_iconv_trie **ptrs, int ptr, unsigned char *inp,
+ size_t inbytesleft, size_t *no_read, int *combining)
+ {
+ struct yaz_iconv_trie *t = (ptr >= 0) ? ptrs[ptr] : 0;
+ if (!t || inbytesleft < 1)
+ return 0;
+ if (t->dir)
+ {
+ size_t ch = inp[0] & 0xff;
+ unsigned long code =
+ lookup(ptrs, t->dir[ch].ptr, inp+1, inbytesleft-1, no_read, combining);
+ if (code)
+ {
+ (*no_read)++;
+ return code;
+ }
+ if (t->dir[ch].to)
+ {
+ code = t->dir[ch].to;
+ *combining = t->dir[ch].combining;
+ *no_read = 1;
+ return code;
+ }
+ }
+ else
+ {
+ struct yaz_iconv_trie_flat *flat = t->flat;
+ while (flat->to)
+ {
+ size_t len = strlen(flat->from);
+ if (len <= inbytesleft)
+ {
+ if (memcmp(flat->from, inp, len) == 0)
+ {
+ *no_read = len;
+ *combining = flat->combining;
+ return flat->to;
+ }
+ }
+ flat++;
+ }
+ }
+ return 0;
+ }
+ }
+}
+
+proc reset_trie {} {
+ global trie
+
+ foreach x [array names trie] {
+ unset trie($x)
+ }
+
+ set trie(no) 1
+ set trie(size) 0
+ set trie(max) 0
+ set trie(split) 50
+ set trie(prefix) {}
+}
+
+proc ins_trie {from to combining} {