From a24b11a8d376eb23f6916f6206eb59a3cf60c5b2 Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Wed, 11 Jan 2006 01:34:06 +0000 Subject: [PATCH] clarify in the code what is the catch list and the throw list, which don't have to be the same, and don't modify the throws attribute since it should be inmutable (for xml and others) git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@8368 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/allocate.cxx | 79 +++++++++++++++++++++++-------------- Source/Modules/emit.cxx | 8 ++-- 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index 71afc0287..4be80dd46 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -464,37 +464,56 @@ class Allocate : public Dispatcher { return methods; } - void mark_exception_classes(Node *n) { - ParmList *throws = 0; - /* the "catchs" feature take precedence over the original throw list */ - String *sthrows = Getattr(n,"feature:catches"); - if (sthrows) { - throws = Swig_cparse_parms(sthrows); - if (throws) { - Setattr(n,"throws",throws); - Delete(throws); + void mark_exception_classes(ParmList *p) + { + while(p) { + SwigType *ty = Getattr(p,"type"); + SwigType *t = SwigType_typedef_resolve_all(ty); + if (SwigType_isreference(t) || SwigType_ispointer(t) || SwigType_isarray(t)) { + Delete(SwigType_pop(t)); + } + Node *c = Swig_symbol_clookup(t,0); + if (c) { + if (!GetFlag(c,"feature:exceptionclass")) { + SetFlag(c,"feature:exceptionclass"); + } + } + p = nextSibling(p); + Delete(t); + } + } + + + void process_exceptions(Node *n) { + ParmList *catchlist = 0; + /* + the "catchlist" attribute is used to emit the block + + try {$action;} + catch ; + + in emit.cxx + + and is either constructued from the "feature:catches" feature + or copied from the node "throws" list. + */ + String *scatchlist = Getattr(n,"feature:catches"); + if (scatchlist) { + catchlist = Swig_cparse_parms(scatchlist); + if (catchlist) { + Setattr(n,"catchlist",catchlist); + mark_exception_classes(catchlist); + Delete(catchlist); } } - if (!throws) { - throws = Getattr(n,"throws"); - } + ParmList *throws = Getattr(n,"throws"); if (throws) { - ParmList *p = throws; - while(p) { - SwigType *ty = Getattr(p,"type"); - SwigType *t = SwigType_typedef_resolve_all(ty); - if (SwigType_isreference(t) || SwigType_ispointer(t) || SwigType_isarray(t)) { - Delete(SwigType_pop(t)); - } - Node *c = Swig_symbol_clookup(t,0); - if (c) { - if (!GetFlag(c,"feature:exceptionclass")) { - SetFlag(c,"feature:exceptionclass"); - } - } - p = nextSibling(p); - Delete(t); + /* if there is no an explicit catchlist, + we catch everything in the throwlist */ + if (!catchlist) { + Setattr(n,"catchlist",throws); } + mark_exception_classes(throws); } } @@ -719,7 +738,7 @@ public: Node *c = 0; for (c = firstChild(n); c; c = nextSibling(c)) { if (Strcmp(nodeType(c),"cdecl") == 0) { - mark_exception_classes(c); + process_exceptions(c); if (inclass) class_member_is_defined_in_bases(c, inclass); @@ -731,7 +750,7 @@ public: virtual int cDeclaration(Node *n) { - mark_exception_classes(n); + process_exceptions(n); if (inclass) { /* check whether the member node n is defined in class node in class's bases */ @@ -815,7 +834,7 @@ public: if (!inclass) return SWIG_OK; Parm *parms = Getattr(n,"parms"); - mark_exception_classes(n); + process_exceptions(n); if (!extendmode) { if (!ParmList_numrequired(parms)) { /* Class does define a default constructor */ diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx index 2720d3be4..c97e434c0 100644 --- a/Source/Modules/emit.cxx +++ b/Source/Modules/emit.cxx @@ -345,7 +345,7 @@ void emit_action(Node *n, Wrapper *f) { String *action; String *wrap; SwigType *rt; - ParmList *throws = Getattr(n,"throws"); + ParmList *catchlist = Getattr(n,"catchlist"); /* Look for fragments */ { @@ -421,16 +421,16 @@ void emit_action(Node *n, Wrapper *f) { /* If we are in C++ mode and there is an exception specification. We're going to enclose the block in a try block */ - if (throws) { + if (catchlist) { Printf(eaction,"try {\n"); } Printv(eaction, action, NIL); - if (throws) { + if (catchlist) { int unknown_catch = 0; Printf(eaction,"}\n"); - for (Parm *ep = throws; ep; ep = nextSibling(ep)) { + for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) { String *em = Swig_typemap_lookup_new("throws",ep,"_e",0); if (em) { SwigType *et = Getattr(ep,"type");