/* Copyright (C) 1999 Free Software Foundation This file is part of libgcj. This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ #include #include #include "make-trie.h" typedef struct trie_node { int key; int level; int position; union { int value; struct trie_node *node; } u[16]; } trie_node; trie_node * make_node () { trie_node *node = (trie_node *) malloc (sizeof(trie_node)); if (node == NULL) abort(); return node; } trie_node * make_leaf_node () { trie_node *node = make_node (); int i = 16; while (--i >= 0) node->u[i].value = -1; return node; } trie_node * make_branch_node () { trie_node *node = make_node (); int i = 16; while (--i >= 0) node->u[i].node = NULL; return node; } trie_node *table = NULL; void enter (int key, int value) { trie_node **ptr = &table; int shift = 12; for (; shift > 0; shift -= 4) { if (*ptr == NULL) { *ptr = make_branch_node (); (*ptr)->key = key & (0xFFFF << (shift + 4)); (*ptr)->level = shift / 4; } ptr = &(*ptr)->u[(key >> shift) & 0xF].node; } if (*ptr == NULL) { *ptr = make_leaf_node (); (*ptr)->key = key & 0xFFF0; (*ptr)->level = 0; } if ((*ptr)->u[key & 0xF].value != -1 && (*ptr)->u[key & 0xF].value != value) fprintf(stderr, "duplicate value for key: %d, %d!\n", key, value); (*ptr)->u[key & 0xF].value = value; } int assigned = 0; void assign (trie_node *node, int level) { int i; if (node == NULL) return; if (node->level != level) abort(); node->position = assigned; assigned++; if (level == 0) return; for (i = 0; i < 16; i++) { assign (node->u[i].node, level-1); } } int next_node_index_toprint = 0; void print (trie_node *node, int index, int level, FILE *out) { int i; if (node->key != index || node->level != level) abort(); if (level == 0) /* leaf node */ { for (i = 0; i < 16; i++) { int node_index = index | (i << (level * 4)); if (node_index < next_node_index_toprint) abort(); if (node->u[i].value == -1) fprintf (out, " /* key: 0x%x */ 0xffff,\n", node_index); else fprintf (out, " /* key: 0x%x */ 0x%x,\n", node_index, node->u[i].value); next_node_index_toprint = node_index + 1; } } else { for (i = 0; i < 16; i++) { int node_index = index | (i << (level * 4)); fprintf (out, " /* branch: 0x%0*x%.*s */ ", 4 - level, node_index >> ( 4 * level), level, "XXXX"); if (node->u[i].node == NULL) fprintf (out, "0,\n"); else fprintf (out, "%d,\n", 16 * node->u[i].node->position); } for (i = 0; i < 16; i++) { int node_index = index | (i << (level * 4)); if (node->u[i].node != NULL) print (node->u[i].node, node_index, level-1, out); } } } void print_table (char *name, FILE *out) { assign (table, 3); fprintf(out, "/* This file is automatically generated. */\n"); fprintf(out, "unsigned short %s[] = {\n", name); print (table, 0x0000, 3, out); fprintf(out, "};\n"); } #if 0 int main (int argc, char **argv) { int count = 0; for (;;) { int key, value; int i = scanf (" 0x%x 0x%x", &key, &value); if (i < 2) break; count++; enter (key, value); } return 0; } #endif