aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcelo Matus <mmatus@acms.arizona.edu>2006-01-10 18:47:51 +0000
committerMarcelo Matus <mmatus@acms.arizona.edu>2006-01-10 18:47:51 +0000
commite676d2f8bd5e77a5fb0377b099bb2c5b0970991f (patch)
tree545ec3089c4bfb5cf1718d11e1f8194f6fa7bd77
parentb044703d0d2b7a33ded626eef5c90f353170bca1 (diff)
downloadswig-e676d2f8bd5e77a5fb0377b099bb2c5b0970991f.tar.gz
rename %throws to %catchs
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@8351 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r--CHANGES.current60
-rw-r--r--Examples/test-suite/exception_order.i2
-rw-r--r--Lib/swig.swg6
-rw-r--r--Lib/typemaps/swigtype.swg4
-rw-r--r--Source/Modules/allocate.cxx19
-rw-r--r--Source/Modules/emit.cxx6
6 files changed, 62 insertions, 35 deletions
diff --git a/CHANGES.current b/CHANGES.current
index 8203d3ea2..b46c451ce 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,8 +1,8 @@
Version 1.3.28 (unreleased).
===========================
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
int foo() throw(E1);
@@ -31,39 +31,57 @@ Version 1.3.28 (unreleased).
} catch(E2) { ... }
}
- which is very tedious. Well, the %throws directive adds the
- 'missing' throw list, and from swig:
+ which is very tedious. Well, the %catchs directive defines
+ 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);
is equivalent to
int barfoo(int i) throw(E1,E2);
- and then, swig will generate the proper try/catch code
- automatically.
+ Note, however, that the %catchs list doesn't have to
+ correspond to the C++ 'throw' list. For example, if you
+ have:
+
+ struct E {};
+ struct E1 : E {};
+ struct E2 : E {};
- The complementing part refers to the fact that you use the
- %exception and %throws directive togheter:
+ 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 {
$action
- } catch(...) {
- <SWIG fail>;
- }
- }
-
- int barfoo(int i);
+ } catch(E &_e) {
+ <raise _e>;
+ }
+
+ 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.
+
+ Also, you can now specify that you want to catch the
+ unknown exception '...', for example:
+
+ %catchs(E1,E2,...) barfoo(int);
- and swig, besides adding the code to catch E1,E2, will add the
- code to catch the "unknown" exception case.
+ In any case, the %catchs directive will emit the
+ 'rethrowing' code using the 'throw' typemap.
- And not, you can't use it as
+ 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:
- %throws(E1,E2,...) barfoo(); // ERROR!!!!
+ %typemap(throws,noblock=1) (...) {
+ %raise(SWIG_ErrorType(SWIG_UnknownError), "UnknownError", 0);
+ }
01/05/2006: wsfulton
diff --git a/Examples/test-suite/exception_order.i b/Examples/test-suite/exception_order.i
index 35c56adb4..3c376b6e8 100644
--- a/Examples/test-suite/exception_order.i
+++ b/Examples/test-suite/exception_order.i
@@ -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 %{
diff --git a/Lib/swig.swg b/Lib/swig.swg
index 77ecd0fe1..23e0d8edc 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -88,10 +88,10 @@
#define %clearexception %feature("except","")
-/* the %throws directive */
+/* the %catchs directive */
-#define %throws(tlist...) %feature("throws","("`tlist`")")
-#define %clearthrows %feature("throws","")
+#define %catchs(tlist...) %feature("catchs","("`tlist`")")
+#define %clearcatchs %feature("catchs","")
/* the %exceptionclass directive */
diff --git a/Lib/typemaps/swigtype.swg b/Lib/typemaps/swigtype.swg
index 9c8f29e63..3b1c0d4c7 100644
--- a/Lib/typemaps/swigtype.swg
+++ b/Lib/typemaps/swigtype.swg
@@ -438,6 +438,10 @@
%raise(SWIG_NewPointerObj(%as_voidptr(&$1),$descriptor,0), "$type", $descriptor);
}
+%typemap(throws,noblock=1) (...) {
+ %raise(SWIG_ErrorType(SWIG_UnknownError), "UnknownType", 0);
+}
+
/* ------------------------------------------------------------
* --- CLASS::* typemaps ---
* ------------------------------------------------------------ */
diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx
index 1394b7adc..af7edaf5c 100644
--- a/Source/Modules/allocate.cxx
+++ b/Source/Modules/allocate.cxx
@@ -465,16 +465,19 @@ class Allocate : public Dispatcher {
}
void mark_exception_classes(Node *n) {
- ParmList *throws = Getattr(n,"throws");
- if (!throws) {
- String *sthrows = Getattr(n,"feature:throws");
- if (sthrows) {
- throws = Swig_cparse_parms(sthrows);
- if (throws) {
- Setattr(n,"throws",throws);
- }
+ ParmList *throws = 0;
+ /* the "catchs" feature take precedence over the original throw list */
+ String *sthrows = Getattr(n,"feature:catchs");
+ if (sthrows) {
+ throws = Swig_cparse_parms(sthrows);
+ if (throws) {
+ Setattr(n,"throws",throws);
+ Delete(throws);
}
}
+ if (!throws) {
+ throws = Getattr(n,"throws");
+ }
if (throws) {
ParmList *p = throws;
while(p) {
diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx
index c65c4d657..2720d3be4 100644
--- a/Source/Modules/emit.cxx
+++ b/Source/Modules/emit.cxx
@@ -437,8 +437,10 @@ void emit_action(Node *n, Wrapper *f) {
SwigType *etr = SwigType_typedef_resolve_all(et);
if (SwigType_isreference(etr) || SwigType_ispointer(etr) || SwigType_isarray(etr)) {
Printf(eaction,"catch(%s) {", SwigType_str(et, "_e"));
- } else {
- Printf(eaction,"catch(%s) {", SwigType_str(et, "&_e"));
+ } else if (SwigType_isvarargs(etr)) {
+ Printf(eaction,"catch(...) {");
+ } else {
+ Printf(eaction,"catch(%s) {", SwigType_str(et, "&_e"));
}
Printv(eaction,em,"\n",NIL);
Printf(eaction,"}\n");