/* ----------------------------------------------------------------------------- * Swig_cargs() * * Emit all of the local variables for a list of parameters. Returns the * number of parameters. * Default values for the local variables are only emitted if the compact default * argument behaviour is required. * ----------------------------------------------------------------------------- */ int Swig_cargs(Wrapper *w, ParmList *p) { int i = 0; int compactdefargs = ParmList_is_compactdefargs(p); while (p != 0) { String *lname = Swig_cparm_name(p, i); SwigType *pt = Getattr(p, k_type); if ((SwigType_type(pt) != T_VOID)) { String *local = 0; String *type = Getattr(p, k_type); /* default values only emitted if in compact default args mode */ String *pvalue = (compactdefargs) ? Getattr(p, k_value) : 0; SwigType *altty = SwigType_alttype(type, 0); int tycode = SwigType_type(type); if (tycode == T_REFERENCE) { if (pvalue) { SwigType *tvalue; String *defname, *defvalue, *rvalue, *qvalue; rvalue = SwigType_typedef_resolve_all(pvalue); qvalue = SwigType_typedef_qualified(rvalue); defname = NewStringf("%s_defvalue", lname); tvalue = Copy(type); SwigType_del_reference(tvalue); tycode = SwigType_type(tvalue); if (tycode != T_USER) { /* plain primitive type, we copy the the def value */ String *lstr = SwigType_lstr(tvalue, defname); defvalue = NewStringf("%s = %s", lstr, qvalue); Delete(lstr); } else { /* user type, we copy the reference value */ String *str = SwigType_str(type, defname); defvalue = NewStringf("%s = %s", str, qvalue); Delete(str); } Wrapper_add_localv(w, defname, defvalue, NIL); Delete(tvalue); Delete(rvalue); Delete(qvalue); Delete(defname); Delete(defvalue); } } else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING))) { pvalue = (String *) "0"; } if (!altty) { local = Swig_clocal(pt, lname, pvalue); } else { local = Swig_clocal(altty, lname, pvalue); Delete(altty); } Wrapper_add_localv(w, lname, local, NIL); Delete(local); i++; } Delete(lname); p = nextSibling(p); } return (i); }
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; }
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; }
static Parm *nonvoid_parms(Parm *p) { if (p) { SwigType *t = Getattr(p,"type"); if (SwigType_type(t) == T_VOID) return 0; } return p; }
String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_char *decl) { String *fcall; fcall = NewStringEmpty(); switch (SwigType_type(t)) { case T_VOID: break; case T_REFERENCE: { String *str = SwigType_str(t, "_result_ref"); Printf(fcall, "{\n"); Printf(fcall, "%s = ", str); Delete(str); } break; case T_USER: Printf(fcall, "%s = ", name); break; default: /* Normal return value */ { String *lstr = SwigType_lstr(t, 0); Printf(fcall, "%s = (%s)", name, lstr); Delete(lstr); } break; } /* Now print out function call */ Append(fcall, decl); /* A sick hack */ { char *c = Char(decl) + Len(decl) - 1; if (!((*c == ';') || (*c == '}'))) Append(fcall, ";"); } if (SwigType_type(t) == T_REFERENCE) { String *lstr = SwigType_lstr(t, 0); Printf(fcall, "\n%s = (%s) &_result_ref;\n", name, lstr); Append(fcall, "}"); Delete(lstr); } return fcall; }
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); }
String *Swig_cfunction_call(String_or_char *name, ParmList *parms) { String *func; int i = 0; int comma = 0; Parm *p = parms; String *nname; func = NewStringEmpty(); nname = SwigType_namestr(name); /* SWIGTEMPLATEDISAMBIGUATOR is compiler dependent (swiglabels.swg), - SUN Studio 9 requires 'template', - gcc-3.4 forbids the use of 'template'. the rest seems not caring very much, */ if (SwigType_istemplate(name)) { String *prefix = Swig_scopename_prefix(nname); if (!prefix || Len(prefix) == 0) { Printf(func, "%s(", nname); } else { String *last = Swig_scopename_last(nname); Printf(func, "%s::SWIGTEMPLATEDISAMBIGUATOR %s(", prefix, last); Delete(last); } Delete(prefix); } else { Printf(func, "%s(", nname); } Delete(nname); while (p) { SwigType *pt = Getattr(p, k_type); if ((SwigType_type(pt) != T_VOID)) { SwigType *rpt = SwigType_typedef_resolve_all(pt); String *pname = Swig_cparm_name(p, i); String *rcaststr = SwigType_rcaststr(rpt, pname); if (comma) { Printv(func, ",", rcaststr, NIL); } else { Append(func, rcaststr); } Delete(rpt); Delete(pname); Delete(rcaststr); comma = 1; i++; } p = nextSibling(p); } Append(func, ")"); return func; }
void cparse_normalize_void(Node *n) { String *decl = Getattr(n, "decl"); Parm *parms = Getattr(n, "parms"); if (SwigType_isfunction(decl)) { if ((ParmList_len(parms) == 1) && (SwigType_type(Getattr(parms, "type")) == T_VOID)) { Replaceall(decl, "f(void).", "f()."); Delattr(n, "parms"); } } }
int ParmList_numrequired(ParmList *p) { int i = 0; while (p) { SwigType *t = Getattr(p,"type"); String *value = Getattr(p,"value"); if (value) return i; if (!(SwigType_type(t) == T_VOID)) i++; else break; p = nextSibling(p); } return i; }
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); }
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; }
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; }
String *Swig_cppconstructor_base_call(const_String_or_char_ptr 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 = NewStringEmpty(); Printf(func, "new %s(", nname); while (p) { pt = Getattr(p, "type"); if ((SwigType_type(pt) != T_VOID)) { String *rcaststr = 0; String *pname = 0; if (comma) Append(func, ","); if (!Getattr(p, "arg:byname")) { pname = Swig_cparm_name(p, i); i++; } else { pname = Getattr(p, "value"); if (pname) pname = Copy(pname); else pname = Copy(Getattr(p, "name")); } rcaststr = SwigType_rcaststr(pt, pname); Append(func, rcaststr); Delete(rcaststr); comma = 1; Delete(pname); } p = nextSibling(p); } Append(func, ")"); Delete(nname); return func; }
static String *Swig_clocal(SwigType *t, const String_or_char *name, const String_or_char *value) { String *decl; decl = NewStringEmpty(); switch (SwigType_type(t)) { case T_REFERENCE: if (value) { String *lstrname = SwigType_lstr(t, name); String *lstr = SwigType_lstr(t, 0); Printf(decl, "%s = (%s) &%s_defvalue", lstrname, lstr, name); Delete(lstrname); Delete(lstr); } else { String *lstrname = SwigType_lstr(t, name); Printf(decl, "%s = 0", lstrname); Delete(lstrname); } break; case T_VOID: break; case T_VARARGS: Printf(decl, "void *%s = 0", name); break; default: if (value) { String *lcaststr = SwigType_lcaststr(t, value); String *lstr = SwigType_lstr(t, 0); String *lstrn = SwigType_lstr(t, name); Printf(decl, "%s = (%s) %s", lstrn, lstr, lcaststr); Delete(lcaststr); Delete(lstr); Delete(lstrn); } else { String *lstrname = SwigType_lstr(t, name); Append(decl, lstrname); Delete(lstrname); } } return decl; }
String *Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self, int varcref) { String *func; String *pname0 = Swig_cparm_name(0, 0); String *pname1 = Swig_cparm_name(0, 1); func = NewStringEmpty(); if (!self) self = NewString("(this)->"); else self = NewString(self); Replaceall(self, "this", pname0); if (SwigType_type(type) != T_ARRAY) { if (!Strstr(type, "enum $unnamed")) { String *dref = Swig_wrapped_var_deref(type, pname1, varcref); Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref); Delete(dref); } else { Printf(func, "if (%s && sizeof(int) == sizeof(%s%s)) *(int*)(void*)&(%s%s) = %s", pname0, self, name, self, name, pname1); } } Delete(self); Delete(pname0); Delete(pname1); return (func); }
int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director) { String *name, *qualifier; ParmList *parms; SwigType *type; Parm *p; String *self = 0; /* If smart pointer, change self dereferencing */ if (flags & CWRAP_SMART_POINTER) { self = NewString("(*this)->"); } /* If node is a member template expansion, we don't allow added code */ if (Getattr(n, k_templatetype)) flags &= ~(CWRAP_EXTEND); name = Getattr(n, k_name); qualifier = Getattr(n, k_qualifier); parms = CopyParmList(nonvoid_parms(Getattr(n, k_parms))); type = NewString(classname); if (qualifier) { SwigType_push(type, qualifier); } SwigType_add_pointer(type); p = NewParm(type, k_self); Setattr(p, k_self, "1"); Setattr(p, k_hidden, "1"); /* Disable the 'this' ownership in 'self' to manage inplace operations like: A& A::operator+=(int i) { ...; return *this;} Here the 'self' parameter ownership needs to be disabled since there could be two objects sharing the same 'this' pointer: the input and the result one. And worse, the pointer could be deleted in one of the objects (input), leaving the other (output) with just a seg. fault to happen. To avoid the previous problem, use %feature("self:disown") *::operator+=; %feature("new") *::operator+=; These two lines just transfer the ownership of the 'this' pointer from the input to the output wrapping object. This happens in python, but may also happens in other target languages. */ if (GetFlag(n, "feature:self:disown")) { Setattr(p, k_wrapdisown, "1"); } set_nextSibling(p, parms); Delete(type); /* Generate action code for the access */ if (!(flags & CWRAP_EXTEND)) { String *explicit_qualifier = 0; String *call = 0; String *cres = 0; String *explicitcall_name = 0; int pure_virtual = !(Cmp(Getattr(n, k_storage), "virtual")) && !(Cmp(Getattr(n, k_value), "0")); /* Call the explicit method rather than allow for a polymorphic call */ if ((flags & CWRAP_DIRECTOR_TWO_CALLS) || (flags & CWRAP_DIRECTOR_ONE_CALL)) { String *access = Getattr(n, "access"); if (access && (Cmp(access, "protected") == 0)) { /* If protected access (can only be if a director method) then call the extra public accessor method (language module must provide this) */ String *explicit_qualifier_tmp = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), k_qname)); explicitcall_name = NewStringf("%sSwigPublic", name); explicit_qualifier = NewStringf("SwigDirector_%s", explicit_qualifier_tmp); Delete(explicit_qualifier_tmp); } else { explicit_qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), k_qname)); } } call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type); cres = Swig_cresult(Getattr(n, k_type), k_result, call); if (pure_virtual && is_director && (flags & CWRAP_DIRECTOR_TWO_CALLS)) { String *qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), k_qname)); Delete(cres); cres = NewStringf("Swig::DirectorPureVirtualException::raise(\"%s::%s\");", qualifier, name); Delete(qualifier); } if (flags & CWRAP_DIRECTOR_TWO_CALLS) { /* Create two method calls, one to call the explicit method, the other a normal polymorphic function call */ String *cres_both_calls = NewStringf(""); String *call_extra = Swig_cmethod_call(name, p, self, 0, director_type); String *cres_extra = Swig_cresult(Getattr(n, k_type), k_result, call_extra); Printv(cres_both_calls, "if (upcall) {\n", cres, "\n", "} else {", cres_extra, "\n}", NIL); Setattr(n, k_wrapaction, cres_both_calls); Delete(cres_extra); Delete(call_extra); Delete(cres_both_calls); } else { Setattr(n, k_wrapaction, cres); } Delete(explicitcall_name); Delete(call); Delete(cres); Delete(explicit_qualifier); } else { /* Methods with default arguments are wrapped with additional methods for each default argument, * however, only one extra %extend method is generated. */ String *defaultargs = Getattr(n, k_defaultargs); String *code = Getattr(n, k_code); String *cname = Getattr(n, k_classname) ? Getattr(n, k_classname) : classname; String *membername = Swig_name_member(cname, name); String *mangled = Swig_name_mangle(membername); int is_smart_pointer = flags & CWRAP_SMART_POINTER; type = Getattr(n, k_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, k_symoverloaded) && code) { Append(mangled, Getattr(defaultargs ? defaultargs : n, k_symovername)); } /* See if there is any code that we need to emit */ if (!defaultargs && code && !is_smart_pointer) { Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, k_self); } if (is_smart_pointer) { int i = 0; Parm *pp = p; String *func = NewStringf("%s(", mangled); String *cres; if (Cmp(Getattr(n, k_storage), k_static) != 0) { String *pname = Swig_cparm_name(pp, i); String *ctname = SwigType_namestr(cname); String *fadd = NewStringf("(%s*)(%s)->operator ->()", ctname, pname); Append(func, fadd); Delete(ctname); Delete(fadd); Delete(pname); pp = nextSibling(pp); if (pp) Append(func, ","); } else { pp = nextSibling(pp); } ++i; while (pp) { SwigType *pt = Getattr(pp, k_type); if ((SwigType_type(pt) != T_VOID)) { String *pname = Swig_cparm_name(pp, i++); String *rcaststr = SwigType_rcaststr(pt, pname); Append(func, rcaststr); Delete(rcaststr); Delete(pname); pp = nextSibling(pp); if (pp) Append(func, ","); } } Append(func, ")"); cres = Swig_cresult(Getattr(n, k_type), k_result, func); Setattr(n, k_wrapaction, cres); Delete(cres); } else { String *call = Swig_cfunction_call(mangled, p); String *cres = Swig_cresult(Getattr(n, k_type), k_result, call); Setattr(n, k_wrapaction, cres); Delete(call); Delete(cres); } Delete(membername); Delete(mangled); } Setattr(n, k_parms, p); Delete(p); Delete(self); Delete(parms); return SWIG_OK; }
static String *Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self, String *explicit_qualifier, SwigType *director_type) { String *func, *nname; int i = 0; Parm *p = parms; SwigType *pt; int comma = 0; func = NewStringEmpty(); if (!p) return func; if (!self) self = (char *) "(this)->"; Append(func, self); if (SwigType_istemplate(name) && (strncmp(Char(name), "operator ", 9) == 0)) { /* fix for template + operators and compilers like gcc 3.3.5 */ String *tprefix = SwigType_templateprefix(name); nname = tprefix; } else { nname = SwigType_namestr(name); } if (director_type) { const char *pname = "darg"; String *rcaststr = SwigType_rcaststr(director_type, pname); Replaceall(func, "this", rcaststr); Delete(rcaststr); } else { pt = Getattr(p, k_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")) { String *pname = Swig_cparm_name(p, 0); Replaceall(func, "this", pname); Delete(pname); } else { String *pname = Swig_cparm_name(p, 0); String *rcaststr = SwigType_rcaststr(pt, pname); Replaceall(func, "this", rcaststr); Delete(rcaststr); Delete(pname); } /* SWIGTEMPLATEDESIMBUAGATOR is compiler dependent (swiglabels.swg), - SUN Studio 9 requires 'template', - gcc-3.4 forbids the use of 'template' (correctly implementing the ISO C++ standard) the others don't seem to care, */ if (SwigType_istemplate(name)) Printf(func, "SWIGTEMPLATEDISAMBIGUATOR "); if (explicit_qualifier) { Printv(func, explicit_qualifier, "::", NIL); } } Printf(func, "%s(", nname); i++; p = nextSibling(p); while (p) { pt = Getattr(p, k_type); if ((SwigType_type(pt) != T_VOID)) { String *pname = Swig_cparm_name(p, i); String *rcaststr = SwigType_rcaststr(pt, pname); if (comma) Append(func, ","); Append(func, rcaststr); Delete(rcaststr); Delete(pname); comma = 1; i++; } p = nextSibling(p); } Append(func, ")"); Delete(nname); return func; }
/* ----------------------------------------------------------------------------- * Swig_cargs() * * Emit all of the local variables for a list of parameters. Returns the * number of parameters. * Default values for the local variables are only emitted if the compact default * argument behaviour is required. * ----------------------------------------------------------------------------- */ int Swig_cargs(Wrapper *w, ParmList *p) { int i = 0; int compactdefargs = ParmList_is_compactdefargs(p); while (p != 0) { String *lname = Swig_cparm_name(p, i); SwigType *pt = Getattr(p, "type"); if ((SwigType_type(pt) != T_VOID)) { String *local = 0; String *type = Getattr(p, "type"); /* default values only emitted if in compact default args mode */ String *pvalue = (compactdefargs) ? Getattr(p, "value") : 0; /* When using compactdefaultargs, the code generated initialises a variable via a constructor call that accepts the * default value as a parameter. The default constructor is not called and therefore SwigValueWrapper is not needed. */ SwigType *altty = pvalue ? 0 : SwigType_alttype(type, 0); int tycode = SwigType_type(type); if (tycode == T_REFERENCE) { if (pvalue) { SwigType *tvalue; String *defname, *defvalue, *rvalue, *qvalue; rvalue = SwigType_typedef_resolve_all(pvalue); qvalue = SwigType_typedef_qualified(rvalue); defname = NewStringf("%s_defvalue", lname); tvalue = Copy(type); SwigType_del_reference(tvalue); tycode = SwigType_type(tvalue); if (tycode != T_USER) { /* plain primitive type, we copy the the def value */ String *lstr = SwigType_lstr(tvalue, defname); defvalue = NewStringf("%s = %s", lstr, qvalue); Delete(lstr); } else { /* user type, we copy the reference value */ String *str = SwigType_str(type, defname); defvalue = NewStringf("%s = %s", str, qvalue); Delete(str); } Wrapper_add_localv(w, defname, defvalue, NIL); Delete(tvalue); Delete(rvalue); Delete(qvalue); Delete(defname); Delete(defvalue); } } else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING))) { pvalue = (String *) "0"; } if (!altty) { local = Swig_clocal(pt, lname, pvalue); } else { local = Swig_clocal(altty, lname, pvalue); Delete(altty); } Wrapper_add_localv(w, lname, local, NIL); Delete(local); i++; } Delete(lname); p = nextSibling(p); } return (i); }