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
This commit is contained in:
Marcelo Matus 2006-01-11 01:34:06 +00:00
commit a24b11a8d3
2 changed files with 53 additions and 34 deletions

View file

@ -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 <list of catches>;
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 */

View file

@ -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");