Author: yamakenz
Date: Mon Aug 13 08:10:17 2007
New Revision: 4845

Modified:
   trunk/uim/canna.c

Log:
* uim/canna.c
  - Include assert.h
  - (get_canna_context): Add NULL pointer check
  - (validate_segment_index): New static function
  - (get_nr_candidate, get_nr_candidates): Rename get_nr_candidate()
    to get_nr_candidates()
  - (init_canna_lib, create_context, begin_conversion,
    get_nth_candidate, get_unconv_candidate, get_nr_segments,
    get_nr_candidates, resize_segment, reset_conversion): Add
    exception-based error handling
  - (release_context):
    * Add exception-based error handling
    * Nullify canna_context
  - (_reset_conversion): Replace precondition check
    with assertion
  - (_update_status):
    * Ditto
    * Add exception-based error handling
  - (uim_plugin_instance_init): Require SRFI-1 for delete!


Modified: trunk/uim/canna.c
==============================================================================
--- trunk/uim/canna.c   (original)
+++ trunk/uim/canna.c   Mon Aug 13 08:10:17 2007
@@ -40,6 +40,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
+#include <assert.h>
 
 #include "uim-scm.h"
 #include "uim-scm-abbrev.h"
@@ -81,20 +82,30 @@
 static uim_lisp context_list;
 
 
-#ifdef UIM_CANNA_DEBUG
 static struct canna_context *
 get_canna_context(uim_lisp cc_)
 {
   struct canna_context *cc;
 
   cc = uim_scm_c_ptr(cc_);
+  if (!cc)
+    uim_fatal_error("NULL canna_context");
+  assert(cc->rk_context_id != -1);
+#ifdef UIM_CANNA_DEBUG
   printf("rk_context_id: %d\n", cc->rk_context_id);
   printf("segment_num: %d\n", cc->segment_num);
+#endif
+
   return cc;
 }
-#else
-#define get_canna_context(cc_) ((struct canna_context *)uim_scm_c_ptr(cc_))
-#endif
+
+static void
+validate_segment_index(struct canna_context *cc, int i)
+{
+  assert(VALID_CANNA_CONTEXTP(cc));
+  if (!VALID_SEGMENT_INDEXP(cc, i))
+    uim_scm_error_obj("invalid segment index", uim_scm_make_int(i));
+}
 
 static uim_lisp
 init_canna_lib(uim_lisp str_)
@@ -105,10 +116,8 @@
    * 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) == ERR) {
-      fprintf(stderr, "%s\n", strerror(errno));
-      return uim_scm_f();
-    }
+    if (RkInitialize(cannaserver) == ERR)
+      uim_fatal_error("RkInitialize() failed");
     RkFinalize();
   }
 
@@ -125,31 +134,29 @@
   int buflen, i;
 
   if (rk_initialized == -1) {
-    if (RkInitialize(cannaserver) == ERR) {
-      fprintf(stderr, "%s\n", strerror(errno));
-      return uim_scm_f();
-    }
+    if (RkInitialize(cannaserver) == ERR)
+      uim_fatal_error("RkInitialize() failed");
     rk_initialized = 1;
   }
 
-  cc = malloc(sizeof(*cc));
+  cc = uim_malloc(sizeof(*cc));
   cc->rk_context_id = RkCreateContext();
   if (cc->rk_context_id == ERR) {
     free(cc);
-    return uim_scm_f();
+    uim_fatal_error("RkCreateContext() failed");
   }    
 
   cc->rk_mode = (RK_XFER << RK_XFERBITS) | RK_KFER;
   cc->max_cand_num_list = NULL;
   cc->segment_num = -1;
 
-  diclist = malloc(BUFSIZE);
+  diclist = uim_malloc(BUFSIZE);
   diclist[0] = '\0';
 
   dic_num = RkGetDicList(cc->rk_context_id, diclist, BUFSIZE);
   if (dic_num == ERR) {
     /* invalid context number */
-    return uim_scm_f();
+    uim_fatal_error("RkGetDicList() failed");
   }
 
   /* buf[] = "dicname1\0dicname2\0dicname3\0...dicname_n\0\0" */
