Author: yamakenz
Date: Sun Jul 22 02:36:05 2007
New Revision: 4769

Modified:
   trunk/scm/canna.scm
   trunk/uim/canna.c

Log:
* This commit simplify canna.c. No new features are added

* uim/canna.c
  - Include uim-scm-abbrev.h
  - (MAX_CONTEXT, context_array, context_len): Removed
  - (VALID_CANNA_CONTEXTP, VALID_SEGMENT_INDEXP): New macro
  - (enum canna_api_result, enum learning_mode): New type
  - (context_list): New static variable
  - (get_canna_context, init_canna_lib, create_context,
    release_context, _reset_conversion, _update_status,
    begin_conversion, get_nth_candidate, get_unconv_candidate,
    get_unconv_candidate, get_nr_segments, get_nr_candidate,
    resize_segment, commit_segment, reset_conversion,
    uim_plugin_instance_init, uim_plugin_instance_quit):
    * Replace integer-based 'id' with pointer object
    * Add lacked error handlings
    * Increase semantic readability
* scm/canna.scm
  - (canna-release-handler, canna-begin-conv): Replace ac-id validity
    check by number? with not-false to follow the id->ptr change


Modified: trunk/scm/canna.scm
==============================================================================
--- trunk/scm/canna.scm (original)
+++ trunk/scm/canna.scm Sun Jul 22 02:36:05 2007
@@ -395,7 +395,7 @@
 
 (define (canna-release-handler cc)
   (let ((cc-id (canna-context-cc-id cc)))
-    (if (number? cc-id)
+    (if cc-id
         (canna-lib-release-context cc-id))))
 
 (define (canna-flush cc)
@@ -470,7 +470,7 @@
 (define (canna-begin-conv cc)
   (let ((cc-id (canna-context-cc-id cc))
        (preconv-str (canna-make-whole-string cc #t canna-type-hiragana)))
-    (if (and (number? cc-id)
+    (if (and cc-id
              (> (string-length preconv-str) 0))
        (let ((num (canna-lib-begin-conversion cc-id preconv-str)))
          (if num

Modified: trunk/uim/canna.c
==============================================================================
--- trunk/uim/canna.c   (original)
+++ trunk/uim/canna.c   Sun Jul 22 02:36:05 2007
@@ -40,15 +40,30 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
+
 #include "uim-scm.h"
+#include "uim-scm-abbrev.h"
 #include "plugin.h"
 
-/* #define UIM_CANNA_DEBUG */
-
-#define MAX_CONTEXT 256
+#if 0
+#define UIM_CANNA_DEBUG
+#endif
 
 #define BUFSIZE 1024
 
+#define VALID_CANNA_CONTEXTP(cc)    ((cc) && (cc)->rk_context_id != -1)
+#define VALID_SEGMENT_INDEXP(cc, i) (0 <= (i) && (i) < cc->segment_num)
+
+enum canna_api_result {
+  ERR = -1,
+  OK  = 0
+};
+
+enum learning_mode {
+  FORGET_SELECTED_CAND = 0,
+  LEARN_SELECTED_CAND  = 1
+};
+
 struct canna_context {
   char diclist[BUFSIZE];
 
@@ -59,58 +74,36 @@
   int segment_num;
 };
 
-static struct canna_context *context_array = NULL;
-
-#if 0
-static int context_array_len;
-#endif
 static int rk_initialized = -1;
 static char *cannaserver = NULL;
+static uim_lisp context_list;
+
 
+#ifdef UIM_CANNA_DEBUG
 static struct canna_context *
-get_canna_context(int id)
+get_canna_context(uim_lisp cc_)
 {
+  struct canna_context *cc;
 
-  if (id >= MAX_CONTEXT || id < 0)
-    return NULL;
-#ifdef UIM_CANNA_DEBUG
-  printf("rk_context_id: %d\n", context_array[id].rk_context_id);
-  printf("segment_num: %d\n", context_array[id].segment_num);
-#endif
-  return &context_array[id];
+  cc = uim_scm_c_ptr(cc_);
+  printf("rk_context_id: %d\n", cc->rk_context_id);
+  printf("segment_num: %d\n", cc->segment_num);
+  return cc;
 }
+#else
+#define get_canna_context(cc_) ((struct canna_context *)uim_scm_c_ptr(cc_))
+#endif
 
 static uim_lisp
 init_canna_lib(uim_lisp str_)
 {
-  struct canna_context *context;
-  int i;
-
-  if (str_ != uim_scm_f())
-    cannaserver = uim_scm_c_str(str_);
-  else
-    cannaserver = NULL;
-
-  context_array = malloc(sizeof(struct canna_context) * MAX_CONTEXT);
-  if (context_array == NULL)
-    return uim_scm_f();
-
-  context = context_array;
-
-  for (i = 0; i < MAX_CONTEXT; i++) {
-    context->rk_context_id = -1;
-    context->rk_mode = (RK_XFER << RK_XFERBITS) | RK_KFER;
-
-    context->max_cand_num_list = NULL;
-
-    context->segment_num = -1;
-
-    context->diclist[0] = '\0';
-    context++;
-  }
+  cannaserver = (NFALSEP(str_)) ? uim_scm_c_str(str_) : NULL;
 
+  /* Immediate init & quit to test cannaserver connectivity? Real
+   * initialization is exist at beginning of create_context(). I don't
+   * know why this sequence is needed at here.  -- YamaKen 2007-07-21 */
   if (rk_initialized == -1) {
-    if (RkInitialize(cannaserver) == -1) {
+    if (RkInitialize(cannaserver) == ERR) {
       fprintf(stderr, "%s\n", strerror(errno));
       return uim_scm_f();
     }
@@ -121,77 +114,88 @@
 }
 
 static uim_lisp
-create_context() {
-  int i;
+create_context(void)
+{
+  struct canna_context *cc;
+  uim_lisp cc_;
+  int dic_num;
   char *buf;
-  int buflen;
-  struct canna_context *cc = context_array;
+  int buflen, i;
 
   if (rk_initialized == -1) {
-    if (RkInitialize(cannaserver) == -1) {
+    if (RkInitialize(cannaserver) == ERR) {
       fprintf(stderr, "%s\n", strerror(errno));
       return uim_scm_f();
     }
     rk_initialized = 1;
   }
 
-  for (i = 0; i < MAX_CONTEXT; i++) {
-     if (cc->rk_context_id == -1) {
-       int dic_num;
-       cc->rk_context_id = RkCreateContext();
-       dic_num = RkGetDicList(cc->rk_context_id,
-                                  cc->diclist, BUFSIZE);
-       if (dic_num == 0) {
-           return uim_scm_make_int(i);
-       } else if (dic_num == -1) {
-           /* invalid context number */
-           return uim_scm_f();
-       } else {
-           int j;
-           /* buf[] = "dicname1\0dicname2\0dicname3\0...dicname_n\0\0" */
-           buf = cc->diclist;
-           for (j = 0; j < dic_num; j++) {
-               RkMountDic(cc->rk_context_id, buf, 0);
-               buflen = strlen(buf) + 1;
-               buf += buflen;
-           }
-       }
-       return uim_scm_make_int(i);
-     }
-     cc++;
+  cc = malloc(sizeof(*cc));
+  cc->rk_context_id = RkCreateContext();
+  if (cc->rk_context_id == ERR) {
+    free(cc);
+    return uim_scm_f();
+  }    
+
+  cc->rk_mode = (RK_XFER << RK_XFERBITS) | RK_KFER;
+  cc->max_cand_num_list = NULL;
+  cc->segment_num = -1;
+  cc->diclist[0] = '\0';
+
+  dic_num = RkGetDicList(cc->rk_context_id, cc->diclist, BUFSIZE);
+  if (dic_num == ERR) {
+    /* invalid context number */
+    return uim_scm_f();
   }
-  return uim_scm_f();
+
+  /* buf[] = "dicname1\0dicname2\0dicname3\0...dicname_n\0\0" */
+  buf = cc->diclist;
+  for (i = 0; i < dic_num; i++) {
+    if (RkMountDic(cc->rk_context_id, buf, 0) != ERR) {
+      fprintf(stderr, "Failed to mount dictionary %s\n", buf);
+    }
+    buflen = strlen(buf) + sizeof((char)'\0');
+    buf += buflen;
+  }
+
+  cc_ = uim_scm_make_ptr(cc);
+  context_list = uim_scm_callf("cons", "oo", cc_, context_list);
+
+  return cc_;
 }
 
 static uim_lisp
-release_context(uim_lisp id_)
+release_context(uim_lisp cc_)
 {
-  int id = uim_scm_c_int(id_);
-  struct canna_context *cc = get_canna_context(id);
+  struct canna_context *cc;
+  uim_lisp ok;
 
-  if (cc == NULL)
-    return uim_scm_f();
+  context_list = uim_scm_callf("delete!", "oo", cc_, context_list);
 
-  if (cc->rk_context_id == -1)
+  cc = get_canna_context(cc_);
+  if (!cc)
     return uim_scm_f();
 
-  if (RkCloseContext(cc->rk_context_id) != -1) {
+  if (cc->rk_context_id != -1) {
+    ok = MAKE_BOOL(RkCloseContext(cc->rk_context_id) != ERR);
     cc->rk_context_id = -1;
-    return uim_scm_t();
   } else {
-    return uim_scm_f();
+    ok = uim_scm_f();
   }
+  free(cc);
+
+  return ok;
 }
 
 static void
 _reset_conversion(struct canna_context *cc)
 {
-  if (cc == NULL)
-     return;
+  if (!VALID_CANNA_CONTEXTP(cc))
+    return;
 
   if (cc->segment_num >= 0) {
      cc->segment_num = -1;
-     RkEndBun(cc->rk_context_id, 0);
+     RkEndBun(cc->rk_context_id, FORGET_SELECTED_CAND);
   }
 }
 
@@ -200,19 +204,15 @@
 {
   RkStat stat;
   int i;
-  if (cc == NULL)
-     return;
 
-  if (cc->rk_context_id == -1)
-     return;
+  if (!VALID_CANNA_CONTEXTP(cc))
+    return;
 
-  if (cc->max_cand_num_list != NULL) {
-    free(cc->max_cand_num_list);
-  }
+  free(cc->max_cand_num_list);
   cc->max_cand_num_list = malloc(sizeof(int) * cc->segment_num);
   for (i = 0; i < cc->segment_num; i++) {
     RkGoTo(cc->rk_context_id, i);
-    if (RkGetStat(cc->rk_context_id, &stat) == 0) {
+    if (RkGetStat(cc->rk_context_id, &stat) == OK) {
       cc->max_cand_num_list[i] = stat.maxcand;
     } else {
       cc->max_cand_num_list[i] = -1;
@@ -222,60 +222,52 @@
 }
 
 static uim_lisp
-begin_conversion(uim_lisp id_, uim_lisp str_)
+begin_conversion(uim_lisp cc_, uim_lisp str_)
 {
-  int id = uim_scm_c_int(id_);
-  char *str;
+  struct canna_context *cc;
+  const char *str;
   int len, segment_num, mode;
-  struct canna_context *cc = get_canna_context(id);
 
-  if (cc == NULL)
-    return uim_scm_f();
-
-  if (cc->rk_context_id == -1)
+  cc = get_canna_context(cc_);
+  if (!VALID_CANNA_CONTEXTP(cc))
     return uim_scm_f();
 
   mode = cc->rk_mode;
-  str = uim_scm_c_str(str_);
+  str = uim_scm_refer_c_str(str_);
   len = strlen(str);
 
-  segment_num = RkBgnBun(cc->rk_context_id, str, len, mode);
-
-  if (segment_num == -1) {
-     /* failed to conversion */
-     if (str != NULL)
-       free(str);
-     return uim_scm_f();
-  }
+  segment_num = RkBgnBun(cc->rk_context_id, (char *)str, len, mode);
+  if (segment_num == ERR)
+    return uim_scm_f();
 
   cc->segment_num = segment_num;
   _update_status(cc);
 
-  if (str != NULL)
-     free(str);
-
   return uim_scm_make_int(cc->segment_num);
 }
 
 static uim_lisp
-get_nth_candidate(uim_lisp id_, uim_lisp seg_, uim_lisp nth_)
+get_nth_candidate(uim_lisp cc_, uim_lisp seg_, uim_lisp nth_)
 {
-  int id = uim_scm_c_int(id_);
-  int seg = uim_scm_c_int(seg_);
-  int nth = uim_scm_c_int(nth_);
-  struct canna_context *cc = get_canna_context(id);
+  struct canna_context *cc;
+  int seg, nth, len;
   char buf[BUFSIZE];
-  int len;
 
-  if (cc == NULL)
+  cc = get_canna_context(cc_);
+  seg = uim_scm_c_int(seg_);
+  nth = uim_scm_c_int(nth_);
+  if (!VALID_CANNA_CONTEXTP(cc) || !VALID_SEGMENT_INDEXP(cc, seg))
     return uim_scm_f();
 
-  if (nth > cc->max_cand_num_list[seg])
-    nth = 0;
-
   RkGoTo(cc->rk_context_id, seg);
+
+  if (nth < 0 || nth > cc->max_cand_num_list[seg])
+    nth = 0;
   RkXfer(cc->rk_context_id, nth);
+
   len = RkGetKanji(cc->rk_context_id, (unsigned char *)buf, BUFSIZE);
+  if (len == ERR)
+    return uim_scm_f();
 #ifdef UIM_CANNA_DEBUG
   printf("nth: %d, kanji: %s\n", nth, buf);
 #endif
@@ -283,19 +275,22 @@
 }
 
 static uim_lisp
-get_unconv_candidate(uim_lisp id_, uim_lisp seg_)
+get_unconv_candidate(uim_lisp cc_, uim_lisp seg_)
 {
-  int id = uim_scm_c_int(id_);
-  int seg = uim_scm_c_int(seg_);
-  struct canna_context *cc = get_canna_context(id);
+  struct canna_context *cc;
+  int seg, len;
   char buf[BUFSIZE];
-  int len;
 
-  if (cc == NULL)
+  cc = get_canna_context(cc_);
+  seg = uim_scm_c_int(seg_);
+  if (!VALID_CANNA_CONTEXTP(cc) || !VALID_SEGMENT_INDEXP(cc, seg))
     return uim_scm_f();
 
   RkGoTo(cc->rk_context_id, seg);
+
   len = RkGetYomi(cc->rk_context_id, (unsigned char *)buf, BUFSIZE);
+  if (len == ERR)
+    return uim_scm_f();
 #ifdef UIM_CANNA_DEBUG
   fprintf(stderr, "yomi: %s\n", buf);
 #endif
@@ -303,62 +298,52 @@
 }
 
 static uim_lisp
-get_nr_segments(uim_lisp id_)
+get_nr_segments(uim_lisp cc_)
 {
-  int id = uim_scm_c_int(id_);
-/*  RkStat stat; */
-  struct canna_context *cc = get_canna_context(id);
-
-  if (cc == NULL)
-     return uim_scm_f();
+  struct canna_context *cc;
+  /* RkStat stat; */
 
-  if (cc->rk_context_id == -1)
-     return uim_scm_f();
+  cc = get_canna_context(cc_);
+  if (!VALID_CANNA_CONTEXTP(cc))
+    return uim_scm_f();
 
   return uim_scm_make_int(cc->segment_num);
 }
 
 static uim_lisp
-get_nr_candidate(uim_lisp id_, uim_lisp nth_)
+get_nr_candidate(uim_lisp cc_, uim_lisp seg_)
 {
-  int id = uim_scm_c_int(id_);
-  int nth = uim_scm_c_int(nth_);
-  struct canna_context *cc = get_canna_context(id);
-
-  if (cc == NULL)
-     return uim_scm_f();
-
-  if (cc->rk_context_id == -1)
-     return uim_scm_f();
+  struct canna_context *cc;
+  int seg;
 
+  cc = get_canna_context(cc_);
+  seg = uim_scm_c_int(seg_);
+  if (!VALID_CANNA_CONTEXTP(cc) || !VALID_SEGMENT_INDEXP(cc, seg))
+    return uim_scm_f();
 
-  if (cc->max_cand_num_list[nth] != -1)
-    return uim_scm_make_int(cc->max_cand_num_list[nth]);
+  if (cc->max_cand_num_list[seg] != -1)
+    return uim_scm_make_int(cc->max_cand_num_list[seg]);
   else
     return uim_scm_f();
 }
 
 static uim_lisp
-resize_segment(uim_lisp id_, uim_lisp s_, uim_lisp nth_)
+resize_segment(uim_lisp cc_, uim_lisp seg_, uim_lisp delta_)
 {
-  int id = uim_scm_c_int(id_);
-  int s = uim_scm_c_int(s_);
-  int nth = uim_scm_c_int(nth_);
-  struct canna_context *cc = get_canna_context(id);
-
-  if (cc == NULL)
-     return uim_scm_f();
+  struct canna_context *cc;
+  int seg, delta, id;
 
-  if (cc->rk_context_id == -1)
-     return uim_scm_f();
+  cc = get_canna_context(cc_);
+  seg = uim_scm_c_int(seg_);
+  delta = uim_scm_c_int(delta_);
+  if (!VALID_CANNA_CONTEXTP(cc) || !VALID_SEGMENT_INDEXP(cc, seg))
+    return uim_scm_f();
 
-  RkGoTo(cc->rk_context_id, s);
+  RkGoTo(cc->rk_context_id, seg);
   RkNfer(cc->rk_context_id);
 
-  if (nth > 0)
-      cc->segment_num = RkEnlarge(cc->rk_context_id);
-  else
-      cc->segment_num = RkShorten(cc->rk_context_id);
+  id = cc->rk_context_id;
+  cc->segment_num = (delta > 0) ? RkEnlarge(id) : RkShorten(id);
 
   _update_status(cc);
 
@@ -366,32 +351,35 @@
 }
 
 static uim_lisp
-commit_segment(uim_lisp id_, uim_lisp s_, uim_lisp nth_)
+commit_segment(uim_lisp cc_, uim_lisp seg_, uim_lisp nth_)
 {
-  int id = uim_scm_c_int(id_);
+  struct canna_context *cc;
 #if 0
-  int s = uim_scm_c_int(s_);
-  int nth = uim_scm_c_int(nth_);
+  int seg, nth;
 #endif
-  struct canna_context *cc = get_canna_context(id);
 
-  if (cc == NULL)
-     return uim_scm_f();
-
-  if (cc->rk_context_id == -1)
-     return uim_scm_f();
+  cc = get_canna_context(cc_);
+#if 0
+  seg = uim_scm_c_int(seg_);
+  nth = uim_scm_c_int(nth_);
+#endif
+  if (!VALID_CANNA_CONTEXTP(cc) /* || !VALID_SEGMENT_INDEXP(cc, seg) */)
+    return uim_scm_f();
 
-  RkEndBun(cc->rk_context_id, 1);
+  RkEndBun(cc->rk_context_id, LEARN_SELECTED_CAND);
   cc->segment_num = -1;
 
   return uim_scm_t();
 }
 
 static uim_lisp
-reset_conversion(uim_lisp id_)
+reset_conversion(uim_lisp cc_)
 {
-  int id = uim_scm_c_int(id_);
-  struct canna_context *cc = get_canna_context(id);
+  struct canna_context *cc;
+
+  cc = get_canna_context(cc_);
+  if (!VALID_CANNA_CONTEXTP(cc))
+    return uim_scm_f();
 
   _reset_conversion(cc);
 
@@ -401,6 +389,9 @@
 void
 uim_plugin_instance_init(void)
 {
+  context_list = uim_scm_null();
+  uim_scm_gc_protect(&context_list);
+
   uim_scm_init_subr_1("canna-lib-init", init_canna_lib);
 
   uim_scm_init_subr_0("canna-lib-alloc-context", create_context);
@@ -418,19 +409,16 @@
 void
 uim_plugin_instance_quit(void)
 {
-  if (cannaserver != NULL) {
-     free(cannaserver);
-     cannaserver = NULL;
-  }
+  uim_scm_callf("for-each", "vo", "canna-lib-release-context", context_list);
+  context_list = uim_scm_null();
+  uim_scm_gc_unprotect(&context_list);
+
+  free(cannaserver);
+  cannaserver = NULL;
 
-  if (/* RkFinalize && */ rk_initialized == 1) {
+  if (rk_initialized == 1) {
      RkFinalize();
      rk_initialized = -1;
-  }
-
-  if (context_array != NULL) {
-     free(context_array);
-     context_array = NULL;
   }
 }
 #endif /* HAVE_CANNA_RK_H */

Reply via email to