Merge branch 'master' of https://github.com/swig/swig into Cmerge

This commit is contained in:
Joey Yakimowich-Payne 2023-02-18 00:05:36 -07:00
commit 5a06ca1ed7
No known key found for this signature in database
GPG key ID: 6BFE655FA5ABD1E1
312 changed files with 10813 additions and 7218 deletions

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* allocate.cxx
*

View file

@ -212,7 +212,7 @@ String* get_c_proxy_name(Node* n) {
String *nspace = Getattr(n, "sym:nspace");
if (nspace) {
scoped_dohptr nspace_mangled(Swig_string_mangle(nspace));
scoped_dohptr nspace_mangled(Swig_name_mangle_string(nspace));
proxyname = NewStringf("%s_%s", (DOH*)nspace_mangled, symname);
} else {
proxyname = Swig_name_type(symname);
@ -1559,7 +1559,7 @@ public:
if (GetFlag(parentNode(n), "feature:nspace")) {
scopename_prefix = Swig_scopename_prefix(Getattr(n, "name"));
if (scopename_prefix) {
scoped_dohptr mangled_prefix(Swig_string_mangle(scopename_prefix));
scoped_dohptr mangled_prefix(Swig_name_mangle_string(scopename_prefix));
scopename_prefix = mangled_prefix;
}
}
@ -1766,7 +1766,7 @@ public:
} else if (strcmp(argv[i], "-namespace") == 0) {
if (argv[i + 1]) {
ns_cxx = NewString(argv[i + 1]);
ns_prefix = Swig_string_mangle(ns_cxx);
ns_prefix = Swig_name_mangle_string(ns_cxx);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
@ -2136,7 +2136,7 @@ public:
s += len_enum_prefix;
Printf(result, "e%s", s);
} else {
Printf(result, "%s", Char(Swig_name_mangle(SwigType_base(type))));
Printf(result, "%s", Char(Swig_name_mangle_string(SwigType_base(type))));
}
Delete(prefix);

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* contract.cxx
*

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* csharp.cxx
*
@ -399,7 +399,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGCSHARP\n#define SWIGCSHARP\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "CSHARP");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@ -1744,35 +1744,32 @@ public:
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
String *classname = SwigType_namestr(c_classname);
String *baseclassname = SwigType_namestr(c_baseclassname);
if (smart) {
SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname);
String *smartnamestr = SwigType_namestr(smart);
String *bsmartnamestr = SwigType_namestr(smart);
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
String *bsmartnamestr = SwigType_namestr(bsmart);
Printv(upcasts_code,
"SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
" return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
"}\n", "\n", NIL);
Delete(rbaseclassname);
Delete(rclassname);
Delete(bsmartnamestr);
Delete(smartnamestr);
Delete(bsmart);
} else {
String *classname = SwigType_namestr(c_classname);
String *baseclassname = SwigType_namestr(c_baseclassname);
Printv(upcasts_code,
"SWIGEXPORT ", baseclassname, " * SWIGSTDCALL ", wname, "(", classname, " *jarg1) {\n",
" return (", baseclassname, " *)jarg1;\n"
"}\n", "\n", NIL);
Delete(baseclassname);
Delete(classname);
}
Delete(baseclassname);
Delete(classname);
Delete(wname);
}
@ -2976,7 +2973,7 @@ public:
/* A C# HandleRef is used for all classes in the SWIG intermediary class.
* The intermediary class methods are thus mangled when overloaded to give
* a unique name. */
String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name"));
String *overloaded_name = Copy(Getattr(n, "sym:name"));
if (Getattr(n, "sym:overloaded")) {
Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
@ -3820,7 +3817,7 @@ public:
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *returntype = Getattr(n, "type");
String *overloaded_name = getOverloadedName(n);
String *overloaded_name = 0;
String *storage = Getattr(n, "storage");
String *value = Getattr(n, "value");
String *decl = Getattr(n, "decl");
@ -3842,7 +3839,6 @@ public:
String *qualified_name = NewStringf("%s::%s", dirclassname, name);
SwigType *c_ret_type = NULL;
String *jupcall_args = NewString("");
String *imclass_dmethod;
String *callback_typedef_parms = NewString("");
String *delegate_parms = NewString("");
String *proxy_method_types = NewString("");
@ -3856,7 +3852,8 @@ public:
// we're consistent with the sym:overload name in functionWrapper. (?? when
// does the overloaded method name get set?)
imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name));
if (!ignored_method)
overloaded_name = getOverloadedName(n);
qualified_return = SwigType_rcaststr(returntype, "c_result");
@ -3909,28 +3906,28 @@ public:
}
}
/* Create the intermediate class wrapper */
tm = Swig_typemap_lookup("imtype", n, "", 0);
if (tm) {
String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
if (imtypeout)
tm = imtypeout;
const String *im_directoroutattributes = Getattr(n, "tmap:imtype:directoroutattributes");
if (im_directoroutattributes) {
Printf(callback_def, " %s\n", im_directoroutattributes);
if (!ignored_method)
Printf(director_delegate_definitions, " %s\n", im_directoroutattributes);
}
if (!ignored_method) {
/* Create the intermediate class wrapper */
tm = Swig_typemap_lookup("imtype", n, "", 0);
if (tm) {
String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
if (imtypeout)
tm = imtypeout;
const String *im_directoroutattributes = Getattr(n, "tmap:imtype:directoroutattributes");
if (im_directoroutattributes) {
Printf(callback_def, " %s\n", im_directoroutattributes);
if (!ignored_method)
Printf(director_delegate_definitions, " %s\n", im_directoroutattributes);
}
Printf(callback_def, " private %s SwigDirectorMethod%s(", tm, overloaded_name);
if (!ignored_method) {
Printf(callback_def, " private %s SwigDirectorMethod%s(", tm, overloaded_name);
const String *csdirectordelegatemodifiers = Getattr(n, "feature:csdirectordelegatemodifiers");
String *modifiers = (csdirectordelegatemodifiers ? NewStringf("%s%s", csdirectordelegatemodifiers, Len(csdirectordelegatemodifiers) > 0 ? " " : "") : NewStringf("public "));
Printf(director_delegate_definitions, " %sdelegate %s", modifiers, tm);
Delete(modifiers);
} else {
Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0));
}
} else {
Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0));
}
if ((c_ret_type = Swig_typemap_lookup("ctype", n, "", 0))) {
@ -4288,6 +4285,8 @@ public:
if (!ignored_method) {
/* Emit the actual upcall through */
String *member_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
String *imclass_dmethod = NewStringf("SwigDirector_%s", member_name);
UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name);
String *methid = Getattr(udata, "class_methodidx");
Setattr(n, "upcalldata", udata);
@ -4303,6 +4302,9 @@ public:
Printf(director_delegate_instances, " private SwigDelegate%s_%s swigDelegate%s;\n", classname, methid, methid);
Printf(director_method_types, " private static global::System.Type[] swigMethodTypes%s = new global::System.Type[] { %s };\n", methid, proxy_method_types);
Printf(director_connect_parms, "SwigDirector%s%s delegate%s", classname, methid, methid);
Delete(imclass_dmethod);
Delete(member_name);
}
Delete(pre_code);

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* d.cxx
*
@ -472,7 +472,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGD\n#define SWIGD\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "D");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@ -1943,7 +1943,7 @@ public:
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *returntype = Getattr(n, "type");
String *overloaded_name = getOverloadedName(n);
String *overloaded_name = 0;
String *storage = Getattr(n, "storage");
String *value = Getattr(n, "value");
String *decl = Getattr(n, "decl");
@ -1962,7 +1962,6 @@ public:
String *qualified_name = NewStringf("%s::%s", dirclassname, name);
SwigType *c_ret_type = NULL;
String *dcallback_call_args = NewString("");
String *imclass_dmethod;
String *callback_typedef_parms = NewString("");
String *delegate_parms = NewString("");
String *proxy_method_param_list = NewString("");
@ -1977,7 +1976,8 @@ public:
// we're consistent with the sym:overload name in functionWrapper. (?? when
// does the overloaded method name get set?)
imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), classname, overloaded_name));
if (!ignored_method)
overloaded_name = getOverloadedName(n);
qualified_return = SwigType_rcaststr(returntype, "c_result");
@ -2381,8 +2381,9 @@ public:
dp_return_type = NewString("");
}
String *member_name = Swig_name_member(getNSpace(), classname, overloaded_name);
String *imclass_dmethod = NewStringf("SwigDirector_%s", member_name);
UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name, dp_return_type, proxy_method_param_list);
Delete(dp_return_type);
// Write the global callback function pointer on the C code.
String *methid = Getattr(udata, "class_methodidx");
@ -2396,6 +2397,10 @@ public:
String *dirClassName = directorClassName(parent);
Printf(proxy_callback_type, "%s_Callback%s", dirClassName, methid);
Printf(im_dmodule_code, "alias extern(C) %s function(void*%s) %s;\n", proxy_callback_return_type, delegate_parms, proxy_callback_type);
Delete(imclass_dmethod);
Delete(member_name);
Delete(dp_return_type);
Delete(proxy_callback_type);
Delete(dirClassName);
}
@ -3374,19 +3379,15 @@ private:
String *upcast_name = Swig_name_member(getNSpace(), d_class_name, (smart != 0 ? "SmartPtrUpcast" : "Upcast"));
String *upcast_wrapper_name = Swig_name_wrapper(upcast_name);
writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)",
upcast_wrapper_name);
writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)", upcast_wrapper_name);
String *classname = SwigType_namestr(c_classname);
String *baseclassname = SwigType_namestr(c_baseclassname);
if (smart) {
String *smartnamestr = SwigType_namestr(smart);
String *bsmartnamestr = SwigType_namestr(smart);
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
if (smart) {
SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname);
String *smartnamestr = SwigType_namestr(smart);
String *bsmartnamestr = SwigType_namestr(bsmart);
Printv(upcasts_code,
"SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name,
@ -3395,10 +3396,9 @@ private:
"}\n",
"\n", NIL);
Delete(rbaseclassname);
Delete(rclassname);
Delete(bsmartnamestr);
Delete(smartnamestr);
Delete(bsmart);
} else {
Printv(upcasts_code,
"SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name,
@ -3413,8 +3413,8 @@ private:
Delete(baseclassname);
Delete(classname);
Delete(upcast_name);
Delete(upcast_wrapper_name);
Delete(upcast_name);
Delete(smart);
}
@ -4286,6 +4286,7 @@ private:
* D::getOverloadedName()
* --------------------------------------------------------------------------- */
String *getOverloadedName(Node *n) const {
// A void* parameter is used for all wrapped classes in the wrapper code.
// Thus, the wrapper function names for overloaded functions are postfixed
// with a counter string to make them unique.

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* directors.cxx
*
@ -233,3 +233,38 @@ void Swig_director_parms_fixup(ParmList *parms) {
}
}
/* -----------------------------------------------------------------------------
* Swig_director_can_unwrap()
*
* Determine whether a function's return type can be returned as an existing
* target language object instead of creating a new target language object.
* Must be a director class and only for return by pointer or reference only
* (not by value or by pointer to pointer etc).
* ----------------------------------------------------------------------------- */
bool Swig_director_can_unwrap(Node *n) {
// FIXME: this will not try to unwrap directors returned as non-director
// base class pointers!
bool unwrap = false;
String *type = Getattr(n, "type");
SwigType *t = SwigType_typedef_resolve_all(type);
SwigType *t1 = SwigType_strip_qualifiers(t);
SwigType *prefix = SwigType_prefix(t1);
if (Strcmp(prefix, "p.") == 0 || Strcmp(prefix, "r.") == 0) {
Node *parent = Swig_methodclass(n);
Node *module = Getattr(parent, "module");
Node *target = Swig_directormap(module, t1);
if (target)
unwrap = true;
}
Delete(prefix);
Delete(t1);
Delete(t);
return unwrap;
}

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* emit.cxx
*

View file

@ -1,6 +1,10 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
* This file is part of SWIG, which is licensed as a whole under version 3
* (or any later version) of the GNU General Public License. Some additional
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at https://www.swig.org/legal.html.
*
* go.cxx
*
@ -508,6 +512,9 @@ private:
Swig_register_filebyname("cgo_comment_typedefs", f_cgo_comment_typedefs);
Swig_banner(f_c_begin);
Swig_obligatory_macros(f_c_runtime, "GO");
if (CPlusPlus) {
Printf(f_c_begin, "\n// source: %s\n\n", swig_filename);
} else {
@ -515,6 +522,7 @@ private:
}
Printf(f_c_runtime, "#define SWIGMODULE %s\n", module);
if (gccgo_flag) {
Printf(f_c_runtime, "#define SWIGGO_PREFIX %s\n", go_prefix);
}
@ -4648,8 +4656,8 @@ private:
* 'X'.
* ---------------------------------------------------------------------- */
String *exportedName(String *name) {
String *copy = Copy(name);
String *exportedName(SwigType *name) {
SwigType *copy = Copy(name);
char c = *Char(copy);
if (islower(c)) {
char l[2];
@ -4669,7 +4677,7 @@ private:
u[2] = '\0';
Replace(copy, l, u, DOH_REPLACE_FIRST);
}
String *ret = Swig_name_mangle(copy);
String *ret = Swig_name_mangle_type(copy);
Delete(copy);
return ret;
}
@ -4717,7 +4725,7 @@ private:
Append(nw, c3);
Delete(c2);
Delete(c3);
String *ret = Swig_name_mangle(nw);
String *ret = Swig_name_mangle_string(nw);
Delete(nw);
return ret;
}
@ -4734,7 +4742,7 @@ private:
String *buildGoWrapperName(String *name, String *overname) {
String *s1 = NewString("_swig_wrap_");
Append(s1, name);
String *s2 = Swig_name_mangle(s1);
String *s2 = Swig_name_mangle_string(s1);
Delete(s1);
if (overname) {
Append(s2, overname);
@ -5548,11 +5556,11 @@ private:
return NewString("int");
}
String *type = Getattr(n, "enumtype");
SwigType *type = Getattr(n, "enumtype");
assert(type);
char *p = Char(type);
int len = Len(type);
String *s = NewString("");
SwigType *s = NewString("");
bool capitalize = true;
for (int i = 0; i < len; ++i, ++p) {
if (*p == ':') {
@ -5568,7 +5576,7 @@ private:
}
}
ret = Swig_name_mangle(s);
ret = Swig_name_mangle_type(s);
Delete(s);
return ret;
}

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* guile.cxx
*
@ -321,7 +321,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGGUILE\n#define SWIGGUILE\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "GUILE");
/* Write out directives and declarations */
@ -1396,7 +1396,7 @@ public:
SwigType *ct = NewStringf("p.%s", Getattr(n, "name"));
swigtype_ptr = SwigType_manglestr(ct);
String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name"));
String *mangled_classname = Swig_name_mangle_string(Getattr(n, "sym:name"));
/* Export clientdata structure */
Printf(f_runtime, "static swig_guile_clientdata _swig_guile_clientdata%s = { NULL, SCM_EOL };\n", mangled_classname);

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* interface.cxx
*
@ -183,6 +183,7 @@ void Swig_interface_propagate_methods(Node *n) {
if (Strcmp(symname, "$ignore") != 0) {
Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
Node *on = Swig_symbol_add(symname, cn);
(void)on;
assert(on == cn);
// Features from the copied base class method are already present, now add in features specific to the added method in the derived class

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* java.cxx
*
@ -456,7 +456,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGJAVA\n#define SWIGJAVA\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "JAVA");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@ -1883,16 +1883,10 @@ public:
Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method_name);
String *classname = SwigType_namestr(c_classname);
String *baseclassname = SwigType_namestr(c_baseclassname);
if (smart) {
SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname);
String *smartnamestr = SwigType_namestr(smart);
String *bsmartnamestr = SwigType_namestr(smart);
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
String *bsmartnamestr = SwigType_namestr(bsmart);
Printv(upcasts_code,
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
@ -1905,11 +1899,13 @@ public:
" return baseptr;\n"
"}\n", "\n", NIL);
Delete(rbaseclassname);
Delete(rclassname);
Delete(bsmartnamestr);
Delete(smartnamestr);
Delete(bsmart);
} else {
String *classname = SwigType_namestr(c_classname);
String *baseclassname = SwigType_namestr(c_baseclassname);
Printv(upcasts_code,
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
" jlong baseptr = 0;\n"
@ -1918,10 +1914,11 @@ public:
" *(", baseclassname, " **)&baseptr = *(", classname, " **)&jarg1;\n"
" return baseptr;\n"
"}\n", "\n", NIL);
Delete(baseclassname);
Delete(classname);
}
Delete(baseclassname);
Delete(classname);
Delete(wname);
Delete(jniname);
}
@ -2991,7 +2988,7 @@ public:
* a Java long is used for all classes in the SWIG intermediary class.
* The intermediary class methods are thus mangled when overloaded to give
* a unique name. */
String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name"));
String *overloaded_name = Copy(Getattr(n, "sym:name"));
if (Getattr(n, "sym:overloaded")) {
Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
@ -4006,7 +4003,7 @@ public:
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *returntype = Getattr(n, "type");
String *overloaded_name = getOverloadedName(n);
String *overloaded_name = 0;
String *storage = Getattr(n, "storage");
String *value = Getattr(n, "value");
String *decl = Getattr(n, "decl");
@ -4029,7 +4026,7 @@ public:
String *classret_desc = NewString("");
SwigType *c_ret_type = NULL;
String *jupcall_args = NewString("swigjobj");
String *imclass_dmethod;
String *imclass_dmethod = 0;
String *callback_def = NewString("");
String *callback_code = NewString("");
String *imcall_args = NewString("");
@ -4042,7 +4039,11 @@ public:
// we're consistent with the sym:overload name in functionWrapper. (?? when
// does the overloaded method name get set?)
imclass_dmethod = NewStringf("%s", Swig_name_member(getNSpace(), dirclassname, overloaded_name));
if (!ignored_method) {
overloaded_name = getOverloadedName(n);
imclass_dmethod = Swig_name_member(getNSpace(), dirclassname, overloaded_name);
}
qualified_return = SwigType_rcaststr(returntype, "c_result");
@ -4095,12 +4096,14 @@ public:
}
}
/* Create the intermediate class wrapper */
tm = Swig_typemap_lookup("jtype", n, "", 0);
if (tm) {
Printf(callback_def, " public static %s %s(%s jself", tm, imclass_dmethod, qualified_classname);
} else {
Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(returntype, 0));
if (!ignored_method) {
/* Create the intermediate class wrapper */
tm = Swig_typemap_lookup("jtype", n, "", 0);
if (tm) {
Printf(callback_def, " public static %s %s(%s jself", tm, imclass_dmethod, qualified_classname);
} else {
Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(returntype, 0));
}
}
String *cdesc = NULL;

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* javascript.cxx
*
@ -1461,7 +1461,7 @@ Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent, con
Hash *entry = NewHash();
String *name = NewString(_name);
Setattr(entry, NAME, Swig_scopename_last(name));
Setattr(entry, NAME_MANGLED, Swig_name_mangle(name));
Setattr(entry, NAME_MANGLED, Swig_name_mangle_string(name));
Setattr(entry, PARENT, NewString(parent));
Setattr(entry, PARENT_MANGLED, NewString(parent_mangled));
@ -1615,6 +1615,8 @@ int JSCEmitter::initialize(Node *n) {
Swig_banner(f_wrap_cpp);
Swig_obligatory_macros(f_runtime, "JAVASCRIPT");
return SWIG_OK;
}
@ -1945,6 +1947,8 @@ int V8Emitter::initialize(Node *n) {
Swig_banner(f_wrap_cpp);
Swig_obligatory_macros(f_runtime, "JAVASCRIPT");
return SWIG_OK;
}

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* lang.cxx
*
@ -77,7 +77,9 @@ static Hash *classhash;
extern int GenerateDefault;
extern int ForceExtern;
extern int AddExtern;
extern int UseWrapperSuffix;
extern "C" {
extern int UseWrapperSuffix;
}
/* import modes */
@ -1308,16 +1310,18 @@ int Language::staticmemberfunctionHandler(Node *n) {
else
cname = NewStringf("%s::%s", sname, name);
} else {
String *mname = Swig_name_mangle(ClassName);
String *classname_str = SwigType_namestr(ClassName);
String *mname = Swig_name_mangle_string(classname_str);
cname = Swig_name_member(NSpace, mname, name);
Delete(mname);
Delete(classname_str);
}
mrename = Swig_name_member(NSpace, ClassPrefix, symname);
if (Extend) {
String *code = Getattr(n, "code");
String *defaultargs = Getattr(n, "defaultargs");
String *mangled = Swig_name_mangle(mrename);
String *mangled = Swig_name_mangle_string(mrename);
Delete(mrename);
mrename = mangled;
@ -1331,7 +1335,7 @@ int Language::staticmemberfunctionHandler(Node *n) {
if (!defaultargs) {
/* Hmmm. An added static member. We have to create a little wrapper for this */
String *mangled_cname = Swig_name_mangle(cname);
String *mangled_cname = Swig_name_mangle_string(cname);
Swig_add_extension_code(n, mangled_cname, parms, type, code, CPlusPlus, 0);
Setattr(n, "extendname", mangled_cname);
Delete(mangled_cname);

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* lua.cxx
*
@ -329,7 +329,7 @@ public:
/* Standard stuff for the SWIG runtime section */
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGLUA\n#define SWIGLUA\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "LUA");
emitLuaFlavor(f_runtime);
@ -556,6 +556,12 @@ public:
this line adds this into the wrapper code
NEW LANGUAGE NOTE:END *********************************************** */
Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL);
// SWIG_fail in lua leads to a call to lua_error() which calls longjmp()
// which means the destructors of any live function-local C++ objects won't
// get run. To avoid this happening, we wrap almost everything in the
// function in a block, and end that right before lua_error() at which
// point those destructors will get called.
if (CPlusPlus) Append(f->def, "\n{");
/* NEW LANGUAGE NOTE:***********************************************
this prints the list of args, eg for a C fn
@ -766,10 +772,12 @@ public:
/* Close the function */
Printv(f->code, "return SWIG_arg;\n", NIL);
// add the failure cleanup code:
Printv(f->code, "\nif(0) SWIG_fail;\n", NIL);
Printv(f->code, "\nfail:\n", NIL);
Printv(f->code, "$cleanup", "lua_error(L);\n", NIL);
Printv(f->code, "return SWIG_arg;\n", NIL);
Printv(f->code, "\nfail: SWIGUNUSED;\n", "$cleanup", NIL);
if (CPlusPlus) Append(f->code, "}\n");
Printv(f->code, "lua_error(L);\n", NIL);
// lua_error() calls longjmp() but we need a dummy return to avoid compiler
// warnings.
Printv(f->code, "return 0;\n", NIL);
Printf(f->code, "}\n");
/* Substitute the cleanup code */
@ -1261,7 +1269,7 @@ public:
full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
assert(full_proxy_class_name);
mangled_full_proxy_class_name = Swig_name_mangle(full_proxy_class_name);
mangled_full_proxy_class_name = Swig_name_mangle_string(full_proxy_class_name);
SwigType *t = Copy(Getattr(n, "name"));
SwigType *fr_t = SwigType_typedef_resolve_all(t); /* Create fully resolved type */
@ -1795,7 +1803,7 @@ public:
if (nspace == 0 || Len(nspace) == 0)
mangled_name = NewString("SwigModule");
else
mangled_name = Swig_name_mangle(nspace);
mangled_name = Swig_name_mangle_string(nspace);
String *cname = NewStringf("swig_%s", mangled_name);
Setattr(carrays_hash, "cname", cname);

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* main.cxx
*
@ -37,10 +37,13 @@ int Verbose = 0;
int AddExtern = 0;
int NoExcept = 0;
int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
int UseWrapperSuffix = 0; // If 1, append suffix to non-overloaded functions too.
extern "C" {
int UseWrapperSuffix = 0; // If 1, append suffix to non-overloaded functions too.
}
/* Suppress warning messages for private inheritance, etc by default.
These are enabled by command line option -Wextra.
/* Suppress warning messages for private inheritance, preprocessor evaluation etc...
WARN_PP_EVALUATION 202
WARN_PARSE_PRIVATE_INHERIT 309
WARN_PARSE_BUILTIN_NAME 321
WARN_PARSE_REDUNDANT 322
@ -48,7 +51,7 @@ int UseWrapperSuffix = 0; // If 1, append suffix to non-overloaded functions too
WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
WARN_LANG_OVERLOAD_CONST 512
*/
#define EXTRA_WARNINGS "202,309,403,405,512,321,322"
#define EXTRA_WARNINGS "309,403,405,512,321,322"
extern "C" {
extern String *ModuleName;
@ -908,25 +911,11 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
Preprocessor_define((DOH *) "SWIG 1", 0);
Preprocessor_define((DOH *) "__STDC__", 0);
// Set the SWIG version value in format 0xAABBCC from package version expected to be in format A.B.C
String *package_version = NewString(PACKAGE_VERSION); /* Note that the fakeversion has not been set at this point */
char *token = strtok(Char(package_version), ".");
String *vers = NewString("SWIG_VERSION 0x");
int count = 0;
while (token) {
int len = (int)strlen(token);
assert(len == 1 || len == 2);
Printf(vers, "%s%s", (len == 1) ? "0" : "", token);
token = strtok(NULL, ".");
count++;
}
Delete(package_version);
assert(count == 3); // Check version format is correct
/* Turn on contracts */
String *vers = Swig_package_version_hex();
Preprocessor_define(vers, 0);
Delete(vers);
Swig_contract_mode_set(1);
Preprocessor_define(vers, 0);
/* Turn off directors mode */
Wrapper_director_mode_set(0);
@ -1326,7 +1315,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
if (tlm->status == Experimental) {
Swig_warning(WARN_LANG_EXPERIMENTAL, "SWIG", 1, "Experimental target language. "
"Target language %s specified by %s is an experimental language. "
"Please read about SWIG experimental languages, http://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n",
"Please read about SWIG experimental languages, https://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n",
tlm->help ? tlm->help : "", tlm->name);
}

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* mzscheme.cxx
*
@ -147,7 +147,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGMZSCHEME\n#define SWIGMZSCHEME\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "MZSCHEME");
module = Getattr(n, "name");
@ -569,7 +569,7 @@ public:
// Make a static variable;
Printf(var_name, "_wrap_const_%s", Swig_name_mangle(Getattr(n, "sym:name")));
Printf(var_name, "_wrap_const_%s", Swig_name_mangle_string(Getattr(n, "sym:name")));
// Build the name for scheme.
Printv(proc_name, iname, NIL);
@ -641,8 +641,6 @@ public:
* classHandler()
* ------------------------------------------------------------ */
virtual int classHandler(Node *n) {
String *mangled_classname = 0;
String *real_classname = 0;
String *scm_structname = NewString("");
SwigType *ctype_ptr = NewStringf("p.%s", getClassType());
@ -658,14 +656,11 @@ public:
convert_proto_tab = NewString("");
struct_name = Getattr(n, "sym:name");
mangled_struct_name = Swig_name_mangle(Getattr(n, "sym:name"));
mangled_struct_name = Swig_name_mangle_string(Getattr(n, "sym:name"));
Printv(scm_structname, struct_name, NIL);
Replaceall(scm_structname, "_", "-");
real_classname = Getattr(n, "name");
mangled_classname = Swig_name_mangle(real_classname);
Printv(fieldnames_tab, "static const char *_swig_struct_", cls_swigtype, "_field_names[] = { \n", NIL);
Printv(convert_proto_tab, "static Scheme_Object *_swig_convert_struct_", cls_swigtype, "(", SwigType_str(ctype_ptr, "ptr"), ");\n", NIL);
@ -695,7 +690,6 @@ public:
" = SWIG_MzScheme_new_scheme_struct(menv, \"", scm_structname, "\", ",
"_swig_struct_", cls_swigtype, "_field_names_cnt,", "(char**) _swig_struct_", cls_swigtype, "_field_names);\n", NIL);
Delete(mangled_classname);
Delete(swigtype_ptr);
swigtype_ptr = 0;
Delete(fieldnames_tab);

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* nested.cxx
*

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* ocaml.cxx
*
@ -276,7 +276,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGOCAML\n#define SWIGOCAML\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "OCAML");
Printf(f_runtime, "#define SWIG_MODULE \"%s\"\n", module);
/* Module name */
@ -1181,6 +1181,7 @@ public:
/*
* Produce the symbol name that ocaml will use when referring to the
* target item. I wonder if there's a better way to do this:
* (WF - use Swig_name_mangle_string/Swig_name_mangle_type)
*
* I shudder to think about doing it with a hash lookup, but that would
* make a couple of things easier:
@ -1209,6 +1210,8 @@ public:
Replaceall(out, "=", "_xx_equals");
Replaceall(out, "/", "_xx_slash");
Replaceall(out, ".", "_xx_dot");
Replaceall(out, "?", "_xx_question");
Replaceall(out, ":", "_xx_colon");
return out;
}
@ -1238,6 +1241,7 @@ public:
int enumvalueDeclaration(Node *n) {
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
SwigType *qtype = 0;
if (name_qualifier_type) {
@ -1245,8 +1249,8 @@ public:
Printv(qtype, name, NIL);
}
if (const_enum && qtype && name && !Getattr(seen_enumvalues, name)) {
Setattr(seen_enumvalues, name, "true");
if (const_enum && qtype && symname && !Getattr(seen_enumvalues, symname)) {
Setattr(seen_enumvalues, symname, "true");
SetFlag(n, "feature:immutable");
Setattr(n, "feature:enumvalue", "1"); // this does not appear to be used
@ -1255,10 +1259,10 @@ public:
String *evname = SwigType_manglestr(qtype);
Insert(evname, 0, "SWIG_ENUM_");
Setattr(n, "feature:enumvname", name);
Setattr(n, "feature:enumvname", symname);
Setattr(n, "feature:symname", evname);
Delete(evname);
Printf(f_enumtypes_value, "| `%s\n", name);
Printf(f_enumtypes_value, "| `%s\n", symname);
return Language::enumvalueDeclaration(n);
} else
@ -1646,20 +1650,13 @@ public:
/* any existing helper functions to handle this? */
if (!is_void) {
if (!(ignored_method && !pure_virtual)) {
/* A little explanation:
* The director_enum test case makes a method whose return type
* is an enum type. returntype here is "int". gcc complains
* about an implicit enum conversion, and although i don't strictly
* agree with it, I'm working on fixing the error:
*
* Below is what I came up with. It's not great but it should
* always essentially work.
*/
String *rettype = SwigType_str(returntype, 0);
if (!SwigType_isreference(returntype)) {
Printf(w->code, "CAMLreturn_type((%s)c_result);\n", SwigType_lstr(returntype, ""));
Printf(w->code, "CAMLreturn_type((%s)c_result);\n", rettype);
} else {
Printf(w->code, "CAMLreturn_type(*c_result);\n");
Printf(w->code, "CAMLreturn_type((%s)*c_result);\n", rettype);
}
Delete(rettype);
}
} else {
Printf(w->code, "CAMLreturn0;\n");

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* octave.cxx
*
@ -190,7 +190,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGOCTAVE\n#define SWIGOCTAVE\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "OCTAVE");
Printf(f_runtime, "#define SWIG_name_d \"%s\"\n", module);
Printf(f_runtime, "#define SWIG_name %s\n", module);
@ -835,7 +835,7 @@ public:
String *setwname = Swig_name_wrapper(setname);
Octave_begin_function(n, setf->def, setname, setwname, true);
Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();\n", iname);
if (is_assignable(n)) {
Setattr(n, "wrap:name", setname);
if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
@ -946,7 +946,7 @@ public:
// This is a bug, due to the fact that swig_type -> octave_class mapping
// is 1-to-n.
static Hash *emitted = NewHash();
String *mangled_classname = Swig_name_mangle(Getattr(n, "name"));
String *mangled_classname = Swig_name_mangle_type(Getattr(n, "name"));
if (Getattr(emitted, mangled_classname)) {
Delete(mangled_classname);
return SWIG_NOWRAP;

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* overload.cxx
*

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* perl5.cxx
*
@ -319,7 +319,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGPERL\n#define SWIGPERL\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "PERL");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* php.cxx
*
@ -16,6 +16,7 @@
#include <algorithm>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
static const char *usage = "\
PHP Options (available with -php7)\n\
@ -148,6 +149,8 @@ static void SwigPHP_emit_pointer_type_registrations() {
Printf(s_wrappers, "/* Implement __toString equivalent, since that worked for the old-style resource wrapped pointers. */\n");
Append(s_wrappers, "#if PHP_MAJOR_VERSION < 8\n");
Printf(s_wrappers, "static int swig_ptr_cast_object(zval *z, zval *retval, int type) {\n");
Append(s_wrappers, "#elif PHP_MAJOR_VERSION > 8 || PHP_MINOR_VERSION >= 2\n");
Printf(s_wrappers, "static ZEND_RESULT_CODE swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n");
Append(s_wrappers, "#else\n");
Printf(s_wrappers, "static int swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n");
Append(s_wrappers, "#endif\n");
@ -216,6 +219,10 @@ static Hash *php_parent_class = NewHash();
// php_class + ":" + php_method -> boolean (using SetFlag()/GetFlag()).
static Hash *has_directed_descendent = NewHash();
// Track required return type for parent class methods.
// php_class + ":" + php_method -> List of php types.
static Hash *parent_class_method_return_type = NewHash();
// Class encapsulating the machinery to add PHP type declarations.
class PHPTypes {
// List with an entry for each parameter and one for the return type.
@ -250,10 +257,21 @@ class PHPTypes {
return std::max(Len(merged_types), Len(byref));
}
String *get_phptype(int key, String *classtypes) {
String *get_phptype(int key, String *classtypes, List *more_return_types = NULL) {
Clear(classtypes);
// We want to minimise the list of class types by not redundantly listing
// a class for which a super-class is also listed. This canonicalisation
// allows for more sharing of arginfo (which reduces module size), makes
// for a cleaner list if it's shown to the user, and also will speed up
// module load a bit.
Hash *classes = NewHash();
DOH *types = Getitem(merged_types, key);
String *result = NewStringEmpty();
if (more_return_types) {
if (types != None) {
merge_type_lists(types, more_return_types);
}
}
if (types != None) {
SortList(types, NULL);
String *prev = NULL;
@ -267,13 +285,36 @@ class PHPTypes {
if (Len(result) > 0) Append(result, "|");
Append(result, c);
} else {
if (Len(classtypes) > 0) Append(classtypes, "|");
Append(classtypes, prefix);
Append(classtypes, i.item);
SetFlag(classes, i.item);
}
prev = i.item;
}
}
// Remove entries for which a super-class is also listed.
Iterator i = First(classes);
while (i.key) {
String *this_class = i.key;
// We must advance the iterator early so we don't delete the element it
// points to.
i = Next(i);
String *parent = this_class;
while ((parent = Getattr(php_parent_class, parent)) != NULL) {
if (GetFlag(classes, parent)) {
Delattr(classes, this_class);
break;
}
}
}
List *sorted_classes = SortedKeys(classes, Strcmp);
for (i = First(sorted_classes); i.item; i = Next(i)) {
if (Len(classtypes) > 0) Append(classtypes, "|");
Append(classtypes, prefix);
Append(classtypes, i.item);
}
Delete(sorted_classes);
// Make the mask 0 if there are only class names specified.
if (Len(result) == 0) {
Append(result, "0");
@ -281,7 +322,11 @@ class PHPTypes {
return result;
}
void init(Node *n) {
public:
PHPTypes(Node *n)
: merged_types(NewList()),
byref(NULL),
num_required(INT_MAX) {
String *php_type_feature = Getattr(n, "feature:php:type");
php_type_flag = 0;
if (php_type_feature != NULL) {
@ -295,21 +340,6 @@ class PHPTypes {
has_director_node = (Getattr(n, "directorNode") != NULL);
}
public:
PHPTypes(Node *n, int num_required_)
: merged_types(NewList()),
byref(NULL),
num_required(num_required_) {
init(n);
}
PHPTypes(Node *n, const PHPTypes *o)
: merged_types(Copy(o->merged_types)),
byref(Copy(o->byref)),
num_required(o->num_required) {
init(n);
}
~PHPTypes() {
Delete(merged_types);
Delete(byref);
@ -329,7 +359,15 @@ public:
}
// key is 0 for return type, or >= 1 for parameters numbered from 1
void process_phptype(Node *n, int key, const String_or_char *attribute_name);
List *process_phptype(Node *n, int key, const String_or_char *attribute_name);
// Merge entries from o_merge_list into merge_list, skipping any entries
// already present.
//
// Both merge_list and o_merge_list should be in sorted order.
static void merge_type_lists(List *merge_list, List *o_merge_list);
void merge_from(const PHPTypes* o);
void set_byref(int key) {
if (!byref) {
@ -344,7 +382,34 @@ public:
Setitem(byref, key, ""); // Just needs to be something != None.
}
void emit_arginfo(String *key) {
void emit_arginfo(DOH *item, String *key) {
Setmark(item, 1);
char *colon_ptr = Strchr(key, ':');
assert(colon_ptr);
int colon = (int)(colon_ptr - Char(key));
if (colon > 0 && Strcmp(colon_ptr + 1, "__construct") != 0) {
// See if there's a parent class which implements this method, and if so
// emit its arginfo and then merge its PHPTypes into ours as we need to
// be compatible with it (whether it is virtual or not).
String *this_class = NewStringWithSize(Char(key), colon);
String *parent = this_class;
while ((parent = Getattr(php_parent_class, parent)) != NULL) {
String *k = NewStringf("%s%s", parent, colon_ptr);
DOH *item = Getattr(all_phptypes, k);
if (item) {
PHPTypes *p = (PHPTypes*)Data(item);
if (!Getmark(item)) {
p->emit_arginfo(item, k);
}
merge_from(p);
Delete(k);
break;
}
Delete(k);
}
Delete(this_class);
}
// We want to only emit each different arginfo once, as that reduces the
// size of both the generated source code and the compiled extension
// module. The parameters at this level are just named arg1, arg2, etc
@ -357,27 +422,28 @@ public:
// arginfo_used Hash to see if we've already generated it.
String *out_phptype = NULL;
String *out_phpclasses = NewStringEmpty();
if (php_type_flag &&
(php_type_flag > 0 || !has_director_node) &&
!GetFlag(has_directed_descendent, key)) {
// We provide a simple way to generate PHP return type declarations
// except for directed methods. The point of directors is to allow
// subclassing in the target language, and if the wrapped method has
// a return type declaration then an overriding method in user code
// needs to have a compatible declaration.
//
// The upshot of this is that enabling return type declarations for
// existing bindings would break compatibility with user code written
// for an older version. For parameters however the situation is
// different because if the parent class declares types for parameters
// a subclass overriding the function will be compatible whether it
// declares them or not.
//
// directorNode being present seems to indicate if this method or one
// it inherits from is directed, which is what we care about here.
// Using (!is_member_director(n)) would get it wrong for testcase
// director_frob.
out_phptype = get_phptype(0, out_phpclasses);
// We provide a simple way to generate PHP return type declarations
// except for directed methods. The point of directors is to allow
// subclassing in the target language, and if the wrapped method has
// a return type declaration then an overriding method in user code
// needs to have a compatible declaration.
//
// The upshot of this is that enabling return type declarations for
// existing bindings would break compatibility with user code written
// for an older version. For parameters however the situation is
// different because if the parent class declares types for parameters
// a subclass overriding the function will be compatible whether it
// declares them or not.
//
// directorNode being present seems to indicate if this method or one
// it inherits from is directed, which is what we care about here.
// Using (!is_member_director(n)) would get it wrong for testcase
// director_frob.
if (php_type_flag && (php_type_flag > 0 || !has_director_node)) {
if (!GetFlag(has_directed_descendent, key)) {
out_phptype = get_phptype(0, out_phpclasses, Getattr(parent_class_method_return_type, key));
}
}
// ### in arginfo_code will be replaced with the id once that is known.
@ -543,12 +609,39 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGPHP\n#define SWIGPHP\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "PHP");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
}
// We need to include php.h before string.h gets included, at least with
// PHP 8.2. Otherwise string.h is included without _GNU_SOURCE being
// included and memrchr() doesn't get declared, and then inline code in
// the PHP headers defines _GNU_SOURCE, includes string.h (which is a
// no op thanks to the include gaurds), then tries to use memrchr() and
// fails.
//
// We also need to suppress -Wdeclaration-after-statement if enabled
// since with PHP 8.2 zend_operators.h contains inline code which triggers
// this warning and our testsuite uses with option and -Werror. I don't
// see a good way to only do this within our testsuite, but disabling
// it globally like this shouldn't be problematic.
Append(f_runtime,
"\n"
"#if defined __GNUC__ && !defined __cplusplus\n"
"# if __GNUC__ >= 4\n"
"# pragma GCC diagnostic push\n"
"# pragma GCC diagnostic ignored \"-Wdeclaration-after-statement\"\n"
"# endif\n"
"#endif\n"
"#include \"php.h\"\n"
"#if defined __GNUC__ && !defined __cplusplus\n"
"# if __GNUC__ >= 4\n"
"# pragma GCC diagnostic pop\n"
"# endif\n"
"#endif\n\n");
/* Set the module name */
module = Copy(Getattr(n, "name"));
cap_module = NewStringf("%(upper)s", module);
@ -631,10 +724,19 @@ public:
/* Emit all of the code */
Language::top(n);
/* Emit all the arginfo */
for (Iterator ki = First(all_phptypes); ki.key; ki = Next(ki)) {
PHPTypes *p = (PHPTypes*)Data(ki.item);
p->emit_arginfo(ki.key);
/* Emit all the arginfo. We sort the keys so the output order doesn't depend on
* hashkey order.
*/
{
List *sorted_keys = SortedKeys(all_phptypes, Strcmp);
for (Iterator k = First(sorted_keys); k.item; k = Next(k)) {
DOH *val = Getattr(all_phptypes, k.item);
if (!Getmark(val)) {
PHPTypes *p = (PHPTypes*)Data(val);
p->emit_arginfo(val, k.item);
}
}
Delete(sorted_keys);
}
SwigPHP_emit_pointer_type_registrations();
@ -840,7 +942,7 @@ public:
void create_command(String *cname, String *fname, Node *n, bool dispatch, String *modes = NULL) {
// This is for the single main zend_function_entry record
ParmList *l = Getattr(n, "parms");
if (cname && Cmp(Getattr(n, "storage"), "friend") != 0) {
if (cname && !Equal(Getattr(n, "storage"), "friend")) {
Printf(f_h, "static PHP_METHOD(%s%s,%s);\n", prefix, cname, fname);
if (wrapperType != staticmemberfn &&
wrapperType != staticmembervar &&
@ -857,12 +959,12 @@ public:
}
}
phptypes->adjust(emit_num_required(l), Equal(fname, "__construct"));
phptypes->adjust(emit_num_required(l), Equal(fname, "__construct") ? true : false);
String *arginfo_id = phptypes->get_arginfo_id();
String *s = cs_entry;
if (!s) s = s_entry;
if (cname && Cmp(Getattr(n, "storage"), "friend") != 0) {
if (cname && !Equal(Getattr(n, "storage"), "friend")) {
Printf(all_cs_entry, " PHP_ME(%s%s,%s,swig_arginfo_%s,%s)\n", prefix, cname, fname, arginfo_id, modes);
} else {
if (dispatch) {
@ -932,7 +1034,7 @@ public:
create_command(class_name, wname, n, true, modes);
if (class_name && Cmp(Getattr(n, "storage"), "friend") != 0) {
if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL);
} else {
Printv(f->def, "static ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
@ -1027,12 +1129,12 @@ public:
" if (director) director->swig_disown();\n",
"}\n", NIL);
}
Printf(f->code, "} else {\n");
if (swig_base) {
Printf(f->code, "PHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
} else {
Printf(f->code, "add_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n}\n");
Printf(f->code, "} else {\nPHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n", prefix, swig_base);
} else if (Getattr(class_node, "feature:php:allowdynamicproperties")) {
Printf(f->code, "} else {\nadd_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n");
}
Printf(f->code, "}\n");
Printf(f->code, "fail:\n");
Printf(f->code, "return;\n");
@ -1222,7 +1324,7 @@ public:
if (is_getter_method(n)) {
// This is to overcome types that can't be set and hence no setter.
if (Cmp(Getattr(n, "feature:immutable"), "1") != 0)
if (!Equal(Getattr(n, "feature:immutable"), "1"))
static_getter = true;
}
} else if (wrapperType == staticmemberfn) {
@ -1248,9 +1350,8 @@ public:
return SWIG_OK;
}
if (!Getattr(n, "sym:previousSibling") && !static_getter) {
// First function of an overloaded group or a function which isn't part
// of a group so reset the phptype information.
if (!static_getter) {
// Create or find existing PHPTypes.
phptypes = NULL;
String *key;
@ -1262,29 +1363,11 @@ public:
PHPTypes *p = (PHPTypes*)GetVoid(all_phptypes, key);
if (p) {
// We already have an entry - this happens when overloads are created
// by %extend, for instance.
// We already have an entry so use it.
phptypes = p;
Delete(key);
} else {
if (class_name) {
// See if there's a parent class which implements this method, and if
// so copy the PHPTypes of that method as a starting point as we need
// to be compatible with it (whether it is virtual or not).
String *parent = class_name;
while ((parent = Getattr(php_parent_class, parent)) != NULL) {
String *k = NewStringf("%s:%s", parent, wname);
PHPTypes *p = (PHPTypes*)GetVoid(all_phptypes, k);
Delete(key);
if (p) {
phptypes = new PHPTypes(n, p);
break;
}
}
}
if (!phptypes) {
phptypes = new PHPTypes(n, emit_num_required(l));
}
phptypes = new PHPTypes(n);
SetVoid(all_phptypes, key, phptypes);
}
}
@ -1300,7 +1383,7 @@ public:
if (!overloaded) {
if (!static_getter) {
if (class_name && Cmp(Getattr(n, "storage"), "friend") != 0) {
if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL);
} else {
if (wrap_nonclass_global) {
@ -1433,15 +1516,6 @@ public:
Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
Wrapper_add_local(f, "upcall", "bool upcall = false");
Printf(f->code, "upcall = (director && (director->swig_get_self()==Z_OBJ_P(ZEND_THIS)));\n");
if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
String *parent = class_name;
while ((parent = Getattr(php_parent_class, parent)) != NULL) {
// Mark this method name as having a directed descendent for all
// classes we're derived from.
SetFlag(has_directed_descendent, NewStringf("%s:%s", parent, wname));
}
}
}
Swig_director_emit_dynamic_cast(n, f);
@ -1501,7 +1575,33 @@ public:
}
emit_return_variable(n, d, f);
phptypes->process_phptype(n, 0, "tmap:out:phptype");
List *return_types = phptypes->process_phptype(n, 0, "tmap:out:phptype");
if (class_name && !Equal(Getattr(n, "storage"), "friend")) {
if (is_member_director(n)) {
String *parent = class_name;
while ((parent = Getattr(php_parent_class, parent)) != NULL) {
// Mark this method name as having no return type declaration for all
// classes we're derived from.
SetFlag(has_directed_descendent, NewStringf("%s:%s", parent, wname));
}
} else if (return_types) {
String *parent = class_name;
while ((parent = Getattr(php_parent_class, parent)) != NULL) {
String *key = NewStringf("%s:%s", parent, wname);
// The parent class method needs to have a superset of the possible
// return types of methods with the same name in subclasses.
List *v = Getattr(parent_class_method_return_type, key);
if (!v) {
// New entry.
Setattr(parent_class_method_return_type, key, Copy(return_types));
} else {
// Update existing entry.
PHPTypes::merge_type_lists(v, return_types);
}
}
}
}
if (outarg) {
Printv(f->code, outarg, NIL);
@ -1736,18 +1836,32 @@ public:
base_class = NewString("Exception");
}
if (Equal(base_class, "Exception")) {
if (!base_class) {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name);
} else if (Equal(base_class, "Exception")) {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name);
} else if (is_class_wrapped(base_class)) {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, SWIG_Php_ce_%s);\n", class_name, base_class);
Setattr(php_parent_class, class_name, base_class);
} else {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name);
Printf(s_oinit, " {\n");
Printf(s_oinit, " swig_type_info *type_info = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, \"_p_%s\");\n", base_class);
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, (zend_class_entry*)(type_info ? type_info->clientdata : NULL));\n", class_name);
Printf(s_oinit, " }\n");
}
if (Getattr(n, "abstracts") && !GetFlag(n, "feature:notabstract")) {
Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;\n", class_name);
}
if (Getattr(n, "feature:php:allowdynamicproperties")) {
Append(s_oinit, "#ifdef ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES\n");
Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES;\n", class_name);
Append(s_oinit, "#endif\n");
} else {
Append(s_oinit, "#ifdef ZEND_ACC_NO_DYNAMIC_PROPERTIES\n");
Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES;\n", class_name);
Append(s_oinit, "#endif\n");
}
String *swig_wrapped = swig_wrapped_interface_ce();
Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", &", swig_wrapped, ");\n", NIL);
@ -2413,7 +2527,7 @@ public:
static PHP *maininstance = 0;
void PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute_name) {
List *PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute_name) {
while (Len(merged_types) <= key) {
Append(merged_types, NewList());
@ -2427,11 +2541,11 @@ void PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute
// declaration for this parameter/return value (you can't store NULL as a
// value in a DOH List).
Setitem(merged_types, key, None);
return;
return NULL;
}
DOH *merge_list = Getitem(merged_types, key);
if (merge_list == None) return;
if (merge_list == None) return NULL;
List *types = Split(phptype, '|', -1);
String *first_type = Getitem(types, 0);
@ -2487,6 +2601,67 @@ void PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute
}
prev = i.item;
}
SortList(merge_list, NULL);
return merge_list;
}
void PHPTypes::merge_type_lists(List *merge_list, List *o_merge_list) {
int i = 0, j = 0;
while (j < Len(o_merge_list)) {
String *candidate = Getitem(o_merge_list, j);
while (i < Len(merge_list)) {
int cmp = Cmp(Getitem(merge_list, i), candidate);
if (cmp == 0)
goto handled;
if (cmp > 0)
break;
++i;
}
Insert(merge_list, i, candidate);
++i;
handled:
++j;
}
}
void PHPTypes::merge_from(const PHPTypes* o) {
num_required = std::min(num_required, o->num_required);
if (o->byref) {
if (byref == NULL) {
byref = Copy(o->byref);
} else {
int len = std::min(Len(byref), Len(o->byref));
// Start at 1 because we only want to merge parameter types, and key 0 is
// the return type.
for (int key = 1; key < len; ++key) {
if (Getitem(byref, key) == None &&
Getitem(o->byref, key) != None) {
Setitem(byref, key, "");
}
}
for (int key = len; key < Len(o->byref); ++key) {
Append(byref, Getitem(o->byref, key));
}
}
}
int len = std::min(Len(merged_types), Len(o->merged_types));
for (int key = 0; key < len; ++key) {
DOH *merge_list = Getitem(merged_types, key);
// None trumps anything else in the merge.
if (merge_list == None) continue;
DOH *o_merge_list = Getitem(o->merged_types, key);
if (o_merge_list == None) {
Setitem(merged_types, key, None);
continue;
}
merge_type_lists(merge_list, o_merge_list);
}
// Copy over any additional entries.
for (int key = len; key < Len(o->merged_types); ++key) {
Append(merged_types, Copy(Getitem(o->merged_types, key)));
}
}
// Collect non-class pointer types from the type table so we can set up PHP

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* python.cxx
*
@ -587,7 +587,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGPYTHON\n#define SWIGPYTHON\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "PYTHON");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@ -1898,16 +1898,20 @@ public:
String *str = Getattr(n, "feature:docstring");
if (!str || Len(str) == 0) {
if (builtin) {
String *name = Getattr(n, "name");
String *rname = add_explicit_scope(SwigType_namestr(name));
SwigType *name = Getattr(n, "name");
SwigType *sname = add_explicit_scope(name);
String *rname = SwigType_namestr(sname);
Printf(doc, "%s", rname);
Delete(sname);
Delete(rname);
} else {
String *classname_str = SwigType_namestr(real_classname);
if (CPlusPlus) {
Printf(doc, "Proxy of C++ %s class.", SwigType_namestr(real_classname));
Printf(doc, "Proxy of C++ %s class.", classname_str);
} else {
Printf(doc, "Proxy of C %s struct.", SwigType_namestr(real_classname));
Printf(doc, "Proxy of C %s struct.", classname_str);
}
Delete(classname_str);
}
}
}
@ -2810,7 +2814,7 @@ public:
Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args, PyObject *kwargs) {", NIL);
}
if (builtin) {
if (!builtin) {
/* Avoid warning if the self parameter is not used. */
Append(f->code, "(void)self;\n");
}
@ -3150,27 +3154,9 @@ public:
Replaceall(tm, "$owner", "0");
}
}
// FIXME: this will not try to unwrap directors returned as non-director
// base class pointers!
/* New addition to unwrap director return values so that the original
* python object is returned instead.
*/
#if 1
int unwrap = 0;
String *decl = Getattr(n, "decl");
int is_pointer = SwigType_ispointer_return(decl);
int is_reference = SwigType_isreference_return(decl);
if (is_pointer || is_reference) {
String *type = Getattr(n, "type");
//Node *classNode = Swig_methodclass(n);
//Node *module = Getattr(classNode, "module");
Node *module = Getattr(parent, "module");
Node *target = Swig_directormap(module, type);
if (target)
unwrap = 1;
}
if (unwrap) {
// Unwrap return values that are director classes so that the original Python object is returned instead.
if (!constructor && Swig_director_can_unwrap(n)) {
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
Printf(f->code, "director = SWIG_DIRECTOR_CAST(%s);\n", Swig_cresult_name());
Append(f->code, "if (director) {\n");
@ -3182,9 +3168,7 @@ public:
} else {
Printf(f->code, "%s\n", tm);
}
#else
Printf(f->code, "%s\n", tm);
#endif
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
@ -3942,35 +3926,36 @@ public:
* classHandler()
* ------------------------------------------------------------ */
String *add_explicit_scope(String *s) {
SwigType *add_explicit_scope(SwigType *s) {
if (!Strstr(s, "::")) {
String *ss = NewStringf("::%s", s);
Delete(s);
s = ss;
return NewStringf("::%s", s);
}
return s;
return Copy(s);
}
void builtin_pre_decl(Node *n) {
String *name = Getattr(n, "name");
String *rname = add_explicit_scope(SwigType_namestr(name));
String *mname = SwigType_manglestr(rname);
SwigType *name = Getattr(n, "name");
SwigType *sname = add_explicit_scope(name);
String *rname = SwigType_namestr(sname);
String *mname = SwigType_manglestr(sname);
Printf(f_init, "\n/* type '%s' */\n", rname);
Printf(f_init, " builtin_pytype = (PyTypeObject *)&SwigPyBuiltin_%s_type;\n", mname);
Printf(f_init, " builtin_pytype->tp_dict = d = PyDict_New();\n");
Delete(sname);
Delete(rname);
Delete(mname);
}
void builtin_post_decl(File *f, Node *n) {
String *name = Getattr(n, "name");
String *pname = Copy(name);
SwigType *name = Getattr(n, "name");
SwigType *pname = Copy(name);
SwigType_add_pointer(pname);
String *symname = Getattr(n, "sym:name");
String *rname = add_explicit_scope(SwigType_namestr(name));
String *mname = SwigType_manglestr(rname);
SwigType *sname = add_explicit_scope(name);
String *rname = SwigType_namestr(sname);
String *mname = SwigType_manglestr(sname);
String *pmname = SwigType_manglestr(pname);
String *templ = NewStringf("SwigPyBuiltin_%s", mname);
int funpack = fastunpack;
@ -4073,14 +4058,16 @@ public:
Printf(f, " PyTuple_SET_ITEM(tuple, 0, other);\n");
Printf(f, " Py_XINCREF(other);\n");
}
Iterator rich_iter = First(richcompare);
List *richcompare_list = SortedKeys(richcompare, 0);
Iterator rich_iter = First(richcompare_list);
if (rich_iter.item) {
Printf(f, " switch (op) {\n");
for (; rich_iter.item; rich_iter = Next(rich_iter))
Printf(f, " case %s : result = %s(self, %s); break;\n", rich_iter.key, rich_iter.item, funpack ? "other" : "tuple");
Printf(f, " case %s : result = %s(self, %s); break;\n", rich_iter.item, Getattr(richcompare, rich_iter.item), funpack ? "other" : "tuple");
Printv(f, " default : break;\n", NIL);
Printf(f, " }\n");
}
Delete(richcompare_list);
Printv(f, " if (!result) {\n", NIL);
Printv(f, " if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {\n", NIL);
Printv(f, " result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);\n", NIL);
@ -4399,9 +4386,10 @@ public:
Delete(clientdata);
Delete(smart);
Delete(sname);
Delete(rname);
Delete(pname);
Delete(mname);
Delete(pname);
Delete(pmname);
Delete(templ);
Delete(tp_flags);
@ -4498,9 +4486,11 @@ public:
Setattr(n, "feature:python:tp_doc", ds);
Delete(ds);
} else {
String *name = Getattr(n, "name");
String *rname = add_explicit_scope(SwigType_namestr(name));
SwigType *name = Getattr(n, "name");
SwigType *sname = add_explicit_scope(name);
String *rname = SwigType_namestr(sname);
Setattr(n, "feature:python:tp_doc", rname);
Delete(sname);
Delete(rname);
}
} else {

View file

@ -5,7 +5,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* r.cxx
*
@ -215,8 +215,7 @@ public:
int typedefHandler(Node *n);
static List *Swig_overload_rank(Node *n,
bool script_lang_wrapping);
static List *Swig_overload_rank(Node *n, bool script_lang_wrapping);
int memberfunctionHandler(Node *n) {
if (debugMode)
@ -243,8 +242,8 @@ public:
return status;
}
// Not used:
String *runtimeCode();
void replaceSpecialVariables(String *method, String *tm, Parm *parm);
protected:
int addRegistrationRoutine(String *rname, int nargs);
@ -740,8 +739,7 @@ int R::top(Node *n) {
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGR\n#define SWIGR\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "R");
Swig_banner_target_lang(s_init, "#");
outputCommandLineArguments(s_init);
@ -1568,7 +1566,8 @@ void R::dispatchFunction(Node *n) {
Printv(f->code,
"argtypes <- mapply(class, list(...));\n",
"argv <- list(...);\n",
"argc <- length(argtypes);\n", NIL );
"argc <- length(argtypes);\n",
"f <- NULL;\n", NIL);
Printf(f->code, "# dispatch functions %d\n", nfunc);
int cur_args = -1;
@ -1596,52 +1595,72 @@ void R::dispatchFunction(Node *n) {
first_compare = false;
}
Printv(f->code, "if (", NIL);
for (p =pi, j = 0 ; j < num_arguments ; j++) {
for (p = pi, j = 0 ; j < num_arguments ; j++) {
if (debugMode) {
Swig_print_node(p);
}
String *tm = Swig_typemap_lookup("rtype", p, "", 0);
if(tm) {
if (tm) {
replaceRClass(tm, Getattr(p, "type"));
}
String *tmcheck = Swig_typemap_lookup("rtypecheck", p, "", 0);
if (tmcheck) {
String *tmp = NewString("");
Printf(tmp, "argv[[%d]]", j+1);
Replaceall(tmcheck, "$arg", tmp);
Printf(tmp, "argtype[%d]", j+1);
Replaceall(tmcheck, "$argtype", tmp);
if (tm) {
Replaceall(tmcheck, "$rtype", tm);
}
String *tmp_argtype = NewStringf("argtypes[%d]", j+1);
Replaceall(tmcheck, "$argtype", tmp_argtype);
String *tmp_arg = NewStringf("argv[[%d]]", j+1);
Replaceall(tmcheck, "$arg", tmp_arg);
replaceRClass(tmcheck, Getattr(p, "type"));
if (debugMode) {
Printf(stdout, "<rtypecheck>%s\n", tmcheck);
}
Printf(f->code, "%s(%s)",
j == 0 ? "" : " && ",
tmcheck);
if (num_arguments == 1) {
Printf(f->code, "%s", tmcheck);
} else {
Printf(f->code, "%s(%s)", j == 0 ? "" : " && ", tmcheck);
}
p = Getattr(p, "tmap:in:next");
Delete(tmp_arg);
Delete(tmp_argtype);
continue;
}
// Below should be migrated into rtypecheck typemaps
// Preparation for this has started by warning in swig-4.1.1 for "numeric", "integer", "character" typemaps
// For swig-4.2: remove the code block below and uncomment typemaps marked 'Replacement rtypecheck typemaps' in rtype.swg.
// There is a slight difference in output as the typemap approach fixes some bugs due to a missing type resolution below
if (tm) {
String *tmcode = NULL;
Printf(f->code, "%s", j == 0 ? "" : " && ");
if (num_arguments != 1)
Printf(f->code, "(");
Printf(f->code, " ");
if (Strcmp(tm, "numeric") == 0) {
Printf(f->code, "is.numeric(argv[[%d]])", j+1);
tmcode = NewString("is.numeric($arg)");
} else if (Strcmp(tm, "integer") == 0) {
Printf(f->code, "(is.integer(argv[[%d]]) || is.numeric(argv[[%d]]))", j+1, j+1);
tmcode = NewString("(is.integer($arg) || is.numeric($arg))");
} else if (Strcmp(tm, "character") == 0) {
Printf(f->code, "is.character(argv[[%d]])", j+1);
tmcode = NewString("is.character($arg)");
} else {
if (SwigType_ispointer(Getattr(p, "type")))
Printf(f->code, "(extends(argtypes[%d], '%s') || is.null(argv[[%d]]))", j+1, tm, j+1);
Printf(f->code, "extends(argtypes[%d], '%s') || is.null(argv[[%d]])", j+1, tm, j+1);
else
Printf(f->code, "extends(argtypes[%d], '%s')", j+1, tm);
Printf(f->code, "extends(argtypes[%d], '%s') && length(argv[[%d]]) == 1", j+1, tm, j+1);
}
}
if (!SwigType_ispointer(Getattr(p, "type"))) {
Printf(f->code, " && length(argv[[%d]]) == 1", j+1);
if (tmcode) {
if (!SwigType_ispointer(Getattr(p, "type")))
Printf(tmcode, " && length($arg) == 1");
Swig_warning(WARN_R_MISSING_RTYPECHECK_TYPEMAP, input_file, line_number,
"Optional rtypecheck code is deprecated. Add the following typemap to fix as the next version of SWIG will not work without it: %%typemap(\"rtypecheck\") %s %%{ %s %%}\n",
SwigType_str(Getattr(p, "type"), 0), tmcode);
String *tmp_arg = NewStringf("argv[[%d]]", j+1);
Replaceall(tmcode, "$arg", tmp_arg);
Printv(f->code, tmcode, NIL);
Delete(tmp_arg);
}
Printf(f->code, " ");
if (num_arguments != 1)
Printf(f->code, ")");
Delete(tmcode);
}
p = Getattr(p, "tmap:in:next");
}
@ -1651,11 +1670,12 @@ void R::dispatchFunction(Node *n) {
}
}
if (cur_args != -1) {
Printf(f->code, "} else {\n"
"stop(\"cannot find overloaded function for %s with argtypes (\","
"toString(argtypes),\")\");\n"
"}", sfname);
Printf(f->code, "};\n");
}
Printf(f->code, "if (is.null(f)) {\n"
"stop(\"cannot find overloaded function for %s with argtypes (\","
"toString(argtypes),\")\");\n"
"}", sfname);
Printv(f->code, ";\nf(...)", NIL);
Printv(f->code, ";\n}", NIL);
Wrapper_print(f, sfile);
@ -1971,6 +1991,13 @@ int R::functionWrapper(Node *n) {
}
Printv(f->def, ")\n{\n", NIL);
// SWIG_fail in R leads to a call to Rf_error() which calls longjmp()
// which means the destructors of any live function-local C++ objects won't
// get run. To avoid this happening, we wrap almost everything in the
// function in a block, and end that right before Rf_error() at which
// point those destructors will get called.
if (CPlusPlus) Append(f->def, "{\n");
Printv(sfun->def, ")\n{\n", NIL);
@ -2083,15 +2110,6 @@ int R::functionWrapper(Node *n) {
/*If the user gave us something to convert the result in */
if ((tm = Swig_typemap_lookup("scoerceout", n, Swig_cresult_name(), sfun))) {
Replaceall(tm,"$result","ans");
if (constructor) {
Node * parent = Getattr(n, "parentNode");
String * smartname = Getattr(parent, "feature:smartptr");
if (smartname) {
smartname = getRClassName(smartname, 1, 1);
Replaceall(tm, "$R_class", smartname);
Delete(smartname);
}
}
if (debugMode) {
Printf(stdout, "Calling replace B: %s, %s, %s\n", Getattr(n, "type"), Getattr(n, "sym:name"), getNSpace());
}
@ -2124,6 +2142,7 @@ int R::functionWrapper(Node *n) {
if (need_cleanup) {
Printv(f->code, cleanup, NIL);
}
if (CPlusPlus) Append(f->code, "}\n");
Printv(f->code, " Rf_error(\"%s %s\", SWIG_ErrorType(SWIG_lasterror_code), SWIG_lasterror_msg);\n", NIL);
Printv(f->code, " return R_NilValue;\n", NIL);
Delete(cleanup);
@ -2288,7 +2307,6 @@ int R::outputRegistrationRoutines(File *out) {
void R::registerClass(Node *n) {
String *name = Getattr(n, "name");
String *kind = Getattr(n, "kind");
if (debugMode)
Swig_print_node(n);
@ -2297,7 +2315,7 @@ void R::registerClass(Node *n) {
Setattr(SClassDefs, sname, sname);
String *base;
if(Strcmp(kind, "class") == 0) {
if (CPlusPlus && (Strcmp(nodeType(n), "class") == 0)) {
base = NewString("");
List *l = Getattr(n, "bases");
if(Len(l)) {
@ -2317,31 +2335,6 @@ void R::registerClass(Node *n) {
Printf(s_classes, "setClass('%s', contains = %s)\n", sname, base);
Delete(base);
String *smartptr = Getattr(n, "feature:smartptr");
if (smartptr) {
List *l = Getattr(n, "bases");
SwigType *spt = Swig_cparse_type(smartptr);
String *smart = SwigType_typedef_resolve_all(spt);
String *smart_rname = SwigType_manglestr(smart);
Printf(s_classes, "setClass('_p%s', contains = c('%s'", smart_rname, sname);
Delete(spt);
Delete(smart);
Delete(smart_rname);
for(int i = 0; i < Len(l); i++) {
Node * b = Getitem(l, i);
smartptr = Getattr(b, "feature:smartptr");
if (smartptr) {
spt = Swig_cparse_type(smartptr);
smart = SwigType_typedef_resolve_all(spt);
smart_rname = SwigType_manglestr(smart);
Printf(s_classes, ", '_p%s'", smart_rname);
Delete(spt);
Delete(smart);
Delete(smart_rname);
}
}
Printf(s_classes, "))\n");
}
}
}
@ -2661,6 +2654,16 @@ String * R::runtimeCode() {
return s;
}
/*----------------------------------------------------------------------
* replaceSpecialVariables()
*--------------------------------------------------------------------*/
void R::replaceSpecialVariables(String *method, String *tm, Parm *parm) {
(void)method;
SwigType *type = Getattr(parm, "type");
replaceRClass(tm, type);
}
/* -----------------------------------------------------------------------
* Called when SWIG wants to initialize this

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* ruby.cxx
*
@ -85,7 +85,7 @@ public:
/* Mangled name */
Delete(mname);
mname = Swig_name_mangle(cname);
mname = Swig_name_mangle_string(cname);
/* Renamed class name */
Clear(name);
@ -1087,7 +1087,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGRUBY\n#define SWIGRUBY\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "RUBY");
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
@ -1871,26 +1871,8 @@ public:
else
Replaceall(tm, "$owner", "0");
#if 1
// FIXME: this will not try to unwrap directors returned as non-director
// base class pointers!
/* New addition to unwrap director return values so that the original
* Ruby object is returned instead.
*/
bool unwrap = false;
String *decl = Getattr(n, "decl");
int is_pointer = SwigType_ispointer_return(decl);
int is_reference = SwigType_isreference_return(decl);
if (is_pointer || is_reference) {
String *type = Getattr(n, "type");
Node *parent = Swig_methodclass(n);
Node *modname = Getattr(parent, "module");
Node *target = Swig_directormap(modname, type);
if (target)
unwrap = true;
}
if (unwrap) {
// Unwrap return values that are director classes so that the original Ruby object is returned instead.
if (Swig_director_can_unwrap(n)) {
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
Printf(f->code, "director = dynamic_cast<Swig::Director *>(%s);\n", Swig_cresult_name());
Printf(f->code, "if (director) {\n");
@ -1902,9 +1884,7 @@ public:
} else {
Printf(f->code, "%s\n", tm);
}
#else
Printf(f->code, "%s\n", tm);
#endif
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s.\n", SwigType_str(t, 0));

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* scilab.cxx
*
@ -200,7 +200,7 @@ public:
/* Output module initialization code */
Swig_banner(beginSection);
Printf(runtimeSection, "\n\n#ifndef SWIGSCILAB\n#define SWIGSCILAB\n#endif\n\n");
Swig_obligatory_macros(runtimeSection, "SCILAB");
// Gateway header source merged with wrapper source in nobuilder mode
if (!generateBuilder)
@ -957,11 +957,7 @@ public:
gatewayXML = NewString("");
Printf(gatewayXML, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
Printf(gatewayXML, "<!--\n");
Printf(gatewayXML, "This file was automatically generated by SWIG (http://www.swig.org).\n");
Printf(gatewayXML, "Version %s\n", Swig_package_version());
Printf(gatewayXML, "\n");
Printf(gatewayXML, "Do not make changes to this file unless you know what you are doing - modify\n");
Printf(gatewayXML, "the SWIG interface file instead.\n");
Swig_banner_target_lang(gatewayXML, "");
Printf(gatewayXML, "-->\n");
Printf(gatewayXML, "<GATEWAY name=\"%s\">\n", gatewayName);

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* swigmain.cxx
*
@ -72,7 +72,7 @@ static TargetLanguageModule modules[] = {
{"-perl5", swig_perl5, "Perl 5", Supported},
{"-php", swig_php, NULL, Supported},
{"-php5", NULL, "PHP 5", Disabled},
{"-php7", swig_php, "PHP 7", Supported},
{"-php7", swig_php, "PHP 7 or later", Supported},
{"-pike", NULL, "Pike", Disabled},
{"-python", swig_python, "Python", Supported},
{"-r", swig_r, "R (aka GNU S)", Supported},
@ -82,7 +82,7 @@ static TargetLanguageModule modules[] = {
{"-tcl", swig_tcl, NULL, Supported},
{"-tcl8", swig_tcl, "Tcl 8", Supported},
{"-uffi", NULL, "Common Lisp / UFFI", Disabled},
{"-xml", swig_xml, "XML", Experimental},
{"-xml", swig_xml, "XML", Supported},
{NULL, NULL, NULL, Disabled}
};

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* swigmod.h
*
@ -405,6 +405,7 @@ String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_Strin
String *Swig_director_declaration(Node *n);
void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f);
void Swig_director_parms_fixup(ParmList *parms);
bool Swig_director_can_unwrap(Node *n);
/* directors.cxx end */
/* Utilities */
@ -422,6 +423,7 @@ void Wrapper_cast_dispatch_mode_set(int);
void Wrapper_naturalvar_mode_set(int);
void clean_overloaded(Node *n);
SwigType *Swig_smartptr_upcast(SwigType *smart, SwigType *c_classname, SwigType *c_baseclassname);
extern "C" {
const char *Swig_to_string(DOH *object, int count = -1);

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* tcl8.cxx
*
@ -161,7 +161,7 @@ public:
Swig_banner(f_begin);
Printf(f_runtime, "\n\n#ifndef SWIGTCL\n#define SWIGTCL\n#endif\n\n");
Swig_obligatory_macros(f_runtime, "TCL");
/* Set the module name, namespace, and prefix */
@ -712,7 +712,7 @@ public:
virtual int classHandler(Node *n) {
static Hash *emitted = NewHash();
String *mangled_classname = 0;
String *real_classname = 0;
SwigType *real_classname = 0;
have_constructor = 0;
have_destructor = 0;
@ -740,7 +740,7 @@ public:
return SWIG_ERROR;
real_classname = Getattr(n, "name");
mangled_classname = Swig_name_mangle(real_classname);
mangled_classname = Swig_name_mangle_type(real_classname);
if (Getattr(emitted, mangled_classname))
return SWIG_NOWRAP;
@ -806,7 +806,7 @@ public:
int index = 0;
b = First(baselist);
while (b.item) {
String *bname = Getattr(b.item, "name");
SwigType *bname = Getattr(b.item, "name");
if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
b = Next(b);
continue;
@ -816,7 +816,7 @@ public:
Printv(base_classes, bname, " ", NIL);
Printv(base_class_init, " ", bname, "Ptr::constructor $ptr\n", NIL);
}
String *bmangle = Swig_name_mangle(bname);
String *bmangle = Swig_name_mangle_type(bname);
// Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL);
// Printf(base_class,"&_wrap_class_%s",bmangle);
Printf(base_class, "0");

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* typepass.cxx
*
@ -254,7 +254,7 @@ class TypePass:private Dispatcher {
int i;
for (i = 0; i < len; i++) {
Node *n = Getitem(ilist, i);
String *bname = Getattr(n, "name");
SwigType *bname = Getattr(n, "name");
Node *bclass = n; /* Getattr(n,"class"); */
Hash *scopes = Getattr(bclass, "typescope");
SwigType_inherit(clsname, bname, cast, 0);
@ -266,36 +266,20 @@ class TypePass:private Dispatcher {
/* Record a (fake) inheritance relationship between smart pointer
and smart pointer to base class, so that smart pointer upcasts
are automatically generated. */
SwigType *bsmart = Copy(smart);
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
SwigType *rbname = SwigType_typedef_resolve_all(bname);
int replace_count = Replaceall(bsmart, rclsname, rbname);
if (replace_count == 0) {
// If no replacement made, it will be because rclsname is fully resolved, but the
// type in the smartptr feature used a typedef or not fully resolved name.
String *firstname = Getattr(first, "name");
Replaceall(bsmart, firstname, rbname);
}
// The code above currently creates a smartptr of the base class by substitution, replacing Derived
// with Base resulting in something like: 'smartptr< Derived >' from 'smartptr< Base >'. Instead
// the feature:smartptr should be used as it also contains 'smartptr< Base >' as specified by the user.
// A similar fix should also be done in upcastsCode in java.cxx, csharp.cxx and writeClassUpcast in d.cxx.
// Printf(stdout, "smartcomparison %s <=> %s\n", SwigType_namestr(bsmart), Getattr(bclass, "feature:smartptr"));
Delete(rclsname);
Delete(rbname);
SwigType *bsmart = Swig_smartptr_upcast(smart, clsname, bname);
String *smartnamestr = SwigType_namestr(smart);
String *bsmartnamestr = SwigType_namestr(bsmart);
/* construct casting code */
String *convcode = NewStringf("\n *newmemory = SWIG_CAST_NEW_MEMORY;\n return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr);
Delete(bsmartnamestr);
Delete(smartnamestr);
/* setup inheritance relationship between smart pointer templates */
SwigType_inherit(smart, bsmart, 0, convcode);
if (!GetFlag(bclass, "feature:smartptr"))
Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name")));
Delete(bsmartnamestr);
Delete(smartnamestr);
Delete(convcode);
Delete(bsmart);
}
@ -462,6 +446,7 @@ class TypePass:private Dispatcher {
SwigType_typedef_class(fname);
scopename = Copy(fname);
} else {
// Does this code ever get executed ??
Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name));
Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name")));
scopename = 0;

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* utils.cxx
*
@ -115,6 +115,68 @@ void Swig_set_max_hash_expand(int count) {
SetMaxHashExpand(count);
}
/* -----------------------------------------------------------------------------
* misc_identifier_fix()
*
* If a template, return template with all template parameters fully resolved.
*
* This is a copy and modification of feature_identifier_fix and typemap_identifier_fix.
* ----------------------------------------------------------------------------- */
static SwigType *misc_identifier_fix(const SwigType *s) {
String *tp = SwigType_istemplate_templateprefix(s);
if (tp) {
String *ts, *ta, *tq, *tr;
ts = SwigType_templatesuffix(s);
ta = SwigType_templateargs(s);
tq = Swig_symbol_type_qualify(ta, 0);
tr = SwigType_typedef_resolve_all(ta);
Append(tp, tr);
Append(tp, ts);
Delete(ts);
Delete(ta);
Delete(tq);
Delete(tr);
}
return tp;
}
/* -----------------------------------------------------------------------------
* Swig_smartptr_upcast()
*
* Replace classname with baseclassname in smart (smart pointer) to morph smart into a
* smart pointer containing the base class instead of the given classname.
* All parameters should be fully qualified types.
* ----------------------------------------------------------------------------- */
SwigType *Swig_smartptr_upcast(SwigType *smart, SwigType *classname, SwigType *baseclassname) {
SwigType *bsmart = Copy(smart);
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
int replace_count = Replaceall(bsmart, rclassname, rbaseclassname);
if (replace_count == 0) {
// If no replacement made, it will be because rclassname is fully resolved, but the
// type in the smartptr feature used a typedef or is not a fully resolved name.
replace_count = Replaceall(bsmart, classname, rbaseclassname);
if (replace_count == 0) {
// Next try with all the template parameters in the smartptr resolved
Delete(bsmart);
SwigType *bsmart = misc_identifier_fix(smart);
if (bsmart) {
replace_count = Replaceall(bsmart, rclassname, rbaseclassname);
}
assert(replace_count); // failed to substitute
}
}
Delete(rbaseclassname);
Delete(rclassname);
return bsmart;
}
extern "C" {
/* -----------------------------------------------------------------------------

View file

@ -4,7 +4,7 @@
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
* and at https://www.swig.org/legal.html.
*
* xml.cxx
*
@ -118,7 +118,7 @@ public:
String *k;
indent_level += 4;
print_indent(0);
Printf(out, "<attributelist id=\"%ld\" addr=\"%p\" >\n", ++id, obj);
Printf(out, "<attributelist id=\"%ld\" addr=\"%p\">\n", ++id, obj);
indent_level += 4;
Iterator ki;
ki = First(obj);
@ -175,7 +175,7 @@ public:
}
indent_level -= 4;
print_indent(0);
Printf(out, "</attributelist >\n");
Printf(out, "</attributelist>\n");
indent_level -= 4;
}
@ -183,7 +183,7 @@ public:
Node *cobj;
print_indent(0);
Printf(out, "<%s id=\"%ld\" addr=\"%p\" >\n", nodeType(obj), ++id, obj);
Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", nodeType(obj), ++id, obj);
Xml_print_attributes(obj);
cobj = firstChild(obj);
if (cobj) {
@ -196,32 +196,32 @@ public:
Printf(out, "\n");
}
print_indent(0);
Printf(out, "</%s >\n", nodeType(obj));
Printf(out, "</%s>\n", nodeType(obj));
}
void Xml_print_parmlist(ParmList *p, const char* markup = "parmlist") {
print_indent(0);
Printf(out, "<%s id=\"%ld\" addr=\"%p\" >\n", markup, ++id, p);
Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", markup, ++id, p);
indent_level += 4;
while (p) {
print_indent(0);
Printf(out, "<parm id=\"%ld\">\n", ++id);
Xml_print_attributes(p);
print_indent(0);
Printf(out, "</parm >\n");
Printf(out, "</parm>\n");
p = nextSibling(p);
}
indent_level -= 4;
print_indent(0);
Printf(out, "</%s >\n", markup);
Printf(out, "</%s>\n", markup);
}
void Xml_print_baselist(List *p) {
print_indent(0);
Printf(out, "<baselist id=\"%ld\" addr=\"%p\" >\n", ++id, p);
Printf(out, "<baselist id=\"%ld\" addr=\"%p\">\n", ++id, p);
indent_level += 4;
Iterator s;
for (s = First(p); s.item; s = Next(s)) {
@ -232,7 +232,7 @@ public:
}
indent_level -= 4;
print_indent(0);
Printf(out, "</baselist >\n");
Printf(out, "</baselist>\n");
}
String *Xml_escape_string(String *str) {
@ -272,21 +272,21 @@ public:
void Xml_print_hash(Hash *p, const char *markup) {
print_indent(0);
Printf(out, "<%s id=\"%ld\" addr=\"%p\" >\n", markup, ++id, p);
Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", markup, ++id, p);
Xml_print_attributes(p);
indent_level += 4;
Iterator n = First(p);
while (n.key) {
print_indent(0);
Printf(out, "<%ssitem id=\"%ld\" addr=\"%p\" >\n", markup, ++id, n.item);
Printf(out, "<%ssitem id=\"%ld\" addr=\"%p\">\n", markup, ++id, n.item);
Xml_print_attributes(n.item);
print_indent(0);
Printf(out, "</%ssitem >\n", markup);
Printf(out, "</%ssitem>\n", markup);
n = Next(n);
}
indent_level -= 4;
print_indent(0);
Printf(out, "</%s >\n", markup);
Printf(out, "</%s>\n", markup);
}
};