diff --git a/SWIG/CHANGES.current b/SWIG/CHANGES.current index f18a9657a..8203d3ea2 100644 --- a/SWIG/CHANGES.current +++ b/SWIG/CHANGES.current @@ -1,5 +1,71 @@ Version 1.3.28 (unreleased). =========================== +01/10/2006: mmatus + + - Add the %throws directive, which complements the %exception + directive in a more automatic way. For example, if you have + + int foo() throw(E1); + + swig generates the proper try/catch code to dispatch E1. + + But if you have: + + + int barfoo(int i) { + if (i == 1) { + throw E1(); + } else { + throw E2(); + } + return 0; + } + + ie, where there is no explicit throw list in the decl, you + end doing: + + %exception barfoo { + try { + $action + } catch(E1) { ... } + } catch(E2) { ... } + } + + which is very tedious. Well, the %throws directive adds the + 'missing' throw list, and from swig: + + %throws(E1,E2) barfoo(int i); + int barfoo(int i); + + is equivalent to + + int barfoo(int i) throw(E1,E2); + + and then, swig will generate the proper try/catch code + automatically. + + The complementing part refers to the fact that you use the + %exception and %throws directive togheter: + + %throws(E1,E2) barfoo(int i); + %exception barfoo(int i) { + try { + $action + } catch(...) { + ; + } + } + + int barfoo(int i); + + and swig, besides adding the code to catch E1,E2, will add the + code to catch the "unknown" exception case. + + And not, you can't use it as + + %throws(E1,E2,...) barfoo(); // ERROR!!!! + + 01/05/2006: wsfulton [Java] Fix unsigned long long and const unsigned long long & typemaps - Bug #1398394 with patch from Dries Decock diff --git a/SWIG/Examples/test-suite/exception_order.i b/SWIG/Examples/test-suite/exception_order.i index 20f0c6331..dd0f8c813 100644 --- a/SWIG/Examples/test-suite/exception_order.i +++ b/SWIG/Examples/test-suite/exception_order.i @@ -15,6 +15,8 @@ } } +%throws(E1,E2) A::barfoo(int i); + %inline %{ struct E1 @@ -50,5 +52,16 @@ throw E3(); return 0; } + + + int barfoo(int i) + { + if (i == 1) { + throw E1(); + } else { + throw E2(); + } + return 0; + } }; %} diff --git a/SWIG/Examples/test-suite/python/exception_order_runme.py b/SWIG/Examples/test-suite/python/exception_order_runme.py index 451518d05..0b0b1c08d 100644 --- a/SWIG/Examples/test-suite/python/exception_order_runme.py +++ b/SWIG/Examples/test-suite/python/exception_order_runme.py @@ -24,3 +24,18 @@ except RuntimeError,e: print "bad exception order", raise RuntimeError, e.args + + +try: + a.barfoo(1) +except E1,e: + pass +except: + raise RuntimeError, "bad exception order" + +try: + a.barfoo(2) +except E2,e: + pass +except: + raise RuntimeError, "bad exception order" diff --git a/SWIG/Lib/swig.swg b/SWIG/Lib/swig.swg index 8f399891d..77ecd0fe1 100644 --- a/SWIG/Lib/swig.swg +++ b/SWIG/Lib/swig.swg @@ -87,6 +87,12 @@ #define %noexception %feature("except","0") #define %clearexception %feature("except","") + +/* the %throws directive */ + +#define %throws(tlist...) %feature("throws","("`tlist`")") +#define %clearthrows %feature("throws","") + /* the %exceptionclass directive */ #define %exceptionclass %feature("exceptionclass") diff --git a/SWIG/Source/Modules/emit.cxx b/SWIG/Source/Modules/emit.cxx index c65c4d657..015a6bb7c 100644 --- a/SWIG/Source/Modules/emit.cxx +++ b/SWIG/Source/Modules/emit.cxx @@ -346,6 +346,18 @@ void emit_action(Node *n, Wrapper *f) { String *wrap; SwigType *rt; ParmList *throws = Getattr(n,"throws"); + if (!throws) { + String *tmp = 0; + String *sthrows = Getattr(n,"feature:throws"); + if (sthrows) { + char *cthrows = Char(sthrows); + if (cthrows && cthrows[0] != '(') { + sthrows = tmp = NewStringf("(%s)",sthrows); + } + throws = SwigType_function_parms(sthrows); + if (tmp) Delete (tmp); + } + } /* Look for fragments */ {