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:
parent
d29dbe752d
commit
15923cd8b8
4 changed files with 139 additions and 33 deletions
|
|
@ -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(); }
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue