commit 3ef23faabd8c656f0f26984d15e260349705202a
parent 398ef613664fb700917ab2c499d4c5b18fb0fe36
Author: ukai <ukai>
Date:   Mon, 10 Dec 2001 17:02:43 +0000
[w3m-dev 02651] search keymap using hash
From: Hironori Sakamoto <hsaka@mth.biglobe.ne.jp>
Diffstat:
17 files changed, 176 insertions(+), 126 deletions(-)
diff --git a/.cvsignore b/.cvsignore
@@ -4,6 +4,7 @@ config.param
 funcname.c
 funcname1.h
 funcname2.h
+functable.c
 tagtable.c
 inflate
 mktable
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,52 @@
+2001-12-11  Hironori Sakamoto <hsaka@mth.biglobe.ne.jp>
+
+	* [w3m-dev 02651] search keymap using hash
+	* XMakefile (func.c): depends functable.c funcname1.h
+	* XMakefile (functable.c): generated from funcname.tab
+	* functable.awk: added
+	* fm.h (w3mKeyList): deleted
+	* func.c (w3mKeyList): ditto
+	* file.c (readHeader): change getFuncList()
+	* func.c (w3mNFuncList): deleted
+	* func.c (functable.c): include
+	* func.c (initKeymap): no need to count w3mFuncList
+	* func.c (initKeymap): change getFuncList()
+	* func.c (initKeymap): put data to keyData hashtable
+	* func.c (countFuncList): deleted
+	* func.c (getFuncList): use getHash_si()
+	* func.c (getKeyData): use getHash_iv()
+	* func.c (addKeyList): deleted
+	* func.c (searchKeyList): deleted
+	* func.h (textlist.h): include
+	* func.h (hash.h): include
+	* func.h (KEY_HASH_SIZE): added
+	* func.h (KeyListItem): deleted
+	* func.h (KeyList): deleted
+	* hash.c: s/hist/sv/
+	* hash.c: add defhashfunc_i(int, void *, iv)
+	* hash.h: s/hist/sv/
+	* hash.h: defhash(int, void *, iv)
+	* hash.h (putHash_*): added
+	* hash.h (getHash_*): added
+	* hash.h (defhashfunc_i): added
+	* history.c (pushHashHist): s/hist/sv/
+	* history.c (getHashHist): s/hist/sv/
+	* history.h (Hist): s/hist/sv/
+	* main.c (searchKeyData): item deleted
+	* main.c (searchKeyData): data added
+	* main.c (searchKeyData): use getKayData() instead of searchKeyList()
+	* main.c (setAlarm): w3mNFuncList deleted
+	* main.c (setAlarm): change getFuncList()
+	* menu.c (w3mNFuncList): deleted
+	* menu.c (w3mFuncList): deleted
+	* menu.c (initMenu): no need to count w3mFuncList
+	* menu.c (setMenuItem): change getFuncList()
+	* proto.h (countFuncList): deleted
+	* proto.h (getFuncList): change args
+	* proto.h (addKeyList): deleted
+	* proto.h (searchKeyList): deleted
+	* proto.h (getKeyData): added
+
 2001-12-11  Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
 
 	* [w3m-dev 02650]
diff --git a/XMakefile b/XMakefile
@@ -54,7 +54,7 @@ tagtable.c: html.h tagtable.tab mktable$(EXT)
 # entity.h: html.h entity.tab mktable$(EXT)
 #	./mktable 100 entity.tab > entity.h
 
-func.o: funcname.c
+func.o: funcname.c functable.c funcname1.h
 keybind.o: funcname2.h
 keybind_lynx.o: funcname2.h
 parsetagx.o: html.c
@@ -68,6 +68,11 @@ funcname1.h: funcname.tab
 funcname2.h: funcname.tab
 	sort funcname.tab | awk -f funcname2.awk > funcname2.h
 
