summaryrefslogtreecommitdiff
path: root/Source/Modules/directors.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Modules/directors.cxx')
-rw-r--r--Source/Modules/directors.cxx288
1 files changed, 288 insertions, 0 deletions
diff --git a/Source/Modules/directors.cxx b/Source/Modules/directors.cxx
new file mode 100644
index 0000000..158b535
--- /dev/null
+++ b/Source/Modules/directors.cxx
@@ -0,0 +1,288 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * directors.cxx
+ *
+ * Director support functions.
+ * Not all of these may be necessary, and some may duplicate existing functionality
+ * in SWIG. --MR
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_directors_cxx[] = "$Id";
+
+#include "swigmod.h"
+
+/* 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("");
+ int arg_idx = 0;
+ Parm *p;
+ if (base) {
+ Printf(call, "%s::", base);
+ }
+ Printf(call, "%s(", method);
+ for (p = l; p; p = nextSibling(p)) {
+ String *pname = Getattr(p, "name");
+ if (!pname && Cmp(Getattr(p, "type"), "void")) {
+ pname = NewString("");
+ Printf(pname, "arg%d", arg_idx++);
+ }
+ if (p != l)
+ Printf(call, ", ");
+ Printv(call, pname, NIL);
+ }
+ Printf(call, ")");
+ return call;
+}
+
+/* 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) {
+ name = Getattr(n, "sym:name");
+ }
+ String *result = NewString("");
+ String *kind = Getattr(n, "kind");
+ Printf(result, "%s %s", kind, name);
+ return result;
+}
+
+String *Swig_class_name(Node *n) {
+ String *name;
+ name = Copy(Getattr(n, "sym:name"));
+ return name;
+}
+
+/* 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);
+ String *directorname = NewStringf("SwigDirector_%s", classname);
+ String *base = Getattr(n, "classtype");
+ String *declaration = Swig_class_declaration(n, directorname);
+ Printf(declaration, " : public %s, public Swig::Director {\n", base);
+ Delete(classname);
+ Delete(directorname);
+ return declaration;
+}
+
+
+String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
+ String *func;
+ int i = 0;
+ int comma = 0;
+ Parm *p = parms;
+ SwigType *pt;
+ String *nname;
+
+ func = NewString("");
+ nname = SwigType_namestr(name);
+ Printf(func, "%s(", nname);
+ while (p) {
+ String *pname;
+ pt = Getattr(p, "type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ if (comma)
+ Printf(func, ",");
+ pname = Getattr(p, "name");
+ Printf(func, "%s", pname);
+ comma = 1;
+ i++;
+ }
+ p = nextSibling(p);
+ }
+ Printf(func, ")");
+ return func;
+}
+
+/* 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.
+ *
+ */
+
+String *Swig_method_decl(SwigType *returntype, 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;
+ 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;
+ }
+ 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 (returntype) { // 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;
+ }
+
+ Delete(elements);
+
+ if (is_const) {
+ if (is_func) {
+ Append(result, " ");
+ Append(result, "const");
+ } else {
+ Insert(result, 0, "const ");
+ }
+ }
+
+ Chop(result);
+
+ if (returntype) {
+ Insert(result, 0, " ");
+ String *rtype = SwigType_str(returntype, 0);
+ Insert(result, 0, rtype);
+ Delete(rtype);
+ }
+
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_director_emit_dynamic_cast()
+ *
+ * In order to call protected virtual director methods from the target language, we need
+ * 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"))) ||
+ (is_non_virtual_protected_access(n) && !(checkAttribute(n, "staticmemberfunctionHandler:storage", "static") ||
+ checkAttribute(n, "storage", "static"))
+ && !Equal(nodeType(n), "constructor"))) {
+ Node *parent = Getattr(n, "parentNode");
+ String *symname = Getattr(parent, "sym:name");
+ String *dirname = NewStringf("SwigDirector_%s", symname);
+ String *dirdecl = NewStringf("%s *darg = 0", dirname);
+ Wrapper_add_local(f, "darg", dirdecl);
+ Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n", dirname);
+ Delete(dirname);
+ Delete(dirdecl);
+ }
+}
+