diff options
Diffstat (limited to 'Source/Modules')
-rw-r--r-- | Source/Modules/csharp.cxx | 94 | ||||
-rw-r--r-- | Source/Modules/d.cxx | 79 | ||||
-rw-r--r-- | Source/Modules/go.cxx | 961 | ||||
-rw-r--r-- | Source/Modules/guile.cxx | 2 | ||||
-rw-r--r-- | Source/Modules/java.cxx | 121 | ||||
-rw-r--r-- | Source/Modules/javascript.cxx | 65 | ||||
-rw-r--r-- | Source/Modules/lang.cxx | 106 | ||||
-rw-r--r-- | Source/Modules/lua.cxx | 11 | ||||
-rw-r--r-- | Source/Modules/main.cxx | 29 | ||||
-rw-r--r-- | Source/Modules/modula3.cxx | 42 | ||||
-rw-r--r-- | Source/Modules/nested.cxx | 25 | ||||
-rw-r--r-- | Source/Modules/ocaml.cxx | 6 | ||||
-rw-r--r-- | Source/Modules/octave.cxx | 683 | ||||
-rw-r--r-- | Source/Modules/perl5.cxx | 26 | ||||
-rw-r--r-- | Source/Modules/php.cxx | 65 | ||||
-rw-r--r-- | Source/Modules/python.cxx | 454 | ||||
-rw-r--r-- | Source/Modules/ruby.cxx | 8 | ||||
-rw-r--r-- | Source/Modules/swigmain.cxx | 5 | ||||
-rw-r--r-- | Source/Modules/swigmod.h | 9 | ||||
-rw-r--r-- | Source/Modules/typepass.cxx | 3 |
20 files changed, 1696 insertions, 1098 deletions
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index d30bd18c5..3b1e03560 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -627,9 +627,11 @@ public: * ----------------------------------------------------------------------------- */ void emitBanner(File *f) { - Printf(f, "/* ----------------------------------------------------------------------------\n"); - Swig_banner_target_lang(f, " *"); - Printf(f, " * ----------------------------------------------------------------------------- */\n\n"); + Printf(f, "//------------------------------------------------------------------------------\n"); + Printf(f, "// <auto-generated />\n"); + Printf(f, "//\n"); + Swig_banner_target_lang(f, "//"); + Printf(f, "//------------------------------------------------------------------------------\n\n"); } /*----------------------------------------------------------------------- @@ -717,7 +719,7 @@ public: String *overloaded_name = getOverloadedName(n); if (!Getattr(n, "sym:overloaded")) { - if (!addSymbol(Getattr(n, "sym:name"), n, imclass_name)) + if (!addSymbol(symname, n, imclass_name)) return SWIG_ERROR; } @@ -912,21 +914,10 @@ public: String *null_attribute = 0; // Now write code to make the function call if (!native_function_flag) { - if (Cmp(nodeType(n), "constant") == 0) { - // Wrapping a constant hack - Swig_save("functionWrapper", n, "wrap:action", NIL); - - // below based on Swig_VargetToFunction() - SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n)); - Setattr(n, "wrap:action", NewStringf("%s = (%s)(%s);", Swig_cresult_name(), SwigType_lstr(ty, 0), Getattr(n, "value"))); - } Swig_director_emit_dynamic_cast(n, f); String *actioncode = emit_action(n); - if (Cmp(nodeType(n), "constant") == 0) - Swig_restore(n); - /* Return value if necessary */ if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { canThrow(n, "out", n); @@ -1088,15 +1079,13 @@ public: return ret; } - String *getCurrentScopeName(String *nspace) - { + String *getCurrentScopeName(String *nspace) { String *scope = 0; if (nspace || getCurrentClass()) { scope = NewString(""); if (nspace) Printf(scope, "%s", nspace); - if (Node* cls = getCurrentClass()) - { + if (Node* cls = getCurrentClass()) { if (Node *outer = Getattr(cls, "nested:outer")) { String *outerClassesPrefix = Copy(Getattr(outer, "sym:name")); for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { @@ -1266,6 +1255,7 @@ public: int unnamedinstance = GetFlag(parent, "unnamedinstance"); String *parent_name = Getattr(parent, "name"); String *nspace = getNSpace(); + String *newsymname = 0; String *tmpValue; // Strange hack from parent method @@ -1290,14 +1280,20 @@ public: { EnumFeature enum_feature = decodeEnumFeature(parent); + if ((enum_feature == SimpleEnum) && GetFlag(parent, "scopedenum")) { + newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname); + symname = newsymname; + } + // Add to language symbol table String *scope = 0; if (unnamedinstance || !parent_name || enum_feature == SimpleEnum) { - if (proxy_class_name) { + String *enumClassPrefix = getEnumClassPrefix(); + if (enumClassPrefix) { scope = NewString(""); if (nspace) Printf(scope, "%s.", nspace); - Printf(scope, "%s", proxy_class_name); + Printf(scope, "%s", enumClassPrefix); } else { scope = Copy(module_class_name); } @@ -1308,7 +1304,7 @@ public: else Printf(scope, ".%s", Getattr(parent, "sym:name")); } - if (!addSymbol(name, n, scope)) + if (!addSymbol(symname, n, scope)) return SWIG_ERROR; const String *csattributes = Getattr(n, "feature:cs:attributes"); @@ -1380,6 +1376,7 @@ public: Delete(scope); } + Delete(newsymname); Delete(tmpValue); Swig_restore(n); return SWIG_OK; @@ -3053,6 +3050,16 @@ public: // Use the C syntax to make a true C# constant and hope that it compiles as C# code value = Getattr(n, "enumvalue") ? Copy(Getattr(n, "enumvalue")) : Copy(Getattr(n, "enumvalueex")); } else { + String *newsymname = 0; + if (!getCurrentClass() || !proxy_flag) { + String *enumClassPrefix = getEnumClassPrefix(); + if (enumClassPrefix) { + // A global scoped enum + newsymname = Swig_name_member(0, enumClassPrefix, symname); + symname = newsymname; + } + } + // Get the enumvalue from a PINVOKE call if (!getCurrentClass() || !cparse_cplusplus || !proxy_flag) { // Strange hack to change the name @@ -3061,7 +3068,7 @@ public: value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); } else { memberconstantHandler(n); - value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), Swig_name_member(0, proxy_class_name, symname))); + value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), Swig_name_member(0, getEnumClassPrefix(), symname))); } } } @@ -3199,43 +3206,6 @@ public: } /* ----------------------------------------------------------------------------- - * makeParameterName() - * - * Inputs: - * n - Node - * p - parameter node - * arg_num - parameter argument number - * setter - set this flag when wrapping variables - * Return: - * arg - a unique parameter name - * ----------------------------------------------------------------------------- */ - - String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter) { - - String *arg = 0; - String *pn = Getattr(p, "name"); - - // Use C parameter name unless it is a duplicate or an empty parameter name - int count = 0; - ParmList *plist = Getattr(n, "parms"); - while (plist) { - if ((Cmp(pn, Getattr(plist, "name")) == 0)) - count++; - plist = nextSibling(plist); - } - String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0; - arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn); - - if (setter && Cmp(arg, "self") != 0) { - // Note that in C# properties, the input variable name is always called 'value' - Delete(arg); - arg = NewString("value"); - } - - return arg; - } - - /* ----------------------------------------------------------------------------- * emitTypeWrapperClass() * ----------------------------------------------------------------------------- */ @@ -4283,6 +4253,10 @@ public: Delete(dirclassname); } + /*---------------------------------------------------------------------- + * nestedClassesSupport() + *--------------------------------------------------------------------*/ + NestedClassSupport nestedClassesSupport() const { return NCS_Full; } diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 419828ea1..8546372ea 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -803,24 +803,24 @@ public: // Emit each enum item. Language::enumDeclaration(n); - if (!GetFlag(n, "nonempty")) { - // Do not wrap empty enums; the resulting D code would be illegal. - Delete(proxy_enum_code); - return SWIG_NOWRAP; - } - - // Finish the enum. - if (typemap_lookup_type) { - Printv(proxy_enum_code, - lookupCodeTypemap(n, "dcode", typemap_lookup_type, WARN_NONE), // Extra D code - "\n}\n", NIL); + if (GetFlag(n, "nonempty")) { + // Finish the enum. + if (typemap_lookup_type) { + Printv(proxy_enum_code, + lookupCodeTypemap(n, "dcode", typemap_lookup_type, WARN_NONE), // Extra D code + "\n}\n", NIL); + } else { + // Handle anonymous enums. + Printv(proxy_enum_code, "\n}\n", NIL); + } + Replaceall(proxy_enum_code, "$dclassname", symname); } else { - // Handle anonymous enums. - Printv(proxy_enum_code, "\n}\n", NIL); + // D enum declarations must have at least one member to be legal, so emit + // an alias to int instead (their ctype/imtype is always int). + Delete(proxy_enum_code); + proxy_enum_code = NewStringf("\nalias int %s;\n", symname); } - Replaceall(proxy_enum_code, "$dclassname", symname); - const String* imports = lookupCodeTypemap(n, "dimports", typemap_lookup_type, WARN_NONE); String* imports_trimmed; @@ -1701,21 +1701,10 @@ public: String *null_attribute = 0; // Now write code to make the function call if (!native_function_flag) { - if (Cmp(nodeType(n), "constant") == 0) { - // Wrapping a constant hack - Swig_save("functionWrapper", n, "wrap:action", NIL); - - // below based on Swig_VargetToFunction() - SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n)); - Setattr(n, "wrap:action", NewStringf("%s = (%s) %s;", Swig_cresult_name(), SwigType_lstr(ty, 0), Getattr(n, "value"))); - } Swig_director_emit_dynamic_cast(n, f); String *actioncode = emit_action(n); - if (Cmp(nodeType(n), "constant") == 0) - Swig_restore(n); - /* Return value if necessary */ if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { canThrow(n, "out", n); @@ -2594,7 +2583,7 @@ private: const_String_or_char_ptr wrapper_function_name) { // TODO: Add support for static linking here. - Printf(im_dmodule_code, "extern(C) %s function%s %s;\n", return_type, + Printf(im_dmodule_code, "SwigExternC!(%s function%s) %s;\n", return_type, parameters, d_name); Printv(wrapper_loader_bind_code, wrapper_loader_bind_command, NIL); Replaceall(wrapper_loader_bind_code, "$function", d_name); @@ -2850,7 +2839,7 @@ private: // polymorphic call or an explicit method call. Needed to prevent infinite // recursion when calling director methods. Node *explicit_n = Getattr(n, "explicitcallnode"); - if (explicit_n) { + if (explicit_n && Swig_directorclass(getCurrentClass())) { String *ex_overloaded_name = getOverloadedName(explicit_n); String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name); @@ -4299,40 +4288,8 @@ private: return proxyname; } - /* --------------------------------------------------------------------------- - * D::makeParameterName() - * - * Inputs: - * n - Node - * p - parameter node - * arg_num - parameter argument number - * setter - set this flag when wrapping variables - * Return: - * arg - a unique parameter name - * --------------------------------------------------------------------------- */ String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const { - String *arg = 0; - String *pn = Getattr(p, "name"); - - // Use C parameter name unless it is a duplicate or an empty parameter name - int count = 0; - ParmList *plist = Getattr(n, "parms"); - while (plist) { - if ((Cmp(pn, Getattr(plist, "name")) == 0)) - count++; - plist = nextSibling(plist); - } - String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0; - arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn); - - if (setter && Cmp(arg, "self") != 0) { - // In theory, we could use the normal parameter name for setter functions. - // Unfortunately, it is set to "Class::VariableName" for static public - // members by the parser, which is not legal D syntax. Thus, we just force - // it to "value". - Delete(arg); - arg = NewString("value"); - } + String *arg = Language::makeParameterName(n, p, arg_num, setter); if (split_proxy_dmodule && Strncmp(arg, package, Len(arg)) == 0) { // If we are in split proxy mode and the argument is named like the target diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index e84109faf..eac83a5a5 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -822,14 +822,13 @@ private: assert(result); - bool needs_wrapper; - int r = goFunctionWrapper(n, name, go_name, overname, wname, base, parms, result, is_static, &needs_wrapper); + int r = goFunctionWrapper(n, name, go_name, overname, wname, base, parms, result, is_static); if (r != SWIG_OK) { return r; } if (!gccgo_flag) { - r = gcFunctionWrapper(n, name, go_name, overname, wname, parms, result, is_static, needs_wrapper); + r = gcFunctionWrapper(wname); if (r != SWIG_OK) { return r; } @@ -862,12 +861,24 @@ private: * base class. * ---------------------------------------------------------------------- */ - int goFunctionWrapper(Node *n, String *name, String *go_name, String *overname, String *wname, List *base, ParmList *parms, SwigType *result, bool is_static, bool *p_needs_wrapper) { + int goFunctionWrapper(Node *n, String *name, String *go_name, String *overname, String *wname, List *base, ParmList *parms, SwigType *result, bool is_static) { Wrapper *dummy = NewWrapper(); emit_attach_parmmaps(parms, dummy); + + Parm *p = parms; + int parm_count = emit_num_arguments(parms); + for (int i = 0; i < parm_count; ++i) { + p = getParm(p); + Swig_cparm_name(p, i); + p = nextParm(p); + } + Swig_typemap_attach_parms("default", parms, dummy); Swig_typemap_attach_parms("gotype", parms, dummy); - int parm_count = emit_num_arguments(parms); + Swig_typemap_attach_parms("goin", parms, dummy); + Swig_typemap_attach_parms("goargout", parms, dummy); + Swig_typemap_attach_parms("imtype", parms, dummy); + int required_count = emit_num_required(parms); String *receiver = class_receiver; @@ -884,30 +895,44 @@ private: receiver = NULL; } + String *goout = Swig_typemap_lookup("goout", n, "swig_r", NULL); + bool add_to_interface = (interfaces && !is_constructor && !is_destructor && !is_static && !overname && checkFunctionVisibility(n, NULL)); bool needs_wrapper = (gccgo_flag || receiver || is_constructor || is_destructor || parm_count > required_count); + bool has_goout = false; + if (goout) { + has_goout = true; + } + // See whether any of the function parameters are represented by - // interface values When calling the C++ code, we need to convert + // interface values. When calling the C++ code, we need to convert // back to a uintptr. - if (!needs_wrapper) { - Parm *p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - String *ty = Getattr(p, "type"); - if (goTypeIsInterface(p, ty)) { - needs_wrapper = true; - break; - } - p = nextParm(p); + p = parms; + for (int i = 0; i < parm_count; ++i) { + p = getParm(p); + String *ty = Getattr(p, "type"); + if (Getattr(p, "tmap:goargout")) { + has_goout = true; + needs_wrapper = true; + } else if (goTypeIsInterface(p, ty) || Getattr(p, "tmap:goin")) { + needs_wrapper = true; } + + if (paramNeedsEscape(p)) { + needs_wrapper = true; + } + + p = nextParm(p); } - if (goTypeIsInterface(n, result)) { + if (goTypeIsInterface(n, result) || goout != NULL) { needs_wrapper = true; } - *p_needs_wrapper = needs_wrapper; + if (!gccgo_flag) { + Printv(f_go_wrappers, "var ", wname, " unsafe.Pointer\n\n", NULL); + } // If this is a method, first declare the C function we will call. // If we do not need a wrapper, then we will only be writing a @@ -920,25 +945,25 @@ private: Printv(f_go_wrappers, "//extern ", go_prefix, "_", wname, "\n", NULL); } + bool arg = false; Printv(f_go_wrappers, "func ", wrapper_name, "(", NULL); if (parm_count > required_count) { - Printv(f_go_wrappers, "int", NULL); + Printv(f_go_wrappers, argName(&arg), " int", NULL); } Parm *p = getParm(parms); - Swig_cparm_name(p, 0); int i = 0; if (is_destructor) { if (parm_count > required_count) { Printv(f_go_wrappers, ", ", NULL); } - Printv(f_go_wrappers, "uintptr", NULL); + Printv(f_go_wrappers, argName(&arg), " uintptr", NULL); ++i; p = nextParm(p); } else if (receiver && (base || !is_constructor)) { if (parm_count > required_count) { Printv(f_go_wrappers, ", ", NULL); } - Printv(f_go_wrappers, receiver, NULL); + Printv(f_go_wrappers, argName(&arg), " ", receiver, NULL); if (!base) { ++i; p = nextParm(p); @@ -946,27 +971,37 @@ private: } for (; i < parm_count; ++i) { p = getParm(p); - // Give the parameter a name we will use below. - Swig_cparm_name(p, i); if (i > 0 || (base && receiver) || parm_count > required_count) { Printv(f_go_wrappers, ", ", NULL); } String *tm = goWrapperType(p, Getattr(p, "type"), false); - Printv(f_go_wrappers, tm, NULL); + Printv(f_go_wrappers, argName(&arg), " ", tm, NULL); Delete(tm); p = nextParm(p); } Printv(f_go_wrappers, ")", NULL); if (is_constructor) { - Printv(f_go_wrappers, " ", class_receiver, NULL); + Printv(f_go_wrappers, " (", argName(&arg), " ", class_receiver, ")", NULL); } else { if (SwigType_type(result) != T_VOID) { String *tm = goWrapperType(n, result, true); - Printv(f_go_wrappers, " ", tm, NULL); + Printv(f_go_wrappers, " (", argName(&arg), " ", tm, ")", NULL); Delete(tm); } } + if (!gccgo_flag) { + Printv(f_go_wrappers, " {\n", NULL); + if (arg) { + Printv(f_go_wrappers, "\t_swig_p := uintptr(unsafe.Pointer(&base))\n", NULL); + } else { + Printv(f_go_wrappers, "\tvar _swig_p uintptr\n", NULL); + } + Printv(f_go_wrappers, "\t_cgo_runtime_cgocall(", wname, ", _swig_p)\n", NULL); + Printv(f_go_wrappers, "\treturn\n", NULL); + Printv(f_go_wrappers, "}", NULL); + } + Printv(f_go_wrappers, "\n\n", NULL); } @@ -978,16 +1013,23 @@ private: Printv(f_go_wrappers, "func ", NULL); - Parm *p = parms; + p = parms; int pi = 0; // Add the receiver if this is a method. + String *first = NULL; if (receiver) { Printv(f_go_wrappers, "(", NULL); if (base && receiver) { Printv(f_go_wrappers, "_swig_base", NULL); + if (first == NULL) { + first = NewString("_swig_base"); + } } else { Printv(f_go_wrappers, Getattr(p, "lname"), NULL); + if (first == NULL) { + first = Copy(Getattr(p, "lname")); + } p = nextParm(p); ++pi; } @@ -1015,6 +1057,9 @@ private: if (pi == 0 && is_destructor) { String *cl = exportedName(class_name); Printv(parm_print, Getattr(p, "lname"), " ", cl, NULL); + if (first == NULL) { + first = Copy(Getattr(p, "lname")); + } Delete(cl); } else { if (pi > (receiver && !base ? 1 : 0)) { @@ -1022,10 +1067,14 @@ private: } if (pi >= required_count) { Printv(parm_print, "_swig_args ...interface{}", NULL); + if (first == NULL) { + first = NewString("_swig_args"); + } break; } - if (needs_wrapper) { - Printv(parm_print, Getattr(p, "lname"), " ", NULL); + Printv(parm_print, Getattr(p, "lname"), " ", NULL); + if (first == NULL) { + first = Copy(Getattr(p, "lname")); } String *tm = goType(p, Getattr(p, "type")); Printv(parm_print, tm, NULL); @@ -1039,12 +1088,18 @@ private: // Write out the result type. if (is_constructor) { String *cl = exportedName(class_name); - Printv(parm_print, " ", cl, NULL); + Printv(parm_print, " (_swig_ret ", cl, ")", NULL); + if (first == NULL) { + first = NewString("_swig_ret"); + } Delete(cl); } else { if (SwigType_type(result) != T_VOID) { String *tm = goType(n, result); - Printv(parm_print, " ", tm, NULL); + Printv(parm_print, " (_swig_ret ", tm, ")", NULL); + if (first == NULL) { + first = NewString("_swig_ret"); + } Delete(tm); } } @@ -1077,46 +1132,49 @@ private: } } - if (gccgo_flag) { - if (!is_constructor) { - Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL); - Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL); + String *call = NewString(""); + + bool need_return_var = SwigType_type(result) != T_VOID && ((gccgo_flag && is_constructor) || has_goout); + if (need_return_var) { + Printv(f_go_wrappers, "\tvar swig_r ", NULL); + if (is_constructor) { + String *cl = exportedName(class_name); + Printv(f_go_wrappers, cl, NULL); + Delete(cl); } else { - // For a constructor the wrapper function will return a - // uintptr but we will return an interface. We want to - // convert the uintptr to the interface after calling - // SwigCgocallDone, so that we don't try to allocate memory - // while the Go scheduler can't see us. - Printv(f_go_wrappers, "\tvar done bool\n", NULL); - Printv(f_go_wrappers, "\tdefer func() {\n", NULL); - Printv(f_go_wrappers, "\t\tif !done {\n", NULL); - Printv(f_go_wrappers, "\t\t\tSwigCgocallDone()\n", NULL); - Printv(f_go_wrappers, "\t\t}\n", NULL); - Printv(f_go_wrappers, "\t}()\n", NULL); - Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL); + Printv(f_go_wrappers, goImType(n, result), NULL); + } + Printv(f_go_wrappers, "\n", NULL); + } + + if (gccgo_flag) { + if (has_goout || is_constructor) { + Printv(call, "\tfunc() {\n", NULL); } + Printv(call, "\tdefer SwigCgocallDone()\n", NULL); + Printv(call, "\tSwigCgocall()\n", NULL); } - Printv(f_go_wrappers, "\t", NULL); + Printv(call, "\t", NULL); if (SwigType_type(result) != T_VOID) { - if (gccgo_flag && is_constructor) { - Printv(f_go_wrappers, "swig_r := ", NULL); + if (need_return_var) { + Printv(call, "swig_r = ", NULL); } else { - Printv(f_go_wrappers, "return ", NULL); + Printv(call, "return ", NULL); } } - Printv(f_go_wrappers, wrapper_name, "(", NULL); + Printv(call, wrapper_name, "(", NULL); if (parm_count > required_count) { - Printv(f_go_wrappers, "len(_swig_args)", NULL); + Printv(call, "len(_swig_args)", NULL); } if (base && receiver) { if (parm_count > required_count) { - Printv(f_go_wrappers, ", ", NULL); + Printv(call, ", ", NULL); } - Printv(f_go_wrappers, "_swig_base", NULL); + Printv(call, "_swig_base", NULL); } Parm *p = parms; @@ -1124,29 +1182,82 @@ private: p = getParm(p); if (i > 0 || (base && receiver) || parm_count > required_count) { - Printv(f_go_wrappers, ", ", NULL); + Printv(call, ", ", NULL); + } + + SwigType *pt = Getattr(p, "type"); + String *ln = Getattr(p, "lname"); + + String *goin = Getattr(p, "tmap:goin"); + if (goin == NULL) { + Printv(call, ln, NULL); + if ((i == 0 && is_destructor) || ((i > 0 || !receiver || base || is_constructor) && goTypeIsInterface(p, pt))) { + Printv(call, ".Swigcptr()", NULL); + } + Setattr(p, "emit:goinput", ln); + } else { + String *ivar = NewString(""); + Printf(ivar, "_swig_i_%d", i); + String *itm = goImType(p, pt); + Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, NULL); + goin = Copy(goin); + Replaceall(goin, "$input", ln); + Replaceall(goin, "$result", ivar); + Printv(f_go_wrappers, goin, NULL); + Delete(goin); + Printv(call, ivar, NULL); + Setattr(p, "emit:goinput", ivar); } - Printv(f_go_wrappers, Getattr(p, "lname"), NULL); - // If this is a destructor, then the C function expects the - // C++ value, and we have the interface. We need to get the - // C++ value. The same is true for a type represented as an - // interface. - if ((i == 0 && is_destructor) || ((i > 0 || !receiver || base || is_constructor) && goTypeIsInterface(p, Getattr(p, "type")))) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + // If the parameter has an argout or freearg typemap, make + // sure that it escapes. + if (paramNeedsEscape(p)) { + Printv(f_go_wrappers, "\tif Swig_escape_always_false {\n", NULL); + Printv(f_go_wrappers, "\t\tSwig_escape_val = ", Getattr(p, "emit:goinput"), "\n", NULL); + Printv(f_go_wrappers, "\t}\n", NULL); } p = nextParm(p); } - Printv(f_go_wrappers, ")\n", NULL); + Printv(call, ")\n", NULL); + + if (gccgo_flag && (has_goout || is_constructor)) { + Printv(call, "\t}()\n", NULL); + } - if (gccgo_flag && is_constructor) { - Printv(f_go_wrappers, "\tSwigCgocallDone()\n", NULL); - Printv(f_go_wrappers, "\tdone = true\n", NULL); - Printv(f_go_wrappers, "\treturn swig_r\n", NULL); + Printv(f_go_wrappers, call, NULL); + Delete(call); + + goargout(parms, parm_count); + + if (need_return_var) { + if (goout == NULL) { + Printv(f_go_wrappers, "\treturn swig_r\n", NULL); + } else { + String *tm = goType(n, result); + Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL); + Replaceall(goout, "$input", "swig_r"); + Replaceall(goout, "$result", "swig_r_1"); + Printv(f_go_wrappers, goout, NULL); + Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL); + } } Printv(f_go_wrappers, "}\n", NULL); + } else if (!gccgo_flag) { + // We don't need a wrapper. If we're using gccgo, the function + // declaration is all we need--it has a //extern comment to + // GCC-compiled wrapper. If we're not using gccgo, we need to + // call the GCC-compiled wrapper here. + Printv(f_go_wrappers, " {\n", NULL); + if (first == NULL) { + Printv(f_go_wrappers, "\tvar _swig_p uintptr\n", NULL); + } else { + Printv(f_go_wrappers, "\t_swig_p := uintptr(unsafe.Pointer(&", first, "))\n", NULL); + } + Printv(f_go_wrappers, "\t_cgo_runtime_cgocall(", wname, ", _swig_p)\n", NULL); + Printv(f_go_wrappers, "\treturn\n", NULL); + Printv(f_go_wrappers, "}", NULL); } Printv(f_go_wrappers, "\n", NULL); @@ -1158,118 +1269,72 @@ private: } /* ---------------------------------------------------------------------- - * gcFunctionWrapper() + * argName() * - * This is used for 6g/8g, not for gccgo. Write out the function - * wrapper which will be compiled with 6c/8c. + * A helper for goFunctionWrapper to output the first argument name + * as "base" and all others as "_". * ---------------------------------------------------------------------- */ - int gcFunctionWrapper(Node *n, String *name, String *go_name, String *overname, String *wname, ParmList *parms, SwigType *result, bool is_static, bool needs_wrapper) { - Wrapper *f = NewWrapper(); - - Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"\"\n", NULL); - Printv(f->def, "#pragma cgo_import_static ", wname, "\n", NULL); - Printv(f->def, "extern void (*", wname, ")(void*);\n", NULL); - Printv(f->def, "static void (*x", wname, ")(void*) = ", wname, ";\n", NULL); - Printv(f->def, "\n", NULL); - Printv(f->def, "void\n", NULL); - - Wrapper *dummy = NewWrapper(); - emit_attach_parmmaps(parms, dummy); - Swig_typemap_attach_parms("default", parms, dummy); - Swig_typemap_attach_parms("gosize", parms, dummy); - int parm_count = emit_num_arguments(parms); - int required_count = emit_num_required(parms); - - String *parm_size = NewString(""); - - if (parm_count > required_count) { - Append(parm_size, "SWIG_PARM_SIZE"); - } - - if (class_receiver && !is_static) { - if (Len(parm_size) > 0) { - Append(parm_size, " + "); - } - Append(parm_size, "SWIG_PARM_SIZE"); + const char *argName(bool *arg) { + if (*arg) { + return "_"; } + *arg = true; + return "base"; + } - Parm *p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - addGcTypeSize(p, Getattr(p, "type"), parm_size); - p = nextParm(p); + /* ---------------------------------------------------------------------- + * paramNeedsEscape() + * + * A helper for goFunctionWrapper that returns whether a parameter + * needs to explicitly escape. This is true if the parameter has a + * non-empty argout or freearg typemap, because in those cases the + * Go argument might be or contain a pointer. We need to ensure + * that that pointer does not oint into the stack, which means that + * it needs to escape. + * ---------------------------------------------------------------------- */ + bool paramNeedsEscape(Parm *p) { + String *argout = Getattr(p, "tmap:argout"); + String *freearg = Getattr(p, "tmap:freearg"); + if ((!argout || Len(argout) == 0) && (!freearg || Len(freearg) == 0)) { + return false; } - - if (SwigType_type(result) != T_VOID) { - addGcTypeSize(n, result, parm_size); + // If a C++ type is represented as an interface type in Go, then + // we don't care whether it escapes, because we know that the + // pointer is a C++ pointer. + if (goTypeIsInterface(p, Getattr(p, "type"))) { + return false; } + return true; + } - if (Len(parm_size) == 0) { - Append(parm_size, "1"); - } + /* ---------------------------------------------------------------------- + * gcFunctionWrapper() + * + * This is used for 6g/8g, not for gccgo. Write out the function + * redirector that will be compiled with 6c/8c. This used to write + * out a real function wrapper, but that has moved into Go code. + * ---------------------------------------------------------------------- */ - String *fn_name; - if (!needs_wrapper) { - fn_name = Copy(go_name); - if (overname) { - Append(fn_name, overname); - } - } else { - fn_name = buildGoWrapperName(name, overname); - } + int gcFunctionWrapper(String *wname) { + Wrapper *f = NewWrapper(); + Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"\"\n", NULL); + Printv(f->def, "#pragma cgo_import_static ", wname, "\n", NULL); + Printv(f->def, "extern void ", wname, "(void*);\n", NULL); + // Declare this as a uintptr, since it is not a pointer into the + // Go heap. // \xc2\xb7 is UTF-8 for U+00B7 which is Unicode 'Middle Dot' - Printv(f->def, "\xc2\xb7", fn_name, "(struct { uint8 x[", parm_size, "];} p)", NULL); - - Delete(fn_name); - Delete(parm_size); - - Printv(f->code, "{\n", NULL); - Printv(f->code, "\truntime\xc2\xb7" "cgocall(x", wname, ", &p);\n", NULL); - Printv(f->code, "}\n", NULL); - Printv(f->code, "\n", NULL); + Printv(f->def, "uintptr \xc2\xb7", wname, " = (uintptr)", wname, ";\n", NULL); Wrapper_print(f, f_gc_wrappers); DelWrapper(f); - DelWrapper(dummy); return SWIG_OK; } /* ---------------------------------------------------------------------- - * getGcTypeSize() - * - * Return the size to use when passing a type from 6g/8g to 6c/8c. - * ---------------------------------------------------------------------- */ - - String *addGcTypeSize(Node *n, SwigType *type, String *orig) { - if (Len(orig) > 0) { - Append(orig, " + "); - } - - String *go = goType(n, type); - if (Cmp(go, "string") == 0) { - // A string has a pointer and a length. - Append(orig, "(2 * SWIG_PARM_SIZE)"); - } else if (Strncmp(go, "[]", 2) == 0) { - // A slice has a pointer, a length, and a capacity. - Append(orig, "(3 * SWIG_PARM_SIZE)"); - } else if (Strcmp(go, "float64") == 0) { - Append(orig, "8"); - } else if (Strcmp(go, "complex64") == 0) { - Append(orig, "8"); - } else if (Strcmp(go, "complex128") == 0) { - Append(orig, "16"); - } else { - Append(orig, "SWIG_PARM_SIZE"); - } - - return orig; - } - - /* ---------------------------------------------------------------------- * gccFunctionWrapper() * * This is used for 6g/8g, not for gccgo. Write out the function @@ -1315,11 +1380,19 @@ private: Parm *p = parms; for (int i = 0; i < parm_count; ++i) { p = getParm(p); + String *ln = Getattr(p, "lname"); SwigType *pt = Getattr(p, "type"); String *ct = gcCTypeForGoValue(p, pt, ln); Printv(f->code, "\t\t\t", ct, ";\n", NULL); Delete(ct); + + String *gn = NewStringf("_swig_go_%d", i); + ct = gcCTypeForGoValue(p, pt, gn); + Setattr(p, "emit:input", gn); + Wrapper_add_local(f, gn, ct); + Delete(ct); + p = nextParm(p); } if (SwigType_type(result) != T_VOID) { @@ -1329,27 +1402,39 @@ private: Delete(ln); Printv(f->code, "\t\t", ct, ";\n", NULL); Delete(ct); + + ln = NewString("_swig_go_result"); + ct = gcCTypeForGoValue(n, result, ln); + Wrapper_add_local(f, "_swig_go_result", ct); + Delete(ct); + Delete(ln); } Printv(f->code, "\t} *swig_a = (struct swigargs *) swig_v;\n", NULL); Printv(f->code, "\n", NULL); - // Copy the input arguments out of the structure into the - // parameter variables. - + // Copy the input arguments out of the structure into the Go local + // variables. p = parms; for (int i = 0; i < parm_count; ++i) { p = getParm(p); + String *ln = Getattr(p, "lname"); + String *gn = Getattr(p, "emit:input"); + Printv(f->code, "\t", gn, " = swig_a->", ln, ";\n", NULL); + p = nextParm(p); + } + // Apply the in typemaps. + p = parms; + for (int i = 0; i < parm_count; ++i) { + p = getParm(p); String *tm = Getattr(p, "tmap:in"); if (!tm) { Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument\n", SwigType_str(Getattr(p, "type"), 0)); } else { - String *ln = Getattr(p, "lname"); - String *input = NewString(""); - Printv(input, "swig_a->", ln, NULL); - Replaceall(tm, "$input", input); - Setattr(p, "emit:input", input); + tm = Copy(tm); + String *gn = Getattr(p, "emit:input"); + Replaceall(tm, "$input", gn); if (i < required_count) { Printv(f->code, "\t", tm, "\n", NULL); } else { @@ -1357,6 +1442,7 @@ private: Printv(f->code, "\t\t", tm, "\n", NULL); Printv(f->code, "\t}\n", NULL); } + Delete(tm); } p = nextParm(p); } @@ -1464,9 +1550,9 @@ private: Delete(fndef); if (SwigType_type(result) != T_VOID) { - String *ln = NewString("go_result"); + String *ln = NewString("_swig_go_result"); String *ct = gccgoCTypeForGoValue(n, result, ln); - Wrapper_add_local(f, "go_result", ct); + Wrapper_add_local(f, "_swig_go_result", ct); Delete(ct); Delete(ln); } @@ -1486,6 +1572,7 @@ private: String *ln = Getattr(p, "lname"); String *pn = NewString("g"); Append(pn, ln); + tm = Copy(tm); Replaceall(tm, "$input", pn); Setattr(p, "emit:input", pn); if (i < required_count) { @@ -1495,6 +1582,7 @@ private: Printv(f->code, " ", tm, "\n", NULL); Printv(f->code, " }\n", NULL); } + Delete(tm); } p = nextParm(p); @@ -1513,7 +1601,7 @@ private: cleanupFunction(n, f, parms); if (SwigType_type(result) != T_VOID) { - Printv(f->code, " return go_result;\n", NULL); + Printv(f->code, " return _swig_go_result;\n", NULL); } Printv(f->code, "}\n", NULL); @@ -1543,20 +1631,26 @@ private: if (!tm) { p = nextSibling(p); } else { + tm = Copy(tm); Replaceall(tm, "$input", Getattr(p, "emit:input")); Printv(f->code, tm, "\n\n", NULL); + Delete(tm); p = Getattr(p, "tmap:check:next"); } } } /* ----------------------------------------------------------------------- - * getGoAction() + * emitGoAction() * - * Get the action of the function. This is used for C/C++ function. + * Emit the action of the function. This is used for the C/C++ function. * ----------------------------------------------------------------------- */ void emitGoAction(Node *n, List *base, ParmList *parms, SwigType *result, Wrapper *f) { + if (!gccgo_flag && SwigType_type(result) != T_VOID) { + Wrapper_add_local(f, "swig_stktop", "char *swig_stktop"); + Printv(f->code, "\tswig_stktop = _swig_topofstack();\n", NULL); + } String *actioncode; if (!base || isStatic(n)) { Swig_director_emit_dynamic_cast(n, f); @@ -1593,12 +1687,7 @@ private: if (!tm) { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s\n", SwigType_str(result, 0)); } else { - if (!gccgo_flag) { - static const String *swig_a_result = NewStringf("swig_a->%s", Swig_cresult_name()); - Replaceall(tm, "$result", swig_a_result); - } else { - Replaceall(tm, "$result", "go_result"); - } + Replaceall(tm, "$result", "_swig_go_result"); if (GetFlag(n, "feature:new")) { Replaceall(tm, "$owner", "1"); } else { @@ -1608,6 +1697,14 @@ private: Delete(tm); } + if (!gccgo_flag && SwigType_type(result) != T_VOID) { + // If the function called back into the Go code, the stack might + // have been copied. We need to adjust swig_a accordingly here. + // This is what cgo does. + Printv(f->code, "\tswig_a = (struct swigargs*)((char*)swig_a + (_swig_topofstack() - swig_stktop));\n", NULL); + Printv(f->code, "\tswig_a->", Swig_cresult_name(), " = ", "_swig_go_result;\n", NULL); + } + Swig_restore(n); } @@ -1626,15 +1723,43 @@ private: if (!tm) { p = nextSibling(p); } else { + tm = Copy(tm); Replaceall(tm, "$result", Swig_cresult_name()); Replaceall(tm, "$input", Getattr(p, "emit:input")); Printv(f->code, tm, "\n", NULL); + Delete(tm); p = Getattr(p, "tmap:argout:next"); } } } /* ----------------------------------------------------------------------- + * goargout() + * + * Handle Go argument output code if any. This is used for the Go + * function. This assumes that each parameter has an "emit:goinput" + * property with the name to use to refer to that parameter. + * ----------------------------------------------------------------------- */ + + void goargout(ParmList *parms, int parm_count) { + Parm *p = parms; + for (int i = 0; i < parm_count; ++i) { + p = getParm(p); + String *tm = Getattr(p, "tmap:goargout"); + if (!tm) { + p = nextSibling(p); + } else { + tm = Copy(tm); + Replaceall(tm, "$result", "swig_r"); + Replaceall(tm, "$input", Getattr(p, "emit:goinput")); + Printv(f_go_wrappers, tm, NULL); + Delete(tm); + p = Getattr(p, "tmap:goargout:next"); + } + } + } + + /* ----------------------------------------------------------------------- * freearg() * * Handle argument cleanup code if any. This is used for the C/C++ @@ -1650,8 +1775,10 @@ private: if (!tm) { p = nextSibling(p); } else { + tm = Copy(tm); Replaceall(tm, "$input", Getattr(p, "emit:input")); Printv(ret, tm, "\n", NULL); + Delete(tm); p = Getattr(p, "tmap:freearg:next"); } } @@ -1835,12 +1962,26 @@ private: if (!is_public(n)) { return SWIG_OK; } - if (Getattr(parentNode(n), "unnamed")) { + + Swig_require("enumvalueDeclaration", n, "*sym:name", NIL); + Node *parent = parentNode(n); + + if (Getattr(parent, "unnamed")) { Setattr(n, "type", NewString("int")); } else { - Setattr(n, "type", Getattr(parentNode(n), "enumtype")); + Setattr(n, "type", Getattr(parent, "enumtype")); } - return goComplexConstant(n, Getattr(n, "type")); + + if (GetFlag(parent, "scopedenum")) { + String *symname = Getattr(n, "sym:name"); + symname = Swig_name_member(0, Getattr(parent, "sym:name"), symname); + Setattr(n, "sym:name", symname); + Delete(symname); + } + + int ret = goComplexConstant(n, Getattr(n, "type")); + Swig_restore(n); + return ret; } /* ----------------------------------------------------------------------- @@ -2047,7 +2188,7 @@ private: } Append(f_go_wrappers, interfaces); - Printf(f_go_wrappers, "}\n\n", NULL); + Printv(f_go_wrappers, "}\n\n", NULL); Delete(interfaces); interfaces = NULL; @@ -2640,6 +2781,7 @@ private: DelWrapper(dummy); Swig_typemap_attach_parms("gotype", parms, NULL); + Swig_typemap_attach_parms("imtype", parms, NULL); int parm_count = emit_num_arguments(parms); String *func_name = NewString("NewDirector"); @@ -2666,7 +2808,9 @@ private: if (!is_ignored) { // Declare the C++ wrapper. - if (gccgo_flag) { + if (!gccgo_flag) { + Printv(f_go_wrappers, "var ", wname, " unsafe.Pointer\n\n", NULL); + } else { Printv(f_go_wrappers, "//extern ", go_prefix, "_", wname, "\n", NULL); } @@ -2674,18 +2818,28 @@ private: if (overname) { Printv(f_go_wrappers, overname, NULL); } - Printv(f_go_wrappers, "(*", director_struct_name, NULL); + Printv(f_go_wrappers, "(_swig_director *", director_struct_name, NULL); p = parms; for (int i = 0; i < parm_count; ++i) { p = getParm(p); String *tm = goType(p, Getattr(p, "type")); - Printv(f_go_wrappers, ", ", tm, NULL); + Printv(f_go_wrappers, ", _ ", tm, NULL); Delete(tm); p = nextParm(p); } - Printv(f_go_wrappers, ") ", go_type_name, "\n\n", NULL); + Printv(f_go_wrappers, ") (_swig_ret ", go_type_name, ")", NULL); + + if (!gccgo_flag) { + Printv(f_go_wrappers, " {\n", NULL); + Printv(f_go_wrappers, "\t_swig_p := uintptr(unsafe.Pointer(&_swig_director))\n", NULL); + Printv(f_go_wrappers, "\t_cgo_runtime_cgocall(", wname, ", _swig_p)\n", NULL); + Printv(f_go_wrappers, "\treturn\n", NULL); + Printv(f_go_wrappers, "}", NULL); + } + + Printv(f_go_wrappers, "\n\n", NULL); Printv(f_go_wrappers, "func ", func_with_over_name, "(v interface{}", NULL); @@ -2754,8 +2908,7 @@ private: Setattr(n, "wrap:action", action); if (!gccgo_flag) { - int r = gcFunctionWrapper(n, fn_name, fn_name, overname, wname, - first_parm, result, is_static, false); + int r = gcFunctionWrapper(wname); if (r != SWIG_OK) { return r; } @@ -3075,6 +3228,7 @@ private: DelWrapper(dummy); Swig_typemap_attach_parms("gotype", parms, NULL); + Swig_typemap_attach_parms("imtype", parms, NULL); int parm_count = emit_num_arguments(parms); SwigType *result = Getattr(n, "type"); @@ -3122,6 +3276,9 @@ private: Swig_typemap_attach_parms("directorin", parms, w); Swig_typemap_attach_parms("directorargout", parms, w); + Swig_typemap_attach_parms("godirectorin", parms, w); + Swig_typemap_attach_parms("goin", parms, dummy); + Swig_typemap_attach_parms("goargout", parms, dummy); if (!is_ignored) { // We use an interface to see if this method is defined in Go. @@ -3155,17 +3312,19 @@ private: // Declare the upcall function, which calls the method on the // parent class. - if (gccgo_flag) { + if (!gccgo_flag) { + Printv(f_go_wrappers, "var ", upcall_wname, " unsafe.Pointer\n\n", NULL); + } else { Printv(f_go_wrappers, "//extern ", go_prefix, "_", upcall_wname, "\n", NULL); } - Printv(f_go_wrappers, "func ", upcall_gc_name, "(", go_type_name, NULL); + Printv(f_go_wrappers, "func ", upcall_gc_name, "(_swig_ptr ", go_type_name, NULL); p = parms; for (int i = 0; i < parm_count; ++i) { p = getParm(p); String *tm = goWrapperType(p, Getattr(p, "type"), false); - Printv(f_go_wrappers, ", ", tm, NULL); + Printv(f_go_wrappers, ", _ ", tm, NULL); Delete(tm); p = nextParm(p); } @@ -3174,11 +3333,19 @@ private: if (SwigType_type(result) != T_VOID) { String *tm = goWrapperType(n, result, true); - Printv(f_go_wrappers, " ", tm, NULL); + Printv(f_go_wrappers, " (_swig_ret ", tm, ")", NULL); Delete(tm); } - Printv(f_go_wrappers, "\n", NULL); + if (!gccgo_flag) { + Printv(f_go_wrappers, " {\n", NULL); + Printv(f_go_wrappers, "\t_swig_p := uintptr(unsafe.Pointer(&_swig_ptr))\n", NULL); + Printv(f_go_wrappers, "\t_cgo_runtime_cgocall(", upcall_wname, ", _swig_p)\n", NULL); + Printv(f_go_wrappers, "\treturn\n", NULL); + Printv(f_go_wrappers, "}", NULL); + } + + Printv(f_go_wrappers, "\n\n", NULL); } // Define the method on the director class in Go. @@ -3234,29 +3401,98 @@ private: if (GetFlag(n, "abstract")) { Printv(f_go_wrappers, "\tpanic(\"call to pure virtual method\")\n", NULL); } else { + bool has_goout = false; + String *goout = NULL; + if (SwigType_type(result) != T_VOID) { + Printv(f_go_wrappers, "\tvar swig_r ", goImType(n, result), "\n", NULL); + goout = Swig_typemap_lookup("goout", n, "swig_r", NULL); + if (goout) { + has_goout = true; + } + } + + p = parms; + for (int i = 0; i < parm_count; ++i) { + p = getParm(p); + if (Getattr(p, "tmap:goargout")) { + has_goout = true; + } + p = nextParm(p); + } + + String *call = NewString(""); + if (gccgo_flag) { - Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL); - Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL); + if (has_goout) { + Printv(call, "\tfunc() {\n", NULL); + } + Printv(call, "\tdefer SwigCgocallDone()\n", NULL); + Printv(call, "\tSwigCgocall()\n", NULL); } - Printv(f_go_wrappers, "\t", NULL); + Printv(call, "\t", NULL); if (SwigType_type(result) != T_VOID) { - Printv(f_go_wrappers, "return ", NULL); + Printv(call, "swig_r = ", NULL); } - Printv(f_go_wrappers, upcall_gc_name, "(swig_p.", go_type_name, NULL); + Printv(call, upcall_gc_name, "(swig_p.", go_type_name, NULL); p = parms; for (int i = 0; i < parm_count; ++i) { + Printv(call, ", ", NULL); p = getParm(p); SwigType *pt = Getattr(p, "type"); - Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL); - if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + + String *ln = Getattr(p, "lname"); + + // This is an ordinary call from Go to C++, so adjust using + // the goin typemap. + String *goin = Getattr(p, "tmap:goin"); + if (goin == NULL) { + Printv(call, ln, NULL); + if (goTypeIsInterface(p, pt)) { + Printv(call, ".Swigcptr()", NULL); + } + Setattr(p, "emit:goinput", ln); + } else { + String *ivar = NewString(""); + Printf(ivar, "_swig_i_%d", i); + String *itm = goImType(p, pt); + Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, NULL); + goin = Copy(goin); + Replaceall(goin, "$input", ln); + Replaceall(goin, "$result", ivar); + Printv(f_go_wrappers, goin, NULL); + Delete(goin); + Printv(call, ivar, NULL); + Setattr(p, "emit:goinput", ivar); } + p = nextParm(p); } - Printv(f_go_wrappers, ")\n", NULL); + Printv(call, ")\n", NULL); + + if (gccgo_flag && has_goout) { + Printv(call, "\t}()\n", NULL); + } + + Printv(f_go_wrappers, call, NULL); + Delete(call); + + goargout(parms, parm_count); + + if (SwigType_type(result) != T_VOID) { + if (goout == NULL) { + Printv(f_go_wrappers, "\treturn swig_r\n", NULL); + } else { + String *tm = goType(n, result); + Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL); + Replaceall(goout, "$input", "swig_r"); + Replaceall(goout, "$result", "swig_r_1"); + Printv(f_go_wrappers, goout, NULL); + Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL); + } + } } Printv(f_go_wrappers, "}\n\n", NULL); @@ -3341,7 +3577,7 @@ private: if (!gccgo_flag) { // Write the upcall wrapper function. This is compiled by gc // and calls the C++ function. - int r = gcFunctionWrapper(n, upcall_name, upcall_name, overname, upcall_wname, first_parm, result, is_static, true); + int r = gcFunctionWrapper(upcall_wname); if (r != SWIG_OK) { return r; } @@ -3389,29 +3625,86 @@ private: Printv(f_go_wrappers, " {\n", NULL); + String *goout = NULL; + if (SwigType_type(result) != T_VOID) { + Printv(f_go_wrappers, "\tvar swig_r ", goImType(n, result), "\n", NULL); + goout = Swig_typemap_lookup("goout", n, "swig_r", NULL); + } + + String *call = NewString(""); + if (gccgo_flag) { - Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL); - Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL); + if (goout != NULL) { + Printv(call, "\tfunc() {\n", NULL); + } + Printv(call, "\tdefer SwigCgocallDone()\n", NULL); + Printv(call, "\tSwigCgocall()\n", NULL); } - Printv(f_go_wrappers, "\t", NULL); + Printv(call, "\t", NULL); if (SwigType_type(result) != T_VOID) { - Printv(f_go_wrappers, "return ", NULL); + Printv(call, "swig_r = ", NULL); } - Printv(f_go_wrappers, upcall_gc_name, "(p.(*", director_struct_name, ").", go_type_name, NULL); + Printv(call, upcall_gc_name, "(p.(*", director_struct_name, ").", go_type_name, NULL); p = parms; for (int i = 0; i < parm_count; ++i) { + Printv(call, ", ", NULL); p = getParm(p); SwigType *pt = Getattr(p, "type"); - Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL); + + String *ln = Copy(Getattr(p, "lname")); if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, ".Swigcptr()", NULL); + Printv(ln, ".Swigcptr()", NULL); + } + + String *goin = Getattr(p, "tmap:goin"); + if (goin == NULL) { + Printv(call, ln, NULL); + Setattr(p, "emit:goinput", ln); + } else { + String *ivar = NewString(""); + Printf(ivar, "_swig_i_%d", i); + String *itm = goImType(p, pt); + Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, NULL); + goin = Copy(goin); + Replaceall(goin, "$input", ln); + Replaceall(goin, "$result", ivar); + Printv(f_go_wrappers, goin, NULL); + Delete(goin); + Printv(call, ivar, NULL); + Setattr(p, "emit:goinput", ivar); } + + Delete(ln); + p = nextParm(p); } - Printv(f_go_wrappers, ")\n", NULL); + Printv(call, ")\n", NULL); + + if (gccgo_flag && goout != NULL) { + Printv(call, "\t}()\n", NULL); + } + + Printv(f_go_wrappers, call, NULL); + Delete(call); + + goargout(parms, parm_count); + + if (SwigType_type(result) != T_VOID) { + if (goout == NULL) { + Printv(f_go_wrappers, "\treturn swig_r\n", NULL); + } else { + String *tm = goType(n, result); + Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL); + Replaceall(goout, "$input", "swig_r"); + Replaceall(goout, "$result", "swig_r_1"); + Printv(f_go_wrappers, goout, NULL); + Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL); + } + } + Printv(f_go_wrappers, "}\n\n", NULL); } @@ -3437,34 +3730,53 @@ private: } Printv(f_go_wrappers, "{\n", NULL); - if (gccgo_flag) { - Printv(f_go_wrappers, "\tSwigCgocallBack()\n", NULL); - Printv(f_go_wrappers, "\tdefer SwigCgocallBackDone()\n", NULL); - } - - Printv(f_go_wrappers, "\t", NULL); - if (is_ignored) { - Printv(f_go_wrappers, "return\n", NULL); + Printv(f_go_wrappers, "\treturn\n", NULL); } else { bool result_is_interface = false; + String *goout = NULL; if (SwigType_type(result) != T_VOID) { - Printv(f_go_wrappers, "return ", NULL); result_is_interface = goTypeIsInterface(NULL, result); + Printv(f_go_wrappers, "\tvar swig_r ", NULL); + if (!result_is_interface) { + Printv(f_go_wrappers, goType(n, result), NULL); + } else { + Printv(f_go_wrappers, result_wrapper, NULL); + } + Printv(f_go_wrappers, "\n", NULL); + goout = Swig_typemap_lookup("godirectorout", n, "swig_r", NULL); + } + + String *call = NewString(""); + + if (gccgo_flag) { + if (goout != NULL) { + Printv(call, "\tfunc() {\n", NULL); + } + Printv(call, "\tSwigCgocallBack()\n", NULL); + Printv(call, "\tdefer SwigCgocallBackDone()\n", NULL); + } + + Printv(call, "\t", NULL); + + if (SwigType_type(result) != T_VOID) { + Printv(call, "swig_r = ", NULL); if (result_is_interface) { - Printv(f_go_wrappers, result_wrapper, "(", NULL); + Printv(call, result_wrapper, "(", NULL); } } - Printv(f_go_wrappers, "p.", go_with_over_name, "(", NULL); + Printv(call, "p.", go_with_over_name, "(", NULL); p = parms; for (int i = 0; i < parm_count; ++i) { p = getParm(p); if (i > 0) { - Printv(f_go_wrappers, ", ", NULL); + Printv(call, ", ", NULL); } SwigType *pt = Getattr(p, "type"); + String *ln = NewString(""); + // If the Go representation is an interface type class, then // we are receiving a uintptr, and must convert to the // interface. @@ -3473,26 +3785,64 @@ private: // Passing is_result as true to goWrapperType gives us the // name of the Go type we need to convert to an interface. String *wt = goWrapperType(p, pt, true); - Printv(f_go_wrappers, wt, "(", NULL); + Printv(ln, wt, "(", NULL); Delete(wt); } - Printv(f_go_wrappers, Getattr(p, "lname"), NULL); + Printv(ln, Getattr(p, "lname"), NULL); if (is_interface) { - Printv(f_go_wrappers, ")", NULL); + Printv(ln, ")", NULL); } + String *goin = Getattr(p, "tmap:godirectorin"); + if (goin == NULL) { + Printv(call, ln, NULL); + } else { + String *ivar = NewString(""); + Printf(ivar, "_swig_i_%d", i); + String *itm = goType(p, pt); + Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, NULL); + goin = Copy(goin); + Replaceall(goin, "$input", ln); + Replaceall(goin, "$result", ivar); + Printv(f_go_wrappers, goin, NULL); + Delete(goin); + Printv(call, ivar, NULL); + Delete(ivar); + } + + Delete(ln); + p = nextParm(p); } - Printv(f_go_wrappers, ")", NULL); + Printv(call, ")", NULL); if (result_is_interface) { - Printv(f_go_wrappers, ".Swigcptr())", NULL); + Printv(call, ".Swigcptr())", NULL); } + Printv(call, "\n", NULL); - Printv(f_go_wrappers, "\n", NULL); + if (gccgo_flag && goout != NULL) { + Printv(call, "\t}()\n", NULL); + } + + Printv(f_go_wrappers, call, NULL); + Delete(call); + + if (SwigType_type(result) != T_VOID) { + if (goout == NULL) { + Printv(f_go_wrappers, "\treturn swig_r\n", NULL); + } else { + String *tm = goImType(n, result); + Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL); + Replaceall(goout, "$input", "swig_r"); + Replaceall(goout, "$result", "swig_r_1"); + Printv(f_go_wrappers, goout, NULL); + Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL); + } + } } Printv(f_go_wrappers, "}\n\n", NULL); @@ -3610,6 +3960,7 @@ private: Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "Unable to use type %s as director method argument\n", SwigType_str(Getattr(p, "type"), 0)); } else { + tm = Copy(tm); String *ln = Getattr(p, "lname"); String *input = NewString(""); Printv(input, "swig_a.", ln, NULL); @@ -3618,12 +3969,28 @@ private: Replaceall(tm, "$owner", "0"); Delete(input); Printv(w->code, "\t", tm, "\n", NULL); + Delete(tm); } p = Getattr(p, "tmap:directorin:next"); } Printv(w->code, " crosscall2(", callback_wname, ", &swig_a, (int) sizeof swig_a);\n", NULL); + /* Marshal outputs */ + for (p = parms; p;) { + String *tm; + if ((tm = Getattr(p, "tmap:directorargout"))) { + tm = Copy(tm); + Replaceall(tm, "$result", "jresult"); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); + Printv(w->code, tm, "\n", NIL); + Delete(tm); + p = Getattr(p, "tmap:directorargout:next"); + } else { + p = nextSibling(p); + } + } + if (SwigType_type(result) != T_VOID) { String *result_str = NewString("c_result"); String *tm = Swig_typemap_lookup("directorout", n, result_str, NULL); @@ -3672,7 +4039,7 @@ private: String *pn = NewString("g"); Append(pn, Getattr(p, "lname")); - Setattr(p, "emit:input", pn); + Setattr(p, "emit:directorinput", pn); String *tm = gccgoCTypeForGoValue(n, Getattr(p, "type"), pn); Wrapper_add_local(w, pn, tm); @@ -3683,9 +4050,11 @@ private: Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "Unable to use type %s as director method argument\n", SwigType_str(Getattr(p, "type"), 0)); } else { + tm = Copy(tm); Replaceall(tm, "$input", pn); Replaceall(tm, "$owner", 0); Printv(w->code, " ", tm, "\n", NULL); + Delete(tm); Printv(args, ", ", pn, NULL); } @@ -3699,6 +4068,21 @@ private: } Printv(w->code, callback_wname, "(go_val", args, ");\n", NULL); + /* Marshal outputs */ + for (p = parms; p;) { + String *tm; + if ((tm = Getattr(p, "tmap:directorargout"))) { + tm = Copy(tm); + Replaceall(tm, "$result", "jresult"); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); + Printv(w->code, tm, "\n", NIL); + Delete(tm); + p = Getattr(p, "tmap:directorargout:next"); + } else { + p = nextSibling(p); + } + } + if (SwigType_type(result) != T_VOID) { String *result_str = NewString("c_result"); String *tm = Swig_typemap_lookup("directorout", n, result_str, NULL); @@ -3717,19 +4101,6 @@ private: Delete(result_str); } } - - /* Marshal outputs */ - for (p = parms; p;) { - String *tm; - if ((tm = Getattr(p, "tmap:directorargout"))) { - Replaceall(tm, "$result", "jresult"); - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } } else { assert(is_pure_virtual); Printv(w->code, " _swig_gopanic(\"call to pure virtual function ", Getattr(parent, "sym:name"), name, "\");\n", NULL); @@ -4057,7 +4428,7 @@ private: } fn = i + 1; - Printf(f_go_wrappers, "\t\tif _, ok := a[%d].(%s); !ok {\n", j, tm); + Printf(f_go_wrappers, "\t\tif _, ok := a[%d].(%s); !ok {\n", j, goType(pj, Getattr(pj, "type"))); Printf(f_go_wrappers, "\t\t\tgoto check_%d\n", fn); Printv(f_go_wrappers, "\t\t}\n", NULL); } @@ -4462,7 +4833,19 @@ private: * ---------------------------------------------------------------------- */ String *goType(Node *n, SwigType *type) { - return goTypeWithInfo(n, type, NULL); + return goTypeWithInfo(n, type, false, NULL); + } + + /* ---------------------------------------------------------------------- + * goImType() + * + * Given a SWIG type, return a string for the intermediate Go type + * to pass to C/C++. This is like goType except that it looks for + * an imtype typemap entry first. + * ---------------------------------------------------------------------- */ + + String *goImType(Node *n, SwigType *type) { + return goTypeWithInfo(n, type, true, NULL); } /* ---------------------------------------------------------------------- @@ -4470,6 +4853,8 @@ private: * * Like goType, but return some more information. * + * If use_imtype is true, this look for a imtype typemap entry. + * * If the p_is_interface parameter is not NULL, this sets * *p_is_interface to indicate whether this type is going to be * represented by a Go interface type. These are cases where the Go @@ -4477,24 +4862,39 @@ private: * forth with C/C++. * ---------------------------------------------------------------------- */ - String *goTypeWithInfo(Node *n, SwigType *type, bool *p_is_interface) { + String *goTypeWithInfo(Node *n, SwigType *type, bool use_imtype, bool *p_is_interface) { if (p_is_interface) { *p_is_interface = false; } - String *ret; - if (n && Cmp(type, Getattr(n, "type")) == 0) { - ret = NULL; - if (Strcmp(Getattr(n, "nodeType"), "parm") == 0) { - ret = Getattr(n, "tmap:gotype"); + String *ret = NULL; + if (use_imtype) { + if (n && Cmp(type, Getattr(n, "type")) == 0) { + if (Strcmp(Getattr(n, "nodeType"), "parm") == 0) { + ret = Getattr(n, "tmap:imtype"); + } + if (!ret) { + ret = Swig_typemap_lookup("imtype", n, "", NULL); + } + } else { + Parm *p = NewParm(type, "goImType", n); + ret = Swig_typemap_lookup("imtype", p, "", NULL); + Delete(p); } - if (!ret) { - ret = Swig_typemap_lookup("gotype", n, "", NULL); + } + if (!ret) { + if (n && Cmp(type, Getattr(n, "type")) == 0) { + if (Strcmp(Getattr(n, "nodeType"), "parm") == 0) { + ret = Getattr(n, "tmap:gotype"); + } + if (!ret) { + ret = Swig_typemap_lookup("gotype", n, "", NULL); + } + } else { + Parm *p = NewParm(type, "goType", n); + ret = Swig_typemap_lookup("gotype", p, "", NULL); + Delete(p); } - } else { - Parm *p = NewParm(type, "goType", n); - ret = Swig_typemap_lookup("gotype", p, "", NULL); - Delete(p); } if (ret && Strstr(ret, "$gotypename") != 0) { @@ -4563,7 +4963,7 @@ private: ret = NewString("uintptr"); } else { bool is_interface; - String *base = goTypeWithInfo(n, r, &is_interface); + String *base = goTypeWithInfo(n, r, false, &is_interface); // At the Go level, an unknown or class type is handled as an // interface wrapping a pointer. This means that if a @@ -4627,12 +5027,12 @@ private: if (add_pointer) { SwigType_add_pointer(r); } - ret = goTypeWithInfo(n, r, p_is_interface); + ret = goTypeWithInfo(n, r, false, p_is_interface); Delete(r); } else if (SwigType_isqualifier(t)) { SwigType *r = Copy(t); SwigType_del_qualifier(r); - ret = goTypeWithInfo(n, r, p_is_interface); + ret = goTypeWithInfo(n, r, false, p_is_interface); Delete(r); } else if (SwigType_isvarargs(t)) { ret = NewString("[]interface{}"); @@ -4658,7 +5058,7 @@ private: String *goWrapperType(Node *n, SwigType *type, bool is_result) { bool is_interface; - String *ret = goTypeWithInfo(n, type, &is_interface); + String *ret = goTypeWithInfo(n, type, true, &is_interface); // If this is an interface, we want to pass the real type. if (is_interface) { @@ -4742,7 +5142,18 @@ private: String *gcCTypeForGoValue(Node *n, SwigType *type, String *name) { bool is_interface; - String *gt = goTypeWithInfo(n, type, &is_interface); + String *gt = goTypeWithInfo(n, type, true, &is_interface); + + String *tail = NewString(""); + SwigType *t = SwigType_typedef_resolve_all(type); + if (!SwigType_isreference(t)) { + while (Strncmp(gt, "*", 1) == 0) { + Replace(gt, "*", "", DOH_REPLACE_FIRST); + Printv(tail, "*", NULL); + } + } + Delete(t); + bool is_string = Strcmp(gt, "string") == 0; bool is_slice = Strncmp(gt, "[]", 2) == 0; bool is_function = Strcmp(gt, "_swig_fnptr") == 0; @@ -4770,18 +5181,21 @@ private: if (is_string) { // Note that we don't turn a reference to a string into a // pointer to a string. Strings are immutable anyhow. - ret = NewString("_gostring_ "); - Append(ret, name); + ret = NewString(""); + Printv(ret, "_gostring_", tail, " ", name, NULL); + Delete(tail); return ret; } else if (is_slice) { // Slices are always passed as a _goslice_, whether or not references // are involved. - ret = NewString("_goslice_ "); - Append(ret, name); + ret = NewString(""); + Printv(ret, "_goslice_", tail, " ", name, NULL); + Delete(tail); return ret; } else if (is_function || is_member) { - ret = NewString("void *"); - Append(ret, name); + ret = NewString(""); + Printv(ret, "void*", tail, " ", name, NULL); + Delete(tail); return ret; } else if (is_complex64) { ret = NewString("_Complex float "); @@ -4798,6 +5212,7 @@ private: SwigType_add_pointer(t); ret = SwigType_lstr(t, name); Delete(t); + Delete(tail); return ret; } else { SwigType *t = SwigType_typedef_resolve_all(type); @@ -4821,6 +5236,7 @@ private: } Delete(q); Delete(t); + Delete(tail); return ret; } } @@ -4853,14 +5269,17 @@ private: } else if (is_float64) { ret = NewString("double "); } else { + Delete(tail); return SwigType_lstr(type, name); } } + Append(ret, tail); if (SwigType_isreference(type)) { Append(ret, "* "); } Append(ret, name); + Delete(tail); return ret; } @@ -4885,7 +5304,7 @@ private: bool goTypeIsInterface(Node *n, SwigType *type) { bool is_interface; - Delete(goTypeWithInfo(n, type, &is_interface)); + Delete(goTypeWithInfo(n, type, false, &is_interface)); return is_interface; } diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx index a9e51fd1b..1c135b53d 100644 --- a/Source/Modules/guile.cxx +++ b/Source/Modules/guile.cxx @@ -1350,7 +1350,7 @@ public: Printv(f_header, tm, "\n", NIL); } else { // Create variable and assign it a value - Printf(f_header, "static %s = %s;\n", SwigType_str(type, var_name), rvalue); + Printf(f_header, "static %s = (%s)(%s);\n", SwigType_str(type, var_name), SwigType_str(type, 0), rvalue); } { /* Hack alert: will cleanup later -- Dave */ diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 9e16bb422..82ecb41a4 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -209,7 +209,7 @@ public: String *symname = Copy(Getattr(n, "sym:name")); if (symname && !GetFlag(n, "feature:flatnested")) { for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) { - Push(symname, "."); + Push(symname, jnidescriptor ? "$" : "."); Push(symname, Getattr(outer_class, "sym:name")); } } @@ -838,7 +838,7 @@ public: bool is_destructor = (Cmp(Getattr(n, "nodeType"), "destructor") == 0); if (!Getattr(n, "sym:overloaded")) { - if (!addSymbol(Getattr(n, "sym:name"), n, imclass_name)) + if (!addSymbol(symname, n, imclass_name)) return SWIG_ERROR; } @@ -1039,26 +1039,15 @@ public: } } + // Now write code to make the function call if (!native_function_flag) { - if (Cmp(nodeType(n), "constant") == 0) { - // Wrapping a constant hack - Swig_save("functionWrapper", n, "wrap:action", NIL); - // below based on Swig_VargetToFunction() - SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n)); - Setattr(n, "wrap:action", NewStringf("%s = (%s)(%s);", Swig_cresult_name(), SwigType_lstr(ty, 0), Getattr(n, "value"))); - } - - // Now write code to make the function call Swig_director_emit_dynamic_cast(n, f); String *actioncode = emit_action(n); // Handle exception classes specified in the "except" feature's "throws" attribute addThrows(n, "feature:except", n); - if (Cmp(nodeType(n), "constant") == 0) - Swig_restore(n); - /* Return value if necessary */ if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { addThrows(n, "tmap:out", n); @@ -1194,15 +1183,13 @@ public: return ret; } - String *getCurrentScopeName(String *nspace) - { + String *getCurrentScopeName(String *nspace) { String *scope = 0; if (nspace || getCurrentClass()) { scope = NewString(""); if (nspace) Printf(scope, "%s", nspace); - if (Node* cls = getCurrentClass()) - { + if (Node* cls = getCurrentClass()) { if (Node *outer = Getattr(cls, "nested:outer")) { String *outerClassesPrefix = Copy(Getattr(outer, "sym:name")); for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { @@ -1370,6 +1357,7 @@ public: int unnamedinstance = GetFlag(parent, "unnamedinstance"); String *parent_name = Getattr(parent, "name"); String *nspace = getNSpace(); + String *newsymname = 0; String *tmpValue; // Strange hack from parent method @@ -1394,14 +1382,20 @@ public: { EnumFeature enum_feature = decodeEnumFeature(parent); + if ((enum_feature == SimpleEnum) && GetFlag(parent, "scopedenum")) { + newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname); + symname = newsymname; + } + // Add to language symbol table String *scope = 0; if (unnamedinstance || !parent_name || enum_feature == SimpleEnum) { - if (proxy_class_name) { + String *enumClassPrefix = getEnumClassPrefix(); + if (enumClassPrefix) { scope = NewString(""); if (nspace) Printf(scope, "%s.", nspace); - Printf(scope, "%s", proxy_class_name); + Printf(scope, "%s", enumClassPrefix); } else { scope = Copy(constants_interface_name); } @@ -1412,7 +1406,7 @@ public: else Printf(scope, ".%s", Getattr(parent, "sym:name")); } - if (!addSymbol(name, n, scope)) + if (!addSymbol(symname, n, scope)) return SWIG_ERROR; if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) { @@ -1466,6 +1460,7 @@ public: Delete(scope); } + Delete(newsymname); Delete(tmpValue); Swig_restore(n); return SWIG_OK; @@ -2268,7 +2263,7 @@ public: Printf(imcall, "swigCPtr"); String *this_type = Copy(getClassType()); - String *name = NewString("self"); + String *name = NewString("jself"); String *qualifier = Getattr(n, "qualifier"); if (qualifier) SwigType_push(this_type, qualifier); @@ -2959,6 +2954,16 @@ public: // Use the C syntax to make a true Java constant and hope that it compiles as Java code value = Getattr(n, "enumvalue") ? Copy(Getattr(n, "enumvalue")) : Copy(Getattr(n, "enumvalueex")); } else { + String *newsymname = 0; + if (!getCurrentClass() || !proxy_flag) { + String *enumClassPrefix = getEnumClassPrefix(); + if (enumClassPrefix) { + // A global scoped enum + newsymname = Swig_name_member(0, enumClassPrefix, symname); + symname = newsymname; + } + } + // Get the enumvalue from a JNI call if (!getCurrentClass() || !cparse_cplusplus || !proxy_flag) { // Strange hack to change the name @@ -2967,8 +2972,9 @@ public: value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); } else { memberconstantHandler(n); - value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), Swig_name_member(0, proxy_class_name, symname))); + value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), Swig_name_member(0, getEnumClassPrefix(), symname))); } + Delete(newsymname); } } return value; @@ -3116,44 +3122,6 @@ public: } /* ----------------------------------------------------------------------------- - * makeParameterName() - * - * Inputs: - * n - Node - * p - parameter node - * arg_num - parameter argument number - * setter - set this flag when wrapping variables - * Return: - * arg - a unique parameter name - * ----------------------------------------------------------------------------- */ - - String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter) { - - String *arg = 0; - String *pn = Getattr(p, "name"); - - // Use C parameter name unless it is a duplicate or an empty parameter name - int count = 0; - ParmList *plist = Getattr(n, "parms"); - while (plist) { - if ((Cmp(pn, Getattr(plist, "name")) == 0)) - count++; - plist = nextSibling(plist); - } - String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0; - arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn); - - if (setter && Cmp(arg, "self") != 0) { - // Note that for setters the parameter name is always set but sometimes includes C++ - // scope resolution, so we need to strip off the scope resolution to make a valid name. - Delete(arg); - arg = NewString("value"); //Swig_scopename_last(pn); - } - - return arg; - } - - /* ----------------------------------------------------------------------------- * emitTypeWrapperClass() * ----------------------------------------------------------------------------- */ @@ -3670,7 +3638,6 @@ public: * --------------------------------------------------------------- */ int classDirectorMethod(Node *n, Node *parent, String *super) { - String *classname = Getattr(parent, "sym:name"); String *c_classname = Getattr(parent, "name"); String *name = Getattr(n, "name"); String *symname = Getattr(n, "sym:name"); @@ -3704,14 +3671,7 @@ public: String *imcall_args = NewString(""); int classmeth_off = curr_class_dmethod - first_class_dmethod; bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; - String *qualified_classname = Copy(classname); - String *nspace = getNSpace(); - - if (nspace && package) - Insert(qualified_classname, 0, NewStringf("%s.%s.", package, nspace)); - else if(nspace) - Insert(qualified_classname, 0, NewStringf("%s.", nspace)); - + String *qualified_classname = getProxyName(getClassName()); // Kludge Alert: functionWrapper sets sym:overload properly, but it // isn't at this point, so we have to manufacture it ourselves. At least @@ -3772,7 +3732,7 @@ public: /* Create the intermediate class wrapper */ tm = Swig_typemap_lookup("jtype", n, "", 0); if (tm) { - Printf(callback_def, " public static %s %s(%s self", tm, imclass_dmethod, qualified_classname); + 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)); } @@ -3834,7 +3794,6 @@ public: } Delete(adjustedreturntypeparm); - Delete(qualified_classname); Swig_director_parms_fixup(l); @@ -3889,7 +3848,7 @@ public: Printf(w->code, "if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) {\n"); } - /* Start the Java field descriptor for the intermediate class's upcall (insert self object) */ + /* Start the Java field descriptor for the intermediate class's upcall (insert jself object) */ Parm *tp = NewParmNode(c_classname, n); String *jdesc; @@ -4100,7 +4059,7 @@ public: /* Emit the intermediate class's upcall to the actual class */ - String *upcall = NewStringf("self.%s(%s)", symname, imcall_args); + String *upcall = NewStringf("jself.%s(%s)", symname, imcall_args); // Handle exception classes specified in the "except" feature's "throws" attribute addThrows(n, "feature:except", n); @@ -4475,18 +4434,15 @@ public: * ------------------------------------------------------------ */ int classDirectorEnd(Node *n) { - String *classname = Getattr(n, "sym:name"); + String *full_classname = Getattr(n, "name"); + String *classname = getProxyName(full_classname, true); String *director_classname = directorClassName(n); String *internal_classname; Wrapper *w = NewWrapper(); - if (Len(package_path) > 0 && Len(getNSpace()) > 0) - internal_classname = NewStringf("%s/%s/%s", package_path, getNSpace(), classname); - else if (Len(package_path) > 0) + if (Len(package_path) > 0) internal_classname = NewStringf("%s/%s", package_path, classname); - else if (Len(getNSpace()) > 0) - internal_classname = NewStringf("%s/%s", getNSpace(), classname); else internal_classname = NewStringf("%s", classname); @@ -4598,6 +4554,7 @@ public: /*---------------------------------------------------------------------- * extraDirectorProtectedCPPMethodsRequired() *--------------------------------------------------------------------*/ + bool extraDirectorProtectedCPPMethodsRequired() const { return false; } @@ -4623,6 +4580,10 @@ public: Setattr(n, "director:ctor", class_ctor); } + /*---------------------------------------------------------------------- + * nestedClassesSupport() + *--------------------------------------------------------------------*/ + NestedClassSupport nestedClassesSupport() const { return NCS_Full; } diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 20af76f9f..0c3f02a75 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -318,6 +318,10 @@ public: **/ virtual int fragmentDirective(Node *n); +public: + + virtual String *getNSpace() const; + private: JSEmitter *emitter; @@ -467,6 +471,10 @@ int JAVASCRIPT::fragmentDirective(Node *n) { return SWIG_OK; } +String *JAVASCRIPT::getNSpace() const { + return Language::getNSpace(); +} + /* --------------------------------------------------------------------- * top() * @@ -716,19 +724,19 @@ int JSEmitter::emitWrapperFunction(Node *n) { // detected via the 'view' attribute. || (Equal(kind, "variable") && Equal(Getattr(n, "view"), "globalfunctionHandler")) ) { - bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); - bool is_static = GetFlag(state.function(), IS_STATIC); + bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0; + bool is_static = GetFlag(state.function(), IS_STATIC) != 0; ret = emitFunction(n, is_member, is_static); } else if (Cmp(kind, "variable") == 0) { - bool is_static = GetFlag(state.variable(), IS_STATIC); + bool is_static = GetFlag(state.variable(), IS_STATIC) != 0; // HACK: smartpointeraccessed static variables are not treated as statics if (GetFlag(n, "allocate:smartpointeraccess")) { is_static = false; } - bool is_member = GetFlag(n, "ismember"); - bool is_setter = GetFlag(n, "memberset") || GetFlag(n, "varset"); - bool is_getter = GetFlag(n, "memberget") || GetFlag(n, "varget"); + bool is_member = GetFlag(n, "ismember") != 0; + bool is_setter = GetFlag(n, "memberset") != 0 || GetFlag(n, "varset") != 0; + bool is_getter = GetFlag(n, "memberget") != 0 || GetFlag(n, "varget") != 0; if (is_setter) { ret = emitSetter(n, is_member, is_static); } else if (is_getter) { @@ -832,7 +840,7 @@ int JSEmitter::emitCtor(Node *n) { Wrapper *wrapper = NewWrapper(); - bool is_overloaded = GetFlag(n, "sym:overloaded"); + bool is_overloaded = GetFlag(n, "sym:overloaded") != 0; Template t_ctor(getTemplate("js_ctor")); @@ -1152,7 +1160,7 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { Wrapper *wrapper = NewWrapper(); Template t_function(getTemplate("js_function")); - bool is_overloaded = GetFlag(n, "sym:overloaded"); + bool is_overloaded = GetFlag(n, "sym:overloaded") != 0; // prepare the function wrapper name String *iname = Getattr(n, "sym:name"); @@ -1223,18 +1231,27 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { // substract the extension "sym:overname", String *wrap_name = NewString(Getattr(n, "wrap:name")); String *overname = Getattr(n, "sym:overname"); + + Node *methodclass = Swig_methodclass(n); + String *class_name = Getattr(methodclass, "sym:name"); + int l1 = Len(wrap_name); int l2 = Len(overname); Delslice(wrap_name, l1 - l2, l1); - Setattr(n, "wrap:name", wrap_name); - state.function(WRAPPER_NAME, wrap_name); + String *new_string = NewStringf("%s_%s", class_name, wrap_name); + String *final_wrap_name = Swig_name_wrapper(new_string); + + Setattr(n, "wrap:name", final_wrap_name); + state.function(WRAPPER_NAME, final_wrap_name); + + t_function.replace("$jslocals", wrapper->locals) .replace("$jscode", wrapper->code); // call this here, to replace all variables - t_function.replace("$jswrapper", wrap_name) + t_function.replace("$jswrapper", final_wrap_name) .replace("$jsname", state.function(NAME)) .pretty_print(f_wrappers); @@ -1280,7 +1297,7 @@ void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, Strin cresult = defaultResultName; tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode); - bool should_own = GetFlag(n, "feature:new"); + bool should_own = GetFlag(n, "feature:new") != 0; if (tm) { Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); @@ -1346,14 +1363,26 @@ int JSEmitter::switchNamespace(Node *n) { return SWIG_OK; } - String *nspace = Getattr(n, "sym:nspace"); - // if nspace is deactivated, everything goes into the global scope if (!GetFlag(n, "feature:nspace")) { current_namespace = Getattr(namespaces, "::"); return SWIG_OK; } +// EXPERIMENTAL: we want to use Language::getNSpace() here +// However, it is not working yet. +// For namespace functions Language::getNSpace() does not give a valid result +#if 0 + JAVASCRIPT *lang = static_cast<JAVASCRIPT*>(Language::instance()); + String *_nspace = lang->getNSpace(); + if (!Equal(nspace, _nspace)) { + Printf(stdout, "##### Custom vs Language::getNSpace(): %s | %s\n", nspace, _nspace); + Swig_print_node(n); + } +#endif + + String *nspace = Getattr(n, "sym:nspace"); + if (nspace == NULL) { // It seems that only classes have 'sym:nspace' set. // We try to get the namespace from the qualified name (i.e., everything before the last '::') @@ -1608,8 +1637,8 @@ int JSCEmitter::enterFunction(Node *n) { int JSCEmitter::exitFunction(Node *n) { Template t_function = getTemplate("jsc_function_declaration"); - bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); - bool is_overloaded = GetFlag(n, "sym:overloaded"); + bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0; + bool is_overloaded = GetFlag(n, "sym:overloaded") != 0; // handle overloaded functions if (is_overloaded) { @@ -2057,10 +2086,10 @@ int V8Emitter::exitVariable(Node *n) { } int V8Emitter::exitFunction(Node *n) { - bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); + bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0; // create a dispatcher for overloaded functions - bool is_overloaded = GetFlag(n, "sym:overloaded"); + bool is_overloaded = GetFlag(n, "sym:overloaded") != 0; if (is_overloaded) { if (!Getattr(n, "sym:nextSibling")) { //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 5ea79f0ab..3efd4e425 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -57,7 +57,9 @@ extern "C" { /* Some status variables used during parsing */ static int InClass = 0; /* Parsing C++ or not */ static String *ClassName = 0; /* This is the real name of the current class */ +static String *EnumClassName = 0; /* Enum class name */ static String *ClassPrefix = 0; /* Class prefix */ +static String *EnumClassPrefix = 0; /* Prefix for strongly typed enums (including ClassPrefix) */ static String *NSpace = 0; /* Namespace for the nspace feature */ static String *ClassType = 0; /* Fully qualified type name to use */ static String *DirectorClassName = 0; /* Director name of the current class */ @@ -1650,10 +1652,24 @@ int Language::enumDeclaration(Node *n) { String *oldNSpace = NSpace; NSpace = Getattr(n, "sym:nspace"); + String *oldEnumClassPrefix = EnumClassPrefix; + if (GetFlag(n, "scopedenum")) { + assert(Getattr(n, "sym:name")); + assert(Getattr(n, "name")); + EnumClassPrefix = ClassPrefix ? NewStringf("%s_", ClassPrefix) : NewString(""); + Printv(EnumClassPrefix, Getattr(n, "sym:name"), NIL); + EnumClassName = Copy(Getattr(n, "name")); + } if (!ImportMode) { emit_children(n); } + if (GetFlag(n, "scopedenum")) { + Delete(EnumClassName); + EnumClassName = 0; + Delete(EnumClassPrefix); + EnumClassPrefix = oldEnumClassPrefix; + } NSpace = oldNSpace; return SWIG_OK; @@ -1667,7 +1683,7 @@ int Language::enumvalueDeclaration(Node *n) { if (CurrentClass && (cplus_mode != PUBLIC)) return SWIG_NOWRAP; - Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL); + Swig_require("enumvalueDeclaration", n, "*name", "*sym:name", "?value", NIL); String *value = Getattr(n, "value"); String *name = Getattr(n, "name"); String *tmpValue; @@ -1678,6 +1694,13 @@ int Language::enumvalueDeclaration(Node *n) { tmpValue = NewString(name); Setattr(n, "value", tmpValue); + Node *parent = parentNode(n); + if (GetFlag(parent, "scopedenum")) { + String *symname = Swig_name_member(0, Getattr(parent, "sym:name"), Getattr(n, "sym:name")); + Setattr(n, "sym:name", symname); + Delete(symname); + } + if (!CurrentClass || !cparse_cplusplus) { Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */ constantWrapper(n); @@ -1716,16 +1739,19 @@ int Language::memberconstantHandler(Node *n) { Setattr(n, "feature:except", Getattr(n, "feature:exceptvar")); } + String *enumvalue_symname = Getattr(n, "enumvalueDeclaration:sym:name"); // Only set if a strongly typed enum String *name = Getattr(n, "name"); String *symname = Getattr(n, "sym:name"); String *value = Getattr(n, "value"); - String *mrename = Swig_name_member(0, ClassPrefix, symname); + String *mrename = Swig_name_member(0, EnumClassPrefix, enumvalue_symname ? enumvalue_symname : symname); Setattr(n, "sym:name", mrename); String *new_name = 0; if (Extend) new_name = Copy(value); + else if (EnumClassName) + new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : EnumClassName, name); else new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName, name); Setattr(n, "name", new_name); @@ -2043,7 +2069,7 @@ int Language::classDirectorConstructors(Node *n) { needed, since there is a public constructor already defined. (scottm) This code is needed here to make the director_abstract + - test generate compileable code (Example2 in director_abastract.i). + test generate compilable code (Example2 in director_abastract.i). (mmatus) This is very strange, since swig compiled with gcc3.2.3 doesn't need it here.... @@ -2369,6 +2395,7 @@ int Language::classDeclaration(Node *n) { int oldInClass = InClass; String *oldClassType = ClassType; String *oldClassPrefix = ClassPrefix; + String *oldEnumClassPrefix = EnumClassPrefix; String *oldClassName = ClassName; String *oldDirectorClassName = DirectorClassName; String *oldNSpace = NSpace; @@ -2410,6 +2437,7 @@ int Language::classDeclaration(Node *n) { Push(ClassPrefix, "_"); Push(ClassPrefix, Getattr(outerClass, "sym:name")); } + EnumClassPrefix = Copy(ClassPrefix); if (strip) { ClassType = Copy(name); } else { @@ -2477,6 +2505,8 @@ int Language::classDeclaration(Node *n) { CurrentClass = oldCurrentClass; Delete(ClassType); ClassType = oldClassType; + Delete(EnumClassPrefix); + EnumClassPrefix = oldEnumClassPrefix; Delete(ClassPrefix); ClassPrefix = oldClassPrefix; Delete(ClassName); @@ -2664,7 +2694,8 @@ int Language::constructorDeclaration(Node *n) { String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0; String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name); Delete(scope); - if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name)) { + if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name) && !SwigType_istemplate(actual_name)) { + // Checking templates is skipped but they ought to be checked... they are just somewhat more tricky to check correctly bool illegal_name = true; if (Extend) { // Check for typedef names used as a constructor name in %extend. This is deprecated except for anonymous @@ -2962,6 +2993,12 @@ int Language::variableWrapper(Node *n) { Delattr(n,"varset"); Delattr(n,"varget"); + String *newsymname = 0; + if (!CurrentClass && EnumClassPrefix) { + newsymname = Swig_name_member(0, EnumClassPrefix, symname); + symname = newsymname; + } + /* If no way to set variables. We simply create functions */ int assignable = is_assignable(n); int flags = use_naturalvar_mode(n); @@ -3019,6 +3056,7 @@ int Language::variableWrapper(Node *n) { functionWrapper(n); Delattr(n, "varget"); Swig_restore(n); + Delete(newsymname); return SWIG_OK; } @@ -3500,6 +3538,45 @@ int Language::is_smart_pointer() const { } /* ----------------------------------------------------------------------------- + * Language::makeParameterName() + * + * Inputs: + * n - Node + * p - parameter node + * arg_num - parameter argument number + * setter - set this flag when wrapping variables + * Return: + * arg - a unique parameter name + * ----------------------------------------------------------------------------- */ +String *Language::makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const { + + String *arg = 0; + String *pn = Getattr(p, "name"); + + // Use C parameter name unless it is a duplicate or an empty parameter name + int count = 0; + ParmList *plist = Getattr(n, "parms"); + while (plist) { + if ((Cmp(pn, Getattr(plist, "name")) == 0)) + count++; + plist = nextSibling(plist); + } + String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0; + arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn); + + if (setter && Cmp(arg, "self") != 0) { + // Some languages (C#) insist on calling the input variable "value" while + // others (D, Java) could, in principle, use something different but this + // would require more work, and so we just use "value" for them too. + // For setters the parameter name sometimes includes C++ scope resolution which needs removing. + Delete(arg); + arg = NewString("value"); + } + + return arg; +} + +/* ----------------------------------------------------------------------------- * Language::() * ----------------------------------------------------------------------------- */ @@ -3517,9 +3594,22 @@ bool Language::extraDirectorProtectedCPPMethodsRequired() const { return true; } +/* ----------------------------------------------------------------------------- + * Language::nestedClassesSupport() + * ----------------------------------------------------------------------------- */ + Language::NestedClassSupport Language::nestedClassesSupport() const { return NCS_Unknown; } + +/* ----------------------------------------------------------------------------- + * Language::kwargsSupport() + * ----------------------------------------------------------------------------- */ + +bool Language::kwargsSupport() const { + return false; +} + /* ----------------------------------------------------------------------------- * Language::is_wrapping_class() * ----------------------------------------------------------------------------- */ @@ -3561,6 +3651,14 @@ String *Language::getClassPrefix() const { } /* ----------------------------------------------------------------------------- + * Language::getEnumClassPrefix() + * ----------------------------------------------------------------------------- */ + +String *Language::getEnumClassPrefix() const { + return EnumClassPrefix; +} + +/* ----------------------------------------------------------------------------- * Language::getClassType() * ----------------------------------------------------------------------------- */ diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx index 46e21fb91..8211fb317 100644 --- a/Source/Modules/lua.cxx +++ b/Source/Modules/lua.cxx @@ -1184,10 +1184,12 @@ public: if (getCurrentClass() && (cplus_mode != PUBLIC)) return SWIG_NOWRAP; - Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL); + Swig_require("enumvalueDeclaration", n, "*name", "?value", "*sym:name", NIL); + String *symname = Getattr(n, "sym:name"); String *value = Getattr(n, "value"); String *name = Getattr(n, "name"); String *tmpValue; + Node *parent = parentNode(n); if (value) tmpValue = NewString(value); @@ -1196,6 +1198,13 @@ public: Setattr(n, "value", tmpValue); Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */ + + if (GetFlag(parent, "scopedenum")) { + symname = Swig_name_member(0, Getattr(parent, "sym:name"), symname); + Setattr(n, "sym:name", symname); + Delete(symname); + } + int result = constantWrapper(n); Delete(tmpValue); diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 833394b9c..aa0d7d589 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -50,6 +50,7 @@ int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime extern "C" { extern String *ModuleName; extern int ignore_nested_classes; + extern int kwargs_supported; } /* usage string split into multiple parts otherwise string is too big for some compilers */ @@ -62,6 +63,8 @@ static const char *usage1 = (const char *) "\ -co <file> - Check <file> out of the SWIG library\n\ -copyctor - Automatically generate copy constructors wherever possible\n\ -cpperraswarn - Treat the preprocessor #error statement as #warning (default)\n\ + -cppext <ext> - Change file extension of generated C++ files to <ext>\n\ + (default is cxx, except for PHP which uses cpp)\n\ -copyright - Display copyright notices\n\ -debug-classes - Display information about the classes found in the interface\n\ -debug-module <n>- Display module parse tree at stages 1-4, <n> is a csv list of stages\n\ @@ -79,6 +82,9 @@ static const char *usage1 = (const char *) "\ -directors - Turn on director mode for all the classes, mainly for testing\n\ -dirprot - Turn on wrapping of protected members for director classes (default)\n\ -D<symbol> - Define a symbol <symbol> (for conditional compilation)\n\ +"; + +static const char *usage2 = (const char *) "\ -E - Preprocess only, does not generate wrapper code\n\ -external-runtime [file] - Export the SWIG runtime stack\n\ -fakeversion <v>- Make SWIG fake the program version number to <v>\n\ @@ -86,9 +92,6 @@ static const char *usage1 = (const char *) "\ -features <list>- Set global features, where <list> is a comma separated list of\n\ features, eg -features directors,autodoc=1\n\ If no explicit value is given to the feature, a default of 1 is used\n\ -"; - -static const char *usage2 = (const char *) "\ -fastdispatch - Enable fast dispatch mode to produce faster overload dispatcher code\n\ -Fmicrosoft - Display error/warning messages in Microsoft format\n\ -Fstandard - Display error/warning messages in commonly used format\n\ @@ -100,6 +103,9 @@ static const char *usage2 = (const char *) "\ -importall - Follow all #include statements as imports\n\ -includeall - Follow all #include statements\n\ -l<ifile> - Include SWIG library file <ifile>\n\ +"; + +static const char *usage3 = (const char *) "\ -macroerrors - Report errors inside macros\n\ -makedefault - Create default constructors/destructors (the default)\n\ -M - List all dependencies\n\ @@ -119,10 +125,10 @@ static const char *usage2 = (const char *) "\ -noexcept - Do not wrap exception specifiers\n\ -nofastdispatch - Disable fast dispatch mode (default)\n\ -nopreprocess - Skip the preprocessor step\n\ + -notemplatereduce - Disable reduction of the typedefs in templates\n\ "; -static const char *usage3 = (const char *) "\ - -notemplatereduce - Disable reduction of the typedefs in templates\n\ +static const char *usage4 = (const char *) "\ -O - Enable the optimization options: \n\ -fastdispatch -fvirtual \n\ -o <outfile> - Set name of the output file to <outfile>\n\ @@ -677,6 +683,15 @@ void SWIG_getoptions(int argc, char *argv[]) { } else if (strcmp(argv[i], "-nocpperraswarn") == 0) { Preprocessor_error_as_warning(0); Swig_mark_arg(i); + } else if (strcmp(argv[i], "-cppext") == 0) { + Swig_mark_arg(i); + if (argv[i + 1]) { + SWIG_config_cppext(argv[i + 1]); + Swig_mark_arg(i + 1); + i++; + } else { + Swig_arg_error(); + } } else if ((strcmp(argv[i], "-debug-typemap") == 0) || (strcmp(argv[i], "-debug_typemap") == 0) || (strcmp(argv[i], "-tm_debug") == 0)) { tm_debug = 1; Swig_mark_arg(i); @@ -850,6 +865,7 @@ void SWIG_getoptions(int argc, char *argv[]) { fputs(usage1, stdout); fputs(usage2, stdout); fputs(usage3, stdout); + fputs(usage4, stdout); Swig_mark_arg(i); help = 1; } @@ -904,6 +920,8 @@ int SWIG_main(int argc, char *argv[], Language *l) { // Inform the parser if the nested classes should be ignored unless explicitly told otherwise via feature:flatnested ignore_nested_classes = l->nestedClassesSupport() == Language::NCS_Unknown ? 1 : 0; + kwargs_supported = l->kwargsSupport() ? 1 : 0; + // Create Library search directories // Check for SWIG_LIB environment variable @@ -1172,6 +1190,7 @@ int SWIG_main(int argc, char *argv[], Language *l) { Printf(stdout, "Processing unnamed structs...\n"); Swig_nested_name_unnamed_c_structs(top); } + Swig_extend_unused_check(); if (Verbose) { Printf(stdout, "Processing types...\n"); diff --git a/Source/Modules/modula3.cxx b/Source/Modules/modula3.cxx index db5d0981b..d9a0c922b 100644 --- a/Source/Modules/modula3.cxx +++ b/Source/Modules/modula3.cxx @@ -1407,25 +1407,12 @@ MODULA3(): } } - if (Cmp(nodeType(n), "constant") == 0) { - // Wrapping a constant hack - Swig_save("functionWrapper", n, "wrap:action", NIL); - - // below based on Swig_VargetToFunction() - SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n)); - Setattr(n, "wrap:action", NewStringf("%s = (%s)(%s);", Swig_cresult_name(), SwigType_lstr(ty, 0), Getattr(n, "value"))); - } - Setattr(n, "wrap:name", wname); // Now write code to make the function call if (!native_function_flag) { String *actioncode = emit_action(n); - if (Cmp(nodeType(n), "constant") == 0) { - Swig_restore(n); - } - /* Return value if necessary */ String *tm; if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { @@ -3622,35 +3609,6 @@ MODULA3(): } /* ----------------------------------------------------------------------------- - * makeParameterName() - * - * Inputs: - * n - Node - * p - parameter node - * arg_num - parameter argument number - * Return: - * arg - a unique parameter name - * ----------------------------------------------------------------------------- */ - - String *makeParameterName(Node *n, Parm *p, int arg_num) { - - // Use C parameter name unless it is a duplicate or an empty parameter name - String *pn = Getattr(p, "name"); - int count = 0; - ParmList *plist = Getattr(n, "parms"); - while (plist) { - if ((Cmp(pn, Getattr(plist, "name")) == 0)) - count++; - plist = nextSibling(plist); - } - String *arg = (!pn || (count > 1)) ? NewStringf("arg%d", - arg_num) : Copy(Getattr(p, - "name")); - - return arg; - } - - /* ----------------------------------------------------------------------------- * attachParameterNames() * * Inputs: diff --git a/Source/Modules/nested.cxx b/Source/Modules/nested.cxx index 3b45e9f90..c4ab6a8ea 100644 --- a/Source/Modules/nested.cxx +++ b/Source/Modules/nested.cxx @@ -362,7 +362,15 @@ void Swig_nested_name_unnamed_c_structs(Node *n) { Delete(bases); } Setattr(classhash, name, c); + + // Merge the extension into the symbol table + if (Node *am = Getattr(Swig_extend_hash(), name)) { + Swig_extend_merge(c, am); + Swig_extend_append_previous(c, am); + Delattr(Swig_extend_hash(), name); + } Swig_symbol_popscope(); + // process declarations following this type (assign correct new type) SwigType *ty = Copy(name); Node *decl = nextSibling(c); @@ -376,16 +384,6 @@ void Swig_nested_name_unnamed_c_structs(Node *n) { decl = nextSibling(decl); } Delete(ty); - // Check for extensions -/* // TODO: we can save extensions hash like class hash and move check_extensions() after nesting processing - if (extendhash) { - if (Node *am = Getattr(extendhash, name)) { - // Merge the extension into the symbol table - merge_extensions(c, am); - append_previous_extension(c, am); - Delattr(extendhash, clsname); - } - }*/ Swig_symbol_setscope(Swig_symbol_global_scope()); add_symbols_c(c); @@ -396,7 +394,12 @@ void Swig_nested_name_unnamed_c_structs(Node *n) { Delete(ins); Delattr(c, "nested:outer"); } else { - // global unnamed struct - ignore it + // global unnamed struct - ignore it and it's instances + SetFlag(c, "feature:ignore"); + while (next && Getattr(next, "nested:unnamedtype") == c) { + SetFlag(next, "feature:ignore"); + next = nextSibling(next); + } c = next; continue; } diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index f1ec8a8cf..ac73c1f0c 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -19,7 +19,7 @@ static const char *usage = "\ Ocaml Options (available with -ocaml)\n\ -oldvarnames - Old intermediary method names for variable wrappers\n\ -prefix <name> - Set a prefix <name> to be prepended to all names\n\ - -suffix <name> - Change .cxx to something else\n\ + -suffix <name> - Deprecated alias for general option -cppext\n\ -where - Emit library location\n\ \n"; @@ -114,6 +114,7 @@ public: } } else if (strcmp(argv[i], "-suffix") == 0) { if (argv[i + 1]) { + Printf(stderr, "swig: warning: -suffix option deprecated. SWIG 3.0.4 and later provide a -cppext option which should be used instead.\n"); SWIG_config_cppext(argv[i + 1]); Swig_mark_arg(i); Swig_mark_arg(i + 1); @@ -1350,9 +1351,6 @@ public: /* * Modified polymorphism code for Ocaml language module. - * Original: - * C++/Python polymorphism demo code, copyright (C) 2002 Mark Rose - * <mrose@stm.lbl.gov> * * TODO * diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index 103b59194..12903166c 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 + * 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 @@ -75,51 +75,44 @@ public: constructor_name(0), docs(0) { - /* Add code to manage protected constructors and directors */ - director_prot_ctor_code = NewString(""); - Printv(director_prot_ctor_code, - "if ( $comparison ) { /* subclassed */\n", - " $director_new \n", - "} else {\n", " error(\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL); - - enable_cplus_runtime_mode(); - allow_overloading(); - director_multiple_inheritance = 1; - director_language = 1; - docs = NewHash(); - } + /* Add code to manage protected constructors and directors */ + director_prot_ctor_code = NewString(""); + Printv(director_prot_ctor_code, + "if ( $comparison ) { /* subclassed */\n", + " $director_new \n", + "} else {\n", " error(\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL); + + enable_cplus_runtime_mode(); + allow_overloading(); + director_multiple_inheritance = 1; + director_language = 1; + docs = NewHash(); + } virtual void main(int argc, char *argv[]) { for (int i = 1; i < argc; i++) { if (argv[i]) { - if (strcmp(argv[i], "-help") == 0) { - fputs(usage, stdout); - } else if (strcmp(argv[i], "-global") == 0 || - strcmp(argv[i], "-noglobal") == 0) { - Printv(stderr, - "*** -global/-noglobal are no longer supported\n" - "*** global load behaviour is now determined at module load\n" - "*** see the Perl section in the manual for details.\n", NIL); - SWIG_exit(EXIT_FAILURE); - } else if (strcmp(argv[i], "-globals") == 0) { - if (argv[i + 1]) { - global_name = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-opprefix") == 0) { - if (argv[i + 1]) { - op_prefix = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } + if (strcmp(argv[i], "-help") == 0) { + fputs(usage, stdout); + } else if (strcmp(argv[i], "-globals") == 0) { + if (argv[i + 1]) { + global_name = NewString(argv[i + 1]); + Swig_mark_arg(i); + Swig_mark_arg(i + 1); + i++; + } else { + Swig_arg_error(); + } + } else if (strcmp(argv[i], "-opprefix") == 0) { + if (argv[i + 1]) { + op_prefix = NewString(argv[i + 1]); + Swig_mark_arg(i); + Swig_mark_arg(i + 1); + i++; + } else { + Swig_arg_error(); + } + } } } @@ -143,21 +136,21 @@ public: { Node *mod = Getattr(n, "module"); if (mod) { - Node *options = Getattr(mod, "options"); - if (options) { - int dirprot = 0; - if (Getattr(options, "dirprot")) { - dirprot = 1; - } - if (Getattr(options, "nodirprot")) { - dirprot = 0; - } - if (Getattr(options, "directors")) { - allow_directors(); - if (dirprot) - allow_dirprot(); - } - } + Node *options = Getattr(mod, "options"); + if (options) { + int dirprot = 0; + if (Getattr(options, "dirprot")) { + dirprot = 1; + } + if (Getattr(options, "nodirprot")) { + dirprot = 0; + } + if (Getattr(options, "directors")) { + allow_directors(); + if (dirprot) + allow_dirprot(); + } + } } } @@ -202,8 +195,8 @@ public: Printf(f_runtime, "#define SWIG_DIRECTORS\n"); Swig_banner(f_directors_h); if (dirprot_mode()) { - // Printf(f_directors_h, "#include <map>\n"); - // Printf(f_directors_h, "#include <string>\n\n"); + // Printf(f_directors_h, "#include <map>\n"); + // Printf(f_directors_h, "#include <string>\n\n"); } } @@ -263,19 +256,19 @@ public: String *r = NewString(""); for (int j=0;s[j];++j) { if (s[j] == '\n') { - Append(r, "\\n\\\n"); + Append(r, "\\n\\\n"); } else if (s[j] == '\r') { - Append(r, "\\r"); + Append(r, "\\r"); } else if (s[j] == '\t') { - Append(r, "\\t"); + Append(r, "\\t"); } else if (s[j] == '\\') { - Append(r, "\\\\"); + Append(r, "\\\\"); } else if (s[j] == '\'') { - Append(r, "\\\'"); + Append(r, "\\\'"); } else if (s[j] == '\"') { - Append(r, "\\\""); + Append(r, "\\\""); } else - Putc(s[j], r); + Putc(s[j], r); } return r; } @@ -293,11 +286,11 @@ public: String *escaped_doc_str = texinfo_escape(doc_str); if (Len(doc_str)>0) { - Printf(f_doc,"static const char* %s_texinfo = ",wrap_name); - Printf(f_doc,"\"-*- texinfo -*-\\n\\\n%s", escaped_doc_str); - if (Len(decl_info)) - Printf(f_doc,"\\n\\\n@end deftypefn"); - Printf(f_doc,"\";\n"); + Printf(f_doc,"static const char* %s_texinfo = ",wrap_name); + Printf(f_doc,"\"-*- texinfo -*-\\n\\\n%s", escaped_doc_str); + if (Len(decl_info)) + Printf(f_doc,"\\n\\\n@end deftypefn"); + Printf(f_doc,"\";\n"); } Delete(escaped_doc_str); @@ -313,7 +306,7 @@ public: String *decl_info = Getattr(n, "decl_info"); String *cdecl_info = Getattr(n, "cdecl_info"); String *args_info = Getattr(n, "args_info"); - return !Len(synopsis) && !Len(decl_info) && + return !Len(synopsis) && !Len(decl_info) && !Len(cdecl_info) && !Len(args_info); } String *texinfo_name(Node* n, const char* defval = "0") { @@ -360,11 +353,11 @@ public: SwigType *type = Getattr(n, "type"); if (type && Strcmp(type, "void")) { - Node *nn = classLookup(Getattr(n, "type")); - String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0); - Append(decl_info, "@var{retval} = "); - Printf(args_str, "%s@var{retval} is of type %s. ", args_str, type_str); - Delete(type_str); + Node *nn = classLookup(Getattr(n, "type")); + String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0); + Append(decl_info, "@var{retval} = "); + Printf(args_str, "%s@var{retval} is of type %s. ", args_str, type_str); + Delete(type_str); } Append(decl_info, name); @@ -380,8 +373,8 @@ public: // strip off {} if necessary char *t = Char(str); if (*t == '{') { - Delitem(str, 0); - Delitem(str, DOH_END); + Delitem(str, 0); + Delitem(str, DOH_END); } // emit into synopsis section @@ -408,7 +401,7 @@ public: * addMissingParameterNames() * For functions that have not had nameless parameters set in the Language class. * - * Inputs: + * Inputs: * plist - entire parameter list * arg_offset - argument number for first parameter * Side effects: @@ -420,8 +413,8 @@ public: int i = arg_offset; while (p) { if (!Getattr(p, "lname")) { - String *pname = Swig_cparm_name(p, i); - Delete(pname); + String *pname = Swig_cparm_name(p, i); + Delete(pname); } i++; p = nextSibling(p); @@ -444,12 +437,12 @@ public: String *tm = Getattr(p, "tmap:in"); if (tm) { - pnext = Getattr(p, "tmap:in:next"); - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - continue; - } + pnext = Getattr(p, "tmap:in:next"); + if (checkAttribute(p, "tmap:in:numinputs", "0")) { + continue; + } } else { - pnext = nextSibling(p); + pnext = nextSibling(p); } String *name = 0; @@ -457,9 +450,9 @@ public: String *value = 0; String *pdoc = Getattr(p, "tmap:doc"); if (pdoc) { - name = Getattr(p, "tmap:doc:name"); - type = Getattr(p, "tmap:doc:type"); - value = Getattr(p, "tmap:doc:value"); + name = Getattr(p, "tmap:doc:name"); + type = Getattr(p, "tmap:doc:type"); + value = Getattr(p, "tmap:doc:value"); } // Note: the generated name should be consistent with that in kwnames[] @@ -471,28 +464,28 @@ public: value = value ? value : Getattr(p, "value"); if (SwigType_isvarargs(type)) - break; + break; String *tex_name = NewString(""); if (name) - Printf(tex_name, "@var{%s}", name); + Printf(tex_name, "@var{%s}", name); else - Printf(tex_name, "@var{?}"); + Printf(tex_name, "@var{?}"); if (Len(decl_str)) - Append(decl_str, ", "); + Append(decl_str, ", "); Append(decl_str, tex_name); if (value) { - String *new_value = convertValue(value, Getattr(p, "type")); - if (new_value) { - value = new_value; - } else { - Node *lookup = Swig_symbol_clookup(value, 0); - if (lookup) - value = Getattr(lookup, "sym:name"); - } - Printf(decl_str, " = %s", value); + String *new_value = convertValue(value, Getattr(p, "type")); + if (new_value) { + value = new_value; + } else { + Node *lookup = Swig_symbol_clookup(value, 0); + if (lookup) + value = Getattr(lookup, "sym:name"); + } + Printf(decl_str, " = %s", value); } Node *nn = classLookup(Getattr(p, "type")); @@ -517,18 +510,18 @@ public: if (v && Len(v) > 0) { char fc = (Char(v))[0]; if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) { - /* number or string (or maybe NULL pointer) */ - if (SwigType_ispointer(t) && Strcmp(v, "0") == 0) - return NewString("None"); - else - return v; + /* number or string (or maybe NULL pointer) */ + if (SwigType_ispointer(t) && Strcmp(v, "0") == 0) + return NewString("None"); + else + return v; } if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) - return SwigType_ispointer(t) ? NewString("nil") : NewString("0"); + return SwigType_ispointer(t) ? NewString("nil") : NewString("0"); if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0) - return NewString("true"); + return NewString("true"); if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0) - return NewString("false"); + return NewString("false"); } return 0; } @@ -572,89 +565,89 @@ public: int varargs = emit_isvarargs(l); char source[64]; - Printf(f->code, "if (!SWIG_check_num_args(\"%s\",args.length(),%i,%i,%i)) " - "{\n SWIG_fail;\n }\n", iname, num_arguments, num_required, varargs); + Printf(f->code, "if (!SWIG_check_num_args(\"%s\",args.length(),%i,%i,%i)) " + "{\n SWIG_fail;\n }\n", iname, num_arguments, num_required, varargs); if (constructor && num_arguments == 1 && num_required == 1) { if (Cmp(storage, "explicit") == 0) { - Node *parent = Swig_methodclass(n); - if (GetFlag(parent, "feature:implicitconv")) { - String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type"))); - Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc); - Delete(desc); - } + Node *parent = Swig_methodclass(n); + if (GetFlag(parent, "feature:implicitconv")) { + String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type"))); + Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc); + Delete(desc); + } } } for (j = 0, p = l; j < num_arguments; ++j) { while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); + p = Getattr(p, "tmap:in:next"); } SwigType *pt = Getattr(p, "type"); String *tm = Getattr(p, "tmap:in"); if (tm) { - if (!tm || checkAttribute(p, "tmap:in:numinputs", "0")) { - p = nextSibling(p); - continue; - } - - sprintf(source, "args(%d)", j); - Setattr(p, "emit:input", source); - - Replaceall(tm, "$source", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Replaceall(tm, "$target", Getattr(p, "lname")); - - if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - - if (Getattr(p, "tmap:in:implicitconv")) { - const char *convflag = "0"; - if (!Getattr(p, "hidden")) { - SwigType *ptype = Getattr(p, "type"); - convflag = get_implicitconv_flag(classLookup(ptype)); - } - Replaceall(tm, "$implicitconv", convflag); - Setattr(p, "implicitconv", convflag); - } - - String *getargs = NewString(""); - if (j >= num_required) - Printf(getargs, "if (%d<args.length()) {\n%s\n}", j, tm); - else - Printv(getargs, tm, NIL); - Printv(f->code, getargs, "\n", NIL); - Delete(getargs); - - p = Getattr(p, "tmap:in:next"); - continue; + if (!tm || checkAttribute(p, "tmap:in:numinputs", "0")) { + p = nextSibling(p); + continue; + } + + sprintf(source, "args(%d)", j); + Setattr(p, "emit:input", source); + + Replaceall(tm, "$source", Getattr(p, "emit:input")); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Replaceall(tm, "$target", Getattr(p, "lname")); + + if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { + Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); + } else { + Replaceall(tm, "$disown", "0"); + } + + if (Getattr(p, "tmap:in:implicitconv")) { + const char *convflag = "0"; + if (!Getattr(p, "hidden")) { + SwigType *ptype = Getattr(p, "type"); + convflag = get_implicitconv_flag(classLookup(ptype)); + } + Replaceall(tm, "$implicitconv", convflag); + Setattr(p, "implicitconv", convflag); + } + + String *getargs = NewString(""); + if (j >= num_required) + Printf(getargs, "if (%d<args.length()) {\n%s\n}", j, tm); + else + Printv(getargs, tm, NIL); + Printv(f->code, getargs, "\n", NIL); + Delete(getargs); + + p = Getattr(p, "tmap:in:next"); + continue; } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - break; + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); + break; } } // Check for trailing varargs if (varargs) { if (p && (tm = Getattr(p, "tmap:in"))) { - Replaceall(tm, "$input", "varargs"); - Printv(f->code, tm, "\n", NIL); + Replaceall(tm, "$input", "varargs"); + Printv(f->code, tm, "\n", NIL); } } // Insert constraint checking code for (p = l; p;) { if ((tm = Getattr(p, "tmap:check"))) { - Replaceall(tm, "$target", Getattr(p, "lname")); - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); + Replaceall(tm, "$target", Getattr(p, "lname")); + Printv(f->code, tm, "\n", NIL); + p = Getattr(p, "tmap:check:next"); } else { - p = nextSibling(p); + p = nextSibling(p); } } @@ -662,23 +655,23 @@ public: String *cleanup = NewString(""); for (p = l; p;) { if ((tm = Getattr(p, "tmap:freearg"))) { - if (Getattr(p, "tmap:freearg:implicitconv")) { - const char *convflag = "0"; - if (!Getattr(p, "hidden")) { - SwigType *ptype = Getattr(p, "type"); - convflag = get_implicitconv_flag(classLookup(ptype)); - } - if (strcmp(convflag, "0") == 0) { - tm = 0; - } - } - if (tm && (Len(tm) != 0)) { - Replaceall(tm, "$source", Getattr(p, "lname")); - Printv(cleanup, tm, "\n", NIL); - } - p = Getattr(p, "tmap:freearg:next"); + if (Getattr(p, "tmap:freearg:implicitconv")) { + const char *convflag = "0"; + if (!Getattr(p, "hidden")) { + SwigType *ptype = Getattr(p, "type"); + convflag = get_implicitconv_flag(classLookup(ptype)); + } + if (strcmp(convflag, "0") == 0) { + tm = 0; + } + } + if (tm && (Len(tm) != 0)) { + Replaceall(tm, "$source", Getattr(p, "lname")); + Printv(cleanup, tm, "\n", NIL); + } + p = Getattr(p, "tmap:freearg:next"); } else { - p = nextSibling(p); + p = nextSibling(p); } } @@ -686,15 +679,15 @@ public: String *outarg = NewString(""); for (p = l; p;) { if ((tm = Getattr(p, "tmap:argout"))) { - Replaceall(tm, "$source", Getattr(p, "lname")); - Replaceall(tm, "$target", "_outp"); - Replaceall(tm, "$result", "_outp"); - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); + Replaceall(tm, "$source", Getattr(p, "lname")); + Replaceall(tm, "$target", "_outp"); + Replaceall(tm, "$result", "_outp"); + Replaceall(tm, "$arg", Getattr(p, "emit:input")); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(outarg, tm, "\n", NIL); + p = Getattr(p, "tmap:argout:next"); } else { - p = nextSibling(p); + p = nextSibling(p); } } @@ -720,9 +713,9 @@ public: Replaceall(tm, "$result", "_outv"); if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "1"); + Replaceall(tm, "$owner", "1"); else - Replaceall(tm, "$owner", "0"); + Replaceall(tm, "$owner", "0"); Printf(f->code, "%s\n", tm); Printf(f->code, "if (_outv.is_defined()) _outp = " "SWIG_Octave_AppendOutput(_outp, _outv);\n"); @@ -737,8 +730,8 @@ public: if (GetFlag(n, "feature:new")) { if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Replaceall(tm, "$source", Swig_cresult_name()); - Printf(f->code, "%s\n", tm); + Replaceall(tm, "$source", Swig_cresult_name()); + Printf(f->code, "%s\n", tm); } } @@ -830,16 +823,16 @@ public: if (is_assignable(n)) { Setattr(n, "wrap:name", setname); if ((tm = Swig_typemap_lookup("varin", n, name, 0))) { - Replaceall(tm, "$source", "args(0)"); - Replaceall(tm, "$target", name); - Replaceall(tm, "$input", "args(0)"); - if (Getattr(n, "tmap:varin:implicitconv")) { - Replaceall(tm, "$implicitconv", get_implicitconv_flag(n)); - } - emit_action_code(n, setf->code, tm); - Delete(tm); + Replaceall(tm, "$source", "args(0)"); + Replaceall(tm, "$target", name); + Replaceall(tm, "$input", "args(0)"); + if (Getattr(n, "tmap:varin:implicitconv")) { + Replaceall(tm, "$implicitconv", get_implicitconv_flag(n)); + } + emit_action_code(n, setf->code, tm); + Delete(tm); } else { - Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0)); + Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0)); } Append(setf->code, "fail:\n"); Printf(setf->code, "return octave_value_list();\n"); @@ -995,18 +988,18 @@ public: int index = 0; b = First(baselist); while (b.item) { - String *bname = Getattr(b.item, "name"); - if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) { - b = Next(b); - continue; - } - - String *bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname))); - Printf(base_class_names, "\"%s\",", bname_mangled); - Printf(base_class, "0,"); - b = Next(b); - index++; - Delete(bname_mangled); + String *bname = Getattr(b.item, "name"); + if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) { + b = Next(b); + continue; + } + + String *bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname))); + Printf(base_class_names, "\"%s\",", bname_mangled); + Printf(base_class, "0,"); + b = Next(b); + index++; + Delete(bname_mangled); } } @@ -1063,8 +1056,8 @@ public: bool overloaded = !!Getattr(n, "sym:overloaded"); if (overloaded) Delslice(rname, Len(rname) - Len(Getattr(n, "sym:overname")), DOH_END); - Printf(s_members_tab, "{\"%s\",%s,0,0,0,%s},\n", - realname, rname, tname); + Printf(s_members_tab, "{\"%s\",%s,0,0,0,%s},\n", + realname, rname, tname); Delete(rname); Delete(tname); } @@ -1112,7 +1105,7 @@ public: Delete(name); Setattr(self, "lname", "self_obj"); if (parms) - set_nextSibling(self, parms); + set_nextSibling(self, parms); Setattr(n, "parms", self); Setattr(n, "wrap:self", "1"); Setattr(n, "hidden", "1"); @@ -1144,12 +1137,12 @@ public: bool overloaded = !!Getattr(n, "sym:overloaded"); if (overloaded) Delslice(rname, Len(rname) - Len(Getattr(n, "sym:overname")), DOH_END); - Printf(s_members_tab, "{\"%s\",%s,0,0,1,%s},\n", - realname, rname, tname); + Printf(s_members_tab, "{\"%s\",%s,0,0,1,%s},\n", + realname, rname, tname); Delete(rname); Delete(tname); } - + return SWIG_OK; } @@ -1217,24 +1210,24 @@ public: if (!Getattr(n, "defaultargs")) { // constructor { - Wrapper *w = NewWrapper(); - String *call; - String *basetype = Getattr(parent, "classtype"); - String *target = Swig_method_decl(0, decl, classname, parms, 0, 0); - call = Swig_csuperclass_call(0, basetype, superparms); - Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype); - Append(w->def, "}\n"); - Delete(target); - Wrapper_print(w, f_directors); - Delete(call); - DelWrapper(w); + Wrapper *w = NewWrapper(); + String *call; + String *basetype = Getattr(parent, "classtype"); + String *target = Swig_method_decl(0, decl, classname, parms, 0, 0); + call = Swig_csuperclass_call(0, basetype, superparms); + Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype); + Append(w->def, "}\n"); + Delete(target); + Wrapper_print(w, f_directors); + Delete(call); + DelWrapper(w); } // constructor header { - String *target = Swig_method_decl(0, decl, classname, parms, 0, 1); - Printf(f_directors_h, " %s;\n", target); - Delete(target); + String *target = Swig_method_decl(0, decl, classname, parms, 0, 1); + Printf(f_directors_h, " %s;\n", target); + Delete(target); } } @@ -1250,7 +1243,7 @@ public: { Wrapper *w = NewWrapper(); Printf(w->def, "SwigDirector_%s::SwigDirector_%s(void* self) :" - "\nSwig::Director((octave_swig_type*)self,static_cast<%s*>(this)) { \n", classname, classname, classname); + "\nSwig::Director((octave_swig_type*)self,static_cast<%s*>(this)) { \n", classname, classname, classname); Append(w->def, "}\n"); Wrapper_print(w, f_directors); DelWrapper(w); @@ -1283,7 +1276,7 @@ public: if (Cmp(storage, "virtual") == 0) { if (Cmp(value, "0") == 0) { - pure_virtual = true; + pure_virtual = true; } } @@ -1317,18 +1310,18 @@ public: Append(declaration, " throw("); if (throw_parm_list) - Swig_typemap_attach_parms("throws", throw_parm_list, 0); + Swig_typemap_attach_parms("throws", throw_parm_list, 0); for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - if (gencomma++) { - Append(w->def, ", "); - Append(declaration, ", "); - } - String *str = SwigType_str(Getattr(p, "type"), 0); - Append(w->def, str); - Append(declaration, str); - Delete(str); - } + if (Getattr(p, "tmap:throws")) { + if (gencomma++) { + Append(w->def, ", "); + Append(declaration, ", "); + } + String *str = SwigType_str(Getattr(p, "type"), 0); + Append(w->def, str); + Append(declaration, str); + Delete(str); + } } Append(w->def, ")"); @@ -1338,27 +1331,27 @@ public: Append(w->def, " {"); Append(declaration, ";\n"); - // declare method return value + // declare method return value // if the return value is a reference or const reference, a specialized typemap must // handle it, including declaration of c_result ($result). if (!is_void) { if (!(ignored_method && !pure_virtual)) { - String *cres = SwigType_lstr(returntype, "c_result"); - Printf(w->code, "%s;\n", cres); - Delete(cres); + String *cres = SwigType_lstr(returntype, "c_result"); + Printf(w->code, "%s;\n", cres); + Delete(cres); } } if (ignored_method) { if (!pure_virtual) { - if (!is_void) - Printf(w->code, "return "); - String *super_call = Swig_method_call(super, l); - Printf(w->code, "%s;\n", super_call); - Delete(super_call); + if (!is_void) + Printf(w->code, "return "); + String *super_call = Swig_method_call(super, l); + Printf(w->code, "%s;\n", super_call); + Delete(super_call); } else { - Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname), - SwigType_namestr(name)); + Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname), + SwigType_namestr(name)); } } else { // attach typemaps to arguments (C/C++ -> Python) @@ -1374,50 +1367,50 @@ public: int outputs = 0; if (!is_void) - outputs++; + outputs++; // build argument list and type conversion string p = l; while (p) { - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - if (Getattr(p, "tmap:directorargout") != 0) - outputs++; - - String *pname = Getattr(p, "name"); - String *ptype = Getattr(p, "type"); - Wrapper_add_local(w, "tmpv", "octave_value tmpv"); - - if ((tm = Getattr(p, "tmap:directorin")) != 0) { - String *parse = Getattr(p, "tmap:directorin:parse"); - if (!parse) { - Setattr(p, "emit:directorinput", "tmpv"); - Replaceall(tm, "$input", "tmpv"); - Replaceall(tm, "$owner", "0"); - Printv(wrap_args, tm, "\n", NIL); - Printf(wrap_args, "args.append(tmpv);\n"); - Putc('O', parse_args); - } else { - Append(parse_args, parse); - Setattr(p, "emit:directorinput", pname); - Replaceall(tm, "$input", pname); - Replaceall(tm, "$owner", "0"); - if (Len(tm) == 0) - Append(tm, pname); - } - p = Getattr(p, "tmap:directorin:next"); - continue; - } else if (Cmp(ptype, "void")) { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, - "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), - SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_NOWRAP; - break; - } - p = nextSibling(p); + if (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + continue; + } + + if (Getattr(p, "tmap:directorargout") != 0) + outputs++; + + String *pname = Getattr(p, "name"); + String *ptype = Getattr(p, "type"); + Wrapper_add_local(w, "tmpv", "octave_value tmpv"); + + if ((tm = Getattr(p, "tmap:directorin")) != 0) { + String *parse = Getattr(p, "tmap:directorin:parse"); + if (!parse) { + Setattr(p, "emit:directorinput", "tmpv"); + Replaceall(tm, "$input", "tmpv"); + Replaceall(tm, "$owner", "0"); + Printv(wrap_args, tm, "\n", NIL); + Printf(wrap_args, "args.append(tmpv);\n"); + Putc('O', parse_args); + } else { + Append(parse_args, parse); + Setattr(p, "emit:directorinput", pname); + Replaceall(tm, "$input", pname); + Replaceall(tm, "$owner", "0"); + if (Len(tm) == 0) + Append(tm, pname); + } + p = Getattr(p, "tmap:directorin:next"); + continue; + } else if (Cmp(ptype, "void")) { + Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, + "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), + SwigType_namestr(c_classname), SwigType_namestr(name)); + status = SWIG_NOWRAP; + break; + } + p = nextSibling(p); } String *method_name = Getattr(n, "sym:name"); @@ -1438,45 +1431,45 @@ public: // marshal return value if (!is_void) { - Printf(w->code, "if (out.length()<%d) {\n", outputs); - Printf(w->code, "Swig::DirectorTypeMismatchException::raise(\"Octave " - "method %s.%s failed to return the required number " "of arguments.\");\n", classname, method_name); - Printf(w->code, "}\n"); - - tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w); - if (tm != 0) { - char temp[24]; - sprintf(temp, "out(%d)", idx); - Replaceall(tm, "$input", temp); - // Replaceall(tm, "$argnum", temp); - Replaceall(tm, "$disown", Getattr(n, "wrap:disown") ? "SWIG_POINTER_DISOWN" : "0"); - if (Getattr(n, "tmap:directorout:implicitconv")) { - Replaceall(tm, "$implicitconv", get_implicitconv_flag(n)); - } - Replaceall(tm, "$result", "c_result"); - Printv(w->code, tm, "\n", NIL); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use return type %s in director method %s::%s (skipping method).\n", - SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_ERROR; - } + Printf(w->code, "if (out.length()<%d) {\n", outputs); + Printf(w->code, "Swig::DirectorTypeMismatchException::raise(\"Octave " + "method %s.%s failed to return the required number " "of arguments.\");\n", classname, method_name); + Printf(w->code, "}\n"); + + tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w); + if (tm != 0) { + char temp[24]; + sprintf(temp, "out(%d)", idx); + Replaceall(tm, "$input", temp); + // Replaceall(tm, "$argnum", temp); + Replaceall(tm, "$disown", Getattr(n, "wrap:disown") ? "SWIG_POINTER_DISOWN" : "0"); + if (Getattr(n, "tmap:directorout:implicitconv")) { + Replaceall(tm, "$implicitconv", get_implicitconv_flag(n)); + } + Replaceall(tm, "$result", "c_result"); + Printv(w->code, tm, "\n", NIL); + Delete(tm); + } else { + Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, + "Unable to use return type %s in director method %s::%s (skipping method).\n", + SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); + status = SWIG_ERROR; + } } idx++; // marshal outputs for (p = l; p;) { - if ((tm = Getattr(p, "tmap:directorargout")) != 0) { - char temp[24]; - sprintf(temp, "out(%d)", idx); - Replaceall(tm, "$result", temp); - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } + if ((tm = Getattr(p, "tmap:directorargout")) != 0) { + char temp[24]; + sprintf(temp, "out(%d)", idx); + Replaceall(tm, "$result", temp); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); + Printv(w->code, tm, "\n", NIL); + p = Getattr(p, "tmap:directorargout:next"); + } else { + p = nextSibling(p); + } } Delete(parse_args); @@ -1486,13 +1479,13 @@ public: if (!is_void) { if (!(ignored_method && !pure_virtual)) { - String *rettype = SwigType_str(returntype, 0); - if (!SwigType_isreference(returntype)) { - Printf(w->code, "return (%s) c_result;\n", rettype); - } else { - Printf(w->code, "return (%s) *c_result;\n", rettype); - } - Delete(rettype); + String *rettype = SwigType_str(returntype, 0); + if (!SwigType_isreference(returntype)) { + Printf(w->code, "return (%s) c_result;\n", rettype); + } else { + Printf(w->code, "return (%s) *c_result;\n", rettype); + } + Delete(rettype); } } @@ -1506,7 +1499,7 @@ public: Replaceall(inline_extra_method, name, extra_method_name); Replaceall(inline_extra_method, ";\n", " {\n "); if (!is_void) - Printf(inline_extra_method, "return "); + Printf(inline_extra_method, "return "); String *methodcall = Swig_method_call(super, l); Printv(inline_extra_method, methodcall, ";\n }\n", NIL); Delete(methodcall); @@ -1515,10 +1508,10 @@ public: // emit the director method if (status == SWIG_OK) { if (!Getattr(n, "defaultargs")) { - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_directors); - Printv(f_directors_h, declaration, NIL); - Printv(f_directors_h, inline_extra_method, NIL); + Replaceall(w->code, "$symname", symname); + Wrapper_print(w, f_directors); + Printv(f_directors_h, declaration, NIL); + Printv(f_directors_h, inline_extra_method, NIL); } } // clean up diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx index ff504d461..224c4852e 100644 --- a/Source/Modules/perl5.cxx +++ b/Source/Modules/perl5.cxx @@ -342,11 +342,18 @@ public: Node *options = Getattr(mod, "options"); module = Copy(Getattr(n,"name")); + String *underscore_module = Copy(module); + Replaceall(underscore_module,":","_"); + + if (verbose > 0) { + fprintf(stdout, "top: using namespace_module: %s\n", Char(namespace_module)); + } + if (directorsEnabled()) { Swig_banner(f_directors_h); Printf(f_directors_h, "\n"); - Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module); - Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module); + Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", underscore_module); + Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", underscore_module); if (dirprot_mode()) { Printf(f_directors_h, "#include <map>\n"); Printf(f_directors_h, "#include <string>\n\n"); @@ -379,13 +386,6 @@ public: fprintf(stdout, "top: No package found\n"); } } - String *underscore_module = Copy(module); - Replaceall(underscore_module,":","_"); - - if (verbose > 0) { - fprintf(stdout, "top: using namespace_module: %s\n", Char(namespace_module)); - } - /* If we're in blessed mode, change the package name to "packagec" */ if (blessed) { @@ -2178,12 +2178,12 @@ public: SwigType_add_pointer(ptype); String *mangle = SwigType_manglestr(ptype); - Wrapper_add_local(w, "self", "SV *self"); - Printf(w->code, "self = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE%s, SWIG_SHADOW);\n", mangle); - Printf(w->code, "sv_bless(self, gv_stashpv(swig_get_class(), 0));\n"); + Wrapper_add_local(w, "swigself", "SV *swigself"); + Printf(w->code, "swigself = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE%s, SWIG_SHADOW);\n", mangle); + Printf(w->code, "sv_bless(swigself, gv_stashpv(swig_get_class(), 0));\n"); Delete(mangle); Delete(ptype); - Append(pstack, "XPUSHs(self);\n"); + Append(pstack, "XPUSHs(swigself);\n"); } Parm *p; diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index b07c82d3b..a2f0e3687 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -44,7 +44,6 @@ static const char *usage = "\ PHP Options (available with -php)\n\ - -cppext <ext> - Change C++ file extension to <ext> (default is cpp)\n\ -noproxy - Don't generate proxy classes.\n\ -prefix <prefix> - Prepend <prefix> to all class names in PHP wrappers\n\ \n"; @@ -221,15 +220,6 @@ public: } else { Swig_arg_error(); } - } else if (strcmp(argv[i], "-cppext") == 0) { - if (argv[i + 1]) { - SWIG_config_cppext(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } } else if ((strcmp(argv[i], "-noshadow") == 0) || (strcmp(argv[i], "-noproxy") == 0)) { shadow = 0; Swig_mark_arg(i); @@ -836,13 +826,6 @@ public: Delete(args); args = NULL; } - if (is_member_director(n)) { - Wrapper_add_local(f, "director", "Swig::Director *director = 0"); - Printf(f->code, "director = dynamic_cast<Swig::Director*>(arg1);\n"); - Wrapper_add_local(f, "upcall", "bool upcall = false"); - Printf(f->code, "upcall = !director->swig_is_overridden_method((char *)\"%s%s\", (char *)\"%s\");\n", - prefix, Swig_class_name(Swig_methodclass(n)), name); - } // This generated code may be called: // 1) as an object method, or @@ -931,6 +914,12 @@ public: Delete(source); } + if (is_member_director(n)) { + Wrapper_add_local(f, "upcall", "bool upcall = false"); + Printf(f->code, "upcall = !Swig::Director::swig_is_overridden_method((char *)\"%s%s\", (char *)\"%s\" TSRMLS_CC);\n", + prefix, Swig_class_name(Swig_methodclass(n)), name); + } + Swig_director_emit_dynamic_cast(n, f); /* Insert constraint checking code */ @@ -1278,7 +1267,7 @@ public: break; char *p; errno = 0; - int n = strtol(Char(value), &p, 0); + long n = strtol(Char(value), &p, 0); Clear(value); if (errno || *p) { Append(value, "?"); @@ -1293,10 +1282,11 @@ public: case T_SCHAR: case T_SHORT: case T_INT: - case T_LONG: { + case T_LONG: + case T_LONGLONG: { char *p; errno = 0; - unsigned int n = strtol(Char(value), &p, 0); + long n = strtol(Char(value), &p, 0); (void) n; if (errno || *p) { Clear(value); @@ -1307,7 +1297,8 @@ public: case T_UCHAR: case T_USHORT: case T_UINT: - case T_ULONG: { + case T_ULONG: + case T_ULONGLONG: { char *p; errno = 0; unsigned int n = strtoul(Char(value), &p, 0); @@ -1319,7 +1310,8 @@ public: break; } case T_FLOAT: - case T_DOUBLE:{ + case T_DOUBLE: + case T_LONGDOUBLE: { char *p; errno = 0; /* FIXME: strtod is locale dependent... */ @@ -1338,13 +1330,6 @@ public: } break; } - case T_REFERENCE: - case T_RVALUE_REFERENCE: - case T_USER: - case T_ARRAY: - Clear(value); - Append(value, "?"); - break; case T_STRING: if (Len(value) < 2) { // How can a string (including "" be less than 2 characters?) @@ -1393,6 +1378,11 @@ public: } break; } + default: + /* Safe default */ + Clear(value); + Append(value, "?"); + break; } if (!arg_values[argno]) { @@ -2045,6 +2035,17 @@ done: } else if (GetFlag(n, "feature:exceptionclass")) { Append(s_phpclasses, "extends Exception "); } + { + Node *node = NewHash(); + Setattr(node, "type", Getattr(n, "name")); + Setfile(node, Getfile(n)); + Setline(node, Getline(n)); + String * interfaces = Swig_typemap_lookup("phpinterfaces", node, "", 0); + if (interfaces) { + Printf(s_phpclasses, "implements %s ", interfaces); + } + Delete(node); + } Printf(s_phpclasses, "{\n\tpublic $%s=null;\n", SWIG_PTR); if (!baseclass) { // Only store this in the base class (NB !baseclass means we *are* @@ -2622,12 +2623,12 @@ done: Printf(w->code, "zval *args[%d];\n", idx); } Printf(w->code, "zval *%s, funcname;\n", Swig_cresult_name()); - Printf(w->code, "MAKE_STD_ZVAL(%s);\n", Swig_cresult_name()); - const char * funcname = GetChar(n, "sym:name"); - Printf(w->code, "ZVAL_STRINGL(&funcname, (char *)\"%s\", %d, 0);\n", funcname, strlen(funcname)); Append(w->code, "if (!swig_self) {\n"); Append(w->code, " SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");"); Append(w->code, "}\n\n"); + Printf(w->code, "MAKE_STD_ZVAL(%s);\n", Swig_cresult_name()); + const char * funcname = GetChar(n, "sym:name"); + Printf(w->code, "ZVAL_STRINGL(&funcname, (char *)\"%s\", %d, 0);\n", funcname, strlen(funcname)); /* wrap complex arguments to zvals */ Printv(w->code, wrap_args, NIL); diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 06c1c4868..dde1b6023 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -17,6 +17,8 @@ static int treduce = SWIG_cparse_template_reduce(0); #include <ctype.h> +#include <errno.h> +#include <stdlib.h> #define PYSHADOW_MEMBER 0x2 #define WARN_PYTHON_MULTIPLE_INH 405 @@ -807,7 +809,7 @@ public: Printv(f_shadow, "\nfrom sys import version_info\n", NULL); if (!builtin && fastproxy) { - Printv(f_shadow, "if version_info >= (3,0,0):\n", NULL); + Printv(f_shadow, "if version_info >= (3, 0, 0):\n", NULL); Printf(f_shadow, tab4 "new_instancemethod = lambda func, inst, cls: %s.SWIG_PyInstanceMethod_New(func)\n", module); Printv(f_shadow, "else:\n", NULL); Printv(f_shadow, tab4, "from new import instancemethod as new_instancemethod\n", NULL); @@ -822,7 +824,7 @@ public: * isn't available in python 2.4 or earlier, so we have to write some * code conditional on the python version. */ - Printv(f_shadow, "if version_info >= (2,6,0):\n", NULL); + Printv(f_shadow, "if version_info >= (2, 6, 0):\n", NULL); Printv(f_shadow, tab4, "def swig_import_helper():\n", NULL); Printv(f_shadow, tab8, "from os.path import dirname\n", NULL); Printv(f_shadow, tab8, "import imp\n", NULL); @@ -852,40 +854,45 @@ public: Printf(f_shadow, "from %s import *\n", module); } if (modern || !classic) { - Printv(f_shadow, "try:\n", tab4, "_swig_property = property\n", "except NameError:\n", tab4, "pass # Python < 2.2 doesn't have 'property'.\n", NULL); + Printv(f_shadow, "try:\n", tab4, "_swig_property = property\n", "except NameError:\n", tab4, "pass # Python < 2.2 doesn't have 'property'.\n\n", NULL); } /* if (!modern) */ /* always needed, a class can be forced to be no-modern, such as an exception */ { // Python-2.2 object hack Printv(f_shadow, - "def _swig_setattr_nondynamic(self,class_type,name,value,static=1):\n", - tab4, "if (name == \"thisown\"): return self.this.own(value)\n", - tab4, "if (name == \"this\"):\n", tab4, tab4, "if type(value).__name__ == 'SwigPyObject':\n", tab4, tab8, "self.__dict__[name] = value\n", + "\n", "def _swig_setattr_nondynamic(self, class_type, name, value, static=1):\n", + tab4, "if (name == \"thisown\"):\n", tab8, "return self.this.own(value)\n", + tab4, "if (name == \"this\"):\n", tab8, "if type(value).__name__ == 'SwigPyObject':\n", tab4, tab8, "self.__dict__[name] = value\n", #ifdef USE_THISOWN - tab4, tab8, "if hasattr(value,\"thisown\"): self.__dict__[\"thisown\"] = value.thisown\n", tab4, tab8, "del value.thisown\n", + tab4, tab8, "if hasattr(value,\"thisown\"):\n", tab8, tab8, "self.__dict__[\"thisown\"] = value.thisown\n", tab4, tab8, "del value.thisown\n", #endif - tab4, tab8, "return\n", tab4, "method = class_type.__swig_setmethods__.get(name,None)\n", tab4, "if method: return method(self,value)\n", + tab4, tab8, "return\n", tab4, "method = class_type.__swig_setmethods__.get(name, None)\n", tab4, "if method:\n", tab4, tab4, "return method(self, value)\n", #ifdef USE_THISOWN tab4, "if (not static) or (name == \"thisown\"):\n", #else tab4, "if (not static):\n", #endif - tab4, tab4, "self.__dict__[name] = value\n", + tab4, tab4, "object.__setattr__(self, name, value)\n", tab4, "else:\n", tab4, tab4, "raise AttributeError(\"You cannot add attributes to %s\" % self)\n\n", - "def _swig_setattr(self,class_type,name,value):\n", tab4, "return _swig_setattr_nondynamic(self,class_type,name,value,0)\n\n", NIL); + "\n", "def _swig_setattr(self, class_type, name, value):\n", tab4, "return _swig_setattr_nondynamic(self, class_type, name, value, 0)\n\n", NIL); Printv(f_shadow, - "def _swig_getattr(self,class_type,name):\n", - tab4, "if (name == \"thisown\"): return self.this.own()\n", - tab4, "method = class_type.__swig_getmethods__.get(name,None)\n", - tab4, "if method: return method(self)\n", tab4, "raise AttributeError(name)\n\n", NIL); + "\n", "def _swig_getattr_nondynamic(self, class_type, name, static=1):\n", + tab4, "if (name == \"thisown\"):\n", tab8, "return self.this.own()\n", + tab4, "method = class_type.__swig_getmethods__.get(name, None)\n", + tab4, "if method:\n", tab8, "return method(self)\n", + tab4, "if (not static):\n", + tab4, tab4, "return object.__getattr__(self, name)\n", + tab4, "else:\n", + tab4, tab4, "raise AttributeError(name)\n\n", + "def _swig_getattr(self, class_type, name):\n", tab4, "return _swig_getattr_nondynamic(self, class_type, name, 0)\n\n", NIL); Printv(f_shadow, - "def _swig_repr(self):\n", - tab4, "try: strthis = \"proxy of \" + self.this.__repr__()\n", - tab4, "except: strthis = \"\"\n", tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL); + "\n", "def _swig_repr(self):\n", + tab4, "try:\n", tab8, "strthis = \"proxy of \" + self.this.__repr__()\n", + tab4, "except:\n", tab8, "strthis = \"\"\n", tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL); if (!classic) { /* Usage of types.ObjectType is deprecated. @@ -895,19 +902,19 @@ public: // "import types\n", "try:\n", // " _object = types.ObjectType\n", - " _object = object\n", " _newclass = 1\n", "except AttributeError:\n", " class _object : pass\n", " _newclass = 0\n", + tab4, "_object = object\n", tab4, "_newclass = 1\n", "except AttributeError:\n", tab4, "class _object:\n", tab8, "pass\n", tab4, "_newclass = 0\n", // "del types\n", "\n\n", NIL); } } if (modern) { - Printv(f_shadow, "def _swig_setattr_nondynamic_method(set):\n", tab4, "def set_attr(self,name,value):\n", + Printv(f_shadow, "\n", "def _swig_setattr_nondynamic_method(set):\n", tab4, "def set_attr(self, name, value):\n", #ifdef USE_THISOWN - tab4, tab4, "if hasattr(self,name) or (name in (\"this\", \"thisown\")):\n", + tab4, tab4, "if hasattr(self, name) or (name in (\"this\", \"thisown\")):\n", #else - tab4, tab4, "if (name == \"thisown\"): return self.this.own(value)\n", tab4, tab4, "if hasattr(self,name) or (name == \"this\"):\n", + tab4, tab4, "if (name == \"thisown\"):\n", tab8, tab4, "return self.this.own(value)\n", tab4, tab4, "if hasattr(self, name) or (name == \"this\"):\n", #endif - tab4, tab4, tab4, "set(self,name,value)\n", + tab4, tab4, tab4, "set(self, name, value)\n", tab4, tab4, "else:\n", tab4, tab4, tab4, "raise AttributeError(\"You cannot add attributes to %s\" % self)\n", tab4, "return set_attr\n\n\n", NIL); } @@ -1523,6 +1530,21 @@ public: return ds; } + virtual String *makeParameterName(Node *n, Parm *p, int arg_num, bool = false) const { + // For the keyword arguments, we want to preserve the names as much as possible, + // so we only minimally rename them in Swig_name_make(), e.g. replacing "keyword" + // with "_keyword" if they have any name at all. + if (check_kwargs(n)) { + String *name = Getattr(p, "name"); + if (name) + return Swig_name_make(p, 0, name, 0, 0); + } + + // For the other cases use the general function which replaces arguments whose + // names clash with keywords with (less useful) "argN". + return Language::makeParameterName(n, p, arg_num); + } + /* ----------------------------------------------------------------------------- * addMissingParameterNames() * For functions that have not had nameless parameters set in the Language class. @@ -1534,13 +1556,14 @@ public: * The "lname" attribute in each parameter in plist will be contain a parameter name * ----------------------------------------------------------------------------- */ - void addMissingParameterNames(ParmList *plist, int arg_offset) { + void addMissingParameterNames(Node *n, ParmList *plist, int arg_offset) { Parm *p = plist; int i = arg_offset; while (p) { if (!Getattr(p, "lname")) { - String *pname = Swig_cparm_name(p, i); - Delete(pname); + String *name = makeParameterName(n, p, i); + Setattr(p, "lname", name); + Delete(name); } i++; p = nextSibling(p); @@ -1563,14 +1586,18 @@ public: Parm *pnext; - int lines = 0; - int start_arg_num = is_wrapping_class() ? 1 : 0; - const int maxwidth = 80; + // Normally we start counting auto-generated argument names from 1, but we should do it from 2 + // if the first argument is "self", i.e. if we're handling a non-static member function. + int arg_num = 1; + if (is_wrapping_class()) { + if (Cmp(Getattr(n, "storage"), "static") != 0) + arg_num++; + } if (calling) func_annotation = false; - addMissingParameterNames(plist, start_arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms + addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms Swig_typemap_attach_parms("in", plist, 0); Swig_typemap_attach_parms("doc", plist, 0); @@ -1579,7 +1606,7 @@ public: return doc; } - for (p = plist; p; p = pnext) { + for (p = plist; p; p = pnext, arg_num++) { String *tm = Getattr(p, "tmap:in"); if (tm) { @@ -1602,25 +1629,22 @@ public: } // Note: the generated name should be consistent with that in kwnames[] - name = name ? name : Getattr(p, "name"); - name = name ? name : Getattr(p, "lname"); - name = Swig_name_make(p, 0, name, 0, 0); // rename parameter if a keyword + String *made_name = 0; + if (!name) { + name = made_name = makeParameterName(n, p, arg_num); + } type = type ? type : Getattr(p, "type"); value = value ? value : Getattr(p, "value"); - if (SwigType_isvarargs(type)) + if (SwigType_isvarargs(type)) { + Delete(made_name); break; + } if (Len(doc)) { // add a comma to the previous one if any Append(doc, ", "); - - // Do we need to wrap a long line? - if ((Len(doc) - lines * maxwidth) > maxwidth) { - Printf(doc, "\n%s", tab4); - lines += 1; - } } // Do the param type too? @@ -1637,22 +1661,16 @@ public: } // Write the function annotation if (func_annotation) - Printf(doc, " : '%s'", type_str); + Printf(doc, ": '%s'", type_str); // Write default value if (value && !calling) { String *new_value = convertValue(value, Getattr(p, "type")); - if (new_value) { - value = new_value; - } else { - Node *lookup = Swig_symbol_clookup(value, 0); - if (lookup) - value = Getattr(lookup, "sym:name"); - } - Printf(doc, "=%s", value); + if (new_value) + Printf(doc, "=%s", new_value); } Delete(type_str); - Delete(name); + Delete(made_name); } if (pdocs) Setattr(n, "feature:pdocs", pdocs); @@ -1799,57 +1817,192 @@ public: } /* ------------------------------------------------------------ + * convertDoubleValue() + * Check if the given string looks like a decimal floating point constant + * and return it if it does, otherwise return NIL. + * ------------------------------------------------------------ */ + String *convertDoubleValue(String *v) { + const char *const s = Char(v); + char *end; + + double value = strtod(s, &end); + (void) value; + if (errno != ERANGE && end != s) { + // An added complication: at least some versions of strtod() recognize + // hexadecimal floating point numbers which don't exist in Python, so + // detect them ourselves and refuse to convert them (this can't be done + // without loss of precision in general). + // + // Also don't accept neither "NAN" nor "INFINITY" (both of which + // conveniently contain "n"). + if (strpbrk(s, "xXnN")) + return NIL; + + // Disregard optional "f" suffix, it can be just dropped in Python as it + // uses doubles for everything anyhow. + for (char* p = end; *p != '\0'; ++p) { + switch (*p) { + case 'f': + case 'F': + break; + + default: + return NIL; + } + } + + // Avoid unnecessary string allocation in the common case when we don't + // need to remove any suffix. + return *end == '\0' ? v : NewStringWithSize(s, end - s); + } + + return NIL; + } + + /* ------------------------------------------------------------ * convertValue() - * Check if string v can be a Python value literal, - * (eg. number or string), or translate it to a Python literal. + * Check if string v can be a Python value literal or a + * constant. Return NIL if it isn't. * ------------------------------------------------------------ */ String *convertValue(String *v, SwigType *t) { - if (v && Len(v) > 0) { - char fc = (Char(v))[0]; - if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) { - /* number or string (or maybe NULL pointer) */ - if (SwigType_ispointer(t) && Strcmp(v, "0") == 0) - return NewString("None"); - else - return v; + const char *const s = Char(v); + char *end; + + // Check if this is a number in any base. + long value = strtol(s, &end, 0); + (void) value; + if (end != s) { + if (errno == ERANGE) { + // There was an overflow, we could try representing the value as Python + // long integer literal, but for now don't bother with it. + return NIL; + } + + if (*end != '\0') { + // If there is a suffix after the number, we can safely ignore any + // combination of "l" and "u", but not anything else (again, stuff like + // "LL" could be handled, but we don't bother to do it currently). + bool seen_long = false; + for (char* p = end; *p != '\0'; ++p) { + switch (*p) { + case 'l': + case 'L': + // Bail out on "LL". + if (seen_long) + return NIL; + seen_long = true; + break; + + case 'u': + case 'U': + break; + + default: + // Except that our suffix could actually be the fractional part of + // a floating point number, so we still have to check for this. + return convertDoubleValue(v); + } + } + } + + // Deal with the values starting with 0 first as they can be octal or + // hexadecimal numbers or even pointers. + if (s[0] == '0') { + if (Len(v) == 1) { + // This is just a lone 0, but it needs to be represented differently + // in Python depending on whether it's a zero or a null pointer. + if (SwigType_ispointer(t)) + return NewString("None"); + else + return v; + } else if (s[1] == 'x' || s[1] == 'X') { + // This must have been a hex number, we can use it directly in Python, + // so nothing to do here. + } else { + // This must have been an octal number, we have to change its prefix + // to be "0o" in Python 3 only (and as long as we still support Python + // 2.5, this can't be done unconditionally). + if (py3) { + if (end - s > 1) { + String *res = NewString("0o"); + Append(res, NewStringWithSize(s + 1, end - s - 1)); + return res; + } + } + } } - if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0) - return NewString("True"); - if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0) - return NewString("False"); - if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) - return SwigType_ispointer(t) ? NewString("None") : NewString("0"); + + // Avoid unnecessary string allocation in the common case when we don't + // need to remove any suffix. + return *end == '\0' ? v : NewStringWithSize(s, end - s); } - return 0; + + // Check if this is a floating point number (notice that it wasn't + // necessarily parsed as a long above, consider e.g. ".123"). + if (String *res = convertDoubleValue(v)) { + return res; + } + + if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0) + return NewString("True"); + if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0) + return NewString("False"); + if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) + return SwigType_ispointer(t) ? NewString("None") : NewString("0"); + + // This could also be an enum type, default value of which could be + // representable in Python if it doesn't include any scope (which could, + // but currently is not, translated). + if (!Strchr(s, ':')) { + Node *lookup = Swig_symbol_clookup(v, 0); + if (lookup) { + if (Cmp(Getattr(lookup, "nodeType"), "enumitem") == 0) + return Getattr(lookup, "sym:name"); + } + } + + return NIL; } + /* ------------------------------------------------------------ - * is_primitive_defaultargs() - * Check if all the default args have primitive type. - * (So we can generate proper parameter list with default - * values..) + * is_representable_as_pyargs() + * Check if the function parameters default argument values + * can be represented in Python. + * + * If this method returns false, the parameters will be translated + * to a generic "*args" which allows us to deal with default values + * at C++ code level where they can always be handled. * ------------------------------------------------------------ */ - bool is_primitive_defaultargs(Node *n) { - ParmList *plist = CopyParmList(Getattr(n, "parms")); - Parm *p; - Parm *pnext; + bool is_representable_as_pyargs(Node *n) { + bool is_representable = true; - Swig_typemap_attach_parms("in", plist, 0); - for (p = plist; p; p = pnext) { - String *tm = Getattr(p, "tmap:in"); - if (tm) { - pnext = Getattr(p, "tmap:in:next"); - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - continue; + if (Getattr(n, "sym:overloaded")) { + ParmList *plist = CopyParmList(Getattr(n, "parms")); + Parm *p; + Parm *pnext; + + for (p = plist; p; p = pnext) { + pnext = NIL; + String *tm = Getattr(p, "tmap:in"); + if (tm) { + pnext = Getattr(p, "tmap:in:next"); + if (checkAttribute(p, "tmap:in:numinputs", "0")) { + continue; + } + } + if (!pnext) { + pnext = nextSibling(p); + } + if (String *value = Getattr(p, "value")) { + String *type = Getattr(p, "type"); + if (!convertValue(value, type)) { + is_representable = false; + break; + } } - } else { - pnext = nextSibling(p); } - String *type = Getattr(p, "type"); - String *value = Getattr(p, "value"); - if (!convertValue(value, type)) - return false; } - return true; + return is_representable; } @@ -1892,7 +2045,7 @@ public: n = nn; /* For overloaded function, just use *args */ - if (is_real_overloaded(n) || GetFlag(n, "feature:compactdefaultargs") || !is_primitive_defaultargs(n)) { + if (is_real_overloaded(n) || GetFlag(n, "feature:compactdefaultargs") || !is_representable_as_pyargs(n)) { String *parms = NewString(""); if (in_class) Printf(parms, "self, "); @@ -2012,7 +2165,7 @@ public: if (ret) ret = SwigType_str(ret, 0); } - return (ret && py3) ? NewStringf(" -> \"%s\" ", ret) + return (ret && py3) ? NewStringf(" -> \"%s\"", ret) : NewString(""); } @@ -2029,15 +2182,15 @@ public: /* Make a wrapper function to insert the code into */ Printv(f_dest, "\ndef ", name, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); if (have_docstring(n)) - Printv(f_dest, " ", docstring(n, AUTODOC_FUNC, tab4), "\n", NIL); + Printv(f_dest, tab4, docstring(n, AUTODOC_FUNC, tab4), "\n", NIL); if (have_pythonprepend(n)) - Printv(f_dest, pythoncode(pythonprepend(n), " "), "\n", NIL); + Printv(f_dest, pythoncode(pythonprepend(n), tab4), "\n", NIL); if (have_pythonappend(n)) { - Printv(f_dest, " val = ", funcCall(name, callParms), "\n", NIL); - Printv(f_dest, pythoncode(pythonappend(n), " "), "\n", NIL); - Printv(f_dest, " return val\n", NIL); + Printv(f_dest, tab4 "val = ", funcCall(name, callParms), "\n", NIL); + Printv(f_dest, pythoncode(pythonappend(n), tab4), "\n", NIL); + Printv(f_dest, tab4 "return val\n", NIL); } else { - Printv(f_dest, " return ", funcCall(name, callParms), "\n", NIL); + Printv(f_dest, tab4 "return ", funcCall(name, callParms), "\n", NIL); } if (Getattr(n, "feature:python:callback") || !have_addtofunc(n)) { @@ -2052,7 +2205,7 @@ public: * check if using kwargs is allowed for this Node * ------------------------------------------------------------ */ - int check_kwargs(Node *n) { + int check_kwargs(Node *n) const { return (use_kw || GetFlag(n, "feature:kwargs")) && !GetFlag(n, "memberset") && !GetFlag(n, "memberget"); } @@ -2154,7 +2307,7 @@ public: Append(f->code, "--argc;\n"); } - Replaceall(dispatch, "$args", "self,args"); + Replaceall(dispatch, "$args", "self, args"); Printv(f->code, dispatch, "\n", NIL); @@ -2431,7 +2584,6 @@ public: } SwigType *pt = Getattr(p, "type"); - String *pn = Getattr(p, "name"); String *ln = Getattr(p, "lname"); bool parse_from_tuple = (i > 0 || !add_self); if (SwigType_type(pt) == T_VARARGS) { @@ -2453,18 +2605,9 @@ public: /* Keyword argument handling */ if (allow_kwargs && parse_from_tuple) { - if (Len(pn)) { - String *tmp = 0; - String *name = pn; - if (!Getattr(p, "hidden")) { - name = tmp = Swig_name_make(p, 0, pn, 0, 0); // rename parameter if a keyword - } - Printf(kwargs, "(char *) \"%s\",", name); - if (tmp) - Delete(tmp); - } else { - Printf(kwargs, "(char *)\"arg%d\",", i + 1); - } + String *name = makeParameterName(n, p, i + 1); + Printf(kwargs, "(char *) \"%s\",", name); + Delete(name); } /* Look for an input typemap */ @@ -2595,7 +2738,6 @@ public: /* Insert cleanup code */ for (p = l; p;) { - // if (!checkAttribute(p,"tmap:in:numinputs","0") && !Getattr(p,"tmap:in:parse")) { if (!Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) { if (Getattr(p, "tmap:freearg:implicitconv")) { const char *convflag = "0"; @@ -3203,7 +3345,7 @@ public: * BEGIN C++ Director Class modifications * ------------------------------------------------------------------------- */ - /* C++/Python polymorphism demo code, copyright (C) 2002 Mark Rose <mrose@stm.lbl.gov> + /* C++/Python polymorphism demo code * * TODO * @@ -3901,7 +4043,7 @@ public: Printv(base_class, bname, NIL); b = Next(b); if (b.item) { - Putc(',', base_class); + Printv(base_class, ", ", NIL); } } } @@ -3922,7 +4064,7 @@ public: String *abcs = Getattr(n, "feature:python:abc"); if (py3 && abcs) { if (Len(base_class)) { - Putc(',', base_class); + Printv(base_class, ", ", NIL); } Printv(base_class, abcs, NIL); } @@ -3957,7 +4099,7 @@ public: if (!modern) { Printv(f_shadow, tab4, "__swig_setmethods__ = {}\n", NIL); if (Len(base_class)) { - Printf(f_shadow, "%sfor _s in [%s]: __swig_setmethods__.update(getattr(_s,'__swig_setmethods__',{}))\n", tab4, base_class); + Printv(f_shadow, tab4, "for _s in [", base_class, "]:\n", tab8, "__swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))\n", NIL); } if (!GetFlag(n, "feature:python:nondynamic")) { @@ -3968,7 +4110,7 @@ public: Printv(f_shadow, tab4, "__swig_getmethods__ = {}\n", NIL); if (Len(base_class)) { - Printf(f_shadow, "%sfor _s in [%s]: __swig_getmethods__.update(getattr(_s,'__swig_getmethods__',{}))\n", tab4, base_class); + Printv(f_shadow, tab4, "for _s in [", base_class, "]:\n", tab8, "__swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))\n", NIL); } Printv(f_shadow, tab4, "__getattr__ = lambda self, name: _swig_getattr(self, ", class_name, ", name)\n", NIL); @@ -4056,7 +4198,7 @@ public: Delete(realct); if (!have_constructor) { if (!builtin) - Printv(f_shadow_file, tab4, "def __init__(self, *args, **kwargs): raise AttributeError(\"", "No constructor defined", + Printv(f_shadow_file, "\n", tab4, "def __init__(self, *args, **kwargs):\n", tab8, "raise AttributeError(\"", "No constructor defined", (Getattr(n, "abstracts") ? " - class is abstract" : ""), "\")\n", NIL); } else if (fastinit && !builtin) { @@ -4094,12 +4236,12 @@ public: Printv(f_shadow_file, "\nclass ", class_name, "Ptr(", class_name, "):\n", tab4, "def __init__(self, this):\n", NIL); if (!modern) { Printv(f_shadow_file, - tab8, "try: self.this.append(this)\n", - tab8, "except: self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL); + tab8, "try:\n", tab8, tab4, "self.this.append(this)\n", + tab8, "except:\n", tab8, tab4, "self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL); } else { Printv(f_shadow_file, - tab8, "try: self.this.append(this)\n", - tab8, "except: self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL); + tab8, "try:\n", tab8, tab4, "self.this.append(this)\n", + tab8, "except:\n", tab8, tab4, "self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL); } } @@ -4108,7 +4250,7 @@ public: List *shadow_list = Getattr(n, "shadow_methods"); for (int i = 0; i < Len(shadow_list); ++i) { String *symname = Getitem(shadow_list, i); - Printf(f_shadow_file, "%s.%s = new_instancemethod(%s.%s,None,%s)\n", class_name, symname, module, Swig_name_member(NSPACE_TODO, class_name, symname), + Printf(f_shadow_file, "%s.%s = new_instancemethod(%s.%s, None, %s)\n", class_name, symname, module, Swig_name_member(NSPACE_TODO, class_name, symname), class_name); } } @@ -4223,12 +4365,11 @@ public: String *callParms = make_pyParmList(n, true, true, allow_kwargs); if (!have_addtofunc(n)) { if (!fastproxy || olddefs) { - Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL); - Printv(f_shadow, " return ", funcCall(fullname, callParms), "\n", NIL); + Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); + Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n", NIL); } } else { - Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL); - Printv(f_shadow, "\n", NIL); + Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); if (have_docstring(n)) Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL); if (have_pythonprepend(n)) { @@ -4314,7 +4455,7 @@ public: int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0; String *parms = make_pyParmList(n, false, false, kw); String *callParms = make_pyParmList(n, false, true, kw); - Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); + Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); if (have_docstring(n)) Printv(f_shadow, tab8, docstring(n, AUTODOC_STATICFUNC, tab8), "\n", NIL); if (have_pythonprepend(n)) @@ -4326,7 +4467,9 @@ public: } else { Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n\n", NIL); } - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", symname, ")\n", NIL); + if (!modern) + Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL); + Printv(f_shadow, tab4, symname, " = staticmethod(", symname, ")\n", NIL); if (!modern) { Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", symname, "\n", NIL); @@ -4338,7 +4481,9 @@ public: NIL); } if (!classic) { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), + if (!modern) + Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL); + Printv(f_shadow, tab4, symname, " = staticmethod(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), ")\n", NIL); } } @@ -4427,7 +4572,7 @@ public: Printv(pass_self, tab8, tab4, "_self = None\n", tab8, "else:\n", tab8, tab4, "_self = self\n", NIL); } - Printv(f_shadow, tab4, "def __init__(", parms, ")", returnTypeAnnotation(n), ": \n", NIL); + Printv(f_shadow, "\n", tab4, "def __init__(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); if (have_docstring(n)) Printv(f_shadow, tab8, docstring(n, AUTODOC_CTOR, tab8), "\n", NIL); if (have_pythonprepend(n)) @@ -4438,7 +4583,7 @@ public: } else { Printv(f_shadow, tab8, "this = ", funcCall(Swig_name_construct(NSPACE_TODO, symname), callParms), "\n", - tab8, "try: self.this.append(this)\n", tab8, "except: self.this = this\n", NIL); + tab8, "try:\n", tab8, tab4, "self.this.append(this)\n", tab8, "except:\n", tab8, tab4, "self.this = this\n", NIL); } if (have_pythonappend(n)) Printv(f_shadow, pythoncode(pythonappend(n), tab8), "\n\n", NIL); @@ -4524,7 +4669,7 @@ public: Printv(f_shadow, tab4, "__swig_destroy__ = ", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "\n", NIL); if (!have_pythonprepend(n) && !have_pythonappend(n)) { if (proxydel) { - Printv(f_shadow, tab4, "__del__ = lambda self : None;\n", NIL); + Printv(f_shadow, tab4, "__del__ = lambda self: None\n", NIL); } return SWIG_OK; } @@ -4535,7 +4680,7 @@ public: Printv(f_shadow, pythoncode(pythonprepend(n), tab8), "\n", NIL); #ifdef USE_THISOWN Printv(f_shadow, tab8, "try:\n", NIL); - Printv(f_shadow, tab8, tab4, "if self.thisown: ", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "(self)\n", NIL); + Printv(f_shadow, tab8, tab4, "if self.thisown:", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "(self)\n", NIL); Printv(f_shadow, tab8, "except: pass\n", NIL); #else #endif @@ -4573,11 +4718,12 @@ public: Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", getname, "\n", NIL); } if (!classic) { - if (!assignable) { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ")\n", NIL); - } else { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ", ", module, ".", setname, ")\n", NIL); - } + if (!modern) + Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL); + Printv(f_shadow, tab4, symname, " = _swig_property(", module, ".", getname, NIL); + if (assignable) + Printv(f_shadow, ", ", module, ".", setname, NIL); + Printv(f_shadow, ")\n", NIL); } Delete(mname); Delete(setname); @@ -4646,11 +4792,12 @@ public: Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", getname, "\n", NIL); } if (!classic && !builtin) { - if (!assignable) { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ")\n", NIL); - } else { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ", ", module, ".", setname, ")\n", NIL); - } + if (!modern) + Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL); + Printv(f_shadow, tab4, symname, " = _swig_property(", module, ".", getname, NIL); + if (assignable) + Printv(f_shadow, ", ", module, ".", setname, NIL); + Printv(f_shadow, ")\n", NIL); } String *getter = Getattr(n, "pybuiltin:getter"); String *setter = Getattr(n, "pybuiltin:setter"); @@ -4776,6 +4923,13 @@ public: return NewString("swigpyrun.h"); } + /*---------------------------------------------------------------------- + * kwargsSupport() + *--------------------------------------------------------------------*/ + + bool kwargsSupport() const { + return true; + } }; /* --------------------------------------------------------------- @@ -4813,6 +4967,16 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { int idx; bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; + if (builtin) { + // Rename any wrapped parameters called 'self' as the generated code contains a variable with same name + Parm *p; + for (p = l; p; p = nextSibling(p)) { + String *arg = Getattr(p, "name"); + if (arg && Cmp(arg, "self") == 0) + Delattr(p, "name"); + } + } + if (Cmp(storage, "virtual") == 0) { if (Cmp(value, "0") == 0) { pure_virtual = true; diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index 6aeaae5a1..310e89b82 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -3426,6 +3426,14 @@ public: String *defaultExternalRuntimeFilename() { return NewString("swigrubyrun.h"); } + + /*---------------------------------------------------------------------- + * kwargsSupport() + *--------------------------------------------------------------------*/ + + bool kwargsSupport() const { + return true; + } }; /* class RUBY */ /* ----------------------------------------------------------------------------- diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx index 8a0861d17..6bbf40d95 100644 --- a/Source/Modules/swigmain.cxx +++ b/Source/Modules/swigmain.cxx @@ -180,11 +180,6 @@ int main(int margc, char **margv) { } else if (strcmp(argv[i], "-nolang") == 0) { dl = new Language; Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-dnone") == 0) || - (strcmp(argv[i], "-dhtml") == 0) || - (strcmp(argv[i], "-dlatex") == 0) || (strcmp(argv[i], "-dascii") == 0) || (strcmp(argv[i], "-stat") == 0)) { - Printf(stderr, "swig: Warning. %s option deprecated.\n", argv[i]); - Swig_mark_arg(i); } else if ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) { if (strcmp(argv[i], "--help") == 0) strcpy(argv[i], "-help"); diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index 63b91bae5..a30fdf8fa 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -291,12 +291,18 @@ protected: /* Return the current class prefix */ String *getClassPrefix() const; + /* Return the current enum class prefix */ + String *getEnumClassPrefix() const; + /* Fully qualified type name to use */ String *getClassType() const; /* Return true if the current method is part of a smart-pointer */ int is_smart_pointer() const; + /* Return the name to use for the given parameter. */ + virtual String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter = false) const; + /* Some language modules require additional wrappers for virtual methods not declared in sub-classes */ virtual bool extraDirectorProtectedCPPMethodsRequired() const; @@ -315,6 +321,9 @@ public: */ virtual NestedClassSupport nestedClassesSupport() const; + /* Returns true if the target language supports key word arguments (kwargs) */ + virtual bool kwargsSupport() const; + protected: /* Identifies if a protected members that are generated when the allprotected option is used. This does not include protected virtual methods as they are turned on with the dirprot option. */ diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 329a601a8..3e323f910 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -667,6 +667,9 @@ class TypePass:private Dispatcher { /* Normalize types. */ SwigType *ty = Getattr(n, "type"); + if (!ty) { + return SWIG_OK; + } normalize_type(ty); SwigType *decl = Getattr(n, "decl"); if (decl) { |