+functable.c: funcname.tab mktable$(EXT)
+	sort funcname.tab | awk -f functable.awk > functable.tab
+	./mktable$(EXT) 100 functable.tab > functable.c
+	-rm -f functable.tab
+
 mktable$(EXT): mktable.o hash.o $(ALIB) $(GCTARGET)
 	$(CC) $(CFLAGS) -o mktable$(EXT) mktable.o hash.o  $(LIBS2)
 
diff --git a/file.c b/file.c
@@ -768,14 +768,13 @@ readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu)
 		 uf->scheme == SCM_LOCAL_CGI) {
 	    Str funcname = Strnew();
 	    int f;
-	    extern int w3mNFuncList;
 
 	    p = lineBuf2->ptr + 12;
 	    SKIP_BLANKS(p);
 	    while (*p && !IS_SPACE(*p))
 		Strcat_char(funcname, *(p++));
 	    SKIP_BLANKS(p);
-	    f = getFuncList(funcname->ptr, w3mFuncList, w3mNFuncList);
+	    f = getFuncList(funcname->ptr);
 	    if (f >= 0) {
 		tmp = Strnew_charp(p);
 		Strchop(tmp);
diff --git a/fm.h b/fm.h
@@ -640,7 +640,6 @@ extern char EscDKeymap[];
 extern char PcKeymap[];
 #endif
 extern FuncList w3mFuncList[];
-extern KeyList w3mKeyList;
 
 global char *HTTP_proxy init(NULL);
 #ifdef USE_GOPHER
diff --git a/func.c b/func.c
@@ -10,11 +10,10 @@
 #include "myctype.h"
 
 #include "funcname.c"
-int w3mNFuncList = 0;
+#include "functable.c"
 
-KeyList w3mKeyList = {
-    NULL, 0, 0
-};
+#define KEYDATA_HASH_SIZE 16
+static Hash_iv *keyData = NULL;
 
 void
 initKeymap(void)
@@ -28,9 +27,6 @@ initKeymap(void)
     int verbose = 1;
     extern int str_to_bool(char *value, int old);
 
-    if (!w3mNFuncList)
-	w3mNFuncList = countFuncList(w3mFuncList);
-
     if ((kf = fopen(rcFile(KEYMAP_FILE), "rt")) == NULL)
 	return;
 
@@ -70,7 +66,7 @@ initKeymap(void)
 	    continue;
 	}
 	s = getWord(&p);
-	f = getFuncList(s, w3mFuncList, w3mNFuncList);
+	f = getFuncList(s);
 	if (f < 0) {
 	    emsg = Sprintf("line %d: invalid command '%s'", lineno, s)->ptr;
 	    record_err_message(emsg);
@@ -87,41 +83,27 @@ initKeymap(void)
 	else
 	    GlobalKeymap[c] = f;
 	s = getQWord(&p);
-	addKeyList(&w3mKeyList, c, s);
+	if (*s) {
+	    if (keyData == NULL)
+		keyData = newHash_iv(KEYDATA_HASH_SIZE);
+	    putHash_iv(keyData, c, (void *)s);
+	}
     }
     fclose(kf);
 }
 
 int
-countFuncList(FuncList *list)
+getFuncList(char *id)
 {
-    int i;
-
-    for (i = 0; list->id != NULL; i++, list++) ;
-    return i;
+    return getHash_si(&functable, id, -1);
 }
 
-int
-getFuncList(char *id, FuncList *list, int nlist)
+char *
+getKeyData(int key)
 {
-    int i, is, ie, m;
-
-    if (id == NULL || *id == '\0' || nlist <= 0)
-	return -1;
-
-    is = 0;
-    ie = nlist - 1;
-    while (1) {
-	i = is + (ie - is) / 2;
-	if ((m = strcmp(id, list[i].id)) == 0)
-	    return i;
-	else if (is >= ie)
-	    return -1;
-	else if (m > 0)
-	    is = i + 1;
-	else
-	    ie = i - 1;
-    }
+    if (keyData == NULL)
+	return NULL;
+    return (char *)getHash_iv(keyData, key, NULL);
 }
 
 int
