Drop longjmp-based exception handling approach
Using longjmp was incompatible with using C++ objects in the code using the wrappers, and using this C API from C++ to avoid ABI incompatibilities between different C++ compilers is one of the main reasons for using this module. Also, this required using a separate SwigObj instead of just using the real object pointer which inevitably resulted in memory leaks whenever a non owned object was returned from anywhere, e.g. from a member accessor or any method returning pointer or reference. Abandon the attempts to recreate C++ exceptions in C and just use a very simple approach allowing to pass an error message out of band after any function call in a global variable. An alternative could be to add a special "out" error parameter to each and every function, but this risked being too verbose, especially for the functions which don't really throw, and the calls to SWIG_PendingException_get() won't need to be made explicitly when using a C++ wrapper around the generated C API in the future. This simplifies both the module and the generated code, in particular we don't need any runtime code at all any more and there is no need for an extra level of indirection for every object. It also makes a couple more tests pass.
This commit is contained in:
parent
bda731cd8f
commit
10d25c7327
7 changed files with 92 additions and 413 deletions
|
|
@ -3,57 +3,41 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "example_wrap.h"
|
||||
|
||||
static void show_exception(const char* prefix) {
|
||||
SWIG_CException* ex = SWIG_PendingException_get();
|
||||
assert(ex);
|
||||
printf("%s exception: %s (%d)\n", prefix, SWIG_CException_msg_get(ex), SWIG_CException_code_get(ex));
|
||||
SWIG_PendingException_reset();
|
||||
}
|
||||
|
||||
int main() {
|
||||
Test *t = Test_new();
|
||||
|
||||
SWIG_try {
|
||||
Test_unknown(t);
|
||||
}
|
||||
SWIG_catch(SWIG_AnyException) {
|
||||
printf("incomplete type: %s\n", SWIG_exc.msg);
|
||||
}
|
||||
SWIG_endtry;
|
||||
Test_unknown(t);
|
||||
show_exception("Unknown");
|
||||
|
||||
SWIG_try {
|
||||
Test_simple(t);
|
||||
}
|
||||
SWIG_catch(SWIG_AnyException) {
|
||||
printf("%s\n", SWIG_exc.msg);
|
||||
}
|
||||
SWIG_endtry;
|
||||
Test_simple(t);
|
||||
show_exception("Int");
|
||||
|
||||
SWIG_try {
|
||||
Test_message(t);
|
||||
}
|
||||
SWIG_catch(SWIG_AnyException) {
|
||||
printf("%s\n", SWIG_exc.msg);
|
||||
}
|
||||
SWIG_endtry;
|
||||
Test_message(t);
|
||||
show_exception("String");
|
||||
|
||||
SWIG_try {
|
||||
Test_hosed(t);
|
||||
}
|
||||
SWIG_catch(Exc) {
|
||||
printf("%d %s\n", Exc_code_get(SWIG_exc.klass),
|
||||
Exc_msg_get(SWIG_exc.klass));
|
||||
}
|
||||
Test_hosed(t);
|
||||
show_exception("Custom");
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
SWIG_try {
|
||||
Test_multi(t, i);
|
||||
Test_multi(t, i);
|
||||
if (!SWIG_PendingException_get()) {
|
||||
printf("Success for i=%d\n", i);
|
||||
} else {
|
||||
printf("For i=%d", i);
|
||||
show_exception("");
|
||||
}
|
||||
SWIG_catch(Exc) {
|
||||
printf("%d %s\n", Exc_code_get(SWIG_exc.klass),
|
||||
Exc_msg_get(SWIG_exc.klass));
|
||||
}
|
||||
SWIG_catch(SWIG_AnyException) {
|
||||
printf("%s\n", SWIG_exc.msg);
|
||||
}
|
||||
SWIG_endtry;
|
||||
}
|
||||
|
||||
SWIG_exit(0);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ FAILING_C_TESTS := \
|
|||
lextype \
|
||||
li_carrays \
|
||||
li_cdata \
|
||||
li_constraints \
|
||||
li_cpointer \
|
||||
nested \
|
||||
nested_extend_c \
|
||||
|
|
@ -88,12 +87,10 @@ FAILING_CPP_TESTS := \
|
|||
nested_class \
|
||||
nested_scope \
|
||||
nested_template_base \
|
||||
overload_arrays \
|
||||
smart_pointer_extend \
|
||||
smart_pointer_not \
|
||||
smart_pointer_template_defaults_overload \
|
||||
struct_initialization_cpp \
|
||||
template_arg_typename \
|
||||
template_basic \
|
||||
template_default \
|
||||
template_default_class_parms_typedef \
|
||||
|
|
|
|||
|
|
@ -5,60 +5,40 @@
|
|||
int main() {
|
||||
A* a = A_new();
|
||||
|
||||
SWIG_try {
|
||||
A_foo(a);
|
||||
}
|
||||
SWIG_catch(E1) {
|
||||
|
||||
}
|
||||
SWIG_catch(SWIG_AnyException) {
|
||||
A_foo(a);
|
||||
if (!SWIG_PendingException_get()) {
|
||||
fprintf(stderr, "foo: bad exception order\n");
|
||||
} else {
|
||||
SWIG_PendingException_reset();
|
||||
}
|
||||
SWIG_endtry;
|
||||
|
||||
SWIG_try {
|
||||
A_bar(a);
|
||||
}
|
||||
SWIG_catch(E2) {
|
||||
|
||||
}
|
||||
SWIG_catch(SWIG_AnyException) {
|
||||
A_bar(a);
|
||||
if (!SWIG_PendingException_get()) {
|
||||
fprintf(stderr, "bar: bad exception order\n");
|
||||
} else {
|
||||
SWIG_PendingException_reset();
|
||||
}
|
||||
SWIG_endtry;
|
||||
|
||||
SWIG_try {
|
||||
A_foobar(a);
|
||||
A_foobar(a);
|
||||
if (!SWIG_PendingException_get()) {
|
||||
fprintf(stderr, "foobar: bad exception order\n");
|
||||
} else {
|
||||
SWIG_PendingException_reset();
|
||||
}
|
||||
SWIG_catch(SWIG_AnyException) {
|
||||
if (strcmp(SWIG_exc.msg, "postcatch unknown") != 0) {
|
||||
fprintf(stderr, "bad exception order\n");
|
||||
SWIG_throw_msg(SWIG_exc.klass, SWIG_exc.msg);
|
||||
}
|
||||
}
|
||||
SWIG_endtry;
|
||||
|
||||
SWIG_try {
|
||||
A_barfoo(a, 1);
|
||||
}
|
||||
SWIG_catch(E1) {
|
||||
|
||||
}
|
||||
SWIG_catch(SWIG_AnyException) {
|
||||
A_barfoo(a, 1);
|
||||
if (!SWIG_PendingException_get()) {
|
||||
fprintf(stderr, "barfoo(1): bad exception order\n");
|
||||
} else {
|
||||
SWIG_PendingException_reset();
|
||||
}
|
||||
SWIG_endtry;
|
||||
|
||||
SWIG_try {
|
||||
A_barfoo(a, 2);
|
||||
}
|
||||
SWIG_catch(E2) {
|
||||
|
||||
}
|
||||
SWIG_catch(SWIG_AnyException) {
|
||||
A_barfoo(a, 2);
|
||||
if (!SWIG_PendingException_get()) {
|
||||
fprintf(stderr, "barfoo(2): bad exception order\n");
|
||||
} else {
|
||||
SWIG_PendingException_reset();
|
||||
}
|
||||
SWIG_endtry;
|
||||
|
||||
SWIG_exit(0);
|
||||
}
|
||||
|
|
|
|||
77
Lib/c/c.swg
77
Lib/c/c.swg
|
|
@ -14,8 +14,6 @@
|
|||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#define SWIG_STR2(x) #x
|
||||
#define SWIG_STR(x) SWIG_STR2(x)
|
||||
#define SWIG_contract_assert(expr, msg) if(!(expr)) { printf("%s\n", msg); SWIG_exit(0); } else
|
||||
%}
|
||||
|
||||
|
|
@ -140,12 +138,12 @@ same_action_all_primitive_types(in, "$1 = ($1_ltype) $input;")
|
|||
}
|
||||
|
||||
%typemap(in) SWIGTYPE {
|
||||
$1 = *($1_ltype *) ($input->obj);
|
||||
$1 = *($1_ltype *)$input;
|
||||
}
|
||||
|
||||
%typemap(in) SWIGTYPE * {
|
||||
if ($input)
|
||||
$1 = ($1_ltype) $input->obj;
|
||||
$1 = ($1_ltype) $input;
|
||||
}
|
||||
|
||||
%typemap(in) SWIGTYPE ** {
|
||||
|
|
@ -159,7 +157,7 @@ same_action_all_primitive_types(in, "$1 = ($1_ltype) $input;")
|
|||
size_t i = 0;
|
||||
for ( ; i < $1_dim0; ++i)
|
||||
if ($input[i])
|
||||
$1[i] = ($*1_ltype) $input[i]->obj;
|
||||
$1[i] = ($*1_ltype) $input[i];
|
||||
else
|
||||
$1[i] = ($*1_ltype) 0;
|
||||
}
|
||||
|
|
@ -174,7 +172,7 @@ same_action_all_primitive_types(in, "$1 = ($1_ltype) $input;")
|
|||
for ( ; i < $1_dim0; ++i) {
|
||||
for ( ; j < $1_dim1; ++j) {
|
||||
if ($input[i][j])
|
||||
$1[i][j] = * ($*1_ltype) $input[i][j]->obj;
|
||||
$1[i][j] = * ($*1_ltype) $input[i][j];
|
||||
else
|
||||
$1[i][j] = * ($*1_ltype) 0;
|
||||
}
|
||||
|
|
@ -191,14 +189,14 @@ same_action_all_primitive_types(in, "$1 = ($1_ltype) $input;")
|
|||
|
||||
%typemap(in) SWIGTYPE & {
|
||||
if ($input)
|
||||
$1 = ($1_ltype) $input->obj;
|
||||
$1 = ($1_ltype) $input;
|
||||
else
|
||||
$1 = ($1_ltype) 0;
|
||||
}
|
||||
|
||||
%typemap(in) SWIGTYPE *& {
|
||||
if ($input)
|
||||
$1 = ($1_ltype) &(*$input)->obj;
|
||||
$1 = ($1_ltype) $input;
|
||||
else
|
||||
$1 = ($1_ltype) 0;
|
||||
}
|
||||
|
|
@ -220,16 +218,16 @@ same_action_all_primitive_types(out, "$result = $1;")
|
|||
}
|
||||
|
||||
%typemap(out) SWIGTYPE *&, SWIGTYPE ** {
|
||||
static SwigObj* _ptr = (SwigObj*) SWIG_create_object($1, SWIG_STR(($1_basetype)));
|
||||
static SwigObj* _ptr = (SwigObj*) $1;
|
||||
$result = &_ptr;
|
||||
}
|
||||
|
||||
%typemap(out) SWIGTYPE {
|
||||
$result = (SwigObj*) SWIG_create_object(&$1, SWIG_STR(($1_basetype)));
|
||||
$result = (SwigObj*) &$1;
|
||||
}
|
||||
|
||||
%typemap(out) SWIGTYPE *, SWIGTYPE & {
|
||||
$result = (SwigObj*) SWIG_create_object($1, SWIG_STR(($1_basetype)));
|
||||
$result = (SwigObj*) $1;
|
||||
}
|
||||
|
||||
%typemap(out) SWIGTYPE * [ANY], SWIGTYPE [ANY][ANY] {
|
||||
|
|
@ -238,13 +236,13 @@ same_action_all_primitive_types(out, "$result = $1;")
|
|||
size_t i = 0;
|
||||
if (_temp) {
|
||||
for ( ; i < $1_dim0; ++i)
|
||||
SWIG_destroy_object< $1_ltype >(_temp[i]);
|
||||
delete ($1_ltype *)_temp[i];
|
||||
free(_temp);
|
||||
}
|
||||
_temp = (SwigObj**) malloc($1_dim0 * sizeof(SwigObj*));
|
||||
for (i = 0 ; i < $1_dim0; ++i) {
|
||||
if ($1[i]) {
|
||||
_temp[i] = SWIG_create_object($1[i], SWIG_STR(($1_ltype)));
|
||||
_temp[i] = $1[i];
|
||||
}
|
||||
else
|
||||
_temp[i] = (SwigObj*) 0;
|
||||
|
|
@ -277,59 +275,18 @@ same_type_all_primitive_types_but_void(cppouttype);
|
|||
#ifdef SWIG_CPPMODE
|
||||
|
||||
%insert("runtime") %{
|
||||
typedef struct {
|
||||
void *obj;
|
||||
const char* symname;
|
||||
bool (*derives_from)(const char* type);
|
||||
} SwigObj;
|
||||
|
||||
template <class T> SWIGINTERN void SWIG_destroy_object(SwigObj* object) {
|
||||
if (!object)
|
||||
return;
|
||||
|
||||
delete static_cast<T*>(object->obj);
|
||||
|
||||
free(object);
|
||||
}
|
||||
|
||||
template <class T> struct SWIG_derives_from {
|
||||
static bool check(const char* type) { return false; }
|
||||
};
|
||||
|
||||
template <class T> SWIGINTERN SwigObj* SWIG_create_object(T* obj, const char* symname) {
|
||||
SwigObj* const result = (SwigObj*)malloc(sizeof(SwigObj));
|
||||
if (result) {
|
||||
result->obj = const_cast<void*>(static_cast<const void*>(obj));
|
||||
result->symname = symname;
|
||||
result->derives_from = SWIG_derives_from<T>::check;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
typedef struct SwigObj SwigObj;
|
||||
%}
|
||||
|
||||
%insert("cheader") %{
|
||||
typedef struct SwigObjStruct SwigObj;
|
||||
typedef struct SwigObj SwigObj;
|
||||
%}
|
||||
|
||||
#ifdef SWIG_C_EXCEPT
|
||||
|
||||
#ifdef SWIG_C_EXCEPT
|
||||
%include "cexcept.swg"
|
||||
|
||||
#else
|
||||
|
||||
%insert("runtime") %{
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
SWIGEXPORTC int SWIG_exit(int code) { exit(code); }
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
%}
|
||||
#endif // SWIG_C_EXCEPT
|
||||
|
||||
#endif
|
||||
#else
|
||||
#endif // SWIG_CPPMODE
|
||||
|
||||
%insert("runtime") %{
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -340,5 +297,3 @@ SWIGEXPORTC int SWIG_exit(int code) { exit(code); }
|
|||
}
|
||||
#endif
|
||||
%}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,194 +4,44 @@
|
|||
* Exception handling code and typemaps for C module.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
%typemap(throws) BASIC_INT_TYPES {
|
||||
char error_msg[256];
|
||||
sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
|
||||
SWIG_CThrowException(0, error_msg);
|
||||
}
|
||||
%ignore SWIG_CException::SWIG_CException;
|
||||
|
||||
%apply BASIC_INT_TYPES { int, long, short, unsigned int, unsigned long, unsigned short, int &, long &, short &, unsigned int &, unsigned long &, unsigned short & };
|
||||
%inline %{
|
||||
class SWIG_CException {
|
||||
public:
|
||||
SWIG_CException(int code, const char* msg) : code(code), msg(strdup(msg)) { }
|
||||
|
||||
%typemap(throws) char *, const char * {
|
||||
SWIG_CThrowException(0, $1);
|
||||
}
|
||||
const int code;
|
||||
const char* const msg;
|
||||
|
||||
// this should match only SwigObj objects
|
||||
%typemap(throws) SWIGTYPE {
|
||||
SwigObj *c_ex;
|
||||
c_ex = SWIG_create_object(&$1, SWIG_STR($1_basetype));
|
||||
SWIG_CThrowException(c_ex, "C++ $1_type exception thrown");
|
||||
}
|
||||
private:
|
||||
friend void SWIG_PendingException_reset();
|
||||
|
||||
%typemap(throws) SWIGTYPE * {
|
||||
SwigObj *c_ex;
|
||||
c_ex = SWIG_create_object($1, SWIG_STR($1_basetype));
|
||||
SWIG_CThrowException(c_ex, "C++ $1_type exception thrown");
|
||||
}
|
||||
~SWIG_CException() { free(const_cast<char*>(msg)); }
|
||||
|
||||
%insert("runtime") %{
|
||||
#include <typeinfo>
|
||||
SWIG_CException(const SWIG_CException& ex);
|
||||
SWIG_CException& operator=(const SWIG_CException& ex);
|
||||
};
|
||||
|
||||
SWIGINTERN void SWIG_terminate();
|
||||
|
||||
#define SWIG_MAX_RT_STACK 256
|
||||
#define SWIG_REGISTRY_INIT 256
|
||||
|
||||
SWIGEXPORTC struct SWIG_exc_struct {
|
||||
int code;
|
||||
char *msg;
|
||||
SwigObj *klass;
|
||||
int handled;
|
||||
} SWIG_exc = { 0, 0, 0, 0 };
|
||||
|
||||
SWIGEXPORTC jmp_buf SWIG_rt_env;
|
||||
SWIGINTERN jmp_buf SWIG_cpp_back_env;
|
||||
SWIGINTERN jmp_buf *SWIG_rt_stack_base = 0;
|
||||
SWIGINTERN jmp_buf *SWIG_rt_stack_ptr = 0;
|
||||
|
||||
SWIGINTERN void SWIG_rt_stack_push() {
|
||||
if (!SWIG_rt_stack_base) {
|
||||
SWIG_rt_stack_base = SWIG_rt_stack_ptr = (jmp_buf *) malloc(sizeof(jmp_buf) * SWIG_MAX_RT_STACK);
|
||||
if ((SWIG_exc.code = setjmp(SWIG_rt_env))) {
|
||||
// deallocate C++ exception
|
||||
if (setjmp(SWIG_rt_env) == 0) {
|
||||
SWIG_rt_stack_push();
|
||||
SWIG_exc.handled = 1;
|
||||
longjmp(SWIG_cpp_back_env, 1);
|
||||
}
|
||||
SWIG_terminate();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check for stack overflow
|
||||
memcpy(SWIG_rt_stack_ptr, SWIG_rt_env, sizeof(SWIG_rt_env));
|
||||
SWIG_rt_stack_ptr++;
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_rt_stack_pop() {
|
||||
if (SWIG_rt_stack_ptr == SWIG_rt_stack_base)
|
||||
return;
|
||||
SWIG_rt_stack_ptr--;
|
||||
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_exc.msg)
|
||||
free(SWIG_exc.msg);
|
||||
if (SWIG_exc.klass) {
|
||||
free(SWIG_exc.klass);
|
||||
static SWIG_CException *SWIG_PendingException = 0;
|
||||
inline SWIG_CException* SWIG_PendingException_get() { return SWIG_PendingException; }
|
||||
inline void SWIG_PendingException_reset() {
|
||||
if (SWIG_PendingException) {
|
||||
delete SWIG_PendingException;
|
||||
SWIG_PendingException = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SWIGEXPORTC void SWIG_rt_try() {
|
||||
SWIG_rt_stack_push();
|
||||
}
|
||||
|
||||
SWIGEXPORTC int SWIG_rt_catch(const char *type) {
|
||||
int result = 0;
|
||||
if (!type || (strcmp("SWIG_AnyException", type) == 0)) {
|
||||
result = 1;
|
||||
}
|
||||
else if (SWIG_exc.klass) {
|
||||
result = strcmp(SWIG_exc.klass->symname, type) == 0 || SWIG_exc.klass->derives_from(type);
|
||||
}
|
||||
if (result) {
|
||||
SWIG_rt_stack_pop();
|
||||
SWIG_exc.handled = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
SWIGEXPORTC void SWIG_rt_throw(SwigObj *klass, const char *msg) {
|
||||
if (SWIG_exc.msg) {
|
||||
free(SWIG_exc.msg);
|
||||
SWIG_exc.msg = (char *) 0;
|
||||
}
|
||||
if (msg) {
|
||||
SWIG_exc.msg = (char *) malloc(strlen(msg) + 1);
|
||||
strcpy(SWIG_exc.msg, msg);
|
||||
}
|
||||
SWIG_exc.klass = klass;
|
||||
SWIG_exc.handled = 0;
|
||||
longjmp(SWIG_rt_env, 1);
|
||||
}
|
||||
|
||||
SWIGEXPORTC void SWIG_rt_unhandled() {
|
||||
if (SWIG_exc.msg) {
|
||||
free(SWIG_exc.msg);
|
||||
SWIG_exc.msg = 0;
|
||||
}
|
||||
SWIG_rt_stack_pop();
|
||||
longjmp(SWIG_rt_env, SWIG_exc.code);
|
||||
}
|
||||
|
||||
SWIGEXPORTC void SWIG_rt_endtry() {
|
||||
if (SWIG_exc.handled) {
|
||||
if (setjmp(SWIG_rt_env) == 0) {
|
||||
SWIG_rt_stack_push();
|
||||
longjmp(SWIG_cpp_back_env, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SWIG_rt_stack_pop(); // pop the SWIG_try context
|
||||
}
|
||||
}
|
||||
|
||||
SWIGEXPORTC int SWIG_exit(int code) {
|
||||
SWIG_cleanup();
|
||||
exit(code);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
SWIGINTERN void SWIG_terminate() {
|
||||
fprintf(stderr, "Unhandled exception: %s\n%s\nExitting...\n",
|
||||
typeid(*SWIG_exc.klass).name(),
|
||||
SWIG_exc.msg ? SWIG_exc.msg : "");
|
||||
SWIG_exit(SWIG_exc.code);
|
||||
}
|
||||
|
||||
#define SWIG_CThrowException(klass, msg) \
|
||||
if (setjmp(SWIG_cpp_back_env) == 0) \
|
||||
SWIG_rt_throw((SwigObj *) klass, msg);
|
||||
%}
|
||||
|
||||
%insert("cheader") %{
|
||||
// special value indicating any type of exception like 'catch(...)'
|
||||
#define SWIG_AnyException "SWIG_AnyException"
|
||||
%insert("runtime") "swigerrors.swg"
|
||||
|
||||
#include <setjmp.h>
|
||||
#define SWIG_exception(code, msg)\
|
||||
SWIG_PendingException = new SWIG_CException(code, msg)
|
||||
|
||||
SWIGIMPORT jmp_buf SWIG_rt_env;
|
||||
|
||||
SWIGIMPORT struct SWIG_exc_struct {
|
||||
int code;
|
||||
char *msg;
|
||||
SwigObj *klass;
|
||||
} SWIG_exc;
|
||||
|
||||
SWIGIMPORT void SWIG_rt_try();
|
||||
SWIGIMPORT int SWIG_rt_catch(const char *type);
|
||||
SWIGIMPORT void SWIG_rt_throw(SwigObj *klass, const char * msg);
|
||||
SWIGIMPORT int SWIG_rt_unhandled();
|
||||
SWIGIMPORT void SWIG_rt_endtry();
|
||||
SWIGIMPORT int SWIG_exit(int code);
|
||||
|
||||
#define SWIG_try \
|
||||
SWIG_rt_try(); \
|
||||
if ((SWIG_exc.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_unhandled(); SWIG_rt_endtry();
|
||||
|
||||
%}
|
||||
%typemap(throws, noblock="1") char *, const char * {
|
||||
SWIG_exception(SWIG_RuntimeError, $1);
|
||||
}
|
||||
|
||||
%typemap(throws, noblock="1") SWIGTYPE {
|
||||
SWIG_exception(SWIG_UnknownError, "exception of type $1_type");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,22 +205,6 @@ SWIGINTERN void SWIG_CSharpException(int code, const char *msg) {
|
|||
|
||||
#endif // SWIGLUA
|
||||
|
||||
#ifdef SWIGC
|
||||
|
||||
%inline %{
|
||||
struct SWIG_CException {
|
||||
SWIG_CException(int code) {
|
||||
SWIG_exc.code = code;
|
||||
}
|
||||
};
|
||||
%}
|
||||
|
||||
#define SWIG_exception(code, msg)\
|
||||
SwigObj *_ex = SWIG_create_object(new SWIG_CException(code), "SWIG_CException"); \
|
||||
SWIG_CThrowException(_ex, msg);
|
||||
|
||||
#endif // SWIGC
|
||||
|
||||
#ifdef SWIGD
|
||||
%{
|
||||
SWIGINTERN void SWIG_DThrowException(int code, const char *msg) {
|
||||
|
|
|
|||
|
|
@ -129,17 +129,12 @@ class C:public Language {
|
|||
String *int_string;
|
||||
String *tl_namespace; // optional top level namespace
|
||||
|
||||
// Contains fully expanded names of the classes for which we have already specialized SWIG_derives_from<>.
|
||||
Hash *already_specialized_derives_from;
|
||||
|
||||
// If non-null, contains wrap:action code to be used in the next functionWrapper() call.
|
||||
String *special_wrap_action;
|
||||
|
||||
// Used only while generating wrappers for an enum, initially true and reset to false as soon as we see any enum elements.
|
||||
bool enum_is_empty;
|
||||
|
||||
bool except_flag;
|
||||
|
||||
// Selects between the wrappers (public) declarations and (private) definitions.
|
||||
enum output_target {
|
||||
output_wrapper_decl,
|
||||
|
|
@ -156,9 +151,8 @@ public:
|
|||
empty_string(NewString("")),
|
||||
int_string(NewString("int")),
|
||||
tl_namespace(NULL),
|
||||
already_specialized_derives_from(NULL),
|
||||
special_wrap_action(NULL),
|
||||
except_flag(true) {
|
||||
special_wrap_action(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -350,6 +344,7 @@ public:
|
|||
* ------------------------------------------------------------ */
|
||||
|
||||
virtual void main(int argc, char *argv[]) {
|
||||
bool except_flag = CPlusPlus;
|
||||
|
||||
// look for certain command line options
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
|
@ -363,9 +358,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (!CPlusPlus)
|
||||
except_flag = false;
|
||||
|
||||
// add a symbol to the parser for conditional compilation
|
||||
Preprocessor_define("SWIGC 1", 0);
|
||||
if (except_flag)
|
||||
|
|
@ -1053,12 +1045,6 @@ ready:
|
|||
Append(wrapper->code, action);
|
||||
}
|
||||
|
||||
String *except = Getattr(n, "feature:except");
|
||||
if (Getattr(n, "throws") || except) {
|
||||
if (!except || (Cmp(except, "0") != 0))
|
||||
Printf(wrapper->code, "if (SWIG_exc.handled) {\nSWIG_rt_stack_pop();\nlongjmp(SWIG_rt_env, 1);\n}\n");
|
||||
}
|
||||
|
||||
// insert cleanup code
|
||||
for (p = parms; p; ) {
|
||||
String *tm;
|
||||
|
|
@ -1319,10 +1305,6 @@ ready:
|
|||
if (CPlusPlus) {
|
||||
// inheritance support: attach all members from base classes to this class
|
||||
if (List *baselist = Getattr(n, "bases")) {
|
||||
// We may need to specialize SWIG_derives_from<> for this class: its unique check() method will return true iff it's given the name of any subclasses of
|
||||
// this class. Notice that it may happen that all our base classes are ignored, in which case we don't do anything.
|
||||
int specialize_derives_from = -1;
|
||||
|
||||
Iterator i;
|
||||
for (i = First(baselist); i.item; i = Next(i)) {
|
||||
// look for member variables and functions
|
||||
|
|
@ -1362,51 +1344,6 @@ ready:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Account for this base class in the RTTI checks.
|
||||
String* const name = Getattr(i.item, "sym:name");
|
||||
if (name) {
|
||||
if (specialize_derives_from == -1) {
|
||||
// Check if we hadn't specialized it already. Somewhat surprisingly, this can happen for an instantiation of a template with default parameter(s)
|
||||
// if it appears both without them and with the default values explicitly given as it happens in e.g. template_default2 unit test.
|
||||
SwigType* const fulltype = Swig_symbol_template_deftype(Getattr(n, "name"), NULL);
|
||||
String* const fulltype_str = SwigType_str(fulltype, NULL);
|
||||
Delete(fulltype);
|
||||
|
||||
if (!already_specialized_derives_from || !Getattr(already_specialized_derives_from, fulltype_str)) {
|
||||
if (!already_specialized_derives_from) {
|
||||
already_specialized_derives_from = NewHash();
|
||||
}
|
||||
|
||||
Setattr(already_specialized_derives_from, fulltype_str, "1");
|
||||
|
||||
Printv(f_wrappers_cxx,
|
||||
"template<> struct SWIG_derives_from< ", fulltype_str, " > {\n",
|
||||
cindent, "static bool check(const char* type) {\n",
|
||||
cindent, cindent, "return ",
|
||||
NIL);
|
||||
|
||||
specialize_derives_from = true;
|
||||
} else {
|
||||
specialize_derives_from = false;
|
||||
}
|
||||
|
||||
Delete(fulltype_str);
|
||||
}
|
||||
else if (specialize_derives_from) {
|
||||
// Continue the already started specialization.
|
||||
Printv(f_wrappers_cxx, " ||\n", cindent, cindent, NIL);
|
||||
}
|
||||
|
||||
if (specialize_derives_from) {
|
||||
Printv(f_wrappers_cxx, "strcmp(type, \"", name, "\") == 0", NIL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (specialize_derives_from == true) {
|
||||
// End SWIG_derives_from specialization.
|
||||
Printv(f_wrappers_cxx, ";\n }\n};\n\n", NIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1532,7 +1469,6 @@ ready:
|
|||
virtual int constructorHandler(Node *n) {
|
||||
Node *klass = Swig_methodclass(n);
|
||||
String *classname = Getattr(klass, "classtype");
|
||||
String *newclassname = Getattr(klass, "sym:name");
|
||||
|
||||
bool const is_copy_ctor = Getattr(n, "copy_constructor");
|
||||
String *arg_lnames;
|
||||
|
|
@ -1544,12 +1480,7 @@ ready:
|
|||
}
|
||||
|
||||
// TODO-C: We need to call the extension ctor here instead of hard-coding "new classname".
|
||||
special_wrap_action = NewStringf(
|
||||
"result = SWIG_create_object(new %s%s, \"%s\");",
|
||||
classname,
|
||||
arg_lnames,
|
||||
newclassname
|
||||
);
|
||||
special_wrap_action = NewStringf("result = (SwigObj*)new %s%s;", classname, arg_lnames);
|
||||
|
||||
Delete(arg_lnames);
|
||||
|
||||
|
|
@ -1564,9 +1495,7 @@ ready:
|
|||
Node *klass = Swig_methodclass(n);
|
||||
|
||||
// TODO-C: We need to use the extension dtor here if one is defined.
|
||||
special_wrap_action = NewStringf(
|
||||
"SWIG_destroy_object< %s >(carg1);", Getattr(klass, "classtype")
|
||||
);
|
||||
special_wrap_action = NewStringf("delete (%s *)carg1;", Getattr(klass, "classtype"));
|
||||
|
||||
return Language::destructorHandler(n);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue