Symbols in the generated director code. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5154 626c5289-ae23-0410-ae9c-e8d60b6d4f22
979 lines
27 KiB
C
979 lines
27 KiB
C
/* -----------------------------------------------------------------------------
|
|
* cwrap.c
|
|
*
|
|
* This file defines a variety of wrapping rules for C/C++ handling including
|
|
* the naming of local variables, calling conventions, and so forth.
|
|
*
|
|
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
|
*
|
|
* Copyright (C) 1998-2000. The University of Chicago
|
|
* Copyright (C) 1995-1998. The University of Utah and The Regents of the
|
|
* University of California.
|
|
*
|
|
* See the file LICENSE for information on usage and redistribution.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
char cvsroot_cwrap_c[] = "$Header$";
|
|
|
|
#include "swig.h"
|
|
|
|
static Parm *nonvoid_parms(Parm *p) {
|
|
if (p) {
|
|
SwigType *t = Getattr(p,"type");
|
|
if (SwigType_type(t) == T_VOID) return 0;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_parm_name()
|
|
*
|
|
* Generates a name for the ith argument in an argument list
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_cparm_name(Parm *p, int i) {
|
|
String *name = NewStringf("arg%d",i+1);
|
|
if (p) {
|
|
Setattr(p,"lname",name);
|
|
}
|
|
|
|
return name;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_clocal()
|
|
*
|
|
* Creates a string that declares a C local variable type. Converts references
|
|
* and user defined types to pointers.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value) {
|
|
String *decl;
|
|
|
|
decl = NewString("");
|
|
|
|
switch(SwigType_type(t)) {
|
|
case T_REFERENCE:
|
|
if (value) {
|
|
Printf(decl,"%s = (%s) &%s_defvalue", SwigType_lstr(t,name), SwigType_lstr(t,0), name);
|
|
} else {
|
|
Printf(decl,"%s = 0", SwigType_lstr(t,name));
|
|
}
|
|
break;
|
|
case T_VOID:
|
|
break;
|
|
case T_VARARGS:
|
|
Printf(decl,"void *%s = 0", name);
|
|
break;
|
|
|
|
default:
|
|
if (value) {
|
|
Printf(decl,"%s = (%s) %s", SwigType_lstr(t,name), SwigType_lstr(t,0), SwigType_lcaststr(t,value));
|
|
} else {
|
|
Printf(decl,"%s", SwigType_lstr(t,name));
|
|
}
|
|
}
|
|
return decl;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_wrapped_var_convert()
|
|
*
|
|
* Converts a member variable for use in the get and set wrapper methods.
|
|
* This function only converts user defined types to pointers.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_wrapped_var_type(SwigType *t) {
|
|
SwigType *ty;
|
|
ty = Copy(t);
|
|
|
|
if (SwigType_isclass(t)) {
|
|
SwigType_add_pointer(ty);
|
|
}
|
|
return ty;
|
|
}
|
|
|
|
String *
|
|
Swig_wrapped_var_deref(SwigType *t, String_or_char *name) {
|
|
if (SwigType_isclass(t)) {
|
|
return NewStringf("*%s",name);
|
|
} else {
|
|
return SwigType_rcaststr(t,name);
|
|
}
|
|
}
|
|
|
|
String *
|
|
Swig_wrapped_var_assign(SwigType *t, String_or_char *name) {
|
|
if (SwigType_isclass(t)) {
|
|
return NewStringf("&%s",name);
|
|
} else {
|
|
return SwigType_lcaststr(t,name);
|
|
}
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_cargs()
|
|
*
|
|
* Emit all of the local variables for a list of parameters. Returns the
|
|
* number of parameters.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int Swig_cargs(Wrapper *w, ParmList *p) {
|
|
int i;
|
|
SwigType *pt;
|
|
String *pvalue;
|
|
String *pname;
|
|
String *local;
|
|
String *lname;
|
|
SwigType *altty;
|
|
String *type;
|
|
int tycode;
|
|
|
|
i = 0;
|
|
while (p != 0) {
|
|
lname = Swig_cparm_name(p,i);
|
|
pt = Getattr(p,"type");
|
|
if ((SwigType_type(pt) != T_VOID)) {
|
|
pname = Getattr(p,"name");
|
|
pvalue = Getattr(p,"value");
|
|
altty = Getattr(p,"alttype");
|
|
type = Getattr(p,"type");
|
|
tycode = SwigType_type(type);
|
|
if (tycode == T_REFERENCE) {
|
|
if (pvalue) {
|
|
String *defname, *defvalue;
|
|
defname = NewStringf("%s_defvalue", lname);
|
|
defvalue = NewStringf("%s = %s", SwigType_str(type,defname), pvalue);
|
|
Wrapper_add_localv(w,defname, defvalue, NIL);
|
|
Delete(defname);
|
|
Delete(defvalue);
|
|
}
|
|
} else if (!pvalue && (tycode == T_POINTER)) {
|
|
pvalue = (String *) "0";
|
|
}
|
|
if (!altty) {
|
|
local = Swig_clocal(pt,lname,pvalue);
|
|
} else {
|
|
local = Swig_clocal(altty,lname, pvalue);
|
|
}
|
|
Wrapper_add_localv(w,lname,local,NIL);
|
|
i++;
|
|
}
|
|
p = nextSibling(p);
|
|
}
|
|
return(i);
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_cresult()
|
|
*
|
|
* This function generates the C code needed to set the result of a C
|
|
* function call.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_char *decl) {
|
|
String *fcall;
|
|
|
|
fcall = NewString("");
|
|
switch(SwigType_type(t)) {
|
|
case T_VOID:
|
|
break;
|
|
case T_REFERENCE:
|
|
Printf(fcall,"{\n");
|
|
Printf(fcall,"%s = ", SwigType_str(t,"_result_ref"));
|
|
break;
|
|
case T_USER:
|
|
Printf(fcall,"%s = ", name);
|
|
break;
|
|
|
|
default:
|
|
/* Normal return value */
|
|
Printf(fcall,"%s = (%s)", name, SwigType_lstr(t,0));
|
|
break;
|
|
}
|
|
|
|
/* Now print out function call */
|
|
Printv(fcall,decl,NIL);
|
|
|
|
/* A sick hack */
|
|
{
|
|
char *c = Char(decl) + Len(decl) - 1;
|
|
if (!((*c == ';') || (*c == '}')))
|
|
Printf(fcall, ";");
|
|
}
|
|
Printf(fcall,"\n");
|
|
|
|
if (SwigType_type(t) == T_REFERENCE) {
|
|
Printf(fcall,"%s = (%s) &_result_ref;\n", name, SwigType_lstr(t,0));
|
|
Printf(fcall,"}\n");
|
|
}
|
|
return fcall;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_cfunction_call()
|
|
*
|
|
* Creates a string that calls a C function using the local variable rules
|
|
* defined above.
|
|
*
|
|
* name(arg0, arg1, arg2, ... argn)
|
|
*
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_cfunction_call(String_or_char *name, ParmList *parms) {
|
|
String *func;
|
|
int i = 0;
|
|
int comma = 0;
|
|
Parm *p = parms;
|
|
SwigType *pt;
|
|
String *nname;
|
|
|
|
func = NewString("");
|
|
nname = SwigType_namestr(name);
|
|
Printf(func,"%s(", nname);
|
|
while (p) {
|
|
String *pname;
|
|
pt = Getattr(p,"type");
|
|
|
|
if ((SwigType_type(pt) != T_VOID)) {
|
|
if (comma) Printf(func,",");
|
|
pname = Swig_cparm_name(p,i);
|
|
Printf(func,"%s", SwigType_rcaststr(pt, pname));
|
|
comma = 1;
|
|
i++;
|
|
}
|
|
p = nextSibling(p);
|
|
}
|
|
Printf(func,")");
|
|
return func;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_cmethod_call()
|
|
*
|
|
* Generates a string that calls a C++ method from a list of parameters.
|
|
*
|
|
* arg0->name(arg1, arg2, arg3, ..., argn)
|
|
*
|
|
* self is an argument that defines how to handle the first argument. Normally,
|
|
* it should be set to "this->". With C++ proxy classes enabled, it could be
|
|
* set to "(*this)->" or some similar sequence.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self) {
|
|
String *func, *nname;
|
|
int i = 0;
|
|
Parm *p = parms;
|
|
SwigType *pt;
|
|
int comma = 0;
|
|
|
|
if (!self) self = (char *) "(this)->";
|
|
|
|
func = NewString("");
|
|
nname = SwigType_namestr(name);
|
|
if (!p) return func;
|
|
Append(func,self);
|
|
pt = Getattr(p,"type");
|
|
|
|
/* If the method is invoked through a dereferenced pointer, we don't add any casts
|
|
(needed for smart pointers). Otherwise, we cast to the appropriate type */
|
|
|
|
if (Strstr(func,"*this")) {
|
|
Replaceall(func,"this", Swig_cparm_name(p,0));
|
|
} else {
|
|
Replaceall(func,"this", SwigType_rcaststr(pt, Swig_cparm_name(p,0)));
|
|
}
|
|
|
|
if (SwigType_istemplate(name)) {
|
|
Printf(func,"template %s(", nname);
|
|
} else {
|
|
Printf(func,"%s(", nname);
|
|
}
|
|
i++;
|
|
p = nextSibling(p);
|
|
while (p) {
|
|
String *pname;
|
|
pt = Getattr(p,"type");
|
|
if ((SwigType_type(pt) != T_VOID)) {
|
|
if (comma) Printf(func,",");
|
|
pname = Swig_cparm_name(p,i);
|
|
Printf(func,"%s", SwigType_rcaststr(pt, pname));
|
|
comma = 1;
|
|
i++;
|
|
}
|
|
p = nextSibling(p);
|
|
}
|
|
Printf(func,")");
|
|
Delete(nname);
|
|
return func;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_cconstructor_call()
|
|
*
|
|
* Creates a string that calls a C constructor function.
|
|
*
|
|
* (name *) calloc(1,sizeof(name));
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_cconstructor_call(String_or_char *name) {
|
|
DOH *func;
|
|
|
|
func = NewString("");
|
|
Printf(func,"(%s *) calloc(1, sizeof(%s))", name, name);
|
|
return func;
|
|
}
|
|
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_cppconstructor_call()
|
|
*
|
|
* Creates a string that calls a C function using the local variable rules
|
|
* defined above.
|
|
*
|
|
* name(arg0, arg1, arg2, ... argn)
|
|
*
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_cppconstructor_base_call(String_or_char *name, ParmList *parms, int skip_self) {
|
|
String *func;
|
|
String *nname;
|
|
int i = 0;
|
|
int comma = 0;
|
|
Parm *p = parms;
|
|
SwigType *pt;
|
|
if (skip_self) {
|
|
if (p) p = nextSibling(p);
|
|
i++;
|
|
}
|
|
nname = SwigType_namestr(name);
|
|
func = NewString("");
|
|
Printf(func,"new %s(", nname);
|
|
while (p) {
|
|
String *pname;
|
|
pt = Getattr(p,"type");
|
|
if ((SwigType_type(pt) != T_VOID)) {
|
|
if (comma) Printf(func,",");
|
|
if (!Getattr(p, "arg:byname")) {
|
|
pname = Swig_cparm_name(p,i);
|
|
i++;
|
|
} else {
|
|
if ((pname = Getattr(p, "value")))
|
|
pname = Copy(pname);
|
|
else
|
|
pname = Copy(Getattr(p, "name"));
|
|
}
|
|
Printf(func,"%s", SwigType_rcaststr(pt, pname));
|
|
comma = 1;
|
|
}
|
|
p = nextSibling(p);
|
|
}
|
|
Printf(func,")");
|
|
Delete(nname);
|
|
return func;
|
|
}
|
|
|
|
String *
|
|
Swig_cppconstructor_call(String_or_char *name, ParmList *parms) {
|
|
return Swig_cppconstructor_base_call(name, parms, 0);
|
|
}
|
|
|
|
String *
|
|
Swig_cppconstructor_nodirector_call(String_or_char *name, ParmList *parms) {
|
|
return Swig_cppconstructor_base_call(name, parms, 1);
|
|
}
|
|
|
|
String *
|
|
Swig_cppconstructor_director_call(String_or_char *name, ParmList *parms) {
|
|
return Swig_cppconstructor_base_call(name, parms, 0);
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_cdestructor_call()
|
|
*
|
|
* Creates a string that calls a C constructor function.
|
|
*
|
|
* free((char *) arg0);
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_cdestructor_call() {
|
|
String *func;
|
|
func = NewString("");
|
|
Printf(func,"free((char *) %s)", Swig_cparm_name(0,0));
|
|
return func;
|
|
}
|
|
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_cppdestructor_call()
|
|
*
|
|
* Creates a string that calls a C constructor function.
|
|
*
|
|
* delete arg0;
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_cppdestructor_call() {
|
|
String *func;
|
|
|
|
func = NewString("");
|
|
Printf(func,"delete %s", Swig_cparm_name(0,0));
|
|
return func;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_cmemberset_call()
|
|
*
|
|
* Generates a string that sets the name of a member in a C++ class or C struct.
|
|
*
|
|
* arg0->name = arg1
|
|
*
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self) {
|
|
String *func;
|
|
func = NewString("");
|
|
if (!self) self = NewString("(this)->");
|
|
else self = NewString(self);
|
|
Replaceall(self,"this",Swig_cparm_name(0,0));
|
|
if (SwigType_type(type) != T_ARRAY) {
|
|
Printf(func,"if (%s) %s%s = %s",Swig_cparm_name(0,0), self,name, Swig_wrapped_var_deref(type, Swig_cparm_name(0,1)));
|
|
}
|
|
Delete(self);
|
|
return(func);
|
|
}
|
|
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_cmemberget_call()
|
|
*
|
|
* Generates a string that sets the name of a member in a C++ class or C struct.
|
|
*
|
|
* arg0->name
|
|
*
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
String *
|
|
Swig_cmemberget_call(String_or_char *name, SwigType *t, String_or_char *self) {
|
|
String *func;
|
|
if (!self) self = NewString("(this)->");
|
|
else self = NewString(self);
|
|
Replaceall(self,"this",Swig_cparm_name(0,0));
|
|
func = NewString("");
|
|
Printf(func,"%s (%s%s)", Swig_wrapped_var_assign(t,""),self, name);
|
|
Delete(self);
|
|
return func;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_MethodToFunction(Node *n)
|
|
*
|
|
* Converts a C++ method node to a function accessor function.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
Swig_MethodToFunction(Node *n, String *classname, int flags) {
|
|
String *name, *qualifier;
|
|
ParmList *parms;
|
|
SwigType *type;
|
|
Parm *p;
|
|
String *self = 0;
|
|
|
|
/* If smart pointer, change self derefencing */
|
|
if (flags & CWRAP_SMART_POINTER) {
|
|
self = NewString("(*this)->");
|
|
}
|
|
/* If node is a member template expansion, we don't allow added code */
|
|
|
|
if (Getattr(n,"templatetype")) flags &= ~(CWRAP_EXTEND);
|
|
|
|
name = Getattr(n,"name");
|
|
qualifier = Getattr(n,"qualifier");
|
|
parms = CopyParmList(nonvoid_parms(Getattr(n,"parms")));
|
|
|
|
type = NewString(classname);
|
|
if (qualifier) {
|
|
SwigType_push(type,qualifier);
|
|
}
|
|
SwigType_add_pointer(type);
|
|
p = NewParm(type,"self");
|
|
Setattr(p,"hidden","1");
|
|
set_nextSibling(p,parms);
|
|
Delete(type);
|
|
|
|
/* Generate action code for the access */
|
|
if (!(flags & CWRAP_EXTEND)) {
|
|
Setattr(n,"wrap:action", Swig_cresult(Getattr(n,"type"),"result", Swig_cmethod_call(name,p,self)));
|
|
} else {
|
|
String *code;
|
|
String *mangled;
|
|
String *membername = Swig_name_member(classname, name);
|
|
mangled = Swig_name_mangle(membername);
|
|
|
|
code = Getattr(n,"code");
|
|
type = Getattr(n,"type");
|
|
|
|
/* Check if the method is overloaded. If so, and it has code attached, we append an extra suffix
|
|
to avoid a name-clash in the generated wrappers. This allows overloaded methods to be defined
|
|
in C. */
|
|
|
|
if (Getattr(n,"sym:overloaded") && code) {
|
|
Append(mangled,Getattr(n,"sym:overname"));
|
|
}
|
|
|
|
Setattr(n,"wrap:action", Swig_cresult(Getattr(n,"type"),"result", Swig_cfunction_call(mangled,p)));
|
|
|
|
/* See if there is any code that we need to emit */
|
|
if (code) {
|
|
String *body;
|
|
String *tmp = NewStringf("%s(%s)", mangled, ParmList_str(p));
|
|
body = SwigType_str(type,tmp);
|
|
Delete(tmp);
|
|
Printv(body,code,"\n",NIL);
|
|
Setattr(n,"wrap:code",body);
|
|
}
|
|
Delete(membername);
|
|
Delete(mangled);
|
|
}
|
|
Setattr(n,"parms",p);
|
|
Delete(p);
|
|
Delete(self);
|
|
return SWIG_OK;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_methodclass()
|
|
*
|
|
* This function returns the class node for a given method or class.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
Node*
|
|
Swig_methodclass(Node *n) {
|
|
Node* type = Getattr(n, "nodeType");
|
|
if (!Cmp(type, "class")) return n;
|
|
return Getattr(n, "parentNode");
|
|
}
|
|
|
|
int
|
|
Swig_directorbase(Node *n) {
|
|
Node *classNode = Swig_methodclass(n);
|
|
return (classNode && (Getattr(classNode, "directorBase") != 0));
|
|
}
|
|
|
|
int
|
|
Swig_directorclass(Node *n) {
|
|
Node *classNode = Swig_methodclass(n);
|
|
assert(classNode != 0);
|
|
return (Getattr(classNode, "vtable") != 0);
|
|
}
|
|
|
|
int
|
|
Swig_directormethod(Node *n) {
|
|
Node *classNode = Swig_methodclass(n);
|
|
if (classNode) {
|
|
Node *vtable = Getattr(classNode, "vtable");
|
|
if (vtable) {
|
|
String *name = Getattr(n, "name");
|
|
String *decl = Getattr(n, "decl");
|
|
String *method_id = NewStringf("%s|%s", name, decl);
|
|
Hash *item = Getattr(vtable, method_id);
|
|
Delete(method_id);
|
|
if (item) {
|
|
return (Getattr(item, "director") != 0);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Node *
|
|
Swig_directormap(Node *module, String *type) {
|
|
int is_void = !Cmp(type, "void");
|
|
if (!is_void && module) {
|
|
/* ?? follow the inheritance hierarchy? */
|
|
|
|
String* base = SwigType_base(type);
|
|
|
|
Node *directormap = Getattr(module, "wrap:directormap");
|
|
if (directormap)
|
|
return Getattr(directormap, base);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_ConstructorToFunction()
|
|
*
|
|
* This function creates a C wrapper for a C constructor function.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
Swig_ConstructorToFunction(Node *n, String *classname,
|
|
String *none_comparison, String *director_ctor, int cplus, int flags)
|
|
{
|
|
ParmList *parms;
|
|
Parm *prefix_args;
|
|
Parm *postfix_args;
|
|
Parm *p;
|
|
ParmList *directorparms;
|
|
SwigType *type;
|
|
String *membername;
|
|
String *mangled;
|
|
Node *classNode;
|
|
int use_director;
|
|
|
|
classNode = Swig_methodclass(n);
|
|
use_director = Swig_directorclass(n);
|
|
|
|
membername = Swig_name_construct(classname);
|
|
mangled = Swig_name_mangle(membername);
|
|
|
|
parms = CopyParmList(nonvoid_parms(Getattr(n,"parms")));
|
|
|
|
/* Prepend the list of prefix_args (if any) */
|
|
prefix_args = Getattr(n,"director:prefix_args");
|
|
if (prefix_args != NIL) {
|
|
Parm *p2, *p3;
|
|
|
|
directorparms = CopyParmList(prefix_args);
|
|
for (p = directorparms; nextSibling(p); p = nextSibling(p));
|
|
for (p2 = parms; p2; p2 = nextSibling(p2)) {
|
|
p3 = CopyParm(p2);
|
|
set_nextSibling(p, p3);
|
|
p = p3;
|
|
}
|
|
} else
|
|
directorparms = parms;
|
|
|
|
postfix_args = Getattr(n,"director:postfix_args");
|
|
if (postfix_args != NIL) {
|
|
Parm *p2, *p3, *p4;
|
|
|
|
if (prefix_args == NIL) /* no prefix args from above. */
|
|
directorparms = CopyParmList(parms);
|
|
|
|
if (directorparms != NIL) {
|
|
p2 = directorparms;
|
|
for ( ; nextSibling(p2); p2 = nextSibling(p2));
|
|
for (p3 = postfix_args; p3; p3 = nextSibling(p3)) {
|
|
p4 = CopyParm(p3);
|
|
set_nextSibling(p2, p4);
|
|
p2 = p4;
|
|
}
|
|
} else
|
|
directorparms = CopyParmList(postfix_args);
|
|
}
|
|
|
|
type = NewString(classname);
|
|
SwigType_add_pointer(type);
|
|
|
|
if (flags & CWRAP_EXTEND) {
|
|
String *code = Getattr(n,"code");
|
|
if (code) {
|
|
String *wrap, *s;
|
|
if (Getattr(n,"sym:overloaded") && code) {
|
|
Append(mangled,Getattr(n,"sym:overname"));
|
|
}
|
|
s = NewStringf("%s(%s)", mangled, ParmList_str(parms));
|
|
wrap = SwigType_str(type,s);
|
|
Delete(s);
|
|
Printv(wrap,code,"\n",NIL);
|
|
Setattr(n,"wrap:code",wrap);
|
|
Delete(wrap);
|
|
}
|
|
Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(mangled,parms)));
|
|
} else {
|
|
if (cplus) {
|
|
/* if a C++ director class exists, create it rather than the original class */
|
|
if (use_director) {
|
|
int abstract = Getattr(n, "abstract") != 0;
|
|
Node *parent = Swig_methodclass(n);
|
|
String *name = Getattr(parent, "sym:name");
|
|
String* directorname = NewStringf("SwigDirector_%s", name);
|
|
String* action = NewString("");
|
|
String* tmp_none_comparison = Copy(none_comparison);
|
|
String* director_call;
|
|
String* nodirector_call;
|
|
|
|
Replaceall( tmp_none_comparison, "$arg", "arg1" );
|
|
|
|
director_call = Swig_cppconstructor_director_call(directorname, directorparms);
|
|
nodirector_call = Swig_cppconstructor_nodirector_call(classname, parms);
|
|
|
|
if (abstract) {
|
|
/* whether or not the abstract class has been subclassed in python,
|
|
* create a director instance (there's no way to create a normal
|
|
* instance). if any of the pure virtual methods haven't been
|
|
* implemented in the target language, calls to those methods will
|
|
* generate Swig::DirectorPureVirtualException exceptions.
|
|
*/
|
|
Printv(action, Swig_cresult(type, "result", director_call), NIL);
|
|
} else {
|
|
/* (scottm): The code for creating a new director is now a string
|
|
template that gets passed in via the director_ctor argument.
|
|
|
|
$comparison : an 'if' comparison from none_comparison
|
|
$director_new: Call new for director class
|
|
$nondirector_new: Call new for non-director class
|
|
*/
|
|
Printv(action, director_ctor, NIL);
|
|
Replaceall( action, "$comparison", tmp_none_comparison);
|
|
Replaceall( action, "$director_new",
|
|
Swig_cresult(type, "result", director_call) );
|
|
Replaceall( action, "$nondirector_new",
|
|
Swig_cresult(type, "result", nodirector_call) );
|
|
}
|
|
Setattr(n, "wrap:action", action);
|
|
Delete(tmp_none_comparison);
|
|
Delete(action);
|
|
Delete(directorname);
|
|
} else {
|
|
Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cppconstructor_call(classname,parms)));
|
|
}
|
|
} else {
|
|
Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cconstructor_call(classname)));
|
|
}
|
|
}
|
|
Setattr(n,"type",type);
|
|
Setattr(n,"parms", parms);
|
|
Delete(type);
|
|
if (directorparms != parms)
|
|
Delete(directorparms);
|
|
Delete(parms);
|
|
Delete(mangled);
|
|
Delete(membername);
|
|
return SWIG_OK;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_DestructorToFunction()
|
|
*
|
|
* This function creates a C wrapper for a destructor function.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags)
|
|
{
|
|
SwigType *type;
|
|
Parm *p;
|
|
|
|
type = NewString(classname);
|
|
SwigType_add_pointer(type);
|
|
p = NewParm(type,"self");
|
|
Delete(type);
|
|
type = NewString("void");
|
|
|
|
if (flags & CWRAP_EXTEND) {
|
|
String *membername, *mangled, *code;
|
|
membername = Swig_name_destroy(classname);
|
|
mangled = Swig_name_mangle(membername);
|
|
code = Getattr(n,"code");
|
|
if (code) {
|
|
String *s = NewStringf("void %s(%s)", mangled, ParmList_str(p));
|
|
Printv(s,code,"\n",NIL);
|
|
Setattr(n,"wrap:code",s);
|
|
Delete(s);
|
|
}
|
|
Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cfunction_call(mangled,p)));
|
|
Delete(membername);
|
|
Delete(mangled);
|
|
} else {
|
|
if (cplus) {
|
|
String* action = NewString("");
|
|
Printf(action, "%s;\n", Swig_cppdestructor_call());
|
|
Setattr(n,"wrap:action", action);
|
|
} else {
|
|
Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cdestructor_call()));
|
|
}
|
|
}
|
|
Setattr(n,"type",type);
|
|
Setattr(n,"parms", p);
|
|
Delete(type);
|
|
Delete(p);
|
|
return SWIG_OK;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_MembersetToFunction()
|
|
*
|
|
* This function creates a C wrapper for setting a structure member.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
Swig_MembersetToFunction(Node *n, String *classname, int flags) {
|
|
String *name;
|
|
ParmList *parms;
|
|
Parm *p;
|
|
SwigType *t;
|
|
SwigType *ty;
|
|
SwigType *type;
|
|
String *membername;
|
|
String *mangled;
|
|
String *self= 0;
|
|
|
|
if (flags & CWRAP_SMART_POINTER) {
|
|
self = NewString("(*this)->");
|
|
}
|
|
|
|
name = Getattr(n,"name");
|
|
type = Getattr(n,"type");
|
|
|
|
membername = Swig_name_member(classname, Swig_name_set(name));
|
|
mangled = Swig_name_mangle(membername);
|
|
|
|
t = NewString(classname);
|
|
SwigType_add_pointer(t);
|
|
parms = NewParm(t,"self");
|
|
Delete(t);
|
|
|
|
ty = Swig_wrapped_var_type(type);
|
|
p = NewParm(ty,name);
|
|
set_nextSibling(parms,p);
|
|
|
|
/* If the type is a pointer or reference. We mark it with a special wrap:disown attribute */
|
|
if (SwigType_check_decl(type,"p.")) {
|
|
Setattr(p,"wrap:disown","1");
|
|
}
|
|
Delete(p);
|
|
|
|
if (flags & CWRAP_EXTEND) {
|
|
String *code = Getattr(n,"code");
|
|
if (code) {
|
|
String *s = NewStringf("void %s(%s)", mangled, ParmList_str(parms));
|
|
Printv(s,code,"\n",NIL);
|
|
Setattr(n,"wrap:code",s);
|
|
Delete(s);
|
|
}
|
|
Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cfunction_call(mangled,parms)));
|
|
} else {
|
|
Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cmemberset_call(name,type,self)));
|
|
}
|
|
Setattr(n,"type","void");
|
|
Setattr(n,"parms", parms);
|
|
Delete(parms);
|
|
Delete(ty);
|
|
Delete(membername);
|
|
Delete(mangled);
|
|
Delete(self);
|
|
return SWIG_OK;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_MembergetToFunction()
|
|
*
|
|
* This function creates a C wrapper for setting a structure member.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
Swig_MembergetToFunction(Node *n, String *classname, int flags) {
|
|
String *name;
|
|
ParmList *parms;
|
|
SwigType *t;
|
|
SwigType *ty;
|
|
SwigType *type;
|
|
String *membername;
|
|
String *mangled;
|
|
String *self = 0;
|
|
|
|
if (flags & CWRAP_SMART_POINTER) {
|
|
self = NewString("(*this)->");
|
|
}
|
|
|
|
name = Getattr(n,"name");
|
|
type = Getattr(n,"type");
|
|
|
|
membername = Swig_name_member(classname, Swig_name_get(name));
|
|
mangled = Swig_name_mangle(membername);
|
|
|
|
t = NewString(classname);
|
|
SwigType_add_pointer(t);
|
|
parms = NewParm(t,"self");
|
|
Delete(t);
|
|
|
|
ty = Swig_wrapped_var_type(type);
|
|
if (flags & CWRAP_EXTEND) {
|
|
String *code = Getattr(n,"code");
|
|
if (code) {
|
|
String *tmp = NewStringf("%s(%s)", mangled, ParmList_str(parms));
|
|
String *s = SwigType_str(ty,tmp);
|
|
Delete(tmp);
|
|
Printv(s,code,"\n",NIL);
|
|
Setattr(n,"wrap:code",s);
|
|
Delete(s);
|
|
}
|
|
Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_cfunction_call(mangled,parms)));
|
|
} else {
|
|
Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_cmemberget_call(name,type,self)));
|
|
}
|
|
Setattr(n,"type",ty);
|
|
Setattr(n,"parms", parms);
|
|
Delete(parms);
|
|
Delete(ty);
|
|
Delete(membername);
|
|
Delete(mangled);
|
|
return SWIG_OK;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_VarsetToFunction()
|
|
*
|
|
* This function creates a C wrapper for setting a global variable.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
Swig_VarsetToFunction(Node *n) {
|
|
String *name,*nname;
|
|
ParmList *parms;
|
|
SwigType *type, *ty;
|
|
|
|
name = Getattr(n,"name");
|
|
type = Getattr(n,"type");
|
|
|
|
nname = SwigType_namestr(name);
|
|
|
|
ty = Swig_wrapped_var_type(type);
|
|
parms = NewParm(ty,"value");
|
|
Delete(ty);
|
|
|
|
Setattr(n,"wrap:action", NewStringf("%s = %s;\n", nname, Swig_wrapped_var_deref(type,Swig_cparm_name(0,0))));
|
|
Setattr(n,"type","void");
|
|
Setattr(n,"parms",parms);
|
|
Delete(parms);
|
|
Delete(nname);
|
|
return SWIG_OK;
|
|
}
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* Swig_VargetToFunction()
|
|
*
|
|
* This function creates a C wrapper for getting a global variable.
|
|
* ----------------------------------------------------------------------------- */
|
|
|
|
int
|
|
Swig_VargetToFunction(Node *n) {
|
|
String *name, *nname;
|
|
SwigType *type, *ty;
|
|
|
|
name = Getattr(n,"name");
|
|
type = Getattr(n,"type");
|
|
|
|
nname = SwigType_namestr(name);
|
|
ty = Swig_wrapped_var_type(type);
|
|
|
|
Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_wrapped_var_assign(type,nname)));
|
|
Setattr(n,"type",ty);
|
|
Delattr(n,"parms");
|
|
Delete(nname);
|
|
Delete(ty);
|
|
return SWIG_OK;
|
|
}
|