Added the ref/unref 'recursive' featues. See refcount.i for details

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@5705 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-02-10 09:21:36 +00:00
commit 15923cd8b8
4 changed files with 139 additions and 33 deletions

View file

@ -6,7 +6,7 @@
#include "refcount.h"
%}
#if 1
#if 0
//
// the old macro way
//
@ -32,8 +32,8 @@ RefCount(B);
// using the ref/unref features you can active the ref. counting
// for RCObj and all its descendents at once
//
%feature("refbase") RCObj "$this->ref();"
%feature("unrefbase") RCObj "$this->unref();"
%feature("ref") RCObj "$this->ref();"
%feature("unref") RCObj "$this->unref();"
#endif
@ -106,16 +106,8 @@ RefCount(B);
/* Other ref/unref uses:
// deactive the refcounting for A1
// deactive the refcounting for A1 and its descendents
%feature("noref") A1;
%feature("nounref") A1;
// deactive the refcounting for A2 and all its descendents
%feature("norefbase") A2;
%feature("nounrefbase") A2;
// active the refcounting only for A3
%feature("ref") A3 { $this->ref(); }
%feature("unref") A3 { $this->unref(); }
*/

View file

@ -395,6 +395,106 @@ Swig_cppconstructor_director_call(String_or_char *name, ParmList *parms) {
return Swig_cppconstructor_base_call(name, parms, 0);
}
/* -----------------------------------------------------------------------------
* Swig_cattr_search()
*
* This function search for the class attribute 'attr' in the class
* 'n' or recursively in its bases.
*
* if you define SWIG_FAST_REC_SEARCH, the method will set the found
* 'attr' in io the target class 'n'. If not, the method will set the
* 'noattr' one. This prevents of having to navigate the entire
* hierarchy tree everytime, so, it is an O(1) method... or something
* like that. However, it populates all the parsed classes with the
* 'attr' and/or 'noattr' attributes.
*
* If you undefine the SWIG_FAST_REC_SEARCH no attribute will be set
* while searching. This could be slower for large projects with very
* large hierarchy trees... or maybe not. But it will be cleaner.
*
* Maybe latter a swig option can be added to switch at runtime.
*
* ----------------------------------------------------------------------------- */
/* #define SWIG_FAST_REC_SEARCH 1 */
String *
Swig_cattr_search(Node *n, const String *attr, const String *noattr)
{
String *f = 0;
n = Swig_methodclass(n);
if (Getattr(n, noattr)) {
/* Printf(stdout,"noattr in %s\n", Getattr(n,"name")); */
return 0;
}
f = Getattr(n, attr);
if (f) {
/* Printf(stdout,"attr in %s\n", Getattr(n,"name")); */
return f;
} else {
List* bl = Getattr(n, "bases");
if (bl) {
Iterator bi;
for (bi = First(bl); bi.item; bi = Next(bi)) {
f = Swig_cattr_search(bi.item, attr, noattr);
if (f) {
#ifdef SWIG_FAST_REC_SEARCH
Setattr(n, attr, f);
#endif
return f;
}
}
}
}
#ifdef SWIG_FAST_REC_SEARCH
Setattr(n, noattr, "1");
#endif
return 0;
}
/* -----------------------------------------------------------------------------
* Swig_unref_call()
*
* find the unref call, if any.
* ----------------------------------------------------------------------------- */
String *
Swig_unref_call(Node *n) {
String* unref = 0;
n = Swig_methodclass(n);
if (!Getattr(n,"feature:nounref")) {
unref = Getattr(n,"feature:unref");
unref = unref ? unref :
Swig_cattr_search(n,"feature:unref","feature:nounref");
if (unref) {
unref = NewStringf("%s",unref);
Replaceall(unref,"$this",Swig_cparm_name(0,0));
}
}
return unref;
}
/* -----------------------------------------------------------------------------
* Swig_ref_call()
*
* find the ref call, if any.
* ----------------------------------------------------------------------------- */
String *
Swig_ref_call(Node *n, const String* lname) {
String* ref = 0;
n = Swig_methodclass(n);
if (!Getattr(n,"feature:noref")) {
ref = Getattr(n,"feature:ref");
ref = ref ? ref :
Swig_cattr_search(n,"feature:ref","feature:noref");
if (ref) {
ref = NewStringf("%s",ref);
Replaceall(ref,"$this",lname);
}
}
return ref;
}
/* -----------------------------------------------------------------------------
* Swig_cdestructor_call()
*
@ -404,11 +504,11 @@ Swig_cppconstructor_director_call(String_or_char *name, ParmList *parms) {
* ----------------------------------------------------------------------------- */
String *
Swig_cdestructor_call() {
String *func;
func = NewString("");
Printf(func,"free((char *) %s)", Swig_cparm_name(0,0));
return func;
Swig_cdestructor_call(Node *n) {
String* unref = Swig_unref_call(n);
if (unref) return unref;
return NewStringf("free((char *) %s);",Swig_cparm_name(0,0));
}
@ -421,12 +521,11 @@ Swig_cdestructor_call() {
* ----------------------------------------------------------------------------- */
String *
Swig_cppdestructor_call() {
String *func;
Swig_cppdestructor_call(Node *n) {
String* unref = Swig_unref_call(n);
if (unref) return unref;
func = NewString("");
Printf(func,"delete %s", Swig_cparm_name(0,0));
return func;
return NewStringf("delete %s;",Swig_cparm_name(0,0));
}
/* -----------------------------------------------------------------------------
@ -584,9 +683,11 @@ Swig_directormethod(Node *n) {
if (vtable) {
String *name = Getattr(n, "name");
String *decl = Getattr(n, "decl");
String *method_id = NewStringf("%s|%s", name, decl);
String *local_decl = SwigType_typedef_resolve_all(decl);
String *method_id = NewStringf("%s|%s", name, local_decl);
Hash *item = Getattr(vtable, method_id);
Delete(method_id);
Delete(local_decl);
if (item) {
return (Getattr(item, "director") != 0);
}
@ -789,11 +890,9 @@ Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags)
Delete(mangled);
} else {
if (cplus) {
String* action = NewString("");
Printf(action, "%s;\n", Swig_cppdestructor_call());
Setattr(n,"wrap:action", action);
Setattr(n,"wrap:action", NewStringf("%s\n",Swig_cppdestructor_call(n)));
} else {
Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cdestructor_call()));
Setattr(n,"wrap:action", NewStringf("%s\n", Swig_cdestructor_call(n)));
}
}
Setattr(n,"type",type);

View file

@ -447,8 +447,10 @@ extern String *Swig_cfunction_call(String_or_char *name, ParmList *parms);
extern String *Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self);
extern String *Swig_cconstructor_call(String_or_char *name);
extern String *Swig_cppconstructor_call(String_or_char *name, ParmList *parms);
extern String *Swig_cdestructor_call();
extern String *Swig_cppdestructor_call();
extern String *Swig_unref_call(Node *n);
extern String *Swig_ref_call(Node *n, const String* lname);
extern String *Swig_cdestructor_call(Node *n);
extern String *Swig_cppdestructor_call(Node *n);
extern String *Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self);
extern String *Swig_cmemberget_call(const String_or_char *name, SwigType *t, String_or_char *self);

View file

@ -1107,6 +1107,7 @@ String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const Stri
String *pname;
Hash *tm;
String *s = 0;
String *sdef = 0;
ParmList *locals;
ParmList *kw;
char temp[256];
@ -1114,18 +1115,24 @@ String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const Stri
String *cname = 0;
String *clname = 0;
/* special case, we need to check for 'ref' call
and set the defaul code 'sdef' */
if (Cmp(op,"newfree") == 0) {
sdef = Swig_ref_call(node, lname);
}
type = Getattr(node,"type");
if (!type) return 0;
if (!type) return sdef;
pname = Getattr(node,"name");
tm = Swig_typemap_search(op,type,pname,&mtype);
if (!tm) return 0;
if (!tm) return sdef;
s = Getattr(tm,"code");
if (!s) return 0;
if (!s) return sdef;
/* Empty typemap. No match */
if (Cmp(s,"pass") == 0) return 0;
if (Cmp(s,"pass") == 0) return sdef;
s = Copy(s); /* Make a local copy of the typemap code */
@ -1216,6 +1223,12 @@ String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const Stri
if (cname) Delete(cname);
if (clname) Delete(clname);
if (mtype) Delete(mtype);
if (sdef) { /* put 'ref' and 'newfree' codes together */
String *p = NewStringf("%s\n%s", sdef, s);
Delete(s);
Delete(sdef);
s = p;
}
return s;
}