Author: yamakenz
Date: Fri Aug 10 15:45:44 2007
New Revision: 4814

Added:
   trunk/m4/ax_func_sigsetjmp.m4
   trunk/uim/uim-error.c
Modified:
   trunk/configure.ac
   trunk/doc/COMPATIBILITY
   trunk/m4/Makefile.am
   trunk/uim/Makefile.am
   trunk/uim/uim-internal.h
   trunk/uim/uim.c
   trunk/uim/uim.h

Log:
* uim/uim.h
  - (uim_fatal_error, uim_malloc, uim_realloc, uim_calloc): New function decl
* uim/uim-internal.h
  - (uim_init_error, uim_catch_error_begin, uim_catch_error_end,
    uim_throw_error): New function decl
* uim/uim-error.c
  - New file
  - (JMP_BUF, SETJMP, LONGJMP): New macro
  - (fatal_errored, guarded, env, err_msg): New static variable
  - (uim_init_error, uim_catch_error_begin, uim_catch_error_end,
    uim_throw_error, uim_fatal_error, uim_malloc, uim_realloc,
    uim_calloc): New function
* uim/uim.c
  - (fatal_error_hook): New static function
  - (uim_init): Initialize the new error handling facilities
* uim/Makefile.am
  - (libuim_la_SOURCES): Add uim-error.c
* m4/ax_func_sigsetjmp.m4
  - New file
* m4/Makefile.am
  - Add ax_func_sigsetjmp.m4
* configure.ac
  - Add AX_FUNC_SIGSETJMP
* doc/COMPATIBILITY
  - Add new section "Exception-based libuim error handling"
  - Add new section "Fatal error handling helpers for plugin developers"


Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac  (original)
+++ trunk/configure.ac  Fri Aug 10 15:45:44 2007
@@ -436,6 +436,7 @@
 AC_FUNC_ALLOCA
 AC_FUNC_MEMCMP
 AC_FUNC_MMAP
+AX_FUNC_SIGSETJMP
 AC_FUNC_FORK
 AC_FUNC_LSTAT
 AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK

Modified: trunk/doc/COMPATIBILITY
==============================================================================
--- trunk/doc/COMPATIBILITY     (original)
+++ trunk/doc/COMPATIBILITY     Fri Aug 10 15:45:44 2007
@@ -57,6 +57,44 @@
 
 The changes are described below in most recently updated order.
 ------------------------------------------------------------------------------
+Summary: Exception-based libuim error handling
+Affects: uim developers
+Updates: internal C API
+Version: 1.5.0
+Revision: ac4814
+Date: 2007-08-11
+Modifier: YamaKen
+Related: Fatal error handling helpers for plugin developers
+        uim-scm API reorganization in uim 1.5.0
+         uim_scm_error()
+         uim_scm_error_obj()
+         uim_scm_set_fatal_error_hook()
+URL:
+Changes:
+      (new) uim_catch_error_begin()
+      (new) uim_catch_error_end()
+      (new) uim_throw_error()
+Description:
+------------------------------------------------------------------------------
+Summary: Fatal error handling helpers for plugin developers
+Affects: IM developers, uim developers
+Updates: C API
+Version: 1.5.0
+Revision: ac4814
+Date: 2007-08-11
+Modifier: YamaKen
+Related: Exception-based libuim error handling
+        uim-scm API reorganization in uim 1.5.0
+         uim_scm_error()
+         uim_scm_error_obj()
+URL:
+Changes:
+      (new) uim_fatal_error()
+      (new) uim_malloc()
+      (new) uim_realloc()
+      (new) uim_calloc()
+Description:
+------------------------------------------------------------------------------
 Summary: New utility procedures in uim 1.5.0
 Affects: uim developers, IM developers
 Updates: Scheme API

Modified: trunk/m4/Makefile.am
==============================================================================
--- trunk/m4/Makefile.am        (original)
+++ trunk/m4/Makefile.am        Fri Aug 10 15:45:44 2007
@@ -1 +1 @@
-EXTRA_DIST = nls.m4 po.m4  codeset.m4 gettext.m4 glibc21.m4 iconv.m4 
intdiv0.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 isc-posix.m4 lcmessage.m4 
lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 stdint_h.m4 uintmax_t.m4 
ulonglong.m4 ac_cxx_have_stl.m4 ac_cxx_namespace.m4 xft.m4 
ax_create_stdint_h.m4 ax_cflags_gcc_option.m4 ax_lib_glibc.m4
+EXTRA_DIST = nls.m4 po.m4  codeset.m4 gettext.m4 glibc21.m4 iconv.m4 
intdiv0.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 isc-posix.m4 lcmessage.m4 
lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 stdint_h.m4 uintmax_t.m4 
ulonglong.m4 ac_cxx_have_stl.m4 ac_cxx_namespace.m4 xft.m4 
ax_create_stdint_h.m4 ax_cflags_gcc_option.m4 ax_lib_glibc.m4 
ax_func_sigsetjmp.m4

