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