diff options
Diffstat (limited to 'Source')
30 files changed, 1402 insertions, 480 deletions
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 621d43421..784187c28 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -13,11 +13,14 @@ * some point. Beware. * ----------------------------------------------------------------------------- */ -/* -Removed until we know more about the min versions of Bison and Yacc required for this -to work, see Byacc man page: http://invisible-island.net/byacc/manpage/yacc.html +/* There are 6 known shift-reduce conflicts in this file, fail compilation if any + more are introduced. + + Please don't increase the number of the conflicts if at all possible. And if + you really have no choice but to do it, make sure you clearly document each + new conflict in this file. + */ %expect 6 -*/ %{ #define yylex yylex @@ -142,7 +145,7 @@ static Node *copy_node(Node *n) { Setattr(nn, key, k.item); continue; } - /* defaultargs will be patched back in later */ + /* defaultargs will be patched back in later in update_defaultargs() */ if (strcmp(ckey,"defaultargs") == 0) { Setattr(nn, "needs_defaultargs", "1"); continue; @@ -657,19 +660,26 @@ static void add_symbols_copy(Node *n) { } } +/* Add in the "defaultargs" attribute for functions in instantiated templates. + * n should be any instantiated template (class or start of linked list of functions). */ static void update_defaultargs(Node *n) { if (n) { Node *firstdefaultargs = n; update_defaultargs(firstChild(n)); n = nextSibling(n); + /* recursively loop through nodes of all types, but all we really need are the overloaded functions */ while (n) { update_defaultargs(firstChild(n)); - assert(!Getattr(n, "defaultargs")); - if (Getattr(n, "needs_defaultargs")) { - Setattr(n, "defaultargs", firstdefaultargs); - Delattr(n, "needs_defaultargs"); + if (!Getattr(n, "defaultargs")) { + if (Getattr(n, "needs_defaultargs")) { + Setattr(n, "defaultargs", firstdefaultargs); + Delattr(n, "needs_defaultargs"); + } else { + firstdefaultargs = n; + } } else { - firstdefaultargs = n; + /* Functions added in with %extend (for specialized template classes) will already have default args patched up */ + assert(Getattr(n, "defaultargs") == firstdefaultargs); } n = nextSibling(n); } @@ -2753,7 +2763,11 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va Swig_symbol_setscope(csyms); } - /* Merge in %extend methods for this class */ + /* Merge in %extend methods for this class. + This only merges methods within %extend for a template specialized class such as + template<typename T> class K {}; %extend K<int> { ... } + The copy_node() call above has already added in the generic %extend methods such as + template<typename T> class K {}; %extend K { ... } */ /* !!! This may be broken. We may have to add the %extend methods at the beginning of the class */ @@ -2885,16 +2899,15 @@ c_declaration : c_decl { SWIG_WARN_NODE_END($$); } | USING idcolon EQUAL type plain_declarator SEMI { - $$ = new_node("using"); - Setattr($$,"name",$2); + /* Convert using statement to a typedef statement */ + $$ = new_node("cdecl"); SwigType_push($4,$5.type); - Setattr($$,"uname",$4); + Setattr($$,"type",$4); + Setattr($$,"storage","typedef"); + Setattr($$,"name",$2); + Setattr($$,"decl",""); + SetFlag($$,"typealias"); add_symbols($$); - SWIG_WARN_NODE_BEGIN($$); - Swig_warning(WARN_CPP11_ALIAS_DECLARATION, cparse_file, cparse_line, "The 'using' keyword in type aliasing is not fully supported yet.\n"); - SWIG_WARN_NODE_END($$); - - $$ = 0; /* TODO - ignored for now */ } | TEMPLATE LESSTHAN template_parms GREATERTHAN USING idcolon EQUAL type plain_declarator SEMI { $$ = new_node("using"); @@ -2926,6 +2939,14 @@ c_decl : storage_class type declarator initializer c_decl_tail { Setattr($$,"throws",$4.throws); Setattr($$,"throw",$4.throwf); Setattr($$,"noexcept",$4.nexcept); + if ($4.val && $4.type) { + /* store initializer type as it might be different to the declared type */ + SwigType *valuetype = NewSwigType($4.type); + if (Len(valuetype) > 0) + Setattr($$,"valuetype",valuetype); + else + Delete(valuetype); + } if (!$5) { if (Len(scanner_ccode)) { String *code = Copy(scanner_ccode); @@ -6131,11 +6152,11 @@ exprcompound : expr PLUS expr { } /* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these. | expr GREATERTHAN expr { - $$.val = NewStringf("%s < %s", $1.val, $3.val); + $$.val = NewStringf("%s > %s", $1.val, $3.val); $$.type = cparse_cplusplus ? T_BOOL : T_INT; } | expr LESSTHAN expr { - $$.val = NewStringf("%s > %s", $1.val, $3.val); + $$.val = NewStringf("%s < %s", $1.val, $3.val); $$.type = cparse_cplusplus ? T_BOOL : T_INT; } */ diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h index bc54bc774..865655896 100644 --- a/Source/Include/swigwarn.h +++ b/Source/Include/swigwarn.h @@ -256,6 +256,7 @@ #define WARN_JAVA_TYPEMAP_JAVAIN_UNDEF 818 #define WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF 819 #define WARN_JAVA_TYPEMAP_JAVADIRECTOROUT_UNDEF 820 +#define WARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF 821 #define WARN_JAVA_COVARIANT_RET 822 #define WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF 823 #define WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC 824 @@ -275,6 +276,7 @@ #define WARN_CSHARP_TYPEMAP_CSIN_UNDEF 838 #define WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF 839 #define WARN_CSHARP_TYPEMAP_CSDIRECTOROUT_UNDEF 840 +#define WARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF 841 #define WARN_CSHARP_COVARIANT_RET 842 #define WARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF 843 #define WARN_CSHARP_EXCODE 844 diff --git a/Source/Makefile.am b/Source/Makefile.am index a316b83d1..d14865ee0 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -47,6 +47,7 @@ eswig_SOURCES = CParse/cscanner.c \ Modules/emit.cxx \ Modules/go.cxx \ Modules/guile.cxx \ + Modules/interface.cxx \ Modules/java.cxx \ Modules/javascript.cxx \ Modules/lang.cxx \ diff --git a/Source/Modules/allegrocl.cxx b/Source/Modules/allegrocl.cxx index fae255b7f..b69e1dd70 100644 --- a/Source/Modules/allegrocl.cxx +++ b/Source/Modules/allegrocl.cxx @@ -1893,11 +1893,12 @@ static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); } else { - if (!Getattr(nodes[j].n, "overload:ignore")) + if (!Getattr(nodes[j].n, "overload:ignore")) { Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), "using %s instead.\n", Swig_name_decl(nodes[i].n)); + } } } nodes[j].error = 1; @@ -1910,11 +1911,12 @@ static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); } else { - if (!Getattr(nodes[j].n, "overload:ignore")) + if (!Getattr(nodes[j].n, "overload:ignore")) { Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), "using %s instead.\n", Swig_name_decl(nodes[i].n)); + } } } nodes[j].error = 1; @@ -1932,11 +1934,12 @@ static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n), "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n)); } else { - if (!Getattr(nodes[j].n, "overload:ignore")) + if (!Getattr(nodes[j].n, "overload:ignore")) { Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), "using %s instead.\n", Swig_name_decl(nodes[i].n)); + } } nodes[j].error = 1; } @@ -3166,6 +3169,9 @@ int ALLEGROCL::enumDeclaration(Node *n) { Printf(stderr, "enumDeclaration %s\n", Getattr(n, "name")); #endif + if (getCurrentClass() && (cplus_mode != PUBLIC)) + return SWIG_NOWRAP; + if (Getattr(n, "sym:name")) { add_defined_foreign_type(n); } diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index f79373d18..3d382b378 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -729,6 +729,8 @@ Allocate(): } } + Swig_interface_propagate_methods(n); + /* Only care about default behavior. Remove temporary values */ Setattr(n, "allocate:visit", "1"); Swig_symbol_setscope(symtab); diff --git a/Source/Modules/cffi.cxx b/Source/Modules/cffi.cxx index 5d2b8435c..c355e452a 100644 --- a/Source/Modules/cffi.cxx +++ b/Source/Modules/cffi.cxx @@ -688,6 +688,9 @@ int CFFI::typedefHandler(Node *n) { } int CFFI::enumDeclaration(Node *n) { + if (getCurrentClass() && (cplus_mode != PUBLIC)) + return SWIG_NOWRAP; + String *name = Getattr(n, "sym:name"); bool slot_name_keywords; String *lisp_name = 0; @@ -1107,7 +1110,7 @@ String *CFFI::convert_literal(String *literal, String *type, bool try_to_split) return num; } else if (SwigType_type(type) == T_CHAR) { /* Use CL syntax for character literals */ - String* result = NewStringf("#\\%c", s[0]); + String* result = NewStringf("#\\%s", s); Delete(num); return result; } else if (SwigType_type(type) == T_STRING) { diff --git a/Source/Modules/clisp.cxx b/Source/Modules/clisp.cxx index 7d7c69a50..d7f197197 100644 --- a/Source/Modules/clisp.cxx +++ b/Source/Modules/clisp.cxx @@ -242,6 +242,9 @@ int CLISP::typedefHandler(Node *n) { } int CLISP::enumDeclaration(Node *n) { + if (getCurrentClass() && (cplus_mode != PUBLIC)) + return SWIG_NOWRAP; + is_function = 0; String *name = Getattr(n, "sym:name"); diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 8a047c46d..01fd5435b 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -52,6 +52,7 @@ class CSHARP:public Language { String *imclass_class_code; // intermediary class code String *proxy_class_def; String *proxy_class_code; + String *interface_class_code; // if %feature("interface") was declared for a class, here goes the interface declaration String *module_class_code; String *proxy_class_name; // proxy class name String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name @@ -126,6 +127,7 @@ public: imclass_class_code(NULL), proxy_class_def(NULL), proxy_class_code(NULL), + interface_class_code(NULL), module_class_code(NULL), proxy_class_name(NULL), full_imclass_name(NULL), @@ -186,8 +188,12 @@ 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, Getattr(outer_class, "sym:name")); + if (String* name = Getattr(outer_class, "sym:name")) { + Push(symname, "."); + Push(symname, name); + } + else + return NULL; } } if (nspace) { @@ -272,6 +278,7 @@ public: SWIG_config_file("csharp.swg"); allow_overloading(); + Swig_interface_feature_enable(); } /* --------------------------------------------------------------------- @@ -1317,7 +1324,7 @@ public: const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0"; Setattr(n, "enumvalue", val); } else if (swigtype == T_CHAR) { - String *val = NewStringf("'%s'", Getattr(n, "enumvalue")); + String *val = NewStringf("'%(hexescape)s'", Getattr(n, "enumvalue")); Setattr(n, "enumvalue", val); Delete(val); } @@ -1441,6 +1448,7 @@ public: virtual int constantWrapper(Node *n) { String *symname = Getattr(n, "sym:name"); SwigType *t = Getattr(n, "type"); + SwigType *valuetype = Getattr(n, "valuetype"); ParmList *l = Getattr(n, "parms"); String *tm; String *return_type = NewString(""); @@ -1493,13 +1501,15 @@ public: Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0)); } + // Default (octal) escaping is no good - change to hex escaped value + String *hexescaped_value = Getattr(n, "rawvalue") ? NewStringf("%(hexescape)s", Getattr(n, "rawvalue")) : 0; // Add the stripped quotes back in String *new_value = NewString(""); if (SwigType_type(t) == T_STRING) { - Printf(new_value, "\"%s\"", Copy(Getattr(n, "value"))); + Printf(new_value, "\"%s\"", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value"))); Setattr(n, "value", new_value); } else if (SwigType_type(t) == T_CHAR) { - Printf(new_value, "\'%s\'", Copy(Getattr(n, "value"))); + Printf(new_value, "\'%s\'", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value"))); Setattr(n, "value", new_value); } @@ -1540,10 +1550,14 @@ public: } else { // Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code if (Getattr(n, "wrappedasconstant")) { - if (SwigType_type(t) == T_CHAR) - Printf(constants_code, "\'%s\';\n", Getattr(n, "staticmembervariableHandler:value")); - else + if (SwigType_type(t) == T_CHAR) { + if (SwigType_type(valuetype) == T_CHAR) + Printf(constants_code, "\'%(hexescape)s\';\n", Getattr(n, "staticmembervariableHandler:value")); + else + Printf(constants_code, "(char)%s;\n", Getattr(n, "staticmembervariableHandler:value")); + } else { Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value")); + } } else { Printf(constants_code, "%s;\n", Getattr(n, "value")); } @@ -1644,6 +1658,119 @@ public: } /* ----------------------------------------------------------------------------- + * getQualifiedInterfaceName() + * ----------------------------------------------------------------------------- */ + + String *getQualifiedInterfaceName(Node *n) { + String *ret = Getattr(n, "interface:qname"); + if (!ret) { + String *nspace = Getattr(n, "sym:nspace"); + String *interface_name = Getattr(n, "interface:name"); + if (nspace) { + if (namespce) + ret = NewStringf("%s.%s.%s", namespce, nspace, interface_name); + else + ret = NewStringf("%s.%s", nspace, interface_name); + } else { + ret = Copy(interface_name); + } + Setattr(n, "interface:qname", ret); + } + return ret; + } + + /* ----------------------------------------------------------------------------- + * getInterfaceName() + * ----------------------------------------------------------------------------- */ + + String *getInterfaceName(SwigType *t, bool qualified) { + String *interface_name = NULL; + if (proxy_flag) { + Node *n = classLookup(t); + if (n && Getattr(n, "interface:name")) + interface_name = qualified ? getQualifiedInterfaceName(n) : Getattr(n, "interface:name"); + } + return interface_name; + } + + /* ----------------------------------------------------------------------------- + * addInterfaceNameAndUpcasts() + * ----------------------------------------------------------------------------- */ + + void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) { + List *keys = Keys(base_list); + for (Iterator it = First(keys); it.item; it = Next(it)) { + Node *base = Getattr(base_list, it.item); + String *c_baseclass = SwigType_namestr(Getattr(base, "name")); + String *interface_name = Getattr(base, "interface:name"); + if (Len(interface_list)) + Append(interface_list, ", "); + Append(interface_list, interface_name); + + Node *attributes = NewHash(); + String *interface_code = Copy(typemapLookup(base, "csinterfacecode", Getattr(base, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF, attributes)); + String *cptr_method_name = 0; + if (interface_code) { + Replaceall(interface_code, "$interfacename", interface_name); + Printv(interface_upcasts, interface_code, NIL); + cptr_method_name = Copy(Getattr(attributes, "tmap:csinterfacecode:cptrmethod")); + } + if (!cptr_method_name) + cptr_method_name = NewStringf("%s_GetInterfaceCPtr", interface_name); + Replaceall(cptr_method_name, ".", "_"); + Replaceall(cptr_method_name, "$interfacename", interface_name); + + String *upcast_method_name = Swig_name_member(getNSpace(), proxy_class_name, cptr_method_name); + upcastsCode(smart, upcast_method_name, c_classname, c_baseclass); + + Delete(upcast_method_name); + Delete(cptr_method_name); + Delete(interface_code); + Delete(c_baseclass); + } + Delete(keys); + } + + /* ----------------------------------------------------------------------------- + * upcastsCode() + * + * Add code for C++ casting to base class + * ----------------------------------------------------------------------------- */ + + void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) { + String *wname = Swig_name_wrapper(upcast_method_name); + + Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL); + Printf(imclass_cppcasts_code, " public static extern global::System.IntPtr %s(global::System.IntPtr jarg1);\n", upcast_method_name); + + Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name); + + if (smart) { + SwigType *bsmart = Copy(smart); + SwigType *rclassname = SwigType_typedef_resolve_all(c_classname); + SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass); + Replaceall(bsmart, rclassname, rbaseclass); + Delete(rclassname); + Delete(rbaseclass); + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); + Printv(upcasts_code, + "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n", + " return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n" + "}\n", "\n", NIL); + Delete(bsmartnamestr); + Delete(smartnamestr); + Delete(bsmart); + } else { + Printv(upcasts_code, + "SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n", + " return (", c_baseclass, " *)jarg1;\n" + "}\n", "\n", NIL); + } + Delete(wname); + } + + /* ----------------------------------------------------------------------------- * emitProxyClassDefAndCPPCasts() * ----------------------------------------------------------------------------- */ @@ -1652,9 +1779,12 @@ public: String *c_baseclass = NULL; String *baseclass = NULL; String *c_baseclassname = NULL; + String *interface_list = NewStringEmpty(); + String *interface_upcasts = NewStringEmpty(); SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); bool feature_director = Swig_directorclass(n) ? true : false; bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested"); + SwigType *smart = Swig_cparse_smartptr(n); // Inheritance from pure C# classes Node *attributes = NewHash(); @@ -1667,31 +1797,29 @@ public: if (!purebase_replace) { List *baselist = Getattr(n, "bases"); if (baselist) { - Iterator base = First(baselist); - while (base.item && GetFlag(base.item, "feature:ignore")) { - base = Next(base); - } - if (base.item) { - c_baseclassname = Getattr(base.item, "name"); - baseclass = Copy(getProxyName(c_baseclassname)); - if (baseclass) - c_baseclass = SwigType_namestr(Getattr(base.item, "name")); - base = Next(base); - /* Warn about multiple inheritance for additional base class(es) */ - while (base.item) { - if (GetFlag(base.item, "feature:ignore")) { - base = Next(base); - continue; - } - String *proxyclassname = Getattr(n, "classtypeobj"); - String *baseclassname = Getattr(base.item, "name"); - Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname)); - base = Next(base); - } - } + Iterator base = First(baselist); + while (base.item) { + if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) { + String *baseclassname = Getattr(base.item, "name"); + if (!c_baseclassname) { + c_baseclassname = baseclassname; + baseclass = Copy(getProxyName(baseclassname)); + if (baseclass) + c_baseclass = SwigType_namestr(baseclassname); + } else { + /* Warn about multiple inheritance for additional base class(es) */ + String *proxyclassname = Getattr(n, "classtypeobj"); + Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), + "Warning for %s, base %s ignored. Multiple inheritance is not supported in C#.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname)); + } + } + base = Next(base); + } } } + Hash *interface_bases = Getattr(n, "interface:bases"); + if (interface_bases) + addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname); bool derived = baseclass && getProxyName(c_baseclassname); if (derived && purebase_notderived) @@ -1707,12 +1835,15 @@ public: Swig_error(Getfile(n), Getline(n), "The csbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type); } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) { Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#. " + "Warning for %s, base %s ignored. Multiple inheritance is not supported in C#. " "Perhaps you need one of the 'replace' or 'notderived' attributes in the csbase typemap?\n", typemap_lookup_type, pure_baseclass); } // Pure C# interfaces const String *pure_interfaces = typemapLookup(n, derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE); + if (*Char(interface_list) && *Char(pure_interfaces)) + Append(interface_list, ", "); + Append(interface_list, pure_interfaces); // Start writing the proxy class if (!has_outerclass) Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements @@ -1725,8 +1856,8 @@ public: Printv(proxy_class_def, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers " $csclassname", // Class name and base class - (*Char(wanted_base) || *Char(pure_interfaces)) ? " : " : "", wanted_base, (*Char(wanted_base) && *Char(pure_interfaces)) ? // Interfaces - ", " : "", pure_interfaces, " {", derived ? typemapLookup(n, "csbody_derived", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF) : // main body of class + (*Char(wanted_base) || *Char(interface_list)) ? " : " : "", wanted_base, (*Char(wanted_base) && *Char(interface_list)) ? // Interfaces + ", " : "", interface_list, " {", derived ? typemapLookup(n, "csbody_derived", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF) : // main body of class typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class NIL); @@ -1771,6 +1902,8 @@ public: Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n", NIL); } + if (*Char(interface_upcasts)) + Printv(proxy_class_def, interface_upcasts, NIL); if (feature_director) { // Generate director connect method @@ -1852,6 +1985,8 @@ public: Delete(director_connect_method_name); } + Delete(interface_upcasts); + Delete(interface_list); Delete(attributes); Delete(destruct); @@ -1859,54 +1994,92 @@ public: Printv(proxy_class_def, typemapLookup(n, "cscode", typemap_lookup_type, WARN_NONE), // extra C# code "\n", NIL); - // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) if (derived) { - SwigType *smart = Swig_cparse_smartptr(n); - String *upcast_method = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); - String *wname = Swig_name_wrapper(upcast_method); - - Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL); - Printf(imclass_cppcasts_code, " public static extern global::System.IntPtr %s(global::System.IntPtr jarg1);\n", upcast_method); - - Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name); - - if (smart) { - SwigType *bsmart = Copy(smart); - SwigType *rclassname = SwigType_typedef_resolve_all(c_classname); - SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass); - Replaceall(bsmart, rclassname, rbaseclass); - Delete(rclassname); - Delete(rbaseclass); - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(bsmart); - Printv(upcasts_code, - "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n", - " return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n" - "}\n", "\n", NIL); - Delete(bsmartnamestr); - Delete(smartnamestr); - Delete(bsmart); - } else { - Printv(upcasts_code, - "SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n", - " return (", c_baseclass, " *)jarg1;\n" - "}\n", "\n", NIL); - } - Delete(wname); - Delete(upcast_method); - Delete(smart); + String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); + upcastsCode(smart, upcast_method_name, c_classname, c_baseclass); + Delete(upcast_method_name); } + + Delete(smart); Delete(baseclass); } /* ---------------------------------------------------------------------- + * emitInterfaceDeclaration() + * ---------------------------------------------------------------------- */ + + void emitInterfaceDeclaration(Node *n, String *interface_name, File *f_interface) { + Printv(f_interface, typemapLookup(n, "csimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL); + Printf(f_interface, "public interface %s", interface_name); + if (List *baselist = Getattr(n, "bases")) { + String *bases = 0; + for (Iterator base = First(baselist); base.item; base = Next(base)) { + if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface")) + continue; // TODO: warn about skipped non-interface bases + String *base_iname = Getattr(base.item, "interface:name"); + if (!bases) + bases = NewStringf(" : %s", base_iname); + else { + Append(bases, ", "); + Append(bases, base_iname); + } + } + if (bases) { + Printv(f_interface, bases, NIL); + Delete(bases); + } + } + Printf(f_interface, " {\n"); + + Node *attributes = NewHash(); + String *interface_code = Copy(typemapLookup(n, "csinterfacecode", Getattr(n, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF, attributes)); + if (interface_code) { + String *interface_declaration = Copy(Getattr(attributes, "tmap:csinterfacecode:declaration")); + if (interface_declaration) { + Replaceall(interface_declaration, "$interfacename", interface_name); + Printv(f_interface, interface_declaration, NIL); + Delete(interface_declaration); + } + Delete(interface_code); + } + } + + /* ---------------------------------------------------------------------- + * calculateDirectBase() + * ---------------------------------------------------------------------- */ + + void calculateDirectBase(Node* n) { + Node* direct_base = 0; + // C++ inheritance + Node *attributes = NewHash(); + SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); + const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE, attributes); + bool purebase_replace = GetFlag(attributes, "tmap:csbase:replace") ? true : false; + bool purebase_notderived = GetFlag(attributes, "tmap:csbase:notderived") ? true : false; + Delete(attributes); + if (!purebase_replace) { + if (List *baselist = Getattr(n, "bases")) { + Iterator base = First(baselist); + while (base.item && (GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) + base = Next(base); + direct_base = base.item; + } + if (!direct_base && purebase_notderived) + direct_base = symbolLookup(const_cast<String*>(pure_baseclass)); + } else { + direct_base = symbolLookup(const_cast<String*>(pure_baseclass)); + } + Setattr(n, "direct_base", direct_base); + } + + /* ---------------------------------------------------------------------- * classHandler() * ---------------------------------------------------------------------- */ virtual int classHandler(Node *n) { - String *nspace = getNSpace(); File *f_proxy = NULL; + File *f_interface = NULL; // save class local variables String *old_proxy_class_name = proxy_class_name; String *old_full_imclass_name = full_imclass_name; @@ -1915,9 +2088,12 @@ public: String *old_proxy_class_def = proxy_class_def; String *old_proxy_class_code = proxy_class_code; bool has_outerclass = Getattr(n, "nested:outer") && !GetFlag(n, "feature:flatnested"); + String *old_interface_class_code = interface_class_code; + interface_class_code = 0; if (proxy_flag) { proxy_class_name = NewString(Getattr(n, "sym:name")); + String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0; if (Node *outer = Getattr(n, "nested:outer")) { String *outerClassesPrefix = Copy(Getattr(outer, "sym:name")); for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { @@ -1927,13 +2103,16 @@ public: String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix; if (!addSymbol(proxy_class_name, n, fnspace)) return SWIG_ERROR; + if (interface_name && !addInterfaceSymbol(interface_name, n, fnspace)) + return SWIG_ERROR; if (nspace) Delete(fnspace); Delete(outerClassesPrefix); - } - else { + } else { if (!addSymbol(proxy_class_name, n, nspace)) return SWIG_ERROR; + if (interface_name && !addInterfaceSymbol(interface_name, n, nspace)) + return SWIG_ERROR; } if (!nspace) { @@ -1960,13 +2139,25 @@ public: f_proxy = getOutputFile(output_directory, proxy_class_name); addOpenNamespace(nspace, f_proxy); + Delete(output_directory); } else ++nesting_depth; + proxy_class_def = NewString(""); proxy_class_code = NewString(""); destructor_call = NewString(""); proxy_class_constants_code = NewString(""); + + if (Getattr(n, "feature:interface")) { + interface_class_code = NewString(""); + String *output_directory = outputDirectory(nspace); + f_interface = getOutputFile(output_directory, interface_name); + addOpenNamespace(nspace, f_interface); + emitInterfaceDeclaration(n, interface_name, interface_class_code); + Delete(output_directory); + } + calculateDirectBase(n); } Language::classHandler(n); @@ -1980,22 +2171,28 @@ public: Replaceall(proxy_class_def, "$csclassname", proxy_class_name); Replaceall(proxy_class_code, "$csclassname", proxy_class_name); Replaceall(proxy_class_constants_code, "$csclassname", proxy_class_name); + Replaceall(interface_class_code, "$csclassname", proxy_class_name); Replaceall(proxy_class_def, "$csclazzname", csclazzname); Replaceall(proxy_class_code, "$csclazzname", csclazzname); Replaceall(proxy_class_constants_code, "$csclazzname", csclazzname); + Replaceall(interface_class_code, "$csclazzname", csclazzname); Replaceall(proxy_class_def, "$module", module_class_name); Replaceall(proxy_class_code, "$module", module_class_name); Replaceall(proxy_class_constants_code, "$module", module_class_name); + Replaceall(interface_class_code, "$module", module_class_name); Replaceall(proxy_class_def, "$imclassname", full_imclass_name); Replaceall(proxy_class_code, "$imclassname", full_imclass_name); Replaceall(proxy_class_constants_code, "$imclassname", full_imclass_name); + Replaceall(interface_class_code, "$imclassname", full_imclass_name); Replaceall(proxy_class_def, "$dllimport", dllimport); Replaceall(proxy_class_code, "$dllimport", dllimport); Replaceall(proxy_class_constants_code, "$dllimport", dllimport); + Replaceall(interface_class_code, "$dllimport", dllimport); + if (!has_outerclass) Printv(f_proxy, proxy_class_def, proxy_class_code, NIL); else { @@ -2058,8 +2255,18 @@ public: Delete(downcast_method); } + if (f_interface) { + Printv(f_interface, interface_class_code, "}\n", NIL); + addCloseNamespace(nspace, f_interface); + if (f_interface != f_single_out) + Delete(f_interface); + f_interface = 0; + } + emitDirectorExtraMethods(n); + Delete(interface_class_code); + interface_class_code = old_interface_class_code; Delete(csclazzname); Delete(proxy_class_name); proxy_class_name = old_proxy_class_name; @@ -2145,6 +2352,8 @@ public: String *pre_code = NewString(""); String *post_code = NewString(""); String *terminator_code = NewString(""); + bool is_interface = Getattr(parentNode(n), "feature:interface") != 0 + && !static_flag && Getattr(n, "interface:owner") == 0; if (!proxy_flag) return; @@ -2217,8 +2426,21 @@ public: Printf(function_code, " %s ", methodmods); if (!is_smart_pointer()) { // Smart pointer classes do not mirror the inheritance hierarchy of the underlying pointer type, so no virtual/override/new required. - if (Getattr(n, "override")) - Printf(function_code, "override "); + if (Node *base_ovr = Getattr(n, "override")) { + if (GetFlag(n, "isextendmember")) + Printf(function_code, "override "); + else { + Node* base = parentNode(base_ovr); + bool ovr = false; + for (Node* direct_base = Getattr(parentNode(n), "direct_base"); direct_base; direct_base = Getattr(direct_base, "direct_base")) { + if (direct_base == base) { // "override" only applies if the base was not discarded (e.g. in case of multiple inheritance or via "ignore") + ovr = true; + break; + } + } + Printf(function_code, ovr ? "override " : "virtual "); + } + } else if (checkAttribute(n, "storage", "virtual")) Printf(function_code, "virtual "); if (Getattr(n, "hides")) @@ -2228,6 +2450,9 @@ public: if (static_flag) Printf(function_code, "static "); Printf(function_code, "%s %s(", return_type, proxy_function_name); + if (is_interface) + Printf(interface_class_code, " %s %s(", return_type, proxy_function_name); + Printv(imcall, full_imclass_name, ".$imfuncname(", NIL); if (!static_flag) @@ -2307,10 +2532,15 @@ public: } /* Add parameter to proxy function */ - if (gencomma >= 2) + if (gencomma >= 2) { Printf(function_code, ", "); + if (is_interface) + Printf(interface_class_code, ", "); + } gencomma = 2; Printf(function_code, "%s %s", param_type, arg); + if (is_interface) + Printf(interface_class_code, "%s %s", param_type, arg); Delete(arg); Delete(param_type); @@ -2320,6 +2550,8 @@ public: Printf(imcall, ")"); Printf(function_code, ")"); + if (is_interface) + Printf(interface_class_code, ");\n"); // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class) if ((tm = Swig_typemap_lookup("csout", n, "", 0))) { @@ -3188,6 +3420,50 @@ public: substitution_performed = true; Delete(classnametype); } + if (Strstr(tm, "$csinterfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$csinterfacename", true); + substitution_performed = true; + Delete(interfacenametype); + } + if (Strstr(tm, "$*csinterfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + Delete(SwigType_pop(interfacenametype)); + if (Len(interfacenametype) > 0) { + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*csinterfacename", true); + substitution_performed = true; + } + Delete(interfacenametype); + } + if (Strstr(tm, "$&csinterfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + SwigType_add_pointer(interfacenametype); + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&csinterfacename", true); + substitution_performed = true; + Delete(interfacenametype); + } + if (Strstr(tm, "$interfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$interfacename", false); + substitution_performed = true; + Delete(interfacenametype); + } + if (Strstr(tm, "$*interfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + Delete(SwigType_pop(interfacenametype)); + if (Len(interfacenametype) > 0) { + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*interfacename", false); + substitution_performed = true; + } + Delete(interfacenametype); + } + if (Strstr(tm, "$&interfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + SwigType_add_pointer(interfacenametype); + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&interfacename", false); + substitution_performed = true; + Delete(interfacenametype); + } Delete(strippedtype); Delete(type); @@ -3234,6 +3510,20 @@ public: } /* ----------------------------------------------------------------------------- + * substituteInterfacenameSpecialVariable() + * ----------------------------------------------------------------------------- */ + + void substituteInterfacenameSpecialVariable(SwigType *interfacenametype, String *tm, const char *interfacenamespecialvariable, bool qualified) { + + String *interfacename = getInterfaceName(interfacenametype, qualified); + if (interfacename) { + String *replacementname = Copy(interfacename); + Replaceall(tm, interfacenamespecialvariable, replacementname); + Delete(replacementname); + } + } + + /* ----------------------------------------------------------------------------- * emitTypeWrapperClass() * ----------------------------------------------------------------------------- */ diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 5fc21ad18..ec66ebed2 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -910,7 +910,7 @@ public: const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0"; Setattr(n, "enumvalue", val); } else if (swigtype == T_CHAR) { - String *val = NewStringf("'%s'", Getattr(n, "enumvalue")); + String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue")); Setattr(n, "enumvalue", val); Delete(val); } @@ -1423,6 +1423,7 @@ public: String *constants_code = NewString(""); SwigType *t = Getattr(n, "type"); + SwigType *valuetype = Getattr(n, "valuetype"); ParmList *l = Getattr(n, "parms"); // Attach the non-standard typemaps to the parameter list. @@ -1470,16 +1471,21 @@ public: Printf(constants_code, "%s;\n", override_value); } else { // Just take the value from the C definition and hope it compiles in D. - String* value = Getattr(n, "wrappedasconstant") ? - Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value"); - - // Add the stripped quotes back in. - if (SwigType_type(t) == T_STRING) { - Printf(constants_code, "\"%s\";\n", value); - } else if (SwigType_type(t) == T_CHAR) { - Printf(constants_code, "\'%s\';\n", value); + if (Getattr(n, "wrappedasconstant")) { + if (SwigType_type(valuetype) == T_CHAR) + Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value")); + else + Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value")); } else { - Printf(constants_code, "%s;\n", value); + // Add the stripped quotes back in. + String* value = Getattr(n, "value"); + if (SwigType_type(t) == T_STRING) { + Printf(constants_code, "\"%s\";\n", value); + } else if (SwigType_type(t) == T_CHAR) { + Printf(constants_code, "\'%s\';\n", value); + } else { + Printf(constants_code, "%s;\n", value); + } } } @@ -3123,28 +3129,23 @@ private: List *baselist = Getattr(n, "bases"); if (baselist) { Iterator base = First(baselist); - while (base.item && GetFlag(base.item, "feature:ignore")) { - base = Next(base); - } - if (base.item) { - basenode = base.item; - c_baseclassname = Getattr(base.item, "name"); - basename = createProxyName(c_baseclassname); - if (basename) - c_baseclass = SwigType_namestr(Getattr(base.item, "name")); - base = Next(base); - /* Warn about multiple inheritance for additional base class(es) */ - while (base.item) { - if (GetFlag(base.item, "feature:ignore")) { - base = Next(base); - continue; + while (base.item) { + if (!GetFlag(base.item, "feature:ignore")) { + String *baseclassname = Getattr(base.item, "name"); + if (!c_baseclassname) { + basenode = base.item; + c_baseclassname = baseclassname; + basename = createProxyName(c_baseclassname); + if (basename) + c_baseclass = SwigType_namestr(baseclassname); + } else { + /* Warn about multiple inheritance for additional base class(es) */ + String *proxyclassname = Getattr(n, "classtypeobj"); + Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), + "Base %s of class %s ignored: multiple inheritance is not supported in D.\n", SwigType_namestr(baseclassname), SwigType_namestr(proxyclassname)); } - String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); - String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); - Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Base %s of class %s ignored: multiple inheritance is not supported in D.\n", baseclassname, proxyclassname); - base = Next(base); } + base = Next(base); } } } @@ -3169,7 +3170,7 @@ private: } } else if (basename && Len(pure_baseclass) > 0) { Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s proxy: Base class %s ignored. Multiple inheritance is not supported in D. " + "Warning for %s, base class %s ignored. Multiple inheritance is not supported in D. " "Perhaps you need one of the 'replace' or 'notderived' attributes in the dbase typemap?\n", typemap_lookup_type, pure_baseclass); } diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 002247fe5..7fa9b2670 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -1362,6 +1362,10 @@ private: goargout(info->parms); if (SwigType_type(info->result) != T_VOID) { + + Swig_save("cgoGoWrapper", info->n, "type", "tmap:goout", NULL); + Setattr(info->n, "type", info->result); + String *goout = goTypemapLookup("goout", info->n, "swig_r"); if (goout == NULL) { Printv(f_go_wrappers, "\treturn swig_r\n", NULL); @@ -1374,6 +1378,8 @@ private: Printv(f_go_wrappers, goout, "\n", NULL); Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL); } + + Swig_restore(info->n); } Printv(f_go_wrappers, "}\n\n", NULL); @@ -1618,8 +1624,13 @@ private: receiver = NULL; } + Swig_save("cgoGoWrapper", n, "type", "tmap:goout", NULL); + Setattr(n, "type", result); + String *goout = goTypemapLookup("goout", n, "swig_r"); + Swig_restore(n); + 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); @@ -2712,6 +2723,9 @@ private: * ---------------------------------------------------------------------- */ virtual int enumDeclaration(Node *n) { + if (getCurrentClass() && (cplus_mode != PUBLIC)) + return SWIG_NOWRAP; + String *name = goEnumName(n); if (Strcmp(name, "int") != 0) { if (!ImportMode || !imported_package) { @@ -2792,6 +2806,7 @@ private: } else if (SwigType_type(type) == T_CHAR) { quote = '\''; } else if (SwigType_type(type) == T_STRING) { + Printv(get, "(char *)", NULL); quote = '"'; } else { quote = '\0'; @@ -4161,7 +4176,6 @@ private: Wrapper *dummy = NewWrapper(); emit_attach_parmmaps(parms, dummy); - DelWrapper(dummy); Swig_typemap_attach_parms("gotype", parms, NULL); Swig_typemap_attach_parms("imtype", parms, NULL); @@ -4218,6 +4232,8 @@ private: Swig_typemap_attach_parms("goin", parms, dummy); Swig_typemap_attach_parms("goargout", parms, dummy); + DelWrapper(dummy); + if (!is_ignored) { // We use an interface to see if this method is defined in Go. Printv(f_go_wrappers, "type ", interface_name, " interface {\n", NULL); diff --git a/Source/Modules/interface.cxx b/Source/Modules/interface.cxx new file mode 100644 index 000000000..f6d4c955b --- /dev/null +++ b/Source/Modules/interface.cxx @@ -0,0 +1,183 @@ +/* ----------------------------------------------------------------------------- + * This file is part of SWIG, which is licensed as a whole under version 3 + * (or any later version) of the GNU General Public License. Some additional + * terms also apply to certain portions of SWIG. The full details of the SWIG + * license and copyrights can be found in the LICENSE and COPYRIGHT files + * included with the SWIG source code as distributed by the SWIG developers + * and at http://www.swig.org/legal.html. + * + * interface.cxx + * + * This module contains support for the interface feature. + * This feature is used in language modules where the target language does not + * naturally support C++ style multiple inheritance, but does support inheritance + * from multiple interfaces. + * ----------------------------------------------------------------------------- */ + +#include "swigmod.h" + +static bool interface_feature_enabled = false; + +/* ----------------------------------------------------------------------------- + * collect_interface_methods() + * + * Create a list of all the methods from the base classes of class n that are + * marked as an interface. The resulting list is thus the list of methods that + * need to be implemented in order for n to be non-abstract. + * ----------------------------------------------------------------------------- */ + +static List *collect_interface_methods(Node *n) { + List *methods = NewList(); + if (Hash *bases = Getattr(n, "interface:bases")) { + List *keys = Keys(bases); + for (Iterator base = First(keys); base.item; base = Next(base)) { + Node *cls = Getattr(bases, base.item); + if (cls == n) + continue; + for (Node *child = firstChild(cls); child; child = nextSibling(child)) { + if (Cmp(nodeType(child), "cdecl") == 0) { + if (GetFlag(child, "feature:ignore") || Getattr(child, "interface:owner")) + continue; // skip methods propagated to bases + Node *m = Copy(child); + set_nextSibling(m, NIL); + set_previousSibling(m, NIL); + Setattr(m, "interface:owner", cls); + Append(methods, m); + } + } + } + Delete(keys); + } + return methods; +} + +/* ----------------------------------------------------------------------------- + * collect_interface_bases + * ----------------------------------------------------------------------------- */ + +static void collect_interface_bases(Hash *bases, Node *n) { + if (Getattr(n, "feature:interface")) { + String *name = Getattr(n, "interface:name"); + if (!Getattr(bases, name)) + Setattr(bases, name, n); + } + + if (List *baselist = Getattr(n, "bases")) { + for (Iterator base = First(baselist); base.item; base = Next(base)) { + if (!GetFlag(base.item, "feature:ignore")) { + if (Getattr(base.item, "feature:interface")) + collect_interface_bases(bases, base.item); + } + } + } +} + +/* ----------------------------------------------------------------------------- + * collect_interface_base_classes() + * + * Create a hash containing all the classes up the inheritance hierarchy + * marked with feature:interface (including this class n). + * Stops going up the inheritance chain as soon as a class is found without + * feature:interface. + * The idea is to find all the base interfaces that a class must implement. + * ----------------------------------------------------------------------------- */ + +static void collect_interface_base_classes(Node *n) { + if (Getattr(n, "feature:interface")) { + // check all bases are also interfaces + if (List *baselist = Getattr(n, "bases")) { + for (Iterator base = First(baselist); base.item; base = Next(base)) { + if (!GetFlag(base.item, "feature:ignore")) { + if (!Getattr(base.item, "feature:interface")) { + Swig_error(Getfile(n), Getline(n), "Base class '%s' of '%s' is not similarly marked as an interface.\n", SwigType_namestr(Getattr(base.item, "name")), SwigType_namestr(Getattr(n, "name"))); + SWIG_exit(EXIT_FAILURE); + } + } + } + } + } + + Hash *interface_bases = NewHash(); + collect_interface_bases(interface_bases, n); + if (Len(interface_bases) == 0) + Delete(interface_bases); + else + Setattr(n, "interface:bases", interface_bases); +} + +/* ----------------------------------------------------------------------------- + * process_interface_name() + * ----------------------------------------------------------------------------- */ + +static void process_interface_name(Node *n) { + if (Getattr(n, "feature:interface")) { + String *interface_name = Getattr(n, "feature:interface:name"); + if (!Len(interface_name)) { + Swig_error(Getfile(n), Getline(n), "The interface feature for '%s' is missing the name attribute.\n", SwigType_namestr(Getattr(n, "name"))); + SWIG_exit(EXIT_FAILURE); + } + if (Strchr(interface_name, '%')) { + String *name = NewStringf(interface_name, Getattr(n, "sym:name")); + Setattr(n, "interface:name", name); + } else { + Setattr(n, "interface:name", interface_name); + } + } +} + +/* ----------------------------------------------------------------------------- + * Swig_interface_propagate_methods() + * + * Find all the base classes marked as an interface (with feature:interface) for + * class node n. For each of these, add all of its methods as methods of n so that + * n is not abstract. If class n is also marked as an interface, it will remain + * abstract and not have any methods added. + * ----------------------------------------------------------------------------- */ + +void Swig_interface_propagate_methods(Node *n) { + if (interface_feature_enabled) { + process_interface_name(n); + collect_interface_base_classes(n); + List *methods = collect_interface_methods(n); + bool is_interface = Getattr(n, "feature:interface") != 0; + for (Iterator mi = First(methods); mi.item; mi = Next(mi)) { + if (!is_interface && GetFlag(mi.item, "abstract")) + continue; + String *this_decl = Getattr(mi.item, "decl"); + String *this_decl_resolved = SwigType_typedef_resolve_all(this_decl); + bool identically_overloaded_method = false; // true when a base class' method is implemented in n + if (SwigType_isfunction(this_decl_resolved)) { + String *name = Getattr(mi.item, "name"); + for (Node *child = firstChild(n); child; child = nextSibling(child)) { + if (Getattr(child, "interface:owner")) + break; // at the end of the list are newly appended methods + if (checkAttribute(child, "name", name)) { + String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl")); + identically_overloaded_method = Strcmp(decl, this_decl_resolved) == 0; + Delete(decl); + if (identically_overloaded_method) + break; + } + } + } + Delete(this_decl_resolved); + if (!identically_overloaded_method) { + // TODO: Fix if the method is overloaded with different arguments / has default args + appendChild(n, mi.item); + } else { + Delete(mi.item); + } + } + Delete(methods); + } +} + +/* ----------------------------------------------------------------------------- + * Swig_interface_feature_enable() + * + * Turn on interface feature support + * ----------------------------------------------------------------------------- */ + +void Swig_interface_feature_enable() { + interface_feature_enabled = true; +} diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index afe8ca841..eb809ff59 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -53,6 +53,7 @@ class JAVA:public Language { String *imclass_class_code; // intermediary class code String *proxy_class_def; String *proxy_class_code; + String *interface_class_code; // if %feature("interface") was declared for a class, here goes the interface declaration String *module_class_code; String *proxy_class_name; // proxy class name String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name @@ -125,6 +126,7 @@ public: imclass_class_code(NULL), proxy_class_def(NULL), proxy_class_code(NULL), + interface_class_code(NULL), module_class_code(NULL), proxy_class_name(NULL), full_proxy_class_name(NULL), @@ -208,10 +210,14 @@ public: String *nspace = Getattr(n, "sym:nspace"); 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, jnidescriptor ? "$" : "."); - Push(symname, Getattr(outer_class, "sym:name")); - } + for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) { + if (String* name = Getattr(outer_class, "sym:name")) { + Push(symname, jnidescriptor ? "$" : "."); + Push(symname, name); + } + else + return NULL; + } } if (nspace) { if (package && !jnidescriptor) @@ -303,6 +309,7 @@ public: SWIG_config_file("java.swg"); allow_overloading(); + Swig_interface_feature_enable(); } /* --------------------------------------------------------------------- @@ -1288,8 +1295,10 @@ public: // Add extra indentation Replaceall(enum_code, "\n", "\n "); Replaceall(enum_code, " \n", "\n"); - - Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL); + if (GetFlag(getCurrentClass(), "feature:interface")) + Printv(interface_class_code, " ", enum_code, "\n\n", NIL); + else + Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL); } else { // Global enums are defined in their own file String *output_directory = outputDirectory(nspace); @@ -1375,7 +1384,7 @@ public: const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0"; Setattr(n, "enumvalue", val); } else if (swigtype == T_CHAR) { - String *val = NewStringf("'%s'", Getattr(n, "enumvalue")); + String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue")); Setattr(n, "enumvalue", val); Delete(val); } @@ -1481,6 +1490,7 @@ public: virtual int constantWrapper(Node *n) { String *symname = Getattr(n, "sym:name"); SwigType *t = Getattr(n, "type"); + SwigType *valuetype = Getattr(n, "valuetype"); ParmList *l = Getattr(n, "parms"); String *tm; String *return_type = NewString(""); @@ -1572,8 +1582,8 @@ public: } else { // Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code if (Getattr(n, "wrappedasconstant")) { - if (SwigType_type(t) == T_CHAR) - Printf(constants_code, "\'%s\';\n", Getattr(n, "staticmembervariableHandler:value")); + if (SwigType_type(valuetype) == T_CHAR) + Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value")); else Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value")); } else { @@ -1724,6 +1734,125 @@ public: } /* ----------------------------------------------------------------------------- + * getQualifiedInterfaceName() + * ----------------------------------------------------------------------------- */ + + String *getQualifiedInterfaceName(Node *n) { + String *ret = Getattr(n, "interface:qname"); + if (!ret) { + String *nspace = Getattr(n, "sym:nspace"); + String *symname = Getattr(n, "interface:name"); + if (nspace) { + if (package) + ret = NewStringf("%s.%s.%s", package, nspace, symname); + else + ret = NewStringf("%s.%s", nspace, symname); + } else { + ret = Copy(symname); + } + Setattr(n, "interface:qname", ret); + } + return ret; + } + + /* ----------------------------------------------------------------------------- + * getInterfaceName() + * ----------------------------------------------------------------------------- */ + + String *getInterfaceName(SwigType *t, bool qualified) { + String *interface_name = NULL; + if (proxy_flag) { + Node *n = classLookup(t); + if (n && Getattr(n, "interface:name")) + interface_name = qualified ? getQualifiedInterfaceName(n) : Getattr(n, "interface:name"); + } + return interface_name; + } + + /* ----------------------------------------------------------------------------- + * addInterfaceNameAndUpcasts() + * ----------------------------------------------------------------------------- */ + + void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) { + List *keys = Keys(base_list); + for (Iterator it = First(keys); it.item; it = Next(it)) { + Node *base = Getattr(base_list, it.item); + String *c_baseclass = SwigType_namestr(Getattr(base, "name")); + String *interface_name = Getattr(base, "interface:name"); + if (Len(interface_list)) + Append(interface_list, ", "); + Append(interface_list, interface_name); + + Node *attributes = NewHash(); + String *interface_code = Copy(typemapLookup(base, "javainterfacecode", Getattr(base, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF, attributes)); + String *cptr_method_name = 0; + if (interface_code) { + Replaceall(interface_code, "$interfacename", interface_name); + Printv(interface_upcasts, interface_code, NIL); + cptr_method_name = Copy(Getattr(attributes, "tmap:javainterfacecode:cptrmethod")); + } + if (!cptr_method_name) + cptr_method_name = NewStringf("%s_GetInterfaceCPtr", interface_name); + Replaceall(cptr_method_name, ".", "_"); + Replaceall(cptr_method_name, "$interfacename", interface_name); + + String *upcast_method_name = Swig_name_member(getNSpace(), proxy_class_name, cptr_method_name); + upcastsCode(smart, upcast_method_name, c_classname, c_baseclass); + Delete(upcast_method_name); + Delete(cptr_method_name); + Delete(interface_code); + Delete(c_baseclass); + } + Delete(keys); + } + + /* ----------------------------------------------------------------------------- + * upcastsCode() + * + * Add code for C++ casting to base class + * ----------------------------------------------------------------------------- */ + + void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) { + String *jniname = makeValidJniName(upcast_method_name); + String *wname = Swig_name_wrapper(jniname); + Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method_name); + if (smart) { + SwigType *bsmart = Copy(smart); + SwigType *rclassname = SwigType_typedef_resolve_all(c_classname); + SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass); + Replaceall(bsmart, rclassname, rbaseclass); + Delete(rclassname); + Delete(rbaseclass); + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); + Printv(upcasts_code, + "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", + " jlong baseptr = 0;\n" + " ", smartnamestr, " *argp1;\n" + " (void)jenv;\n" + " (void)jcls;\n" + " argp1 = *(", smartnamestr, " **)&jarg1;\n" + " *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n" + " return baseptr;\n" + "}\n", "\n", NIL); + Delete(bsmartnamestr); + Delete(smartnamestr); + Delete(bsmart); + } else { + Printv(upcasts_code, + "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", + " jlong baseptr = 0;\n" + " (void)jenv;\n" + " (void)jcls;\n" + " *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n" + " return baseptr;\n" + "}\n", "\n", NIL); + } + Delete(wname); + Delete(jniname); + } + + /* ----------------------------------------------------------------------------- * emitProxyClassDefAndCPPCasts() * ----------------------------------------------------------------------------- */ @@ -1732,9 +1861,12 @@ public: String *c_baseclass = NULL; String *baseclass = NULL; String *c_baseclassname = NULL; + String *interface_list = NewStringEmpty(); + String *interface_upcasts = NewStringEmpty(); SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); bool feature_director = Swig_directorclass(n) ? true : false; bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested"); + SwigType *smart = Swig_cparse_smartptr(n); // Inheritance from pure Java classes Node *attributes = NewHash(); @@ -1747,32 +1879,31 @@ public: if (!purebase_replace) { List *baselist = Getattr(n, "bases"); if (baselist) { - Iterator base = First(baselist); - while (base.item && GetFlag(base.item, "feature:ignore")) { - base = Next(base); - } - if (base.item) { - c_baseclassname = Getattr(base.item, "name"); - baseclass = Copy(getProxyName(c_baseclassname)); - if (baseclass) - c_baseclass = SwigType_namestr(Getattr(base.item, "name")); - base = Next(base); - /* Warn about multiple inheritance for additional base class(es) */ - while (base.item) { - if (GetFlag(base.item, "feature:ignore")) { - base = Next(base); - continue; - } - String *proxyclassname = Getattr(n, "classtypeobj"); - String *baseclassname = Getattr(base.item, "name"); - Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname)); - base = Next(base); - } - } + Iterator base = First(baselist); + while (base.item) { + if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) { + String *baseclassname = Getattr(base.item, "name"); + if (!c_baseclassname) { + c_baseclassname = baseclassname; + baseclass = Copy(getProxyName(baseclassname)); + if (baseclass) + c_baseclass = SwigType_namestr(baseclassname); + } else { + /* Warn about multiple inheritance for additional base class(es) */ + String *proxyclassname = Getattr(n, "classtypeobj"); + Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), + "Warning for %s, base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname)); + } + } + base = Next(base); + } } } + Hash *interface_bases = Getattr(n, "interface:bases"); + if (interface_bases) + addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname); + bool derived = baseclass && getProxyName(c_baseclassname); if (derived && purebase_notderived) pure_baseclass = empty_string; @@ -1787,13 +1918,15 @@ public: Swig_error(Getfile(n), Getline(n), "The javabase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type); } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) { Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java. " + "Warning for %s, base %s ignored. Multiple inheritance is not supported in Java. " "Perhaps you need one of the 'replace' or 'notderived' attributes in the javabase typemap?\n", typemap_lookup_type, pure_baseclass); } // Pure Java interfaces const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE); - + if (*Char(interface_list) && *Char(pure_interfaces)) + Append(interface_list, ", "); + Append(interface_list, pure_interfaces); // Start writing the proxy class if (!has_outerclass) // Import statements Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE),"\n", NIL); @@ -1801,8 +1934,8 @@ public: Printv(proxy_class_def, "static ", NIL); // C++ nested classes correspond to static java classes Printv(proxy_class_def, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers " $javaclassname", // Class name and bases - (*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(pure_interfaces) ? // Pure Java interfaces - " implements " : "", pure_interfaces, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class + (*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(interface_list) ? // Pure Java interfaces + " implements " : "", interface_list, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class NIL); @@ -1845,6 +1978,8 @@ public: if (*Char(destruct)) Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " void ", destruct_methodname, "()", destructor_throws_clause, " ", destruct, "\n", NIL); } + if (*Char(interface_upcasts)) + Printv(proxy_class_def, interface_upcasts, NIL); /* Insert directordisconnect typemap, if this class has directors enabled */ /* Also insert the swigTakeOwnership and swigReleaseOwnership methods */ @@ -1866,6 +2001,8 @@ public: Delete(take_jnicall); } + Delete(interface_upcasts); + Delete(interface_list); Delete(attributes); Delete(destruct); @@ -1873,60 +2010,80 @@ public: Printv(proxy_class_def, typemapLookup(n, "javacode", typemap_lookup_type, WARN_NONE), // extra Java code "\n", NIL); - // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) if (derived) { - SwigType *smart = Swig_cparse_smartptr(n); - String *upcast_method = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); - String *jniname = makeValidJniName(upcast_method); - String *wname = Swig_name_wrapper(jniname); - Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method); - if (smart) { - SwigType *bsmart = Copy(smart); - SwigType *rclassname = SwigType_typedef_resolve_all(c_classname); - SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass); - Replaceall(bsmart, rclassname, rbaseclass); - Delete(rclassname); - Delete(rbaseclass); - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(bsmart); - Printv(upcasts_code, - "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", - " jlong baseptr = 0;\n" - " ", smartnamestr, " *argp1;\n" - " (void)jenv;\n" - " (void)jcls;\n" - " argp1 = *(", smartnamestr, " **)&jarg1;\n" - " *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n" - " return baseptr;\n" - "}\n", "\n", NIL); - Delete(bsmartnamestr); - Delete(smartnamestr); - Delete(bsmart); - } else { - Printv(upcasts_code, - "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", - " jlong baseptr = 0;\n" - " (void)jenv;\n" - " (void)jcls;\n" - " *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n" - " return baseptr;\n" - "}\n", "\n", NIL); - } - Delete(wname); - Delete(jniname); - Delete(upcast_method); - Delete(smart); + String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); + upcastsCode(smart, upcast_method_name, c_classname, c_baseclass); + Delete(upcast_method_name); } + + Delete(smart); Delete(baseclass); } /* ---------------------------------------------------------------------- - * classHandler() + * emitInterfaceDeclaration() * ---------------------------------------------------------------------- */ - virtual int classHandler(Node *n) { + void emitInterfaceDeclaration(Node *n, String *interface_name, File *f_interface, String *nspace) { + if (package || nspace) { + Printf(f_interface, "package "); + if (package) + Printv(f_interface, package, nspace ? "." : "", NIL); + if (nspace) + Printv(f_interface, nspace, NIL); + Printf(f_interface, ";\n"); + } + + Printv(f_interface, typemapLookup(n, "javaimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL); + Printf(f_interface, "public interface %s", interface_name); + if (List *baselist = Getattr(n, "bases")) { + String *bases = 0; + for (Iterator base = First(baselist); base.item; base = Next(base)) { + if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface")) + continue; // TODO: warn about skipped non-interface bases + String *base_iname = Getattr(base.item, "interface:name"); + if (!bases) + bases = Copy(base_iname); + else { + Append(bases, ", "); + Append(bases, base_iname); + } + } + if (bases) { + Printv(f_interface, " extends ", bases, NIL); + Delete(bases); + } + } + Printf(f_interface, " {\n"); + + Node *attributes = NewHash(); + String *interface_code = Copy(typemapLookup(n, "javainterfacecode", Getattr(n, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF, attributes)); + if (interface_code) { + String *interface_declaration = Copy(Getattr(attributes, "tmap:javainterfacecode:declaration")); + if (interface_declaration) { + Replaceall(interface_declaration, "$interfacename", interface_name); + Printv(f_interface, interface_declaration, NIL); + Delete(interface_declaration); + } + Delete(interface_code); + } + } + /* ---------------------------------------------------------------------- + * classDeclaration() + * ---------------------------------------------------------------------- */ + + int classDeclaration(Node *n) { + return Language::classDeclaration(n); + } + + /* ---------------------------------------------------------------------- + * classHandler() + * ---------------------------------------------------------------------- */ + + virtual int classHandler(Node *n) { File *f_proxy = NULL; + File *f_interface = NULL; String *old_proxy_class_name = proxy_class_name; String *old_full_proxy_class_name = full_proxy_class_name; String *old_full_imclass_name = full_imclass_name; @@ -1936,6 +2093,8 @@ public: String *old_proxy_class_def = proxy_class_def; String *old_proxy_class_code = proxy_class_code; bool has_outerclass = Getattr(n, "nested:outer") && !GetFlag(n, "feature:flatnested"); + String *old_interface_class_code = interface_class_code; + interface_class_code = 0; if (proxy_flag) { proxy_class_name = NewString(Getattr(n, "sym:name")); @@ -1976,17 +2135,21 @@ public: } } + String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0; if (outerClassesPrefix) { String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix; if (!addSymbol(proxy_class_name, n, fnspace)) return SWIG_ERROR; + if (interface_name && !addInterfaceSymbol(interface_name, n, fnspace)) + return SWIG_ERROR; if (nspace) Delete(fnspace); Delete(outerClassesPrefix); - } - else { + } else { if (!addSymbol(proxy_class_name, n, nspace)) return SWIG_ERROR; + if (interface_name && !addInterfaceSymbol(interface_name, n, nspace)) + return SWIG_ERROR; } // Each outer proxy class goes into a separate file @@ -2022,11 +2185,27 @@ public: destructor_call = NewString(""); destructor_throws_clause = NewString(""); proxy_class_constants_code = NewString(""); + + if (Getattr(n, "feature:interface")) { + interface_class_code = NewString(""); + String *output_directory = outputDirectory(nspace); + String *filen = NewStringf("%s%s.java", output_directory, interface_name); + f_interface = NewFile(filen, "w", SWIG_output_files()); + if (!f_interface) { + FileErrorDisplay(filen); + SWIG_exit(EXIT_FAILURE); + } + Append(filenames_list, filen); // file name ownership goes to the list + emitBanner(f_interface); + emitInterfaceDeclaration(n, interface_name, interface_class_code, nspace); + Delete(filen); + Delete(output_directory); + } } + Language::classHandler(n); if (proxy_flag) { - emitProxyClassDefAndCPPCasts(n); String *javaclazzname = Swig_name_member(getNSpace(), getClassPrefix(), ""); // mangled full proxy class name @@ -2034,18 +2213,22 @@ public: Replaceall(proxy_class_def, "$javaclassname", proxy_class_name); Replaceall(proxy_class_code, "$javaclassname", proxy_class_name); Replaceall(proxy_class_constants_code, "$javaclassname", proxy_class_name); + Replaceall(interface_class_code, "$javaclassname", proxy_class_name); Replaceall(proxy_class_def, "$javaclazzname", javaclazzname); Replaceall(proxy_class_code, "$javaclazzname", javaclazzname); Replaceall(proxy_class_constants_code, "$javaclazzname", javaclazzname); + Replaceall(interface_class_code, "$javaclazzname", javaclazzname); Replaceall(proxy_class_def, "$module", module_class_name); Replaceall(proxy_class_code, "$module", module_class_name); Replaceall(proxy_class_constants_code, "$module", module_class_name); + Replaceall(interface_class_code, "$module", module_class_name); Replaceall(proxy_class_def, "$imclassname", full_imclass_name); Replaceall(proxy_class_code, "$imclassname", full_imclass_name); Replaceall(proxy_class_constants_code, "$imclassname", full_imclass_name); + Replaceall(interface_class_code, "$imclassname", full_imclass_name); if (!has_outerclass) Printv(f_proxy, proxy_class_def, proxy_class_code, NIL); @@ -2110,8 +2293,16 @@ public: Delete(downcast_method); } + if (f_interface) { + Printv(f_interface, interface_class_code, "}\n", NIL); + Delete(f_interface); + f_interface = 0; + } + emitDirectorExtraMethods(n); + Delete(interface_class_code); + interface_class_code = old_interface_class_code; Delete(javaclazzname); Delete(proxy_class_name); proxy_class_name = old_proxy_class_name; @@ -2203,6 +2394,8 @@ public: bool setter_flag = false; String *pre_code = NewString(""); String *post_code = NewString(""); + bool is_interface = Getattr(parentNode(n), "feature:interface") != 0 + && !static_flag && Getattr(n, "interface:owner") == 0; if (!proxy_flag) return; @@ -2252,6 +2445,9 @@ public: if (static_flag) Printf(function_code, "static "); Printf(function_code, "%s %s(", return_type, proxy_function_name); + + if (is_interface) + Printf(interface_class_code, " %s %s(", return_type, proxy_function_name); Printv(imcall, full_imclass_name, ".$imfuncname(", NIL); if (!static_flag) { @@ -2339,10 +2535,15 @@ public: } /* Add parameter to proxy function */ - if (gencomma >= 2) + if (gencomma >= 2) { Printf(function_code, ", "); + if (is_interface) + Printf(interface_class_code, ", "); + } gencomma = 2; Printf(function_code, "%s %s", param_type, arg); + if (is_interface) + Printf(interface_class_code, "%s %s", param_type, arg); if (prematureGarbageCollectionPreventionParameter(pt, p)) { String *pgcppname = Getattr(p, "tmap:javain:pgcppname"); @@ -2364,6 +2565,8 @@ public: Printf(imcall, ")"); Printf(function_code, ")"); + if (is_interface) + Printf(interface_class_code, ");\n"); // Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in proxy class) if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) { @@ -3068,6 +3271,50 @@ public: substitution_performed = true; Delete(classnametype); } + if (Strstr(tm, "$javainterfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$javainterfacename", jnidescriptor, true); + substitution_performed = true; + Delete(interfacenametype); + } + if (Strstr(tm, "$*javainterfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + Delete(SwigType_pop(interfacenametype)); + if (Len(interfacenametype) > 0) { + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*javainterfacename", jnidescriptor, true); + substitution_performed = true; + } + Delete(interfacenametype); + } + if (Strstr(tm, "$&javainterfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + SwigType_add_pointer(interfacenametype); + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&javainterfacename", jnidescriptor, true); + substitution_performed = true; + Delete(interfacenametype); + } + if (Strstr(tm, "$interfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$interfacename", jnidescriptor, false); + substitution_performed = true; + Delete(interfacenametype); + } + if (Strstr(tm, "$*interfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + Delete(SwigType_pop(interfacenametype)); + if (Len(interfacenametype) > 0) { + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*interfacename", jnidescriptor, false); + substitution_performed = true; + } + Delete(interfacenametype); + } + if (Strstr(tm, "$&interfacename")) { + SwigType *interfacenametype = Copy(strippedtype); + SwigType_add_pointer(interfacenametype); + substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&interfacename", jnidescriptor, false); + substitution_performed = true; + Delete(interfacenametype); + } Delete(strippedtype); Delete(type); @@ -3117,6 +3364,24 @@ public: } /* ----------------------------------------------------------------------------- + * substituteInterfacenameSpecialVariable() + * ----------------------------------------------------------------------------- */ + + void substituteInterfacenameSpecialVariable(SwigType *interfacenametype, String *tm, const char *interfacenamespecialvariable, bool jnidescriptor, bool qualified) { + + String *interfacename = getInterfaceName(interfacenametype/*, jnidescriptor*/, qualified); + if (interfacename) { + String *replacementname = Copy(interfacename); + + if (jnidescriptor) + Replaceall(replacementname,".","/"); + Replaceall(tm, interfacenamespecialvariable, replacementname); + + Delete(replacementname); + } + } + + /* ----------------------------------------------------------------------------- * emitTypeWrapperClass() * ----------------------------------------------------------------------------- */ @@ -3273,7 +3538,7 @@ public: * ----------------------------------------------------------------------------- */ String *prematureGarbageCollectionPreventionParameter(SwigType *t, Parm *p) { - String *proxyClassName = 0; + String *pgcpp_java_type = 0; String *jtype = NewString(Getattr(p, "tmap:jtype")); // Strip C comments @@ -3290,11 +3555,9 @@ public: if (Cmp(jtype, "long") == 0) { if (proxy_flag) { if (!GetFlag(p, "tmap:jtype:nopgcpp") && !nopgcpp_flag) { - String *proxyname = getProxyName(t); - if (proxyname) { - // Found a struct/class parameter passed by value, reference, pointer, or pointer reference - proxyClassName = proxyname; - } else { + String *interface_name = getInterfaceName(t, true); + pgcpp_java_type = interface_name ? interface_name : getProxyName(t); + if (!pgcpp_java_type) { // Look for proxy class parameters passed to C++ layer using non-default typemaps, ie not one of above types String *jstype = NewString(Getattr(p, "tmap:jstype")); if (jstype) { @@ -3316,7 +3579,7 @@ public: if (cls && !Getattr(cls, "feature:ignore")) { String *symname = Getattr(cls, "sym:name"); if (symname && Strcmp(symname, jstype) == 0) { - proxyClassName = symname; + pgcpp_java_type = symname; } } } @@ -3328,7 +3591,7 @@ public: } } Delete(jtype); - return proxyClassName; + return pgcpp_java_type; } /* ----------------------------------------------------------------------------- diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index aa81581f0..9b1173443 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -1649,6 +1649,9 @@ int Language::externDeclaration(Node *n) { * ---------------------------------------------------------------------- */ int Language::enumDeclaration(Node *n) { + if (CurrentClass && (cplus_mode != PUBLIC)) + return SWIG_NOWRAP; + String *oldNSpace = NSpace; NSpace = Getattr(n, "sym:nspace"); @@ -3119,6 +3122,31 @@ int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr } /* ----------------------------------------------------------------------------- + * Language::addInterfaceSymbol() + * + * Adds a symbol entry into the target language symbol tables - for the interface + * feature only. + * Returns 1 if the symbol is added successfully. + * The scope is as per addSymbol. + * ----------------------------------------------------------------------------- */ + +int Language::addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope) { + if (interface_name) { + Node *existing_symbol = symbolLookup(interface_name, scope); + if (existing_symbol) { + String *proxy_class_name = Getattr(n, "sym:name"); + Swig_error(input_file, line_number, "The interface feature name '%s' for proxy class '%s' is already defined in the generated target language module in scope '%s'.\n", + interface_name, proxy_class_name, scope); + Swig_error(Getfile(existing_symbol), Getline(existing_symbol), "Previous declaration of '%s'\n", interface_name); + return 0; + } + if (!addSymbol(interface_name, n, scope)) + return 0; + } + return 1; +} + +/* ----------------------------------------------------------------------------- * Language::symbolAddScope() * * Creates a scope (symbols Hash) for given name. This method is auxiliary, @@ -3214,7 +3242,7 @@ void Language::dumpSymbols() { * Language::symbolLookup() * ----------------------------------------------------------------------------- */ -Node *Language::symbolLookup(String *s, const_String_or_char_ptr scope) { +Node *Language::symbolLookup(const String *s, const_String_or_char_ptr scope) { Hash *symbols = Getattr(symtabs, scope ? scope : ""); if (!symbols) { return NULL; @@ -3797,6 +3825,7 @@ String *Language::defaultExternalRuntimeFilename() { /* ----------------------------------------------------------------------------- * Language::replaceSpecialVariables() + * * Language modules should implement this if special variables are to be handled * correctly in the $typemap(...) special variable macro. * method - typemap method name @@ -3816,3 +3845,4 @@ Language *Language::instance() { Hash *Language::getClassHash() const { return classhash; } + diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx index 12e8d10ba..80ea47f3f 100644 --- a/Source/Modules/lua.cxx +++ b/Source/Modules/lua.cxx @@ -856,6 +856,9 @@ public: //Printf(stdout,"Swig_overload_dispatch %s %s '%s' %d\n",symname,wname,dispatch,maxargs); if (!luaAddSymbol(lua_name, n)) { + DelWrapper(f); + Delete(dispatch); + Delete(tmp); return SWIG_ERROR; } @@ -1157,6 +1160,9 @@ public: * ------------------------------------------------------------ */ virtual int enumDeclaration(Node *n) { + if (getCurrentClass() && (cplus_mode != PUBLIC)) + return SWIG_NOWRAP; + current[STATIC_CONST] = true; current[ENUM_CONST] = true; // There is some slightly specific behaviour with enums. Basically, diff --git a/Source/Modules/modula3.cxx b/Source/Modules/modula3.cxx index 307c7857d..9983e69d2 100644 --- a/Source/Modules/modula3.cxx +++ b/Source/Modules/modula3.cxx @@ -2176,20 +2176,24 @@ MODULA3(): /* Deal with inheritance */ List *baselist = Getattr(n, "bases"); - if (baselist != NIL) { + if (baselist) { Iterator base = First(baselist); - if (base.item) { - c_baseclassname = Getattr(base.item, "name"); - baseclass = Copy(getProxyName(c_baseclassname)); - if (baseclass) { - c_baseclass = SwigType_namestr(Getattr(base.item, "name")); + while (base.item) { + if (!GetFlag(base.item, "feature:ignore")) { + String *baseclassname = Getattr(base.item, "name"); + if (!c_baseclassname) { + c_baseclassname = baseclassname; + baseclass = Copy(getProxyName(baseclassname)); + if (baseclass) + c_baseclass = SwigType_namestr(baseclassname); + } else { + /* Warn about multiple inheritance for additional base class(es) */ + String *proxyclassname = Getattr(n, "classtypeobj"); + Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), + "Warning for %s, base %s ignored. Multiple inheritance is not supported in Modula 3.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname)); + } } base = Next(base); - if (base.item != NIL) { - Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", - name, Getattr(base.item, "name")); - } } } @@ -2201,7 +2205,7 @@ MODULA3(): const String *pure_baseclass = typemapLookup(n, "m3base", name, WARN_NONE); if (hasContent(pure_baseclass) && hasContent(baseclass)) { Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", name, pure_baseclass); + "Warning for %s, base %s ignored. Multiple inheritance is not supported in Modula 3.\n", name, pure_baseclass); } // Pure Modula 3 interfaces const String *pure_interfaces = typemapLookup(n, derived ? "m3interfaces_derived" : "m3interfaces", @@ -2431,7 +2435,7 @@ MODULA3(): base = Next(base); if (base.item) { Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", + "Warning for %s, base %s ignored. Multiple inheritance is not supported in Modula 3.\n", proxy_class_name, Getattr(base.item, "name")); } } diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index 1c5ceefaa..9df6a9551 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -1287,6 +1287,9 @@ public: * typedef enum and enum are handled. I need to produce consistent names, * which means looking up and registering by typedef and enum name. */ int enumDeclaration(Node *n) { + if (getCurrentClass() && (cplus_mode != PUBLIC)) + return SWIG_NOWRAP; + String *name = Getattr(n, "name"); if (name) { String *oname = NewString(name); diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index 37cfeee64..b977609a8 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -469,7 +469,6 @@ public: value = Getattr(p, "tmap:doc:value"); } - // 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 diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx index dd3ca4972..330294efd 100644 --- a/Source/Modules/overload.cxx +++ b/Source/Modules/overload.cxx @@ -433,6 +433,7 @@ String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int * int fn = 0; Node *ni = Getitem(dispatch, i); Parm *pi = Getattr(ni, "wrap:parms"); + bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0; int num_required = emit_num_required(pi); int num_arguments = emit_num_arguments(pi); if (num_arguments > *maxargs) @@ -476,6 +477,7 @@ String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int * String *tm = Getattr(pj, "tmap:typecheck"); if (tm) { + tm = Copy(tm); /* normalise for comparison later */ Replaceid(tm, Getattr(pj, "lname"), "_v"); @@ -528,13 +530,14 @@ String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int * String *tmp = NewStringf(argv_template_string, j); String *conv = Getattr(pj, "implicitconv"); - if (conv) { + if (conv && !implicitconvtypecheckoff) { Replaceall(tm, "$implicitconv", conv); } else { Replaceall(tm, "$implicitconv", "0"); } Replaceall(tm, "$input", tmp); Printv(f, "{\n", tm, "}\n", NIL); + Delete(tm); fn = i + 1; Printf(f, "if (!_v) goto check_%d;\n", fn); Printf(f, "_ranki += _v*_pi;\n"); @@ -574,6 +577,9 @@ String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int * if (fn) Printf(f, "check_%d:\n\n", fn); + if (implicitconvtypecheckoff) + Delattr(ni, "implicitconvtypecheckoff"); + Delete(lfmt); Delete(coll); } @@ -607,6 +613,7 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int * int fn = 0; Node *ni = Getitem(dispatch, i); Parm *pi = Getattr(ni, "wrap:parms"); + bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0; int num_required = emit_num_required(pi); int num_arguments = emit_num_arguments(pi); if (num_arguments > *maxargs) @@ -646,6 +653,7 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int * String *tm = Getattr(pj, "tmap:typecheck"); if (tm) { + tm = Copy(tm); /* normalise for comparison later */ Replaceid(tm, Getattr(pj, "lname"), "_v"); @@ -699,13 +707,14 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int * String *tmp = NewStringf(argv_template_string, j); String *conv = Getattr(pj, "implicitconv"); - if (conv) { + if (conv && !implicitconvtypecheckoff) { Replaceall(tm, "$implicitconv", conv); } else { Replaceall(tm, "$implicitconv", "0"); } Replaceall(tm, "$input", tmp); Printv(f, "{\n", tm, "}\n", NIL); + Delete(tm); fn = i + 1; Printf(f, "if (!_v) goto check_%d;\n", fn); } @@ -737,6 +746,9 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int * if (fn) Printf(f, "check_%d:\n\n", fn); + if (implicitconvtypecheckoff) + Delattr(ni, "implicitconvtypecheckoff"); + Delete(lfmt); Delete(coll); } diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx index 9182ce46b..406568b16 100644 --- a/Source/Modules/perl5.cxx +++ b/Source/Modules/perl5.cxx @@ -2130,6 +2130,8 @@ public: String *cres = SwigType_lstr(returntype, "c_result"); Printf(w->code, "%s;\n", cres); Delete(cres); + } + if (!ignored_method) { String *pres = NewStringf("SV *%s", Swig_cresult_name()); Wrapper_add_local(w, Swig_cresult_name(), pres); Delete(pres); diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index fbece2715..02bd827f8 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -1904,7 +1904,7 @@ done: enumvalue = GetChar(n, "enumvalueex"); } - if (enumvalue) { + if (enumvalue && *Char(enumvalue)) { // Check for a simple constant expression which is valid in PHP. // If we find one, initialise the const member with it; otherwise // we initialise it using the C/C++ wrapped constant. @@ -1916,7 +1916,8 @@ done: break; } } - if (!*p) set_to = enumvalue; + if (!*p) + set_to = enumvalue; } if (wrapping_member_constant) { @@ -2018,7 +2019,7 @@ done: String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number, - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, baseclassname); + "Warning for %s, base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, baseclassname); base = Next(base); } } diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 18824ac1d..0852ce241 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -517,6 +517,7 @@ public: fputs(usage3, stdout); } else if (strcmp(argv[i], "-py3") == 0) { py3 = 1; + Preprocessor_define("SWIGPYTHON_PY3", 0); Swig_mark_arg(i); } else if (strcmp(argv[i], "-builtin") == 0) { builtin = 1; @@ -809,10 +810,10 @@ public: mod_docstring = NULL; } - Printv(f_shadow, "\nfrom sys import version_info\n", NULL); + Printv(f_shadow, "\nfrom sys import version_info as _swig_python_version_info\n", NULL); if (!builtin && fastproxy) { - Printv(f_shadow, "if version_info >= (3, 0, 0):\n", NULL); + Printv(f_shadow, "if _swig_python_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); @@ -826,8 +827,30 @@ public: * in 2.6, and fail in 2.7 onwards), but the relative import syntax * isn't available in python 2.4 or earlier, so we have to write some * code conditional on the python version. + * + * For python 2.7.0 and newer, first determine the shadow wrappers package + * based on the __name__ it was given by the importer that loaded it. + * Then construct a name for the module based on the package name and the + * module name (we know the module name). Use importlib to try and load + * it. If an attempt to load the module with importlib fails with an + * ImportError then fallback and try and load just the module name from + * the global namespace. */ - Printv(f_shadow, "if version_info >= (2, 6, 0):\n", NULL); + Printv(f_shadow, "if _swig_python_version_info >= (2, 7, 0):\n", NULL); + Printv(f_shadow, tab4, "def swig_import_helper():\n", NULL); + Printv(f_shadow, tab8, "import importlib\n", NULL); + Printv(f_shadow, tab8, "pkg = __name__.rpartition('.')[0]\n", NULL); + Printf(f_shadow, tab8 "mname = '.'.join((pkg, '%s')).lstrip('.')\n", + module); + Printv(f_shadow, tab8, "try:\n", NULL); + Printv(f_shadow, tab8, tab4, "return importlib.import_module(mname)\n", + NULL); + Printv(f_shadow, tab8, "except ImportError:\n", NULL); + Printf(f_shadow, tab8 tab4 "return importlib.import_module('%s')\n", + module); + Printf(f_shadow, tab4 "%s = swig_import_helper()\n", module); + Printv(f_shadow, tab4, "del swig_import_helper\n", NULL); + Printv(f_shadow, "elif _swig_python_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); @@ -849,13 +872,36 @@ public: Printv(f_shadow, "else:\n", NULL); Printf(f_shadow, tab4 "import %s\n", module); - /* Delete the version_info symbol since we don't use it elsewhere in the + if (builtin) { + /* + * Pull in all the attributes from the C module. + * + * An alternative approach to doing this if/else chain was + * proposed by Michael Thon. Someone braver than I may try it out. + * I fear some current swig user may depend on some side effect + * of from _foo import * + * + * for attr in _foo.__all__: + * globals()[attr] = getattr(_foo, attr) + * + */ + Printf(f_shadow, "# pull in all the attributes from %s\n", module); + Printv(f_shadow, "if __name__.rpartition('.')[0] != '':\n", NULL); + Printv(f_shadow, tab4, "if _swig_python_version_info >= (2, 7, 0):\n", NULL); + Printv(f_shadow, tab8, "try:\n", NULL); + Printf(f_shadow, tab8 tab4 "from .%s import *\n", module); + Printv(f_shadow, tab8 "except ImportError:\n", NULL); + Printf(f_shadow, tab8 tab4 "from %s import *\n", module); + Printv(f_shadow, tab4, "else:\n", NULL); + Printf(f_shadow, tab8 "from %s import *\n", module); + Printv(f_shadow, "else:\n", NULL); + Printf(f_shadow, tab4 "from %s import *\n", module); + } + + /* Delete the _swig_python_version_info symbol since we don't use it elsewhere in the * module. */ - Printv(f_shadow, "del version_info\n", NULL); + Printv(f_shadow, "del _swig_python_version_info\n", NULL); - if (builtin) { - 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\n", NULL); } @@ -897,15 +943,11 @@ public: "\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, - "\n", "def _swig_getattr_nondynamic(self, class_type, name, static=1):\n", + "\n", "def _swig_getattr(self, class_type, name):\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); + tab4, "raise AttributeError(\"'%s' object has no attribute '%s'\" % (class_type.__name__, name))\n\n", NIL); Printv(f_shadow, "\n", "def _swig_repr(self):\n", @@ -1209,13 +1251,14 @@ public: Printf(out, "import %s%s%s%s\n", apkg, *Char(apkg) ? "." : "", pfx, mod); Delete(apkg); } else { - if (py3) { - if (py3_rlen1) - Printf(out, "from . import %.*s\n", py3_rlen1, rpkg); - Printf(out, "from .%s import %s%s\n", rpkg, pfx, mod); - } else { - Printf(out, "import %s%s%s%s\n", rpkg, *Char(rpkg) ? "." : "", pfx, mod); - } + Printf(out, "from sys import version_info as _swig_python_version_info\n"); + Printf(out, "if _swig_python_version_info >= (2, 7, 0):\n"); + if (py3_rlen1) + Printf(out, tab4 "from . import %.*s\n", py3_rlen1, rpkg); + Printf(out, tab4 "from .%s import %s%s\n", rpkg, pfx, mod); + Printf(out, "else:\n"); + Printf(out, tab4 "import %s%s%s%s\n", rpkg, *Char(rpkg) ? "." : "", pfx, mod); + Printf(out, "del _swig_python_version_info\n"); Delete(rpkg); } return out; @@ -2728,7 +2771,8 @@ public: int noargs = funpack && (tuple_required == 0 && tuple_arguments == 0); int onearg = funpack && (tuple_required == 1 && tuple_arguments == 1); - if (builtin && funpack && !overname && !builtin_ctor && !GetFlag(n, "feature:compactdefaultargs")) { + if (builtin && funpack && !overname && !builtin_ctor && + !(GetFlag(n, "feature:compactdefaultargs") && (tuple_arguments > tuple_required || varargs))) { String *argattr = NewStringf("%d", tuple_arguments); Setattr(n, "python:argcount", argattr); Delete(argattr); @@ -3454,6 +3498,28 @@ public: * constantWrapper() * ------------------------------------------------------------ */ + /* Determine if the node requires the _swigconstant code to be generated */ + bool needs_swigconstant(Node* n) { + SwigType *type = Getattr(n, "type"); + SwigType *qtype = SwigType_typedef_resolve_all(type); + SwigType *uqtype = SwigType_strip_qualifiers(qtype); + bool result = false; + + /* Note, that we need special handling for function pointers, as + * SwigType_base(fptr) does not return the underlying pointer-to-function + * type but the return-type of function. */ + if(!SwigType_isfunction(uqtype) && !SwigType_isfunctionpointer(uqtype)) { + SwigType *basetype = SwigType_base(uqtype); + result = SwigType_isclass(basetype) != 0; + Delete(basetype); + } + + Delete(qtype); + Delete(uqtype); + + return result; + } + virtual int constantWrapper(Node *n) { String *name = Getattr(n, "name"); String *iname = Getattr(n, "sym:name"); @@ -3496,8 +3562,15 @@ public: Replaceall(tm, "$source", value); Replaceall(tm, "$target", name); Replaceall(tm, "$value", value); - if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER)) && (!in_class || !Getattr(n, "feature:python:callback"))) { - // Generate method which registers the new constant + if (needs_swigconstant(n) && !builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER)) && (!in_class || !Getattr(n, "feature:python:callback"))) { + // Generate `*_swigconstant()` method which registers the new constant. + // + // *_swigconstant methods are required for constants of class type. + // Class types are registered in shadow file (see *_swigregister). The + // instances of class must be created (registered) after the type is + // registered, so we can't let SWIG_init() to register constants of + // class type (the SWIG_init() is called before shadow classes are + // defined and registered). Printf(f_wrappers, "SWIGINTERN PyObject *%s_swigconstant(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", iname); Printf(f_wrappers, tab2 "PyObject *module;\n", tm); Printf(f_wrappers, tab2 "PyObject *d;\n"); @@ -3537,13 +3610,17 @@ public: if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) { if (!in_class) { - Printv(f_shadow, "\n",NIL); - Printv(f_shadow, module, ".", iname, "_swigconstant(",module,")\n", NIL); + if(needs_swigconstant(n)) { + Printv(f_shadow, "\n",NIL); + Printv(f_shadow, module, ".", iname, "_swigconstant(",module,")\n", NIL); + } Printv(f_shadow, iname, " = ", module, ".", iname, "\n", NIL); } else { if (!(Getattr(n, "feature:python:callback"))) { - Printv(f_shadow_stubs, "\n",NIL); - Printv(f_shadow_stubs, module, ".", iname, "_swigconstant(", module, ")\n", NIL); + if(needs_swigconstant(n)) { + Printv(f_shadow_stubs, "\n",NIL); + Printv(f_shadow_stubs, module, ".", iname, "_swigconstant(", module, ")\n", NIL); + } Printv(f_shadow_stubs, iname, " = ", module, ".", iname, "\n", NIL); } } @@ -4123,9 +4200,9 @@ public: printSlot(f, getSlot(n, "feature:python:nb_inplace_xor"), "nb_inplace_xor", "binaryfunc"); printSlot(f, getSlot(n, "feature:python:nb_inplace_or"), "nb_inplace_or", "binaryfunc"); printSlot(f, getSlot(n, "feature:python:nb_floor_divide"), "nb_floor_divide", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_true_divide"), "nb_true_divide", "binaryfunc"); + printSlot(f, getSlot(n, "feature:python:nb_divide"), "nb_true_divide", "binaryfunc"); printSlot(f, getSlot(n, "feature:python:nb_inplace_floor_divide"), "nb_inplace_floor_divide", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_true_divide"), "nb_inplace_true_divide", "binaryfunc"); + printSlot(f, getSlot(n, "feature:python:nb_inplace_divide"), "nb_inplace_true_divide", "binaryfunc"); Printv(f, "#if PY_VERSION_HEX >= 0x02050000\n", NIL); printSlot(f, getSlot(n, "feature:python:nb_index"), "nb_index", "unaryfunc"); Printv(f, "#endif\n", NIL); diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index 758cb00ee..301b49f9e 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -1179,6 +1179,9 @@ int R::OutputArrayMethod(String *className, List *el, File *out) { tdname is the typedef of the enumeration, i.e. giving its name. *************************************************************/ int R::enumDeclaration(Node *n) { + if (getCurrentClass() && (cplus_mode != PUBLIC)) + return SWIG_NOWRAP; + String *name = Getattr(n, "name"); String *tdname = Getattr(n, "tdname"); @@ -1479,11 +1482,12 @@ List * R::Swig_overload_rank(Node *n, Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); } else { - if (!Getattr(nodes[j].n, "overload:ignore")) + if (!Getattr(nodes[j].n, "overload:ignore")) { Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), "using %s instead.\n", Swig_name_decl(nodes[i].n)); + } } } nodes[j].error = 1; @@ -1496,11 +1500,12 @@ List * R::Swig_overload_rank(Node *n, Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); } else { - if (!Getattr(nodes[j].n, "overload:ignore")) + if (!Getattr(nodes[j].n, "overload:ignore")) { Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), "using %s instead.\n", Swig_name_decl(nodes[i].n)); + } } } nodes[j].error = 1; @@ -1518,11 +1523,12 @@ List * R::Swig_overload_rank(Node *n, Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n), "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n)); } else { - if (!Getattr(nodes[j].n, "overload:ignore")) + if (!Getattr(nodes[j].n, "overload:ignore")) { Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), "using %s instead.\n", Swig_name_decl(nodes[i].n)); + } } nodes[j].error = 1; } diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index 62a6d960c..2a3128472 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -1011,6 +1011,8 @@ public: virtual int top(Node *n) { + String *mod_docstring = NULL; + /** * See if any Ruby module options have been specified as options * to the %module directive. @@ -1032,6 +1034,7 @@ public: multipleInheritance = true; director_multiple_inheritance = 1; } + mod_docstring = Getattr(options, "docstring"); } } @@ -1146,6 +1149,15 @@ public: Printf(f_header, "#define SWIG_init Init_%s\n", feature); Printf(f_header, "#define SWIG_name \"%s\"\n\n", module); + + if (mod_docstring) { + if (Len(mod_docstring)) { + Printf(f_header, "/*\n Document-module: %s\n\n%s\n*/\n", module, mod_docstring); + } + Delete(mod_docstring); + mod_docstring = NULL; + } + Printf(f_header, "static VALUE %s;\n", modvar); /* Start generating the initialization function */ @@ -1534,7 +1546,8 @@ public: /* Finish argument marshalling */ Printf(kwargs, " NULL }"); if (allow_kwargs) { - Printv(f->locals, tab4, "const char *kwnames[] = ", kwargs, ";\n", NIL); +// kwarg support not implemented +// Printv(f->locals, tab4, "const char *kwnames[] = ", kwargs, ";\n", NIL); } /* Trailing varargs */ @@ -2110,13 +2123,11 @@ public: // Generate prototype list, go to first node Node *sibl = n; - String* type = SwigType_str(Getattr(sibl,"type"),NULL); - while (Getattr(sibl, "sym:previousSibling")) sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up // Constructors will be treated specially - const bool isCtor = Cmp(Getattr(sibl,"feature:new"), "1") == 0; + const bool isCtor = (!Cmp(Getattr(sibl, "nodeType"), "constructor")); const bool isMethod = ( Cmp(Getattr(sibl, "ismember"), "1") == 0 && (!isCtor) ); @@ -2138,7 +2149,11 @@ public: String *protoTypes = NewString(""); do { Append( protoTypes, "\n\" "); - if ( !isCtor ) Printv( protoTypes, type, " ", NIL ); + if (!isCtor) { + SwigType *type = SwigType_str(Getattr(sibl, "type"), NULL); + Printv(protoTypes, type, " ", NIL); + Delete(type); + } Printv(protoTypes, methodName, NIL ); Parm* p = Getattr(sibl, "wrap:parms"); if (p && (current == MEMBER_FUNC || current == MEMBER_VAR || @@ -2159,7 +2174,6 @@ public: Append(f->code, "\nreturn Qnil;\n"); Delete(methodName); - Delete(type); Delete(protoTypes); Printv(f->code, "}\n", NIL); @@ -2473,7 +2487,7 @@ public: String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Ruby.\n", proxyclassname, baseclassname); + "Warning for %s, base %s ignored. Multiple inheritance is not supported in Ruby.\n", proxyclassname, baseclassname); base = Next(base); } } @@ -3460,6 +3474,7 @@ public: *--------------------------------------------------------------------*/ bool kwargsSupport() const { + // kwargs support isn't actually implemented, but changing to return false may break something now as it turns on compactdefaultargs return true; } }; /* class RUBY */ diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx index 63f689eaa..137adc234 100644 --- a/Source/Modules/scilab.cxx +++ b/Source/Modules/scilab.cxx @@ -326,6 +326,7 @@ public: bool isLastOverloaded = isOverloaded && !Getattr(node, "sym:nextSibling"); if (!isOverloaded && !addSymbol(functionName, node)) { + DelWrapper(wrapper); return SWIG_ERROR; } @@ -633,7 +634,10 @@ public: /* Add function to builder table */ addFunctionToScilab(scilabSetFunctionName, setFunctionName); + + DelWrapper(setFunctionWrapper); } + DelWrapper(getFunctionWrapper); return SWIG_OK; } @@ -884,7 +888,7 @@ public: Printf(builderCode, "libs = [];\n"); // Flags from command line arguments - Printf(builderCode, "cflags = [];\n"); + Printf(builderCode, "cflags = \"\";\n"); for (int i = 0; i < Len(cflags); i++) { String *cflag = Getitem(cflags, i); Printf(builderCode, "cflags = cflags + \" %s\";\n", cflag); @@ -900,7 +904,7 @@ public: } } } else { - Printf(builderCode, "ldflags = [];\n"); + Printf(builderCode, "ldflags = \"\";\n"); } // External script to set flags diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index c4007be51..34763cc09 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -208,8 +208,9 @@ public: /* Miscellaneous */ virtual int validIdentifier(String *s); /* valid identifier? */ virtual int addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope = ""); /* Add symbol */ + virtual int addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope = ""); virtual void dumpSymbols(); - virtual Node *symbolLookup(String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */ + virtual Node *symbolLookup(const String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */ virtual Hash* symbolAddScope(const_String_or_char_ptr scope); virtual Hash* symbolScopeLookup(const_String_or_char_ptr scope); virtual Hash* symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope); @@ -422,19 +423,24 @@ extern "C" { } /* Contracts */ - void Swig_contracts(Node *n); void Swig_contract_mode_set(int flag); int Swig_contract_mode_get(); /* Browser */ - void Swig_browser(Node *n, int); void Swig_default_allocators(Node *n); void Swig_process_types(Node *n); + +/* Nested classes */ void Swig_nested_process_classes(Node *n); void Swig_nested_name_unnamed_c_structs(Node *n); +/* Interface feature */ +void Swig_interface_feature_enable(); +void Swig_interface_propagate_methods(Node *n); + +/* Miscellaneous */ template <class T> class save_value { T _value; T& _value_ptr; diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index da077fd07..dc4d02bdd 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -224,7 +224,7 @@ class TypePass:private Dispatcher { if (tname) Delete(tname); if (!bcls) { - if (!clsforward) { + if (!clsforward && !GetFlag(cls, "feature:ignore")) { if (ispublic && !Getmeta(bname, "already_warned")) { Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname)); if (Strchr(bname, '<')) { @@ -265,7 +265,13 @@ class TypePass:private Dispatcher { SwigType *bsmart = Copy(smart); SwigType *rclsname = SwigType_typedef_resolve_all(clsname); SwigType *rbname = SwigType_typedef_resolve_all(bname); - Replaceall(bsmart, rclsname, rbname); + int replace_count = Replaceall(bsmart, rclsname, rbname); + if (replace_count == 0) { + // If no replacement made, it will be because rclsname is fully resolved, but the + // type in the smartptr feature used a typedef or not fully resolved name. + String *firstname = Getattr(first, "name"); + Replaceall(bsmart, firstname, rbname); + } Delete(rclsname); Delete(rbname); String *smartnamestr = SwigType_namestr(smart); diff --git a/Source/Swig/include.c b/Source/Swig/include.c index 08226a25c..94df338f0 100644 --- a/Source/Swig/include.c +++ b/Source/Swig/include.c @@ -291,6 +291,7 @@ int Swig_insert_file(const_String_or_char_ptr filename, File *outfile) { while ((nbytes = Read(f, buffer, 4096)) > 0) { Write(outfile, buffer, nbytes); } + fclose(f); return 0; } diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index c552ac2cb..91f05c0a2 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -309,6 +309,7 @@ int Swig_storage_isstatic(Node *n) { * Swig_string_escape() * * Takes a string object and produces a string with escape codes added to it. + * Octal escaping is used. * ----------------------------------------------------------------------------- */ String *Swig_string_escape(String *s) { @@ -342,6 +343,43 @@ String *Swig_string_escape(String *s) { return ns; } +/* ----------------------------------------------------------------------------- + * Swig_string_hexescape() + * + * Takes a string object and produces a string with escape codes added to it. + * Hex escaping is used. + * ----------------------------------------------------------------------------- */ + +String *Swig_string_hexescape(String *s) { + String *ns; + int c; + ns = NewStringEmpty(); + + while ((c = Getc(s)) != EOF) { + if (c == '\n') { + Printf(ns, "\\n"); + } else if (c == '\r') { + Printf(ns, "\\r"); + } else if (c == '\t') { + Printf(ns, "\\t"); + } else if (c == '\\') { + Printf(ns, "\\\\"); + } else if (c == '\'') { + Printf(ns, "\\'"); + } else if (c == '\"') { + Printf(ns, "\\\""); + } else if (c == ' ') { + Putc(c, ns); + } else if (!isgraph(c)) { + if (c < 0) + c += UCHAR_MAX + 1; + Printf(ns, "\\x%X", c); + } else { + Putc(c, ns); + } + } + return ns; +} /* ----------------------------------------------------------------------------- * Swig_string_upper() @@ -1148,6 +1186,39 @@ String *Swig_string_strip(String *s) { } /* ----------------------------------------------------------------------------- + * Swig_string_rstrip() + * + * Strip given suffix from identifiers + * + * Printf(stderr,"%(rstrip:[Cls])s","HelloCls") -> Hello + * ----------------------------------------------------------------------------- */ + +String *Swig_string_rstrip(String *s) { + String *ns; + int len = Len(s); + if (!len) { + ns = NewString(s); + } else { + const char *cs = Char(s); + const char *ce = Strchr(cs, ']'); + if (*cs != '[' || !ce) { + ns = NewString(s); + } else { + String *fmt = NewStringf("%%.%ds", ce-cs-1); + String *suffix = NewStringf(fmt, cs+1); + int suffix_len = Len(suffix); + if (0 == Strncmp(cs+len-suffix_len, suffix, suffix_len)) { + int copy_len = len-suffix_len-(ce+1-cs); + ns = NewStringWithSize(ce+1, copy_len); + } else { + ns = NewString(ce+1); + } + } + } + return ns; +} + +/* ----------------------------------------------------------------------------- * Swig_offset_string() * * Insert number tabs before each new line in s @@ -1328,7 +1399,7 @@ String *replace_captures(int num_captures, const char *input, String *subst, int * * Executes a regular expression substitution. For example: * - * Printf(stderr,"gsl%(regex:/GSL_.*_/\\1/)s","GSL_Hello_") -> gslHello + * Printf(stderr,"gsl%(regex:/GSL_(.*)_/\\1/)s", "GSL_Hello_") -> gslHello * ----------------------------------------------------------------------------- */ String *Swig_string_regex(String *s) { const int pcre_options = 0; @@ -1392,6 +1463,7 @@ String *Swig_pcre_version(void) { void Swig_init() { /* Set some useful string encoding methods */ DohEncoding("escape", Swig_string_escape); + DohEncoding("hexescape", Swig_string_hexescape); DohEncoding("upper", Swig_string_upper); DohEncoding("lower", Swig_string_lower); DohEncoding("title", Swig_string_title); @@ -1403,6 +1475,7 @@ void Swig_init() { DohEncoding("command", Swig_string_command); DohEncoding("schemify", Swig_string_schemify); DohEncoding("strip", Swig_string_strip); + DohEncoding("rstrip", Swig_string_rstrip); DohEncoding("regex", Swig_string_regex); /* aliases for the case encoders */ diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 2d1effa18..c7f187177 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -50,6 +50,13 @@ void Swig_name_unregister(const_String_or_char_ptr method) { } } +/* Return naming format for the specified method or the default format if none was explicitly registered */ +static String* get_naming_format_for(const char *method, const char *def_format) { + String* f = naming_hash ? Getattr(naming_hash, method) : NULL; + + return f ? Copy(f) : NewString(def_format); +} + static int name_mangle(String *r) { char *c; int special; @@ -172,18 +179,8 @@ String *Swig_name_mangle(const_String_or_char_ptr s) { * ----------------------------------------------------------------------------- */ String *Swig_name_wrapper(const_String_or_char_ptr fname) { - String *r; - String *f; + String *r = get_naming_format_for("wrapper", "_wrap_%f"); - r = NewStringEmpty(); - if (!naming_hash) - naming_hash = NewHash(); - f = Getattr(naming_hash, "wrapper"); - if (!f) { - Append(r, "_wrap_%f"); - } else { - Append(r, f); - } Replace(r, "%f", fname, DOH_REPLACE_ANY); name_mangle(r); return r; @@ -198,20 +195,11 @@ String *Swig_name_wrapper(const_String_or_char_ptr fname) { String *Swig_name_member(const_String_or_char_ptr nspace, const_String_or_char_ptr classname, const_String_or_char_ptr membername) { String *r; - String *f; String *rclassname; char *cname; rclassname = SwigType_namestr(classname); - r = NewStringEmpty(); - if (!naming_hash) - naming_hash = NewHash(); - f = Getattr(naming_hash, "member"); - if (!f) { - Append(r, "%n%c_%m"); - } else { - Append(r, f); - } + r = get_naming_format_for("member", "%n%c_%m"); cname = Char(rclassname); if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { cname = strchr(cname, ' ') + 1; @@ -231,23 +219,12 @@ String *Swig_name_member(const_String_or_char_ptr nspace, const_String_or_char_p * ----------------------------------------------------------------------------- */ String *Swig_name_get(const_String_or_char_ptr nspace, const_String_or_char_ptr vname) { - String *r; - String *f; + String *r = get_naming_format_for("get", "%n%v_get"); #ifdef SWIG_DEBUG Printf(stdout, "Swig_name_get: '%s'\n", vname); #endif - r = NewStringEmpty(); - if (!naming_hash) - naming_hash = NewHash(); - f = Getattr(naming_hash, "get"); - if (!f) { - Append(r, "%n%v_get"); - } else { - Append(r, f); - } - replace_nspace(r, nspace); Replace(r, "%v", vname, DOH_REPLACE_ANY); /* name_mangle(r); */ @@ -261,18 +238,7 @@ String *Swig_name_get(const_String_or_char_ptr nspace, const_String_or_char_ptr * ----------------------------------------------------------------------------- */ String *Swig_name_set(const_String_or_char_ptr nspace, const_String_or_char_ptr vname) { - String *r; - String *f; - - r = NewStringEmpty(); - if (!naming_hash) - naming_hash = NewHash(); - f = Getattr(naming_hash, "set"); - if (!f) { - Append(r, "%n%v_set"); - } else { - Append(r, f); - } + String *r = get_naming_format_for("set", "%n%v_set"); replace_nspace(r, nspace); Replace(r, "%v", vname, DOH_REPLACE_ANY); @@ -280,28 +246,14 @@ String *Swig_name_set(const_String_or_char_ptr nspace, const_String_or_char_ptr return r; } -/* ----------------------------------------------------------------------------- - * Swig_name_construct() - * - * Returns the name of the accessor function used to create an object. - * ----------------------------------------------------------------------------- */ - -String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { +/* Common implementation of all Swig_name_<special-method>() functions below. */ +static String *make_full_name_for(const char *method, const char *def_format, const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { String *r; - String *f; String *rclassname; char *cname; rclassname = SwigType_namestr(classname); - r = NewStringEmpty(); - if (!naming_hash) - naming_hash = NewHash(); - f = Getattr(naming_hash, "construct"); - if (!f) { - Append(r, "new_%n%c"); - } else { - Append(r, f); - } + r = get_naming_format_for(method, def_format); cname = Char(rclassname); if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { @@ -314,6 +266,16 @@ String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_cha return r; } +/* ----------------------------------------------------------------------------- + * Swig_name_construct() + * + * Returns the name of the accessor function used to create an object. + * ----------------------------------------------------------------------------- */ + +String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { + return make_full_name_for("construct", "new_%n%c", nspace, classname); +} + /* ----------------------------------------------------------------------------- * Swig_name_copyconstructor() @@ -322,31 +284,7 @@ String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_cha * ----------------------------------------------------------------------------- */ String *Swig_name_copyconstructor(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { - String *r; - String *f; - String *rclassname; - char *cname; - - rclassname = SwigType_namestr(classname); - r = NewStringEmpty(); - if (!naming_hash) - naming_hash = NewHash(); - f = Getattr(naming_hash, "copy"); - if (!f) { - Append(r, "copy_%n%c"); - } else { - Append(r, f); - } - - cname = Char(rclassname); - if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { - cname = strchr(cname, ' ') + 1; - } - - replace_nspace(r, nspace); - Replace(r, "%c", cname, DOH_REPLACE_ANY); - Delete(rclassname); - return r; + return make_full_name_for("copy", "copy_%n%c", nspace, classname); } /* ----------------------------------------------------------------------------- @@ -356,30 +294,7 @@ String *Swig_name_copyconstructor(const_String_or_char_ptr nspace, const_String_ * ----------------------------------------------------------------------------- */ String *Swig_name_destroy(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { - String *r; - String *f; - String *rclassname; - char *cname; - rclassname = SwigType_namestr(classname); - r = NewStringEmpty(); - if (!naming_hash) - naming_hash = NewHash(); - f = Getattr(naming_hash, "destroy"); - if (!f) { - Append(r, "delete_%n%c"); - } else { - Append(r, f); - } - - cname = Char(rclassname); - if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { - cname = strchr(cname, ' ') + 1; - } - - replace_nspace(r, nspace); - Replace(r, "%c", cname, DOH_REPLACE_ANY); - Delete(rclassname); - return r; + return make_full_name_for("destroy", "delete_%n%c", nspace, classname); } @@ -390,30 +305,7 @@ String *Swig_name_destroy(const_String_or_char_ptr nspace, const_String_or_char_ * ----------------------------------------------------------------------------- */ String *Swig_name_disown(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { - String *r; - String *f; - String *rclassname; - char *cname; - rclassname = SwigType_namestr(classname); - r = NewStringEmpty(); - if (!naming_hash) - naming_hash = NewHash(); - f = Getattr(naming_hash, "disown"); - if (!f) { - Append(r, "disown_%n%c"); - } else { - Append(r, f); - } - - cname = Char(rclassname); - if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { - cname = strchr(cname, ' ') + 1; - } - - replace_nspace(r, nspace); - Replace(r, "%c", cname, DOH_REPLACE_ANY); - Delete(rclassname); - return r; + return make_full_name_for("disown", "disown_%n%c", nspace, classname); } @@ -466,8 +358,7 @@ static DOH *get_object(Hash *n, String *decl) { return rn; } -static -DOH *name_object_get(Hash *namehash, String *tname, SwigType *decl, SwigType *ncdecl) { +static DOH *name_object_get(Hash *namehash, String *tname, SwigType *decl, SwigType *ncdecl) { DOH *rn = 0; Hash *n = Getattr(namehash, tname); if (n) { @@ -646,8 +537,7 @@ static void merge_features(Hash *features, Node *n) { * the declaration, decl. * ----------------------------------------------------------------------------- */ -static -void features_get(Hash *features, const String *tname, SwigType *decl, SwigType *ncdecl, Node *node) { +static void features_get(Hash *features, const String *tname, SwigType *decl, SwigType *ncdecl, Node *node) { Node *n = Getattr(features, tname); #ifdef SWIG_DEBUG Printf(stdout, " features_get: %s\n", tname); @@ -844,41 +734,41 @@ void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *d * ----------------------------------------------------------------------------- */ static Hash *namewarn_hash = 0; -Hash *Swig_name_namewarn_hash() { +static Hash *name_namewarn_hash() { if (!namewarn_hash) namewarn_hash = NewHash(); return namewarn_hash; } static Hash *rename_hash = 0; -Hash *Swig_name_rename_hash() { +static Hash *name_rename_hash() { if (!rename_hash) rename_hash = NewHash(); return rename_hash; } static List *namewarn_list = 0; -List *Swig_name_namewarn_list() { +static List *name_namewarn_list() { if (!namewarn_list) namewarn_list = NewList(); return namewarn_list; } static List *rename_list = 0; -List *Swig_name_rename_list() { +static List *name_rename_list() { if (!rename_list) rename_list = NewList(); return rename_list; } /* ----------------------------------------------------------------------------- - * int Swig_need_name_warning(Node *n) + * int need_name_warning(Node *n) * * Detects if a node needs name warnings * * ----------------------------------------------------------------------------- */ -int Swig_need_name_warning(Node *n) { +static int need_name_warning(Node *n) { int need = 1; /* We don't use name warnings for: @@ -1061,13 +951,13 @@ int Swig_need_protected(Node *n) { } /* ----------------------------------------------------------------------------- - * void Swig_name_nameobj_add() + * void name_nameobj_add() * * Add nameobj (rename/namewarn) * * ----------------------------------------------------------------------------- */ -static List *Swig_make_attrlist(const char *ckey) { +static List *make_attrlist(const char *ckey) { List *list = NewList(); const char *cattr = strchr(ckey, '$'); if (cattr) { @@ -1089,7 +979,7 @@ static List *Swig_make_attrlist(const char *ckey) { return list; } -static void Swig_name_object_attach_keys(const char *keys[], Hash *nameobj) { +static void name_object_attach_keys(const char *keys[], Hash *nameobj) { Node *kw = nextSibling(nameobj); List *matchlist = 0; while (kw) { @@ -1105,7 +995,7 @@ static void Swig_name_object_attach_keys(const char *keys[], Hash *nameobj) { || (isregexmatch = (strncmp(ckey, "regexmatch", 10) == 0)) || (isnotmatch = isregexmatch = (strncmp(ckey, "notregexmatch", 13) == 0))) { Hash *mi = NewHash(); - List *attrlist = Swig_make_attrlist(ckey); + List *attrlist = make_attrlist(ckey); if (!matchlist) matchlist = NewList(); Setattr(mi, "value", Getattr(kw, "value")); @@ -1135,7 +1025,7 @@ static void Swig_name_object_attach_keys(const char *keys[], Hash *nameobj) { } } -void Swig_name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, String *name, SwigType *decl, Hash *nameobj) { +static void name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, String *name, SwigType *decl, Hash *nameobj) { String *nname = 0; if (name && Len(name)) { String *target_fmt = Getattr(nameobj, "targetfmt"); @@ -1164,13 +1054,13 @@ void Swig_name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, Str } /* ----------------------------------------------------------------------------- - * int Swig_name_match_nameobj() + * int name_match_nameobj() * * Apply and check the nameobj's math list to the node * * ----------------------------------------------------------------------------- */ -static DOH *Swig_get_lattr(Node *n, List *lattr) { +static DOH *get_lattr(Node *n, List *lattr) { DOH *res = 0; int ilen = Len(lattr); int i; @@ -1192,7 +1082,7 @@ static DOH *Swig_get_lattr(Node *n, List *lattr) { #ifdef HAVE_PCRE #include <pcre.h> -int Swig_name_regexmatch_value(Node *n, String *pattern, String *s) { +static int name_regexmatch_value(Node *n, String *pattern, String *s) { pcre *compiled_pat; const char *err; int errpos; @@ -1224,7 +1114,7 @@ int Swig_name_regexmatch_value(Node *n, String *pattern, String *s) { #else /* !HAVE_PCRE */ -int Swig_name_regexmatch_value(Node *n, String *pattern, String *s) { +static int name_regexmatch_value(Node *n, String *pattern, String *s) { (void)pattern; (void)s; Swig_error("SWIG", Getline(n), @@ -1234,7 +1124,7 @@ int Swig_name_regexmatch_value(Node *n, String *pattern, String *s) { #endif /* HAVE_PCRE/!HAVE_PCRE */ -int Swig_name_match_value(String *mvalue, String *value) { +static int name_match_value(String *mvalue, String *value) { #if defined(SWIG_USE_SIMPLE_MATCHOR) int match = 0; char *cvalue = Char(value); @@ -1260,12 +1150,11 @@ int Swig_name_match_value(String *mvalue, String *value) { #endif } - -int Swig_name_match_nameobj(Hash *rn, Node *n) { +static int name_match_nameobj(Hash *rn, Node *n) { int match = 1; List *matchlist = Getattr(rn, "matchlist"); #ifdef SWIG_DEBUG - Printf(stdout, "Swig_name_match_nameobj: %s\n", Getattr(n, "name")); + Printf(stdout, "name_match_nameobj: %s\n", Getattr(n, "name")); #endif if (matchlist) { int ilen = Len(matchlist); @@ -1273,14 +1162,14 @@ int Swig_name_match_nameobj(Hash *rn, Node *n) { for (i = 0; match && (i < ilen); ++i) { Node *mi = Getitem(matchlist, i); List *lattr = Getattr(mi, "attrlist"); - String *nval = Swig_get_lattr(n, lattr); + String *nval = get_lattr(n, lattr); int notmatch = GetFlag(mi, "notmatch"); int regexmatch = GetFlag(mi, "regexmatch"); match = 0; if (nval) { String *kwval = Getattr(mi, "value"); - match = regexmatch ? Swig_name_regexmatch_value(n, kwval, nval) - : Swig_name_match_value(kwval, nval); + match = regexmatch ? name_regexmatch_value(n, kwval, nval) + : name_match_value(kwval, nval); #ifdef SWIG_DEBUG Printf(stdout, "val %s %s %d %d \n", nval, kwval, match, ilen); #endif @@ -1290,19 +1179,19 @@ int Swig_name_match_nameobj(Hash *rn, Node *n) { } } #ifdef SWIG_DEBUG - Printf(stdout, "Swig_name_match_nameobj: %d\n", match); + Printf(stdout, "name_match_nameobj: %d\n", match); #endif return match; } /* ----------------------------------------------------------------------------- - * Hash *Swig_name_nameobj_lget() + * Hash *name_nameobj_lget() * * Get a nameobj (rename/namewarn) from the list of filters * * ----------------------------------------------------------------------------- */ -Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *name, String *decl) { +static Hash *name_nameobj_lget(List *namelist, Node *n, String *prefix, String *name, String *decl) { Hash *res = 0; if (namelist) { int len = Len(namelist); @@ -1313,7 +1202,7 @@ Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *na String *rdecl = Getattr(rn, "decl"); if (rdecl && (!decl || !Equal(rdecl, decl))) { continue; - } else if (Swig_name_match_nameobj(rn, n)) { + } else if (name_match_nameobj(rn, n)) { String *tname = Getattr(rn, "targetname"); if (tname) { String *sfmt = Getattr(rn, "sourcefmt"); @@ -1336,8 +1225,8 @@ Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *na DohIncref(name); } } - match = regextarget ? Swig_name_regexmatch_value(n, tname, sname) - : Swig_name_match_value(tname, sname); + match = regextarget ? name_regexmatch_value(n, tname, sname) + : name_match_value(tname, sname); Delete(sname); } else { /* Applying the renaming rule may fail if it contains a %(regex)s expression that doesn't match the given name. */ @@ -1367,23 +1256,23 @@ Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *na void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn) { const char *namewrn_keys[] = { "rename", "error", "fullname", "sourcefmt", "targetfmt", 0 }; - Swig_name_object_attach_keys(namewrn_keys, namewrn); - Swig_name_nameobj_add(Swig_name_namewarn_hash(), Swig_name_namewarn_list(), prefix, name, decl, namewrn); + name_object_attach_keys(namewrn_keys, namewrn); + name_nameobj_add(name_namewarn_hash(), name_namewarn_list(), prefix, name, decl, namewrn); } /* ----------------------------------------------------------------------------- - * Hash *Swig_name_namewarn_get() + * Hash *name_namewarn_get() * * Return the namewarn object, if there is one. * * ----------------------------------------------------------------------------- */ -Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl) { +static Hash *name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl) { if (!namewarn_hash && !namewarn_list) return 0; if (n) { /* Return in the obvious cases */ - if (!name || !Swig_need_name_warning(n)) { + if (!name || !need_name_warning(n)) { return 0; } else { String *access = Getattr(n, "access"); @@ -1395,11 +1284,11 @@ Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *de } if (name) { /* Check to see if the name is in the hash */ - Hash *wrn = Swig_name_object_get(Swig_name_namewarn_hash(), prefix, name, decl); - if (wrn && !Swig_name_match_nameobj(wrn, n)) + Hash *wrn = Swig_name_object_get(name_namewarn_hash(), prefix, name, decl); + if (wrn && !name_match_nameobj(wrn, n)) wrn = 0; if (!wrn) { - wrn = Swig_name_nameobj_lget(Swig_name_namewarn_list(), n, prefix, name, decl); + wrn = name_nameobj_lget(name_namewarn_list(), n, prefix, name, decl); } if (wrn && Getattr(wrn, "error")) { if (n) { @@ -1422,7 +1311,7 @@ Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *de * ----------------------------------------------------------------------------- */ String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl) { - Hash *wrn = Swig_name_namewarn_get(n, prefix, name, decl); + Hash *wrn = name_namewarn_get(n, prefix, name, decl); return (name && wrn) ? Getattr(wrn, "name") : 0; } @@ -1434,7 +1323,7 @@ String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl) * ----------------------------------------------------------------------------- */ static void single_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname) { - Swig_name_nameobj_add(Swig_name_rename_hash(), Swig_name_rename_list(), prefix, name, decl, newname); + name_nameobj_add(name_rename_hash(), name_rename_list(), prefix, name, decl, newname); } /* Add a new rename. Works much like new_feature including default argument handling. */ @@ -1443,7 +1332,7 @@ void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *ne ParmList *declparms = declaratorparms; const char *rename_keys[] = { "fullname", "sourcefmt", "targetfmt", "continue", "regextarget", 0 }; - Swig_name_object_attach_keys(rename_keys, newname); + name_object_attach_keys(rename_keys, newname); /* Add the name */ single_rename_add(prefix, name, decl, newname); @@ -1556,11 +1445,10 @@ String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, } } - if (rename_hash || rename_list || namewarn_hash || namewarn_list) { - Hash *rn = Swig_name_object_get(Swig_name_rename_hash(), prefix, name, decl); - if (!rn || !Swig_name_match_nameobj(rn, n)) { - rn = Swig_name_nameobj_lget(Swig_name_rename_list(), n, prefix, name, decl); + Hash *rn = Swig_name_object_get(name_rename_hash(), prefix, name, decl); + if (!rn || !name_match_nameobj(rn, n)) { + rn = name_nameobj_lget(name_rename_list(), n, prefix, name, decl); if (rn) { String *sfmt = Getattr(rn, "sourcefmt"); int fullname = GetFlag(rn, "fullname"); @@ -1596,7 +1484,7 @@ String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, } } nname = result ? result : name; - wrn = Swig_name_namewarn_get(n, prefix, nname, decl); + wrn = name_namewarn_get(n, prefix, nname, decl); if (wrn) { String *rename = Getattr(wrn, "rename"); if (rename) { @@ -1641,14 +1529,14 @@ String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, /* ----------------------------------------------------------------------------- * void Swig_name_inherit() * - * Inherit namewarn,rename, and feature objects + * Inherit namewarn, rename, and feature objects * * ----------------------------------------------------------------------------- */ void Swig_name_inherit(String *base, String *derived) { /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */ - Swig_name_object_inherit(Swig_name_rename_hash(), base, derived); - Swig_name_object_inherit(Swig_name_namewarn_hash(), base, derived); + Swig_name_object_inherit(name_rename_hash(), base, derived); + Swig_name_object_inherit(name_namewarn_hash(), base, derived); Swig_name_object_inherit(Swig_cparse_features(), base, derived); } diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index becae9456..35a67640f 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -283,13 +283,11 @@ extern int ParmList_is_compactdefargs(ParmList *p); extern void Swig_naming_init(void); extern void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn); - extern Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl); extern void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *namewrn, ParmList *declaratorparms); extern void Swig_name_inherit(String *base, String *derived); extern List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix); extern void Swig_inherit_base_symbols(List *bases); extern int Swig_need_protected(Node *n); - extern int Swig_need_name_warning(Node *n); extern int Swig_need_redefined_warn(Node *a, Node *b, int InClass); extern String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname); |