@@ -177,33 +184,33 @@
 release_context(uim_lisp cc_)
 {
   struct canna_context *cc;
-  uim_lisp ok;
+  uim_bool err;
 
   context_list = uim_scm_callf("delete!", "oo", cc_, context_list);
 
   cc = get_canna_context(cc_);
-  if (!cc)
-    return uim_scm_f();
+  uim_scm_nullify_c_ptr(cc_);
 
   if (cc->rk_context_id != -1) {
-    ok = MAKE_BOOL(RkCloseContext(cc->rk_context_id) != ERR);
-    cc->rk_context_id = -1;
+    err = (RkCloseContext(cc->rk_context_id) == ERR);
   } else {
-    ok = uim_scm_f();
+    err = UIM_TRUE;
   }
 #ifdef UIM_CANNA_DEBUG
   free(cc->diclist);
 #endif
   free(cc);
 
-  return ok;
+  if (err)
+    uim_fatal_error("canna-lib-release-context failed");
+
+  return uim_scm_f();
 }
 
 static void
 _reset_conversion(struct canna_context *cc)
 {
-  if (!VALID_CANNA_CONTEXTP(cc))
-    return;
+  assert(VALID_CANNA_CONTEXTP(cc));
 
   if (cc->segment_num >= 0) {
      cc->segment_num = -1;
@@ -217,11 +224,10 @@
   RkStat stat;
   int i;
 
-  if (!VALID_CANNA_CONTEXTP(cc))
-    return;
+  assert(VALID_CANNA_CONTEXTP(cc));
 
   free(cc->max_cand_num_list);
-  cc->max_cand_num_list = malloc(sizeof(int) * cc->segment_num);
+  cc->max_cand_num_list = uim_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) == OK) {
@@ -241,8 +247,6 @@
   int len, segment_num, mode;
 
   cc = get_canna_context(cc_);
-  if (!VALID_CANNA_CONTEXTP(cc))
-    return uim_scm_f();
 
   mode = cc->rk_mode;
   str = uim_scm_refer_c_str(str_);
@@ -250,7 +254,7 @@
 
   segment_num = RkBgnBun(cc->rk_context_id, (char *)str, len, mode);
   if (segment_num == ERR)
-    return uim_scm_f();
+    uim_fatal_error("RkBgnBun() failed");
 
   cc->segment_num = segment_num;
   _update_status(cc);
@@ -268,8 +272,7 @@
   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();
+  validate_segment_index(cc, seg);
 
   RkGoTo(cc->rk_context_id, seg);
 
@@ -279,7 +282,7 @@
 
   len = RkGetKanji(cc->rk_context_id, (unsigned char *)buf, BUFSIZE);
   if (len == ERR)
-    return uim_scm_f();
+    uim_fatal_error("RkGetKanji() failed");
 #ifdef UIM_CANNA_DEBUG
   printf("nth: %d, kanji: %s\n", nth, buf);
 #endif
@@ -295,14 +298,13 @@
 
   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();
+  validate_segment_index(cc, seg);
 
   RkGoTo(cc->rk_context_id, seg);
 
   len = RkGetYomi(cc->rk_context_id, (unsigned char *)buf, BUFSIZE);
   if (len == ERR)
-    return uim_scm_f();
+    uim_fatal_error("RkGetYomi() failed");
 #ifdef UIM_CANNA_DEBUG
   fprintf(stderr, "yomi: %s\n", buf);
 #endif
@@ -316,27 +318,24 @@
   /* RkStat stat; */
 
   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 cc_, uim_lisp seg_)
+get_nr_candidates(uim_lisp cc_, uim_lisp seg_)
 {
   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();
+  validate_segment_index(cc, seg);
+
+  if (cc->max_cand_num_list[seg] == -1)
+    uim_scm_error("invalid candidate index");
 
-  if (cc->max_cand_num_list[seg] != -1)
-    return uim_scm_make_int(cc->max_cand_num_list[seg]);
-  else
-    return uim_scm_f();
+  return uim_scm_make_int(cc->max_cand_num_list[seg]);
 }
 
 static uim_lisp
@@ -348,8 +347,7 @@
   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();
+  validate_segment_index(cc, seg);
 
   RkGoTo(cc->rk_context_id, seg);
   RkNfer(cc->rk_context_id);
@@ -374,9 +372,8 @@
 #if 0
   seg = uim_scm_c_int(seg_);
   nth = uim_scm_c_int(nth_);
+  validate_segment_index(cc, seg);
 #endif
-  if (!VALID_CANNA_CONTEXTP(cc) /* || !VALID_SEGMENT_INDEXP(cc, seg) */)
-    return uim_scm_f();
 
   RkEndBun(cc->rk_context_id, LEARN_SELECTED_CAND);
   cc->segment_num = -1;
@@ -390,8 +387,6 @@
   struct canna_context *cc;
 
   cc = get_canna_context(cc_);
-  if (!VALID_CANNA_CONTEXTP(cc))
-    return uim_scm_f();
 
   _reset_conversion(cc);
 
@@ -404,14 +399,15 @@
   context_list = uim_scm_null();
   uim_scm_gc_protect(&context_list);
 
-  uim_scm_init_subr_1("canna-lib-init", init_canna_lib);
+  uim_scm_eval_c_string("(require-extension (srfi 1))"); /* for delete! */
 
+  uim_scm_init_subr_1("canna-lib-init", init_canna_lib);
   uim_scm_init_subr_0("canna-lib-alloc-context", create_context);
   uim_scm_init_subr_1("canna-lib-release-context", release_context);
   uim_scm_init_subr_3("canna-lib-get-nth-candidate", get_nth_candidate);
   uim_scm_init_subr_2("canna-lib-get-unconv-candidate", get_unconv_candidate);
   uim_scm_init_subr_1("canna-lib-get-nr-segments",get_nr_segments);
-  uim_scm_init_subr_2("canna-lib-get-nr-candidates", get_nr_candidate);
+  uim_scm_init_subr_2("canna-lib-get-nr-candidates", get_nr_candidates);
   uim_scm_init_subr_3("canna-lib-resize-segment", resize_segment);
   uim_scm_init_subr_2("canna-lib-begin-conversion", begin_conversion);
   uim_scm_init_subr_3("canna-lib-commit-segment", commit_segment);

Reply via email to