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)))