From dcec3c3fb0f19c75c487befe8cedde1fb8cd67ea Mon Sep 17 00:00:00 2001 From: Maciej Drwal Date: Wed, 30 Jul 2008 22:09:02 +0000 Subject: [PATCH] Added std_string support. Renamed SWIG_exception to SWIG_exc to avoid name collision with macro in Lib/exception.i. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-maciekd@10720 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/c/exception/runme.c | 14 ++-- Examples/test-suite/c/exception_order_runme.c | 4 +- Lib/c/c.swg | 68 +++++++++---------- Lib/c/std_string.i | 50 ++++++++++++++ Lib/exception.i | 6 +- Source/Modules/c.cxx | 48 +++++++++++-- 6 files changed, 140 insertions(+), 50 deletions(-) create mode 100644 Lib/c/std_string.i diff --git a/Examples/c/exception/runme.c b/Examples/c/exception/runme.c index 619f9b00e..7bef0a250 100644 --- a/Examples/c/exception/runme.c +++ b/Examples/c/exception/runme.c @@ -9,7 +9,7 @@ int main() { Test_unknown(t); } SWIG_catch(SWIG_AnyException) { - printf("incomplete type: %s\n", SWIG_exception.msg); + printf("incomplete type: %s\n", SWIG_exc.msg); } SWIG_endtry; @@ -17,7 +17,7 @@ int main() { Test_simple(t); } SWIG_catch(SWIG_AnyException) { - printf("%s\n", SWIG_exception.msg); + printf("%s\n", SWIG_exc.msg); } SWIG_endtry; @@ -25,7 +25,7 @@ int main() { Test_message(t); } SWIG_catch(SWIG_AnyException) { - printf("%s\n", SWIG_exception.msg); + printf("%s\n", SWIG_exc.msg); } SWIG_endtry; @@ -33,7 +33,8 @@ int main() { Test_hosed(t); } SWIG_catch(Exc) { - printf("%d %s\n", Exc_code_get(SWIG_exception.klass), Exc_msg_get(SWIG_exception.klass)); + printf("%d %s\n", Exc_code_get(SWIG_exc.klass), + Exc_msg_get(SWIG_exc.klass)); } int i; @@ -42,10 +43,11 @@ int main() { Test_multi(t, i); } SWIG_catch(Exc) { - printf("%d %s\n", Exc_code_get(SWIG_exception.klass), Exc_msg_get(SWIG_exception.klass)); + printf("%d %s\n", Exc_code_get(SWIG_exc.klass), + Exc_msg_get(SWIG_exc.klass)); } SWIG_catch(SWIG_AnyException) { - printf("%s\n", SWIG_exception.msg); + printf("%s\n", SWIG_exc.msg); } SWIG_endtry; } diff --git a/Examples/test-suite/c/exception_order_runme.c b/Examples/test-suite/c/exception_order_runme.c index 0db538661..a409db13e 100644 --- a/Examples/test-suite/c/exception_order_runme.c +++ b/Examples/test-suite/c/exception_order_runme.c @@ -31,9 +31,9 @@ int main() { A_foobar(a); } SWIG_catch(SWIG_AnyException) { - if (strcmp(SWIG_exception.msg, "postcatch unknown") != 0) { + if (strcmp(SWIG_exc.msg, "postcatch unknown") != 0) { fprintf(stderr, "bad exception order\n"); - SWIG_throw_msg(SWIG_exception.klass, SWIG_exception.msg); + SWIG_throw_msg(SWIG_exc.klass, SWIG_exc.msg); } } SWIG_endtry; diff --git a/Lib/c/c.swg b/Lib/c/c.swg index d03d55584..9c9152d70 100644 --- a/Lib/c/c.swg +++ b/Lib/c/c.swg @@ -72,12 +72,12 @@ typedef struct { %typemap(in) SWIGTYPE * { if ($input) - $1 = ($1_type) $input->obj; + $1 = ($1_ltype) $input->obj; } %typemap(in) SWIGTYPE * [ANY] { if ($input) { - $1 = ($1_basetype*) malloc($1_dim0 * sizeof($1_basetype)); + $1 = ($1_basetype *) malloc($1_dim0 * sizeof($1_basetype)); int i; for (i = 0; i < $1_dim0; ++i) if ($input[i]) @@ -185,12 +185,12 @@ SWIGINTERN int SWIG_registry_size = SWIG_REGISTRY_INIT; SWIGINTERN SwigObj *SWIG_create_object(const char *classname); SWIGINTERN void SWIG_destroy_object(SwigObj *object); -SWIGEXPORTC struct SWIG_exception_struct { +SWIGEXPORTC struct SWIG_exc_struct { int code; char *msg; SwigObj *klass; int handled; -} SWIG_exception = { 0, 0, 0, 0 }; +} SWIG_exc = { 0, 0, 0, 0 }; SWIGEXPORTC jmp_buf SWIG_rt_env; SWIGEXPORTC int SWIG_rt_init = 0; @@ -243,12 +243,12 @@ SWIGINTERN void SWIG_remove_registry_entry(SwigObj *entry) { SWIGINTERN void SWIG_cleanup() { if (SWIG_rt_stack_base) free(SWIG_rt_stack_base); - if (SWIG_exception.msg) - free(SWIG_exception.msg); - if (SWIG_exception.klass) { - if (SWIG_exception.klass->typenames) - free(SWIG_exception.klass->typenames); - free(SWIG_exception.klass); + if (SWIG_exc.msg) + free(SWIG_exc.msg); + if (SWIG_exc.klass) { + if (SWIG_exc.klass->typenames) + free(SWIG_exc.klass->typenames); + free(SWIG_exc.klass); } int i; if (SWIG_registry_base) { @@ -276,10 +276,10 @@ SWIGEXPORTC int SWIG_rt_catch(const char *type) { if (!type || (strcmp("SWIG_AnyException", type) == 0)) { result = 1; } - else if (SWIG_exception.klass) { + else if (SWIG_exc.klass) { int i = 0; - while (SWIG_exception.klass->typenames[i]) { - if (strcmp(SWIG_exception.klass->typenames[i++], type) == 0) { + while (SWIG_exc.klass->typenames[i]) { + if (strcmp(SWIG_exc.klass->typenames[i++], type) == 0) { result = 1; break; } @@ -287,36 +287,36 @@ SWIGEXPORTC int SWIG_rt_catch(const char *type) { } if (result) { SWIG_rt_stack_pop(); - SWIG_exception.handled = 1; + SWIG_exc.handled = 1; } return result; } SWIGEXPORTC void SWIG_rt_throw(SwigObj *klass, const char *msg) { - if (SWIG_exception.msg) { - free(SWIG_exception.msg); - SWIG_exception.msg = (char *) 0; + if (SWIG_exc.msg) { + free(SWIG_exc.msg); + SWIG_exc.msg = (char *) 0; } if (msg) { - SWIG_exception.msg = (char *) malloc(strlen(msg) + 1); - strcpy(SWIG_exception.msg, msg); + SWIG_exc.msg = (char *) malloc(strlen(msg) + 1); + strcpy(SWIG_exc.msg, msg); } - SWIG_exception.klass = klass; - SWIG_exception.handled = 0; + SWIG_exc.klass = klass; + SWIG_exc.handled = 0; longjmp(SWIG_rt_env, 1); } SWIGEXPORTC void SWIG_rt_unhandled() { - if (SWIG_exception.msg) { - free(SWIG_exception.msg); - SWIG_exception.msg = 0; + if (SWIG_exc.msg) { + free(SWIG_exc.msg); + SWIG_exc.msg = 0; } SWIG_rt_stack_pop(); - longjmp(SWIG_rt_env, SWIG_exception.code); + longjmp(SWIG_rt_env, SWIG_exc.code); } SWIGEXPORTC void SWIG_rt_endtry() { - if (SWIG_exception.handled) { + if (SWIG_exc.handled) { if (setjmp(SWIG_rt_env) == 0) { SWIG_rt_stack_push(); longjmp(SWIG_cpp_back_env, 1); @@ -338,9 +338,9 @@ SWIGEXPORTC int SWIG_exit(int code) { SWIGINTERN void SWIG_terminate() { fprintf(stderr, "Unhandled exception: %s\n%s\nExitting...\n", - SWIG_exception.klass->typenames[0], - SWIG_exception.msg ? SWIG_exception.msg : ""); - SWIG_exit(SWIG_exception.code); + SWIG_exc.klass->typenames[0], + SWIG_exc.msg ? SWIG_exc.msg : ""); + SWIG_exit(SWIG_exc.code); } SWIGINTERN void SWIG_Runtime_init() { @@ -348,11 +348,11 @@ SWIGINTERN void SWIG_Runtime_init() { if (!SWIG_rt_init) { SWIG_rt_init = 1; SWIG_rt_stack_base = SWIG_rt_stack_ptr = (jmp_buf *) malloc(sizeof(jmp_buf) * SWIG_MAX_RT_STACK); - if (SWIG_exception.code = setjmp(SWIG_rt_env)) { + if (SWIG_exc.code = setjmp(SWIG_rt_env)) { // deallocate C++ exception if (setjmp(SWIG_rt_env) == 0) { SWIG_rt_stack_push(); - SWIG_exception.handled = 1; + SWIG_exc.handled = 1; longjmp(SWIG_cpp_back_env, 1); } SWIG_terminate(); @@ -379,11 +379,11 @@ typedef struct { const char **typenames; } SwigObj; -SWIGIMPORT struct SWIG_exception_struct { +SWIGIMPORT struct SWIG_exc_struct { int code; char *msg; SwigObj *klass; -} SWIG_exception; +} SWIG_exc; SWIGIMPORT void SWIG_rt_try(); SWIGIMPORT int SWIG_rt_catch(const char *type); @@ -394,7 +394,7 @@ SWIGIMPORT int SWIG_exit(int code); #define SWIG_try \ SWIG_rt_try(); \ - if ((SWIG_exception.code = setjmp(SWIG_rt_env)) == 0) + 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); diff --git a/Lib/c/std_string.i b/Lib/c/std_string.i new file mode 100644 index 000000000..9269c6e40 --- /dev/null +++ b/Lib/c/std_string.i @@ -0,0 +1,50 @@ +%{ +#include +%} + +namespace std { + +// use "const string &" typemaps for wrapping member strings +%naturalvar string; + +class string; + +%typemap(ctype) string "char *" +%typemap(ctype) const string & "char *" +%typemap(couttype) string "char *" +%typemap(couttype) const string & "char *" + +%typemap(in) string { + if ($input) { + $1.assign($input); + } + else { + $1.resize(0); + } +} + +%typemap(in) const string & { + if ($input) { + $1 = new std::string($input); + } + else { + $1 = new std::string(); + $1->resize(0); + } +} + +%typemap(freearg) const string & { + if ($1) + delete $1; +} + +%typemap(out) string, const string & { + const char *str = cppresult.c_str(); + size_t len = strlen(str); + $result = (char *) malloc(len + 1); + memcpy($result, str, len); + $result[len] = '\0'; +} + +} + diff --git a/Lib/exception.i b/Lib/exception.i index e89e22e5a..18b08994f 100644 --- a/Lib/exception.i +++ b/Lib/exception.i @@ -217,13 +217,15 @@ SWIGINTERN void SWIG_CSharpException(int code, const char *msg) { %inline %{ struct SWIG_CException { SWIG_CException(int code) { - SWIG_exception.code = code; + SWIG_exc.code = code; } }; %} #define SWIG_exception(code, msg)\ - SWIG_CThrowException(_wrap_new_SWIG_CException(code), msg); + SwigObj *_ex = SWIG_create_object("SWIG_CException"); \ + _ex->obj = (void *) new SWIG_CException(code); \ + SWIG_CThrowException(_ex, msg); #endif // SWIGC diff --git a/Source/Modules/c.cxx b/Source/Modules/c.cxx index e6f3a5a7a..a971f6f8a 100644 --- a/Source/Modules/c.cxx +++ b/Source/Modules/c.cxx @@ -510,12 +510,19 @@ ready: if (SwigType_isconst(type)) SwigType_del_qualifier(type); SwigType *return_var_type; - return_var_type = SwigType_isreference(type) ? SwigType_add_pointer(SwigType_base(type)) : type; - return_var_type = SwigType_isarray(type) ? SwigType_add_pointer(SwigType_base(type)) : type; + if (SwigType_isenum(type)) Wrapper_add_localv(wrapper, "cppresult", "int", "cppresult", NIL); - else + else { + if (SwigType_isreference(type)) + return_var_type = SwigType_base(type); + else if (SwigType_isarray(type)) + return_var_type = SwigType_add_pointer(SwigType_base(type)); + else + return_var_type = type; + Wrapper_add_localv(wrapper, "cppresult", SwigType_str(return_var_type, 0), "cppresult", NIL); + } } // make sure lnames are set @@ -618,7 +625,7 @@ ready: // emit action code String *action = emit_action(n); if (Getattr(n, "throws") || (Cmp(Getattr(n, "feature:except"), "0") != 0)) { - Printf(action, "if (SWIG_exception.handled) {\nSWIG_rt_stack_pop();\nlongjmp(SWIG_rt_env, 1);\n}\n"); + Printf(action, "if (SWIG_exc.handled) {\nSWIG_rt_stack_pop();\nlongjmp(SWIG_rt_env, 1);\n}\n"); } if (Cmp(nodeType(n), "constructor") != 0) Replace(action, "result =", "cppresult = $mod", DOH_REPLACE_FIRST); @@ -627,8 +634,8 @@ ready: if (SwigType_isreference(type)) { String *ref_cast = NewString(""); if (SwigType_isconst(SwigType_del_reference(type))) { - Printf(ref_cast, "const_cast<%s*>(&", SwigType_str(SwigType_base(type), 0)); - Replaceall(action, ";", ");"); + //Printf(ref_cast, "(%s*)", SwigType_str(SwigType_base(type), 0)); + Printf(ref_cast, "*"); } else Printf(ref_cast, "&"); @@ -656,6 +663,35 @@ ready: Append(wrapper->code, action); } + // insert constraint checking + for (p = parms; p; ) { + if ((tm = Getattr(p, "tmap:check"))) { + Replaceall(tm, "$target", Getattr(p, "lname")); + Printv(wrapper->code, tm, "\n", NIL); + p = Getattr(p, "tmap:check:next"); + } + else { + p = nextSibling(p); + } + } + + // insert cleanup code + for (p = parms; p; ) { + if ((tm = Getattr(p, "tmap:freearg"))) { + if (tm && (Len(tm) != 0)) { + String *input = NewStringf("c%s", Getattr(p, "lname")); + Replaceall(tm, "$source", Getattr(p, "lname")); + Replaceall(tm, "$input", input); + Delete(input); + Printv(wrapper->code, tm, "\n", NIL); + } + p = Getattr(p, "tmap:freearg:next"); + } + else { + p = nextSibling(p); + } + } + if (!is_void_return) Append(wrapper->code, "return result;\n");