@@ -240,46 +222,6 @@ getKey(char *s)
 	return -1;
 }
 
-void
-addKeyList(KeyList *list, int key, char *data)
-{
-    KeyListItem *item;
-
-    if (data == NULL || *data == '\0')
-	data = NULL;
-    else
-	data = allocStr(data, -1);
-    item = searchKeyList(list, key);
-    if (item == NULL) {
-	if (data == NULL)
-	    return;
-	list->nitem++;
-	if (list->nitem > list->size) {
-	    list->size = (list->size >= 2) ? (list->size * 3 / 2) : 2;
-	    list->item = New_Reuse(KeyListItem, list->item,
-				   list->size * sizeof(KeyListItem));
-	}
-	item = &(list->item[list->nitem - 1]);
-	item->key = key;
-    }
-    item->data = data;
-}
-
-KeyListItem *
-searchKeyList(KeyList *list, int key)
-{
-    int i;
-    KeyListItem *item;
-
-    if (list == NULL)
-	return NULL;
-    for (i = 0, item = list->item; i < list->nitem; i++, item++) {
-	if (key == item->key)
-	    return item;
-    }
-    return NULL;
-}
-
 char *
 getWord(char **str)
 {
diff --git a/func.h b/func.h
@@ -6,6 +6,11 @@
 #ifndef FUNC_H
 #define FUNC_H
 
+#include "textlist.h"
+#include "hash.h"
+
+#define KEY_HASH_SIZE 127
+
 #define K_ESC  0x100
 #define K_ESCB 0x200
 #define K_ESCD 0x400
@@ -15,15 +20,4 @@ typedef struct _FuncList {
     void (*func) ();
 } FuncList;
 
-typedef struct _KeyListItem {
-    int key;
-    char *data;
-} KeyListItem;
-
-typedef struct _KeyList {
-    KeyListItem *item;
-    int nitem;
-    int size;
-} KeyList;
-
 #endif				/* not FUNC_H */
diff --git a/functable.awk b/functable.awk
@@ -0,0 +1,9 @@
+BEGIN {
+  print "#include <stdio.h>"
+  print "#include \"funcname1.h\""
+  print "%%"
+}
+/^#/ { next }
+{
+  print $1 " FUNCNAME_" $2;
+} 
diff --git a/hash.c b/hash.c
@@ -25,5 +25,6 @@ hashfunc(char *s)
 /* *INDENT-OFF* */
 defhashfunc(char *, int, si)
 defhashfunc(char *, char *, ss)
-defhashfunc(char *, void *, hist)
+defhashfunc(char *, void *, sv)
+defhashfunc_i(int, void *, iv)
 /* *INDENT-ON* */
diff --git a/hash.h b/hash.h
@@ -20,7 +20,8 @@ extern type getHash_##sym(Hash_##sym *t, keytype key, type failval);
 
 defhash(char *, int, si)
 defhash(char *, char *, ss)
-defhash(char *, void *, hist)
+defhash(char *, void *, sv)
+defhash(int, void *, iv)
 #define defhashfunc(keytype,type,sym) \
 Hash_##sym * \
 newHash_##sym(int size)\
@@ -79,4 +80,62 @@ getHash_##sym(Hash_##sym *t, keytype key, type failval)\
     return failval;\
   return hi->value;\
 }
