Merge branch 'master' into gsoc2017-php7-classes-via-c-api

This commit is contained in:
Olly Betts 2021-03-25 17:45:17 +13:00
commit 8ded9d8dae
1906 changed files with 50934 additions and 30001 deletions

View file

@ -471,7 +471,7 @@ void add_defined_foreign_type(Node *n, int overwrite = 0, String *k = 0,
// a synonym type was found (held in variable 'match')
// Printf(stderr, "setting primary synonym of %p to %p\n", new_node, match);
if (new_node == match)
Printf(stderr, "Hey-4 * - '%s' is a synonym of iteself!\n", Getattr(new_node, "name"));
Printf(stderr, "Hey-4 * - '%s' is a synonym of itself!\n", Getattr(new_node, "name"));
Setattr(new_node, "allegrocl:synonym-of", match);
// Printf(stderr,"*** 4\n");
add_linked_type(new_node);
@ -1685,285 +1685,6 @@ int ALLEGROCL::top(Node *n) {
return SWIG_OK;
}
/* very shamelessly 'borrowed' from overload.cxx, which
keeps the below Swig_overload_rank() code to itself.
We don't need a dispatch function in the C++ wrapper
code; we want it over on the lisp side. */
#define Swig_overload_rank Allegrocl_swig_overload_rank
#define MAX_OVERLOAD 256
/* Overload "argc" and "argv" */
// String *argv_template_string;
// String *argc_template_string;
struct Overloaded {
Node *n; /* Node */
int argc; /* Argument count */
ParmList *parms; /* Parameters used for overload check */
int error; /* Ambiguity error */
};
/* -----------------------------------------------------------------------------
* Swig_overload_rank()
*
* This function takes an overloaded declaration and creates a list that ranks
* all overloaded methods in an order that can be used to generate a dispatch
* function.
* Slight difference in the way this function is used by scripting languages and
* statically typed languages. The script languages call this method via
* Swig_overload_dispatch() - where wrappers for all overloaded methods are generated,
* however sometimes the code can never be executed. The non-scripting languages
* call this method via Swig_overload_check() for each overloaded method in order
* to determine whether or not the method should be wrapped. Note the slight
* difference when overloading methods that differ by const only. The
* scripting languages will ignore the const method, whereas the non-scripting
* languages ignore the first method parsed.
* ----------------------------------------------------------------------------- */
static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
Overloaded nodes[MAX_OVERLOAD];
int nnodes = 0;
Node *o = Getattr(n, "sym:overloaded");
Node *c;
if (!o)
return 0;
c = o;
while (c) {
if (Getattr(c, "error")) {
c = Getattr(c, "sym:nextSibling");
continue;
}
/* if (SmartPointer && Getattr(c,"cplus:staticbase")) {
c = Getattr(c,"sym:nextSibling");
continue;
} */
/* Make a list of all the declarations (methods) that are overloaded with
* this one particular method name */
if (Getattr(c, "wrap:name")) {
nodes[nnodes].n = c;
nodes[nnodes].parms = Getattr(c, "wrap:parms");
nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
nodes[nnodes].error = 0;
nnodes++;
}
c = Getattr(c, "sym:nextSibling");
}
/* Sort the declarations by required argument count */
{
int i, j;
for (i = 0; i < nnodes; i++) {
for (j = i + 1; j < nnodes; j++) {
if (nodes[i].argc > nodes[j].argc) {
Overloaded t = nodes[i];
nodes[i] = nodes[j];
nodes[j] = t;
}
}
}
}
/* Sort the declarations by argument types */
{
int i, j;
for (i = 0; i < nnodes - 1; i++) {
if (nodes[i].argc == nodes[i + 1].argc) {
for (j = i + 1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
Parm *p1 = nodes[i].parms;
Parm *p2 = nodes[j].parms;
int differ = 0;
int num_checked = 0;
while (p1 && p2 && (num_checked < nodes[i].argc)) {
// Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
if (checkAttribute(p1, "tmap:in:numinputs", "0")) {
p1 = Getattr(p1, "tmap:in:next");
continue;
}
if (checkAttribute(p2, "tmap:in:numinputs", "0")) {
p2 = Getattr(p2, "tmap:in:next");
continue;
}
String *t1 = Getattr(p1, "tmap:typecheck:precedence");
String *t2 = Getattr(p2, "tmap:typecheck:precedence");
if ((!t1) && (!nodes[i].error)) {
Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
"Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0));
nodes[i].error = 1;
} else if ((!t2) && (!nodes[j].error)) {
Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
"Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n",
Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0));
nodes[j].error = 1;
}
if (t1 && t2) {
int t1v, t2v;
t1v = atoi(Char(t1));
t2v = atoi(Char(t2));
differ = t1v - t2v;
} else if (!t1 && t2)
differ = 1;
else if (t1 && !t2)
differ = -1;
else if (!t1 && !t2)
differ = -1;
num_checked++;
if (differ > 0) {
Overloaded t = nodes[i];
nodes[i] = nodes[j];
nodes[j] = t;
break;
} else if ((differ == 0) && (Strcmp(t1, "0") == 0)) {
t1 = Getattr(p1, "ltype");
if (!t1) {
t1 = SwigType_ltype(Getattr(p1, "type"));
if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) {
SwigType_add_pointer(t1);
}
Setattr(p1, "ltype", t1);
}
t2 = Getattr(p2, "ltype");
if (!t2) {
t2 = SwigType_ltype(Getattr(p2, "type"));
if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) {
SwigType_add_pointer(t2);
}
Setattr(p2, "ltype", t2);
}
/* Need subtype check here. If t2 is a subtype of t1, then we need to change the
order */
if (SwigType_issubtype(t2, t1)) {
Overloaded t = nodes[i];
nodes[i] = nodes[j];
nodes[j] = t;
}
if (Strcmp(t1, t2) != 0) {
differ = 1;
break;
}
} else if (differ) {
break;
}
if (Getattr(p1, "tmap:in:next")) {
p1 = Getattr(p1, "tmap:in:next");
} else {
p1 = nextSibling(p1);
}
if (Getattr(p2, "tmap:in:next")) {
p2 = Getattr(p2, "tmap:in:next");
} else {
p2 = nextSibling(p2);
}
}
if (!differ) {
/* See if declarations differ by const only */
String *d1 = Getattr(nodes[i].n, "decl");
String *d2 = Getattr(nodes[j].n, "decl");
if (d1 && d2) {
String *dq1 = Copy(d1);
String *dq2 = Copy(d2);
if (SwigType_isconst(d1)) {
Delete(SwigType_pop(dq1));
}
if (SwigType_isconst(d2)) {
Delete(SwigType_pop(dq2));
}
if (Strcmp(dq1, dq2) == 0) {
if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
if (script_lang_wrapping) {
// Swap nodes so that the const method gets ignored (shadowed by the non-const method)
Overloaded t = nodes[i];
nodes[i] = nodes[j];
nodes[j] = t;
}
differ = 1;
if (!nodes[j].error) {
if (script_lang_wrapping) {
Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
"Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].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")) {
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;
} else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) {
differ = 1;
if (!nodes[j].error) {
if (script_lang_wrapping) {
Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
"Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].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")) {
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;
}
}
Delete(dq1);
Delete(dq2);
}
}
if (!differ) {
if (!nodes[j].error) {
if (script_lang_wrapping) {
Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
"Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].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")) {
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;
}
}
}
}
}
}
List *result = NewList();
{
int i;
for (i = 0; i < nnodes; i++) {
if (nodes[i].error)
Setattr(nodes[i].n, "overload:ignore", "1");
Append(result, nodes[i].n);
// Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms));
// Swig_print_node(nodes[i].n);
}
}
return result;
}
/* end shameless borrowing */
int any_varargs(ParmList *pl) {
Parm *p;

View file

@ -504,7 +504,7 @@ class Allocate:public Dispatcher {
in emit.cxx
and is either constructued from the "feature:catches" feature
and is either constructed from the "feature:catches" feature
or copied from the node "throws" list.
*/
String *scatchlist = Getattr(n, "feature:catches");

View file

@ -547,7 +547,7 @@ int CHICKEN::functionWrapper(Node *n) {
}
emit_return_variable(n, d, f);
/* Insert the argumetn output code */
/* Insert the argument output code */
Printv(f->code, argout, NIL);
/* Output cleanup code */
@ -1456,7 +1456,7 @@ String *CHICKEN::chickenPrimitiveName(String *name) {
if (value)
return value;
else {
Swig_error(input_file, line_number, "Internal Error: attempting to reference non-existant primitive name %s\n", name);
Swig_error(input_file, line_number, "Internal Error: attempting to reference non-existent primitive name %s\n", name);
return NewString("#f");
}
}

View file

@ -68,8 +68,8 @@ class CSHARP:public Language {
String *module_baseclass; //inheritance for module class from %pragma
String *imclass_interfaces; //interfaces for intermediary class class from %pragma
String *module_interfaces; //interfaces for module class from %pragma
String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma
String *module_class_modifiers; //class modifiers for module class overriden by %pragma
String *imclass_class_modifiers; //class modifiers for intermediary class overridden by %pragma
String *module_class_modifiers; //class modifiers for module class overridden by %pragma
String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
String *director_callback_typedefs; // Director function pointer typedefs for callbacks
@ -1384,7 +1384,7 @@ public:
// Wrap C/C++ enums with constant integers or use the typesafe enum pattern
SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum ");
Setattr(n, "type", typemap_lookup_type);
const String *tm = typemapLookup(n, "cstype", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF);
const String *tm = typemapLookup(n, "cstype", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF);
String *return_type = Copy(tm);
substituteClassname(typemap_lookup_type, return_type);
@ -1533,7 +1533,7 @@ public:
if (classname_substituted_flag) {
if (SwigType_isenum(t)) {
// This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
Printf(constants_code, "(%s)%s.%s();\n", return_type, full_imclass_name, Swig_name_get(getNSpace(), symname));
Printf(constants_code, "(%s)%s.%s();\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
} else {
// This handles function pointers using the %constant directive
Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
@ -1709,11 +1709,11 @@ public:
* addInterfaceNameAndUpcasts()
* ----------------------------------------------------------------------------- */
void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, SwigType *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"));
SwigType *c_baseclassname = Getattr(base, "name");
String *interface_name = Getattr(base, "interface:name");
if (Len(interface_list))
Append(interface_list, ", ");
@ -1732,13 +1732,12 @@ public:
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);
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
Delete(upcast_method_name);
Delete(cptr_method_name);
Delete(interface_code);
Delete(c_baseclass);
}
Delete(keys);
}
@ -1749,7 +1748,7 @@ public:
* Add code for C++ casting to base class
* ----------------------------------------------------------------------------- */
void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) {
void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) {
String *wname = Swig_name_wrapper(upcast_method_name);
Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
@ -1757,28 +1756,35 @@ public:
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
String *classname = SwigType_namestr(c_classname);
String *baseclassname = SwigType_namestr(c_baseclassname);
if (smart) {
SwigType *bsmart = 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);
String *bsmartnamestr = SwigType_namestr(smart);
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
Printv(upcasts_code,
"SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
" return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
"}\n", "\n", NIL);
Delete(rbaseclassname);
Delete(rclassname);
Delete(bsmartnamestr);
Delete(smartnamestr);
Delete(bsmart);
} else {
Printv(upcasts_code,
"SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n",
" return (", c_baseclass, " *)jarg1;\n"
"SWIGEXPORT ", baseclassname, " * SWIGSTDCALL ", wname, "(", classname, " *jarg1) {\n",
" return (", baseclassname, " *)jarg1;\n"
"}\n", "\n", NIL);
}
Delete(baseclassname);
Delete(classname);
Delete(wname);
}
@ -1787,10 +1793,9 @@ public:
* ----------------------------------------------------------------------------- */
void emitProxyClassDefAndCPPCasts(Node *n) {
String *c_classname = SwigType_namestr(Getattr(n, "name"));
String *c_baseclass = NULL;
SwigType *c_classname = Getattr(n, "name");
SwigType *c_baseclassname = NULL;
String *baseclass = NULL;
String *c_baseclassname = NULL;
String *interface_list = NewStringEmpty();
String *interface_upcasts = NewStringEmpty();
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
@ -1812,12 +1817,13 @@ public:
Iterator base = First(baselist);
while (base.item) {
if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
String *baseclassname = Getattr(base.item, "name");
SwigType *baseclassname = Getattr(base.item, "name");
if (!c_baseclassname) {
c_baseclassname = baseclassname;
baseclass = Copy(getProxyName(baseclassname));
if (baseclass)
c_baseclass = SwigType_namestr(baseclassname);
String *name = getProxyName(baseclassname);
if (name) {
c_baseclassname = baseclassname;
baseclass = name;
}
} else {
/* Warn about multiple inheritance for additional base class(es) */
String *proxyclassname = Getattr(n, "classtypeobj");
@ -1833,7 +1839,7 @@ public:
if (interface_bases)
addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
bool derived = baseclass && getProxyName(c_baseclassname);
bool derived = baseclass != 0;
if (derived && purebase_notderived)
pure_baseclass = empty_string;
const String *wanted_base = baseclass ? baseclass : pure_baseclass;
@ -1841,7 +1847,6 @@ public:
if (purebase_replace) {
wanted_base = pure_baseclass;
derived = false;
Delete(baseclass);
baseclass = NULL;
if (purebase_notderived)
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);
@ -1873,46 +1878,70 @@ public:
typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
NIL);
// C++ destructor is wrapped by the Dispose method
// Note that the method name is specified in a typemap attribute called methodname
// C++ destructor is wrapped by the Finalize and Dispose methods
const char *tmap_method = derived ? "csdestruct_derived" : "csdestruct";
const String *tm = typemapExists(n, tmap_method, typemap_lookup_type);
if (tm) {
Swig_error(Getfile(tm), Getline(tm),
"A deprecated %s typemap was found for %s, please remove it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.\n",
tmap_method, proxy_class_name);
}
tmap_method = "csfinalize";
tm = typemapExists(n, tmap_method, typemap_lookup_type);
if (tm) {
Swig_error(Getfile(tm), Getline(tm),
"A deprecated %s typemap was found for %s, please remove it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.\n",
tmap_method, proxy_class_name);
}
tmap_method = derived ? "csdisposing_derived" : "csdisposing";
String *destruct = NewString("");
const String *tm = NULL;
attributes = NewHash();
String *destruct_methodname = NULL;
String *destruct_methodmodifiers = NULL;
const String *destruct_methodname = NULL;
const String *destruct_methodmodifiers = NULL;
const String *destruct_parameters = NULL;
if (derived) {
tm = typemapLookup(n, "csdestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:csdestruct_derived:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:csdestruct_derived:methodmodifiers");
tm = typemapLookup(n, "csdisposing_derived", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:csdisposing_derived:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:csdisposing_derived:methodmodifiers");
destruct_parameters = Getattr(attributes, "tmap:csdisposing_derived:parameters");
} else {
tm = typemapLookup(n, "csdestruct", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:csdestruct:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:csdestruct:methodmodifiers");
tm = typemapLookup(n, "csdisposing", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:csdisposing:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:csdisposing:methodmodifiers");
destruct_parameters = Getattr(attributes, "tmap:csdisposing:parameters");
}
if (tm && *Char(tm)) {
if (!destruct_methodname) {
Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in csdestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in %s typemap for %s\n", tmap_method, proxy_class_name);
}
if (!destruct_methodmodifiers) {
Swig_error(Getfile(n), Getline(n),
"No methodmodifiers attribute defined in csdestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name);
"No methodmodifiers attribute defined in %s typemap for %s.\n", tmap_method, proxy_class_name);
}
if (!destruct_parameters)
destruct_parameters = empty_string;
}
// Emit the Finalize and Dispose methods
if (tm) {
// Finalize method
if (*Char(destructor_call)) {
Printv(proxy_class_def, typemapLookup(n, "csfinalize", typemap_lookup_type, WARN_NONE), NIL);
}
// Dispose method
// Finalize and Dispose methods
Printv(proxy_class_def, typemapLookup(n, derived ? "csdispose_derived" : "csdispose", typemap_lookup_type, WARN_NONE), NIL);
// Dispose(bool disposing) method
Printv(destruct, tm, NIL);
if (*Char(destructor_call))
Replaceall(destruct, "$imcall", destructor_call);
else
Replaceall(destruct, "$imcall", "throw new global::System.MethodAccessException(\"C++ destructor does not have public access\")");
if (*Char(destruct))
Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n",
NIL);
if (*Char(destruct)) {
Printv(proxy_class_def, "\n ", NIL);
const String *methodmods = Getattr(n, "destructmethodmodifiers");
if (methodmods)
Printv(proxy_class_def, methodmods, NIL);
else
Printv(proxy_class_def, destruct_methodmodifiers, " ", derived ? "override" : "virtual", NIL);
Printv(proxy_class_def, " void ", destruct_methodname, "(", destruct_parameters, ") ", destruct, "\n", NIL);
}
}
if (*Char(interface_upcasts))
Printv(proxy_class_def, interface_upcasts, NIL);
@ -1929,7 +1958,7 @@ public:
String *methid = Getattr(udata, "class_methodidx");
String *overname = Getattr(udata, "overname");
Printf(proxy_class_code, " if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s))\n", method, methid);
Printf(proxy_class_code, " swigDelegate%s = new SwigDelegate%s_%s(SwigDirector%s);\n", methid, proxy_class_name, methid, overname);
Printf(proxy_class_code, " swigDelegate%s = new SwigDelegate%s_%s(SwigDirectorMethod%s);\n", methid, proxy_class_name, methid, overname);
}
String *director_connect_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
Printf(proxy_class_code, " %s.%s(swigCPtr", imclass_name, director_connect_method_name);
@ -2008,12 +2037,11 @@ public:
if (derived) {
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
Delete(upcast_method_name);
}
Delete(smart);
Delete(baseclass);
}
/* ----------------------------------------------------------------------
@ -2022,7 +2050,8 @@ public:
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);
Printv(f_interface, typemapLookup(n, "csinterfacemodifiers", Getattr(n, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL);
Printf(f_interface, " %s", interface_name);
if (List *baselist = Getattr(n, "bases")) {
String *bases = 0;
for (Iterator base = First(baselist); base.item; base = Next(base)) {
@ -2782,7 +2811,8 @@ public:
/* Insert the csconstruct typemap, doing the replacement for $directorconnect, as needed */
Hash *attributes = NewHash();
String *construct_tm = Copy(typemapLookup(n, "csconstruct", Getattr(n, "name"),
String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj");
String *construct_tm = Copy(typemapLookup(n, "csconstruct", typemap_lookup_type,
WARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF, attributes));
if (construct_tm) {
if (!feature_director) {
@ -2860,7 +2890,11 @@ public:
if (proxy_flag) {
Printv(destructor_call, full_imclass_name, ".", Swig_name_destroy(getNSpace(), symname), "(swigCPtr)", NIL);
const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
if (methodmods)
Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods);
}
return SWIG_OK;
}
@ -3541,6 +3575,24 @@ public:
return tm;
}
/* -----------------------------------------------------------------------------
* typemapExists()
* n - for input only and must contain info for Getfile(n) and Getline(n) to work
* tmap_method - typemap method name
* type - typemap type to lookup
* returns found typemap or NULL if not found
* ----------------------------------------------------------------------------- */
const String *typemapExists(Node *n, const_String_or_char_ptr tmap_method, SwigType *type) {
Node *node = NewHash();
Setattr(node, "type", type);
Setfile(node, Getfile(n));
Setline(node, Getline(n));
const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
Delete(node);
return tm;
}
/* -----------------------------------------------------------------------------
* canThrow()
* Determine whether the code in the typemap can throw a C# exception.
@ -3811,15 +3863,17 @@ public:
/* If returning a reference, initialize the pointer to a sane
default - if a C# exception occurs, then the pointer returns
something other than a NULL-initialized reference. */
String *non_ref_type = Copy(returntype);
SwigType *noref_type = SwigType_del_reference(Copy(returntype));
String *noref_ltype = SwigType_lstr(noref_type, 0);
String *return_ltype = SwigType_lstr(returntype, 0);
/* Remove reference and const qualifiers */
Replaceall(non_ref_type, "r.", "");
Replaceall(non_ref_type, "q(const).", "");
Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
Delete(non_ref_type);
Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
Printf(w->code, "c_result = &result_default;\n");
Delete(return_ltype);
Delete(noref_ltype);
Delete(noref_type);
}
Delete(base_typename);
@ -3851,7 +3905,7 @@ public:
Printf(director_delegate_definitions, " %s\n", im_directoroutattributes);
}
Printf(callback_def, " private %s SwigDirector%s(", tm, overloaded_name);
Printf(callback_def, " private %s SwigDirectorMethod%s(", tm, overloaded_name);
if (!ignored_method) {
const String *csdirectordelegatemodifiers = Getattr(n, "feature:csdirectordelegatemodifiers");
String *modifiers = (csdirectordelegatemodifiers ? NewStringf("%s%s", csdirectordelegatemodifiers, Len(csdirectordelegatemodifiers) > 0 ? " " : "") : NewStringf("public "));
@ -3881,7 +3935,7 @@ public:
Swig_typemap_attach_parms("ctype", l, 0);
Swig_typemap_attach_parms("imtype", l, 0);
Swig_typemap_attach_parms("cstype", l, 0);
Swig_typemap_attach_parms("directorin", l, 0);
Swig_typemap_attach_parms("directorin", l, w);
Swig_typemap_attach_parms("csdirectorin", l, 0);
Swig_typemap_attach_parms("directorargout", l, w);
@ -4015,11 +4069,10 @@ public:
/* Get the C# parameter type */
if ((tm = Getattr(p, "tmap:cstype"))) {
substituteClassname(pt, tm);
if (Strncmp(tm, "ref ", 4) == 0) {
Replace(tm, "ref ", "", DOH_REPLACE_FIRST);
int flags = DOH_REPLACE_FIRST | DOH_REPLACE_ID_BEGIN | DOH_REPLACE_NOCOMMENT;
if (Replace(tm, "ref ", "", flags) || Replace(tm, "ref\t", "", flags)) {
Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
} else if (Strncmp(tm, "out ", 4) == 0) {
Replace(tm, "out ", "", DOH_REPLACE_FIRST);
} else if (Replace(tm, "out ", "", flags) || Replace(tm, "out\t", "", flags)) {
Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
} else {
Printf(proxy_method_types, "typeof(%s)", tm);
@ -4062,11 +4115,11 @@ public:
/* header declaration, start wrapper definition */
String *target;
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
target = Swig_method_decl(rtype, decl, name, l, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
@ -4283,7 +4336,7 @@ public:
/* constructor */
{
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
String *call = Swig_csuperclass_call(0, basetype, superparms);
Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor"));
@ -4296,7 +4349,7 @@ public:
/* constructor header */
{
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 1);
String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@ -4396,8 +4449,8 @@ public:
Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirclassname);
Printf(w->def, "%s::~%s() noexcept {\n", dirclassname, dirclassname);
} else if (Getattr(n, "throw")) {
Printf(f_directors_h, " virtual ~%s() throw ();\n", dirclassname);
Printf(w->def, "%s::~%s() throw () {\n", dirclassname, dirclassname);
Printf(f_directors_h, " virtual ~%s() throw();\n", dirclassname);
Printf(w->def, "%s::~%s() throw() {\n", dirclassname, dirclassname);
} else {
Printf(f_directors_h, " virtual ~%s();\n", dirclassname);
Printf(w->def, "%s::~%s() {\n", dirclassname, dirclassname);

View file

@ -989,7 +989,7 @@ public:
// Smart pointer classes do not mirror the inheritance hierarchy of the
// underlying types, so aliasing the base class methods in is not required
// for them.
// DMD BUG: We have to emit the alias after the last function becasue
// DMD BUG: We have to emit the alias after the last function because
// taking a delegate in the overload checking code fails otherwise
// (http://d.puremagic.com/issues/show_bug.cgi?id=4860).
if (!Getattr(n, "sym:nextSibling") && !is_smart_pointer() &&
@ -1227,8 +1227,9 @@ public:
// Insert the dconstructor typemap (replacing $directorconnect as needed).
Hash *attributes = NewHash();
String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj");
String *construct_tm = Copy(lookupCodeTypemap(n, "dconstructor",
Getattr(n, "name"), WARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF, attributes));
typemap_lookup_type, WARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF, attributes));
if (construct_tm) {
const bool use_director = (parentNode(n) && Swig_directorclass(n));
if (!use_director) {
@ -1298,7 +1299,12 @@ public:
virtual int destructorHandler(Node *n) {
Language::destructorHandler(n);
String *symname = Getattr(n, "sym:name");
Printv(destructor_call, im_dmodule_fq_name, ".", Swig_name_destroy(getNSpace(),symname), "(cast(void*)swigCPtr)", NIL);
const String *methodmods = Getattr(n, "feature:d:methodmodifiers");
if (methodmods)
Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods);
return SWIG_OK;
}
@ -1476,7 +1482,7 @@ public:
}
Delete(attributes);
// Retrive the override value set via %dconstvalue, if any.
// Retrieve the override value set via %dconstvalue, if any.
String *override_value = Getattr(n, "feature:d:constvalue");
if (override_value) {
Printf(constants_code, "%s;\n", override_value);
@ -1995,15 +2001,17 @@ public:
/* If returning a reference, initialize the pointer to a sane
default - if a D exception occurs, then the pointer returns
something other than a NULL-initialized reference. */
String *non_ref_type = Copy(returntype);
SwigType *noref_type = SwigType_del_reference(Copy(returntype));
String *noref_ltype = SwigType_lstr(noref_type, 0);
String *return_ltype = SwigType_lstr(returntype, 0);
/* Remove reference and const qualifiers */
Replaceall(non_ref_type, "r.", "");
Replaceall(non_ref_type, "q(const).", "");
Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
Delete(non_ref_type);
Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
Printf(w->code, "c_result = &result_default;\n");
Delete(return_ltype);
Delete(noref_ltype);
Delete(noref_type);
}
Delete(base_typename);
@ -2058,7 +2066,7 @@ public:
Swig_typemap_attach_parms("ctype", l, 0);
Swig_typemap_attach_parms("imtype", l, 0);
Swig_typemap_attach_parms("dtype", l, 0);
Swig_typemap_attach_parms("directorin", l, 0);
Swig_typemap_attach_parms("directorin", l, w);
Swig_typemap_attach_parms("ddirectorin", l, 0);
Swig_typemap_attach_parms("directorargout", l, w);
@ -2212,11 +2220,11 @@ public:
/* header declaration, start wrapper definition */
String *target;
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
target = Swig_method_decl(rtype, decl, name, l, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
@ -2436,7 +2444,7 @@ public:
/* constructor */
{
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
String *call = Swig_csuperclass_call(0, basetype, superparms);
String *classtype = SwigType_namestr(Getattr(n, "name"));
@ -2451,7 +2459,7 @@ public:
/* constructor header */
{
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 1);
String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@ -2495,8 +2503,8 @@ public:
Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirclassname);
Printf(w->def, "%s::~%s() noexcept {\n", dirclassname, dirclassname);
} else if (Getattr(n, "throw")) {
Printf(f_directors_h, " virtual ~%s() throw ();\n", dirclassname);
Printf(w->def, "%s::~%s() throw () {\n", dirclassname, dirclassname);
Printf(f_directors_h, " virtual ~%s() throw();\n", dirclassname);
Printf(w->def, "%s::~%s() throw() {\n", dirclassname, dirclassname);
} else {
Printf(f_directors_h, " virtual ~%s();\n", dirclassname);
Printf(w->def, "%s::~%s() {\n", dirclassname, dirclassname);
@ -3132,11 +3140,10 @@ private:
* Handle inheriting from D and C++ classes.
*/
String *c_classname = SwigType_namestr(Getattr(n, "name"));
String *c_baseclass = NULL;
Node *basenode = NULL;
String *basename = NULL;
String *c_classname = Getattr(n, "name");
String *c_baseclassname = NULL;
Node *basenode = NULL;
String *baseclass = NULL;
// Inheritance from pure D classes.
Node *attributes = NewHash();
@ -3153,13 +3160,14 @@ private:
Iterator base = First(baselist);
while (base.item) {
if (!GetFlag(base.item, "feature:ignore")) {
String *baseclassname = Getattr(base.item, "name");
SwigType *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);
String *name = createProxyName(baseclassname);
if (name) {
c_baseclassname = baseclassname;
baseclass = name;
}
} else {
/* Warn about multiple inheritance for additional base class(es) */
String *proxyclassname = Getattr(n, "classtypeobj");
@ -3172,25 +3180,24 @@ private:
}
}
bool derived = (basename != NULL);
bool derived = baseclass != NULL;
if (derived && purebase_notderived) {
pure_baseclass = empty_string;
}
const String *wanted_base = basename ? basename : pure_baseclass;
const String *wanted_base = baseclass ? baseclass : pure_baseclass;
if (purebase_replace) {
wanted_base = pure_baseclass;
derived = false;
basenode = NULL;
Delete(basename);
basename = NULL;
baseclass = NULL;
if (purebase_notderived) {
Swig_error(Getfile(n), Getline(n),
"The dbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n",
typemap_lookup_type);
}
} else if (basename && Len(pure_baseclass) > 0) {
} else if (baseclass && Len(pure_baseclass) > 0) {
Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
"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);
@ -3198,7 +3205,7 @@ private:
// Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
if (derived) {
writeClassUpcast(n, proxy_class_name, c_classname, c_baseclass);
writeClassUpcast(n, proxy_class_name, c_classname, c_baseclassname);
}
/*
@ -3266,17 +3273,20 @@ private:
// attribute called »methodname«.
const String *tm = NULL;
String *dispose_methodname;
String *dispose_methodmodifiers;
const String *dispose_methodname;
const String *dispose_methodmodifiers;
const String *dispose_parameters;
attributes = NewHash();
if (derived) {
tm = lookupCodeTypemap(n, "ddispose_derived", typemap_lookup_type, WARN_NONE, attributes);
dispose_methodname = Getattr(attributes, "tmap:ddispose_derived:methodname");
dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose_derived:methodmodifiers");
dispose_parameters = Getattr(attributes, "tmap:ddispose_derived:parameters");
} else {
tm = lookupCodeTypemap(n, "ddispose", typemap_lookup_type, WARN_NONE, attributes);
dispose_methodname = Getattr(attributes, "tmap:ddispose:methodname");
dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose:methodmodifiers");
dispose_parameters = Getattr(attributes, "tmap:ddispose:parameters");
}
if (tm && *Char(tm)) {
@ -3290,6 +3300,8 @@ private:
"No methodmodifiers attribute defined in ddispose%s typemap for %s.\n",
(derived ? "_derived" : ""), proxy_class_name);
}
if (!dispose_parameters)
dispose_parameters = empty_string;
}
if (tm) {
@ -3310,9 +3322,13 @@ private:
}
if (*Char(dispose_code)) {
Printv(body, "\n", dispose_methodmodifiers,
(derived ? " override" : ""), " void ", dispose_methodname, "() ",
dispose_code, "\n", NIL);
Printv(body, "\n", NIL);
const String *methodmods = Getattr(n, "destructmethodmodifiers");
if (methodmods)
Printv(body, methodmods, NIL);
else
Printv(body, dispose_methodmodifiers, (derived ? " override" : ""), NIL);
Printv(body, " void ", dispose_methodname, "(", dispose_parameters, ") ", dispose_code, "\n", NIL);
}
}
@ -3337,8 +3353,7 @@ private:
// Write the class body and the curly bracket closing the class definition
// to the proxy module.
indentCode(body);
Replaceall(body, "$dbaseclass", basename);
Delete(basename);
Replaceall(body, "$dbaseclass", baseclass);
Printv(proxy_class_code, body, "\n}\n", NIL);
Delete(body);
@ -3351,7 +3366,7 @@ private:
/* ---------------------------------------------------------------------------
* D::writeClassUpcast()
* --------------------------------------------------------------------------- */
void writeClassUpcast(Node *n, const String* d_class_name, String* c_class_name, String* c_base_name) {
void writeClassUpcast(Node *n, const String* d_class_name, SwigType* c_classname, SwigType* c_baseclassname) {
SwigType *smart = Swig_cparse_smartptr(n);
String *upcast_name = Swig_name_member(getNSpace(), d_class_name, (smart != 0 ? "SmartPtrUpcast" : "Upcast"));
@ -3360,36 +3375,42 @@ private:
writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)",
upcast_wrapper_name);
String *classname = SwigType_namestr(c_classname);
String *baseclassname = SwigType_namestr(c_baseclassname);
if (smart) {
SwigType *bsmart = Copy(smart);
SwigType *rclassname = SwigType_typedef_resolve_all(c_class_name);
SwigType *rbaseclass = SwigType_typedef_resolve_all(c_base_name);
Replaceall(bsmart, rclassname, rbaseclass);
Delete(rclassname);
Delete(rbaseclass);
String *smartnamestr = SwigType_namestr(smart);
String *bsmartnamestr = SwigType_namestr(bsmart);
String *bsmartnamestr = SwigType_namestr(smart);
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
Printv(upcasts_code,
"SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name,
"(", smartnamestr, " *objectRef) {\n",
" return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n"
"}\n",
"\n", NIL);
Delete(rbaseclassname);
Delete(rclassname);
Delete(bsmartnamestr);
Delete(smartnamestr);
Delete(bsmart);
} else {
Printv(upcasts_code,
"SWIGEXPORT ", c_base_name, " * ", upcast_wrapper_name,
"(", c_base_name, " *objectRef) {\n",
" return (", c_base_name, " *)objectRef;\n"
"SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name,
"(", baseclassname, " *objectRef) {\n",
" return (", baseclassname, " *)objectRef;\n"
"}\n",
"\n", NIL);
}
Replaceall(upcasts_code, "$cclass", c_class_name);
Replaceall(upcasts_code, "$cbaseclass", c_base_name);
Replaceall(upcasts_code, "$cclass", classname);
Replaceall(upcasts_code, "$cbaseclass", baseclassname);
Delete(baseclassname);
Delete(classname);
Delete(upcast_name);
Delete(upcast_wrapper_name);
Delete(smart);
@ -4341,7 +4362,7 @@ private:
*
* Determines whether the class the passed function node belongs to overrides
* all the overlaods for the passed function node defined somewhere up the
* inheritance hierachy.
* inheritance hierarchy.
* --------------------------------------------------------------------------- */
bool areAllOverloadsOverridden(Node *n) const {
List *base_list = Getattr(parentNode(n), "bases");
@ -4366,7 +4387,7 @@ private:
}
// We try to find at least a single overload which exists in the base class
// so we can progress up the inheritance hierachy even if there have been
// so we can progress up the inheritance hierarchy even if there have been
// new overloads introduced after the topmost class.
Node *base_function = NULL;
String *symname = Getattr(n, "sym:name");
@ -4392,7 +4413,7 @@ private:
!(Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode())) {
// If the base class function is »protected« and were are not in
// director mode, it is not emitted to the base class and thus we do
// not count it. Otherwise, we would run into issues if the visiblity
// not count it. Otherwise, we would run into issues if the visibility
// of some functions was changed from protected to public in a child
// class with the using directive.
continue;

View file

@ -15,12 +15,12 @@
#include "swigmod.h"
/* Swig_csuperclass_call()
/* -----------------------------------------------------------------------------
* Swig_csuperclass_call()
*
* Generates a fully qualified method call, including the full parameter list.
* e.g. "base::method(i, j)"
*
*/
* ----------------------------------------------------------------------------- */
String *Swig_csuperclass_call(String *base, String *method, ParmList *l) {
String *call = NewString("");
@ -44,12 +44,12 @@ String *Swig_csuperclass_call(String *base, String *method, ParmList *l) {
return call;
}
/* Swig_class_declaration()
/* -----------------------------------------------------------------------------
* Swig_class_declaration()
*
* Generate the start of a class/struct declaration.
* e.g. "class myclass"
*
*/
* ----------------------------------------------------------------------------- */
String *Swig_class_declaration(Node *n, String *name) {
if (!name) {
@ -61,18 +61,22 @@ String *Swig_class_declaration(Node *n, String *name) {
return result;
}
/* -----------------------------------------------------------------------------
* Swig_class_name()
* ----------------------------------------------------------------------------- */
String *Swig_class_name(Node *n) {
String *name;
name = Copy(Getattr(n, "sym:name"));
return name;
}
/* Swig_director_declaration()
/* -----------------------------------------------------------------------------
* Swig_director_declaration()
*
* Generate the full director class declaration, complete with base classes.
* e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
*
*/
* ----------------------------------------------------------------------------- */
String *Swig_director_declaration(Node *n) {
String *classname = Swig_class_name(n);
@ -87,6 +91,10 @@ String *Swig_director_declaration(Node *n) {
}
/* -----------------------------------------------------------------------------
* Swig_method_call()
* ----------------------------------------------------------------------------- */
String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
String *func;
int i = 0;
@ -115,153 +123,63 @@ String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
return func;
}
/* Swig_method_decl
/* -----------------------------------------------------------------------------
* Swig_method_decl()
*
* Misnamed and misappropriated! Taken from SWIG's type string manipulation utilities
* and modified to generate full (or partial) type qualifiers for method declarations,
* local variable declarations, and return value casting. More importantly, it merges
* parameter type information with actual parameter names to produce a complete method
* declaration that fully mirrors the original method declaration.
*
* There is almost certainly a saner way to do this.
*
* This function needs to be cleaned up and possibly split into several smaller
* functions. For instance, attaching default names to parameters should be done in a
* separate function.
*
*/
* Return a stringified version of a C/C++ declaration.
* ----------------------------------------------------------------------------- */
String *Swig_method_decl(SwigType *rettype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values) {
String *result;
List *elements;
String *element = 0, *nextelement;
int is_const = 0;
int nelements, i;
int is_func = 0;
String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args) {
String *result = NewString("");
bool conversion_operator = Strstr(id, "operator ") != 0 && !return_base_type;
Parm *parm = args;
int arg_idx = 0;
if (id) {
result = NewString(Char(id));
} else {
result = NewString("");
}
elements = SwigType_split(decl);
nelements = Len(elements);
if (nelements > 0) {
element = Getitem(elements, 0);
}
for (i = 0; i < nelements; i++) {
if (i < (nelements - 1)) {
nextelement = Getitem(elements, i + 1);
} else {
nextelement = 0;
while (parm) {
String *type = Getattr(parm, "type");
String *name = Getattr(parm, "name");
if (!name && Cmp(type, "void")) {
name = NewString("");
Printf(name, "arg%d", arg_idx++);
Setattr(parm, "name", name);
}
if (SwigType_isqualifier(element)) {
int skip = 0;
DOH *q = 0;
if (!strip) {
q = SwigType_parm(element);
if (!Cmp(q, "const")) {
is_const = 1;
is_func = SwigType_isfunction(nextelement);
if (is_func)
skip = 1;
skip = 1;
}
if (!skip) {
Insert(result, 0, " ");
Insert(result, 0, q);
}
Delete(q);
}
} else if (SwigType_isfunction(element)) {
Parm *parm;
String *p;
Append(result, "(");
parm = args;
while (parm != 0) {
String *type = Getattr(parm, "type");
String *name = Getattr(parm, "name");
if (!name && Cmp(type, "void")) {
name = NewString("");
Printf(name, "arg%d", arg_idx++);
Setattr(parm, "name", name);
}
if (!name) {
name = NewString("");
}
p = SwigType_str(type, name);
Append(result, p);
String *value = Getattr(parm, "value");
if (values && (value != 0)) {
Printf(result, " = %s", value);
}
parm = nextSibling(parm);
if (parm != 0)
Append(result, ", ");
}
Append(result, ")");
} else if (rettype) { // This check is intended for conversion operators to a pointer/reference which needs the pointer/reference ignoring in the declaration
if (SwigType_ispointer(element)) {
Insert(result, 0, "*");
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
Insert(result, 0, "(");
Append(result, ")");
}
} else if (SwigType_ismemberpointer(element)) {
String *q;
q = SwigType_parm(element);
Insert(result, 0, "::*");
Insert(result, 0, q);
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
Insert(result, 0, "(");
Append(result, ")");
}
Delete(q);
} else if (SwigType_isreference(element)) {
Insert(result, 0, "&");
} else if (SwigType_isarray(element)) {
DOH *size;
Append(result, "[");
size = SwigType_parm(element);
Append(result, size);
Append(result, "]");
Delete(size);
} else {
if (Strcmp(element, "v(...)") == 0) {
Insert(result, 0, "...");
} else {
String *bs = SwigType_namestr(element);
Insert(result, 0, " ");
Insert(result, 0, bs);
Delete(bs);
}
}
}
element = nextelement;
parm = nextSibling(parm);
}
Delete(elements);
String *rettype = Copy(decl);
String *quals = SwigType_pop_function_qualifiers(rettype);
String *qualifiers = 0;
if (quals)
qualifiers = SwigType_str(quals, 0);
if (is_const) {
if (is_func) {
Append(result, " ");
Append(result, "const");
} else {
Insert(result, 0, "const ");
}
}
String *popped_decl = SwigType_pop_function(rettype);
if (return_base_type)
Append(rettype, return_base_type);
Chop(result);
if (rettype) {
Insert(result, 0, " ");
if (!conversion_operator) {
SwigType *rettype_stripped = SwigType_strip_qualifiers(rettype);
String *rtype = SwigType_str(rettype, 0);
Insert(result, 0, rtype);
Append(result, rtype);
if ((SwigType_issimple(rettype_stripped) && return_base_type) || SwigType_isqualifier(rettype))
Append(result, " ");
Delete(rtype);
Delete(rettype_stripped);
}
if (id)
Append(result, id);
String *args_string = default_args ? ParmList_str_defaultargs(args) : ParmList_str(args);
Printv(result, "(", args_string, ")", NIL);
if (qualifiers)
Printv(result, " ", qualifiers, NIL);
Delete(args_string);
Delete(popped_decl);
Delete(qualifiers);
Delete(quals);
Delete(rettype);
return result;
}
@ -272,6 +190,7 @@ String *Swig_method_decl(SwigType *rettype, SwigType *decl, const_String_or_char
* to add an extra dynamic_cast to call the public C++ wrapper in the director class.
* Also for non-static protected members when the allprotected option is on.
* ----------------------------------------------------------------------------- */
void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) {
// TODO: why is the storage element removed in staticmemberfunctionHandler ??
if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) ||
@ -290,13 +209,13 @@ void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) {
}
}
/* ------------------------------------------------------------
/* -----------------------------------------------------------------------------
* Swig_director_parms_fixup()
*
* For each parameter in the C++ member function, copy the parameter name
* to its "lname"; this ensures that Swig_typemap_attach_parms() will do
* the right thing when it sees strings like "$1" in "directorin" typemaps.
* ------------------------------------------------------------ */
* ----------------------------------------------------------------------------- */
void Swig_director_parms_fixup(ParmList *parms) {
Parm *p;

View file

@ -12,6 +12,7 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
#include "cparse.h"
/* -----------------------------------------------------------------------------
* emit_return_variable()
@ -112,9 +113,8 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
/* This is compatibility code to deal with the deprecated "ignore" typemap */
Parm *p = l;
Parm *np;
String *tm;
while (p) {
tm = Getattr(p, "tmap:in");
String *tm = Getattr(p, "tmap:in");
if (tm && checkAttribute(p, "tmap:in:numinputs", "0")) {
Replaceall(tm, "$target", Getattr(p, "lname"));
Printv(f->code, tm, "\n", NIL);
@ -134,7 +134,6 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
/* Perform a sanity check on "in" and "freearg" typemaps. These
must exactly match to avoid chaos. If a mismatch occurs, we
nuke the freearg typemap */
{
Parm *p = l;
Parm *npin, *npfreearg;
@ -189,13 +188,45 @@ void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
p = lp;
while (p) {
if (SwigType_isvarargs(Getattr(p, "type"))) {
// Mark the head of the ParmList that it has varargs
Setattr(l, "emit:varargs", lp);
//Printf(stdout, "setting emit:varargs %s ... %s +++ %s\n", Getattr(l, "emit:varargs"), Getattr(l, "type"), Getattr(p, "type"));
break;
}
p = nextSibling(p);
}
}
}
/*
* An equivalent type can be used in the typecheck typemap for SWIG to detect the overloading of equivalent
* target language types. This is primarily for the smartptr feature, where a pointer and a smart pointer
* are seen as equivalent types in the target language.
*/
{
Parm *p = l;
while (p) {
String *tm = Getattr(p, "tmap:typecheck");
if (tm) {
String *equivalent = Getattr(p, "tmap:typecheck:equivalent");
if (equivalent) {
String *precedence = Getattr(p, "tmap:typecheck:precedence");
if (precedence && Strcmp(precedence, "0") != 0)
Swig_error(Getfile(tm), Getline(tm), "The 'typecheck' typemap for %s contains an 'equivalent' attribute for a 'precedence' that is not set to SWIG_TYPECHECK_POINTER or 0.\n", SwigType_str(Getattr(p, "type"), 0));
SwigType *cpt = Swig_cparse_type(equivalent);
if (cpt) {
Setattr(p, "equivtype", cpt);
Delete(cpt);
} else {
Swig_error(Getfile(tm), Getline(tm), "Invalid type (%s) in 'equivalent' attribute in 'typecheck' typemap for type %s.\n", equivalent, SwigType_str(Getattr(p, "type"), 0));
}
}
p = Getattr(p, "tmap:typecheck:next");
} else {
p = nextSibling(p);
}
}
}
}
/* -----------------------------------------------------------------------------
@ -300,7 +331,8 @@ int emit_num_required(ParmList *parms) {
/* -----------------------------------------------------------------------------
* emit_isvarargs()
*
* Checks if a function is a varargs function
* Checks if a ParmList is a parameter list containing varargs.
* This function requires emit_attach_parmmaps to have been called beforehand.
* ----------------------------------------------------------------------------- */
int emit_isvarargs(ParmList *p) {
@ -311,6 +343,28 @@ int emit_isvarargs(ParmList *p) {
return 0;
}
/* -----------------------------------------------------------------------------
* emit_isvarargs_function()
*
* Checks for varargs in a function/constructor (can be overloaded)
* ----------------------------------------------------------------------------- */
bool emit_isvarargs_function(Node *n) {
bool has_varargs = false;
Node *over = Getattr(n, "sym:overloaded");
if (over) {
for (Node *sibling = over; sibling; sibling = Getattr(sibling, "sym:nextSibling")) {
if (ParmList_has_varargs(Getattr(sibling, "parms"))) {
has_varargs = true;
break;
}
}
} else {
has_varargs = ParmList_has_varargs(Getattr(n, "parms")) ? true : false;
}
return has_varargs;
}
/* -----------------------------------------------------------------------------
* void emit_mark_vararg_parms()
*
@ -454,29 +508,29 @@ String *emit_action(Node *n) {
if (catchlist) {
int unknown_catch = 0;
int has_varargs = 0;
Printf(eaction, "}\n");
Printf(eaction, "}");
for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) {
String *em = Swig_typemap_lookup("throws", ep, "_e", 0);
if (em) {
SwigType *et = Getattr(ep, "type");
SwigType *etr = SwigType_typedef_resolve_all(et);
if (SwigType_isreference(etr) || SwigType_ispointer(etr) || SwigType_isarray(etr)) {
Printf(eaction, "catch(%s) {", SwigType_str(et, "_e"));
Printf(eaction, " catch(%s) {", SwigType_str(et, "_e"));
} else if (SwigType_isvarargs(etr)) {
Printf(eaction, "catch(...) {");
Printf(eaction, " catch(...) {");
has_varargs = 1;
} else {
Printf(eaction, "catch(%s) {", SwigType_str(et, "&_e"));
Printf(eaction, " catch(%s) {", SwigType_str(et, "&_e"));
}
Printv(eaction, em, "\n", NIL);
Printf(eaction, "}\n");
Printf(eaction, "}");
} else {
Swig_warning(WARN_TYPEMAP_THROW, Getfile(n), Getline(n), "No 'throws' typemap defined for exception type '%s'\n", SwigType_str(Getattr(ep, "type"), 0));
unknown_catch = 1;
}
}
if (unknown_catch && !has_varargs) {
Printf(eaction, "catch(...) { throw; }\n");
Printf(eaction, " catch(...) {\nthrow;\n}");
}
}

View file

@ -125,6 +125,8 @@ class GO:public Language {
String *prefix_option;
// -fgo-pkgpath option.
String *pkgpath_option;
// Prefix for translating %import directive to import statements.
String *import_prefix;
// Whether to use a shared library.
bool use_shlib;
// Name of shared library to import.
@ -199,11 +201,12 @@ class GO:public Language {
public:
GO():package(NULL),
module(NULL),
cgo_flag(false),
cgo_flag(true),
gccgo_flag(false),
go_prefix(NULL),
prefix_option(NULL),
pkgpath_option(NULL),
import_prefix(NULL),
use_shlib(false),
soname(NULL),
intgo_type_size(0),
@ -269,6 +272,9 @@ private:
} else if (strcmp(argv[i], "-cgo") == 0) {
Swig_mark_arg(i);
cgo_flag = true;
} else if (strcmp(argv[i], "-no-cgo") == 0) {
Swig_mark_arg(i);
cgo_flag = false;
} else if (strcmp(argv[i], "-gccgo") == 0) {
Swig_mark_arg(i);
gccgo_flag = true;
@ -290,6 +296,15 @@ private:
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-import-prefix") == 0) {
if (argv[i + 1]) {
import_prefix = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-use-shlib") == 0) {
Swig_mark_arg(i);
use_shlib = true;
@ -615,6 +630,12 @@ private:
Language::top(n);
if (directorsEnabled()) {
// Insert director runtime into the f_runtime file (make it occur before %header section)
Swig_insert_file("director_common.swg", f_c_runtime);
Swig_insert_file("director.swg", f_c_runtime);
}
Delete(go_imports);
// Write out definitions for the types not defined by SWIG.
@ -734,7 +755,11 @@ private:
if (modname) {
if (!Getattr(go_imports, modname)) {
Setattr(go_imports, modname, modname);
Printv(f_go_imports, "import \"", modname, "\"\n", NULL);
Printv(f_go_imports, "import \"", NULL);
if (import_prefix) {
Printv(f_go_imports, import_prefix, "/", NULL);
}
Printv(f_go_imports, modname, "\"\n", NULL);
}
imported_package = modname;
saw_import = true;
@ -3857,12 +3882,11 @@ private:
String *cxx_director_name = NewString("SwigDirector_");
Append(cxx_director_name, class_name);
String *decl = Swig_method_decl(NULL, Getattr(n, "decl"),
cxx_director_name, first_parm, 0, 0);
String *decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0);
Printv(f_c_directors_h, " ", decl, ";\n", NULL);
Delete(decl);
decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0, 0);
decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0);
Printv(f_c_directors, cxx_director_name, "::", decl, "\n", NULL);
Delete(decl);
@ -4091,6 +4115,7 @@ private:
String *name = Getattr(n, "sym:name");
if (!name) {
assert(is_ignored);
(void)is_ignored;
name = Getattr(n, "name");
}
@ -4587,7 +4612,7 @@ private:
Append(upcall_method_name, overname);
}
SwigType *rtype = Getattr(n, "classDirectorMethods:type");
String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0, 0);
String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0);
Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL);
Delete(upcall_decl);
@ -5035,13 +5060,13 @@ private:
// Declare the method for the director class.
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
String *decl = Swig_method_decl(rtype, Getattr(n, "decl"), Getattr(n, "name"), parms, 0, 0);
String *decl = Swig_method_decl(rtype, Getattr(n, "decl"), Getattr(n, "name"), parms, 0);
Printv(f_c_directors_h, " virtual ", decl, NULL);
Delete(decl);
String *qname = NewString("");
Printv(qname, "SwigDirector_", class_name, "::", Getattr(n, "name"), NULL);
decl = Swig_method_decl(rtype, Getattr(n, "decl"), qname, parms, 0, 0);
decl = Swig_method_decl(rtype, Getattr(n, "decl"), qname, parms, 0);
Printv(w->def, decl, NULL);
Delete(decl);
Delete(qname);
@ -5935,7 +5960,7 @@ private:
*
* Given a C/C++ name, return a name in Go which will be exported.
* If the first character is an upper case letter, this returns a
* copy of its argment. If the first character is a lower case
* copy of its argument. If the first character is a lower case
* letter, this forces it to upper case. Otherwise, this prepends
* 'X'.
* ---------------------------------------------------------------------- */
@ -6061,6 +6086,7 @@ private:
}
bool r = addSymbol(name, n, scope) ? true : false;
assert(r);
(void)r;
return true;
}
@ -6974,9 +7000,11 @@ extern "C" Language *swig_go(void) {
const char * const GO::usage = "\
Go Options (available with -go)\n\
-cgo - Generate cgo input files\n\
-gccgo - Generate code for gccgo rather than 6g/8g\n\
-no-cgo - Do not generate cgo input files\n\
-gccgo - Generate code for gccgo rather than gc\n\
-go-pkgpath <p> - Like gccgo -fgo-pkgpath option\n\
-go-prefix <p> - Like gccgo -fgo-prefix option\n\
-import-prefix <p> - Prefix to add to %import directives\n\
-intgosize <s> - Set size of Go int type--32 or 64 bits\n\
-package <name> - Set name of the Go package to <name>\n\
-use-shlib - Force use of a shared library\n\

View file

@ -255,7 +255,7 @@ public:
if (goops) {
if (linkage != GUILE_LSTYLE_PASSIVE && linkage != GUILE_LSTYLE_MODULE) {
Printf(stderr, "guile: GOOPS support requires passive or module linkage\n");
exit(1);
SWIG_exit(EXIT_FAILURE);
}
}

View file

@ -151,12 +151,14 @@ void Swig_interface_propagate_methods(Node *n) {
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;
if (Cmp(nodeType(child), "cdecl") == 0) {
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;
}
}
}
}

View file

@ -15,6 +15,7 @@
#include <limits.h> // for INT_MAX
#include "cparse.h"
#include <ctype.h>
#include "javadoc.h"
/* Hash type used for upcalls from C/C++ */
typedef DOH UpcallData;
@ -46,7 +47,9 @@ class JAVA:public Language {
bool global_variable_flag; // Flag for when wrapping a global variable
bool old_variable_names; // Flag for old style variable names in the intermediary class
bool member_func_flag; // flag set when wrapping a member function
bool doxygen; //flag for converting found doxygen to javadoc
bool comment_creation_chatter; //flag for getting information about where comments were created in java.cxx
String *imclass_name; // intermediary class name
String *module_class_name; // module class name
String *constants_interface_name; // constants interface name
@ -72,8 +75,8 @@ class JAVA:public Language {
String *module_baseclass; //inheritance for module class from %pragma
String *imclass_interfaces; //interfaces for intermediary class class from %pragma
String *module_interfaces; //interfaces for module class from %pragma
String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma
String *module_class_modifiers; //class modifiers for module class overriden by %pragma
String *imclass_class_modifiers; //class modifiers for intermediary class overridden by %pragma
String *module_class_modifiers; //class modifiers for module class overridden by %pragma
String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
String *imclass_directors; // Intermediate class director code
@ -120,6 +123,8 @@ public:
global_variable_flag(false),
old_variable_names(false),
member_func_flag(false),
doxygen(false),
comment_creation_chatter(false),
imclass_name(NULL),
module_class_name(NULL),
constants_interface_name(NULL),
@ -164,11 +169,15 @@ public:
director_multiple_inheritance = 0;
director_language = 1;
}
~JAVA() {
delete doxygenTranslator;
}
/* -----------------------------------------------------------------------------
* constructIntermediateClassName()
*
* Construct the fully qualified name of the intermidiate class and set
* Construct the fully qualified name of the intermediate class and set
* the full_imclass_name attribute accordingly.
* ----------------------------------------------------------------------------- */
void constructIntermediateClassName(Node *n) {
@ -256,6 +265,8 @@ public:
SWIG_library_directory("java");
int doxygen_translator_flags = 0;
// Look for certain command line options
for (int i = 1; i < argc; i++) {
if (argv[i]) {
@ -277,6 +288,16 @@ public:
Printf(stderr, "Deprecated command line option: %s. Proxy classes are now generated by default.\n", argv[i]);
Swig_mark_arg(i);
proxy_flag = true;
} else if ((strcmp(argv[i], "-doxygen") == 0)) {
Swig_mark_arg(i);
doxygen = true;
scan_doxygen_comments = true;
} else if ((strcmp(argv[i], "-debug-doxygen-translator") == 0)) {
Swig_mark_arg(i);
doxygen_translator_flags |= DoxygenTranslator::debug_translator;
} else if ((strcmp(argv[i], "-debug-doxygen-parser") == 0)) {
Swig_mark_arg(i);
doxygen_translator_flags |= DoxygenTranslator::debug_parser;
} else if ((strcmp(argv[i], "-noproxy") == 0)) {
Swig_mark_arg(i);
proxy_flag = false;
@ -300,6 +321,9 @@ public:
}
}
}
if (doxygen)
doxygenTranslator = new JavaDocConverter(doxygen_translator_flags);
// Add a symbol to the parser for conditional compilation
Preprocessor_define("SWIGJAVA 1", 0);
@ -567,6 +591,13 @@ public:
if (module_imports)
Printf(f_module, "%s\n", module_imports);
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0);
if (comment_creation_chatter)
Printf(f_module, "/* This was generated from top() */\n");
Printv(f_module, Char(doxygen_comments), NIL);
Delete(doxygen_comments);
}
if (Len(module_class_modifiers) > 0)
Printf(f_module, "%s ", module_class_modifiers);
Printf(f_module, "%s ", module_class_name);
@ -1246,6 +1277,14 @@ public:
if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0);
if (comment_creation_chatter)
Printf(enum_code, "/* This was generated from enumDeclaration() */\n");
Printv(enum_code, Char(doxygen_comments), NIL);
Delete(doxygen_comments);
}
String *scope = getCurrentScopeName(nspace);
if (!addSymbol(symname, n, scope))
return SWIG_ERROR;
@ -1265,9 +1304,17 @@ public:
Replaceall(enum_code, "$static ", "");
Delete(scope);
} else {
// Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
if (symname && !Getattr(n, "unnamedinstance"))
Printf(constants_code, " // %s \n", symname);
// Translate and write javadoc comment for the enum itself if flagged
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
if (comment_creation_chatter)
Printf(constants_code, "/* This was generated from enumDeclaration() */\n");
Printf(constants_code, Char(doxygen_comments));
Printf(constants_code, "\n");
Delete(doxygen_comments);
}
}
// Emit each enum item
@ -1418,12 +1465,24 @@ public:
}
if (!addSymbol(symname, n, scope))
return SWIG_ERROR;
if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) {
if (!GetFlag(n, "firstenumitem"))
Printf(enum_code, ",\n");
}
// Translate and write javadoc comment if flagged
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
if (comment_creation_chatter)
Printf(enum_code, "/* This was generated from enumvalueDeclaration() */\n");
Printv(enum_code, Char(doxygen_comments), NIL);
Delete(doxygen_comments);
}
if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) {
// Wrap (non-anonymous) C/C++ enum with a proper Java enum
// Emit the enum item.
if (!GetFlag(n, "firstenumitem"))
Printf(enum_code, ",\n");
Printf(enum_code, " %s", symname);
if (Getattr(n, "enumvalue")) {
String *value = enumValue(n);
@ -1497,6 +1556,15 @@ public:
String *constants_code = NewString("");
Swig_save("constantWrapper", n, "value", NIL);
// Translate and write javadoc comment if flagged
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
if (comment_creation_chatter)
Printf(constants_code, "/* This was generated from constantWrapper() */\n");
Printv(constants_code, Char(doxygen_comments), NIL);
Delete(doxygen_comments);
}
bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname;
@ -1565,7 +1633,7 @@ public:
if (classname_substituted_flag) {
if (SwigType_isenum(t)) {
// This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
Printf(constants_code, "%s.swigToEnum(%s.%s());\n", return_type, full_imclass_name, Swig_name_get(getNSpace(), symname));
Printf(constants_code, "%s.swigToEnum(%s.%s());\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
} else {
// This handles function pointers using the %constant directive
Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
@ -1785,11 +1853,11 @@ public:
* addInterfaceNameAndUpcasts()
* ----------------------------------------------------------------------------- */
void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, SwigType *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"));
SwigType *c_baseclassname = Getattr(base, "name");
String *interface_name = Getattr(base, "interface:name");
if (Len(interface_list))
Append(interface_list, ", ");
@ -1808,12 +1876,12 @@ public:
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);
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
Delete(upcast_method_name);
Delete(cptr_method_name);
Delete(interface_code);
Delete(c_baseclass);
}
Delete(keys);
}
@ -1824,19 +1892,23 @@ public:
* Add code for C++ casting to base class
* ----------------------------------------------------------------------------- */
void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) {
void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) {
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);
String *classname = SwigType_namestr(c_classname);
String *baseclassname = SwigType_namestr(c_baseclassname);
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);
String *bsmartnamestr = SwigType_namestr(smart);
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
SwigType *rclassname = SwigType_typedef_resolve_all(classname);
SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
Replaceall(bsmartnamestr, rclassname, rbaseclassname);
Printv(upcasts_code,
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
" jlong baseptr = 0;\n"
@ -1847,19 +1919,24 @@ public:
" *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n"
" return baseptr;\n"
"}\n", "\n", NIL);
Delete(rbaseclassname);
Delete(rclassname);
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"
" *(", baseclassname, " **)&baseptr = *(", classname, " **)&jarg1;\n"
" return baseptr;\n"
"}\n", "\n", NIL);
}
Delete(baseclassname);
Delete(classname);
Delete(wname);
Delete(jniname);
}
@ -1869,10 +1946,9 @@ public:
* ----------------------------------------------------------------------------- */
void emitProxyClassDefAndCPPCasts(Node *n) {
String *c_classname = SwigType_namestr(Getattr(n, "name"));
String *c_baseclass = NULL;
SwigType *c_classname = Getattr(n, "name");
SwigType *c_baseclassname = NULL;
String *baseclass = NULL;
String *c_baseclassname = NULL;
String *interface_list = NewStringEmpty();
String *interface_upcasts = NewStringEmpty();
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
@ -1894,12 +1970,13 @@ public:
Iterator base = First(baselist);
while (base.item) {
if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
String *baseclassname = Getattr(base.item, "name");
SwigType *baseclassname = Getattr(base.item, "name");
if (!c_baseclassname) {
c_baseclassname = baseclassname;
baseclass = Copy(getProxyName(baseclassname));
if (baseclass)
c_baseclass = SwigType_namestr(baseclassname);
String *name = getProxyName(baseclassname);
if (name) {
c_baseclassname = baseclassname;
baseclass = name;
}
} else {
/* Warn about multiple inheritance for additional base class(es) */
String *proxyclassname = Getattr(n, "classtypeobj");
@ -1916,7 +1993,7 @@ public:
if (interface_bases)
addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
bool derived = baseclass && getProxyName(c_baseclassname);
bool derived = baseclass != 0;
if (derived && purebase_notderived)
pure_baseclass = empty_string;
const String *wanted_base = baseclass ? baseclass : pure_baseclass;
@ -1924,7 +2001,6 @@ public:
if (purebase_replace) {
wanted_base = pure_baseclass;
derived = false;
Delete(baseclass);
baseclass = NULL;
if (purebase_notderived)
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);
@ -1936,13 +2012,24 @@ public:
// 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);
else
// Translate and write javadoc comment if flagged
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0);
if (comment_creation_chatter)
Printf(proxy_class_def, "/* This was generated from emitProxyClassDefAndCPPCasts() */\n");
Printv(proxy_class_def, Char(doxygen_comments), NIL);
Delete(doxygen_comments);
}
if (has_outerclass)
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
@ -1956,16 +2043,19 @@ public:
String *destruct = NewString("");
const String *tm = NULL;
attributes = NewHash();
String *destruct_methodname = NULL;
String *destruct_methodmodifiers = NULL;
const String *destruct_methodname = NULL;
const String *destruct_methodmodifiers = NULL;
const String *destruct_parameters = NULL;
if (derived) {
tm = typemapLookup(n, "javadestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:javadestruct_derived:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct_derived:methodmodifiers");
destruct_parameters = Getattr(attributes, "tmap:javadestruct_derived:parameters");
} else {
tm = typemapLookup(n, "javadestruct", typemap_lookup_type, WARN_NONE, attributes);
destruct_methodname = Getattr(attributes, "tmap:javadestruct:methodname");
destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct:methodmodifiers");
destruct_parameters = Getattr(attributes, "tmap:javadestruct:parameters");
}
if (tm && *Char(tm)) {
if (!destruct_methodname) {
@ -1974,6 +2064,8 @@ public:
if (!destruct_methodmodifiers) {
Swig_error(Getfile(n), Getline(n), "No methodmodifiers attribute defined in javadestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name);
}
if (!destruct_parameters)
destruct_parameters = empty_string;
}
// Emit the finalize and delete methods
if (tm) {
@ -1987,8 +2079,15 @@ public:
Replaceall(destruct, "$jnicall", destructor_call);
else
Replaceall(destruct, "$jnicall", "throw new UnsupportedOperationException(\"C++ destructor does not have public access\")");
if (*Char(destruct))
Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " void ", destruct_methodname, "()", destructor_throws_clause, " ", destruct, "\n", NIL);
if (*Char(destruct)) {
Printv(proxy_class_def, "\n ", NIL);
const String *methodmods = Getattr(n, "destructmethodmodifiers");
if (methodmods)
Printv(proxy_class_def, methodmods, NIL);
else
Printv(proxy_class_def, destruct_methodmodifiers, NIL);
Printv(proxy_class_def, " void ", destruct_methodname, "(", destruct_parameters, ")", destructor_throws_clause, " ", destruct, "\n", NIL);
}
}
if (*Char(interface_upcasts))
Printv(proxy_class_def, interface_upcasts, NIL);
@ -2024,12 +2123,11 @@ public:
if (derived) {
String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
Delete(upcast_method_name);
}
Delete(smart);
Delete(baseclass);
}
/* ----------------------------------------------------------------------
@ -2047,7 +2145,8 @@ public:
}
Printv(f_interface, typemapLookup(n, "javaimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL);
Printf(f_interface, "public interface %s", interface_name);
Printv(f_interface, typemapLookup(n, "javainterfacemodifiers", Getattr(n, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL);
Printf(f_interface, " %s", interface_name);
if (List *baselist = Getattr(n, "bases")) {
String *bases = 0;
for (Iterator base = First(baselist); base.item; base = Next(base)) {
@ -2417,6 +2516,15 @@ public:
setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0);
}
// Translate and write javadoc comment if flagged
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
if (comment_creation_chatter)
Printf(function_code, "/* This was generated from proxyclassfunctionhandler() */\n");
Printv(function_code, Char(doxygen_comments), NIL);
Delete(doxygen_comments);
}
/* Start generating the proxy function */
const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
@ -2424,7 +2532,7 @@ 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);
@ -2544,8 +2652,6 @@ 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))) {
@ -2603,8 +2709,13 @@ public:
Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
}
if (is_interface) {
Printf(interface_class_code, ")");
generateThrowsClause(n, interface_class_code);
Printf(interface_class_code, ";\n");
}
generateThrowsClause(n, function_code);
Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
Printf(function_code, " %s\n\n", tm ? tm : empty_string);
Printv(proxy_class_code, function_code, NIL);
Delete(pre_code);
@ -2649,6 +2760,15 @@ public:
tm = Getattr(n, "tmap:jtype"); // typemaps were attached earlier to the node
Printf(im_return_type, "%s", tm);
// Translate and write javadoc comment if flagged
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
if (comment_creation_chatter)
Printf(function_code, "/* This was generated from constructionhandler() */\n");
Printv(function_code, Char(doxygen_comments), NIL);
Delete(doxygen_comments);
}
Printf(function_code, " %s %s(", methodmods, proxy_class_name);
Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name);
@ -2757,7 +2877,8 @@ public:
/* Insert the javaconstruct typemap, doing the replacement for $directorconnect, as needed */
Hash *attributes = NewHash();
String *construct_tm = Copy(typemapLookup(n, "javaconstruct", Getattr(n, "name"),
String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj");
String *construct_tm = Copy(typemapLookup(n, "javaconstruct", typemap_lookup_type,
WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF, attributes));
if (construct_tm) {
if (!feature_director) {
@ -2827,6 +2948,9 @@ public:
if (proxy_flag) {
Printv(destructor_call, full_imclass_name, ".", Swig_name_destroy(getNSpace(), symname), "(swigCPtr)", NIL);
generateThrowsClause(n, destructor_throws_clause);
const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
if (methodmods)
Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods);
}
return SWIG_OK;
}
@ -2910,6 +3034,15 @@ public:
String *pre_code = NewString("");
String *post_code = NewString("");
// Translate and write javadoc comment if flagged
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
String *doxygen_comments = doxygenTranslator->getDocumentation(n, " ");
if (comment_creation_chatter)
Printf(function_code, "/* This was generated from moduleClassFunctionHandler() */\n");
Printv(function_code, doxygen_comments, NIL);
Delete(doxygen_comments);
}
if (l) {
if (SwigType_type(Getattr(l, "type")) == T_VOID) {
l = nextSibling(l);
@ -3062,7 +3195,7 @@ public:
}
generateThrowsClause(n, function_code);
Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
Printf(function_code, " %s\n\n", tm ? tm : empty_string);
Printv(module_class_code, function_code, NIL);
Delete(pre_code);
@ -3760,15 +3893,16 @@ public:
Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", smartptr, smartptr);
Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n");
Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n");
Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
}
else {
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName);
} else {
Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name);
Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName);
Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName);
}
Printf(code_wrap->code, " (void)jcls;\n");
Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\n");
Printf(code_wrap->code, " if (director) {\n");
Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\n");
Printf(code_wrap->code, " }\n");
Printf(code_wrap->code, "}\n");
Wrapper_print(code_wrap, f_wrappers);
@ -3945,15 +4079,17 @@ public:
/* If returning a reference, initialize the pointer to a sane
default - if a Java exception occurs, then the pointer returns
something other than a NULL-initialized reference. */
String *non_ref_type = Copy(returntype);
SwigType *noref_type = SwigType_del_reference(Copy(returntype));
String *noref_ltype = SwigType_lstr(noref_type, 0);
String *return_ltype = SwigType_lstr(returntype, 0);
/* Remove reference and const qualifiers */
Replaceall(non_ref_type, "r.", "");
Replaceall(non_ref_type, "q(const).", "");
Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
Delete(non_ref_type);
Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL);
Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL);
Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype);
Printf(w->code, "c_result = &result_default;\n");
Delete(return_ltype);
Delete(noref_ltype);
Delete(noref_type);
}
Delete(base_typename);
@ -4044,7 +4180,7 @@ public:
Swig_typemap_attach_parms("out", l, 0);
Swig_typemap_attach_parms("jni", l, 0);
Swig_typemap_attach_parms("jtype", l, 0);
Swig_typemap_attach_parms("directorin", l, 0);
Swig_typemap_attach_parms("directorin", l, w);
Swig_typemap_attach_parms("javadirectorin", l, 0);
Swig_typemap_attach_parms("directorargout", l, w);
@ -4243,11 +4379,11 @@ public:
/* header declaration, start wrapper definition */
String *target;
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
target = Swig_method_decl(rtype, decl, name, l, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
@ -4461,8 +4597,8 @@ public:
if (!directorexcept) {
directorexcept = NewString("");
Printf(directorexcept, "jthrowable $error = jenv->ExceptionOccurred();\n");
Printf(directorexcept, "if ($error) {\n");
Printf(directorexcept, " jenv->ExceptionClear();$directorthrowshandlers\n");
Printf(directorexcept, "if ($error) {");
Printf(directorexcept, "$directorthrowshandlers\n");
Printf(directorexcept, " Swig::DirectorException::raise(jenv, $error);\n");
Printf(directorexcept, "}\n");
} else {
@ -4562,7 +4698,7 @@ public:
/* constructor */
{
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 0);
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0);
String *call = Swig_csuperclass_call(0, basetype, superparms);
String *classtype = SwigType_namestr(Getattr(n, "name"));
@ -4576,7 +4712,7 @@ public:
/* constructor header */
{
String *target = Swig_method_decl(0, decl, dirclassname, parms, 0, 1);
String *target = Swig_method_decl(0, decl, dirclassname, parms, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@ -4652,8 +4788,8 @@ public:
Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirClassName);
Printf(w->def, "%s::~%s() noexcept {\n", dirClassName, dirClassName);
} else if (Getattr(n, "throw")) {
Printf(f_directors_h, " virtual ~%s() throw ();\n", dirClassName);
Printf(w->def, "%s::~%s() throw () {\n", dirClassName, dirClassName);
Printf(f_directors_h, " virtual ~%s() throw();\n", dirClassName);
Printf(w->def, "%s::~%s() throw() {\n", dirClassName, dirClassName);
} else {
Printf(f_directors_h, " virtual ~%s();\n", dirClassName);
Printf(w->def, "%s::~%s() {\n", dirClassName, dirClassName);
@ -4700,34 +4836,27 @@ public:
// .'s to delimit namespaces, so we need to replace those with /'s
Replace(internal_classname, NSPACE_SEPARATOR, "/", DOH_REPLACE_ANY);
Wrapper_add_localv(w, "baseclass", "static jclass baseclass", "= 0", NIL);
Printf(w->def, "void %s::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) {", director_classname);
Printf(w->def, "static jclass baseclass = swig_new_global_ref(jenv, \"%s\");\n", internal_classname);
Printf(w->def, "if (!baseclass) return;\n");
if (first_class_dmethod != curr_class_dmethod) {
Printf(w->def, "static struct {\n");
Printf(w->def, "const char *mname;\n");
Printf(w->def, "const char *mdesc;\n");
Printf(w->def, "jmethodID base_methid;\n");
Printf(w->def, "} methods[] = {\n");
Printf(w->def, "static SwigDirectorMethod methods[] = {\n");
for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
UpcallData *udata = Getitem(dmethods_seq, i);
Printf(w->def, "{ \"%s\", \"%s\", NULL }", Getattr(udata, "method"), Getattr(udata, "fdesc"));
Printf(w->def, "SwigDirectorMethod(jenv, baseclass, \"%s\", \"%s\")", Getattr(udata, "method"), Getattr(udata, "fdesc"));
if (i != curr_class_dmethod - 1)
Putc(',', w->def);
Putc('\n', w->def);
}
Printf(w->def, "};\n");
Printf(w->def, "};");
}
Printf(w->code, "if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) {\n");
Printf(w->code, "if (!baseclass) {\n");
Printf(w->code, "baseclass = jenv->FindClass(\"%s\");\n", internal_classname);
Printf(w->code, "if (!baseclass) return;\n");
Printf(w->code, "baseclass = (jclass) jenv->NewGlobalRef(baseclass);\n");
Printf(w->code, "}\n");
int n_methods = curr_class_dmethod - first_class_dmethod;
@ -4742,12 +4871,8 @@ public:
/* Emit the code to look up the class's methods, initialize the override array */
Printf(w->code, "bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true);\n");
Printf(w->code, "for (int i = 0; i < %d; ++i) {\n", n_methods);
Printf(w->code, " if (!methods[i].base_methid) {\n");
Printf(w->code, " methods[i].base_methid = jenv->GetMethodID(baseclass, methods[i].mname, methods[i].mdesc);\n");
Printf(w->code, " if (!methods[i].base_methid) return;\n");
Printf(w->code, " }\n");
Printf(w->code, " bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true);\n");
Printf(w->code, " for (int i = 0; i < %d; ++i) {\n", n_methods);
// Generally, derived classes have a mix of overridden and
// non-overridden methods and it is worth making a GetMethodID
// check during initialization to determine if each method is
@ -4767,8 +4892,8 @@ public:
} else {
Printf(w->code, " swig_override[i] = false;\n");
Printf(w->code, " if (derived) {\n");
Printf(w->code, " jmethodID methid = jenv->GetMethodID(jcls, methods[i].mname, methods[i].mdesc);\n");
Printf(w->code, " swig_override[i] = (methid != methods[i].base_methid);\n");
Printf(w->code, " jmethodID methid = jenv->GetMethodID(jcls, methods[i].name, methods[i].desc);\n");
Printf(w->code, " swig_override[i] = methods[i].methid && (methid != methods[i].methid);\n");
Printf(w->code, " jenv->ExceptionClear();\n");
Printf(w->code, " }\n");
}
@ -4856,6 +4981,9 @@ extern "C" Language *swig_java(void) {
const char *JAVA::usage = "\
Java Options (available with -java)\n\
-doxygen - Convert C++ doxygen comments to JavaDoc comments in proxy classes\n\
-debug-doxygen-parser - Display doxygen parser module debugging information\n\
-debug-doxygen-translator - Display doxygen translator module debugging information\n\
-nopgcpp - Suppress premature garbage collection prevention parameter\n\
-noproxy - Generate the low-level functional interface instead\n\
of proxy classes\n\

View file

@ -33,6 +33,7 @@ static bool js_template_enable_debug = false;
#define GETTER "getter"
#define SETTER "setter"
#define PARENT "parent"
#define PARENT_MANGLED "parent_mangled"
#define CTOR "ctor"
#define CTOR_WRAPPERS "ctor_wrappers"
#define CTOR_DISPATCHERS "ctor_dispatchers"
@ -196,6 +197,11 @@ public:
*/
virtual int emitWrapperFunction(Node *n);
/**
* Invoked by nativeWrapper callback
*/
virtual int emitNativeFunction(Node *n);
/**
* Invoked from constantWrapper after call to Language::constantWrapper.
**/
@ -262,7 +268,7 @@ protected:
virtual int createNamespace(String *scope);
virtual Hash *createNamespaceEntry(const char *name, const char *parent);
virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled);
virtual int emitNamespaces() = 0;
@ -310,6 +316,7 @@ public:
virtual int classHandler(Node *n);
virtual int functionWrapper(Node *n);
virtual int constantWrapper(Node *n);
virtual int nativeWrapper(Node *n);
virtual void main(int argc, char *argv[]);
virtual int top(Node *n);
@ -440,6 +447,18 @@ int JAVASCRIPT::constantWrapper(Node *n) {
return SWIG_OK;
}
/* ---------------------------------------------------------------------
* nativeWrapper()
*
* Function wrapper for generating placeholders for native functions
* --------------------------------------------------------------------- */
int JAVASCRIPT::nativeWrapper(Node *n) {
emitter->emitNativeFunction(n);
return SWIG_OK;
}
/* ---------------------------------------------------------------------
* classHandler()
*
@ -552,7 +571,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) {
emitter = swig_javascript_create_V8Emitter();
Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0);
SWIG_library_directory("javascript/v8");
// V8 API is C++, so output must be C++ compatibile even when wrapping C code
// V8 API is C++, so output must be C++ compatible even when wrapping C code
if (!cparse_cplusplus) {
Swig_cparse_cplusplusout(1);
}
@ -664,7 +683,7 @@ int JSEmitter::initialize(Node * /*n */ ) {
Delete(namespaces);
}
namespaces = NewHash();
Hash *global_namespace = createNamespaceEntry("exports", 0);
Hash *global_namespace = createNamespaceEntry("exports", 0, 0);
Setattr(namespaces, "::", global_namespace);
current_namespace = global_namespace;
@ -767,6 +786,14 @@ int JSEmitter::emitWrapperFunction(Node *n) {
return ret;
}
int JSEmitter::emitNativeFunction(Node *n) {
String *wrapname = Getattr(n, "wrap:name");
enterFunction(n);
state.function(WRAPPER_NAME, wrapname);
exitFunction(n);
return SWIG_OK;
}
int JSEmitter::enterClass(Node *n) {
state.clazz(RESET);
state.clazz(NAME, Getattr(n, "sym:name"));
@ -993,7 +1020,7 @@ int JSEmitter::emitDtor(Node *n) {
Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above.
So this code doesn't actually quite work as I expect. The end result is that the code still works because
destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is wierd.
destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is weird.
I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free.
Maybe the fix for the destructor_action always true problem is that this is supposed to be embedded in the if(Extend) block above.
@ -1124,7 +1151,7 @@ int JSEmitter::emitConstant(Node *n) {
Template t_getter(getTemplate("js_getter"));
// call the variable methods as a constants are
// registred in same way
// registered in same way
enterVariable(n);
state.variable(GETTER, wname);
// TODO: why do we need this?
@ -1428,19 +1455,20 @@ int JSEmitter::createNamespace(String *scope) {
}
assert(parent_namespace != 0);
Hash *new_namespace = createNamespaceEntry(Char(scope), Char(Getattr(parent_namespace, "name")));
Hash *new_namespace = createNamespaceEntry(Char(scope), Char(Getattr(parent_namespace, "name")), Char(Getattr(parent_namespace, "name_mangled")));
Setattr(namespaces, scope, new_namespace);
Delete(parent_scope);
return SWIG_OK;
}
Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent) {
Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent, const char *parent_mangled) {
Hash *entry = NewHash();
String *name = NewString(_name);
Setattr(entry, NAME, Swig_scopename_last(name));
Setattr(entry, NAME_MANGLED, Swig_name_mangle(name));
Setattr(entry, PARENT, NewString(parent));
Setattr(entry, PARENT_MANGLED, NewString(parent_mangled));
Delete(name);
return entry;
@ -1467,7 +1495,7 @@ protected:
virtual int enterClass(Node *n);
virtual int exitClass(Node *n);
virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static);
virtual Hash *createNamespaceEntry(const char *name, const char *parent);
virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled);
virtual int emitNamespaces();
private:
@ -1547,7 +1575,8 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma
Printf(arg, "argv[%d]", i);
break;
default:
throw "Illegal state.";
Printf(stderr, "Illegal MarshallingMode.");
SWIG_exit(EXIT_FAILURE);
}
tm = emitInputTypemap(n, p, wrapper, arg);
Delete(arg);
@ -1773,8 +1802,8 @@ int JSCEmitter::exitClass(Node *n) {
return SWIG_OK;
}
Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent) {
Hash *entry = JSEmitter::createNamespaceEntry(name, parent);
Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled) {
Hash *entry = JSEmitter::createNamespaceEntry(name, parent, parent_mangled);
Setattr(entry, "functions", NewString(""));
Setattr(entry, "values", NewString(""));
return entry;
@ -1786,8 +1815,7 @@ int JSCEmitter::emitNamespaces() {
Hash *entry = it.item;
String *name = Getattr(entry, NAME);
String *name_mangled = Getattr(entry, NAME_MANGLED);
String *parent = Getattr(entry, PARENT);
String *parent_mangled = Swig_name_mangle(parent);
String *parent_mangled = Getattr(entry, PARENT_MANGLED);
String *functions = Getattr(entry, "functions");
String *variables = Getattr(entry, "values");
@ -2037,7 +2065,7 @@ int V8Emitter::exitClass(Node *n) {
.pretty_print(f_init_inheritance);
Delete(base_name_mangled);
}
// emit registeration of class template
// emit registration of class template
Template t_register = getTemplate("jsv8_register_class");
t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
.replace("$jsname", state.clazz(NAME))
@ -2185,7 +2213,8 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar
Printf(arg, "args[%d]", i);
break;
default:
throw "Illegal state.";
Printf(stderr, "Illegal MarshallingMode.");
SWIG_exit(EXIT_FAILURE);
}
tm = emitInputTypemap(n, p, wrapper, arg);
@ -2206,7 +2235,7 @@ int V8Emitter::emitNamespaces() {
String *name = Getattr(entry, NAME);
String *name_mangled = Getattr(entry, NAME_MANGLED);
String *parent = Getattr(entry, PARENT);
String *parent_mangled = Swig_name_mangle(parent);
String *parent_mangled = Getattr(entry, PARENT_MANGLED);
bool do_create = true;
bool do_register = true;
@ -2427,7 +2456,7 @@ Template & Template::trim() {
/* -----------------------------------------------------------------------------
* Template& Template::replace(const String* pattern, const String* repl) :
*
* replaces all occurences of a given pattern with a given replacement.
* replaces all occurrences of a given pattern with a given replacement.
*
* - pattern: the pattern to be replaced
* - repl: the replacement string

View file

@ -307,15 +307,12 @@ int Dispatcher::namespaceDeclaration(Node *n) {
return defaultHandler(n);
}
/* Allocators */
Language::Language():
none_comparison(NewString("$arg != 0")),
director_ctor_code(NewString("")),
director_prot_ctor_code(0),
symtabs(NewHash()),
classtypes(NewHash()),
enumtypes(NewHash()),
overloading(0),
multiinput(0),
cplus_runtime(0),
@ -336,12 +333,12 @@ directors(0) {
director_language = 0;
assert(!this_);
this_ = this;
doxygenTranslator = NULL;
}
Language::~Language() {
Delete(symtabs);
Delete(classtypes);
Delete(enumtypes);
Delete(director_ctor_code);
Delete(none_comparison);
this_ = 0;
@ -1084,6 +1081,8 @@ int Language::functionHandler(Node *n) {
globalfunctionHandler(n);
InClass = oldInClass;
} else {
// This is a member function, set a flag so the documentation type is correct
SetFlag(n, "memberfunction");
Node *explicit_n = 0;
if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
@ -1273,6 +1272,9 @@ int Language::memberfunctionHandler(Node *n) {
int flags = Getattr(n, "template") ? extendmember | SmartPointer : Extend | SmartPointer | DirectorExtraCall;
Swig_MethodToFunction(n, NSpace, ClassType, flags, director_type, is_member_director(CurrentClass, n));
Setattr(n, "sym:name", fname);
/* Explicitly save low-level and high-level documentation names */
Setattr(n, "doc:low:name", fname);
Setattr(n, "doc:high:name", symname);
functionWrapper(n);
@ -1333,6 +1335,9 @@ int Language::staticmemberfunctionHandler(Node *n) {
Setattr(n, "name", cname);
Setattr(n, "sym:name", mrename);
/* Explicitly save low-level and high-level documentation names */
Setattr(n, "doc:low:name", mrename);
Setattr(n, "doc:high:name", symname);
if (cb) {
String *cbname = NewStringf(cb, symname);
@ -1889,6 +1894,8 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_
}
if (!checkAttribute(nn, "storage", "virtual"))
continue;
if (GetFlag(nn, "final"))
continue;
/* we need to add methods(cdecl) and destructor (to check for throw decl) */
int is_destructor = (Cmp(nodeType, "destructor") == 0);
if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
@ -2104,7 +2111,7 @@ int Language::classDirectorMethods(Node *n) {
Node *item = Getitem(vtable, i);
String *method = Getattr(item, "methodNode");
String *fqdname = Getattr(item, "fqdname");
if (GetFlag(method, "feature:nodirector"))
if (GetFlag(method, "feature:nodirector") || GetFlag(method, "final"))
continue;
String *wrn = Getattr(method, "feature:warnfilter");
@ -2151,8 +2158,8 @@ int Language::classDirectorDestructor(Node *n) {
File *f_directors = Swig_filebyname("director");
File *f_directors_h = Swig_filebyname("director_h");
if (Getattr(n, "throw")) {
Printf(f_directors_h, " virtual ~%s() throw ();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() throw () {\n}\n\n", DirectorClassName, DirectorClassName);
Printf(f_directors_h, " virtual ~%s() throw();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() throw() {\n}\n\n", DirectorClassName, DirectorClassName);
} else {
Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() {\n}\n\n", DirectorClassName, DirectorClassName);
@ -2193,6 +2200,16 @@ int Language::classDirector(Node *n) {
String *using_protected_members_code = NewString("");
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
Node *nodeType = Getattr(ni, "nodeType");
if (Cmp(nodeType, "destructor") == 0 && GetFlag(ni, "final")) {
String *classtype = Getattr(n, "classtype");
SWIG_WARN_NODE_BEGIN(ni);
Swig_warning(WARN_LANG_DIRECTOR_FINAL, input_file, line_number, "Destructor %s is final, %s cannot be a director class.\n", Swig_name_decl(ni), classtype);
SWIG_WARN_NODE_END(ni);
SetFlag(n, "feature:nodirector");
Delete(vtable);
Delete(using_protected_members_code);
return SWIG_OK;
}
bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
if (isNonVirtualProtectedAccess(ni)) {
@ -3264,11 +3281,13 @@ Node *Language::symbolLookup(const String *s, const_String_or_char_ptr scope) {
* Tries to locate a class from a type definition
* ----------------------------------------------------------------------------- */
Node *Language::classLookup(const SwigType *s) const {
Node *Language::classLookup(const SwigType *s) {
static Hash *classtypes = 0;
Node *n = 0;
/* Look in hash of cached values */
n = Getattr(classtypes, s);
n = classtypes ? Getattr(classtypes, s) : 0;
if (!n) {
Symtab *stab = 0;
SwigType *ty1 = SwigType_typedef_resolve_all(s);
@ -3296,6 +3315,14 @@ Node *Language::classLookup(const SwigType *s) const {
break;
if (Strcmp(nodeType(n), "class") == 0)
break;
Node *sibling = n;
while (sibling) {
sibling = Getattr(sibling, "csym:nextSibling");
if (sibling && Strcmp(nodeType(sibling), "class") == 0)
break;
}
if (sibling)
break;
n = parentNode(n);
if (!n)
break;
@ -3323,6 +3350,8 @@ Node *Language::classLookup(const SwigType *s) const {
}
if (acceptable_prefix) {
SwigType *cs = Copy(s);
if (!classtypes)
classtypes = NewHash();
Setattr(classtypes, cs, n);
Delete(cs);
} else {
@ -3349,10 +3378,12 @@ Node *Language::classLookup(const SwigType *s) const {
* ----------------------------------------------------------------------------- */
Node *Language::enumLookup(SwigType *s) {
static Hash *enumtypes = 0;
Node *n = 0;
/* Look in hash of cached values */
n = Getattr(enumtypes, s);
n = enumtypes ? Getattr(enumtypes, s) : 0;
if (!n) {
Symtab *stab = 0;
SwigType *lt = SwigType_ltype(s);
@ -3393,6 +3424,8 @@ Node *Language::enumLookup(SwigType *s) {
if (n) {
/* Found a match. Look at the prefix. We only allow simple types. */
if (Len(prefix) == 0) { /* Simple type */
if (!enumtypes)
enumtypes = NewHash();
Setattr(enumtypes, Copy(s), n);
} else {
n = 0;
@ -3513,7 +3546,7 @@ int Language::need_nonpublic_ctor(Node *n) {
Note: given all the complications here, I am always in favor to
always enable 'dirprot', since is the C++ idea of protected
members, and use %ignore for the method you don't whan to add in
members, and use %ignore for the method you don't want to add in
the director class.
*/
if (directorsEnabled()) {
@ -3589,7 +3622,7 @@ String *Language::makeParameterName(Node *n, Parm *p, int arg_num, bool setter)
String *arg = 0;
String *pn = Getattr(p, "name");
// Use C parameter name unless it is a duplicate or an empty parameter name
// Check if parameter name is a duplicate.
int count = 0;
ParmList *plist = Getattr(n, "parms");
while (plist) {
@ -3597,8 +3630,14 @@ String *Language::makeParameterName(Node *n, Parm *p, int arg_num, bool setter)
count++;
plist = nextSibling(plist);
}
String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0;
arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn);
// If the parameter has no name at all or has a non-unique name, replace it with "argN".
if (!pn || count > 1) {
arg = NewStringf("arg%d", arg_num);
} else {
// Otherwise, try to use the original C name, but modify it if necessary to avoid conflicting with the language keywords.
arg = Swig_name_make(p, 0, pn, 0, 0);
}
if (setter && Cmp(arg, "self") != 0) {
// Some languages (C#) insist on calling the input variable "value" while
@ -3773,7 +3812,7 @@ int Language::abstractClassTest(Node *n) {
if (dirabstract) {
if (is_public(dirabstract)) {
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
"Director class '%s' is abstract, abstract method '%s' is not accesible, maybe due to multiple inheritance or 'nodirector' feature\n",
"Director class '%s' is abstract, abstract method '%s' is not accessible, maybe due to multiple inheritance or 'nodirector' feature\n",
SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
} else {
Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),

View file

@ -141,7 +141,7 @@ private:
// This variable holds the name of the current class in Lua. Usually it is
// the same as C++ class name, but rename directives can change it.
String *proxy_class_name;
// This is a so calld fully qualified symname - the above proxy class name
// This is a so called fully qualified symname - the above proxy class name
// prepended with class namespace. If class Lua name is the same as class C++ name,
// then it is basically C++ fully qualified name with colons replaced with dots.
String *full_proxy_class_name;
@ -1002,6 +1002,7 @@ public:
// REPORT("variableWrapper", n);
String *lua_name = Getattr(n, "lua:name");
assert(lua_name);
(void)lua_name;
current[VARIABLE] = true;
// let SWIG generate the wrappers
int result = Language::variableWrapper(n);
@ -1359,7 +1360,7 @@ public:
String *rt = Copy(getClassType());
SwigType_add_pointer(rt);
// Adding class to apropriate namespace
// Adding class to appropriate namespace
registerClass(nspace, wrap_class_name);
Hash *nspaceHash = getCArraysHash(nspace);
@ -1461,7 +1462,7 @@ public:
assert(proxy_class_name);
assert(full_proxy_class_name);
// Then print class isntance part
// Then print class instance part
Printv(f_wrappers, "static swig_lua_class *swig_", mangled_full_proxy_class_name, "_bases[] = {", base_class, "0};\n", NIL);
Delete(base_class);
Printv(f_wrappers, "static const char *swig_", mangled_full_proxy_class_name, "_base_names[] = {", base_class_names, "0};\n", NIL);
@ -2110,7 +2111,7 @@ public:
// variable in resulting file
getCArraysHash(0);
}
// Because we cant access directly 'symtabs', instead we access
// Because we can't directly access 'symtabs', instead we access
// top-level scope and look on all scope pseudo-symbols in it.
Hash *top_scope = symbolScopeLookup("");
assert(top_scope);
@ -2193,7 +2194,7 @@ public:
String *luaCurrentSymbolNSpace() {
String *scope = 0;
// If ouside class, than NSpace is used.
// If outside class, than NSpace is used.
// If inside class, but current[NO_CPP], then this is friend function. It belongs to NSpace
if (!getCurrentClass() || current[NO_CPP]) {
scope = getNSpace();

View file

@ -23,6 +23,7 @@
#include "swigwarn.h"
#include "cparse.h"
#include <ctype.h>
#include <errno.h>
#include <limits.h> // for INT_MAX
// Global variables
@ -38,14 +39,15 @@ int NoExcept = 0;
int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
/* Suppress warning messages for private inheritance, preprocessor evaluation etc...
WARN_PP_EVALUATION 202
WARN_PARSE_PRIVATE_INHERIT 309
WARN_TYPE_ABSTRACT 403
WARN_LANG_OVERLOAD_CONST 512
WARN_PARSE_BUILTIN_NAME 321
WARN_PARSE_REDUNDANT 322
WARN_PP_EVALUATION 202
WARN_PARSE_PRIVATE_INHERIT 309
WARN_PARSE_BUILTIN_NAME 321
WARN_PARSE_REDUNDANT 322
WARN_TYPE_ABSTRACT 403
WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
WARN_LANG_OVERLOAD_CONST 512
*/
#define EXTRA_WARNINGS "202,309,403,512,321,322"
#define EXTRA_WARNINGS "202,309,403,405,512,321,322"
extern "C" {
extern String *ModuleName;
@ -64,7 +66,7 @@ static const char *usage1 = (const char *) "\
-copyctor - Automatically generate copy constructors wherever possible\n\
-cpperraswarn - Treat the preprocessor #error statement as #warning (default)\n\
-cppext <ext> - Change file extension of generated C++ files to <ext>\n\
(default is cxx, except for PHP5 which uses cpp)\n\
(default is cxx)\n\
-copyright - Display copyright notices\n\
-debug-classes - Display information about the classes found in the interface\n\
-debug-module <n>- Display module parse tree at stages 1-4, <n> is a csv list of stages\n\
@ -96,7 +98,7 @@ static const char *usage2 = (const char *) "\
-Fmicrosoft - Display error/warning messages in Microsoft format\n\
-Fstandard - Display error/warning messages in commonly used format\n\
-fvirtual - Compile in virtual elimination mode\n\
-help - This output\n\
-help - Display help\n\
-I- - Don't search the current directory\n\
-I<dir> - Look for SWIG files in directory <dir>\n\
-ignoremissing - Ignore missing include files\n\
@ -129,14 +131,14 @@ static const char *usage3 = (const char *) "\
";
static const char *usage4 = (const char *) "\
-O - Enable the optimization options: \n\
-fastdispatch -fvirtual \n\
-O - Enable the optimization options:\n\
-fastdispatch -fvirtual\n\
-o <outfile> - Set name of C/C++ output file to <outfile>\n\
-oh <headfile> - Set name of C++ output header file for directors to <headfile>\n\
-outcurrentdir - Set default output dir to current dir instead of input file's path\n\
-outdir <dir> - Set language specific files output directory to <dir>\n\
-pcreversion - Display PCRE version information\n\
-small - Compile in virtual elimination & compact mode\n\
-small - Compile in virtual elimination and compact mode\n\
-swiglib - Report location of SWIG library and exit\n\
-templatereduce - Reduce all the typedefs in templates\n\
-v - Run in verbose mode\n\
@ -154,10 +156,14 @@ Options can also be defined using the SWIG_FEATURES environment variable, for ex
$ export SWIG_FEATURES\n\
$ swig -python interface.i\n\
\n\
is equivalent to: \n\
is equivalent to:\n\
\n\
$ swig -Wall -python interface.i \n\
$ swig -Wall -python interface.i\n\
\n\
Arguments may also be passed in a file, separated by whitespace. For example:\n\
\n\
$ echo \"-Wall -python interface.i\" > args.txt\n\
$ swig @args.txt\n\
\n";
// Local variables
@ -454,7 +460,7 @@ static void SWIG_dump_runtime() {
SWIG_exit(EXIT_SUCCESS);
}
void SWIG_getoptions(int argc, char *argv[]) {
static void getoptions(int argc, char *argv[]) {
int i;
// Get options
for (i = 1; i < argc; i++) {
@ -873,7 +879,7 @@ void SWIG_getoptions(int argc, char *argv[]) {
}
}
int SWIG_main(int argc, char *argv[], Language *l) {
int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
char *c;
/* Initialize the SWIG core */
@ -885,7 +891,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
// Initialize the preprocessor
Preprocessor_init();
lang = l;
// Set lang to a dummy value if no target language was specified so we
// can process options enough to handle -version, etc.
lang = tlm ? tlm->fac() : new Language;
// Set up some default symbols (available in both SWIG interface files
// and C files)
@ -918,9 +926,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Wrapper_director_protected_mode_set(1);
// Inform the parser if the nested classes should be ignored unless explicitly told otherwise via feature:flatnested
ignore_nested_classes = l->nestedClassesSupport() == Language::NCS_Unknown ? 1 : 0;
ignore_nested_classes = lang->nestedClassesSupport() == Language::NCS_Unknown ? 1 : 0;
kwargs_supported = l->kwargsSupport() ? 1 : 0;
kwargs_supported = lang->kwargsSupport() ? 1 : 0;
// Create Library search directories
@ -949,7 +957,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
/* Check for SWIG_FEATURES environment variable */
SWIG_getoptions(argc, argv);
getoptions(argc, argv);
// Define the __cplusplus symbol
if (CPlusPlus)
@ -962,6 +970,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Printf(stdout, "\nNote: 'swig -<lang> -help' displays options for a specific target language.\n\n");
SWIG_exit(EXIT_SUCCESS); // Exit if we're in help mode
}
// Check all of the options to make sure we're cool.
// Don't check for an input file if -external-runtime is passed
Swig_check_options(external_runtime ? 0 : 1);
@ -1057,7 +1066,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
char *cfile = Char(input_file);
if (cfile && cfile[0] == '-') {
Printf(stderr, "Unable to find option or file '%s', ", input_file);
Printf(stderr, "use 'swig -help' for more information.\n");
Printf(stderr, "Use 'swig -help' for more information.\n");
} else {
Printf(stderr, "Unable to find file '%s'.\n", input_file);
}
@ -1066,6 +1075,13 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Swig_warning(WARN_DEPRECATED_INPUT_FILE, "SWIG", 1, "Use of the include path to find the input file is deprecated and will not work with ccache. Please include the path when specifying the input file.\n"); // so that behaviour is like c/c++ compilers
}
}
if (!tlm) {
Printf(stderr, "No target language specified.\n");
Printf(stderr, "Use 'swig -help' for more information.\n");
SWIG_exit(EXIT_FAILURE);
}
if (!no_cpp) {
fclose(df);
Printf(fs, "%%include <swig.swg>\n");
@ -1125,9 +1141,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
} else
f_dependencies_file = stdout;
if (dependencies_target) {
Printf(f_dependencies_file, "%s: ", dependencies_target);
Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(dependencies_target));
} else {
Printf(f_dependencies_file, "%s: ", outfile);
Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(outfile));
}
List *files = Preprocessor_depend();
List *phony_targets = NewList();
@ -1138,7 +1154,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
use_file = 0;
}
if (use_file) {
Printf(f_dependencies_file, "\\\n %s ", Getitem(files, i));
Printf(f_dependencies_file, "\\\n %s ", Swig_filename_escape_space(Getitem(files, i)));
if (depend_phony)
Append(phony_targets, Getitem(files, i));
}
@ -1146,7 +1162,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Printf(f_dependencies_file, "\n");
if (depend_phony) {
for (int i = 0; i < Len(phony_targets); i++) {
Printf(f_dependencies_file, "\n%s:\n", Getitem(phony_targets, i));
Printf(f_dependencies_file, "\n%s:\n", Swig_filename_escape_space(Getitem(phony_targets, i)));
}
}
@ -1300,6 +1316,13 @@ int SWIG_main(int argc, char *argv[], Language *l) {
// Check the extension for a c/c++ file. If so, we're going to declare everything we see as "extern"
ForceExtern = check_extension(input_file);
if (tlm->status == Experimental) {
Swig_warning(WARN_LANG_EXPERIMENTAL, "SWIG", 1, "Experimental target language. "
"Target language %s specified by %s is an experimental language. "
"Please read about SWIG experimental languages, http://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n",
tlm->help ? tlm->help : "", tlm->name);
}
lang->top(top);
if (browse) {
@ -1354,13 +1377,15 @@ int SWIG_main(int argc, char *argv[], Language *l) {
while (freeze) {
}
if ((werror) && (Swig_warn_count())) {
return Swig_warn_count();
}
delete lang;
return Swig_error_count();
int error_count = werror ? Swig_warn_count() : 0;
error_count += Swig_error_count();
if (error_count != 0)
SWIG_exit(error_count);
return 0;
}
/* -----------------------------------------------------------------------------
@ -1372,5 +1397,20 @@ int SWIG_main(int argc, char *argv[], Language *l) {
void SWIG_exit(int exit_code) {
while (freeze) {
}
if (exit_code > 0) {
CloseAllOpenFiles();
/* Remove all generated files */
if (all_output_files) {
for (int i = 0; i < Len(all_output_files); i++) {
String *filename = Getitem(all_output_files, i);
int removed = remove(Char(filename));
if (removed == -1)
fprintf(stderr, "On exit, could not delete file %s: %s\n", Char(filename), strerror(errno));
}
}
}
exit(exit_code);
}

View file

@ -219,8 +219,8 @@ private:
String *module_baseclass; //inheritance for module class from %pragma
String *m3raw_interfaces; //interfaces for intermediary class class from %pragma
String *module_interfaces; //interfaces for module class from %pragma
String *m3raw_class_modifiers; //class modifiers for intermediary class overriden by %pragma
String *m3wrap_modifiers; //class modifiers for module class overriden by %pragma
String *m3raw_class_modifiers; //class modifiers for intermediary class overridden by %pragma
String *m3wrap_modifiers; //class modifiers for module class overridden by %pragma
String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
String *m3raw_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
String *destructor_call; //C++ destructor call if any
@ -822,7 +822,7 @@ MODULA3():
Printf(file, "\n");
Printf(file, "int main (int argc, char *argv[]) {\n");
Printf(file, "\
/*This progam must work for floating point numbers and integers.\n\
/*This program must work for floating point numbers and integers.\n\
Thus all numbers are converted to double precision floating point format.*/\n");
scanConstant(file, n);
Printf(file, " return 0;\n");
@ -3214,7 +3214,7 @@ MODULA3():
tm = Getattr(p, "tmap:m3wrapargvar");
if (tm != NIL) {
/* exceptions that may be raised but can't be catched,
/* exceptions that may be raised but can't be caught,
thus we won't count them in num_exceptions */
addImports(m3wrap_impl.import, "m3wrapargvar", p);
addThrows(throws_hash, "m3wrapargvar", p);

View file

@ -1,59 +0,0 @@
/* -----------------------------------------------------------------------------
* 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.
*
* module.cxx
*
* This file is responsible for the module system.
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
struct Module {
ModuleFactory fac;
char *name;
Module *next;
Module(const char *n, ModuleFactory f) {
fac = f;
name = new char[strlen(n) + 1];
strcpy(name, n);
next = 0;
} ~Module() {
delete[]name;
}
};
static Module *modules = 0;
/* -----------------------------------------------------------------------------
* void Swig_register_module()
*
* Register a module.
* ----------------------------------------------------------------------------- */
void Swig_register_module(const char *n, ModuleFactory f) {
Module *m = new Module(n, f);
m->next = modules;
modules = m;
}
/* -----------------------------------------------------------------------------
* Language *Swig_find_module()
*
* Given a command line option, locates the factory function.
* ----------------------------------------------------------------------------- */
ModuleFactory Swig_find_module(const char *name) {
Module *m = modules;
while (m) {
if (strcmp(m->name, name) == 0) {
return m->fac;
}
m = m->next;
}
return 0;
}

View file

@ -17,12 +17,10 @@
static const char *usage = "\
Mzscheme Options (available with -mzscheme)\n\
-declaremodule - Create extension that declares a module\n\
-dynamic-load <library>,[library,...] - Do not link with these libraries, dynamic load\n\
them\n\
-noinit - Do not emit scheme_initialize, scheme_reload,\n\
scheme_module_name functions\n\
-prefix <name> - Set a prefix <name> to be prepended to all names\n\
-declaremodule - Create extension that declares a module\n\
-dynamic-load <lib>,[lib,...] - Do not link with these libraries, dynamic load them\n\
-noinit - Do not emit module initialization code\n\
-prefix <name> - Set a prefix <name> to be prepended to all names\n\
";
static String *fieldnames_tab = 0;
@ -223,7 +221,6 @@ public:
Wrapper *f = NewWrapper();
String *proc_name = NewString("");
String *source = NewString("");
String *target = NewString("");
String *arg = NewString("");
String *cleanup = NewString("");
@ -314,10 +311,9 @@ public:
String *ln = Getattr(p, "lname");
// Produce names of source and target
Clear(source);
Clear(target);
Clear(arg);
Printf(source, "argv[%d]", i);
String *source = NewStringf("argv[%d]", i);
Printf(target, "%s", ln);
Printv(arg, Getattr(p, "name"), NIL);
@ -341,6 +337,7 @@ public:
if (i >= numreq) {
Printf(f->code, "}\n");
}
Delete(source);
}
/* Insert constraint checking code */
@ -439,9 +436,8 @@ public:
sprintf(temp, "%d", numargs);
if (exporting_destructor) {
Printf(init_func_def, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname);
} else {
Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, wname, proc_name, numreq, numargs);
}
Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, wname, proc_name, numreq, numargs);
} else {
if (!Getattr(n, "sym:nextSibling")) {
/* Emit overloading dispatch function */
@ -457,6 +453,7 @@ public:
Printv(df->def, "static Scheme_Object *\n", dname, "(int argc, Scheme_Object **argv) {", NIL);
Printv(df->code, dispatch, "\n", NIL);
Printf(df->code, "scheme_signal_error(\"No matching function for overloaded '%s'\");\n", iname);
Printf(df->code, "return NULL;\n", iname);
Printv(df->code, "}\n", NIL);
Wrapper_print(df, f_wrappers);
Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, dname, proc_name, 0, maxargs);
@ -467,7 +464,6 @@ public:
}
Delete(proc_name);
Delete(source);
Delete(target);
Delete(arg);
Delete(outarg);
@ -528,7 +524,7 @@ public:
Replaceall(tm, "$source", "argv[0]");
Replaceall(tm, "$target", name);
Replaceall(tm, "$input", "argv[0]");
/* Printv(f->code, tm, "\n",NIL); */
Replaceall(tm, "$argnum", "1");
emit_action_code(n, f->code, tm);
} else {
throw_unhandled_mzscheme_type_error(t);
@ -765,7 +761,7 @@ public:
/* ------------------------------------------------------------
* validIdentifer()
* validIdentifier()
* ------------------------------------------------------------ */
virtual int validIdentifier(String *s) {

View file

@ -68,7 +68,7 @@ public:
director_prot_ctor_code = NewString("");
Printv(director_prot_ctor_code,
"if ( $comparison ) { /* subclassed */\n",
" $director_new \n", "} else {\n", " failwith(\"accessing abstract class or protected constructor\"); \n", "}\n", NIL);
" $director_new \n", "} else {\n", " caml_failwith(\"accessing abstract class or protected constructor\"); \n", "}\n", NIL);
director_multiple_inheritance = 1;
director_language = 1;
}
@ -167,6 +167,12 @@ public:
return declaration;
}
void emitBanner(File *f) {
Printf(f, "(* ----------------------------------------------------------------------------\n");
Swig_banner_target_lang(f, " *");
Printf(f, " * ---------------------------------------------------------------------------- *)\n\n");
}
/* ------------------------------------------------------------
* top()
*
@ -196,6 +202,7 @@ public:
* use %module(directors="1") modulename at the start of the
* interface file to enable director generation.
*/
String *mod_docstring = NULL;
{
Node *module = Getattr(n, "module");
if (module) {
@ -210,6 +217,7 @@ public:
if (Getattr(options, "sizeof")) {
generate_sizeof = 1;
}
mod_docstring = Getattr(options, "docstring");
}
}
}
@ -310,9 +318,19 @@ public:
FileErrorDisplay(mlifilen);
SWIG_exit(EXIT_FAILURE);
}
emitBanner(f_mlout);
emitBanner(f_mliout);
Language::top(n);
if (mod_docstring) {
if (Len(mod_docstring)) {
Printv(f_mliout, "(** ", mod_docstring, " *)\n", NIL);
}
Delete(mod_docstring);
mod_docstring = NULL;
}
Printf(f_enum_to_int, ") | _ -> (C_int (get_int v))\n" "let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n", module);
Printf(f_mlibody, "val enum_to_int : c_enum_type -> c_obj -> Swig.c_obj\n");
@ -417,6 +435,29 @@ public:
return SwigType_isarray(SwigType_typedef_resolve_all(t));
}
virtual int membervariableHandler(Node *n) {
String *symname = Getattr(n, "sym:name");
Language::membervariableHandler(n);
String *mname = Swig_name_member(NSPACE_TODO, classname, symname);
String *getname = Swig_name_get(NSPACE_TODO, mname);
String *mangled_getname = mangleNameForCaml(getname);
Delete(getname);
if (!GetFlag(n, "feature:immutable")) {
String *setname = Swig_name_set(NSPACE_TODO, mname);
String *mangled_setname = mangleNameForCaml(setname);
Delete(setname);
Printf(f_class_ctors, " \"[%s]\", (fun args -> " "if args = (C_list [ raw_ptr ]) then _%s args else _%s args) ;\n", symname, mangled_getname, mangled_setname);
Delete(mangled_setname);
} else {
Printf(f_class_ctors, " \"[%s]\", (fun args -> " "if args = (C_list [ raw_ptr ]) then _%s args else C_void) ;\n", symname, mangled_getname);
}
Delete(mangled_getname);
Delete(mname);
return SWIG_OK;
}
/* ------------------------------------------------------------
* functionWrapper()
* Create a function declaration and register it with the interpreter.
@ -432,7 +473,6 @@ public:
Wrapper *f = NewWrapper();
String *proc_name = NewString("");
String *source = NewString("");
String *target = NewString("");
String *arg = NewString("");
String *cleanup = NewString("");
@ -447,6 +487,8 @@ public:
int destructor = (!Cmp(nodeType, "destructor"));
String *overname = 0;
bool isOverloaded = Getattr(n, "sym:overloaded") ? true : false;
// For overloaded functions, only the dispatch function needs to be exposed in the ml and mli files.
bool expose_func = !isOverloaded || !Getattr(n, "sym:nextSibling");
// Make a wrapper name for this
String *wname = Swig_name_wrapper(iname);
@ -470,33 +512,19 @@ public:
Printv(proc_name, "_", iname, NIL);
String *mangled_name = mangleNameForCaml(proc_name);
if (classmode && in_constructor) { // Emit constructor for object
if (classmode && in_constructor && expose_func) { // Emit constructor for object
String *mangled_name_nounder = NewString((char *) (Char(mangled_name)) + 1);
Printf(f_class_ctors_end, "let %s clst = _%s clst\n", mangled_name_nounder, mangled_name_nounder);
Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name_nounder);
Delete(mangled_name_nounder);
} else if (classmode && in_destructor) {
Printf(f_class_ctors, " \"~\", %s ;\n", mangled_name);
} else if (classmode && !in_constructor && !in_destructor && !static_member_function) {
} else if (classmode && !in_constructor && !in_destructor && !static_member_function &&
!Getattr(n, "membervariableHandler:sym:name") && expose_func) {
String *opname = Copy(Getattr(n, "memberfunctionHandler:sym:name"));
Replaceall(opname, "operator ", "");
if (strstr(Char(mangled_name), "__get__")) {
String *set_name = Copy(mangled_name);
if (!GetFlag(n, "feature:immutable")) {
Replaceall(set_name, "__get__", "__set__");
Printf(f_class_ctors, " \"%s\", (fun args -> " "if args = (C_list [ raw_ptr ]) then %s args else %s args) ;\n", opname, mangled_name, set_name);
Delete(set_name);
} else {
Printf(f_class_ctors, " \"%s\", (fun args -> " "if args = (C_list [ raw_ptr ]) then %s args else C_void) ;\n", opname, mangled_name);
}
} else if (strstr(Char(mangled_name), "__set__")) {
; /* Nothing ... handled by the case above */
} else {
Printf(f_class_ctors, " \"%s\", %s ;\n", opname, mangled_name);
}
Printf(f_class_ctors, " \"%s\", %s ;\n", opname, mangled_name);
Delete(opname);
}
@ -515,16 +543,6 @@ public:
// adds local variables
Wrapper_add_local(f, "args", "CAMLparam1(args)");
Wrapper_add_local(f, "ret", "SWIG_CAMLlocal2(swig_result,rv)");
Wrapper_add_local(f, "_v", "int _v = 0");
if (isOverloaded) {
Wrapper_add_local(f, "i", "int i");
Wrapper_add_local(f, "argc", "int argc = caml_list_length(args)");
Wrapper_add_local(f, "argv", "CAML_VALUE *argv");
Printv(f->code,
"argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
"for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
}
d = SwigType_typedef_qualified(d);
emit_parameter_variables(l, f);
@ -534,7 +552,18 @@ public:
numargs = emit_num_arguments(l);
numreq = emit_num_required(l);
if (!isOverloaded) {
if (numargs > 0) {
if (numreq > 0) {
Printf(f->code, "if (caml_list_length(args) < %d || caml_list_length(args) > %d) {\n", numreq, numargs);
} else {
Printf(f->code, "if (caml_list_length(args) > %d) {\n", numargs);
}
Printf(f->code, "caml_invalid_argument(\"Incorrect number of arguments passed to '%s'\");\n}\n", iname);
} else {
Printf(f->code, "if (caml_list_length(args) > 0) caml_invalid_argument(\"'%s' takes no arguments\");\n", iname);
}
}
Printf(f->code, "swig_result = Val_unit;\n");
// Now write code to extract the parameters (this is super ugly)
@ -550,10 +579,9 @@ public:
pt = SwigType_typedef_qualified(pt);
// Produce names of source and target
Clear(source);
Clear(target);
Clear(arg);
Printf(source, "caml_list_nth(args,%d)", i);
String *source = NewStringf("caml_list_nth(args,%d)", i);
Printf(target, "%s", ln);
Printv(arg, Getattr(p, "name"), NIL);
@ -577,6 +605,7 @@ public:
if (i >= numreq) {
Printf(f->code, "}\n");
}
Delete(source);
}
/* Insert constraint checking code */
@ -693,8 +722,6 @@ public:
// Wrap things up (in a manner of speaking)
Printv(f->code, tab4, "swig_result = caml_list_append(swig_result,rv);\n", NIL);
if (isOverloaded)
Printv(f->code, "free(argv);\n", NIL);
Printv(f->code, tab4, "CAMLreturn(swig_result);\n", NIL);
Printv(f->code, "}\n", NIL);
@ -711,7 +738,6 @@ public:
"free(argv);\n" "CAMLreturn(%s(args));\n",
&maxargs);
Wrapper_add_local(df, "_v", "int _v = 0");
Wrapper_add_local(df, "argv", "CAML_VALUE *argv");
/* Undifferentiate name .. this is the dispatch function */
@ -725,8 +751,19 @@ public:
Printv(df->code,
"argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
"for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
Printv(df->code, dispatch, "\n", NIL);
Printf(df->code, "failwith(\"No matching function for overloaded '%s'\");\n", iname);
Printv(df->code, dispatch, "\nfree(argv);\n", NIL);
Node *sibl = n;
while (Getattr(sibl, "sym:previousSibling"))
sibl = Getattr(sibl, "sym:previousSibling");
String *protoTypes = NewString("");
do {
String *fulldecl = Swig_name_decl(sibl);
Printf(protoTypes, "\n\" %s\\n\"", fulldecl);
Delete(fulldecl);
} while ((sibl = Getattr(sibl, "sym:nextSibling")));
Printf(df->code, "caml_failwith(\"Wrong number or type of arguments for overloaded function '%s'.\\n\""
"\n\" Possible C/C++ prototypes are:\\n\"%s);\n", iname, protoTypes);
Delete(protoTypes);
Printv(df->code, "}\n", NIL);
Wrapper_print(df, f_wrappers);
@ -735,19 +772,20 @@ public:
}
}
Printf(f_mlbody,
"external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n"
"let %s arg = match %s_f (fnhelper arg) with\n"
" [] -> C_void\n"
"| [x] -> (if %s then Gc.finalise \n"
" (fun x -> ignore ((invoke x) \"~\" C_void)) x) ; x\n"
"| lst -> C_list lst ;;\n", mangled_name, wname, mangled_name, mangled_name, newobj ? "true" : "false");
if (expose_func) {
Printf(f_mlbody, "external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n", mangled_name, wname);
Printf(f_mlbody, "let %s arg = match %s_f (%s(fnhelper arg)) with\n", mangled_name, mangled_name,
in_constructor && Swig_directorclass(getCurrentClass()) ? "director_core_helper " : "");
Printf(f_mlbody, " [] -> C_void\n"
"| [x] -> (if %s then Gc.finalise \n"
" (fun x -> ignore ((invoke x) \"~\" C_void)) x) ; x\n"
"| lst -> C_list lst ;;\n", newobj ? "true" : "false");
}
if (!classmode || in_constructor || in_destructor || static_member_function)
if ((!classmode || in_constructor || in_destructor || static_member_function) && expose_func)
Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name);
Delete(proc_name);
Delete(source);
Delete(target);
Delete(arg);
Delete(outarg);
@ -761,10 +799,11 @@ public:
* variableWrapper()
*
* Create a link to a C variable.
* This creates a single function _wrap_swig_var_varname().
* This creates a single function _wrap_varname().
* This function takes a single optional argument. If supplied, it means
* we are setting this variable to some value. If omitted, it means we are
* simply evaluating this variable. In the set case we return C_void.
* simply evaluating this variable. We return the value of the variable
* in both cases.
*
* symname is the name of the variable with respect to C. This
* may need to differ from the original name in the case of enums.
@ -780,9 +819,6 @@ public:
String *proc_name = NewString("");
String *tm;
String *tm2 = NewString("");
String *argnum = NewString("0");
String *arg = NewString("SWIG_Field(args,0)");
Wrapper *f;
if (!name) {
@ -802,14 +838,16 @@ public:
// evaluation function names
String *var_name = Swig_name_wrapper(iname);
// Build the name for scheme.
// Build the name for OCaml.
Printv(proc_name, iname, NIL);
Setattr(n, "wrap:name", proc_name);
Printf(f->def, "SWIGEXT CAML_VALUE %s(CAML_VALUE args) {\n", var_name);
// Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
Wrapper_add_local(f, "swig_result", "CAML_VALUE swig_result");
Wrapper_add_local(f, "args", "CAMLparam1(args)");
Wrapper_add_local(f, "swig_result", "SWIG_CAMLlocal1(swig_result)");
Printf(f->code, "swig_result = Val_unit;\n");
if (!GetFlag(n, "feature:immutable")) {
/* Check for a setting of the variable value */
@ -818,13 +856,12 @@ public:
Replaceall(tm, "$source", "args");
Replaceall(tm, "$target", name);
Replaceall(tm, "$input", "args");
/* Printv(f->code, tm, "\n",NIL); */
emit_action_code(n, f->code, tm);
} else if ((tm = Swig_typemap_lookup("in", n, name, 0))) {
Replaceall(tm, "$source", "args");
Replaceall(tm, "$target", name);
Replaceall(tm, "$input", "args");
Printv(f->code, tm, "\n", NIL);
emit_action_code(n, f->code, tm);
} else {
throw_unhandled_ocaml_type_error(t, "varin/in");
}
@ -842,12 +879,12 @@ public:
Replaceall(tm, "$source", name);
Replaceall(tm, "$target", "swig_result");
Replaceall(tm, "$result", "swig_result");
Printf(f->code, "%s\n", tm);
emit_action_code(n, f->code, tm);
} else {
throw_unhandled_ocaml_type_error(t, "varout/out");
}
Printf(f->code, "\nreturn swig_result;\n");
Printf(f->code, "\nCAMLreturn(swig_result);\n");
Printf(f->code, "}\n");
Wrapper_print(f, f_wrappers);
@ -868,9 +905,6 @@ public:
Delete(var_name);
Delete(proc_name);
Delete(argnum);
Delete(arg);
Delete(tm2);
DelWrapper(f);
return SWIG_OK;
}
@ -898,10 +932,9 @@ public:
virtual int constantWrapper(Node *n) {
String *name = Getattr(n, "feature:symname");
SwigType *type = Getattr(n, "type");
String *value = Getattr(n, "value");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
SwigType *qname = Getattr(n, "qualified:name");
String *rvalue = NewString("");
String *temp = 0;
if (qname)
value = qname;
@ -913,31 +946,8 @@ public:
}
// See if there's a typemap
Printv(rvalue, value, NIL);
if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) {
temp = Copy(rvalue);
Clear(rvalue);
Printv(rvalue, "\"", temp, "\"", NIL);
Delete(temp);
}
if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
temp = Copy(rvalue);
Clear(rvalue);
Printv(rvalue, "'", temp, "'", NIL);
Delete(temp);
}
// Create variable and assign it a value
Printf(f_header, "static %s = ", SwigType_lstr(type, name));
bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
if ((SwigType_type(type) == T_STRING)) {
Printf(f_header, "\"%s\";\n", value);
} else if (SwigType_type(type) == T_CHAR && !is_enum_item) {
Printf(f_header, "\'%s\';\n", value);
} else {
Printf(f_header, "%s;\n", value);
}
Printf(f_header, "static %s = %s;\n", SwigType_str(type, name), value);
SetFlag(n, "feature:immutable");
variableWrapper(n);
return SWIG_OK;
@ -1104,11 +1114,12 @@ public:
int classHandler(Node *n) {
String *name = Getattr(n, "name");
classname = Getattr(n, "sym:name");
if (!name)
return SWIG_OK;
String *mangled_sym_name = mangleNameForCaml(name);
String *mangled_name = mangleNameForCaml(name);
String *this_class_def = NewString(f_classtemplate);
String *name_normalized = normalizeTemplatedClassName(name);
String *old_class_ctors = f_class_ctors;
@ -1117,7 +1128,6 @@ public:
bool sizeof_feature = generate_sizeof && isSimpleType(name);
classname = mangled_sym_name;
classmode = true;
int rv = Language::classHandler(n);
classmode = false;
@ -1125,15 +1135,15 @@ public:
if (sizeof_feature) {
Printf(f_wrappers,
"SWIGEXT CAML_VALUE _wrap_%s_sizeof( CAML_VALUE args ) {\n"
" CAMLparam1(args);\n" " CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_sym_name, name_normalized);
" CAMLparam1(args);\n" " CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_name, name_normalized);
Printf(f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", classname, mangled_sym_name);
Printf(f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", mangled_name, mangled_name);
}
/* Insert sizeof operator for concrete classes */
if (sizeof_feature) {
Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__", classname, "_sizeof ())) ;\n", NIL);
Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__", mangled_name, "_sizeof ())) ;\n", NIL);
}
/* Handle up-casts in a nice way */
List *baselist = Getattr(n, "bases");
@ -1152,7 +1162,7 @@ public:
}
}
Replaceall(this_class_def, "$classname", classname);
Replaceall(this_class_def, "$classname", mangled_name);
Replaceall(this_class_def, "$normalized", name_normalized);
Replaceall(this_class_def, "$realname", name);
Replaceall(this_class_def, "$baselist", base_classes);
@ -1165,7 +1175,7 @@ public:
Multiwrite(this_class_def);
Setattr(n, "ocaml:ctor", classname);
Setattr(n, "ocaml:ctor", mangled_name);
return rv;
}
@ -1404,8 +1414,7 @@ public:
pure_virtual = true;
}
}
Wrapper_add_local(w, "swig_result", "CAMLparam0();\n" "SWIG_CAMLlocal2(swig_result,args)");
Printf(w->locals, "CAMLparam0();\n");
/* determine if the method returns a pointer */
is_pointer = SwigType_ispointer_return(decl);
@ -1416,15 +1425,47 @@ public:
String *pclassname = NewStringf("SwigDirector_%s", classname);
String *qualified_name = NewStringf("%s::%s", pclassname, name);
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
Printf(w->def, "%s {", target);
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
/* header declaration */
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
Printf(declaration, " virtual %s;", target);
target = Swig_method_decl(rtype, decl, name, l, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
// Get any exception classes in the throws typemap
if (Getattr(n, "noexcept")) {
Append(w->def, " noexcept");
Append(declaration, " noexcept");
}
ParmList *throw_parm_list = 0;
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
Parm *p;
int gencomma = 0;
Append(w->def, " throw(");
Append(declaration, " throw(");
if (throw_parm_list)
Swig_typemap_attach_parms("throws", throw_parm_list, 0);
for (p = throw_parm_list; p; p = nextSibling(p)) {
if (Getattr(p, "tmap:throws")) {
if (gencomma++) {
Append(w->def, ", ");
Append(declaration, ", ");
}
String *str = SwigType_str(Getattr(p, "type"), 0);
Append(w->def, str);
Append(declaration, str);
Delete(str);
}
}
Append(w->def, ")");
Append(declaration, ")");
}
Append(w->def, " {");
Append(declaration, ";\n");
/* declare method return value
* if the return value is a reference or const reference, a specialized typemap must
* handle it, including declaration of c_result ($result).
@ -1447,23 +1488,25 @@ public:
if (ignored_method) {
if (!pure_virtual) {
if (!is_void)
Printf(w->code, "return ");
String *super_call = Swig_method_call(super, l);
Printf(w->code, "%s;\n", super_call);
if (is_void)
Printf(w->code, "%s;\n", super_call);
else
Printf(w->code, "CAMLreturn_type(%s);\n", super_call);
Delete(super_call);
} else {
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
SwigType_namestr(name));
}
} else {
Wrapper_add_local(w, "swig_result", "SWIG_CAMLlocal2(swig_result, args)");
/* attach typemaps to arguments (C/C++ -> Ocaml) */
String *arglist = NewString("");
Swig_director_parms_fixup(l);
Swig_typemap_attach_parms("in", l, 0);
Swig_typemap_attach_parms("directorin", l, 0);
Swig_typemap_attach_parms("directorin", l, w);
Swig_typemap_attach_parms("directorargout", l, w);
Parm *p;
@ -1573,10 +1616,12 @@ public:
/* wrap complex arguments to values */
Printv(w->code, wrap_args, NIL);
/* pass the method call on to the Python object */
/* pass the method call on to the OCaml object */
Printv(w->code,
"swig_result = caml_swig_alloc(1,C_list);\n" "SWIG_Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0);
Printf(w->code, "swig_result = " "callback3(*caml_named_value(\"swig_runmethod\")," "swig_get_self(),copy_string(\"%s\"),args);\n", Getattr(n, "name"));
Printf(w->code, "static const CAML_VALUE *swig_ocaml_func_val = NULL;\n" "if (!swig_ocaml_func_val) {\n");
Printf(w->code, " swig_ocaml_func_val = caml_named_value(\"swig_runmethod\");\n }\n");
Printf(w->code, "swig_result = caml_callback3(*swig_ocaml_func_val,swig_get_self(),caml_copy_string(\"%s\"),args);\n", Getattr(n, "name"));
/* exception handling */
tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
if (!tm) {
@ -1592,7 +1637,7 @@ public:
/*
* Python method may return a simple object, or a tuple.
* for in/out aruments, we have to extract the appropriate values from the
* for in/out arguments, we have to extract the appropriate values from the
* argument list, then marshal everything back to C/C++ (return value and
* output arguments).
*/
@ -1651,6 +1696,8 @@ public:
Printf(w->code, "CAMLreturn_type(*c_result);\n");
}
}
} else {
Printf(w->code, "CAMLreturn0;\n");
}
Printf(w->code, "}\n");
@ -1716,7 +1763,7 @@ public:
Wrapper *w = NewWrapper();
String *call;
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
String *target = Swig_method_decl(0, decl, classname, parms, 0);
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
Delete(target);
@ -1727,7 +1774,7 @@ public:
/* constructor header */
{
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
String *target = Swig_method_decl(0, decl, classname, parms, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@ -1817,9 +1864,9 @@ public:
}
String *runtimeCode() {
String *s = Swig_include_sys("ocaml.swg");
String *s = Swig_include_sys("ocamlrun.swg");
if (!s) {
Printf(stderr, "*** Unable to open 'ocaml.swg'\n");
Printf(stderr, "*** Unable to open 'ocamlrun.swg'\n");
s = NewString("");
}
return s;

View file

@ -19,10 +19,8 @@ static String *op_prefix = 0;
static const char *usage = "\
Octave Options (available with -octave)\n\
-cppcast - Enable C++ casting operators (default)\n\
-globals <name> - Set <name> used to access C global variables [default: 'cvar']\n\
Use '.' to load C global variables into module namespace\n\
-nocppcast - Disable C++ casting operators\n\
-opprefix <str> - Prefix <str> for global operator functions [default: 'op_']\n\
\n";
@ -92,8 +90,7 @@ public:
}
virtual void main(int argc, char *argv[]) {
int cppcast = 1;
for (int i = 1; i < argc; i++) {
if (argv[i]) {
if (strcmp(argv[i], "-help") == 0) {
@ -116,12 +113,13 @@ public:
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-cppcast") == 0) {
cppcast = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nocppcast") == 0) {
cppcast = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-cppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nocppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
SWIG_exit(EXIT_FAILURE);
}
}
}
@ -130,8 +128,6 @@ public:
global_name = NewString("cvar");
if (!op_prefix)
op_prefix = NewString("op_");
if(cppcast)
Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
SWIG_library_directory("octave");
Preprocessor_define("SWIGOCTAVE 1", 0);
@ -139,7 +135,7 @@ public:
SWIG_typemap_lang("octave");
allow_overloading();
// Octave API is C++, so output must be C++ compatibile even when wrapping C code
// Octave API is C++, so output must be C++ compatible even when wrapping C code
if (!cparse_cplusplus)
Swig_cparse_cplusplusout(1);
}
@ -422,13 +418,14 @@ public:
* The "lname" attribute in each parameter in plist will be contain a parameter name
* ----------------------------------------------------------------------------- */
void addMissingParameterNames(ParmList *plist, int arg_offset) {
void addMissingParameterNames(Node* n, ParmList *plist, int arg_offset) {
Parm *p = plist;
int i = arg_offset;
while (p) {
if (!Getattr(p, "lname")) {
String *pname = Swig_cparm_name(p, i);
Delete(pname);
String *name = makeParameterName(n, p, i);
Setattr(p, "lname", name);
Delete(name);
}
i++;
p = nextSibling(p);
@ -440,14 +437,14 @@ public:
ParmList *plist = CopyParmList(Getattr(n, "parms"));
Parm *p;
Parm *pnext;
int start_arg_num = is_wrapping_class() ? 1 : 0;
int arg_num = is_wrapping_class() ? 1 : 0;
addMissingParameterNames(plist, start_arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
Swig_typemap_attach_parms("in", plist, 0);
Swig_typemap_attach_parms("doc", plist, 0);
for (p = plist; p; p = pnext) {
for (p = plist; p; p = pnext, arg_num++) {
String *tm = Getattr(p, "tmap:in");
if (tm) {
@ -469,9 +466,10 @@ public:
value = Getattr(p, "tmap:doc:value");
}
name = name ? name : Getattr(p, "name");
name = name ? name : Getattr(p, "lname");
name = Swig_name_make(p, 0, name, 0, 0); // rename parameter if a keyword
String *made_name = 0;
if (!name) {
name = made_name = makeParameterName(n, p, arg_num);
}
type = type ? type : Getattr(p, "type");
value = value ? value : Getattr(p, "value");
@ -507,7 +505,7 @@ public:
Delete(type_str);
Delete(tex_name);
Delete(name);
Delete(made_name);
}
if (pdocs)
Setattr(n, "feature:pdocs", pdocs);
@ -569,6 +567,10 @@ public:
Wrapper *f = NewWrapper();
Octave_begin_function(n, f->def, iname, overname, !overloaded);
// Start default try block to execute
// cleanup code if exception is thrown
Printf(f->code, "try {\n");
emit_parameter_variables(l, f);
emit_attach_parmmaps(l, f);
Setattr(n, "wrap:parms", l);
@ -756,9 +758,20 @@ public:
}
Printf(f->code, "return _out;\n");
Printf(f->code, "fail:\n"); // we should free locals etc if this happens
// Execute cleanup code if branched to fail: label
Printf(f->code, "fail:\n");
Printv(f->code, cleanup, NIL);
Printf(f->code, "return octave_value_list();\n");
// Execute cleanup code if exception was thrown
Printf(f->code, "}\n");
Printf(f->code, "catch(...) {\n");
Printv(f->code, cleanup, NIL);
Printf(f->code, "throw;\n");
Printf(f->code, "}\n");
// End wrapper function
Printf(f->code, "}\n");
/* Substitute the cleanup code */
@ -832,7 +845,7 @@ public:
String *setwname = Swig_name_wrapper(setname);
Octave_begin_function(n, setf->def, setname, setwname, true);
Printf(setf->def, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
if (is_assignable(n)) {
Setattr(n, "wrap:name", setname);
if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
@ -847,8 +860,9 @@ public:
} else {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
}
Append(setf->code, "return octave_value_list();\n");
Append(setf->code, "fail:\n");
Printf(setf->code, "return octave_value_list();\n");
Append(setf->code, "return octave_value_list();\n");
} else {
Printf(setf->code, "return octave_set_immutable(args,nargout);");
}
@ -868,10 +882,10 @@ public:
} else {
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
}
Append(getf->code, " return obj;\n");
Append(getf->code, "return obj;\n");
if (addfail) {
Append(getf->code, "fail:\n");
Append(getf->code, " return octave_value_list();\n");
Append(getf->code, "return octave_value_list();\n");
}
Append(getf->code, "}\n");
Wrapper_print(getf, f_wrappers);
@ -1234,7 +1248,7 @@ public:
Wrapper *w = NewWrapper();
String *call;
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
String *target = Swig_method_decl(0, decl, classname, parms, 0);
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype);
Append(w->def, "}\n");
@ -1246,7 +1260,7 @@ public:
// constructor header
{
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
String *target = Swig_method_decl(0, decl, classname, parms, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@ -1310,13 +1324,13 @@ public:
String *pclassname = NewStringf("SwigDirector_%s", classname);
String *qualified_name = NewStringf("%s::%s", pclassname, name);
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
// header declaration
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
target = Swig_method_decl(rtype, decl, name, l, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
@ -1393,7 +1407,7 @@ public:
Swig_director_parms_fixup(l);
Swig_typemap_attach_parms("in", l, 0);
Swig_typemap_attach_parms("directorin", l, 0);
Swig_typemap_attach_parms("directorin", l, w);
Swig_typemap_attach_parms("directorargout", l, w);
Parm *p;

View file

@ -185,7 +185,8 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
nodes[j] = t;
break;
} else if ((differ == 0) && (Strcmp(t1, "0") == 0)) {
t1 = Getattr(p1, "ltype");
t1 = Getattr(p1, "equivtype");
t1 = t1 ? t1 : Getattr(p1, "ltype");
if (!t1) {
t1 = SwigType_ltype(Getattr(p1, "type"));
if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) {
@ -193,7 +194,8 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
}
Setattr(p1, "ltype", t1);
}
t2 = Getattr(p2, "ltype");
t2 = Getattr(p2, "equivtype");
t2 = t2 ? t2 : Getattr(p2, "ltype");
if (!t2) {
t2 = SwigType_ltype(Getattr(p2, "type"));
if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) {
@ -231,9 +233,21 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
}
if (!differ) {
/* See if declarations differ by const only */
String *d1 = Getattr(nodes[i].n, "decl");
String *d2 = Getattr(nodes[j].n, "decl");
if (d1 && d2) {
String *decl1 = Getattr(nodes[i].n, "decl");
String *decl2 = Getattr(nodes[j].n, "decl");
if (decl1 && decl2) {
/* Remove ref-qualifiers. Note that rvalue ref-qualifiers are already ignored and
* it is illegal to overload a function with and without ref-qualifiers. So with
* all the combinations of ref-qualifiers and cv-qualifiers, we just detect
* the cv-qualifier (const) overloading. */
String *d1 = Copy(decl1);
String *d2 = Copy(decl2);
if (SwigType_isreference(d1) || SwigType_isrvalue_reference(d1)) {
Delete(SwigType_pop(d1));
}
if (SwigType_isreference(d2) || SwigType_isrvalue_reference(d2)) {
Delete(SwigType_pop(d2));
}
String *dq1 = Copy(d1);
String *dq2 = Copy(d2);
if (SwigType_isconst(d1)) {
@ -428,7 +442,7 @@ String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *
/* Loop over the functions */
bool emitcheck = 1;
bool emitcheck = true;
for (i = 0; i < nfunc; i++) {
int fn = 0;
Node *ni = Getitem(dispatch, i);
@ -504,7 +518,7 @@ String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *
if (tml)
Replaceid(tml, Getattr(pl, "lname"), "_v");
if (!tml || Cmp(tm, tml))
emitcheck = 1;
emitcheck = true;
//printf("tmap: %s[%d] (%d) => %s\n\n",
// Char(Getattr(nk, "sym:name")),
// l, emitcheck, tml?Char(tml):0);
@ -596,7 +610,7 @@ String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *
/*
Fast dispatch mechanism, provided by Salvador Fandi~no Garc'ia (#930586).
*/
String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *maxargs) {
static String *overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *maxargs, const_String_or_char_ptr fmt_fastdispatch) {
int i, j;
*maxargs = 1;
@ -639,6 +653,7 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *
// printf("overload: %s coll=%d\n", Char(Getattr(n, "sym:name")), Len(coll));
bool emitcheck = false;
int num_braces = 0;
bool test = (Len(coll) > 0 && num_arguments);
if (test) {
@ -659,7 +674,7 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *
/* if all the wrappers have the same type check on this
argument we can optimize it out */
bool emitcheck = 0;
emitcheck = false;
for (int k = 0; k < Len(coll) && !emitcheck; k++) {
Node *nk = Getitem(coll, k);
Parm *pk = Getattr(nk, "wrap:parms");
@ -681,7 +696,7 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *
if (tml)
Replaceid(tml, Getattr(pl, "lname"), "_v");
if (!tml || Cmp(tm, tml))
emitcheck = 1;
emitcheck = true;
//printf("tmap: %s[%d] (%d) => %s\n\n",
// Char(Getattr(nk, "sym:name")),
// l, emitcheck, tml?Char(tml):0);
@ -738,8 +753,8 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *
for ( /* empty */ ; num_braces > 0; num_braces--)
Printf(f, "}\n");
String *lfmt = ReplaceFormat(fmt, num_arguments);
// The language module may want to generate different code for last overloaded function called (with same number of arguments)
String *lfmt = ReplaceFormat(!emitcheck && fmt_fastdispatch ? fmt_fastdispatch : fmt, num_arguments);
Printf(f, Char(lfmt), Getattr(ni, "wrap:name"));
Printf(f, "}\n"); /* braces closes "if" for this method */
@ -756,10 +771,10 @@ String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *
return f;
}
String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *maxargs) {
String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *maxargs, const_String_or_char_ptr fmt_fastdispatch) {
if (fast_dispatch_mode || GetFlag(n, "feature:fastdispatch")) {
return Swig_overload_dispatch_fast(n, fmt, maxargs);
return overload_dispatch_fast(n, fmt, maxargs, fmt_fastdispatch);
}
int i, j;

View file

@ -16,11 +16,9 @@
#include <ctype.h>
static const char *usage = "\
Perl5 Options (available with -perl5)\n\
Perl 5 Options (available with -perl5)\n\
-compat - Compatibility mode\n\
-const - Wrap constants as constants and not variables (implies -proxy)\n\
-cppcast - Enable C++ casting operators\n\
-nocppcast - Disable C++ casting operators, useful for generating bugs\n\
-nopm - Do not generate the .pm file\n\
-noproxy - Don't create proxy classes\n\
-proxy - Create proxy classes\n\
@ -148,7 +146,6 @@ public:
virtual void main(int argc, char *argv[]) {
int i = 1;
int cppcast = 1;
SWIG_library_directory("perl5");
@ -189,25 +186,22 @@ public:
} else if (strcmp(argv[i],"-v") == 0) {
Swig_mark_arg(i);
verbose++;
} else if (strcmp(argv[i], "-cppcast") == 0) {
cppcast = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nocppcast") == 0) {
cppcast = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-compat") == 0) {
compat = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-help") == 0) {
fputs(usage, stdout);
} else if (strcmp(argv[i], "-cppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nocppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
SWIG_exit(EXIT_FAILURE);
}
}
}
if (cppcast) {
Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
}
Preprocessor_define("SWIGPERL 1", 0);
// SWIGPERL5 is deprecated, and no longer documented.
Preprocessor_define("SWIGPERL5 1", 0);
@ -900,6 +894,15 @@ public:
Printf(f->code, "%s\n", tm);
}
if (director_method) {
if ((tm = Swig_typemap_lookup("directorfree", n, Swig_cresult_name(), 0))) {
Replaceall(tm, "$input", Swig_cresult_name());
Replaceall(tm, "$result", "ST(argvi)");
Printf(f->code, "%s\n", tm);
Delete(tm);
}
}
Printv(f->code, "XSRETURN(argvi);\n", "fail:\n", cleanup, "SWIG_croak_null();\n" "}\n" "}\n", NIL);
/* Add the dXSARGS last */
@ -2018,7 +2021,7 @@ public:
Wrapper *w = NewWrapper();
String *call;
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
String *target = Swig_method_decl(0, decl, classname, parms, 0);
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call);
Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
@ -2031,7 +2034,7 @@ public:
/* constructor header */
{
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
String *target = Swig_method_decl(0, decl, classname, parms, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@ -2080,12 +2083,12 @@ public:
String *pclassname = NewStringf("SwigDirector_%s", classname);
String *qualified_name = NewStringf("%s::%s", pclassname, name);
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
/* header declaration */
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
target = Swig_method_decl(rtype, decl, name, l, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
@ -2129,27 +2132,26 @@ public:
* if the return value is a reference or const reference, a specialized typemap must
* handle it, including declaration of c_result ($result).
*/
if (!is_void) {
if (!ignored_method || pure_virtual) {
if (!SwigType_isclass(returntype)) {
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
Delete(construct_result);
} else {
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
}
if (!is_void && (!ignored_method || pure_virtual)) {
if (!SwigType_isclass(returntype)) {
if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
Delete(construct_result);
} else {
String *cres = SwigType_lstr(returntype, "c_result");
Printf(w->code, "%s;\n", cres);
Delete(cres);
Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
}
} else {
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);
}
}
if (!is_void && !ignored_method) {
String *pres = NewStringf("SV *%s", Swig_cresult_name());
Wrapper_add_local(w, Swig_cresult_name(), pres);
Delete(pres);
}
if (ignored_method) {
@ -2172,7 +2174,7 @@ public:
/* remove the wrapper 'w' since it was producing spurious temps */
Swig_typemap_attach_parms("in", l, 0);
Swig_typemap_attach_parms("directorin", l, 0);
Swig_typemap_attach_parms("directorin", l, w);
Swig_typemap_attach_parms("directorargout", l, w);
Wrapper_add_local(w, "SP", "dSP");
@ -2346,7 +2348,7 @@ public:
/*
* Python method may return a simple object, or a tuple.
* for in/out aruments, we have to extract the appropriate PyObjects from the tuple,
* for in/out arguments, we have to extract the appropriate PyObjects from the tuple,
* then marshal everything back to C/C++ (return value and output arguments).
*
*/
@ -2504,8 +2506,8 @@ public:
Printf(f_directors_h, " virtual ~%s() noexcept;\n", DirectorClassName);
Printf(f_directors, "%s::~%s() noexcept {%s}\n\n", DirectorClassName, DirectorClassName, body);
} else if (Getattr(n, "throw")) {
Printf(f_directors_h, " virtual ~%s() throw ();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() throw () {%s}\n\n", DirectorClassName, DirectorClassName, body);
Printf(f_directors_h, " virtual ~%s() throw();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() throw() {%s}\n\n", DirectorClassName, DirectorClassName, body);
} else {
Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
Printf(f_directors, "%s::~%s() {%s}\n\n", DirectorClassName, DirectorClassName, body);

View file

@ -12,7 +12,7 @@
* -----------------------------------------------------------------------------
*/
/* FIXME: PHP5 OO wrapping TODO list:
/* FIXME: PHP OO wrapping TODO list:
*
* Medium term:
*
@ -211,7 +211,7 @@ static void SwigPHP_emit_resource_registrations() {
ki = First(zend_types);
if (ki.key)
Printf(s_oinit, "\n/* Register resource destructors for pointer types */\n");
Printf(s_oinit, "\n /* Register resource destructors for pointer types */\n");
while (ki.key) {
DOH *key = ki.key;
Node *class_node = ki.item;
@ -249,11 +249,11 @@ static void SwigPHP_emit_resource_registrations() {
Printf(s_vdecl, "static int le_swig_%s=0; /* handle for %s */\n", key, human_name);
// register with php
Printf(s_oinit, "le_swig_%s=zend_register_list_destructors_ex"
Printf(s_oinit, " le_swig_%s=zend_register_list_destructors_ex"
"(%s, NULL, SWIGTYPE%s->name, module_number);\n", key, rsrc_dtor_name, key);
// store php type in class struct
Printf(s_oinit, "SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n", key, key);
Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n", key, key);
Delete(rsrc_dtor_name);
@ -341,8 +341,8 @@ public:
/* subsections of the init section */
s_vinit = NewStringEmpty();
s_vdecl = NewString("/* vdecl subsection */\n");
s_cinit = NewString("/* cinit subsection */\n");
s_oinit = NewString("/* oinit subsection */\n");
s_cinit = NewString(" /* cinit subsection */\n");
s_oinit = NewString(" /* oinit subsection */\n");
pragma_phpinfo = NewStringEmpty();
s_phpclasses = NewString("/* PHP Proxy Classes */\n");
f_directors_h = NewStringEmpty();
@ -433,7 +433,7 @@ public:
/* Initialize the rest of the module */
Printf(s_oinit, "ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, NULL);\n", module, module);
Printf(s_oinit, " ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, NULL);\n", module, module);
/* start the header section */
Printf(s_header, "ZEND_BEGIN_MODULE_GLOBALS(%s)\n", module);
@ -441,8 +441,8 @@ public:
Printf(s_header, "int error_code;\n");
Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module);
Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n", module);
Printf(s_header, "#define SWIG_ErrorMsg() (%s_globals.error_msg)\n", module);
Printf(s_header, "#define SWIG_ErrorCode() (%s_globals.error_code)\n", module);
Printf(s_header, "#define SWIG_ErrorMsg() ZEND_MODULE_GLOBALS_ACCESSOR(%s, error_msg)\n", module);
Printf(s_header, "#define SWIG_ErrorCode() ZEND_MODULE_GLOBALS_ACCESSOR(%s, error_code)\n", module);
/* The following can't go in Lib/php/phprun.swg as it uses SWIG_ErrorMsg(), etc
* which has to be dynamically generated as it depends on the module name.
@ -551,6 +551,20 @@ public:
s_arginfo = NewString("/* arginfo subsection */\n");
arginfo_used = NewHash();
// Add arginfo we'll definitely need for *_alter_newobject and *_get_newobject.
SetFlag(arginfo_used, "1");
Append(s_arginfo,
"ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_1, 0, 0, 1)\n"
" ZEND_ARG_INFO(0,arg1)\n"
"ZEND_END_ARG_INFO()\n");
SetFlag(arginfo_used, "2");
Append(s_arginfo,
"ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_2, 0, 0, 2)\n"
" ZEND_ARG_INFO(0,arg1)\n"
" ZEND_ARG_INFO(0,arg2)\n"
"ZEND_END_ARG_INFO()\n");
/* start the function entry section */
s_entry = NewString("/* entry subsection */\n");
@ -613,7 +627,7 @@ public:
Printf(s_init, "extern \"C\" {\n");
Printf(s_init, "#endif\n");
// We want to write "SWIGEXPORT ZEND_GET_MODULE(%s)" but ZEND_GET_MODULE
// in PHP5 has "extern "C" { ... }" around it so we can't do that.
// in PHP7 has "extern "C" { ... }" around it so we can't do that.
Printf(s_init, "SWIGEXPORT zend_module_entry *get_module(void) { return &%s_module_entry; }\n", module);
Printf(s_init, "#ifdef __cplusplus\n");
Printf(s_init, "}\n");
@ -632,17 +646,17 @@ public:
// Printv(s_init,s_resourcetypes,NIL);
/* We need this after all classes written out by ::top */
Printf(s_oinit, "CG(active_class_entry) = NULL;\n");
Printf(s_oinit, "/* end oinit subsection */\n");
Printf(s_oinit, " CG(active_class_entry) = NULL;\n");
Printf(s_oinit, " /* end oinit subsection */\n");
Printf(s_init, "%s\n", s_oinit);
/* Constants generated during top call */
Printf(s_cinit, "/* end cinit subsection */\n");
Printf(s_cinit, " /* end cinit subsection */\n");
Printf(s_init, "%s\n", s_cinit);
Clear(s_cinit);
Delete(s_cinit);
Printf(s_init, " return SUCCESS;\n");
Printf(s_init, " return SUCCESS;\n");
Printf(s_init, "}\n\n");
// Now do REQUEST init which holds any user specified %rinit, and also vinit
@ -660,15 +674,15 @@ public:
if (Len(s_vinit) > 0) {
/* finish our init section which will have been used by class wrappers */
Printv(s_init,
"/* vinit subsection */\n",
" /* vinit subsection */\n",
s_vinit, "\n"
"/* end vinit subsection */\n",
" /* end vinit subsection */\n",
NIL);
Clear(s_vinit);
}
Delete(s_vinit);
Printf(s_init, " return SUCCESS;\n");
Printf(s_init, " return SUCCESS;\n");
Printf(s_init, "}\n\n");
}
@ -681,7 +695,7 @@ public:
"/* shutdown section */\n"
"{\n",
s_shutdown,
" return SUCCESS;\n"
" return SUCCESS;\n"
"}\n\n", NIL);
}
@ -736,8 +750,8 @@ public:
}
Printv(f_begin, s_vdecl, s_wrappers, NIL);
Printv(f_begin, s_arginfo, "\n\n", all_cs_entry, "\n\n", s_entry,
" SWIG_ZEND_NAMED_FE(swig_", module, "_alter_newobject,_wrap_swig_", module, "_alter_newobject,NULL)\n"
" SWIG_ZEND_NAMED_FE(swig_", module, "_get_newobject,_wrap_swig_", module, "_get_newobject,NULL)\n"
" SWIG_ZEND_NAMED_FE(swig_", module, "_alter_newobject,_wrap_swig_", module, "_alter_newobject,swig_arginfo_2)\n"
" SWIG_ZEND_NAMED_FE(swig_", module, "_get_newobject,_wrap_swig_", module, "_get_newobject,swig_arginfo_1)\n"
" ZEND_FE_END\n};\n\n", NIL);
Printv(f_begin, s_init, NIL);
Delete(s_header);
@ -759,7 +773,7 @@ public:
Delete(s_fakeoowrappers);
s_fakeoowrappers = NULL;
}
Printf(f_phpcode, "%s\n?>\n", s_phpclasses);
Printf(f_phpcode, "%s\n", s_phpclasses);
Delete(f_phpcode);
return SWIG_OK;
@ -778,17 +792,18 @@ public:
}
// We want to only emit each different arginfo once, as that reduces the
// size of both the generated source code and the compiled extension
// module. To do this, we name the arginfo to encode the number of
// parameters and which (if any) are passed by reference by using a
// sequence of 0s (for non-reference) and 1s (for by references).
// module. The parameters at this level are just named arg1, arg2, etc
// so we generate an arginfo name with the number of parameters and a
// bitmap value saying which (if any) are passed by reference.
bool constructor = false;
if (Cmp(fname,"__construct") == 0) {
constructor = true;
}
ParmList *l = Getattr(n, "parms");
int Iterator = 0;
String * arginfo_code = NewStringEmpty();
unsigned long bitmap = 0, bit = 1;
int n_params = 0;
bool overflowed = false;
for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
/* Ignored parameters */
if ((overload || (!constructor && class_name)) && (Iterator == 0)) {
@ -798,16 +813,34 @@ public:
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
continue;
}
Append(arginfo_code, GetFlag(p, "tmap:in:byref") ? "1" : "0");
++n_params;
if (GetFlag(p, "tmap:in:byref")) {
bitmap |= bit;
if (bit == 0) overflowed = true;
}
bit <<= 1;
}
String * arginfo_code;
if (overflowed) {
// We overflowed the bitmap so just generate a unique name - this only
// happens for a function with more parameters than bits in a long
// where a high numbered parameter is passed by reference, so should be
// rare in practice.
static int overflowed_counter = 0;
arginfo_code = NewStringf("z%d", ++overflowed_counter);
} else if (bitmap == 0) {
// No parameters passed by reference.
arginfo_code = NewStringf("%d", n_params);
} else {
arginfo_code = NewStringf("%d_%lx", n_params, bitmap);
}
int numberOfParams = Len(arginfo_code);
if (!GetFlag(arginfo_used, arginfo_code)) {
// Not had this one before, so emit it.
// Not had this one before so emit it.
SetFlag(arginfo_used, arginfo_code);
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, %d)\n", arginfo_code, numberOfParams);
for (const char * p = Char(arginfo_code); *p; ++p) {
Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p);
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, %d)\n", arginfo_code, n_params);
for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
Printf(s_arginfo, " ZEND_ARG_INFO(%d,%s)\n", GetFlag(p, "tmap:in:byref"), Getattr(p, "lname"));
}
Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
}
@ -1120,36 +1153,9 @@ public:
baseClassExtend = NULL;
}
Wrapper *f = NewWrapper();
// Need arg info set for __get magic function with one variable.
String * arginfo_code = NewString("0");
if (!GetFlag(arginfo_used, arginfo_code)) {
// Not had this one before, so emit it.
SetFlag(arginfo_used, arginfo_code);
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 1)\n", arginfo_code);
for (const char * p = Char(arginfo_code); *p; ++p) {
Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p);
}
Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
}
arginfo_code = NULL;
// Need arg info set for __set and __isset magic function with two variable.
arginfo_code = NewString("00");
if (!GetFlag(arginfo_used, arginfo_code)) {
// Not had this one before, so emit it.
SetFlag(arginfo_used, arginfo_code);
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 2)\n", arginfo_code);
for (const char * p = Char(arginfo_code); *p; ++p) {
Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p);
}
Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
}
arginfo_code = NULL;
Printf(f_h, "PHP_METHOD(%s,__set);\n", class_name);
Printf(all_cs_entry, " PHP_ME(%s,__set,swig_arginfo_00,ZEND_ACC_PUBLIC)\n", class_name);
Printf(all_cs_entry, " PHP_ME(%s,__set,swig_arginfo_2,ZEND_ACC_PUBLIC)\n", class_name);
Printf(f->code, "PHP_METHOD(%s,__set) {\n",class_name);
Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)SWIG_Z_FETCH_OBJ_P(getThis());\n");
@ -1184,7 +1190,7 @@ public:
Printf(f_h, "PHP_METHOD(%s,__get);\n", class_name);
Printf(all_cs_entry, " PHP_ME(%s,__get,swig_arginfo_0,ZEND_ACC_PUBLIC)\n", class_name);
Printf(all_cs_entry, " PHP_ME(%s,__get,swig_arginfo_1,ZEND_ACC_PUBLIC)\n", class_name);
Printf(f->code, "PHP_METHOD(%s,__get) {\n",class_name);
Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)SWIG_Z_FETCH_OBJ_P(getThis());\n", class_name);
@ -1218,7 +1224,7 @@ public:
Printf(f_h, "PHP_METHOD(%s,__isset);\n", class_name);
Printf(all_cs_entry, " PHP_ME(%s,__isset,swig_arginfo_0,ZEND_ACC_PUBLIC)\n", class_name);
Printf(all_cs_entry, " PHP_ME(%s,__isset,swig_arginfo_1,ZEND_ACC_PUBLIC)\n", class_name);
Printf(f->code, "PHP_METHOD(%s,__isset) {\n",class_name);
Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)SWIG_Z_FETCH_OBJ_P(getThis());\n", class_name);
@ -1643,7 +1649,7 @@ public:
/* Insert argument output code */
bool hasargout = false;
for (i = 0, p = l; p; i++) {
if ((tm = Getattr(p, "tmap:argout"))) {
if ((tm = Getattr(p, "tmap:argout")) && Len(tm)) {
hasargout = true;
Replaceall(tm, "$source", Getattr(p, "lname"));
// Replaceall(tm,"$input",Getattr(p,"lname"));
@ -1803,11 +1809,11 @@ public:
if (constructor) {
class_has_ctor = true;
// Skip the Foo:: prefix.
char *ptr = strrchr(GetChar(Swig_methodclass(n), "sym:name"), ':');
char *ptr = strrchr(GetChar(current_class, "sym:name"), ':');
if (ptr) {
ptr++;
} else {
ptr = GetChar(Swig_methodclass(n), "sym:name");
ptr = GetChar(current_class, "sym:name");
}
if (strcmp(ptr, GetChar(n, "constructorHandler:sym:name")) == 0) {
methodname = "__construct";
@ -1930,7 +1936,7 @@ public:
/* FIXME: How should this be handled? The rest of SWIG just seems
* to not bother checking for malloc failing! */
fprintf(stderr, "Malloc failed!\n");
exit(1);
SWIG_exit(EXIT_FAILURE);
}
for (i = 0; i < max_num_of_arguments; ++i) {
arg_names[i] = NULL;
@ -1942,7 +1948,7 @@ public:
/* FIXME: How should this be handled? The rest of SWIG just seems
* to not bother checking for malloc failing! */
fprintf(stderr, "Malloc failed!\n");
exit(1);
SWIG_exit(EXIT_FAILURE);
}
for (i = 0; i < max_num_of_arguments; ++i) {
arg_values[i] = NULL;
@ -2169,14 +2175,6 @@ public:
/* We need $this to refer to the current class, so can't allow it
* to be used as a parameter. */
Setattr(seen, "this", seen);
/* We use $r to store the return value, so disallow that as a parameter
* name in case the user uses the "call-time pass-by-reference" feature
* (it's deprecated and off by default in PHP5, but we want to be
* maximally portable). Similarly we use $c for the classname or new
* stdClass object.
*/
Setattr(seen, "r", seen);
Setattr(seen, "c", seen);
for (int argno = 0; argno < max_num_of_arguments; ++argno) {
String *&pname = arg_names[argno];
@ -2224,7 +2222,7 @@ public:
Replaceall(value, "$", "\\$");
}
Printf(args, "$%s=%s", arg_names[i], value);
} else if (constructor && i >= 1 && i < min_num_of_arguments) {
} else if (constructor && strcmp(methodname, "__construct") == 0 && i >= 1 && i < min_num_of_arguments) {
// We need to be able to call __construct($resource).
Printf(args, "$%s=null", arg_names[i]);
} else {
@ -2281,13 +2279,15 @@ public:
Printf(prepare, "case %d: ", ++last_handled_i);
}
if (non_void_return) {
if ((!directorsEnabled() || !Swig_directorclass(n)) && !newobject) {
if (!constructor) {
Append(prepare, "$r=");
} else if (wrapperType == staticmemberfn || wrapperType == staticmembervar) {
Append(prepare, "$r=");
} else {
Printf(prepare, "$this->%s=", SWIG_PTR);
}
}
if (!directorsEnabled() || !Swig_directorclass(n) || !newobject) {
if (!directorsEnabled() || !Swig_directorclass(n) || !constructor) {
Printf(prepare, "%s(%s); break;\n", iname, invoke_args);
} else if (!i) {
Printf(prepare, "%s($_this%s); break;\n", iname, invoke_args);
@ -2303,14 +2303,16 @@ public:
if (had_a_case)
Printf(prepare, "default: ");
if (non_void_return) {
if ((!directorsEnabled() || !Swig_directorclass(n)) && !newobject) {
if (!constructor) {
Append(prepare, "$r=");
} else if (wrapperType == staticmemberfn || wrapperType == staticmembervar) {
Append(prepare, "$r=");
} else {
Printf(prepare, "$this->%s=", SWIG_PTR);
}
}
if (!directorsEnabled() || !Swig_directorclass(n) || !newobject) {
if (!directorsEnabled() || !Swig_directorclass(n) || !constructor) {
Printf(prepare, "%s(%s);\n", iname, invoke_args);
} else {
Printf(prepare, "%s($_this, %s);\n", iname, invoke_args);
@ -2378,20 +2380,33 @@ public:
}
if (constructor) {
const char * arg0;
// Discriminate between the PHP constructor and a C++ constructor
// renamed to become a factory function in PHP.
bool php_constructor = (strcmp(methodname, "__construct") == 0);
const char * arg0 = NULL;
if (max_num_of_arguments > 0) {
arg0 = Char(arg_names[0]);
} else {
} else if (php_constructor) {
// The PHP constructor needs to be able to wrap a resource, but a
// renamed constructor doesn't.
arg0 = "res";
Delete(args);
args = NewString("$res=null");
}
String *mangled_type = SwigType_manglestr(Getattr(n, "type"));
if (!php_constructor) {
// A renamed constructor should be a static method.
Append(acc, "static ");
}
Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args);
Printf(output, "\t\tif (is_resource($%s) && get_resource_type($%s) === '%s') {\n", arg0, arg0, mangled_type);
Printf(output, "\t\t\t$this->%s=$%s;\n", SWIG_PTR, arg0);
Printf(output, "\t\t\treturn;\n");
Printf(output, "\t\t}\n");
if (php_constructor) {
// The PHP constructor needs to be able to wrap a resource, but a
// renamed constructor doesn't.
Printf(output, "\t\tif (is_resource($%s) && get_resource_type($%s) === '%s') {\n", arg0, arg0, mangled_type);
Printf(output, "\t\t\t$this->%s=$%s;\n", SWIG_PTR, arg0);
Printf(output, "\t\t\treturn;\n");
Printf(output, "\t\t}\n");
}
} else {
Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args);
}
@ -2420,7 +2435,7 @@ public:
Printf(output, "\tstatic function %s(%s) {\n", methodname, args);
}
if (!newobject)
if (!constructor)
Printf(output, "%s", prepare);
if (constructor) {
if (!directorsEnabled() || !Swig_directorclass(n)) {
@ -2714,7 +2729,7 @@ done:
String *type = Getattr(n, "name");
String *value = Getattr(n, "value");
if (Strcmp(lang, "php") == 0 || Strcmp(lang, "php4") == 0) {
if (Strcmp(lang, "php") == 0) {
if (Strcmp(type, "code") == 0) {
if (value) {
Printf(pragma_code, "%s\n", value);
@ -2990,7 +3005,6 @@ done:
}
Printf(s_phpclasses, "\t}\n");
/* Create __isset for PHP 5.1 and later; PHP 5.0 will just ignore it. */
/* __isset() should return true for read-only properties, so check for
* *_get() not *_set(). */
Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
@ -3277,7 +3291,7 @@ done:
String *call;
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
String *target = Swig_method_decl(0, decl, classname, parms, 0);
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s, Swig::Director(self) {", classname, target, call);
Append(w->def, "}");
@ -3289,7 +3303,7 @@ done:
/* constructor header */
{
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
String *target = Swig_method_decl(0, decl, classname, parms, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@ -3333,12 +3347,12 @@ done:
String *pclassname = NewStringf("SwigDirector_%s", classname);
String *qualified_name = NewStringf("%s::%s", pclassname, name);
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
/* header declaration */
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
target = Swig_method_decl(rtype, decl, name, l, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
@ -3417,7 +3431,7 @@ done:
/* remove the wrapper 'w' since it was producing spurious temps */
Swig_typemap_attach_parms("in", l, 0);
Swig_typemap_attach_parms("directorin", l, 0);
Swig_typemap_attach_parms("directorin", l, w);
Swig_typemap_attach_parms("directorargout", l, w);
Parm *p;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -131,12 +131,10 @@ enum autodoc_t {
static const char *usage = "\
Ruby Options (available with -ruby)\n\
-autorename - Enable renaming of classes and methods to follow Ruby coding standards\n\
-cppcast - Enable C++ casting operators (default)\n\
-globalmodule - Wrap everything into the global module\n\
-initname <name>- Set entry function to Init_<name> (used by `require')\n\
-minherit - Attempt to support multiple inheritance\n\
-noautorename - Disable renaming of classes and methods (default)\n\
-nocppcast - Disable C++ casting operators, useful for generating bugs\n\
-prefix <name> - Set a prefix <name> to be prepended to all names\n\
";
@ -257,32 +255,22 @@ private:
autodoc = make_autodoc(n, ad_type);
have_auto = (autodoc && Len(autodoc) > 0);
}
// If there is more than one line then make docstrings like this:
//
// This is line1
// And here is line2 followed by the rest of them
//
// otherwise, put it all on a single line
//
if (have_auto || have_ds)
doc = NewString("/*");
if (have_auto && have_ds) { // Both autodoc and docstring are present
doc = NewString("");
Printv(doc, "\n", autodoc, "\n", str, NIL);
Printv(doc, "\n", autodoc, "\n", str, "\n", NIL);
} else if (!have_auto && have_ds) { // only docstring
if (Strchr(str, '\n') == 0) {
doc = NewString(str);
} else {
doc = NewString("");
Printv(doc, str, NIL);
}
Printv(doc, str, NIL);
} else if (have_auto && !have_ds) { // only autodoc
if (Strchr(autodoc, '\n') == 0) {
doc = NewStringf("%s", autodoc);
} else {
doc = NewString("");
Printv(doc, "\n", autodoc, NIL);
}
} else
Printv(doc, "\n", autodoc, "\n", NIL);
} else {
doc = NewString("");
}
if (have_auto || have_ds)
Append(doc, "*/\n");
// Save the generated strings in the parse tree in case they are used later
// by post processing tools
@ -302,13 +290,14 @@ private:
* The "lname" attribute in each parameter in plist will be contain a parameter name
* ----------------------------------------------------------------------------- */
void addMissingParameterNames(ParmList *plist, int arg_offset) {
void addMissingParameterNames(Node* n, ParmList *plist, int arg_offset) {
Parm *p = plist;
int i = arg_offset;
while (p) {
if (!Getattr(p, "lname")) {
String *pname = Swig_cparm_name(p, i);
Delete(pname);
String *name = makeParameterName(n, p, i);
Setattr(p, "lname", name);
Delete(name);
}
i++;
p = nextSibling(p);
@ -327,10 +316,10 @@ private:
Parm *p;
Parm *pnext;
int lines = 0;
int start_arg_num = is_wrapping_class() ? 1 : 0;
int arg_num = is_wrapping_class() ? 1 : 0;
const int maxwidth = 80;
addMissingParameterNames(plist, start_arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms
Swig_typemap_attach_parms("in", plist, 0);
Swig_typemap_attach_parms("doc", plist, 0);
@ -340,7 +329,7 @@ private:
return doc;
}
for (p = plist; p; p = pnext) {
for (p = plist; p; p = pnext, arg_num++) {
String *tm = Getattr(p, "tmap:in");
if (tm) {
@ -363,9 +352,10 @@ private:
}
// Note: the generated name should be consistent with that in kwnames[]
name = name ? name : Getattr(p, "name");
name = name ? name : Getattr(p, "lname");
name = Swig_name_make(p, 0, name, 0, 0); // rename parameter if a keyword
String *made_name = 0;
if (!name) {
name = made_name = makeParameterName(n, p, arg_num);
}
type = type ? type : Getattr(p, "type");
value = value ? value : Getattr(p, "value");
@ -416,7 +406,7 @@ private:
Printf(doc, "=%s", value);
}
Delete(type_str);
Delete(name);
Delete(made_name);
}
if (pdocs)
Setattr(n, "feature:pdocs", pdocs);
@ -436,7 +426,7 @@ private:
String *make_autodoc(Node *n, autodoc_t ad_type) {
int extended = 0;
// If the function is overloaded then this funciton is called
// If the function is overloaded then this function is called
// for the last one. Rewind to the first so the docstrings are
// in order.
while (Getattr(n, "sym:previousSibling"))
@ -522,7 +512,7 @@ private:
last_mode = ad_type;
last_autodoc = Copy(methodName);
String *doc = NewString("/*\n");
String *doc = NewString("");
int counter = 0;
bool skipAuto = false;
Node* on = n;
@ -762,7 +752,6 @@ private:
n = Getattr(n, "sym:nextSibling");
}
Append(doc, "\n*/\n");
Delete(full_name);
Delete(class_name);
Delete(super_names);
@ -844,7 +833,6 @@ public:
virtual void main(int argc, char *argv[]) {
int cppcast = 1;
int autorename = 0;
/* Set location of SWIG library */
@ -883,12 +871,6 @@ public:
multipleInheritance = true;
director_multiple_inheritance = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-cppcast") == 0) {
cppcast = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nocppcast") == 0) {
cppcast = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-autorename") == 0) {
autorename = 1;
Swig_mark_arg(i);
@ -907,15 +889,17 @@ public:
}
} else if (strcmp(argv[i], "-help") == 0) {
Printf(stdout, "%s\n", usage);
} else if (strcmp(argv[i], "-cppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nocppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
SWIG_exit(EXIT_FAILURE);
}
}
}
if (cppcast) {
/* Turn on cppcast mode */
Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
}
if (autorename) {
/* Turn on the autorename mode */
Preprocessor_define((DOH *) "SWIG_RUBY_AUTORENAME", 0);
@ -1316,7 +1300,13 @@ public:
Iterator alias = First(aliases);
while (alias.item) {
if (Len(alias.item) > 0) {
if (multipleInheritance) {
if (current == NO_CPP) {
if (useGlobalModule) {
Printv(f_init, tab4, "rb_define_alias(rb_cObject, \"", alias.item, "\", \"", iname, "\");\n", NIL);
} else {
Printv(f_init, tab4, "rb_define_alias(rb_singleton_class(", modvar, "), \"", alias.item, "\", \"", iname, "\");\n", NIL);
}
} else if (multipleInheritance) {
Printv(klass->init, tab4, "rb_define_alias(", klass->mImpl, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
} else {
Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
@ -2201,6 +2191,12 @@ public:
String *tm;
String *getfname, *setfname;
Wrapper *getf, *setf;
const int assignable = is_assignable(n);
// Determine whether virtual global variables shall be used
// which have different getter and setter signatures,
// see https://docs.ruby-lang.org/en/2.6.0/extension_rdoc.html#label-Global+Variables+Shared+Between+C+and+Ruby
const bool use_virtual_var = (current == NO_CPP && useGlobalModule);
getf = NewWrapper();
setf = NewWrapper();
@ -2211,7 +2207,7 @@ public:
getfname = Swig_name_wrapper(getname);
Setattr(n, "wrap:name", getfname);
Printv(getf->def, "SWIGINTERN VALUE\n", getfname, "(", NIL);
Printf(getf->def, "VALUE self");
Printf(getf->def, (use_virtual_var) ? "ID id, VALUE *data" : "VALUE self");
Printf(getf->def, ") {");
Wrapper_add_local(getf, "_val", "VALUE _val");
@ -2234,8 +2230,8 @@ public:
Wrapper_print(getf, f_wrappers);
if (!is_assignable(n)) {
setfname = NewString("NULL");
if (!assignable) {
setfname = NewString("(rb_gvar_setter_t *)NULL");
} else {
/* create setter */
String* docs = docstring(n, AUTODOC_SETTER);
@ -2245,8 +2241,12 @@ public:
String *setname = Swig_name_set(NSPACE_TODO, iname);
setfname = Swig_name_wrapper(setname);
Setattr(n, "wrap:name", setfname);
Printv(setf->def, "SWIGINTERN VALUE\n", setfname, "(VALUE self, ", NIL);
Printf(setf->def, "VALUE _val) {");
Printf(setf->def, "SWIGINTERN ");
if (use_virtual_var) {
Printv(setf->def, "void\n", setfname, "(VALUE _val, ID id, VALUE *data) {", NIL);
} else {
Printv(setf->def, "VALUE\n", setfname, "(VALUE self, VALUE _val) {", NIL);
}
tm = Swig_typemap_lookup("varin", n, name, 0);
if (tm) {
Replaceall(tm, "$input", "_val");
@ -2257,28 +2257,31 @@ public:
} else {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s\n", SwigType_str(t, 0));
}
Printv(setf->code, tab4, "return _val;\n", NIL);
Printf(setf->code, "fail:\n");
Printv(setf->code, tab4, "return Qnil;\n", NIL);
if (use_virtual_var) {
Printf(setf->code, "fail:\n");
Printv(setf->code, tab4, "return;\n", NIL);
} else {
Printv(setf->code, tab4, "return _val;\n", NIL);
Printf(setf->code, "fail:\n");
Printv(setf->code, tab4, "return Qnil;\n", NIL);
}
Printf(setf->code, "}\n");
Wrapper_print(setf, f_wrappers);
Delete(setname);
}
/* define accessor method */
if (CPlusPlus) {
Insert(getfname, 0, "VALUEFUNC(");
Append(getfname, ")");
Insert(setfname, 0, "VALUEFUNC(");
Append(setfname, ")");
}
/* define accessor methods */
Insert(getfname, 0, "VALUEFUNC(");
Append(getfname, ")");
Insert(setfname, 0, (use_virtual_var) ? "SWIG_RUBY_VOID_ANYARGS_FUNC(" : "VALUEFUNC(");
Append(setfname, ")");
String *s = NewString("");
switch (current) {
case STATIC_VAR:
/* C++ class variable */
Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "\", ", getfname, ", 0);\n", NIL);
if (!GetFlag(n, "feature:immutable")) {
if (assignable) {
Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "=\", ", setfname, ", 1);\n", NIL);
}
Printv(klass->init, s, NIL);
@ -2289,14 +2292,11 @@ public:
assert(current == NO_CPP);
if (!useGlobalModule) {
Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "\", ", getfname, ", 0);\n", NIL);
if (!GetFlag(n, "feature:immutable")) {
if (assignable) {
Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "=\", ", setfname, ", 1);\n", NIL);
}
} else {
Printv(s, tab4, "rb_define_global_method(\"", iname, "\", ", getfname, ", 0);\n", NIL);
if (!GetFlag(n, "feature:immutable")) {
Printv(s, tab4, "rb_define_global_method(\"", iname, "=\", ", setfname, ", 1);\n", NIL);
}
Printv(s, tab4, "rb_define_virtual_variable(\"$", iname, "\", ", getfname, ", ", setfname, ");\n", NIL);
}
Printv(f_init, s, NIL);
Delete(s);
@ -2925,7 +2925,7 @@ public:
Wrapper *w = NewWrapper();
String *call;
String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
String *target = Swig_method_decl(0, decl, classname, parms, 0);
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
Delete(target);
@ -2936,7 +2936,7 @@ public:
/* constructor header */
{
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
String *target = Swig_method_decl(0, decl, classname, parms, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@ -3046,7 +3046,7 @@ public:
if (argc > 0) {
Printf(w->code, "%s = rb_funcall(swig_get_self(), rb_intern(\"%s\"), %d%s);\n", Swig_cresult_name(), methodName, argc, args);
} else {
Printf(w->code, "%s = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, NULL);\n", Swig_cresult_name(), methodName);
Printf(w->code, "%s = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, Qnil);\n", Swig_cresult_name(), methodName);
}
if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n");
}
@ -3102,12 +3102,12 @@ public:
String *pclassname = NewStringf("SwigDirector_%s", classname);
String *qualified_name = NewStringf("%s::%s", pclassname, name);
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
/* header declaration */
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
target = Swig_method_decl(rtype, decl, name, l, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
@ -3188,7 +3188,7 @@ public:
Swig_director_parms_fixup(l);
Swig_typemap_attach_parms("in", l, 0);
Swig_typemap_attach_parms("directorin", l, 0);
Swig_typemap_attach_parms("directorin", l, w);
Swig_typemap_attach_parms("directorargout", l, w);
char source[256];

View file

@ -496,7 +496,7 @@ public:
/* Add the failure cleanup code */
/* TODO */
/* Final substititions if applicable */
/* Final substitutions if applicable */
Replaceall(wrapper->code, "$symname", functionName);
/* Set CheckInputArgument and CheckOutputArgument input arguments */

View file

@ -26,79 +26,62 @@
can be dynamically loaded in future versions. */
extern "C" {
Language *swig_tcl(void);
Language *swig_python(void);
Language *swig_perl5(void);
Language *swig_ruby(void);
Language *swig_csharp(void);
Language *swig_d(void);
Language *swig_go(void);
Language *swig_guile(void);
Language *swig_modula3(void);
Language *swig_mzscheme(void);
Language *swig_java(void);
Language *swig_php(void);
Language *swig_php4(void);
Language *swig_php5(void);
Language *swig_javascript(void);
Language *swig_lua(void);
Language *swig_mzscheme(void);
Language *swig_ocaml(void);
Language *swig_octave(void);
Language *swig_pike(void);
Language *swig_sexp(void);
Language *swig_xml(void);
Language *swig_chicken(void);
Language *swig_csharp(void);
Language *swig_allegrocl(void);
Language *swig_lua(void);
Language *swig_clisp(void);
Language *swig_cffi(void);
Language *swig_uffi(void);
Language *swig_perl5(void);
Language *swig_php(void);
Language *swig_python(void);
Language *swig_r(void);
Language *swig_ruby(void);
Language *swig_scilab(void);
Language *swig_go(void);
Language *swig_d(void);
Language *swig_javascript(void);
Language *swig_tcl(void);
Language *swig_xml(void);
}
struct swig_module {
const char *name;
ModuleFactory fac;
const char *help;
};
/* Association of command line options to language modules.
Place an entry for new language modules here, keeping the
list sorted alphabetically. */
static swig_module modules[] = {
{"-allegrocl", swig_allegrocl, "ALLEGROCL"},
{"-chicken", swig_chicken, "CHICKEN"},
{"-clisp", swig_clisp, "CLISP"},
{"-cffi", swig_cffi, "CFFI"},
{"-csharp", swig_csharp, "C#"},
{"-d", swig_d, "D"},
{"-go", swig_go, "Go"},
{"-guile", swig_guile, "Guile"},
{"-java", swig_java, "Java"},
{"-javascript", swig_javascript, "Javascript"},
{"-lua", swig_lua, "Lua"},
{"-modula3", swig_modula3, "Modula 3"},
{"-mzscheme", swig_mzscheme, "Mzscheme"},
{"-ocaml", swig_ocaml, "Ocaml"},
{"-octave", swig_octave, "Octave"},
{"-perl", swig_perl5, "Perl"},
{"-perl5", swig_perl5, 0},
{"-php", swig_php5, 0},
{"-php4", swig_php4, 0},
{"-php5", swig_php5, "PHP5"},
{"-php7", swig_php, "PHP7"},
{"-pike", swig_pike, "Pike"},
{"-python", swig_python, "Python"},
{"-r", swig_r, "R (aka GNU S)"},
{"-ruby", swig_ruby, "Ruby"},
{"-scilab", swig_scilab, "Scilab"},
{"-sexp", swig_sexp, "Lisp S-Expressions"},
{"-tcl", swig_tcl, "Tcl"},
{"-tcl8", swig_tcl, 0},
{"-uffi", swig_uffi, "Common Lisp / UFFI"},
{"-xml", swig_xml, "XML"},
{NULL, NULL, NULL}
static TargetLanguageModule modules[] = {
{"-allegrocl", NULL, "ALLEGROCL", Disabled},
{"-chicken", NULL, "CHICKEN", Disabled},
{"-clisp", NULL, "CLISP", Disabled},
{"-cffi", NULL, "CFFI", Disabled},
{"-csharp", swig_csharp, "C#", Supported},
{"-d", swig_d, "D", Supported},
{"-go", swig_go, "Go", Supported},
{"-guile", swig_guile, "Guile", Supported},
{"-java", swig_java, "Java", Supported},
{"-javascript", swig_javascript, "Javascript", Supported},
{"-lua", swig_lua, "Lua", Supported},
{"-modula3", NULL, "Modula 3", Disabled},
{"-mzscheme", swig_mzscheme, "MzScheme/Racket", Experimental},
{"-ocaml", swig_ocaml, "OCaml", Experimental},
{"-octave", swig_octave, "Octave", Supported},
{"-perl", swig_perl5, NULL, Supported},
{"-perl5", swig_perl5, "Perl 5", Supported},
{"-php", swig_php, NULL, Supported},
{"-php5", NULL, "PHP 5", Disabled},
{"-php7", swig_php, "PHP 7", Supported},
{"-pike", NULL, "Pike", Disabled},
{"-python", swig_python, "Python", Supported},
{"-r", swig_r, "R (aka GNU S)", Supported},
{"-ruby", swig_ruby, "Ruby", Supported},
{"-scilab", swig_scilab, "Scilab", Supported},
{"-sexp", NULL, "Lisp S-Expressions", Disabled},
{"-tcl", swig_tcl, NULL, Supported},
{"-tcl8", swig_tcl, "Tcl 8", Supported},
{"-uffi", NULL, "Common Lisp / UFFI", Disabled},
{"-xml", swig_xml, "XML", Supported},
{NULL, NULL, NULL, Disabled}
};
#ifdef MACSWIG
@ -106,10 +89,6 @@ static swig_module modules[] = {
#include <SIOUX.h>
#endif
#ifndef SWIG_LANG
#define SWIG_LANG "-python"
#endif
//-----------------------------------------------------------------
// main()
//
@ -119,13 +98,14 @@ static swig_module modules[] = {
void SWIG_merge_envopt(const char *env, int oargc, char *oargv[], int *nargc, char ***nargv) {
if (!env) {
*nargc = oargc;
*nargv = oargv;
*nargv = (char **)malloc(sizeof(char *) * (oargc + 1));
memcpy(*nargv, oargv, sizeof(char *) * (oargc + 1));
return;
}
int argc = 1;
int arge = oargc + 1024;
char **argv = (char **) malloc(sizeof(char *) * (arge));
char **argv = (char **) malloc(sizeof(char *) * (arge + 1));
char *buffer = (char *) malloc(2048);
char *b = buffer;
char *be = b + 1023;
@ -147,49 +127,140 @@ void SWIG_merge_envopt(const char *env, int oargc, char *oargv[], int *nargc, ch
for (int i = 1; (i < oargc) && (argc < arge); ++i, ++argc) {
argv[argc] = oargv[i];
}
argv[argc] = NULL;
*nargc = argc;
*nargv = argv;
}
static void insert_option(int *argc, char ***argv, int index, char const *start, char const *end) {
int new_argc = *argc;
char **new_argv = *argv;
size_t option_len = end - start;
// Preserve the NULL pointer at argv[argc]
new_argv = (char **)realloc(new_argv, (new_argc + 2) * sizeof(char *));
memmove(&new_argv[index + 1], &new_argv[index], sizeof(char *) * (new_argc + 1 - index));
new_argc++;
new_argv[index] = (char *)malloc(option_len + 1);
memcpy(new_argv[index], start, option_len);
new_argv[index][option_len] = '\0';
*argc = new_argc;
*argv = new_argv;
}
static void merge_options_files(int *argc, char ***argv) {
static const int BUFFER_SIZE = 4096;
char buffer[BUFFER_SIZE];
int i;
int insert;
char **new_argv = *argv;
int new_argc = *argc;
FILE *f;
i = 1;
while (i < new_argc) {
if (new_argv[i] && new_argv[i][0] == '@' && (f = fopen(&new_argv[i][1], "r"))) {
int ci;
char *b;
char *be = &buffer[BUFFER_SIZE];
int quote = 0;
bool escape = false;
new_argc--;
memmove(&new_argv[i], &new_argv[i + 1], sizeof(char *) * (new_argc - i));
insert = i;
b = buffer;
while ((ci = fgetc(f)) != EOF) {
const char c = static_cast<char>(ci);
if (escape) {
if (b != be) {
*b = c;
++b;
}
escape = false;
} else if (c == '\\') {
escape = true;
} else if (!quote && (c == '\'' || c == '"')) {
quote = c;
} else if (quote && c == quote) {
quote = 0;
} else if (isspace(c) && !quote) {
if (b != buffer) {
insert_option(&new_argc, &new_argv, insert, buffer, b);
insert++;
b = buffer;
}
} else if (b != be) {
*b = c;
++b;
}
}
if (b != buffer)
insert_option(&new_argc, &new_argv, insert, buffer, b);
fclose(f);
} else {
++i;
}
}
*argv = new_argv;
*argc = new_argc;
}
int main(int margc, char **margv) {
int i;
Language *dl = 0;
ModuleFactory fac = 0;
const TargetLanguageModule *language_module = 0;
int argc;
char **argv;
SWIG_merge_envopt(getenv("SWIG_FEATURES"), margc, margv, &argc, &argv);
merge_options_files(&argc, &argv);
#ifdef MACSWIG
SIOUXSettings.asktosaveonclose = false;
argc = ccommand(&argv);
#endif
/* Register built-in modules */
for (i = 0; modules[i].name; i++) {
Swig_register_module(modules[i].name, modules[i].fac);
}
Swig_init_args(argc, argv);
/* Get options */
for (i = 1; i < argc; i++) {
if (argv[i]) {
fac = Swig_find_module(argv[i]);
if (fac) {
dl = (fac) ();
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nolang") == 0) {
dl = new Language;
bool is_target_language_module = false;
for (int j = 0; modules[j].name; j++) {
if (strcmp(modules[j].name, argv[i]) == 0) {
language_module = &modules[j];
is_target_language_module = true;
break;
}
}
if (is_target_language_module) {
Swig_mark_arg(i);
if (language_module->status == Disabled) {
if (language_module->help)
Printf(stderr, "Target language option %s (%s) is no longer supported.\n", language_module->name, language_module->help);
else
Printf(stderr, "Target language option %s is no longer supported.\n", language_module->name);
SWIG_exit(EXIT_FAILURE);
}
} else if ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) {
if (strcmp(argv[i], "--help") == 0)
strcpy(argv[i], "-help");
Printf(stdout, "Target Language Options\n");
Printf(stdout, "Supported Target Language Options\n");
for (int j = 0; modules[j].name; j++) {
if (modules[j].help) {
if (modules[j].help && modules[j].status == Supported) {
Printf(stdout, " %-15s - Generate %s wrappers\n", modules[j].name, modules[j].help);
}
}
Printf(stdout, "\nExperimental Target Language Options\n");
for (int j = 0; modules[j].name; j++) {
if (modules[j].help && modules[j].status == Experimental) {
Printf(stdout, " %-15s - Generate %s wrappers\n", modules[j].name, modules[j].help);
}
}
@ -197,14 +268,8 @@ int main(int margc, char **margv) {
}
}
}
if (!dl) {
fac = Swig_find_module(SWIG_LANG);
if (fac) {
dl = (fac) ();
}
}
int res = SWIG_main(argc, argv, dl);
int res = SWIG_main(argc, argv, language_module);
return res;
}

View file

@ -214,8 +214,8 @@ public:
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);
virtual Node *classLookup(const SwigType *s) const; /* Class lookup */
virtual Node *enumLookup(SwigType *s); /* Enum lookup */
static Node *classLookup(const SwigType *s); /* Class lookup */
static Node *enumLookup(SwigType *s); /* Enum lookup */
virtual int abstractClassTest(Node *n); /* Is class really abstract? */
virtual int is_assignable(Node *n); /* Is variable assignable? */
virtual String *runtimeCode(); /* returns the language specific runtime code */
@ -342,10 +342,11 @@ protected:
/* Director language module */
int director_language;
/* Used to translate Doxygen comments to target documentation format */
class DoxygenTranslator *doxygenTranslator;
private:
Hash *symtabs; /* symbol tables */
Hash *classtypes;
Hash *enumtypes;
int overloading;
int multiinput;
int cplus_runtime;
@ -353,10 +354,23 @@ private:
static Language *this_;
};
int SWIG_main(int, char **, Language *);
extern "C" {
void SWIG_typemap_lang(const char *);
typedef Language *(*ModuleFactory) (void);
}
enum Status {Disabled, Experimental, Supported};
struct TargetLanguageModule {
const char *name;
ModuleFactory fac;
const char *help;
Status status;
};
int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm);
void emit_parameter_variables(ParmList *l, Wrapper *f);
void emit_return_variable(Node *n, SwigType *rt, Wrapper *f);
void SWIG_exit(int); /* use EXIT_{SUCCESS,FAILURE} */
void SWIG_config_file(const_String_or_char_ptr );
const String *SWIG_output_directory();
void SWIG_config_cppext(const char *ext);
@ -368,15 +382,15 @@ List *SWIG_output_files();
void SWIG_library_directory(const char *);
int emit_num_arguments(ParmList *);
int emit_num_required(ParmList *);
int emit_isvarargs(ParmList *);
int emit_isvarargs(ParmList *p);
bool emit_isvarargs_function(Node *n);
void emit_attach_parmmaps(ParmList *, Wrapper *f);
void emit_mark_varargs(ParmList *l);
String *emit_action(Node *n);
int emit_action_code(Node *n, String *wrappercode, String *action);
void Swig_overload_check(Node *n);
String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *);
String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *, const_String_or_char_ptr fmt_fastdispatch = 0);
String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *);
String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *);
List *Swig_overload_rank(Node *n, bool script_lang_wrapping);
SwigType *cplus_value_type(SwigType *t);
@ -385,20 +399,12 @@ String *Swig_csuperclass_call(String *base, String *method, ParmList *l);
String *Swig_class_declaration(Node *n, String *name);
String *Swig_class_name(Node *n);
String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms);
String *Swig_method_decl(SwigType *rtype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values);
String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args);
String *Swig_director_declaration(Node *n);
void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f);
void Swig_director_parms_fixup(ParmList *parms);
/* directors.cxx end */
extern "C" {
void SWIG_typemap_lang(const char *);
typedef Language *(*ModuleFactory) (void);
}
void Swig_register_module(const char *name, ModuleFactory fac);
ModuleFactory Swig_find_module(const char *name);
/* Utilities */
int is_public(Node *n);

View file

@ -15,7 +15,7 @@
#include "cparse.h"
static const char *usage = "\
Tcl 8 Options (available with -tcl)\n\
Tcl 8 Options (available with -tcl8)\n\
-itcl - Enable ITcl support\n\
-nosafe - Leave out SafeInit module function.\n\
-prefix <name> - Set a prefix <name> to be prepended to all names\n\
@ -76,7 +76,6 @@ public:
* ------------------------------------------------------------ */
virtual void main(int argc, char *argv[]) {
int cppcast = 1;
SWIG_library_directory("tcl");
@ -106,22 +105,19 @@ public:
} else if (strcmp(argv[i], "-nosafe") == 0) {
nosafe = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-cppcast") == 0) {
cppcast = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nocppcast") == 0) {
cppcast = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-help") == 0) {
fputs(usage, stdout);
} else if (strcmp(argv[i], "-cppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nocppcast") == 0) {
Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
Swig_mark_arg(i);
SWIG_exit(EXIT_FAILURE);
}
}
}
if (cppcast) {
Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
}
Preprocessor_define("SWIGTCL 1", 0);
// SWIGTCL8 is deprecated, and no longer documented.
Preprocessor_define("SWIGTCL8 1", 0);

View file

@ -267,6 +267,8 @@ class TypePass:private Dispatcher {
and smart pointer to base class, so that smart pointer upcasts
are automatically generated. */
SwigType *bsmart = Copy(smart);
// TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
SwigType *rbname = SwigType_typedef_resolve_all(bname);
int replace_count = Replaceall(bsmart, rclsname, rbname);
@ -276,6 +278,12 @@ class TypePass:private Dispatcher {
String *firstname = Getattr(first, "name");
Replaceall(bsmart, firstname, rbname);
}
// The code above currently creates a smartptr of the base class by substitution, replacing Derived
// with Base resulting in something like: 'smartptr< Derived >' from 'smartptr< Base >'. Instead
// the feature:smartptr should be used as it also contains 'smartptr< Base >' as specified by the user.
// A similar fix should also be done in upcastsCode in java.cxx, csharp.cxx and writeClassUpcast in d.cxx.
// Printf(stdout, "smartcomparison %s <=> %s\n", SwigType_namestr(bsmart), Getattr(bclass, "feature:smartptr"));
Delete(rclsname);
Delete(rbname);
String *smartnamestr = SwigType_namestr(smart);
@ -961,7 +969,7 @@ class TypePass:private Dispatcher {
if (Getattr(c, "sym:overloaded") != checkoverloaded) {
Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
Swig_print_node(c);
exit (1);
SWIG_exit(EXIT_FAILURE);
}
String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
@ -969,7 +977,7 @@ class TypePass:private Dispatcher {
if (!Getattr(c, "sym:overloaded")) {
Printf(stdout, "sym:overloaded error.....%p\n", c);
Swig_print_node(c);
exit (1);
SWIG_exit(EXIT_FAILURE);
}
c = Getattr(c, "sym:nextSibling");
}

View file

@ -363,23 +363,24 @@ int UFFI::classHandler(Node *n) {
for (c = firstChild(n); c; c = nextSibling(c)) {
SwigType *type = Getattr(c, "type");
SwigType *decl = Getattr(c, "decl");
type = Copy(type);
SwigType_push(type, decl);
String *lisp_type;
if (type) {
type = Copy(type);
SwigType_push(type, decl);
String *lisp_type;
if (Strcmp(nodeType(c), "cdecl")) {
Printf(stderr, "Structure %s has a slot that we can't deal with.\n", name);
Printf(stderr, "nodeType: %s, name: %s, type: %s\n", nodeType(c), Getattr(c, "name"), Getattr(c, "type"));
SWIG_exit(EXIT_FAILURE);
if (Strcmp(nodeType(c), "cdecl")) {
Printf(stderr, "Structure %s has a slot that we can't deal with.\n", name);
Printf(stderr, "nodeType: %s, name: %s, type: %s\n", nodeType(c), Getattr(c, "name"), Getattr(c, "type"));
SWIG_exit(EXIT_FAILURE);
}
/* Printf(stdout, "Converting %s in %s\n", type, name); */
lisp_type = get_ffi_type(n, type, Getattr(c, "sym:name"));
Printf(f_cl, " (#.(%s \"%s\" :type :slot) %s)\n", identifier_converter, Getattr(c, "sym:name"), lisp_type);
Delete(lisp_type);
}
/* Printf(stdout, "Converting %s in %s\n", type, name); */
lisp_type = get_ffi_type(n, type, Getattr(c, "sym:name"));
Printf(f_cl, " (#.(%s \"%s\" :type :slot) %s)\n", identifier_converter, Getattr(c, "sym:name"), lisp_type);
Delete(lisp_type);
}
// Language::classHandler(n);