summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CParse/parser.y63
-rw-r--r--Source/Include/swigwarn.h2
-rw-r--r--Source/Makefile.am1
-rw-r--r--Source/Modules/allegrocl.cxx12
-rw-r--r--Source/Modules/allocate.cxx2
-rw-r--r--Source/Modules/cffi.cxx5
-rw-r--r--Source/Modules/clisp.cxx3
-rw-r--r--Source/Modules/csharp.cxx440
-rw-r--r--Source/Modules/d.cxx63
-rw-r--r--Source/Modules/go.cxx18
-rw-r--r--Source/Modules/interface.cxx183
-rw-r--r--Source/Modules/java.cxx447
-rw-r--r--Source/Modules/lang.cxx32
-rw-r--r--Source/Modules/lua.cxx6
-rw-r--r--Source/Modules/modula3.cxx30
-rw-r--r--Source/Modules/ocaml.cxx3
-rw-r--r--Source/Modules/octave.cxx1
-rw-r--r--Source/Modules/overload.cxx16
-rw-r--r--Source/Modules/perl5.cxx2
-rw-r--r--Source/Modules/php.cxx7
-rw-r--r--Source/Modules/python.cxx137
-rw-r--r--Source/Modules/r.cxx12
-rw-r--r--Source/Modules/ruby.cxx29
-rw-r--r--Source/Modules/scilab.cxx8
-rw-r--r--Source/Modules/swigmod.h12
-rw-r--r--Source/Modules/typepass.cxx10
-rw-r--r--Source/Swig/include.c1
-rw-r--r--Source/Swig/misc.c75
-rw-r--r--Source/Swig/naming.c260
-rw-r--r--Source/Swig/swig.h2
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);