+#define defhashfunc_i(keytype,type,sym) \
+Hash_##sym * \
+newHash_##sym(int size)\
+{\
+  struct Hash_##sym *hash;\
+  int i;\
+\
+  hash = (Hash_##sym*)GC_malloc(sizeof(Hash_##sym));\
+  hash->size = size;\
+  hash->tab = (HashItem_##sym**)GC_malloc(size*sizeof(HashItem_##sym*));\
+  for (i = 0; i < size; i++)\
+    hash->tab[i] = NULL;\
+  return hash;\
+}\
+\
+static HashItem_##sym* \
+lookupHash_##sym(Hash_##sym *t, keytype key, int *hashval_return)\
+{\
+  HashItem_##sym *hi;\
+\
+  *hashval_return = key%t->size;\
+  for (hi = t->tab[*hashval_return]; hi != NULL; hi = hi->next) {\
+    if (hi->key == key)\
+      return hi;\
+  }\
+  return NULL;\
+}\
+\
+void \
+putHash_##sym(Hash_##sym *t, keytype key, type value)\
+{\
+  int h;\
+  HashItem_##sym *hi;\
+\
+  hi = lookupHash_##sym(t,key,&h);\
+  if (hi) {\
+    hi->value = value;\
+    return;\
+  }\
+\
+  hi = (HashItem_##sym*)GC_malloc(sizeof(HashItem_##sym));\
+  hi->key = key;\
+  hi->value = value;\
+  hi->next = t->tab[h];\
+  t->tab[h] = hi;\
+}\
+\
+type \
+getHash_##sym(Hash_##sym *t, keytype key, type failval)\
+{\
+  int h;\
+  HashItem_##sym *hi;\
+\
+  hi = lookupHash_##sym(t,key,&h);\
+  if (hi == NULL)\
+    return failval;\
+  return hi->value;\
+}
 #endif				/* not HASH_H */
diff --git a/history.c b/history.c
@@ -140,7 +140,7 @@ pushHashHist(Hist *hist, char *ptr)
 	hist->list->nitem--;
     }
     item = pushHist(hist, ptr);
-    putHash_hist(hist->hash, ptr, (void *)item);
+    putHash_sv(hist->hash, ptr, (void *)item);
     return item;
 }
 
@@ -152,11 +152,11 @@ getHashHist(Hist *hist, char *ptr)
     if (hist == NULL || hist->list == NULL)
 	return NULL;
     if (hist->hash == NULL) {
-	hist->hash = newHash_hist(HIST_HASH_SIZE);
+	hist->hash = newHash_sv(HIST_HASH_SIZE);
 	for (item = hist->list->first; item; item = item->next)
-	    putHash_hist(hist->hash, (char *)item->ptr, (void *)item);
+	    putHash_sv(hist->hash, (char *)item->ptr, (void *)item);
     }
-    return (HistItem *)getHash_hist(hist->hash, ptr, NULL);
+    return (HistItem *)getHash_sv(hist->hash, ptr, NULL);
 }
 
 char *
diff --git a/history.h b/history.h
@@ -14,7 +14,7 @@ typedef GeneralList HistList;
 typedef struct {
     HistList *list;
     HistItem *current;
-    Hash_hist *hash;
+    Hash_sv *hash;
 } Hist;
 
 extern Hist *newHist();
diff --git a/indep.c b/indep.c
@@ -33,7 +33,7 @@ allocStr(const char *s, int len)
 int
 strCmp(const void *s1, const void *s2)
 {
-    return strcmp(*(const char **)s1,  *(const char **)s2);
+    return strcmp(*(const char **)s1, *(const char **)s2);
 }
 
 char *
diff --git a/main.c b/main.c
@@ -4615,7 +4615,7 @@ set_buffer_environ(Buffer *buf)
 char *
 searchKeyData(void)
 {
-    KeyListItem *item;
+    char *data;
 
     if (CurrentKeyData != NULL && *CurrentKeyData != '\0')
 	return allocStr(CurrentKeyData, -1);
@@ -4625,10 +4625,10 @@ searchKeyData(void)
 #endif
     if (CurrentKey < 0)
 	return NULL;
-    item = searchKeyList(&w3mKeyList, CurrentKey);
-    if (item == NULL || item->data == NULL || *item->data == '\0')
+    data = getKeyData(CurrentKey);
+    if (data == NULL || *data == '\0')
 	return NULL;
-    return allocStr(item->data, -1);
+    return allocStr(data, -1);
 }
 
 static int
