[Anthy-dev 927] Re: skk.scm preedit

Back to archive index

Etsushi Kato ekato****@ees*****
2004年 7月 16日 (金) 11:15:18 JST


こんにちは、加藤です。

skk の補完ですが、もう少し変更しました。いちおうこれで最後のつもりです。

前回のコードでは補完候補のバッファが一つしか作っていないので、同じアプ
リケーションの中でいくつも同時に補完していると、おかしなことになってし
まっていました (あほでした…)。revision 997 に対するパッチです。よろし
くお願いします。

-- 
Etsushi Kato
ekato****@ees*****
-------------- next part --------------
--- skk-dic.c.orig	Thu Jul 15 20:14:22 2004
+++ skk-dic.c	Fri Jul 16 10:53:47 2004
@@ -90,7 +90,10 @@
 /* completion */
 struct skk_comp_array {
   int nr_comps;
+  int refcount;
   char **comps;
+  char *head;
+  struct skk_comp_array *next;
 } *skk_comp;
 
 static int
@@ -452,13 +455,12 @@
 static void
 move_line_to_cache_head(struct dic_info *di, struct skk_line *sl)
 {
-  struct skk_line *head, *prev;
+  struct skk_line *prev;
 
   if (di->head.next == sl)
     return;
 
-  head = di->head.next;
-  prev = head;
+  prev = di->head.next;
   while (prev->next != sl) {
     prev = prev->next;
   }
@@ -470,13 +472,12 @@
 static void
 add_line_to_cache_last(struct dic_info *di, struct skk_line *sl)
 {
-  struct skk_line *head, *prev;
+  struct skk_line *prev;
 
   if (di->head.next == NULL)
     di->head.next = sl;
   else {
-    head = di->head.next;
-    prev = head;
+    prev = di->head.next;
     while (prev->next) {
       prev = prev->next;
     }	
@@ -649,27 +650,34 @@
 {
   struct skk_line *sl;
   struct skk_comp_array *ca;
-  int len;
 
-  len = strlen(s);
-  if (!di || len == 0) {
+  if (!di) {
     return NULL;
   }
   ca = malloc(sizeof(struct skk_comp_array));
   ca->nr_comps = 0;
-  ca->comps = 0;
+  ca->refcount = 0;
+  ca->comps = NULL;
+  ca->head = NULL;
+  ca->next = NULL;
+
   /* search from cache */
   for (sl = di->head.next; sl; sl = sl->next) {
-    if (!strncmp(sl->head, s, len) && strcmp(sl->head, s) &&
+    if (!strncmp(sl->head, s, strlen(s)) && strcmp(sl->head, s) &&
         (sl->okuri_head == '\0')) {
       ca->nr_comps++;
       ca->comps = realloc(ca->comps, sizeof(char *) * ca->nr_comps);
       ca->comps[ca->nr_comps - 1] = strdup(sl->head);
     }
   }
+
   if (ca->nr_comps == 0) {
     free(ca);
     ca = NULL;
+  } else {
+    ca->head = strdup(s);
+    ca->next = skk_comp;
+    skk_comp = ca;
   }
   return ca;
 }
@@ -678,7 +686,17 @@
 find_comp_array(struct dic_info *di, char *s)
 {
   struct skk_comp_array *ca;
-  ca = skk_make_comp_array_from_cache(skk_dic, s);
+
+  if (strlen(s) == 0)
+    return NULL;
+
+  for (ca = skk_comp; ca; ca = ca->next) {
+    if (!strcmp(ca->head, s))
+      break;
+  }
+  if (ca == NULL)
+    ca = skk_make_comp_array_from_cache(skk_dic, s);
+
   return ca;
 }
 
@@ -696,9 +714,12 @@
 static LISP
 skk_get_completion(LISP head_)
 {
-  skk_comp = find_comp_array_lisp(head_);
-  if (skk_comp)
+  struct skk_comp_array *ca;
+  ca = find_comp_array_lisp(head_);
+  if (ca) {
+    ca->refcount++;
     return siod_true_value();
+  }
   return NIL;
 }
 
@@ -706,11 +727,13 @@
 skk_get_nth_completion(LISP nth_, LISP head_)
 {
   int n;
+  struct skk_comp_array *ca;
   char *str;
 
+  ca = find_comp_array_lisp(head_);
   n = get_c_int(nth_);
-  if (skk_comp && skk_comp->nr_comps > n) {
-    str = skk_comp->comps[n];
+  if (ca && ca->nr_comps > n) {
+    str = ca->comps[n];
     return strcons(strlen(str), str);
   }
   return NIL;
@@ -720,25 +743,48 @@
 skk_get_nr_completions(LISP head_)
 {
   int n = 0;
+  struct skk_comp_array *ca;
 
-  if (skk_comp) {
-    n = skk_comp->nr_comps;
+  ca = find_comp_array_lisp(head_);
+  if (ca) {
+    n = ca->nr_comps;
   }
   return intcons(n);
 }
 
 static LISP
-skk_clear_completions(void)
+skk_clear_completions(LISP head_)
 {
   int i;
+  struct skk_comp_array *ca, *ca_prev;
+  char *hs;
 
-  if (skk_comp) {
-    for (i = 0; i < skk_comp->nr_comps; i++) {
-      free(skk_comp->comps[i]);
-    }
-    free(skk_comp->comps);
-    free(skk_comp);
-    skk_comp = NULL;
+  hs = get_c_string(head_);
+  for (ca = skk_comp; ca; ca = ca->next) {
+    if (!strcmp(ca->head, hs)) {
+      ca->refcount--;
+      break;
+    }
+  }
+
+  if (ca && ca->refcount == 0) {
+    for (i = 0; i < ca->nr_comps; i++) {
+      free(ca->comps[i]);
+    }
+    free(ca->comps);
+    free(ca->head);
+
+    if (ca == skk_comp) {
+      skk_comp = ca->next;
+      free(ca);
+    } else {
+      ca_prev = skk_comp;
+      while (ca_prev->next != ca) {
+        ca_prev = ca_prev->next;
+      }
+      ca_prev->next = ca->next;
+      free(ca);
+    }
   }
   return siod_true_value();
 }
@@ -1025,7 +1071,7 @@
   init_subr_1("skk-lib-get-completion", skk_get_completion);
   init_subr_2("skk-lib-get-nth-completion", skk_get_nth_completion);
   init_subr_1("skk-lib-get-nr-completions", skk_get_nr_completions);
-  init_subr_0("skk-lib-clear-completions", skk_clear_completions);
+  init_subr_1("skk-lib-clear-completions", skk_clear_completions);
 }
 
 void
-------------- next part --------------
--- skk.scm.orig	Thu Jul 15 11:14:28 2004
+++ skk.scm	Fri Jul 16 10:56:26 2004
@@ -1054,17 +1054,19 @@
 	   #t)
        (if (skk-cancel-key? key key-state)
 	   (begin
-	     (skk-lib-clear-completions)
+	     (skk-lib-clear-completions
+	       (skk-make-string (skk-context-head sc) skk-type-hiragana))
 	     (skk-context-set-state! sc 'skk-state-kanji)
 	     #f)
 	   #t)
        (begin
 	 (set! res
 	       (reverse (string-to-list (skk-get-current-completion sc))))
+	 (skk-lib-clear-completions
+	   (skk-make-string (skk-context-head sc) skk-type-hiragana))
 	 (set! len (length res))
 	 (skk-context-set-head! sc '())
 	 (skk-list-to-context-head sc res len 0)
-	 (skk-lib-clear-completions)
 	 (skk-context-set-state! sc 'skk-state-kanji)
 	 (set! res (skk-proc-state-kanji c key key-state))))
       #f)))


Anthy-dev メーリングリストの案内
Back to archive index