Added: trunk/m4/ax_func_sigsetjmp.m4
==============================================================================
--- (empty file)
+++ trunk/m4/ax_func_sigsetjmp.m4       Fri Aug 10 15:45:44 2007
@@ -0,0 +1,44 @@
+##### 
+#
+# SYNOPSIS
+#
+#   AX_FUNC_SIGSETJMP
+#
+# DESCRIPTION
+#
+#   Check whether sigsetjmp(3) and siglongjmp(3) is available.
+#
+#   Since sigsetjmp(3) and siglongjmp(3) may be a macro,
+#   AC_CHECK_FUNC() is not appropriate to detect them. This macro can
+#   properly detect them although having '_FUNC_' prefix for the naming
+#   convention. This macro uses compile-time detection and so is
+#   cross-compile ready.
+#
+# LAST MODIFICATION
+#
+#   2007-08-11
+#
+# COPYLEFT
+#
+#   Copyright (c) 2007 YAMAMOTO Kengo <yamaken AT bp.iij4u.or.jp>
+#
+#   Copying and distribution of this file, with or without
+#   modification, are permitted in any medium without royalty provided
+#   the copyright notice and this notice are preserved.
+
+AC_DEFUN([AX_FUNC_SIGSETJMP], [
+  AC_CACHE_CHECK([for sigsetjmp],
+                 [ax_cv_func_sigsetjmp],
+                 [AC_LINK_IFELSE(
+                    AC_LANG_PROGRAM([EMAIL PROTECTED]:@include <setjmp.h>]],
+                                    [[sigjmp_buf env;
+                                     while (!sigsetjmp(env, 1))
+                                       siglongjmp(env, 1);
+                                     return 0;]]),
+                    [ax_cv_func_sigsetjmp=yes],
+                    [ax_cv_func_sigsetjmp=no])])
+  if test "x$ax_cv_func_sigsetjmp" = xyes; then
+    AC_DEFINE([HAVE_SIGSETJMP], [1],
+              [Define to 1 if you have the `sigsetjmp' (and 'siglongjmp') 
function or macro.])
+  fi
+])

Modified: trunk/uim/Makefile.am
==============================================================================
--- trunk/uim/Makefile.am       (original)
+++ trunk/uim/Makefile.am       Fri Aug 10 15:45:44 2007
@@ -35,7 +35,8 @@
                uim-custom.h
 
 libuim_la_SOURCES = uim-scm.c \
-               uim-internal.h uim.c uim-key.c uim-func.c uim-util.c \
+               uim-internal.h uim-error.c uim.c \
+               uim-key.c uim-func.c uim-util.c \
                iconv.c plugin.c \
                uim-ipc.c uim-helper.c uim-helper-client.c \
                gettext.h intl.c \

Added: trunk/uim/uim-error.c
==============================================================================
--- (empty file)
+++ trunk/uim/uim-error.c       Fri Aug 10 15:45:44 2007
@@ -0,0 +1,155 @@
+/*
+
+  Copyright (c) 2007 uim Project http://code.google.com/p/uim/
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+  3. Neither the name of authors nor the names of its contributors
+     may be used to endorse or promote products derived from this software
+     without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 
IS'' AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 
LIABLE
+  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  SUCH DAMAGE.
+
+*/
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include <assert.h>
+
+#include "uim.h"
+
+
+#if HAVE_SIGSETJMP
+#define JMP_BUF           sigjmp_buf
+#define SETJMP(env)       sigsetjmp((env), 1)
+#define LONGJMP(env, val) siglongjmp((env), (val))
+#else
+#define JMP_BUF           jmp_buf
+#define SETJMP(env)       setjmp(env)
+#define LONGJMP(env, val) longjmp((env), (val))
+#endif
+
+/* Immediately returns UIM_TRUE if uim is disabled by a fatal error. */
+
+static uim_bool fatal_errored;
+static int guarded;
+static JMP_BUF env;
+static const char *err_msg;
+
+
+void
+uim_init_error(void)
+{
+  /* For re-initialization of libuim. */
+  guarded = 0;
+
+  /* fatal_errored must not be cleared even if libuim is re-initialized. */
+}
+
+/* can be nested */
+uim_bool
+uim_catch_error_begin(void)
+{
+  assert(guarded >= 0);
+
+  if (fatal_errored)
+    return UIM_TRUE;
+
+  if (!guarded++) {
+    if (SETJMP(env)) {
+      guarded = 0;
+
+      fputs("ERROR: ", stderr);
+      if (fatal_errored)
+       fputs("fatal: ", stderr);
+      fputs(err_msg, stderr);
+      fputs("\n", stderr);
+
+      return UIM_TRUE;
+    }
+  }
+
+  return UIM_FALSE;
+}
+
+void
+uim_catch_error_end(void)
+{
+  guarded--;
+
+  assert(guarded >= 0);
+}
+
+void
+uim_throw_error(const char *msg)
+{
+  if (!guarded)
+    exit(EXIT_FAILURE);
+
+  err_msg = msg;
+  LONGJMP(env, guarded);
+}
+
+void
+uim_fatal_error(const char *msg)
+{
+  fatal_errored = UIM_TRUE;
+  uim_throw_error(msg);
+}
+
+void *
+uim_malloc(size_t size)
+{
+  void *p;
+
+  p = malloc(size);
+  if (!p)
+    uim_fatal_error("malloc() failed");
+
+  return p;
+}
+
+void *
+uim_realloc(void *p, size_t size)
+{
+  p = realloc(p, size);
+  if (!p)
+    uim_fatal_error("realloc() failed");
+
+  return p;
+}
+
+void *
+uim_calloc(size_t nmemb, size_t size)
+{
+  void *p;
+
+  p = calloc(nmemb, size);
+  if (!p)
+    uim_fatal_error("calloc() failed");
+
+  return p;
+}
+

Modified: trunk/uim/uim-internal.h
==============================================================================
--- trunk/uim/uim-internal.h    (original)
+++ trunk/uim/uim-internal.h    Fri Aug 10 15:45:44 2007
@@ -107,6 +107,11 @@
 };
 
 
+void     uim_init_error(void);
+uim_bool uim_catch_error_begin(void);
+void     uim_catch_error_end(void);
+void     uim_throw_error(const char *msg);
+
 void uim_scm_init(const char *system_load_path);
 void uim_scm_quit(void);
 void uim_scm_set_fatal_error_hook(void (*hook)(void));

Modified: trunk/uim/uim.c
==============================================================================
--- trunk/uim/uim.c     (original)
+++ trunk/uim/uim.c     Fri Aug 10 15:45:44 2007
@@ -47,6 +47,8 @@
 
 #define OK 0
 
+static void fatal_error_hook(void);
+
 static void *uim_init_internal(void *dummy);
 struct uim_get_candidate_args {
   uim_context uc;
@@ -71,6 +73,12 @@
 /****************************************************************
  * Core APIs                                                    *
  ****************************************************************/
+static void
+fatal_error_hook(void)
+{
+  uim_fatal_error("fatal error in Scheme interpreter");
+}
+
 int
 uim_init(void)
 {
@@ -79,8 +87,11 @@
   if (uim_initialized)
     return OK;
 
+  uim_init_error();
+
   sys_load_path = (uim_issetugid()) ? NULL : getenv("LIBUIM_SYSTEM_SCM_FILES");
   uim_scm_init(sys_load_path);
+  uim_scm_set_fatal_error_hook(fatal_error_hook);
 
   return 
(int)uim_scm_call_with_gc_ready_stack((uim_gc_gate_func_ptr)uim_init_internal, 
NULL);
 }

Modified: trunk/uim/uim.h
==============================================================================
--- trunk/uim/uim.h     (original)
+++ trunk/uim/uim.h     Fri Aug 10 15:45:44 2007
@@ -937,6 +937,13 @@
                             void (*sw_app_im_cb)(void *ptr, const char *name),
                             void (*sw_system_im_cb)(void *ptr, const char 
*name));
 
+
+/* For plugins implementation. Bridges should not use these functions. */
+void uim_fatal_error(const char *msg);  /* Disables uim */
+void *uim_malloc(size_t size);
+void *uim_realloc(void *p, size_t size);
+void *uim_calloc(size_t nmemb, size_t size);
+
 #ifdef __cplusplus
 }
 #endif

Reply via email to