rename %throws to %catchs

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@8351 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2006-01-10 18:47:51 +00:00
commit 043e45ca47
6 changed files with 62 additions and 35 deletions

View file

@ -2,7 +2,7 @@ Version 1.3.28 (unreleased).
=========================== ===========================
01/10/2006: mmatus 01/10/2006: mmatus
- Add the %throws directive, which complements the %exception - Add the %catchs directive, which complements the %exception
directive in a more automatic way. For example, if you have directive in a more automatic way. For example, if you have
int foo() throw(E1); int foo() throw(E1);
@ -31,39 +31,57 @@ Version 1.3.28 (unreleased).
} catch(E2) { ... } } catch(E2) { ... }
} }
which is very tedious. Well, the %throws directive adds the which is very tedious. Well, the %catchs directive defines
'missing' throw list, and from swig: the list of exception to catch, and from swig:
%throws(E1,E2) barfoo(int i); %catch(E1,E2) barfoo(int i);
int barfoo(int i); int barfoo(int i);
is equivalent to is equivalent to
int barfoo(int i) throw(E1,E2); int barfoo(int i) throw(E1,E2);
and then, swig will generate the proper try/catch code Note, however, that the %catchs list doesn't have to
automatically. correspond to the C++ 'throw' list. For example, if you
have:
The complementing part refers to the fact that you use the struct E {};
%exception and %throws directive togheter: struct E1 : E {};
struct E2 : E {};
int barfoo(int i) throw(E1,E2);
you can define
%catchs(E) barfoo(int i);
and swig will generate an action code equivalent to
%throws(E1,E2) barfoo(int i);
%exception barfoo(int i) {
try { try {
$action $action
} catch(...) { } catch(E &_e) {
<SWIG fail>; <raise _e>;
} }
}
int barfoo(int i); Of course, you still have to satisfy the C++ restrictions,
and the catchs list must be compatible (not the same)
than the original C++ throw list.
and swig, besides adding the code to catch E1,E2, will add the Also, you can now specify that you want to catch the
code to catch the "unknown" exception case. unknown exception '...', for example:
And not, you can't use it as %catchs(E1,E2,...) barfoo(int);
%throws(E1,E2,...) barfoo(); // ERROR!!!! In any case, the %catchs directive will emit the
'rethrowing' code using the 'throw' typemap.
For the same, for the '...' case to work, you need to
write the proper typemap in your target language. In the
UTL, this looks like:
%typemap(throws,noblock=1) (...) {
%raise(SWIG_ErrorType(SWIG_UnknownError), "UnknownError", 0);
}
01/05/2006: wsfulton 01/05/2006: wsfulton

View file

@ -15,7 +15,7 @@
} }
} }
%throws(E1,E2*,ET<int>,ET<double>) A::barfoo(int i); %catchs(E1,E2*,ET<int>,ET<double>,...) A::barfoo(int i);
%inline %{ %inline %{

View file

@ -88,10 +88,10 @@
#define %clearexception %feature("except","") #define %clearexception %feature("except","")
/* the %throws directive */ /* the %catchs directive */
#define %throws(tlist...) %feature("throws","("`tlist`")") #define %catchs(tlist...) %feature("catchs","("`tlist`")")
#define %clearthrows %feature("throws","") #define %clearcatchs %feature("catchs","")
/* the %exceptionclass directive */ /* the %exceptionclass directive */

View file

@ -438,6 +438,10 @@
%raise(SWIG_NewPointerObj(%as_voidptr(&$1),$descriptor,0), "$type", $descriptor); %raise(SWIG_NewPointerObj(%as_voidptr(&$1),$descriptor,0), "$type", $descriptor);
} }
%typemap(throws,noblock=1) (...) {
%raise(SWIG_ErrorType(SWIG_UnknownError), "UnknownType", 0);
}
/* ------------------------------------------------------------ /* ------------------------------------------------------------
* --- CLASS::* typemaps --- * --- CLASS::* typemaps ---
* ------------------------------------------------------------ */ * ------------------------------------------------------------ */

View file

@ -465,16 +465,19 @@ class Allocate : public Dispatcher {
} }
void mark_exception_classes(Node *n) { void mark_exception_classes(Node *n) {
ParmList *throws = Getattr(n,"throws"); ParmList *throws = 0;
if (!throws) { /* the "catchs" feature take precedence over the original throw list */
String *sthrows = Getattr(n,"feature:throws"); String *sthrows = Getattr(n,"feature:catchs");
if (sthrows) { if (sthrows) {
throws = Swig_cparse_parms(sthrows); throws = Swig_cparse_parms(sthrows);
if (throws) { if (throws) {
Setattr(n,"throws",throws); Setattr(n,"throws",throws);
} Delete(throws);
} }
} }
if (!throws) {
throws = Getattr(n,"throws");
}
if (throws) { if (throws) {
ParmList *p = throws; ParmList *p = throws;
while(p) { while(p) {

View file

@ -437,8 +437,10 @@ void emit_action(Node *n, Wrapper *f) {
SwigType *etr = SwigType_typedef_resolve_all(et); SwigType *etr = SwigType_typedef_resolve_all(et);
if (SwigType_isreference(etr) || SwigType_ispointer(etr) || SwigType_isarray(etr)) { if (SwigType_isreference(etr) || SwigType_ispointer(etr) || SwigType_isarray(etr)) {
Printf(eaction,"catch(%s) {", SwigType_str(et, "_e")); Printf(eaction,"catch(%s) {", SwigType_str(et, "_e"));
} else { } else if (SwigType_isvarargs(etr)) {
Printf(eaction,"catch(%s) {", SwigType_str(et, "&_e")); Printf(eaction,"catch(...) {");
} else {
Printf(eaction,"catch(%s) {", SwigType_str(et, "&_e"));
} }
Printv(eaction,em,"\n",NIL); Printv(eaction,em,"\n",NIL);
Printf(eaction,"}\n"); Printf(eaction,"}\n");