Exceptions support for C. exception_order test shows how to use type information to achieve correct catching order. Examples cleanup.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-maciekd@10671 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Maciej Drwal 2008-07-17 00:52:11 +00:00
commit 88facfd390
27 changed files with 223 additions and 429 deletions

View file

@ -13,23 +13,27 @@
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
typedef struct {
void *obj;
const char **typenames;
} SwigObj;
%}
// typemaps for function parameters
%typemap(ctype) void, short, int, long, char, float, double "$1_type"
%typemap(ctype) void, short, int, long, char, float, double, bool "$1_type"
%typemap(ctype) unsigned short, unsigned int, unsigned long, unsigned char "$1_type"
%typemap(ctype) void *, short *, int *, long *, char *, float *, double * "$1_type"
%typemap(ctype) void **, short **, int **, long **, char **, float **, double ** "$1_type"
%typemap(ctype) void *, short *, int *, long *, char *, float *, double *, bool * "$1_type"
%typemap(ctype) void **, short **, int **, long **, char **, float **, double **, bool ** "$1_type"
%typemap(ctype) unsigned short *, unsigned int *, unsigned long *, unsigned char * "$1_type"
%typemap(ctype) unsigned short **, unsigned int **, unsigned long **, unsigned char ** "$1_type"
%typemap(ctype) short &, int &, long &, char &, float &, double & "$1_basetype *"
%typemap(ctype) short &, int &, long &, char &, float &, double &, bool & "$1_basetype *"
%typemap(ctype) unsigned short &, unsigned int &, unsigned long &, unsigned char & "$1_basetype *"
%typemap(ctype) const short, const int, const long, const char, const float, const double "$1_type"
%typemap(ctype) const short, const int, const long, const char, const float, const double, const bool "$1_type"
%typemap(ctype) const unsigned short, const unsigned int, const unsigned long, const unsigned char "$1_type"
%typemap(ctype) const void *, const short *, const int *, const long *, const char *, const float *, const double * "$1_type"
%typemap(ctype) bool "_Bool"
%typemap(ctype) void * [ANY], short * [ANY], int * [ANY], long * [ANY], char * [ANY], float * [ANY], double * [ANY] "$1 = ($1_basetype*) $input;"
%typemap(ctype) const void *, const short *, const int *, const long *, const char *, const float *, const double *, const bool * "$1_type"
%typemap(ctype) void * [ANY], short * [ANY], int * [ANY], long * [ANY], char * [ANY], float * [ANY], double * [ANY], bool * [ANY] "$1 = ($1_basetype*) $input;"
%typemap(ctype) SWIGTYPE "struct SwigObj$1_type *"
%typemap(ctype) SWIGTYPE * "struct SwigObj$1_type"
%typemap(ctype) SWIGTYPE & "struct SwigObj$1_basetype*"
@ -81,13 +85,12 @@
// typemaps for return values
%typemap(couttype) void, short, int, long, char, float, double "$1_type"
%typemap(couttype) void *, short *, int *, long *, char *, float *, double* "$1_type"
%typemap(couttype) const short, const int, const long, const char, const float, const double "$1_basetype"
%typemap(couttype) const void *, const short *, const int *, const long *, const char *, const float *, const double * "$1_type"
%typemap(couttype) short &, int &, long &, char &, float &, double & "$1_basetype *"
%typemap(couttype) const short &, const int &, const long &, const char &, const float &, const double & "$1_basetype const *"
%typemap(couttype) bool "_Bool"
%typemap(couttype) void, short, int, long, char, float, double, bool "$1_type"
%typemap(couttype) void *, short *, int *, long *, char *, float *, double*, bool* "$1_type"
%typemap(couttype) const short, const int, const long, const char, const float, const double, const bool "$1_basetype"
%typemap(couttype) const void *, const short *, const int *, const long *, const char *, const float *, const double *, const bool * "$1_type"
%typemap(couttype) short &, int &, long &, char &, float &, double &, bool & "$1_basetype *"
%typemap(couttype) const short &, const int &, const long &, const char &, const float &, const double &, const bool & "$1_basetype const *"
%typemap(couttype) SWIGTYPE "struct SwigObj$1_type *"
%typemap(couttype) SWIGTYPE * "struct SwigObj$1_type"
%typemap(couttype) SWIGTYPE & "struct SwigObj$1_basetype *"
@ -132,25 +135,33 @@
// exception handling
%typemap(throws) int, long, short, unsigned int, unsigned long, unsigned short {
char error_msg[256];
sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
SWIG_CThrowException(0, error_msg);
}
%typemap(throws) char *, const char * {
SWIG_CThrowException(0, $1);
}
// this should match only non-built-in and non-template objects
%typemap(throws) SWIGTYPE {
(void)_e;
SWIG_CThrowException(3, "C++ $1_type exception thrown");
SWIG_CThrowException(0, "C++ $1_type exception thrown");
}
%insert("runtime") %{
#define SWIG_MAX_HANDLERS 256
#define SWIG_MAX_RT_STACK 256
SWIGEXPORTC int SWIG_exception_code;
SWIGEXPORTC struct {
int code;
char *msg;
SwigObj *klass;
} SWIG_exception;
SWIGEXPORTC jmp_buf SWIG_rt_env;
SWIGEXPORTC int SWIG_rt_init = 0;
SWIGINTERN struct {
int reg;
int code;
void (*fun)();
} SWIG_Handlers[SWIG_MAX_HANDLERS];
SWIGINTERN int SWIG_next_handler = 0;
SWIGINTERN jmp_buf *SWIG_rt_stack_base = 0;
SWIGINTERN jmp_buf *SWIG_rt_stack_ptr = 0;
@ -167,6 +178,13 @@ SWIGINTERN void SWIG_rt_stack_pop() {
memcpy(SWIG_rt_env, SWIG_rt_stack_ptr, sizeof(SWIG_rt_env));
}
SWIGINTERN void SWIG_cleanup() {
if (SWIG_rt_stack_base)
free(SWIG_rt_stack_base);
if (SWIG_exception.msg)
free(SWIG_exception.msg);
}
#ifdef __cplusplus
extern "C" {
#endif
@ -175,93 +193,112 @@ SWIGEXPORTC void SWIG_rt_try() {
SWIG_rt_stack_push();
}
SWIGEXPORTC int SWIG_rt_catch(int code) {
int result = (SWIG_exception_code == code);
SWIGEXPORTC int SWIG_rt_catch(const char *type) {
int result = 0;
if (!type || (strcmp("SWIG_AnyException", type) == 0)) {
result = 1;
}
else if (SWIG_exception.klass) {
int i = 0;
while (SWIG_exception.klass->typenames[i]) {
if (strcmp(SWIG_exception.klass->typenames[i++], type) == 0) {
result = 1;
break;
}
}
}
if (result)
SWIG_rt_stack_pop();
return result;
}
SWIGEXPORTC void SWIG_rt_throw(int code) {
longjmp(SWIG_rt_env, code);
SWIGEXPORTC void SWIG_rt_throw(SwigObj *klass, const char *msg) {
if (SWIG_exception.msg) {
free(SWIG_exception.msg);
SWIG_exception.msg = (char *) 0;
}
if (msg) {
SWIG_exception.msg = (char *) malloc(strlen(msg));
strcpy(SWIG_exception.msg, msg);
}
SWIG_exception.klass = klass;
longjmp(SWIG_rt_env, 1);
}
SWIGEXPORTC void SWIG_rt_endtry() {
if (SWIG_exception.msg)
free(SWIG_exception.msg);
SWIG_rt_stack_pop();
longjmp(SWIG_rt_env, SWIG_exception_code);
longjmp(SWIG_rt_env, SWIG_exception.code);
}
SWIGEXPORTC void SWIG_Register_Handler(int code, void (*fun)()) {
if (SWIG_next_handler < SWIG_MAX_HANDLERS) {
int i = SWIG_next_handler++;
SWIG_Handlers[i].reg = 1;
SWIG_Handlers[i].code = code;
SWIG_Handlers[i].fun = fun;
}
}
SWIGEXPORTC void SWIG_Unregister_Handler(int code) {
int i;
for (i = 0; i < SWIG_next_handler; ++i) {
if (SWIG_Handlers[i].code == code)
SWIG_Handlers[i].reg = 0;
}
SWIGEXPORTC int SWIG_exit(int code) {
SWIG_cleanup();
exit(code);
}
#ifdef __cplusplus
}
#endif
SWIGINTERN void SWIG_terminate() {
fprintf(stderr, "Unhandled exception: %s\n%s (error code: %d)\nExitting...\n",
SWIG_exception.klass->typenames[0],
SWIG_exception.msg,
SWIG_exception.code);
SWIG_exit(SWIG_exception.code);
}
SWIGINTERN void SWIG_Runtime_init() {
int i, code;
if (!SWIG_rt_init) {
SWIG_rt_init = 1;
for (i = 0; i < SWIG_MAX_HANDLERS; ++i)
SWIG_Handlers[i].reg = 0;
SWIG_rt_stack_base = SWIG_rt_stack_ptr = (jmp_buf *) malloc(sizeof(jmp_buf) * SWIG_MAX_RT_STACK);
if (code = setjmp(SWIG_rt_env)) {
for (i = 0; i < SWIG_next_handler; ++i) {
if (SWIG_Handlers[i].reg)
if (SWIG_Handlers[i].code == code)
SWIG_Handlers[i].fun();
}
fprintf(stderr, "Unhandled exception. Exitting...\n");
exit(code);
}
if (SWIG_exception.code = setjmp(SWIG_rt_env))
SWIG_terminate();
}
}
SWIGINTERN void SWIG_CThrowException(int code, char *msg) {
SWIGINTERN void SWIG_CThrowException(void *klass, const char *msg) {
if (SWIG_rt_init)
longjmp(SWIG_rt_env, code);
else {
fprintf(stderr, "%s\n", msg);
exit(code);
}
SWIG_rt_throw((SwigObj *) klass, msg);
else
SWIG_terminate();
}
%}
%insert("proxy_header") %{
// special value indicating any type of exception like 'catch(...)'
#define SWIG_AnyException "SWIG_AnyException"
#include <stdbool.h>
#include <setjmp.h>
void SWIG_Register_Handler(int code, void (*fun)());
void SWIG_Unregister_Handler(int code);
int SWIG_exception_try();
void SWIG_exception_throw();
SWIGIMPORT jmp_buf SWIG_rt_env;
SWIGIMPORT int SWIG_exception_code;
typedef struct {
void *obj;
const char **typenames;
} SwigObj;
SWIGIMPORT struct {
int code;
char *msg;
SwigObj *klass;
} SWIG_exception;
SWIGIMPORT void SWIG_rt_try();
SWIGIMPORT int SWIG_rt_catch();
SWIGIMPORT void SWIG_rt_throw(int val);
SWIGIMPORT int SWIG_rt_catch(const char *type);
SWIGIMPORT void SWIG_rt_throw(SwigObj *klass, const char * msg);
SWIGIMPORT int SWIG_rt_endtry();
SWIGIMPORT int SWIG_exit(int code);
#define SWIG_try \
SWIG_rt_try(); \
if ((SWIG_exception_code = setjmp(SWIG_rt_env)) == 0)
#define SWIG_catch(val) else if (SWIG_rt_catch(val))
#define SWIG_throw(val) SWIG_rt_throw(val);
if ((SWIG_exception.code = setjmp(SWIG_rt_env)) == 0)
#define SWIG_catch(type) else if (SWIG_rt_catch(#type))
#define SWIG_throw(klass) SWIG_rt_throw((SwigObj *) klass, 0);
#define SWIG_throw_msg(klass, msg) SWIG_rt_throw((SwigObj *) klass, msg);
#define SWIG_endtry else SWIG_rt_endtry();
%}