--- /dev/null
+#ifndef _CHISE_NAME_H
+#define _CHISE_NAME_H
+
+typedef struct CHISE_HASH_TABLE_ENTRY CHISE_HASH_TABLE_ENTRY;
+typedef struct CHISE_HASH_TABLE CHISE_HASH_TABLE;
+
+typedef CHISE_HASH_TABLE CHISE_NAME_TABLE;
+typedef CHISE_HASH_TABLE_ENTRY CHISE_NAME_TABLE_ENTRY;
+
+CHISE_NAME_TABLE* chise_make_name_table ();
+void chise_destroy_name_table (CHISE_NAME_TABLE* table);
+int chise_name_table_put (CHISE_NAME_TABLE* table,
+ unsigned char *key, void *value);
+void* chise_name_table_get (CHISE_NAME_TABLE* table, unsigned char *key);
+int chise_name_table_grow (CHISE_NAME_TABLE* table);
+
+#endif /* !_CHISE_NAME_H */
--- /dev/null
+#include <string.h>
+
+typedef struct CHISE_HASH_TABLE_ENTRY
+{
+ void *key;
+ void *value;
+} CHISE_HASH_TABLE_ENTRY;
+
+typedef struct CHISE_HASH_TABLE
+{
+ size_t size;
+ CHISE_HASH_TABLE_ENTRY *data;
+} CHISE_HASH_TABLE;
+
+CHISE_HASH_TABLE*
+chise_make_hash_table (size_t size)
+{
+ CHISE_HASH_TABLE* hash
+ = (CHISE_HASH_TABLE*)malloc (sizeof (CHISE_HASH_TABLE));
+
+ if (hash == NULL)
+ return NULL;
+
+ hash->data
+ = (CHISE_HASH_TABLE_ENTRY*) malloc (sizeof (CHISE_HASH_TABLE_ENTRY)
+ * size);
+ if (hash->data == NULL)
+ {
+ free (hash);
+ return NULL;
+ }
+
+ hash->size = size;
+ memset (hash->data, 0, sizeof (CHISE_HASH_TABLE_ENTRY) * size);
+ return hash;
+}
+
+void
+chise_destroy_hash_table (CHISE_HASH_TABLE* hash)
+{
+ if (hash == NULL)
+ return;
+ free (hash->data);
+ free (hash);
+}
+
+
+/* derived from hashpjw, Dragon Book P436. */
+int
+chise_hash_c_string (const unsigned char *ptr)
+{
+ int hash = 0;
+
+ while (*ptr != '\0')
+ {
+ int g;
+ hash = (hash << 4) + *ptr++;
+ g = hash & 0xf0000000;
+ if (g)
+ hash = (hash ^ (g >> 24)) ^ g;
+ }
+ return hash & 07777777777;
+}
+
+
+typedef CHISE_HASH_TABLE CHISE_NAME_TABLE;
+typedef CHISE_HASH_TABLE_ENTRY CHISE_NAME_TABLE_ENTRY;
+
+CHISE_NAME_TABLE*
+chise_make_name_table ()
+{
+ return chise_make_hash_table (32);
+}
+
+void
+chise_destroy_name_table (CHISE_NAME_TABLE* table)
+{
+ chise_destroy_hash_table (table);
+}
+
+int
+chise_name_table_put (CHISE_NAME_TABLE* table,
+ unsigned char *key, void *value)
+{
+ int i, index;
+ CHISE_NAME_TABLE_ENTRY* entry;
+
+ if (table == NULL)
+ return -1;
+
+ index = chise_hash_c_string (key) % table->size;
+ for (i = index; i < table->size; i++)
+ {
+ entry = &table->data[i];
+ if (entry->key == NULL)
+ {
+ size_t len = strlen (key);
+
+ entry->key = (unsigned char*)malloc (len + 1);
+ if (entry->key == NULL)
+ return -1;
+ strcpy (entry->key, key);
+ entry->value = value;
+ return 0;
+ }
+ else if (strcmp (entry->key, key) == 0)
+ {
+ entry->value = value;
+ return 0;
+ }
+ }
+ if (chise_name_table_grow (table) == 0)
+ return chise_name_table_put (table, key, value);
+ return -1;
+}
+
+void *
+chise_name_table_get (CHISE_NAME_TABLE* table,
+ unsigned char *key)
+{
+ int i, index;
+ CHISE_NAME_TABLE_ENTRY entry;
+
+ if (table == NULL)
+ return NULL;
+
+ index = chise_hash_c_string (key) % table->size;
+ for (i = index; i < table->size; i++)
+ {
+ entry = table->data[i];
+ if (entry.key == NULL)
+ return NULL;
+ else if (strcmp (entry.key, key) == 0)
+ return entry.value;
+ }
+ return NULL;
+}
+
+int
+chise_name_table_grow (CHISE_NAME_TABLE* table)
+{
+ CHISE_NAME_TABLE *new_table
+ = chise_make_hash_table (table->size * 2);
+ int i;
+
+ if (new_table == NULL)
+ return -1;
+
+ for (i = 0; i < table->size; i++)
+ {
+ CHISE_NAME_TABLE_ENTRY entry = table->data[i];
+ if ( (entry.key != NULL) && (entry.value != NULL) )
+ {
+ int status
+ = chise_name_table_put (new_table, entry.key, entry.value);
+ if (status != 0)
+ {
+ chise_destroy_hash_table (new_table);
+ return -1;
+ }
+ }
+ }
+ table->size = new_table->size;
+ table->data = new_table->data;
+ free (new_table);
+ return 0;
+}