@@ -4700,7 +4700,6 @@ setAlarm(void)
 {
     char *data;
     int sec = 0, cmd = -1;
-    extern int w3mNFuncList;
 
     CurrentKeyData = NULL;	/* not allowed in w3m-control: */
     data = searchKeyData();
@@ -4714,7 +4713,7 @@ setAlarm(void)
     if (*data != '\0') {
 	sec = atoi(getWord(&data));
 	if (sec > 0)
-	    cmd = getFuncList(getWord(&data), w3mFuncList, w3mNFuncList);
+	    cmd = getFuncList(getWord(&data));
     }
     if (cmd >= 0) {
 	setAlarmEvent(sec, AL_EXPLICIT, cmd, getQWord(&data));
diff --git a/menu.c b/menu.c
@@ -329,8 +329,6 @@ static MenuItem MainMenuItem[] = {
 
 /* --- MainMenu (END) --- */
 
-extern int w3mNFuncList;
-extern FuncList w3mFuncList[];
 static MenuList *w3mMenuList;
 
 static Menu *CurrentMenu = NULL;
@@ -1421,9 +1419,6 @@ initMenu(void)
     if ((mf = fopen(rcFile(MENU_FILE), "rt")) == NULL)
 	goto create_menu;
 
-    if (!w3mNFuncList)
-	w3mNFuncList = countFuncList(w3mFuncList);
-
     in_menu = 0;
     while (!feof(mf)) {
 	line = Strfgets(mf);
@@ -1501,7 +1496,7 @@ setMenuItem(MenuItem *item, char *type, char *line)
 	    return -1;
 	item->type = MENU_FUNC;
 	item->label = label;
-	f = getFuncList(func, w3mFuncList, w3mNFuncList);
+	f = getFuncList(func);
 	item->func = w3mFuncList[(f >= 0) ? f : FUNCNAME_nulcmd].func;
 	item->keys = keys;
 	item->data = data;
diff --git a/myctype.c b/myctype.c
@@ -30,42 +30,42 @@ unsigned char MYCTYPE_MAP[0x100] = {
 unsigned char MYCTYPE_DIGITMAP[0x100] = {
     /* NUL SOH STX ETX EOT ENQ ACK BEL   BS  HT  LF  VT  FF  CR  SO  SI */
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN   EM SUB ESC  FS  GS  RS  US */
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     /* SPC   !   "   #   $   %   &   '    (   )   *   +   ,   -   .   / */
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     /*   0   1   2   3   4   5   6   7    8   9   :   ;   <   =   >   ? */
     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
     /*   @   A   B   C   D   E   F   G    H   I   J   K   L   M   N   O */
     255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     /*   P   Q   R   S   T   U   V   W    X   Y   Z   [   \   ]   ^   _ */
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     /*   `   a   b   c   d   e   f   g    h   i   j   k   l   m   n   o */
     255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     /*   p   q   r   s   t   u   v   w    x   y   z   {   |   }   ~ DEL */
 
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
     255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-	255,
+    255,
 };
 
 
diff --git a/proto.h b/proto.h
@@ -520,11 +520,9 @@ extern void msToggle(void);
 extern char *searchKeyData(void);
 
 extern void initKeymap(void);
-extern int countFuncList(FuncList *list);
-extern int getFuncList(char *id, FuncList *list, int nlist);
+extern int getFuncList(char *id);
 extern int getKey(char *s);
-extern void addKeyList(KeyList *list, int key, char *data);
-extern KeyListItem *searchKeyList(KeyList *list, int key);
+extern char *getKeyData(int key);
 extern char *getWord(char **str);
 extern char *getQWord(char **str);