diff --git a/Source/Modules/Makefile.in b/Source/Modules/Makefile.in
new file mode 100644
index 000000000..353a59699
--- /dev/null
+++ b/Source/Modules/Makefile.in
@@ -0,0 +1,41 @@
+#######################################################################
+# $Header$
+#######################################################################
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+CXX = @CXX@
+CFLAGS = @CFLAGS@ @SWILL@
+YACC = @YACC@
+AR = @AR@
+RANLIB = @RANLIB@
+
+TARGET = libmodules.a
+OBJS = main.@OBJEXT@ module.@OBJEXT@ emit.@OBJEXT@ overload.@OBJEXT@ lang.@OBJEXT@ typepass.@OBJEXT@ allocate.@OBJEXT@ browser.@OBJEXT@ contract.@OBJEXT@ swigmain.@OBJEXT@ tcl8.@OBJEXT@ python.@OBJEXT@ perl5.@OBJEXT@ guile.@OBJEXT@ ruby.@OBJEXT@ mzscheme.@OBJEXT@ java.@OBJEXT@ php4.@OBJEXT@ ocaml.@OBJEXT@ xml.@OBJEXT@ pike.@OBJEXT@ s-exp.@OBJEXT@
+SRCS = main.cxx module.cxx emit.cxx overload.cxx lang.cxx typepass.cxx allocate.cxx browser.cxx contract.cxx swigmain.cxx tcl8.cxx python.cxx perl5.cxx guile.cxx ruby.cxx mzscheme.cxx java.cxx php4.cxx ocaml.cxx xml.cxx pike.cxx s-exp.cxx
+
+INCLUDES = -I$(srcdir)/../Include \
+ -I$(srcdir)/../DOH/Include \
+ -I$(srcdir)/../Preprocessor \
+ -I$(srcdir)/../Swig \
+ -I../Include
+
+# Rules for creation of a .@OBJEXT@ file from .cxx
+.SUFFIXES: .cxx
+.cxx.@OBJEXT@:
+ $(CXX) $(INCLUDES) $(CFLAGS) -c -o $*.@OBJEXT@ $<
+
+
+swig: $(TARGET)
+
+$(TARGET): $(OBJS)
+ $(AR) cr $(TARGET) $(OBJS)
+ $(RANLIB) $(TARGET)
+
+clean::
+ rm -f *.@OBJEXT@ *~ $(TARGET)
+
+nuke::
+ rm -f Makefile *~
diff --git a/Source/Modules/README b/Source/Modules/README
new file mode 100644
index 000000000..058779d22
--- /dev/null
+++ b/Source/Modules/README
@@ -0,0 +1,9 @@
+06/25/2002
+
+This directory contains all of the SWIG language modules. Many of these
+modules contain code that dates back to SWIG1.0. The module API has changed
+a lot in the development releases so this is fairly messy. We're working on
+cleaning it up, but you'll have to bear with us until it's done.
+
+-- Dave
+
diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx
new file mode 100644
index 000000000..4d7db5fae
--- /dev/null
+++ b/Source/Modules/allocate.cxx
@@ -0,0 +1,453 @@
+/* -----------------------------------------------------------------------------
+ * allocate.cxx
+ *
+ * This module tries to figure out which classes and structures support
+ * default constructors and destructors in C++. There are several rules that
+ * define this behavior including pure abstract methods, private sections,
+ * and non-default constructors in base classes. See the ARM or
+ * Doc/Manual/SWIGPlus.html for details.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1998-2002. The University of Chicago
+ * Copyright (C) 1995-1998. The University of Utah and The Regents of the
+ * University of California.
+ *
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_allocate_cxx[] = "$Header$";
+
+#include "swigmod.h"
+
+class Allocate : public Dispatcher {
+ Node *inclass;
+ enum AccessMode { PUBLIC, PRIVATE, PROTECTED };
+ AccessMode cplus_mode;
+ int extendmode;
+
+ /* Checks to see if a class is abstract through inheritance */
+ int is_abstract_inherit(Node *n, Node *base = 0, int first = 0) {
+ if (!first && (base == n)) return 0;
+ if (!base) {
+ /* Root node */
+ Symtab *stab = Getattr(n,"symtab"); /* Get symbol table for node */
+ Symtab *oldtab = Swig_symbol_setscope(stab);
+ int ret = is_abstract_inherit(n,n,1);
+ Swig_symbol_setscope(oldtab);
+ return ret;
+ }
+ List *abstract = Getattr(base,"abstract");
+ if (abstract) {
+ for (int i = 0; i < Len(abstract); i++) {
+ Node *nn = Getitem(abstract,i);
+ String *name = Getattr(nn,"name");
+ String *base_decl = Getattr(nn,"decl");
+ if (Strstr(name,"~")) continue; /* Don't care about destructors */
+ int implemented = 0;
+ Node *dn = Swig_symbol_clookup(name,0);
+ if (!dn) {
+ Printf(stdout,"node: %x '%s'. base: %x '%s'. member '%s'\n", n, Getattr(n,"name"), base, Getattr(base,"name"), name);
+ }
+ assert(dn); // Assertion of doom
+ while (dn && !implemented) {
+ String *local_decl = Getattr(dn,"decl");
+ if (local_decl && !Strcmp(local_decl, base_decl)) {
+ if (Getattr(dn,"abstract")) return 1;
+ implemented++;
+ }
+ dn = Getattr(dn,"csym:nextSibling");
+ }
+ if (!implemented && (Getattr(nn,"abstract"))) {
+ return 1;
+ }
+ /*
+ if (dn && (Getattr(dn,"abstract"))) {
+ return 1;
+ }
+ */
+ }
+ }
+ List *bases = Getattr(base,"bases");
+ if (!bases) return 0;
+ for (int i = 0; i < Len(bases); i++) {
+ if (is_abstract_inherit(n,Getitem(bases,i))) {
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+
+ /* Grab methods used by smart pointers */
+
+ List *smart_pointer_methods(Node *cls, List *methods) {
+ if (!methods) {
+ methods = NewList();
+ }
+
+ Node *c = firstChild(cls);
+ String *kind = Getattr(cls,"kind");
+ int mode;
+ if (Strcmp(kind,"class") == 0) mode = PRIVATE;
+ else mode = PUBLIC;
+
+ while (c) {
+ if (Getattr(c,"error") || Getattr(c,"feature:ignore")) {
+ c = nextSibling(c);
+ continue;
+ }
+ if (Strcmp(nodeType(c),"cdecl") == 0) {
+ if (!Getattr(c,"feature:ignore")) {
+ String *storage = Getattr(c,"storage");
+ if (!((Cmp(storage,"static") == 0) || (Cmp(storage,"typedef") == 0))) {
+ String *name = Getattr(c,"name");
+ String *symname = Getattr(c,"sym:name");
+ Node *e = Swig_symbol_clookup_local(name,0);
+ if (e && !Getattr(e,"feature:ignore") && (Cmp(symname, Getattr(e,"sym:name")) == 0)) {
+ Swig_warning(WARN_LANG_DEREF_SHADOW,Getfile(e),Getline(e),"Declaration of '%s' shadows declaration accessible via operator->() at %s:%d\n",
+ name, Getfile(c),Getline(c));
+ } else {
+ /* Make sure node with same name doesn't already exist */
+ int k;
+ int match = 0;
+ for (k = 0; k < Len(methods); k++) {
+ e = Getitem(methods,k);
+ if (Cmp(symname,Getattr(e,"sym:name")) == 0) {
+ match = 1;
+ break;
+ }
+ if ((!symname || (!Getattr(e,"sym:name"))) && (Cmp(name,Getattr(e,"name")) == 0)) {
+ match = 1;
+ break;
+ }
+ }
+ if (!match) {
+ Node *cc = c;
+ while (cc) {
+ Append(methods,cc);
+ cc = Getattr(cc,"sym:nextSibling");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (Strcmp(nodeType(c),"access") == 0) {
+ kind = Getattr(c,"kind");
+ if (Strcmp(kind,"public") == 0) mode = PUBLIC;
+ else mode = PRIVATE;
+ }
+ c = nextSibling(c);
+ }
+ /* Look for methods in base classes */
+ {
+ Node *bases = Getattr(cls,"bases");
+ int k;
+ for (k = 0; k < Len(bases); k++) {
+ smart_pointer_methods(Getitem(bases,k),methods);
+ }
+ }
+ /* Remove protected/private members */
+ {
+ for (int i = 0; i < Len(methods); ) {
+ Node *n = Getitem(methods,i);
+ if (checkAttribute(n,"access","protected") || checkAttribute(n,"access","private")) {
+ Delitem(methods,i);
+ continue;
+ }
+ i++;
+ }
+ }
+ return methods;
+ }
+
+ void mark_exception_classes(ParmList *p) {
+ while(p) {
+ SwigType *ty = Getattr(p,"type");
+ SwigType *t = SwigType_typedef_resolve_all(ty);
+ Node *c = Swig_symbol_clookup(t,0);
+ if (c) {
+ Setattr(c,"cplus:exceptionclass","1");
+ }
+ p = nextSibling(p);
+ }
+ }
+
+public:
+ virtual int top(Node *n) {
+ cplus_mode = PUBLIC;
+ inclass = 0;
+ extendmode = 0;
+ emit_children(n);
+ return SWIG_OK;
+ }
+
+ virtual int importDirective(Node *n) { return emit_children(n); }
+ virtual int includeDirective(Node *n) { return emit_children(n); }
+ virtual int externDeclaration(Node *n) { return emit_children(n); }
+ virtual int namespaceDeclaration(Node *n) { return emit_children(n); }
+ virtual int extendDirective(Node *n) {
+ extendmode = 1;
+ emit_children(n);
+ extendmode = 0;
+ return SWIG_OK;
+ }
+
+ virtual int classDeclaration(Node *n) {
+ Symtab *symtab = Swig_symbol_current();
+ Swig_symbol_setscope(Getattr(n,"symtab"));
+
+ if (!CPlusPlus) {
+ /* Always have default constructors/destructors in C */
+ Setattr(n,"allocate:default_constructor","1");
+ Setattr(n,"allocate:default_destructor","1");
+ }
+
+ if (Getattr(n,"allocate:visit")) return SWIG_OK;
+ Setattr(n,"allocate:visit","1");
+
+ /* Always visit base classes first */
+ {
+ List *bases = Getattr(n,"bases");
+ if (bases) {
+ for (int i = 0; i < Len(bases); i++) {
+ Node *b = Getitem(bases,i);
+ classDeclaration(b);
+ }
+ }
+ }
+
+ inclass = n;
+ String *kind = Getattr(n,"kind");
+ if (Strcmp(kind,"class") == 0) {
+ cplus_mode = PRIVATE;
+ } else {
+ cplus_mode = PUBLIC;
+ }
+
+ emit_children(n);
+
+ /* Check if the class is abstract via inheritance. This might occur if a class didn't have
+ any pure virtual methods of its own, but it didn't implement all of the pure methods in
+ a base class */
+
+ if (is_abstract_inherit(n)) {
+ if ((!Getattr(n,"abstract")) && ((Getattr(n,"allocate:public_constructor") || (!Getattr(n,"feature:nodefault") && !Getattr(n,"allocate:has_constructor"))))) {
+ if (!Getattr(n,"feature:notabstract")) {
+ Swig_warning(WARN_TYPE_ABSTRACT,Getfile(n),Getline(n),"Class '%s' might be abstract. No constructors generated. \n", SwigType_namestr(Getattr(n,"name")));
+ Setattr(n,"abstract",NewList());
+ }
+ }
+ }
+
+ if (!Getattr(n,"allocate:has_constructor")) {
+ /* No constructor is defined. We need to check a few things */
+ /* If class is abstract. No default constructor. Sorry */
+ if (Getattr(n,"abstract")) {
+ Delattr(n,"allocate:default_constructor");
+ }
+ if (!Getattr(n,"allocate:default_constructor")) {
+ /* Check base classes */
+ List *bases = Getattr(n,"bases");
+ int allows_default = 1;
+
+ for (int i = 0; i < Len(bases); i++) {
+ Node *n = Getitem(bases,i);
+ /* If base class does not allow default constructor, we don't allow it either */
+ if (!Getattr(n,"allocate:default_constructor") && (!Getattr(n,"allocate:default_base_constructor"))) {
+ allows_default = 0;
+ }
+ }
+ if (allows_default) {
+ Setattr(n,"allocate:default_constructor","1");
+ }
+ }
+ }
+ if (!Getattr(n,"allocate:has_destructor")) {
+ /* No destructor was defined. We need to check a few things here too */
+ List *bases = Getattr(n,"bases");
+ int allows_destruct = 1;
+
+ for (int i = 0; i < Len(bases); i++) {
+ Node *n = Getitem(bases,i);
+ /* If base class does not allow default destructor, we don't allow it either */
+ if (!Getattr(n,"allocate:default_destructor") && (!Getattr(n,"allocate:default_base_destructor"))) {
+ allows_destruct = 0;
+ }
+ }
+ if (allows_destruct) {
+ Setattr(n,"allocate:default_destructor","1");
+ }
+ }
+
+
+ /* Check if base classes allow smart pointers, but might be hidden */
+ if (!Getattr(n,"allocate:smartpointer")) {
+ Node *sp = Swig_symbol_clookup((char*)"operator ->",0);
+ if (sp) {
+ /* Look for parent */
+ Node *p = parentNode(sp);
+ if (Strcmp(nodeType(p),"extend") == 0) {
+ p = parentNode(p);
+ }
+ if (Strcmp(nodeType(p),"class") == 0) {
+ if (Getattr(p,"feature:ignore")) {
+ Setattr(n,"allocate:smartpointer",Getattr(p,"allocate:smartpointer"));
+ }
+ }
+ }
+ }
+
+ /* Only care about default behavior. Remove temporary values */
+ Setattr(n,"allocate:visit","1");
+ inclass = 0;
+ Swig_symbol_setscope(symtab);
+ return SWIG_OK;
+ }
+
+ virtual int accessDeclaration(Node *n) {
+ String *kind = Getattr(n,"kind");
+ if (Cmp(kind,"public") == 0) {
+ cplus_mode = PUBLIC;
+ } else if (Cmp(kind,"private") == 0) {
+ cplus_mode = PRIVATE;
+ } else if (Cmp(kind,"protected") == 0) {
+ cplus_mode = PROTECTED;
+ }
+ return SWIG_OK;
+ }
+
+ virtual int cDeclaration(Node *n) {
+
+ mark_exception_classes(Getattr(n,"throws"));
+
+ if (inclass) {
+ String *name = Getattr(n,"name");
+ if (cplus_mode != PUBLIC) {
+ /* Look for a private assignment operator */
+ if (Strcmp(name,"operator =") == 0) {
+ Setattr(inclass,"allocate:noassign","1");
+ }
+ } else {
+ /* Look for smart pointer operator */
+ if ((Strcmp(name,"operator ->") == 0) && (!Getattr(n,"feature:ignore"))) {
+ /* Look for version with no parameters */
+ Node *sn = n;
+ while (sn) {
+ if (!Getattr(sn,"parms")) {
+ SwigType *type = SwigType_typedef_resolve_all(Getattr(sn,"type"));
+ SwigType_push(type,Getattr(sn,"decl"));
+ Delete(SwigType_pop_function(type));
+ SwigType *base = SwigType_base(type);
+ Node *sc = Swig_symbol_clookup(base, 0);
+ if ((sc) && (Strcmp(nodeType(sc),"class") == 0)) {
+ if (SwigType_check_decl(type,"p.")) {
+ List *methods = smart_pointer_methods(sc,0);
+ Setattr(inclass,"allocate:smartpointer",methods);
+ break;
+ } else {
+ /* Hmmm. The return value is not a pointer. If the type is a value
+ or reference. We're going to chase it to see if another operator->()
+ can be found */
+
+ if ((SwigType_check_decl(type,"")) || (SwigType_check_decl(type,"r."))) {
+ Node *nn = Swig_symbol_clookup((char*)"operator ->", Getattr(sc,"symtab"));
+ if (nn) {
+ sn = nn;
+ continue;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ virtual int constructorDeclaration(Node *n) {
+ if (!inclass) return SWIG_OK;
+ Parm *parms = Getattr(n,"parms");
+
+ mark_exception_classes(Getattr(n,"throws"));
+ if (!extendmode) {
+ if (!ParmList_numrequired(parms)) {
+ /* Class does define a default constructor */
+ /* However, we had better see where it is defined */
+ if (cplus_mode == PUBLIC) {
+ Setattr(inclass,"allocate:default_constructor","1");
+ } else if (cplus_mode == PROTECTED) {
+ Setattr(inclass,"allocate:default_base_constructor","1");
+ }
+ }
+ /* Class defines some kind of constructor. May or may not be public */
+ Setattr(inclass,"allocate:has_constructor","1");
+ if (cplus_mode == PUBLIC) {
+ Setattr(inclass,"allocate:public_constructor","1");
+ }
+ }
+
+ /* See if this is a copy constructor */
+ if (parms && (ParmList_numrequired(parms) == 1)) {
+ /* Look for a few cases. X(const X &), X(X &), X(X *) */
+
+ String *cc = NewStringf("r.q(const).%s", Getattr(inclass,"name"));
+ if (Strcmp(cc,Getattr(parms,"type")) == 0) {
+ Setattr(n,"copy_constructor","1");
+ }
+ Delete(cc);
+ cc = NewStringf("r.%s", Getattr(inclass,"name"));
+ if (Strcmp(cc,Getattr(parms,"type")) == 0) {
+ Setattr(n,"copy_constructor","1");
+ }
+ Delete(cc);
+ cc = NewStringf("p.%s", Getattr(inclass,"name"));
+ String *ty = SwigType_strip_qualifiers(Getattr(parms,"type"));
+ if (Strcmp(cc,ty) == 0) {
+ Setattr(n,"copy_constructor","1");
+ }
+ Delete(cc);
+ Delete(ty);
+ }
+ return SWIG_OK;
+ }
+
+ virtual int destructorDeclaration(Node *n) {
+ if (!inclass) return SWIG_OK;
+ if (!extendmode) {
+ Setattr(inclass,"allocate:has_destructor","1");
+ if (cplus_mode == PUBLIC) {
+ Setattr(inclass,"allocate:default_destructor","1");
+ } else if (cplus_mode == PROTECTED) {
+ Setattr(inclass,"allocate:default_base_destructor","1");
+ }
+ }
+ return SWIG_OK;
+ }
+};
+
+void Swig_default_allocators(Node *n) {
+ if (!n) return;
+ Allocate *a = new Allocate;
+ a->top(n);
+ delete a;
+}
+
+
+
+
+
+
+
diff --git a/Source/Modules/browser.cxx b/Source/Modules/browser.cxx
new file mode 100644
index 000000000..da90a81b8
--- /dev/null
+++ b/Source/Modules/browser.cxx
@@ -0,0 +1,415 @@
+/* -----------------------------------------------------------------------------
+ * browser.cxx
+ *
+ * A web-base parse tree browser using SWILL. This is an optional
+ * feature that's normally disabled.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 2002. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_browser_cxx[] = "$Header$";
+
+#include "swigmod.h"
+
+#ifdef SWIG_SWILL
+extern "C" {
+#include "swill.h"
+}
+
+static FILE *out = 0;
+static Node *view_top = 0;
+
+class Browser : public Dispatcher {
+ void show_checkbox(Node *t, Node *n) {
+ int v = 0;
+ if (Getmeta(n,"visible")) {
+ v = 1;
+ }
+ if (v) {
+ Printf(out,"[-] ", n, t, n,n);
+ } else {
+ Printf(out,"[+] ", n, t, n,n);
+ }
+ }
+ void show_attributes(Node *obj) {
+ if (!Getmeta(obj,"visible")) return;
+ String *os = NewString("");
+ String *k;
+ k = Firstkey(obj);
+ while (k) {
+ if ((Cmp(k,"nodeType") == 0) || (Cmp(k,"firstChild") == 0) || (Cmp(k,"lastChild") == 0) ||
+ (Cmp(k,"parentNode") == 0) || (Cmp(k,"nextSibling") == 0) ||
+ (Cmp(k,"previousSibling") == 0) || (*(Char(k)) == '$')) {
+ /* Do nothing */
+ } else if (Cmp(k,"parms") == 0) {
+ String *o = NewString("");
+ Printf(o,"%s", ParmList_protostr(Getattr(obj,k)));
+ Replaceall(o,"&","&");
+ Replaceall(o,"<","<");
+ Replaceall(o,">",">");
+ Printf(os,"? %-12s - %s\n", Getattr(obj,k), k, o);
+ Delete(o);
+ } else {
+ DOH *o;
+ char *trunc = "";
+ if (DohIsString(Getattr(obj,k))) {
+ o = Str(Getattr(obj,k));
+ if (Len(o) > 70) {
+ trunc = "...";
+ }
+ Replaceall(o,"&","&");
+ Replaceall(o,"<","<");
+ Printf(os,"? %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj,k), k, o, trunc);
+ Delete(o);
+ } else {
+ Printf(os,"? %-12s - 0x%x\n", Getattr(obj,k), k, Getattr(obj,k));
+ }
+ }
+ k = Nextkey(obj);
+ }
+ Printf(out,"\n%s
\n", Char(os));
+ Delete(os);
+ }
+
+public:
+ virtual int emit_one(Node *n) {
+ char *tag = Char(nodeType(n));
+ char *file = Char(Getfile(n));
+ int line = Getline(n);
+ char *name = GetChar(n,"name");
+
+ show_checkbox(view_top, n);
+ Printf(out,"%s", n, tag);
+ if (name) {
+ Printf(out," (%s)", name);
+ }
+ Printf(out,". %s:%d\n", file, line);
+ Printf(out,"
");
+ Dispatcher::emit_one(n);
+ return SWIG_OK;
+ }
+ virtual int emit_children(Node *n) {
+ if (Getmeta(n,"visible")) {
+ Printf(out,"
\n");
+ Dispatcher::emit_children(n);
+ Printf(out,"
\n");
+ }
+ return SWIG_OK;
+ }
+ virtual int defaultHandler(Node *n) {
+ show_attributes(n);
+ return SWIG_OK;
+ }
+ virtual int top(Node *n) {
+ show_attributes(n);
+ emit_children(n);
+ return SWIG_OK;
+ }
+ virtual int includeDirective(Node *n) {
+ show_attributes(n);
+ emit_children(n);
+ return SWIG_OK;
+ }
+ virtual int importDirective(Node *n) {
+ show_attributes(n);
+ emit_children(n);
+ return SWIG_OK;
+ }
+
+ virtual int extendDirective(Node *n) {
+ show_attributes(n);
+ emit_children(n);
+ return SWIG_OK;
+ }
+ virtual int classDeclaration(Node *n) {
+ show_attributes(n);
+ emit_children(n);
+ return SWIG_OK;
+ }
+
+ virtual int templateDeclaration(Node *n) {
+ show_attributes(n);
+ emit_children(n);
+ return SWIG_OK;
+ }
+
+ virtual int enumDeclaration(Node *n) {
+ show_attributes(n);
+ emit_children(n);
+ return SWIG_OK;
+ }
+ virtual int typemapDirective(Node *n) {
+ show_attributes(n);
+ emit_children(n);
+ return SWIG_OK;
+ }
+ virtual int namespaceDeclaration(Node *n) {
+ show_attributes(n);
+ emit_children(n);
+ return SWIG_OK;
+ }
+ virtual int usingDeclaration(Node *n) {
+ show_attributes(n);
+ emit_children(n);
+ return SWIG_OK;
+ }
+
+};
+
+static int browser_exit = 0;
+static Node *tree_top = 0;
+static Browser *browse = 0;
+
+/* ----------------------------------------------------------------------
+ * exit_handler() - Force the browser to exit
+ * ---------------------------------------------------------------------- */
+
+void exit_handler(FILE *f) {
+ browser_exit = 1;
+ Printf(f,"Terminated.\n");
+}
+
+/* ----------------------------------------------------------------------
+ * node_handler() - Generate information about a specific node
+ * ---------------------------------------------------------------------- */
+
+static void display(FILE *f, Node *n) {
+ /* Print standard HTML header */
+
+ Printf(f,"SWIG-%s\n", SWIG_VERSION);
+ Printf(f,"SWIG-%s
\n", SWIG_VERSION);
+ Printf(f,"[ Exit ]");
+ Printf(f," [ Top ]", tree_top);
+ if (n != tree_top) {
+ Printf(f," [ Up ]", parentNode(n));
+ }
+ Printf(f," [ Symbols ]");
+ Printf(f,"
\n");
+
+ out = f;
+
+ browse->emit_one(n);
+
+ /* Print standard footer */
+ Printf(f,"
\n");
+
+}
+
+void node_handler(FILE *f) {
+ Node *n = 0;
+ if (!swill_getargs("p(node)", &n)) {
+ n = tree_top;
+ }
+ view_top = n;
+ display(f,n);
+}
+
+
+/* ----------------------------------------------------------------------
+ * hide_handler() - Hide a node
+ * ---------------------------------------------------------------------- */
+
+void hide_handler(FILE *f) {
+ Node *n = 0;
+ if (!swill_getargs("p(hn)", &n)) {
+ n = 0;
+ }
+ if (n) {
+ Delmeta(n,"visible");
+ }
+ node_handler(f);
+}
+
+void show_handler(FILE *f) {
+ Node *n = 0;
+ if (!swill_getargs("p(hn)", &n)) {
+ n = 0;
+ }
+ if (n) {
+ Setmeta(n,"visible","1");
+ }
+ node_handler(f);
+}
+
+void raw_data(FILE *out, Node *obj) {
+ if (!obj) return;
+ if (DohIsMapping(obj)) {
+ String *k;
+ String *os = NewString("");
+ Printf(os,"Hash {\n");
+ k = Firstkey(obj);
+ while (k) {
+ DOH *o;
+ const char *trunc = "";
+ if (DohIsString(Getattr(obj,k))) {
+ o = Str(Getattr(obj,k));
+ if (Len(o) > 70) {
+ trunc = "...";
+ }
+ Replaceall(o,"<","<");
+ Printf(os," ? %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj,k), k, o, trunc);
+ Delete(o);
+ } else {
+ Printf(os," ? %-12s - 0x%x\n", Getattr(obj,k), k, Getattr(obj,k));
+ }
+ k = Nextkey(obj);
+ }
+ Printf(os,"}\n");
+ Printf(out,"\n%s
\n", Char(os));
+ Delete(os);
+ } else if (DohIsString(obj)) {
+ String *o = Str(obj);
+ Replaceall(o,"<","<");
+ Printf(out,"\n%s
\n", Char(o));
+ Delete(o);
+ } else if (DohIsSequence(obj)) {
+ int i;
+ String *os = NewString("");
+ Printf(os,"List [\n");
+ for (i = 0; i < Len(obj); i++) {
+ DOH *o = Getitem(obj,i);
+ const char *trunc = "";
+ if (DohIsString(o)) {
+ String *s = Str(o);
+ if (Len(s) > 70) {
+ trunc = "...";
+ }
+ Replaceall(o,"<","<");
+ Printf(os," ? [%d] - \"%(escape)-0.70s%s\"\n", o,i,s, trunc);
+ Delete(s);
+ } else {
+ Printf(os," ? [%d] - 0x%x\n", o, i, o);
+ }
+ }
+ Printf(os,"\n]\n");
+ Printf(out,"\n%s
\n", Char(os));
+ Delete(os);
+ }
+}
+
+void data_handler(FILE *f) {
+ DOH *n = 0;
+ if (!swill_getargs("p(n)", &n)) {
+ n = 0;
+ }
+ Printf(f,"SWIG-%s\n", SWIG_VERSION);
+ Printf(f,"SWIG-%s
\n", SWIG_VERSION);
+ Printf(f,"[ Exit ]");
+ Printf(f," [ Top ]", tree_top);
+ Printf(f,"
\n");
+ if (n) {
+ raw_data(f,n);
+ }
+ /* Print standard footer */
+ Printf(f,"
\n");
+}
+
+void symbol_handler(FILE *f) {
+ Symtab *sym;
+ char *name = 0;
+
+ Printf(f,"SWIG-%s\n", SWIG_VERSION);
+ Printf(f,"SWIG-%s
\n", SWIG_VERSION);
+ Printf(f,"[ Exit ]");
+ Printf(f," [ Top ]", tree_top);
+ Printf(f," [ Symbols ]");
+ Printf(f,"
\n");
+
+ if (!swill_getargs("p(sym)|s(name)", &sym, &name)) {
+ sym = Swig_symbol_getscope("");
+ name = 0;
+ }
+ if (!sym) {
+ Printf(f,"No symbol table specified!\n");
+ return;
+ }
+ {
+ String *q = Swig_symbol_qualifiedscopename(sym);
+ if (!Len(q)) {
+ Printf(f,"Symbol table: :: (global)
\n");
+ } else {
+ Printf(f,"Symbol table: %s
\n", q);
+ }
+ Delete(q);
+ }
+
+ fprintf(f,"
");
+
+ if (name) {
+ Node *n = Swig_symbol_clookup(name,sym);
+ Printf(f,"Symbol '%s':\n", name);
+ Printf(f,"\n");
+ if (!n) {
+ Printf(f,"Not defined!\n");
+ } else {
+ raw_data(f,n);
+ }
+ Printf(f,"
\n");
+ }
+
+ Printf(f,"Nested scopes
\n");
+ Printf(f,"
\n");
+ {
+ Hash *h;
+ h = firstChild(sym);
+ while (h) {
+ Printf(f,"%s\n", h, Getattr(h,"name"));
+ h = nextSibling(h);
+ }
+ }
+ Printf(f,"
\n");
+
+ Printf(f,"Symbol table contents\n");
+ raw_data(f,Getattr(sym,"symtab"));
+ Printf(f,"
\n");
+
+}
+#endif
+
+void
+Swig_browser(Node *top, int port) {
+#ifdef SWIG_SWILL
+ int sport;
+ browser_exit = 0;
+
+ /* Initialize the server */
+ sport = swill_init(port);
+ if (sport < 0) {
+ Printf(stderr,"Couldn't open socket on port %d. Sorry.\n", port);
+ return;
+ }
+ browse = new Browser();
+ Setmeta(top,"visible","1");
+ tree_top = top;
+
+ Printf(stderr,"SWIG: Tree browser listening on port %d\n", sport);
+
+ swill_handle("exit.html", exit_handler,0);
+ swill_handle("index.html", node_handler, 0);
+ swill_handle("hide.html", hide_handler,0);
+ swill_handle("show.html", show_handler,0);
+ swill_handle("data.html", data_handler,0);
+ swill_handle("symbol.html", symbol_handler, 0);
+ swill_netscape("index.html");
+
+ while (!browser_exit) {
+ swill_serve();
+ }
+ Printf(stderr,"Browser terminated.\n");
+ swill_close();
+ delete browse;
+ return;
+#endif
+}
+
+
+
+
+
diff --git a/Source/Modules/contract.cxx b/Source/Modules/contract.cxx
new file mode 100644
index 000000000..fba5827aa
--- /dev/null
+++ b/Source/Modules/contract.cxx
@@ -0,0 +1,118 @@
+/* -----------------------------------------------------------------------------
+ * contract.cxx
+ *
+ * Experimental support for contracts
+ *
+ * Author(s) : Aquinas Hobor (aahobor@cs.uchicago.edu)
+ *
+ * Copyright (C) 1999-2000. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_contract_cxx[] = "$Header$";
+
+#include "swigmod.h"
+
+class Contracts : public Dispatcher {
+
+public:
+ virtual int top(Node *n) {
+ emit_children(n);
+ return SWIG_OK;
+ }
+
+ virtual int importDirective(Node *n) { return emit_children(n); }
+ virtual int includeDirective(Node *n) { return emit_children(n); } // ?
+ virtual int externDeclaration(Node *n) { return emit_children(n); }
+
+ String * strParms(ParmList *l) {
+ int comma = 0;
+ int i = 0;
+ Parm *p = l;
+ SwigType *pt;
+ String * returns = NewString("");
+ while(p) {
+ String *pname;
+ pt = Getattr(p,"type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ if (comma) Printf(returns,",");
+ pname = Swig_cparm_name(p,i);
+ Printf(returns,"%s",SwigType_rcaststr(pt,pname));
+ comma = 1;
+ i++;
+ }
+ p = nextSibling(p);
+ }
+ return returns;
+ }
+
+ virtual int cDeclaration(Node *n) {
+ String *name = Getattr(n,"name");
+ String *k = Getattr(n,"feature:contract");
+
+ if(k)
+ {
+ /* make the names */
+ ParmList *l = Getmeta(k,"parms");
+ String *params = ParmList_str(l);
+ String *transformed = strParms(l);
+ if(DohStrcmp(params,"")==0) {
+ DohDelete(params);
+ params = DohNewString("void");
+ }
+ String *contractName = DohNewStringf("__SWIG_precontract_%s",name);
+
+ /* make the contract */
+ String *contract = DohNewStringf("int %s(%s,int rt[2])\n{\n",contractName,params);
+ SwigScanner * ss = NewSwigScanner();
+ SwigScanner_clear(ss);
+ SwigScanner_push(ss,Copy(k));
+ SwigScanner_token(ss); // Get rid of the '{' at the begining
+
+ /* loop over the clauses */
+ int clauseNum = 1;
+ int token = -1;
+ while(1) {
+ String *clause = DohNewString(""); /*BUG -- should free*/
+ while((token=SwigScanner_token(ss))) {
+ if ((token==SWIG_TOKEN_SEMI)||(token==SWIG_TOKEN_RBRACE))
+ break;
+ // if (token != SWIG_TOKEN_ENDLINE)
+ Printf(clause,"%s",SwigScanner_text(ss));
+ }
+ if (DohStrcmp(clause,"\n") != 0) {
+ Printf(contract,"if (!(%s",clause);
+ Printf(contract,")) {\nrt[0]=__LINE__;\nrt[1]=%i;\nreturn 1;\n}\n",clauseNum);
+ }
+ if(token==SWIG_TOKEN_RBRACE) break;
+ clauseNum++;
+ }
+
+ /* finish it off and attach it to the main tree */
+ Printf(contract,"return 0;\n}\n");
+ Setattr(n,"wrap:code",contract); /*BUG -- WHAT IF SOMETHING IS ALREADY THERE*/
+
+ /* Generate the calling code */
+ String * calling = DohNewString("{\nint cfail[2];\nchar message[255];\n");
+ Printf(calling,"if (%s(%s,cfail)) {\n",contractName,transformed);
+ Printf(calling,"sprintf(message,\"Contract %s failed on clause %%i (line %%i)!\",cfail[1],cfail[0]);\n",contractName);
+ Printf(calling,"PyErr_SetString(PyExc_Exception,message);return NULL;\n}\n");
+ Printf(calling,"}\n");
+ /* Setattr(n,"feature:preassert",calling); */
+ }
+ /*There are two attributes "feature:preassert" and "feature:postassert".*/
+
+
+ return SWIG_OK;
+ }
+
+};
+
+void Swig_contracts(Node *n) {
+ Printf(stdout,"Applying contracts (experimental v0.09)\n");
+
+ Contracts *a = new Contracts;
+ a->top(n);
+ delete a;
+
+}
diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx
new file mode 100644
index 000000000..1f4bcf8bb
--- /dev/null
+++ b/Source/Modules/emit.cxx
@@ -0,0 +1,452 @@
+/* -----------------------------------------------------------------------------
+ * emit.cxx
+ *
+ * Useful functions for emitting various pieces of code.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1998-2000. The University of Chicago
+ * Copyright (C) 1995-1998. The University of Utah and The Regents of the
+ * University of California.
+ *
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+#include "swigmod.h"
+
+char cvsroot_emit_cxx[] = "$Header$";
+
+extern SwigType *cplus_value_type(SwigType *t);
+
+/* -----------------------------------------------------------------------------
+ * emit_args()
+ *
+ * Creates a list of variable declarations for both the return value
+ * and function parameters.
+ *
+ * The return value is always called result and arguments arg0, arg1, arg2, etc...
+ * Returns the number of parameters associated with a function.
+ * ----------------------------------------------------------------------------- */
+
+void emit_args(SwigType *rt, ParmList *l, Wrapper *f) {
+
+ Parm *p;
+ String *tm;
+
+ /* Emit function arguments */
+ Swig_cargs(f, l);
+
+ /* Handle return type */
+ if (rt && (SwigType_type(rt) != T_VOID)) {
+ if (!CPlusPlus || (CPlusPlus && !SwigType_isclass(rt))) {
+ Wrapper_add_local(f,"result", SwigType_lstr(rt,"result"));
+ } else {
+ SwigType *vt = 0;
+ vt = cplus_value_type(rt);
+ if (!vt) {
+ Wrapper_add_local(f,"result", SwigType_lstr(rt,"result"));
+ } else {
+ Wrapper_add_local(f,"result", SwigType_lstr(vt,"result"));
+ Delete(vt);
+ }
+ }
+ }
+
+ /* Attach typemaps to parameters */
+ /* Swig_typemap_attach_parms("ignore",l,f); */
+
+ Swig_typemap_attach_parms("default",l,f);
+ Swig_typemap_attach_parms("arginit",l,f);
+
+ /* Apply the arginit and default */
+ p = l;
+ while (p) {
+ tm = Getattr(p,"tmap:arginit");
+ if (tm) {
+ Replace(tm,"$target", Getattr(p,"lname"), DOH_REPLACE_ANY);
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:arginit:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Apply the default typemap */
+ p = l;
+ while (p) {
+ tm = Getattr(p,"tmap:default");
+ if (tm) {
+ Replace(tm,"$target", Getattr(p,"lname"), DOH_REPLACE_ANY);
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:default:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+#ifdef DEPRECATED
+ /* Apply the ignore typemap */
+ p = l;
+ while (p) {
+ tm = Getattr(p,"tmap:ignore");
+ if (tm) {
+ Parm *np;
+ Replace(tm,"$target", Getattr(p,"lname"), DOH_REPLACE_ANY);
+ Printv(f->code,tm,"\n",NIL);
+ np = Getattr(p,"tmap:ignore:next");
+
+ /* Deprecate this part later */
+ while (p && (p != np)) {
+ Setattr(p,"ignore","1");
+ p = nextSibling(p);
+ }
+ /* -- end deprecate */
+
+ } else {
+ p = nextSibling(p);
+ }
+ }
+#endif
+ return;
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_attach_parmmaps()
+ *
+ * Attach the standard parameter related typemaps.
+ * ----------------------------------------------------------------------------- */
+
+void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
+ Swig_typemap_attach_parms("in",l,f);
+ Swig_typemap_attach_parms("typecheck",l,0);
+ Swig_typemap_attach_parms("argout",l,f);
+ Swig_typemap_attach_parms("check",l,f);
+ Swig_typemap_attach_parms("freearg",l,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");
+ if (tm && checkAttribute(p,"tmap:in:numinputs","0")) {
+ Replaceall(tm,"$target", Getattr(p,"lname"));
+ Printv(f->code,tm,"\n",NIL);
+ np = Getattr(p,"tmap:in:next");
+ while (p && (p != np)) {
+ Setattr(p,"ignore","1");
+ p = nextSibling(p);
+ }
+ } else if (tm) {
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* 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;
+ while (p) {
+ npin = Getattr(p,"tmap:in:next");
+
+ /*
+ if (Getattr(p,"tmap:ignore")) {
+ npin = Getattr(p,"tmap:ignore:next");
+ } else if (Getattr(p,"tmap:in")) {
+ npin = Getattr(p,"tmap:in:next");
+ }
+ */
+
+ if (Getattr(p,"tmap:freearg")) {
+ npfreearg = Getattr(p,"tmap:freearg:next");
+ if (npin != npfreearg) {
+ while (p != npin) {
+ Delattr(p,"tmap:freearg");
+ Delattr(p,"tmap:freearg:next");
+ p = nextSibling(p);
+ }
+ }
+ }
+ p = npin;
+ }
+ }
+
+ /* Check for variable length arguments with no input typemap.
+ If no input is defined, we set this to ignore and print a
+ message.
+ */
+ {
+ Parm *p = l;
+ Parm *lp = 0;
+ while (p) {
+ if (!checkAttribute(p,"tmap:in:numinputs","0")) {
+ lp = p;
+ p = Getattr(p,"tmap:in:next");
+ continue;
+ }
+ if (SwigType_isvarargs(Getattr(p,"type"))) {
+ Swig_warning(WARN_LANG_VARARGS,input_file,line_number,"Variable length arguments discarded.\n");
+ Setattr(p,"tmap:in","");
+ }
+ lp = 0;
+ p = nextSibling(p);
+ }
+
+ /* Check if last input argument is variable length argument */
+ if (lp) {
+ p = lp;
+ while (p) {
+ if (SwigType_isvarargs(Getattr(p,"type"))) {
+ Setattr(l,"emit:varargs",lp);
+ break;
+ }
+ p = nextSibling(p);
+ }
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_num_arguments() ** new in 1.3.10
+ *
+ * Calculate the total number of arguments. This function is safe for use
+ * with multi-valued typemaps which may change the number of arguments in
+ * strange ways.
+ * ----------------------------------------------------------------------------- */
+
+int emit_num_arguments(ParmList *parms) {
+ Parm *p = parms;
+ int nargs = 0;
+
+ while (p) {
+ if (Getattr(p,"tmap:in")) {
+ nargs += GetInt(p,"tmap:in:numinputs");
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+#ifdef DEPRECATED
+ while (p) {
+ /* Ignored arguments */
+ if (Getattr(p,"tmap:ignore")) {
+ p = Getattr(p,"tmap:ignore:next");
+ } else {
+ /* Marshalled arguments */
+ nargs++;
+ if (Getattr(p,"tmap:in")) {
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+#endif
+ if (parms && (p = Getattr(parms,"emit:varargs"))) {
+ if (!nextSibling(p)) {
+ nargs--;
+ }
+ }
+ return nargs;
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_num_required() ** new in 1.3.10
+ *
+ * Computes the number of required arguments. This is function is safe for
+ * use with multi-valued typemaps and knows how to skip over everything
+ * properly.
+ * ----------------------------------------------------------------------------- */
+
+int emit_num_required(ParmList *parms) {
+ Parm *p = parms;
+ int nargs = 0;
+
+ while (p) {
+ if (Getattr(p,"tmap:in") && checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ if (Getattr(p,"value")) break;
+ if (Getattr(p,"tmap:default")) break;
+ nargs+= GetInt(p,"tmap:in:numinputs");
+ if (Getattr(p,"tmap:in")) {
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* Print message for non-default arguments */
+ while (p) {
+ if (Getattr(p,"tmap:in") && checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ if (!Getattr(p,"value") && (!Getattr(p,"tmap:default"))) {
+ Swig_error(Getfile(p),Getline(p),"Error. Non-optional argument '%s' follows an optional argument.\n",Getattr(p,"name"));
+ }
+ if (Getattr(p,"tmap:in")) {
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ if (parms && (p = Getattr(parms,"emit:varargs"))) {
+ if (!nextSibling(p)) {
+ nargs--;
+ }
+ }
+ return nargs;
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_isvarargs()
+ *
+ * Checks if a function is a varargs function
+ * ----------------------------------------------------------------------------- */
+
+int
+emit_isvarargs(ParmList *p) {
+ if (!p) return 0;
+ if (Getattr(p,"emit:varargs")) return 1;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * replace_args()
+ * ----------------------------------------------------------------------------- */
+
+static
+void replace_args(Parm *p, String *s) {
+ while (p) {
+ String *n = Getattr(p,"name");
+ if (n) {
+ Replace(s,n,Getattr(p,"lname"), DOH_REPLACE_ID);
+ }
+ p = nextSibling(p);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * int emit_action()
+ *
+ * Emits action code for a wrapper and checks for exception handling
+ * ----------------------------------------------------------------------------- */
+
+void emit_action(Node *n, Wrapper *f) {
+ String *tm;
+ String *action;
+ String *wrap;
+ Parm *p;
+ SwigType *rt;
+ ParmList *throws = Getattr(n,"throws");
+
+ /* Look for fragments */
+ {
+ String *f;
+ f = Getattr(n,"feature:fragment");
+ if (f) {
+ char *c, *tok;
+ String *t = Copy(f);
+ c = Char(t);
+ tok = strtok(c,",");
+ while (tok) {
+ Swig_fragment_emit(tok);
+ tok = strtok(NULL,",");
+ }
+ Delete(t);
+ }
+ }
+
+ /* Emit wrapper code (if any) */
+ wrap = Getattr(n,"wrap:code");
+ if (wrap && Swig_filebyname("header")!=Getattr(n,"wrap:code:done") ) {
+ File *f_code = Swig_filebyname("header");
+ if (f_code) {
+ Printv(f_code,wrap,NIL);
+ }
+ Setattr(n,"wrap:code:done",f_code);
+ }
+ action = Getattr(n,"feature:action");
+ if (!action)
+ action = Getattr(n,"wrap:action");
+ assert(action);
+
+ /* Get the return type */
+
+ rt = Getattr(n,"type");
+
+ /* Preassert -- EXPERIMENTAL */
+ tm = Getattr(n,"feature:preassert");
+ if (tm) {
+ p = Getattr(n,"parms");
+ replace_args(p,tm);
+ Printv(f->code,tm,"\n",NIL);
+ }
+
+ /* Exception handling code */
+
+ /* If we are in C++ mode and there is a throw specifier. We're going to
+ enclose the block in a try block */
+
+ if (throws) {
+ Printf(f->code,"try {\n");
+ }
+
+ /* Look for except typemap (Deprecated) */
+ tm = Swig_typemap_lookup_new("except",n,"result",0);
+
+ /* Look for except feature */
+ if (!tm) {
+ tm = Getattr(n,"feature:except");
+ if (tm) tm = Copy(tm);
+ }
+ if ((tm) && Len(tm) && (Strcmp(tm,"1") != 0)) {
+ Replaceall(tm,"$name",Getattr(n,"name"));
+ Replaceall(tm,"$symname", Getattr(n,"sym:name"));
+ Replaceall(tm,"$function", action);
+ Replaceall(tm,"$action", action);
+ Printv(f->code,tm,"\n", NIL);
+ Delete(tm);
+ } else {
+ Printv(f->code, action, "\n",NIL);
+ }
+
+ if (throws) {
+ Printf(f->code,"}\n");
+ for (Parm *ep = throws; ep; ep = nextSibling(ep)) {
+ String *em = Swig_typemap_lookup_new("throws",ep,"_e",0);
+ if (em) {
+ Printf(f->code,"catch(%s) {\n", SwigType_str(Getattr(ep,"type"),"&_e"));
+ Printv(f->code,em,"\n",NIL);
+ Printf(f->code,"}\n");
+ } else {
+ Swig_warning(WARN_TYPEMAP_THROW, Getfile(n), Getline(n),
+ "No 'throw' typemap defined for exception type '%s'\n", SwigType_str(Getattr(ep,"type"),0));
+ }
+ }
+ Printf(f->code,"catch(...) { throw; }\n");
+ }
+
+ /* Postassert - EXPERIMENTAL */
+ tm = Getattr(n,"feature:postassert");
+ if (tm) {
+ p = Getattr(n,"parms");
+ replace_args(p,tm);
+ Printv(f->code,tm,"\n",NIL);
+ }
+}
+
+
+
+
diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx
new file mode 100644
index 000000000..a6b53b536
--- /dev/null
+++ b/Source/Modules/guile.cxx
@@ -0,0 +1,1208 @@
+/******************************************************************************
+ * Simplified Wrapper and Interface Generator (SWIG)
+ *
+ * Author : David Beazley
+ *
+ * Department of Computer Science
+ * University of Chicago
+ * 1100 E 58th Street
+ * Chicago, IL 60637
+ * beazley@cs.uchicago.edu
+ *
+ * Please read the file LICENSE for the copyright and terms by which SWIG
+ * can be used and distributed.
+ *****************************************************************************/
+
+char cvsroot_guile_cxx[] = "$Header$";
+
+/***********************************************************************
+ * $Header$
+ *
+ * guile.cxx
+ *
+ * Definitions for adding functions to Guile
+ ***********************************************************************/
+
+#include "swigmod.h"
+
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+#include
+
+static const char *guile_usage = (char*)"\
+Guile Options (available with -guile)\n\
+ -ldflags - Print runtime libraries to link with\n\
+ -prefix name - Use NAME as prefix [default \"gswig_\"]\n\
+ -package name - Set the path of the module [default NULL]\n\
+ -emit-setters - Emit procedures-with-setters for variables\n\
+ and structure slots.\n\
+ -linkage lstyle - Use linkage protocol LSTYLE [default `module']\n\
+ -procdoc file - Output procedure documentation to FILE\n\
+ -procdocformat format - Output procedure documentation in FORMAT;\n\
+ one of `guile-1.4', `plain', `texinfo'\n\
+ -scmstub file - Output Scheme FILE with module declaration and\n\
+ exports; only with `passive' and `simple' linkage\n\
+\n\
+ When unspecified, the default LSTYLE is `simple'. For native Guile\n\
+ module linking (for Guile versions >=1.5.0), use `module'. Other\n\
+ LSTYLE values are: `passive' for passive linking (no C-level\n\
+ module-handling code), `ltdlmod' for Guile's old dynamic module\n\
+ convention (versions <= 1.4), or `hobbit' for hobbit modules.\n\
+\n";
+
+static File *f_runtime = 0;
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+
+
+static char *prefix = (char *) "gswig_";
+static char *module = 0;
+static char *package = 0;
+static enum {
+ GUILE_LSTYLE_SIMPLE, // call `SWIG_init()'
+ GUILE_LSTYLE_PASSIVE, // passive linking (no module code)
+ GUILE_LSTYLE_MODULE, // native guile module linking (Guile >= 1.4.1)
+ GUILE_LSTYLE_LTDLMOD_1_4, // old (Guile <= 1.4) dynamic module convention
+ GUILE_LSTYLE_HOBBIT // use (hobbit4d link)
+} linkage = GUILE_LSTYLE_SIMPLE;
+
+static File *procdoc = 0;
+static File *scmstub = 0;
+static String *scmtext;
+
+static enum {
+ GUILE_1_4,
+ PLAIN,
+ TEXINFO
+} docformat = GUILE_1_4;
+
+static int emit_setters = 0;
+static int struct_member = 0;
+
+static String *beforereturn = 0;
+static String *return_nothing_doc = 0;
+static String *return_one_doc = 0;
+static String *return_multi_doc = 0;
+
+static String *exported_symbols = 0;
+
+class GUILE : public Language {
+public:
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main (int argc, char *argv[]) {
+ int i, orig_len;
+
+ SWIG_library_directory("guile");
+ SWIG_typemap_lang("guile");
+
+ // Look for certain command line options
+ for (i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp (argv[i], "-help") == 0) {
+ fputs (guile_usage, stderr);
+ SWIG_exit (EXIT_SUCCESS);
+ }
+ else if (strcmp (argv[i], "-prefix") == 0) {
+ if (argv[i + 1]) {
+ prefix = new char[strlen (argv[i + 1]) + 2];
+ strcpy (prefix, argv[i + 1]);
+ Swig_mark_arg (i);
+ Swig_mark_arg (i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ }
+ else if (strcmp (argv[i], "-package") == 0) {
+ if (argv[i + 1]) {
+ package = new char[strlen (argv[i + 1]) + 2];
+ strcpy (package, argv [i + 1]);
+ Swig_mark_arg (i);
+ Swig_mark_arg (i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ }
+ else if (strcmp (argv[i], "-ldflags") == 0) {
+ printf("%s\n", SWIG_GUILE_RUNTIME);
+ SWIG_exit (EXIT_SUCCESS);
+ }
+ else if (strcmp (argv[i], "-Linkage") == 0
+ || strcmp (argv[i], "-linkage") == 0) {
+ if (argv[i + 1]) {
+ if (0 == strcmp (argv[i + 1], "ltdlmod"))
+ linkage = GUILE_LSTYLE_LTDLMOD_1_4;
+ else if (0 == strcmp (argv[i + 1], "hobbit"))
+ linkage = GUILE_LSTYLE_HOBBIT;
+ else if (0 == strcmp (argv[i + 1], "simple"))
+ linkage = GUILE_LSTYLE_SIMPLE;
+ else if (0 == strcmp (argv[i + 1], "passive"))
+ linkage = GUILE_LSTYLE_PASSIVE;
+ else if (0 == strcmp (argv[i + 1], "module"))
+ linkage = GUILE_LSTYLE_MODULE;
+ else
+ Swig_arg_error ();
+ Swig_mark_arg (i);
+ Swig_mark_arg (i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ }
+ else if (strcmp (argv[i], "-procdoc") == 0) {
+ if (argv[i + 1]) {
+ procdoc = NewFile(argv[i + 1], (char *) "w");
+ Swig_mark_arg (i);
+ Swig_mark_arg (i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ }
+ else if (strcmp (argv[i], "-procdocformat") == 0) {
+ if (strcmp(argv[i+1], "guile-1.4") == 0)
+ docformat = GUILE_1_4;
+ else if (strcmp(argv[i+1], "plain") == 0)
+ docformat = PLAIN;
+ else if (strcmp(argv[i+1], "texinfo") == 0)
+ docformat = TEXINFO;
+ else Swig_arg_error();
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ }
+ else if (strcmp (argv[i], "-emit-setters") == 0) {
+ emit_setters = 1;
+ Swig_mark_arg (i);
+ }
+ else if (strcmp (argv[i], "-scmstub") == 0) {
+ if (argv[i + 1]) {
+ scmstub = NewFile(argv[i + 1], (char *) "w");
+ Swig_mark_arg (i);
+ Swig_mark_arg (i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ }
+ }
+ }
+
+ // Make sure `prefix' ends in an underscore
+
+ orig_len = strlen (prefix);
+ if (prefix[orig_len - 1] != '_') {
+ prefix[1 + orig_len] = 0;
+ prefix[orig_len] = '_';
+ }
+
+ /* Add a symbol for this module */
+ Preprocessor_define ("SWIGGUILE 1",0);
+ /* Read in default typemaps */
+ SWIG_config_file("guile.i");
+ allow_overloading();
+
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
+
+ f_runtime = NewFile(outfile,"w");
+ if (!f_runtime) {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header",f_header);
+ Swig_register_filebyname("wrapper",f_wrappers);
+ Swig_register_filebyname("runtime",f_runtime);
+ Swig_register_filebyname("init",f_init);
+
+ scmtext = NewString("");
+ Swig_register_filebyname("scheme", scmtext);
+ exported_symbols = NewString("");
+
+ Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n");
+ Swig_banner (f_runtime);
+
+ Printf (f_runtime, "/* Implementation : GUILE */\n\n");
+
+ /* Write out directives and declarations */
+
+ if (NoInclude) {
+ Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
+ }
+
+ module = Swig_copy_string(Char(Getattr(n,"name")));
+
+ if (CPlusPlus) {
+ Printf(f_runtime, "extern \"C\" {\n\n");
+ }
+
+ switch (linkage) {
+ case GUILE_LSTYLE_SIMPLE:
+ /* Simple linkage; we have to export the SWIG_init function. The user can
+ rename the function by a #define. */
+ Printf (f_runtime, "extern void\nSWIG_init (void)\n;\n");
+ Printf (f_init, "extern void\nSWIG_init (void)\n{\n");
+ break;
+ default:
+ /* Other linkage; we make the SWIG_init function static */
+ Printf (f_runtime, "static void\nSWIG_init (void)\n;\n");
+ Printf (f_init, "static void\nSWIG_init (void)\n{\n");
+ break;
+ }
+ Printf (f_init, "\tSWIG_Guile_Init();\n");
+ if (CPlusPlus) {
+ Printf(f_runtime, "\n}\n");
+ }
+
+ Language::top(n);
+
+ /* Close module */
+
+ Printf(f_wrappers,"#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
+
+ SwigType_emit_type_table (f_runtime, f_wrappers);
+
+ Printf(f_wrappers,"#ifdef __cplusplus\n}\n#endif\n");
+
+ Printf (f_init, "SWIG_Guile_RegisterTypes(swig_types, swig_types_initial);\n");
+ Printf (f_init, "}\n\n");
+ char module_name[256];
+
+ if (!module)
+ sprintf(module_name, "swig");
+ else {
+ if (package)
+ sprintf(module_name,"%s/%s", package,module);
+ else
+ strcpy(module_name,module);
+ }
+ emit_linkage (module_name);
+
+ if (procdoc) {
+ Delete(procdoc);
+ procdoc = NULL;
+ }
+ if (scmstub) {
+ Delete(scmstub);
+ scmstub = NULL;
+ }
+
+ /* Close all of the files */
+ Dump(f_header,f_runtime);
+ Dump(f_wrappers,f_runtime);
+ Wrapper_pretty_print(f_init,f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_runtime);
+ Delete(f_runtime);
+ return SWIG_OK;
+ }
+
+ void emit_linkage (char *module_name) {
+ String *module_func = NewString("");
+
+ if (CPlusPlus) {
+ Printf(f_init, "extern \"C\" {\n\n");
+ }
+
+ Printv(module_func,module_name,NIL);
+ Replaceall(module_func,"-", "_");
+
+ switch (linkage) {
+ case GUILE_LSTYLE_SIMPLE:
+ Printf (f_init, "\n/* Linkage: simple */\n");
+ break;
+ case GUILE_LSTYLE_PASSIVE:
+ Printf (f_init, "\n/* Linkage: passive */\n");
+ Replaceall(module_func,"/", "_");
+ Insert(module_func,0, "scm_init_");
+ Append(module_func,"_module");
+
+ Printf (f_init, "SCM\n%s (void)\n{\n", module_func);
+ Printf (f_init, " SWIG_init();\n");
+ Printf (f_init, " return SCM_UNSPECIFIED;\n");
+ Printf (f_init, "}\n");
+ break;
+ case GUILE_LSTYLE_LTDLMOD_1_4:
+ Printf (f_init, "\n/* Linkage: ltdlmod */\n");
+ Replaceall(module_func,"/", "_");
+ Insert(module_func,0, "scm_init_");
+ Append(module_func,"_module");
+ Printf (f_init, "SCM\n%s (void)\n{\n", module_func);
+ {
+ String *mod = NewString(module_name);
+ Replaceall(mod,"/", " ");
+ Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n",
+ mod);
+ Printf (f_init, " return SCM_UNSPECIFIED;\n");
+ Delete(mod);
+ }
+ Printf (f_init, "}\n");
+ break;
+ case GUILE_LSTYLE_MODULE:
+ Printf (f_init, "\n/* Linkage: module */\n");
+ Replaceall(module_func,"/", "_");
+ Insert(module_func,0, "scm_init_");
+ Append(module_func,"_module");
+
+ Printf (f_init, "static void SWIG_init_helper(void *data)\n");
+ Printf (f_init, "{\n SWIG_init();\n");
+ if (Len(exported_symbols) > 0)
+ Printf (f_init, " scm_c_export(%sNULL);",
+ exported_symbols);
+ Printf (f_init, "\n}\n\n");
+
+ Printf (f_init, "SCM\n%s (void)\n{\n", module_func);
+ {
+ String *mod = NewString(module_name);
+ Replaceall(mod,"/", " ");
+ Printf(f_init, " SCM module = scm_c_define_module(\"%s\",\n", mod);
+ Printf(f_init, " SWIG_init_helper, NULL);\n");
+ Printf(f_init, " return SCM_UNSPECIFIED;\n");
+ Delete(mod);
+ }
+ Printf (f_init, "}\n");
+ break;
+ case GUILE_LSTYLE_HOBBIT:
+ Printf (f_init, "\n/* Linkage: hobbit */\n");
+ Replaceall(module_func,"/", "_slash_");
+ Insert(module_func,0, "scm_init_");
+ Printf (f_init, "SCM\n%s (void)\n{\n", module_func);
+ {
+ String *mod = NewString(module_name);
+ Replaceall(mod,"/", " ");
+ Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n",
+ mod);
+ Printf (f_init, " return SCM_UNSPECIFIED;\n");
+ Delete(mod);
+ }
+ Printf (f_init, "}\n");
+ break;
+ default:
+ abort(); // for now
+ }
+
+ if (scmstub) {
+ /* Emit Scheme stub if requested */
+ String *mod = NewString(module_name);
+ Replaceall(mod, "/", " ");
+ Printf (scmstub, ";;; -*- buffer-read-only: t -*- vi: set ro: */\n");
+ Printf (scmstub, ";;; Automatically generated by SWIG; do not edit.\n\n");
+ if (linkage == GUILE_LSTYLE_SIMPLE
+ || linkage == GUILE_LSTYLE_PASSIVE)
+ Printf (scmstub, "(define-module (%s))\n\n", mod);
+ Delete(mod);
+ Printf (scmstub, "%s", scmtext);
+ if ((linkage == GUILE_LSTYLE_SIMPLE
+ || linkage == GUILE_LSTYLE_PASSIVE)
+ && Len(exported_symbols) > 0) {
+ String *ex = NewString(exported_symbols);
+ Replaceall(ex, ", ", "\n ");
+ Replaceall(ex, "\"", "");
+ Chop(ex);
+ Printf(scmstub, "\n(export %s)\n", ex);
+ Delete(ex);
+ }
+ }
+
+ Delete(module_func);
+ if (CPlusPlus) {
+ Printf(f_init, "\n}\n");
+ }
+ }
+
+ /* Return true iff T is a pointer type */
+
+ int is_a_pointer (SwigType *t) {
+ return SwigType_ispointer(SwigType_typedef_resolve_all(t));
+ }
+
+ /* Report an error handling the given type. */
+
+ void throw_unhandled_guile_type_error (SwigType *d) {
+ Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number,
+ "Unable to handle type %s.\n", SwigType_str(d,0));
+ }
+
+ /* Write out procedure documentation */
+
+ void write_doc(const String *proc_name,
+ const String *signature,
+ const String *doc,
+ const String *signature2 = NULL) {
+ switch (docformat) {
+ case GUILE_1_4:
+ Printv(procdoc, "\f\n", NIL);
+ Printv(procdoc, "(", signature, ")\n", NIL);
+ if (signature2)
+ Printv(procdoc, "(", signature2, ")\n", NIL);
+ Printv(procdoc, doc, "\n", NIL);
+ break;
+ case PLAIN:
+ Printv(procdoc, "\f", proc_name, "\n\n", NIL);
+ Printv(procdoc, "(", signature, ")\n", NIL);
+ if (signature2)
+ Printv(procdoc, "(", signature2, ")\n", NIL);
+ Printv(procdoc, doc, "\n\n", NIL);
+ break;
+ case TEXINFO:
+ Printv(procdoc, "\f", proc_name, "\n", NIL);
+ Printv(procdoc, "@deffn primitive ", signature, "\n", NIL);
+ if (signature2)
+ Printv(procdoc, "@deffnx primitive ", signature2, "\n", NIL);
+ Printv(procdoc, doc, "\n", NIL);
+ Printv(procdoc, "@end deffn\n\n", NIL);
+ break;
+ }
+ }
+
+ /* returns false if the typemap is an empty string */
+ bool handle_documentation_typemap(String *output,
+ const String *maybe_delimiter,
+ Parm *p,
+ const String *typemap,
+ const String *default_doc)
+ {
+ String *tmp = NewString("");
+ String *tm;
+ if (!(tm = Getattr(p, typemap))) {
+ Printf(tmp, "%s", default_doc);
+ tm = tmp;
+ }
+ bool result = (Len(tm) > 0);
+ if (maybe_delimiter && Len(output) > 0 && Len(tm) > 0) {
+ Printv(output, maybe_delimiter, NIL);
+ }
+ String *pn = Getattr(p,"name");
+ String *pt = Getattr(p,"type");
+ Replaceall(tm, "$name", pn); // legacy for $parmname
+ Replaceall(tm, "$type", SwigType_str(pt,0));
+ /* $NAME is like $name, but marked-up as a variable. */
+ String *ARGNAME = NewString("");
+ if (docformat == TEXINFO)
+ Printf(ARGNAME, "@var{%s}", pn);
+ else Printf(ARGNAME, "%(upper)s", pn);
+ Replaceall(tm, "$NAME", ARGNAME);
+ Replaceall(tm, "$PARMNAME", ARGNAME);
+ Printv(output,tm,NIL);
+ Delete(tmp);
+ return result;
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * Create a function declaration and register it with the interpreter.
+ * ------------------------------------------------------------ */
+
+ virtual int functionWrapper(Node *n) {
+ String *iname = Getattr(n,"sym:name");
+ SwigType *d = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+ Parm *p;
+ String *proc_name = 0;
+ char source[256], target[256];
+ Wrapper *f = NewWrapper();;
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *signature = NewString("");
+ String *doc_body = NewString("");
+ String *returns = NewString("");
+ int num_results = 1;
+ String *tmp = NewString("");
+ String *tm;
+ int i;
+ int numargs = 0;
+ int numreq = 0;
+ String *overname = 0;
+ int args_passed_as_array = 0;
+
+ // Make a wrapper name for this
+ String *wname = Swig_name_wrapper(iname);
+ if (Getattr(n,"sym:overloaded")) {
+ overname = Getattr(n,"sym:overname");
+ args_passed_as_array = 1;
+ } else {
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+ }
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n,"wrap:name",wname);
+
+ // Build the name for scheme.
+ proc_name = NewString(iname);
+ Replaceall(proc_name,"_", "-");
+
+ /* Emit locals etc. into f->code; figure out which args to ignore */
+ emit_args (d, l, f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l,f);
+ Setattr(n,"wrap:parms",l);
+
+ /* Get number of required and total arguments */
+ numargs = emit_num_arguments(l);
+ numreq = emit_num_required(l);
+
+ /* Declare return variable */
+
+ Wrapper_add_local (f,"gswig_result", "SCM gswig_result");
+ Wrapper_add_local (f,"gswig_list_p", "int gswig_list_p = 0");
+
+ /* Get the output typemap so we can start generating documentation. Don't
+ worry, the returned string is saved as 'tmap:out' */
+
+ Swig_typemap_lookup_new("out",n,"result",0);
+
+ if ((tm = Getattr(n,"tmap:out:doc"))) {
+ Printv(returns,tm,NIL);
+ if (Len(tm) > 0) num_results = 1;
+ else num_results = 0;
+ } else {
+ String *s = SwigType_str(d,0);
+ Chop(s);
+ Printf(returns,"<%s>",s);
+ Delete(s);
+ num_results = 1;
+ }
+
+ /* Open prototype and signature */
+
+ Printv(f->def, "static SCM\n", wname," (", NIL);
+ if (args_passed_as_array) {
+ Printv(f->def, "int argc, SCM *argv", NIL);
+ }
+ Printv(signature, proc_name, NIL);
+
+ /* Now write code to extract the parameters */
+
+ for (i = 0, p = l; i < numargs; i++) {
+
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *ln = Getattr(p,"lname");
+ int opt_p = (i >= numreq);
+
+ // Produce names of source and target
+ if (args_passed_as_array)
+ sprintf(source, "argv[%d]", i);
+ else
+ sprintf(source,"s_%d",i);
+ sprintf(target,"%s", Char(ln));
+
+ if (!args_passed_as_array) {
+ if (i!=0) Printf(f->def,", ");
+ Printf(f->def,"SCM s_%d", i);
+ }
+ if (opt_p) {
+ Printf(f->code," if (%s != GH_NOT_PASSED) {\n", source);
+ }
+ if ((tm = Getattr(p,"tmap:in"))) {
+ Replaceall(tm,"$source",source);
+ Replaceall(tm,"$target",target);
+ Replaceall(tm,"$input",source);
+ Setattr(p,"emit:input", source);
+ Printv(f->code,tm,"\n",NIL);
+
+ if (procdoc) {
+ /* Add to signature (arglist) */
+ handle_documentation_typemap(signature, " ", p, "tmap:in:arglist",
+ "$name");
+ /* Document the type of the arg in the documentation body */
+ handle_documentation_typemap(doc_body, ", ", p, "tmap:in:doc",
+ "$NAME is of type <$type>");
+ }
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ throw_unhandled_guile_type_error (pt);
+ p = nextSibling(p);
+ }
+ if (opt_p)
+ Printf(f->code," }\n");
+ }
+ if (Len(doc_body) > 0)
+ Printf(doc_body, ".\n");
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:check"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ /* Pass output arguments back to the caller. */
+
+ /* Insert argument output code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:argout"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Replaceall(tm,"$arg",Getattr(p,"emit:input"));
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(outarg,tm,"\n",NIL);
+ if (procdoc) {
+ if (handle_documentation_typemap(returns, ", ",
+ p, "tmap:argout:doc",
+ "$NAME (of type $type)")) {
+ /* A documentation typemap that is not the empty string
+ indicates that a value is returned to Scheme. */
+ num_results++;
+ }
+ }
+ p = Getattr(p,"tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:freearg"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(cleanup,tm,"\n",NIL);
+ p = Getattr(p,"tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Close prototype */
+
+ Printf(f->def, ")\n{\n");
+
+ /* Define the scheme name in C. This define is used by several Guile
+ macros. */
+ Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
+
+ // Now write code to make the function call
+ Printv(f->code, tab4, "gh_defer_ints();\n", NIL);
+ emit_action(n,f);
+ Printv(f->code, tab4, "gh_allow_ints();\n", NIL);
+
+ // Now have return value, figure out what to do with it.
+
+ if ((tm = Getattr(n,"tmap:out"))) {
+ Replaceall(tm,"$result","gswig_result");
+ Replaceall(tm,"$target","gswig_result");
+ Replaceall(tm,"$source","result");
+ Printv(f->code,tm,"\n",NIL);
+ }
+ else {
+ throw_unhandled_guile_type_error (d);
+ }
+
+ // Dump the argument output code
+ Printv(f->code,outarg,NIL);
+
+ // Dump the argument cleanup code
+ Printv(f->code,cleanup,NIL);
+
+ // Look for any remaining cleanup
+
+ if (Getattr(n,"feature:new")) {
+ if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printv(f->code,tm,"\n",NIL);
+ }
+ }
+
+ // Free any memory allocated by the function being wrapped..
+ if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printv(f->code,tm,"\n",NIL);
+ }
+
+ // Wrap things up (in a manner of speaking)
+
+ if (beforereturn)
+ Printv(f->code, beforereturn, "\n", NIL);
+ Printv(f->code, "return gswig_result;\n", NIL);
+
+ // Undefine the scheme name
+
+ Printf(f->code, "#undef FUNC_NAME\n");
+ Printf(f->code, "}\n");
+
+ Wrapper_print (f, f_wrappers);
+
+ if (!Getattr(n, "sym:overloaded")) {
+ if (numargs > 10) {
+ int i;
+ /* gh_new_procedure would complain: too many args */
+ /* Build a wrapper wrapper */
+ Printv(f_wrappers, "static SCM\n", wname,"_rest (SCM rest)\n", NIL);
+ Printv(f_wrappers, "{\n", NIL);
+ Printf(f_wrappers, "SCM arg[%d];\n", numargs);
+ Printf(f_wrappers, "SWIG_Guile_GetArgs (arg, rest, %d, %d, \"%s\");\n",
+ numreq, numargs-numreq, proc_name);
+ Printv(f_wrappers, "return ", wname, "(", NIL);
+ Printv(f_wrappers, "arg[0]", NIL);
+ for (i = 1; i3) {
+ int len = Len(proc_name);
+ const char *pc = Char(proc_name);
+ /* MEMBER-set and MEMBER-get functions. */
+ int is_setter = (pc[len - 3] == 's');
+ if (is_setter) {
+ Printf(f_init, "SCM setter = ");
+ struct_member = 2; /* have a setter */
+ }
+ else Printf(f_init, "SCM getter = ");
+ Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n",
+ proc_name, wname, numreq, numargs-numreq);
+ if (!is_setter) {
+ /* Strip off "-get" */
+ char *pws_name = (char*) malloc(sizeof(char) * (len - 3));
+ strncpy(pws_name, pc, len - 3);
+ pws_name[len - 4] = 0;
+ if (struct_member==2) {
+ /* There was a setter, so create a procedure with setter */
+ Printf (f_init, "gh_define(\"%s\", "
+ "scm_make_procedure_with_setter(getter, setter));\n",
+ pws_name);
+ }
+ else {
+ /* There was no setter, so make an alias to the getter */
+ Printf (f_init, "gh_define(\"%s\", getter);\n",
+ pws_name);
+ }
+ Printf (exported_symbols, "\"%s\", ", pws_name);
+ free(pws_name);
+ }
+ }
+ else {
+ /* Register the function */
+ Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n",
+ proc_name, wname, numreq, numargs-numreq);
+ }
+ }
+ else { /* overloaded function; don't export the single methods */
+ if (!Getattr(n,"sym:nextSibling")) {
+ /* Emit overloading dispatch function */
+
+ int maxargs;
+ String *dispatch = Swig_overload_dispatch(n,"return %s(argc,argv);",&maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *df = NewWrapper();
+ String *dname = Swig_name_wrapper(iname);
+
+ Printv(df->def,
+ "static SCM\n", dname,
+ "(SCM rest)\n{\n",
+ NIL);
+ Printf(df->code, "SCM argv[%d];\n", maxargs);
+ Printf(df->code, "int argc = SWIG_Guile_GetArgs (argv, rest, %d, %d, \"%s\");\n",
+ 0, maxargs, proc_name);
+ Printv(df->code,dispatch,"\n",NIL);
+ Printf(df->code,"scm_misc_error(\"%s\", \"No matching method for generic function `%s'\", SCM_EOL);\n", proc_name, iname);
+ Printv(df->code,"}\n",NIL);
+ Wrapper_print(df,f_wrappers);
+ Printf(f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, 0, 1);\n",
+ proc_name, dname);
+ DelWrapper(df);
+ Delete(dispatch);
+ Delete(dname);
+ }
+ }
+ Printf (exported_symbols, "\"%s\", ", proc_name);
+ if (procdoc) {
+ String *returns_text = NewString("");
+ if (num_results == 0) Printv(returns_text, return_nothing_doc, NIL);
+ else if (num_results == 1) Printv(returns_text, return_one_doc, NIL);
+ else Printv(returns_text, return_multi_doc, NIL);
+ /* Substitute documentation variables */
+ static const char *numbers[] = {"zero", "one", "two", "three",
+ "four", "five", "six", "seven",
+ "eight", "nine", "ten", "eleven",
+ "twelve"};
+ if (num_results <= 12)
+ Replaceall(returns_text, "$num_values", numbers[num_results]);
+ else {
+ String *num_results_str = NewStringf("%d", num_results);
+ Replaceall(returns_text, "$num_values", num_results_str);
+ Delete(num_results_str);
+ }
+ Replaceall(returns_text, "$values", returns);
+ Printf(doc_body, "\n%s", returns_text);
+ write_doc(proc_name, signature, doc_body);
+ Delete(returns_text);
+ }
+
+ Delete(proc_name);
+ Delete(outarg);
+ Delete(cleanup);
+ Delete(signature);
+ Delete(doc_body);
+ Delete(returns);
+ Delete(tmp);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ *
+ * Create a link to a C variable.
+ * This creates a single function PREFIX_var_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. Either way, we return the variables
+ * value.
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+
+ char *name = GetChar(n,"name");
+ char *iname = GetChar(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+
+ String *proc_name;
+ char var_name[256];
+ Wrapper *f;
+ String *tm;
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ f = NewWrapper();
+ // evaluation function names
+
+ strcpy(var_name, Char(Swig_name_wrapper(iname)));
+
+ // Build the name for scheme.
+ proc_name = NewString(iname);
+ Replaceall(proc_name,"_", "-");
+
+ if (1 || (SwigType_type(t) != T_USER) || (is_a_pointer(t))) {
+
+ Printf (f->def, "static SCM\n%s(SCM s_0)\n{\n", var_name);
+
+ /* Define the scheme name in C. This define is used by several Guile
+ macros. */
+ Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
+
+ Wrapper_add_local (f, "gswig_result", "SCM gswig_result");
+
+ if (!Getattr(n,"feature:immutable")) {
+ /* Check for a setting of the variable value */
+ Printf (f->code, "if (s_0 != GH_NOT_PASSED) {\n");
+ if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) {
+ Replaceall(tm,"$source","s_0");
+ Replaceall(tm,"$input","s_0");
+ Replaceall(tm,"$target",name);
+ Printv(f->code,tm,"\n",NIL);
+ }
+ else {
+ throw_unhandled_guile_type_error (t);
+ }
+ Printf (f->code, "}\n");
+ }
+
+ // Now return the value of the variable (regardless
+ // of evaluating or setting)
+
+ if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) {
+ Replaceall(tm,"$source",name);
+ Replaceall(tm,"$target","gswig_result");
+ Replaceall(tm,"$result", "gswig_result");
+ Printv(f->code,tm,"\n",NIL);
+ }
+ else {
+ throw_unhandled_guile_type_error (t);
+ }
+ Printf (f->code, "\nreturn gswig_result;\n");
+ Printf (f->code, "#undef FUNC_NAME\n");
+ Printf (f->code, "}\n");
+
+ Wrapper_print (f, f_wrappers);
+
+ // Now add symbol to the Guile interpreter
+
+ if (!emit_setters
+ || Getattr(n,"feature:immutable")) {
+ /* Read-only variables become a simple procedure returning the
+ value; read-write variables become a simple procedure with
+ an optional argument. */
+ Printf (f_init, "\t gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, %d, 0);\n",
+ proc_name, var_name, Getattr(n,"feature:immutable") ? 0 : 1);
+ }
+ else {
+ /* Read/write variables become a procedure with setter. */
+ Printf (f_init, "\t{ SCM p = gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, 1, 0);\n",
+ proc_name, var_name);
+ Printf (f_init, "\t gh_define(\"%s\", "
+ "scm_make_procedure_with_setter(p, p)); }\n",
+ proc_name);
+ }
+ Printf (exported_symbols, "\"%s\", ", proc_name);
+
+ if (procdoc) {
+ /* Compute documentation */
+ String *signature = NewString("");
+ String *signature2 = NULL;
+ String *doc = NewString("");
+
+ if (Getattr(n,"feature:immutable")) {
+ Printv(signature, proc_name, NIL);
+ Printv(doc, "Returns constant ", NIL);
+ if ((tm = Getattr(n,"tmap:varout:doc"))) {
+ Printv(doc,tm,NIL);
+ } else {
+ String *s = SwigType_str(t,0);
+ Chop(s);
+ Printf(doc,"<%s>",s);
+ Delete(s);
+ }
+ }
+ else if (emit_setters) {
+ Printv(signature, proc_name, NIL);
+ signature2 = NewString("");
+ Printv(signature2, "set! (", proc_name, ") ", NIL);
+ handle_documentation_typemap(signature2, NIL, n, "tmap:varin:arglist",
+ "new-value");
+ Printv(doc, "Get or set the value of the C variable, \n", NIL);
+ Printv(doc, "which is of type ", NIL);
+ handle_documentation_typemap(doc, NIL, n, "tmap:varout:doc",
+ "$1_type");
+ Printv(doc, ".");
+ }
+ else {
+ Printv(signature, proc_name,
+ " #:optional ", NIL);
+ if ((tm = Getattr(n,"tmap:varin:doc"))) {
+ Printv(signature,tm,NIL);
+ } else {
+ String *s = SwigType_str(t,0);
+ Chop(s);
+ Printf(signature,"new-value <%s>",s);
+ Delete(s);
+ }
+
+ Printv(doc, "If NEW-VALUE is provided, "
+ "set C variable to this value.\n", NIL);
+ Printv(doc, "Returns variable value ", NIL);
+ if ((tm = Getattr(n,"tmap:varout:doc"))) {
+ Printv(doc,tm,NIL);
+ } else {
+ String *s = SwigType_str(t,0);
+ Chop(s);
+ Printf(doc,"<%s>",s);
+ Delete(s);
+ }
+ }
+ write_doc(proc_name, signature, doc, signature2);
+ Delete(signature);
+ if (signature2) Delete(signature2);
+ Delete(doc);
+ }
+
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number,
+ "Unsupported variable type %s (ignored).\n", SwigType_str(t,0));
+ }
+ Delete(proc_name);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ *
+ * We create a read-only variable.
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ char *name = GetChar(n,"name");
+ char *iname = GetChar(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ String *value = Getattr(n,"value");
+
+ String *proc_name;
+ char var_name[256];
+ String *rvalue;
+ Wrapper *f;
+ SwigType *nctype;
+ String *tm;
+
+ f = NewWrapper();
+
+ // Make a static variable;
+
+ sprintf (var_name, "%sconst_%s", prefix, iname);
+
+ // Strip const qualifier from type if present
+
+ nctype = NewString(type);
+ if (SwigType_isconst(nctype)) {
+ Delete(SwigType_pop(nctype));
+ }
+
+ // Build the name for scheme.
+ proc_name = NewString(iname);
+ Replaceall(proc_name,"_", "-");
+
+ if ((SwigType_type(nctype) == T_USER) && (!is_a_pointer(nctype))) {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
+ "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+
+ // See if there's a typemap
+
+ if (SwigType_type(nctype) == T_STRING) {
+ rvalue = NewStringf("\"%s\"", value);
+ } else if (SwigType_type(nctype) == T_CHAR) {
+ rvalue = NewStringf("\'%s\'", value);
+ } else {
+ rvalue = NewString(value);
+ }
+
+ if ((tm = Swig_typemap_lookup_new("constant",n,name,0))) {
+ Replaceall(tm,"$source",rvalue);
+ Replaceall(tm,"$value",rvalue);
+ Replaceall(tm,"$target",name);
+ Printv(f_header,tm,"\n",NIL);
+ } else {
+ // Create variable and assign it a value
+ Printf (f_header, "static %s = %s;\n", SwigType_lstr(nctype,var_name),
+ rvalue);
+ }
+ {
+ /* Hack alert: will cleanup later -- Dave */
+ Node *n = NewHash();
+ Setattr(n,"name",var_name);
+ Setattr(n,"sym:name",iname);
+ Setattr(n,"type", nctype);
+ Setattr(n,"feature:immutable", "1");
+ variableWrapper(n);
+ Delete(n);
+ }
+ Delete(nctype);
+ Delete(proc_name);
+ Delete(rvalue);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+ virtual int membervariableHandler(Node *n) {
+ if (emit_setters) {
+ struct_member = 1;
+ Printf(f_init, "{\n");
+ Language::membervariableHandler(n);
+ Printf(f_init, "}\n");
+ struct_member = 0;
+ }
+ else {
+ /* Only emit traditional VAR-get and VAR-set procedures */
+ Language::membervariableHandler(n);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * pragmaDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int pragmaDirective(Node *n)
+ {
+ if (!ImportMode) {
+ String *lang = Getattr(n,"lang");
+ String *cmd = Getattr(n,"name");
+ String *value = Getattr(n,"value");
+
+# define store_pragma(PRAGMANAME) \
+ if (Strcmp(cmd, #PRAGMANAME) == 0) { \
+ if (PRAGMANAME) Delete(PRAGMANAME); \
+ PRAGMANAME = value ? NewString(value) : NULL; \
+ }
+
+ if (Strcmp(lang,"guile") == 0) {
+ store_pragma(beforereturn)
+ store_pragma(return_nothing_doc)
+ store_pragma(return_one_doc)
+ store_pragma(return_multi_doc);
+# undef store_pragma
+ }
+ }
+ return Language::pragmaDirective(n);
+ }
+
+ /* ------------------------------------------------------------
+ * validIdentifier()
+ * ------------------------------------------------------------ */
+
+ virtual int validIdentifier(String *s) {
+ char *c = Char(s);
+ /* Check whether we have an R5RS identifier. Guile supports a
+ superset of R5RS identifiers, but it's probably a bad idea to use
+ those. */
+ /* --> * | */
+ /* --> | */
+ if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~'))) {
+ /* --> + | - | ... */
+ if ((strcmp(c, "+") == 0)
+ || strcmp(c, "-") == 0
+ || strcmp(c, "...") == 0) return 1;
+ else return 0;
+ }
+ /* --> | | */
+ while (*c) {
+ if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+')
+ || (*c == '-') || (*c == '.') || (*c == '@'))) return 0;
+ c++;
+ }
+ return 1;
+ }
+};
+
+/* -----------------------------------------------------------------------------
+ * swig_guile() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+extern "C" Language *
+swig_guile(void) {
+ return new GUILE();
+}
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
new file mode 100644
index 000000000..499a58b24
--- /dev/null
+++ b/Source/Modules/java.cxx
@@ -0,0 +1,1900 @@
+/* -----------------------------------------------------------------------------
+ * java.cxx
+ *
+ * Java wrapper module.
+ *
+ * Author(s) : Harco de Hilster
+ * William Fulton
+ *
+ * Copyright (C) 1999-2002. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_java_cxx[] = "$Header$";
+
+#include
+#include // for INT_MAX
+#include "swigmod.h"
+
+class JAVA : public Language {
+ static const char *usage;
+ const String *empty_string;
+
+ Hash *swig_types_hash;
+ File *f_runtime;
+ File *f_header;
+ File *f_wrappers;
+ File *f_init;
+
+ bool proxy_flag; // Flag for generating shadow classes
+ bool have_default_constructor_flag;
+ bool native_function_flag; // Flag for when wrapping a native function
+ bool enum_constant_flag; // Flag for when wrapping an enum or constant
+ bool static_flag; // Flag for when wrapping a static functions or member variables
+ bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable
+ bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const
+ bool global_variable_flag; // Flag for when wrapping a global variable
+
+ String *jniclass_name; // JNI class name
+ String *module_class_name; // module class name
+ String *jniclass_class_code; // JNI class Java code - that is the native methods
+ String *shadow_classdef;
+ String *shadow_code;
+ String *module_class_code;
+ String *shadow_classname;
+ String *variable_name; //Name of a variable being wrapped
+ String *shadow_constants_code;
+ String *module_constants_code;
+ String *package; // Package name
+ String *jnipackage; // JNI package name
+ String *jniclass_imports; //jniclass imports from %pragma
+ String *module_imports; //module imports from %pragma
+ String *jniclass_baseclass; //inheritance for jniclass class from %pragma
+ String *module_baseclass; //inheritance for module class from %pragma
+ String *jniclass_interfaces; //interfaces for jniclass class from %pragma
+ String *module_interfaces; //interfaces for module class from %pragma
+ String *jniclass_class_modifiers; //class modifiers for jniclass class overriden by %pragma
+ String *module_class_modifiers; //class modifiers for module class overriden by %pragma
+ String *wrapper_conversion_code; //C++ casts for inheritance hierarchies JNI code
+ String *jniclass_cppcasts_code; //C++ casts up inheritance hierarchies JNI class Java code
+ String *destructor_call; //Destructor (delete) call if any
+
+ enum type_additions {none, pointer, reference};
+
+ public:
+
+ /* -----------------------------------------------------------------------------
+ * JAVA()
+ * ----------------------------------------------------------------------------- */
+
+ JAVA() :
+ empty_string(NewString("")),
+
+ swig_types_hash(NULL),
+ f_runtime(NULL),
+ f_header(NULL),
+ f_wrappers(NULL),
+ f_init(NULL),
+
+ proxy_flag(true),
+ have_default_constructor_flag(false),
+ native_function_flag(false),
+ enum_constant_flag(false),
+ static_flag(false),
+ variable_wrapper_flag(false),
+ wrapping_member_flag(false),
+ global_variable_flag(false),
+
+ jniclass_name(NULL),
+ module_class_name(NULL),
+ jniclass_class_code(NULL),
+ shadow_classdef(NULL),
+ shadow_code(NULL),
+ module_class_code(NULL),
+ shadow_classname(NULL),
+ variable_name(NULL),
+ shadow_constants_code(NULL),
+ module_constants_code(NULL),
+ package(NULL),
+ jnipackage(NULL),
+ jniclass_imports(NULL),
+ module_imports(NULL),
+ jniclass_baseclass(NULL),
+ module_baseclass(NULL),
+ jniclass_interfaces(NULL),
+ module_interfaces(NULL),
+ jniclass_class_modifiers(NULL),
+ module_class_modifiers(NULL),
+ wrapper_conversion_code(NULL),
+ jniclass_cppcasts_code(NULL),
+ destructor_call(NULL)
+
+ {
+ }
+
+ /* -----------------------------------------------------------------------------
+ * is_shadow()
+ *
+ * Test to see if a type corresponds to something wrapped with a shadow/proxy class
+ * Return NULL if not otherwise the shadow name
+ * ----------------------------------------------------------------------------- */
+
+ String *is_shadow(SwigType *t) {
+ if (proxy_flag) {
+ Node *n = classLookup(t);
+ if (n) {
+ return Getattr(n,"sym:name");
+ }
+ }
+ return NULL;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * makeValidJniName()
+ * ----------------------------------------------------------------------------- */
+
+ String *makeValidJniName(const String *name) {
+ String *valid_jni_name = NewString(name);
+ Replaceall(valid_jni_name,"_","_1");
+ return valid_jni_name;
+ }
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+
+ SWIG_library_directory("java");
+
+ // Look for certain command line options
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i],"-package") == 0) {
+ if (argv[i+1]) {
+ package = NewString("");
+ Printf(package, argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if ((strcmp(argv[i],"-shadow") == 0) || ((strcmp(argv[i],"-proxy") == 0))) {
+ 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],"-noproxy") == 0)) {
+ Swig_mark_arg(i);
+ proxy_flag = false;
+ } else if (strcmp(argv[i],"-jnic") == 0) {
+ Swig_mark_arg(i);
+ Printf(stderr,"Deprecated command line option: -jnic. C JNI calling convention now used when -c++ not specified.\n");
+ } else if (strcmp(argv[i],"-nofinalize") == 0) {
+ Swig_mark_arg(i);
+ Printf(stderr,"Deprecated command line option: -nofinalize. Use the new javafinalize typemaps instead.\n");
+ } else if (strcmp(argv[i],"-jnicpp") == 0) {
+ Swig_mark_arg(i);
+ Printf(stderr,"Deprecated command line option: -jnicpp. C++ JNI calling convention now used when -c++ specified.\n");
+ } else if (strcmp(argv[i],"-help") == 0) {
+ Printf(stderr,"%s\n", usage);
+ }
+ }
+ }
+
+ // Add a symbol to the parser for conditional compilation
+ Preprocessor_define("SWIGJAVA 1",0);
+
+ // Add typemap definitions
+ SWIG_typemap_lang("java");
+ SWIG_config_file("java.swg");
+
+ allow_overloading();
+ }
+
+ /* ---------------------------------------------------------------------
+ * top()
+ * --------------------------------------------------------------------- */
+
+ virtual int top(Node *n) {
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
+
+ f_runtime = NewFile(outfile,"w");
+ if (!f_runtime) {
+ Printf(stderr,"Unable to open %s\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header",f_header);
+ Swig_register_filebyname("wrapper",f_wrappers);
+ Swig_register_filebyname("runtime",f_runtime);
+ Swig_register_filebyname("init",f_init);
+ swig_types_hash = NewHash();
+
+ // Make the JNI class and module class names. The jniclassname can be set in the module directive.
+ Node* optionsnode = Getattr( Getattr(n,"module") ,"options");
+ if (optionsnode)
+ if (Getattr(optionsnode,"jniclassname"))
+ jniclass_name = Copy(Getattr(optionsnode,"jniclassname"));
+ if (!jniclass_name) {
+ jniclass_name = NewStringf("%sJNI", Getattr(n,"name"));
+ module_class_name = Copy(Getattr(n,"name"));
+ } else {
+ // Rename the module name if it is the same as JNI class name - a backwards compatibility solution
+ if (Cmp(jniclass_name, Getattr(n,"name")) == 0)
+ module_class_name = NewStringf("%sModule", Getattr(n,"name"));
+ else
+ module_class_name = Copy(Getattr(n,"name"));
+ }
+
+
+ jniclass_class_code = NewString("");
+ shadow_classdef = NewString("");
+ shadow_code = NewString("");
+ module_constants_code = NewString("");
+ jniclass_baseclass = NewString("");
+ jniclass_interfaces = NewString("");
+ jniclass_class_modifiers = NewString(""); // package access only to the JNI class by default
+ module_class_code = NewString("");
+ module_baseclass = NewString("");
+ module_interfaces = NewString("");
+ module_imports = NewString("");
+ module_class_modifiers = NewString("public");
+ jniclass_imports = NewString("");
+ jniclass_cppcasts_code = NewString("");
+ wrapper_conversion_code = NewString("");
+ if (!package) package = NewString("");
+ jnipackage = NewString("");
+
+ Swig_banner(f_runtime); // Print the SWIG banner message
+
+ if (NoInclude) {
+ Printf(f_runtime,"#define SWIG_NOINCLUDE\n");
+ }
+
+ String *wrapper_name = NewString("");
+
+ if(Len(package)) {
+ String *jniname = makeValidJniName(package);
+ Printv(jnipackage, jniname, NIL);
+ Delete(jniname);
+ Replaceall(jnipackage,".","_");
+ Append(jnipackage, "_");
+ }
+ String *jniname = makeValidJniName(jniclass_name);
+ Printf(wrapper_name, "Java_%s%s_%%f", Char(jnipackage), jniname);
+ Delete(jniname);
+
+ Swig_name_register((char*)"wrapper", Char(wrapper_name));
+ Swig_name_register((char*)"set", (char*)"set_%v");
+ Swig_name_register((char*)"get", (char*)"get_%v");
+ Swig_name_register((char*)"member", (char*)"%c_%m");
+
+ Delete(wrapper_name);
+
+ Printf(f_wrappers,"#ifdef __cplusplus\n");
+ Printf(f_wrappers,"extern \"C\" {\n");
+ Printf(f_wrappers,"#endif\n");
+
+ /* Emit code */
+ Language::top(n);
+
+ // Generate the Java JNI class
+ {
+ String *filen = NewStringf("%s.java", jniclass_name);
+ File *f_java = NewFile(filen,"w");
+ if(!f_java) {
+ Printf(stderr,"Unable to open %s\n", filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(filen); filen = NULL;
+
+ // Start writing out the Java JNI class
+ if(Len(package) > 0)
+ Printf(f_java, "package %s;\n\n", package);
+
+ emitBanner(f_java);
+ if(jniclass_imports)
+ Printf(f_java, "%s\n", jniclass_imports);
+
+ if (Len(jniclass_class_modifiers) > 0)
+ Printf(f_java, "%s ", jniclass_class_modifiers);
+ Printf(f_java, "class %s ", jniclass_name);
+
+ if (jniclass_baseclass && *Char(jniclass_baseclass))
+ Printf(f_java, "extends %s ", jniclass_baseclass);
+ if (Len(jniclass_interfaces) > 0)
+ Printv(f_java, "implements ", jniclass_interfaces, " ", NIL);
+ Printf(f_java, "{\n");
+
+ // Add the native methods
+ Printv(f_java, jniclass_class_code, NIL);
+ Printv(f_java, jniclass_cppcasts_code, NIL);
+
+ // Finish off the Java class
+ Printf(f_java, "}\n");
+ Close(f_java);
+ }
+
+ // Generate the Java module class
+ {
+ String *filen = NewStringf("%s.java", module_class_name);
+ File *f_module = NewFile(filen,"w");
+ if(!f_module) {
+ Printf(stderr,"Unable to open %s\n", filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(filen); filen = NULL;
+
+ // Start writing out the Java module class
+ if(Len(package) > 0)
+ Printf(f_module, "package %s;\n\n", package);
+
+ emitBanner(f_module);
+ if(module_imports)
+ Printf(f_module, "%s\n", module_imports);
+
+ if (Len(module_class_modifiers) > 0)
+ Printf(f_module, "%s ", module_class_modifiers);
+ Printf(f_module, "class %s ", module_class_name);
+
+ if (module_baseclass && *Char(module_baseclass))
+ Printf(f_module, "extends %s ", module_baseclass);
+ if (Len(module_interfaces) > 0)
+ Printv(f_module, "implements ", module_interfaces, " ", NIL);
+ Printf(f_module, "{\n");
+
+ // Add the wrapper methods
+ Printv(f_module, module_class_code, NIL);
+
+ // Write out all the enums constants
+ if (Len(module_constants_code) != 0 )
+ Printv(f_module, " // enums and constants\n", module_constants_code, NIL);
+
+ // Finish off the Java class
+ Printf(f_module, "}\n");
+ Close(f_module);
+ }
+
+ if(wrapper_conversion_code)
+ Printv(f_wrappers,wrapper_conversion_code,NIL);
+
+ Printf(f_wrappers,"#ifdef __cplusplus\n");
+ Printf(f_wrappers,"}\n");
+ Printf(f_wrappers,"#endif\n");
+
+ // Output a Java class for each SWIG type
+ for (String *swig_type = Firstkey(swig_types_hash); swig_type; swig_type = Nextkey(swig_types_hash)) {
+ emitJavaClass(swig_type, Getattr(swig_types_hash, swig_type));
+ }
+
+ Delete(swig_types_hash); swig_types_hash = NULL;
+ Delete(jniclass_name); jniclass_name = NULL;
+ Delete(jniclass_class_code); jniclass_class_code = NULL;
+ Delete(shadow_classdef); shadow_classdef = NULL;
+ Delete(shadow_code); shadow_code = NULL;
+ Delete(module_constants_code); module_constants_code = NULL;
+ Delete(jniclass_baseclass); jniclass_baseclass = NULL;
+ Delete(jniclass_interfaces); jniclass_interfaces = NULL;
+ Delete(jniclass_class_modifiers); jniclass_class_modifiers = NULL;
+ Delete(module_class_name); module_class_name = NULL;
+ Delete(module_class_code); module_class_code = NULL;
+ Delete(module_baseclass); module_baseclass = NULL;
+ Delete(module_interfaces); module_interfaces = NULL;
+ Delete(module_imports); module_imports = NULL;
+ Delete(module_class_modifiers); module_class_modifiers = NULL;
+ Delete(jniclass_imports); jniclass_imports = NULL;
+ Delete(jniclass_cppcasts_code); jniclass_cppcasts_code = NULL;
+ Delete(wrapper_conversion_code); wrapper_conversion_code = NULL;
+ Delete(package); package = NULL;
+ Delete(jnipackage); jnipackage = NULL;
+
+ /* Close all of the files */
+ Dump(f_header,f_runtime);
+ Dump(f_wrappers,f_runtime);
+ Wrapper_pretty_print(f_init,f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_runtime);
+ Delete(f_runtime);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitBanner()
+ * ----------------------------------------------------------------------------- */
+
+ void emitBanner(File *f) {
+ Printf(f, "/* ----------------------------------------------------------------------------\n");
+ Printf(f, " * This file was automatically generated by SWIG (http://www.swig.org).\n");
+ Printf(f, " * Version: %s\n", SWIG_VERSION);
+ Printf(f, " *\n");
+ Printf(f, " * Do not make changes to this file unless you know what you are doing--modify\n");
+ Printf(f, " * the SWIG interface file instead.\n");
+ Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
+ }
+
+ /* ----------------------------------------------------------------------
+ * nativeWrapper()
+ * ---------------------------------------------------------------------- */
+
+ virtual int nativeWrapper(Node *n) {
+ String *wrapname = Getattr(n,"wrap:name");
+
+ if (!addSymbol(wrapname,n)) return SWIG_ERROR;
+
+ if (Getattr(n,"type")) {
+ Swig_save(&n,"name",NIL);
+ Setattr(n,"name", wrapname);
+ native_function_flag = true;
+ functionWrapper(n);
+ Swig_restore(&n);
+ native_function_flag = false;
+ } else {
+ Printf(stderr,"%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n,"wrap:name"));
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * functionWrapper()
+ * ---------------------------------------------------------------------- */
+
+ virtual int functionWrapper(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+ String *tm;
+ Parm *p;
+ int i;
+ String *jnirettype = NewString("");
+ String *javarettype = NewString("");
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *body = NewString("");
+ String *javaParameterSignature = NewString("");
+ int num_arguments = 0;
+ int num_required = 0;
+ bool is_void_return;
+ String *overloaded_name = getOverloadedName(n);
+
+ if (!Getattr(n,"sym:overloaded")) {
+ if (!addSymbol(Getattr(n,"sym:name"),n)) return SWIG_ERROR;
+ }
+
+ /*
+ Generate the java class wrapper function ie the java shadow class. Only done for public
+ member variables. That is this generates the getters/setters for member variables.
+ Not for enums and constants.
+ */
+ if(proxy_flag && wrapping_member_flag && !enum_constant_flag) {
+ // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name
+ String *getter_setter_name = NewString("");
+ if(Cmp(symname, Swig_name_set(Swig_name_member(shadow_classname, variable_name))) == 0)
+ Printf(getter_setter_name,"set");
+ else
+ Printf(getter_setter_name,"get");
+ Putc(toupper((int) *Char(variable_name)), getter_setter_name);
+ Printf(getter_setter_name, "%s", Char(variable_name)+1);
+
+ Setattr(n,"java:shadowfuncname", getter_setter_name);
+ Setattr(n,"java:funcname", symname);
+
+ javaShadowFunctionHandler(n);
+
+ Delete(getter_setter_name);
+ }
+
+ /*
+ The rest of this function deals with generating the java wrapper function (that wraps
+ a c/c++ function) and generating the JNI c code. Each java wrapper function has a
+ matching JNI c function call.
+ */
+
+ // A new wrapper function object
+ Wrapper *f = NewWrapper();
+
+ // Make a wrapper name for this function
+ String *jniname = makeValidJniName(overloaded_name);
+ String *wname = Swig_name_wrapper(jniname);
+ Delete(jniname);
+
+ /* Attach the non-standard typemaps to the parameter list. */
+ Swig_typemap_attach_parms("jni", l, f);
+ Swig_typemap_attach_parms("jtype", l, f);
+
+ /* Get Java return types */
+ if ((tm = Swig_typemap_lookup_new("jni",n,"",0))) {
+ Printf(jnirettype,"%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number,
+ "No jni typemap defined for %s\n", SwigType_str(t,0));
+ }
+
+ if ((tm = Swig_typemap_lookup_new("jtype",n,"",0))) {
+ Printf(javarettype,"%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number,
+ "No jtype typemap defined for %s\n", SwigType_str(t,0));
+ }
+
+ is_void_return = (Cmp(jnirettype, "void") == 0);
+ if (!is_void_return)
+ Wrapper_add_localv(f,"jresult", jnirettype, "jresult = 0",NIL);
+
+ Printf(jniclass_class_code, " public final static native %s %s(", javarettype, overloaded_name);
+
+ Printv(f->def, "JNIEXPORT ", jnirettype, " JNICALL ", wname, "(JNIEnv *jenv, jclass jcls", NIL);
+
+ // Usually these function parameters are unused - The code below ensures that compilers do not issue such a warning if configured to do so.
+ Printv(f->code," (void)jenv;\n",NIL);
+ Printv(f->code," (void)jcls;\n",NIL);
+
+ // Emit all of the local variables for holding arguments.
+ emit_args(t,l,f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l,f);
+ Setattr(n,"wrap:parms",l);
+
+ /* Get number of required and total arguments */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+
+ int gencomma = 0;
+
+ // Now walk the function parameter list and generate code to get arguments
+ for (i = 0, p=l; i < num_arguments; i++) {
+
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *ln = Getattr(p,"lname");
+ String *javaparamtype = NewString("");
+ String *jni_param_type = NewString("");
+ String *arg = NewString("");
+
+ Printf(arg,"j%s", ln);
+
+ /* Get the jni types of the parameter */
+ if ((tm = Getattr(p,"tmap:jni"))) {
+ Printv(jni_param_type, tm, NIL);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number,
+ "No jni typemap defined for %s\n", SwigType_str(pt,0));
+ }
+
+ /* Get the java types of the parameter */
+ if ((tm = Getattr(p,"tmap:jtype"))) {
+ Printv(javaparamtype, tm, NIL);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number,
+ "No jtype typemap defined for %s\n", SwigType_str(pt,0));
+ }
+
+ /* Add to java function header */
+ if(gencomma) Printf(jniclass_class_code, ", ");
+ Printf(jniclass_class_code, "%s %s", javaparamtype, arg);
+
+ gencomma = 1;
+
+ // Add to Jni function header
+ Printv(f->def, ", ", jni_param_type, " ", arg, NIL);
+
+ // Get typemap for this argument
+ if ((tm = Getattr(p,"tmap:in"))) {
+ addThrows(n, "tmap:in", p);
+ Replaceall(tm,"$source",arg); /* deprecated */
+ Replaceall(tm,"$target",ln); /* deprecated */
+ Replaceall(tm,"$arg",arg); /* deprecated? */
+ Replaceall(tm,"$input", arg);
+ Setattr(p,"emit:input", arg);
+ Printf(f->code,"%s\n", tm);
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument.\n",SwigType_str(pt,0));
+ p = nextSibling(p);
+ }
+ Delete(javaparamtype);
+ Delete(jni_param_type);
+ Delete(arg);
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:check"))) {
+ addThrows(n, "tmap:check", p);
+ Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */
+ Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:freearg"))) {
+ addThrows(n, "tmap:freearg", p);
+ Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */
+ Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(cleanup,tm,"\n",NIL);
+ p = Getattr(p,"tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:argout"))) {
+ addThrows(n, "tmap:argout", p);
+ Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */
+ Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */
+ Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */
+ Replaceall(tm,"$result","jresult");
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(outarg,tm,"\n",NIL);
+ p = Getattr(p,"tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Get any Java exception classes in the throw typemap
+ if (ParmList *throw_parm_list = Getattr(n,"throws")) {
+ Swig_typemap_attach_parms("throws", throw_parm_list, f);
+ for (p = throw_parm_list; p; p=nextSibling(p)) {
+ if ((tm = Getattr(p,"tmap:throws"))) {
+ addThrows(n, "tmap:throws", p);
+ }
+ }
+ }
+
+ if (Cmp(nodeType(n), "constant") == 0) {
+ // Wrapping a constant hack
+ Swig_save(&n,"wrap:action",NIL);
+
+ // below based on Swig_VargetToFunction()
+ SwigType *ty = Swig_wrapped_var_type(Getattr(n,"type"));
+ Setattr(n,"wrap:action", NewStringf("result = (%s) %s;\n", SwigType_lstr(ty,0), Getattr(n, "value")));
+ }
+
+ // Now write code to make the function call
+ if(!native_function_flag)
+ emit_action(n,f);
+
+ if (Cmp(nodeType(n), "constant") == 0)
+ Swig_restore(&n);
+
+ /* Return value if necessary */
+ if(!native_function_flag) {
+ if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
+ addThrows(n, "tmap:out", n);
+ Replaceall(tm,"$source", "result"); /* deprecated */
+ Replaceall(tm,"$target", "jresult"); /* deprecated */
+ Replaceall(tm,"$result","jresult");
+ Printf(f->code,"%s", tm);
+ if (Len(tm))
+ Printf(f->code,"\n");
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s in function %s.\n", SwigType_str(t,0), Getattr(n,"name"));
+ }
+ }
+
+ /* Output argument output code */
+ Printv(f->code,outarg,NIL);
+
+ /* Output cleanup code */
+ Printv(f->code,cleanup,NIL);
+
+ /* Look to see if there is any newfree cleanup code */
+ if (Getattr(n,"feature:new")) {
+ if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
+ Replaceall(tm,"$source","result"); /* deprecated */
+ Printf(f->code,"%s\n",tm);
+ }
+ }
+
+ /* See if there is any return cleanup code */
+ if(!native_function_flag) {
+ if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) {
+ Replaceall(tm,"$source","result"); /* deprecated */
+ Printf(f->code,"%s\n",tm);
+ }
+ }
+
+ /* Finish JNI C function and JNI class native function definitions */
+ Printf(jniclass_class_code, ")");
+ generateThrowsClause(n, jniclass_class_code);
+ Printf(jniclass_class_code, ";\n");
+ Printf(f->def,") {");
+
+ if(!is_void_return)
+ Printv(f->code, " return jresult;\n", NIL);
+ Printf(f->code, "}\n");
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code,"$cleanup",cleanup);
+
+ if(!is_void_return)
+ Replaceall(f->code,"$null","0");
+ else
+ Replaceall(f->code,"$null","");
+
+ /* Dump the function out */
+ if(!native_function_flag)
+ Wrapper_print(f,f_wrappers);
+
+ Setattr(n,"wrap:name", wname);
+
+ /* Emit warnings for the few cases that can't be overloaded in Java */
+ if (Getattr(n,"sym:overloaded")) {
+ if (!Getattr(n,"sym:nextSibling"))
+ Swig_overload_rank(n);
+ }
+
+ if(!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
+ moduleClassFunctionHandler(n);
+ }
+
+ Delete(jnirettype);
+ Delete(javarettype);
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(body);
+ Delete(javaParameterSignature);
+ Delete(overloaded_name);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * variableWrapper()
+ *
+ * Create a JAVA link to a C variable.
+ * ----------------------------------------------------------------------- */
+
+ virtual int variableWrapper(Node *n) {
+ Language::variableWrapper(n); /* Default to functions */
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * globalvariableHandler()
+ * ------------------------------------------------------------------------ */
+
+ virtual int globalvariableHandler(Node *n) {
+
+ variable_name = Getattr(n,"sym:name");
+ global_variable_flag = true;
+ int ret = Language::globalvariableHandler(n);
+ global_variable_flag = false;
+ return ret;
+ }
+
+ /* -----------------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+ String *tm;
+ String *shadowrettype = NewString("");
+ String *constants_code = NewString("");
+
+ if (!addSymbol(symname,n)) return SWIG_ERROR;
+
+ /* Attach the non-standard typemaps to the parameter list. */
+ Swig_typemap_attach_parms("jstype", l, NULL);
+
+ /* Get Java return types */
+ bool is_return_type_java_class = false;
+ if ((tm = Swig_typemap_lookup_new("jstype",n,"",0))) {
+ is_return_type_java_class = substituteJavaclassname(t, tm);
+ Printf(shadowrettype, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number,
+ "No jstype typemap defined for %s\n", SwigType_str(t,0));
+ }
+
+ // Add the stripped quotes back in
+ String *new_value = NewString("");
+ Swig_save(&n,"value",NIL);
+ if(SwigType_type(t) == T_STRING) {
+ Printf(new_value, "\"%s\"", Copy(Getattr(n, "value")));
+ Setattr(n, "value", new_value);
+ }
+ else if(SwigType_type(t) == T_CHAR) {
+ Printf(new_value, "\'%s\'", Copy(Getattr(n, "value")));
+ Setattr(n, "value", new_value);
+ }
+
+ // enums are wrapped using a public final static int in java.
+ // Other constants are wrapped using a public final static [jstype] in Java.
+ Printf(constants_code, " public final static %s %s = ", shadowrettype, ((proxy_flag && wrapping_member_flag) ? variable_name : symname));
+
+ // The %javaconst directive determines how the constant value is obtained
+ String *javaconst = Getattr(n,"feature:java:const");
+ if (Cmp(nodeType(n), "enumitem") == 0 || !javaconst || Cmp(javaconst, "0") == 0) {
+ // Enums and default constant handling will work with any type of C constant and initialises the Java variable from C through a JNI call.
+
+ if(is_return_type_java_class) // This handles function pointers using the %constant directive
+ Printf(constants_code, "new %s(%s.%s(), false);\n", shadowrettype, jniclass_name, Swig_name_get(symname));
+ else
+ Printf(constants_code, "%s.%s();\n", jniclass_name, Swig_name_get(symname));
+
+ // Each constant and enum value is wrapped with a separate JNI function call
+ enum_constant_flag = true;
+ variableWrapper(n);
+ enum_constant_flag = false;
+ } else {
+ // Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code
+ Printf(constants_code, "%s;\n", Getattr(n,"value"));
+ }
+
+ if(proxy_flag && wrapping_member_flag)
+ Printv(shadow_constants_code, constants_code, NIL);
+ else
+ Printv(module_constants_code, constants_code, NIL);
+
+ Swig_restore(&n);
+ Delete(new_value);
+ Delete(shadowrettype);
+ Delete(constants_code);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * pragmaDirective()
+ *
+ * Valid Pragmas:
+ * jniclassbase - base (extends) for the JNI class
+ * jniclassclassmodifiers - class modifiers for the JNI class
+ * jniclasscode - text (java code) is copied verbatim to the JNI class
+ * jniclassimports - import statements for the JNI class
+ * jniclassinterfaces - interface (implements) for the JNI class
+ *
+ * modulebase - base (extends) for the module class
+ * moduleclassmodifiers - class modifiers for the module class
+ * modulecode - text (java code) is copied verbatim to the module class
+ * moduleimports - import statements for the module class
+ * moduleinterfaces - interface (implements) for the module class
+ *
+ * ----------------------------------------------------------------------------- */
+
+ virtual int pragmaDirective(Node *n) {
+ if (!ImportMode) {
+ String *lang = Getattr(n,"lang");
+ String *code = Getattr(n,"name");
+ String *value = Getattr(n,"value");
+
+ if(Strcmp(lang, "java") == 0) {
+
+ String *strvalue = NewString(value);
+ Replaceall(strvalue,"\\\"", "\"");
+
+ if(Strcmp(code, "jniclassbase") == 0) {
+ Delete(jniclass_baseclass);
+ jniclass_baseclass = Copy(strvalue);
+ }
+ else if(Strcmp(code, "jniclassclassmodifiers") == 0) {
+ Delete(jniclass_class_modifiers);
+ jniclass_class_modifiers = Copy(strvalue);
+ }
+ else if(Strcmp(code, "jniclasscode") == 0) {
+ Printf(jniclass_class_code, "%s\n", strvalue);
+ }
+ else if(Strcmp(code, "jniclassimports") == 0) {
+ Delete(jniclass_imports);
+ jniclass_imports = Copy(strvalue);
+ }
+ else if(Strcmp(code, "jniclassinterfaces") == 0) {
+ Delete(jniclass_interfaces);
+ jniclass_interfaces = Copy(strvalue);
+ }
+ else if(Strcmp(code, "modulebase") == 0) {
+ Delete(module_baseclass);
+ module_baseclass = Copy(strvalue);
+ }
+ else if(Strcmp(code, "moduleclassmodifiers") == 0) {
+ Delete(module_class_modifiers);
+ module_class_modifiers = Copy(strvalue);
+ }
+ else if(Strcmp(code, "modulecode") == 0) {
+ Printf(module_class_code, "%s\n", strvalue);
+ }
+ else if(Strcmp(code, "moduleimports") == 0) {
+ Delete(module_imports);
+ module_imports = Copy(strvalue);
+ }
+ else if(Strcmp(code, "moduleinterfaces") == 0) {
+ Delete(module_interfaces);
+ module_interfaces = Copy(strvalue);
+ }
+ else if(Strcmp(code, "moduleimport") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use the moduleimports pragma.\n", input_file, line_number);
+ }
+ else if(Strcmp(code, "moduleinterface") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use the moduleinterfaces pragma.\n", input_file, line_number);
+ }
+ else if(Strcmp(code, "modulemethodmodifiers") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %javamethodmodifiers.\n", input_file, line_number);
+ }
+ else if(Strcmp(code, "allshadowimport") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaimports).\n", input_file, line_number);
+ }
+ else if(Strcmp(code, "allshadowcode") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javacode).\n", input_file, line_number);
+ }
+ else if(Strcmp(code, "allshadowbase") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javabase).\n", input_file, line_number);
+ }
+ else if(Strcmp(code, "allshadowinterface") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javainterfaces).\n", input_file, line_number);
+ }
+ else if(Strcmp(code, "allshadowclassmodifiers") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaclassmodifiers).\n", input_file, line_number);
+ }
+ else if (proxy_flag) {
+ if (Strcmp(code,"shadowcode") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javacode).\n", input_file, line_number);
+ }
+ else if (Strcmp(code,"shadowimport") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaimports).\n", input_file, line_number);
+ }
+ else if (Strcmp(code,"shadowbase") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javabase).\n", input_file, line_number);
+ }
+ else if (Strcmp(code,"shadowinterface") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javainterfaces).\n", input_file, line_number);
+ }
+ else if (Strcmp(code,"shadowclassmodifiers") == 0) {
+ Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaclassmodifiers).\n", input_file, line_number);
+ } else {
+ Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number);
+ }
+ } else {
+ Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number);
+ }
+ Delete(strvalue);
+ }
+ }
+ return Language::pragmaDirective(n);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitShadowClassDefAndCPPCasts()
+ * ----------------------------------------------------------------------------- */
+
+ void emitShadowClassDefAndCPPCasts(Node *n) {
+ String *c_classname = SwigType_namestr(Getattr(n,"name"));
+ String *c_baseclass = NULL;
+ String *baseclass = NULL;
+ String *c_baseclassname = NULL;
+
+ /* Deal with inheritance */
+ List *baselist = Getattr(n,"bases");
+ if (baselist) {
+ Node *base = Firstitem(baselist);
+ c_baseclassname = Getattr(base,"name");
+ baseclass = Copy(is_shadow(c_baseclassname));
+ if (baseclass){
+ c_baseclass = SwigType_namestr(Getattr(base,"name"));
+ }
+ base = Nextitem(baselist);
+ if (base) {
+ Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number,
+ "Warning for %s: Base %s ignored. Multiple inheritance is not supported in Java.\n", shadow_classname, Getattr(base,"name"));
+ }
+ }
+
+ bool derived = baseclass && is_shadow(c_baseclassname);
+ if (!baseclass)
+ baseclass = NewString("");
+
+ // Inheritance from pure Java classes
+ const String *pure_java_baseclass = javaTypemapLookup("javabase", shadow_classname, WARN_NONE);
+ if (Len(pure_java_baseclass) > 0 && Len(baseclass) > 0) {
+ Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number,
+ "Warning for %s: Base %s ignored. Multiple inheritance is not supported in Java.\n", shadow_classname, pure_java_baseclass);
+ }
+
+ // Pure Java interfaces
+ const String *pure_java_interfaces = javaTypemapLookup("javainterfaces", shadow_classname, WARN_NONE);
+
+ // Start writing the shadow class
+ Printv(shadow_classdef,
+ javaTypemapLookup("javaimports", shadow_classname, WARN_NONE), // Import statements
+ "\n",
+ javaTypemapLookup("javaclassmodifiers", shadow_classname, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
+ " class $javaclassname", // Class name and bases
+ (derived || *Char(pure_java_baseclass)) ?
+ " extends " :
+ "",
+ baseclass,
+ pure_java_baseclass,
+ *Char(pure_java_interfaces) ? // Pure Java interfaces
+ " implements " :
+ "",
+ pure_java_interfaces,
+ " {\n",
+ " private long swigCPtr;\n", // Member variables for memory handling
+ derived ?
+ "" :
+ " protected boolean swigCMemOwn;\n",
+ "\n",
+ " ",
+ javaTypemapLookup("javaptrconstructormodifiers", shadow_classname, WARN_JAVA_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers
+ " $javaclassname(long cPtr, boolean cMemoryOwn) {\n", // Constructor used for wrapping pointers
+ derived ?
+ " super($jniclassname.SWIG$javaclassnameTo$baseclass(cPtr), cMemoryOwn);\n" :
+ " swigCMemOwn = cMemoryOwn;\n",
+ " swigCPtr = cPtr;\n",
+ " }\n",
+ NIL);
+
+ if(!have_default_constructor_flag) { // All Java classes need a constructor
+ Printv(shadow_classdef,
+ "\n",
+ " protected $javaclassname() {\n",
+ " this(0, false);\n",
+ " }\n",
+ NIL);
+ }
+
+ Printv(shadow_classdef,
+ javaTypemapLookup("javafinalize", shadow_classname, WARN_NONE), // finalize method
+ "\n",
+ *Char(destructor_call) ?
+ " public void delete() {\n" :
+ " protected void delete() {\n",
+ " if(swigCPtr != 0 && swigCMemOwn) {\n",
+ destructor_call,
+ "",
+ " swigCMemOwn = false;\n",
+ derived ? // Zero all pointers up any inheritance hierarchy
+ " super.delete();\n" :
+ "",
+ " }\n",
+ " swigCPtr = 0;\n",
+ " }\n",
+ javaTypemapLookup("javagetcptr", shadow_classname, WARN_JAVA_TYPEMAP_GETCPTR_UNDEF), // getCPtr method
+ javaTypemapLookup("javacode", shadow_classname, WARN_NONE), // extra Java code
+ "\n",
+ NIL);
+
+ // Substitute various strings into the above template
+ Replaceall(shadow_code, "$javaclassname", shadow_classname);
+ Replaceall(shadow_classdef, "$javaclassname", shadow_classname);
+
+ Replaceall(shadow_classdef, "$baseclass", baseclass);
+ Replaceall(shadow_code, "$baseclass", baseclass);
+
+ Replaceall(shadow_classdef, "$jniclassname", jniclass_name);
+ Replaceall(shadow_code, "$jniclassname", jniclass_name);
+
+ // Add JNI code to do C++ casting to base class (only for classes in an inheritance hierarchy)
+ if(derived){
+ Printv(jniclass_cppcasts_code," public final static native long ",
+ "SWIG$javaclassnameTo$baseclass(long jarg1);\n",
+ NIL);
+
+ Replaceall(jniclass_cppcasts_code, "$javaclassname", shadow_classname);
+ Replaceall(jniclass_cppcasts_code, "$baseclass", baseclass);
+
+ Printv(wrapper_conversion_code,
+ "JNIEXPORT jlong JNICALL Java_$jnipackage$jnijniclass_SWIG$jniclazznameTo$jnibaseclass",
+ "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
+ " jlong baseptr = 0;\n"
+ " (void)jenv;\n"
+ " (void)jcls;\n"
+ " *($cbaseclass **)&baseptr = *($cclass **)&jarg1;\n"
+ " return baseptr;\n"
+ "}\n",
+ "\n",
+ NIL);
+
+ String *jnijniclass = makeValidJniName(jniclass_name);
+ String *jniclazzname = makeValidJniName(shadow_classname);
+ String *jnibaseclass = makeValidJniName(baseclass);
+ Replaceall(wrapper_conversion_code, "$jnibaseclass",jnibaseclass);
+ Replaceall(wrapper_conversion_code, "$cbaseclass", c_baseclass);
+ Replaceall(wrapper_conversion_code, "$jniclazzname",jniclazzname);
+ Replaceall(wrapper_conversion_code, "$cclass", c_classname);
+ Replaceall(wrapper_conversion_code, "$jnipackage", jnipackage);
+ Replaceall(wrapper_conversion_code, "$jnijniclass", jnijniclass);
+
+ Delete(jnibaseclass);
+ Delete(jniclazzname);
+ Delete(jnijniclass);
+ }
+ Delete(baseclass);
+ }
+
+ /* ----------------------------------------------------------------------
+ * classHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int classHandler(Node *n) {
+
+ File *f_shadow = NULL;
+ if (proxy_flag) {
+ shadow_classname = NewString(Getattr(n,"sym:name"));
+
+ if (!addSymbol(shadow_classname,n)) return SWIG_ERROR;
+
+ if (Cmp(shadow_classname, jniclass_name) == 0) {
+ Printf(stderr, "Class name cannot be equal to JNI class name: %s\n", shadow_classname);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ if (Cmp(shadow_classname, module_class_name) == 0) {
+ Printf(stderr, "Class name cannot be equal to module class name: %s\n", shadow_classname);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ String *filen = NewStringf("%s.java", shadow_classname);
+ f_shadow = NewFile(filen,"w");
+ if(!f_shadow) {
+ Printf(stderr, "Unable to create proxy class file: %s\n", filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(filen); filen = NULL;
+
+ emitBanner(f_shadow);
+
+ if(Len(package) > 0)
+ Printf(f_shadow, "package %s;\n\n", package);
+
+ Clear(shadow_classdef);
+ Clear(shadow_code);
+
+ have_default_constructor_flag = false;
+ destructor_call = NewString("");
+ shadow_constants_code = NewString("");
+ }
+ Language::classHandler(n);
+
+ if (proxy_flag) {
+
+ emitShadowClassDefAndCPPCasts(n);
+
+ Printv(f_shadow, shadow_classdef, shadow_code, NIL);
+
+ // Write out all the enums and constants
+ if (Len(shadow_constants_code) != 0 )
+ Printv(f_shadow, " // enums and constants\n", shadow_constants_code, NIL);
+
+ Printf(f_shadow, "}\n");
+ Close(f_shadow);
+ f_shadow = NULL;
+
+ Delete(shadow_classname); shadow_classname = NULL;
+ Delete(destructor_call); destructor_call = NULL;
+ Delete(shadow_constants_code); shadow_constants_code = NULL;
+ }
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int memberfunctionHandler(Node *n) {
+ Language::memberfunctionHandler(n);
+
+ if (proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *java_function_name = Swig_name_member(shadow_classname, overloaded_name);
+ Setattr(n,"java:shadowfuncname", Getattr(n, "sym:name"));
+ Setattr(n,"java:funcname", java_function_name);
+ javaShadowFunctionHandler(n);
+ Delete(overloaded_name);
+ }
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+
+ static_flag = true;
+ Language::staticmemberfunctionHandler(n);
+
+ if (proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *java_function_name = Swig_name_member(shadow_classname, overloaded_name);
+ Setattr(n,"java:shadowfuncname", Getattr(n,"sym:name"));
+ Setattr(n,"java:funcname", java_function_name);
+ javaShadowFunctionHandler(n);
+ Delete(overloaded_name);
+ }
+ static_flag = false;
+
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * javaShadowFunctionHandler()
+ *
+ * Function called for creating a java class wrapper function around a c++ function in the
+ * java wrapper class. Used for both static and non static functions.
+ * C++ static functions map to java static functions.
+ * Two extra attributes in the Node must be available. These are "java:shadowfuncname" - the name of the java class shadow
+ * function, which in turn will call "java:funcname" - the java native function name which wraps the c++ function.
+ * ----------------------------------------------------------------------------- */
+
+ void javaShadowFunctionHandler(Node *n) {
+ SwigType *t = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+ String *java_function_name = Getattr(n,"java:funcname");
+ String *java_shadow_function_name = Getattr(n,"java:shadowfuncname");
+ String *tm;
+ Parm *p;
+ int i;
+ String *nativecall = NewString("");
+ String *shadowrettype = NewString("");
+ String *user_arrays = NewString("");
+
+ if(!proxy_flag) return;
+
+ if (l) {
+ if (SwigType_type(Getattr(l,"type")) == T_VOID) {
+ l = nextSibling(l);
+ }
+ }
+
+ /* Attach the non-standard typemaps to the parameter list */
+ Swig_typemap_attach_parms("in", l, NULL);
+ Swig_typemap_attach_parms("jstype", l, NULL);
+ Swig_typemap_attach_parms("javain", l, NULL);
+
+ /* Get Java return types */
+ if ((tm = Swig_typemap_lookup_new("jstype",n,"",0))) {
+ substituteJavaclassname(t, tm);
+ Printf(shadowrettype, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number,
+ "No jstype typemap defined for %s\n", SwigType_str(t,0));
+ }
+
+ /* Start generating the shadow function */
+ Printf(shadow_code, " %s ", Getattr(n,"feature:java:methodmodifiers"));
+ if (static_flag)
+ Printf(shadow_code, "static ");
+ Printf(shadow_code, "%s %s(", shadowrettype, java_shadow_function_name);
+
+ Printv(nativecall, jniclass_name, ".", java_function_name, "(", NIL);
+ if (!static_flag)
+ Printv(nativecall, "swigCPtr", NIL);
+
+ int gencomma = !static_flag;
+
+ /* Output each parameter */
+ for (i = 0, p=l; p; i++) {
+
+ /* Ignored parameters */
+ if (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ continue;
+ }
+
+ /* Ignore the 'this' argument for variable wrappers */
+ if (!(variable_wrapper_flag && i==0))
+ {
+ SwigType *pt = Getattr(p,"type");
+ String *javaparamtype = NewString("");
+
+ /* Get the java type of the parameter */
+ if ((tm = Getattr(p,"tmap:jstype"))) {
+ substituteJavaclassname(pt, tm);
+ Printf(javaparamtype, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number,
+ "No jstype typemap defined for %s\n", SwigType_str(pt,0));
+ }
+
+ if (gencomma)
+ Printf(nativecall, ", ");
+
+ String *arg = makeParameterName(n, p, i);
+
+ // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in native function (in JNI class)
+ if ((tm = Getattr(p,"tmap:javain"))) {
+ substituteJavaclassname(pt, tm);
+ Replaceall(tm, "$javainput", arg);
+ Printv(nativecall, tm, NIL);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number,
+ "No javain typemap defined for %s\n", SwigType_str(pt,0));
+ }
+
+ /* Add to java shadow function header */
+ if (gencomma >= 2)
+ Printf(shadow_code, ", ");
+ gencomma = 2;
+ Printf(shadow_code, "%s %s", javaparamtype, arg);
+
+ Delete(arg);
+ Delete(javaparamtype);
+ }
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ Printf(nativecall, ")");
+ Printf(shadow_code, ")");
+ generateThrowsClause(n, shadow_code);
+
+ // Transform return type used in native function (in JNI class) to type used in Java wrapper function (in proxy class)
+ if ((tm = Swig_typemap_lookup_new("javaout",n,"",0))) {
+ if (Getattr(n,"feature:new"))
+ Replaceall(tm,"$owner","true");
+ else
+ Replaceall(tm,"$owner","false");
+ substituteJavaclassname(t, tm);
+ Replaceall(tm, "$jnicall", nativecall);
+ Printf(shadow_code, " %s\n\n", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number,
+ "No javaout typemap defined for %s\n", SwigType_str(t,0));
+ }
+
+ Delete(shadowrettype);
+ Delete(nativecall);
+ Delete(user_arrays);
+ }
+
+ /* ----------------------------------------------------------------------
+ * constructorHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int constructorHandler(Node *n) {
+
+ ParmList *l = Getattr(n,"parms");
+ String *tm;
+ Parm *p;
+ int i;
+ String *user_arrays = NewString("");
+
+ Language::constructorHandler(n);
+
+ if(proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *nativecall = NewString("");
+
+ Printf(shadow_code, " %s %s(", Getattr(n,"feature:java:methodmodifiers"), shadow_classname);
+ Printv(nativecall, "this(", jniclass_name, ".", Swig_name_construct(overloaded_name), "(", NIL);
+
+ /* Attach the non-standard typemaps to the parameter list */
+ Swig_typemap_attach_parms("in", l, NULL);
+ Swig_typemap_attach_parms("jstype", l, NULL);
+ Swig_typemap_attach_parms("javain", l, NULL);
+
+ int gencomma = 0;
+
+ /* Output each parameter */
+ for (i = 0, p=l; p; i++) {
+
+ /* Ignored parameters */
+ if (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ continue;
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *javaparamtype = NewString("");
+
+ /* Get the java type of the parameter */
+ if ((tm = Getattr(p,"tmap:jstype"))) {
+ substituteJavaclassname(pt, tm);
+ Printf(javaparamtype, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number,
+ "No jstype typemap defined for %s\n", SwigType_str(pt,0));
+ }
+
+ if (gencomma)
+ Printf(nativecall, ", ");
+
+ String *arg = makeParameterName(n, p, i);
+
+ // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in native function (in JNI class)
+ if ((tm = Getattr(p,"tmap:javain"))) {
+ substituteJavaclassname(pt, tm);
+ Replaceall(tm, "$javainput", arg);
+ Printv(nativecall, tm, NIL);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number,
+ "No javain typemap defined for %s\n", SwigType_str(pt,0));
+ }
+
+ /* Add to java shadow function header */
+ if(gencomma)
+ Printf(shadow_code, ", ");
+ Printf(shadow_code, "%s %s", javaparamtype, arg);
+ gencomma = 1;
+
+ Delete(arg);
+ Delete(javaparamtype);
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ Printf(nativecall, "), true);\n");
+
+ Printf(shadow_code, ")");
+ generateThrowsClause(n, shadow_code);
+ Printf(shadow_code, " {\n");
+ Printv(shadow_code, user_arrays, NIL);
+ Printf(shadow_code, " %s", nativecall);
+ Printf(shadow_code, " }\n\n");
+
+ if(!gencomma) // We must have a default constructor
+ have_default_constructor_flag = true;
+
+ Delete(overloaded_name);
+ Delete(nativecall);
+ }
+
+ Delete(user_arrays);
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * destructorHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int destructorHandler(Node *n) {
+ Language::destructorHandler(n);
+ String *symname = Getattr(n,"sym:name");
+
+ if(proxy_flag) {
+ Printv(destructor_call, " ", jniclass_name, ".", Swig_name_destroy(symname), "(swigCPtr);\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * membervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int membervariableHandler(Node *n) {
+ variable_name = Getattr(n,"sym:name");
+ wrapping_member_flag = true;
+ variable_wrapper_flag = true;
+ Language::membervariableHandler(n);
+ wrapping_member_flag = false;
+ variable_wrapper_flag = false;
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * staticmembervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ variable_name = Getattr(n,"sym:name");
+ wrapping_member_flag = true;
+ static_flag = true;
+ Language::staticmembervariableHandler(n);
+ wrapping_member_flag = false;
+ static_flag = false;
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberconstantHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int memberconstantHandler(Node *n) {
+ variable_name = Getattr(n,"sym:name");
+ wrapping_member_flag = true;
+ Language::memberconstantHandler(n);
+ wrapping_member_flag = false;
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getOverloadedName()
+ * ----------------------------------------------------------------------------- */
+
+ String *getOverloadedName(Node *n) {
+
+ /* Although the JNI is designed to handle overloaded Java functions, a Java long is used for all classes in the SWIG
+ * JNI native interface. The JNI native interface function is thus mangled when overloaded to give a unique name. */
+ String *overloaded_name = NewStringf("%s", Getattr(n,"sym:name"));
+
+ if (Getattr(n,"sym:overloaded")) {
+ Printv(overloaded_name, Getattr(n,"sym:overname"), NIL);
+ }
+
+ return overloaded_name;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * moduleClassFunctionHandler()
+ * ----------------------------------------------------------------------------- */
+
+ void moduleClassFunctionHandler(Node *n) {
+ SwigType *t = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+ String *tm;
+ Parm *p;
+ int i;
+ String *nativecall = NewString("");
+ String *shadowrettype = NewString("");
+ String *user_arrays = NewString("");
+ int num_arguments = 0;
+ int num_required = 0;
+ String *overloaded_name = getOverloadedName(n);
+ String *func_name = NULL;
+
+ if (l) {
+ if (SwigType_type(Getattr(l,"type")) == T_VOID) {
+ l = nextSibling(l);
+ }
+ }
+
+ /* Attach the non-standard typemaps to the parameter list */
+ Swig_typemap_attach_parms("jstype", l, NULL);
+ Swig_typemap_attach_parms("javain", l, NULL);
+
+ /* Get Java return types */
+ if ((tm = Swig_typemap_lookup_new("jstype",n,"",0))) {
+ substituteJavaclassname(t, tm);
+ Printf(shadowrettype, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number,
+ "No jstype typemap defined for %s\n", SwigType_str(t,0));
+ }
+
+ /* Change function name for global variables */
+ if (proxy_flag && global_variable_flag) {
+ // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name
+ func_name = NewString("");
+ if(Cmp(Getattr(n,"sym:name"), Swig_name_set(variable_name)) == 0)
+ Printf(func_name,"set");
+ else
+ Printf(func_name,"get");
+ Putc(toupper((int) *Char(variable_name)), func_name);
+ Printf(func_name, "%s", Char(variable_name)+1);
+ } else {
+ func_name = Copy(Getattr(n,"sym:name"));
+ }
+
+ /* Start generating the function */
+ Printf(module_class_code, " %s static %s %s(", Getattr(n,"feature:java:methodmodifiers"), shadowrettype, func_name);
+ Printv(nativecall, jniclass_name, ".", overloaded_name, "(", NIL);
+
+ /* Get number of required and total arguments */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+
+ int gencomma = 0;
+
+ /* Output each parameter */
+ for (i = 0, p=l; i < num_arguments; i++) {
+
+ /* Ignored parameters */
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *javaparamtype = NewString("");
+
+ /* Get the java type of the parameter */
+ if ((tm = Getattr(p,"tmap:jstype"))) {
+ substituteJavaclassname(pt, tm);
+ Printf(javaparamtype, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number,
+ "No jstype typemap defined for %s\n", SwigType_str(pt,0));
+ }
+
+ if (gencomma)
+ Printf(nativecall, ", ");
+
+ String *arg = makeParameterName(n, p, i);
+
+ // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in native function (in JNI class)
+ if ((tm = Getattr(p,"tmap:javain"))) {
+ substituteJavaclassname(pt, tm);
+ Replaceall(tm, "$javainput", arg);
+ Printv(nativecall, tm, NIL);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number,
+ "No javain typemap defined for %s\n", SwigType_str(pt,0));
+ }
+
+ /* Add to java shadow function header */
+ if (gencomma >= 2)
+ Printf(module_class_code, ", ");
+ gencomma = 2;
+ Printf(module_class_code, "%s %s", javaparamtype, arg);
+
+ p = Getattr(p,"tmap:in:next");
+ Delete(arg);
+ Delete(javaparamtype);
+ }
+
+ Printf(nativecall, ")");
+ Printf(module_class_code, ")");
+ generateThrowsClause(n, module_class_code);
+
+ // Transform return type used in native function (in JNI class) to type used in Java wrapper function (in module class)
+ if ((tm = Swig_typemap_lookup_new("javaout",n,"",0))) {
+ if (Getattr(n,"feature:new"))
+ Replaceall(tm,"$owner","true");
+ else
+ Replaceall(tm,"$owner","false");
+ substituteJavaclassname(t, tm);
+ Replaceall(tm, "$jnicall", nativecall);
+ Printf(module_class_code, " %s\n\n", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number,
+ "No javaout typemap defined for %s\n", SwigType_str(t,0));
+ }
+
+ Delete(shadowrettype);
+ Delete(nativecall);
+ Delete(user_arrays);
+ Delete(func_name);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * substituteJavaclassname()
+ *
+ * Substitute $javaclassname with either the shadow class name for classes/structs/unions that SWIG knows about.
+ * Otherwise use the $descriptor name for the Java class name. Note that the $&javaclassname substitution
+ * is the same as a $&descriptor substitution, ie one pointer added to descriptor name.
+ * Inputs:
+ * pt - parameter type
+ * tm - jstype typemap
+ * Outputs:
+ * tm - jstype typemap with $javaclassname substitution
+ * Return:
+ * is_java_class - flag indicating if a substitution was performed
+ * ----------------------------------------------------------------------------- */
+
+ bool substituteJavaclassname(SwigType *pt, String *tm) {
+ bool is_java_class = false;
+ if (Strstr(tm, "$javaclassname") || Strstr(tm,"$&javaclassname")) {
+ String *javaclassname = is_shadow(pt);
+ if (javaclassname) {
+ Replaceall(tm,"$&javaclassname", javaclassname); // is_shadow() works for pointers to classes too
+ Replaceall(tm,"$javaclassname", javaclassname);
+ }
+ else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
+ String *descriptor = NULL;
+ SwigType *type = Copy(SwigType_typedef_resolve_all(pt));
+
+ if (Strstr(tm, "$&javaclassname")) {
+ SwigType_add_pointer(type);
+ descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
+ Replaceall(tm, "$&javaclassname", descriptor);
+ }
+ else { // $javaclassname
+ descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
+ Replaceall(tm, "$javaclassname", descriptor);
+ }
+
+ // Add to hash table so that the SWIGTYPE Java classes can be created later
+ Setattr(swig_types_hash, descriptor, type);
+ Delete(descriptor);
+ Delete(type);
+ }
+ is_java_class = true;
+ }
+ return is_java_class;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * makeParameterName()
+ *
+ * Inputs:
+ * n - Node
+ * p - parameter node
+ * arg_num - parameter argument number
+ * Return:
+ * arg - a unique parameter name
+ * ----------------------------------------------------------------------------- */
+
+ String *makeParameterName(Node *n, Parm *p, int arg_num) {
+
+ // Use C parameter name unless it is a duplicate or an empty parameter name
+ String *pn = Getattr(p,"name");
+ int count = 0;
+ ParmList *plist = Getattr(n,"parms");
+ while (plist) {
+ if ((Cmp(pn, Getattr(plist,"name")) == 0))
+ count++;
+ plist = nextSibling(plist);
+ }
+ String *arg = (!pn || (count > 1)) ? NewStringf("arg%d",arg_num) : Copy(Getattr(p,"name"));
+
+ return arg;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitJavaClass()
+ * ----------------------------------------------------------------------------- */
+
+ void emitJavaClass(String *javaclassname, SwigType *type) {
+ String *filen = NewStringf("%s.java", javaclassname);
+ File *f_swigtype = NewFile(filen,"w");
+ String *swigtype = NewString("");
+
+ // Emit banner and package name
+ emitBanner(f_swigtype);
+ if(Len(package) > 0)
+ Printf(f_swigtype, "package %s;\n\n", package);
+
+ // Pure Java baseclass and interfaces
+ const String *pure_java_baseclass = javaTypemapLookup("javabase", type, WARN_NONE);
+ const String *pure_java_interfaces = javaTypemapLookup("javainterfaces", type, WARN_NONE);
+
+ // Emit the class
+ Printv(swigtype,
+ javaTypemapLookup("javaimports", type, WARN_NONE), // Import statements
+ "\n",
+ javaTypemapLookup("javaclassmodifiers", type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
+ " class $javaclassname", // Class name and bases
+ *Char(pure_java_baseclass) ?
+ " extends " :
+ "",
+ pure_java_baseclass,
+ *Char(pure_java_interfaces) ? // Pure Java interfaces
+ " implements " :
+ "",
+ pure_java_interfaces,
+ " {\n",
+ " private long swigCPtr;\n",
+ "\n",
+ " ",
+ javaTypemapLookup("javaptrconstructormodifiers", type, WARN_JAVA_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers
+ " $javaclassname(long cPtr, boolean bFutureUse) {\n", // Constructor used for wrapping pointers
+ " swigCPtr = cPtr;\n",
+ " }\n",
+ "\n",
+ " protected $javaclassname() {\n", // Default constructor
+ " swigCPtr = 0;\n",
+ " }\n",
+ javaTypemapLookup("javagetcptr", type, WARN_JAVA_TYPEMAP_GETCPTR_UNDEF), // getCPtr method
+ javaTypemapLookup("javacode", type, WARN_NONE), // extra Java code
+ "}\n",
+ "\n",
+ NIL);
+
+ Replaceall(swigtype, "$javaclassname", javaclassname);
+ Printv(f_swigtype, swigtype, NIL);
+
+ Close(f_swigtype);
+ Delete(filen);
+ Delete(swigtype);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * javaTypemapLookup()
+ * ----------------------------------------------------------------------------- */
+
+ const String *javaTypemapLookup(const String *op, String *type, int warning) {
+ String *tm = NULL;
+ const String *code = NULL;
+
+ if((tm = Swig_typemap_search(op, type, NULL, NULL))) {
+ code = Getattr(tm,"code");
+ }
+
+ if (!code) {
+ code = empty_string;
+ if (warning != WARN_NONE)
+ Swig_warning(warning, input_file, line_number, "No %s typemap defined for %s\n", op, type);
+ }
+
+ return code ? code : empty_string;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * addThrows()
+ * ----------------------------------------------------------------------------- */
+
+ void addThrows(Node *n, const String *typemap, Node *parameter) {
+ // Get the comma separated throws clause - held in "throws" attribute in the typemap passed in
+ String *throws_attribute = NewStringf("%s:throws", typemap);
+ String *throws = Getattr(parameter,throws_attribute);
+
+ if (throws) {
+ String *throws_list = Getattr(n,"java:throwslist");
+ if (!throws_list) {
+ throws_list = NewList();
+ Setattr(n,"java:throwslist", throws_list);
+ }
+
+ // Put the exception classes in the throws clause into a temporary List
+ List *temp_classes_list = Split(throws,',',INT_MAX);
+
+ // Add the exception classes to the node throws list, but don't duplicate if already in list
+ if (temp_classes_list && Len(temp_classes_list) > 0) {
+ for (String *cls = Firstitem(temp_classes_list); cls; cls = Nextitem(temp_classes_list)) {
+ String *javacls = NewString(cls);
+ Replaceall(javacls," ",""); // remove spaces
+ Replaceall(javacls,"\t",""); // remove tabs
+ if (Len(javacls) > 0) {
+ // $javaclassname substitution
+ SwigType *pt = Getattr(parameter,"type");
+ substituteJavaclassname(pt, javacls);
+
+ // Don't duplicate the Java class in the throws clause
+ bool found_flag = false;
+ for (String *item = Firstitem(throws_list); item; item = Nextitem(throws_list)) {
+ if (Strcmp(item, javacls) == 0)
+ found_flag = true;
+ }
+ if (!found_flag)
+ Append(throws_list, javacls);
+ }
+ Delete(javacls);
+ }
+ }
+ Delete(temp_classes_list);
+ }
+ Delete(throws_attribute);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * generateThrowsClause()
+ * ----------------------------------------------------------------------------- */
+
+ void generateThrowsClause(Node *n, String *code) {
+ // Add the throws clause into code
+ List *throws_list = Getattr(n,"java:throwslist");
+ if (throws_list) {
+ String *cls = Firstitem(throws_list);
+ Printf(code, " throws %s", cls);
+ while ( (cls = Nextitem(throws_list)) )
+ Printf(code, ", %s", cls);
+ }
+ }
+
+}; /* class JAVA */
+
+/* -----------------------------------------------------------------------------
+ * swig_java() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+extern "C" Language *
+swig_java(void) {
+ return new JAVA();
+}
+
+/* -----------------------------------------------------------------------------
+ * Static member variables
+ * ----------------------------------------------------------------------------- */
+
+const char *JAVA::usage = (char*)"\
+Java Options (available with -java)\n\
+ -package - set name of the Java package\n\
+ -noproxy - Generate the low-level functional interface instead of proxy classes\n";
+
+
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx
new file mode 100644
index 000000000..4245b7193
--- /dev/null
+++ b/Source/Modules/lang.cxx
@@ -0,0 +1,1853 @@
+/* -----------------------------------------------------------------------------
+ * lang.cxx
+ *
+ * Language base class functions. Default C++ handling is also implemented here.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1998-2000. The University of Chicago
+ * Copyright (C) 1995-1998. The University of Utah and The Regents of the
+ * University of California.
+ *
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_lang_cxx[] = "$Header$";
+
+#include "swigmod.h"
+#include
+
+/* Some status variables used during parsing */
+
+static int InClass = 0; /* Parsing C++ or not */
+static String *ClassName = 0; /* This is the real name of the current class */
+static String *ClassPrefix = 0; /* Class prefix */
+static String *ClassType = 0; /* Fully qualified type name to use */
+int Abstract = 0;
+int ImportMode = 0;
+int IsVirtual = 0;
+static String *AttributeFunctionGet = 0;
+static String *AttributeFunctionSet = 0;
+static int cplus_mode = 0;
+static Node *CurrentClass = 0;
+int line_number = 0;
+char *input_file = 0;
+int SmartPointer = 0;
+
+extern int GenerateDefault;
+extern int ForceExtern;
+extern int NoExtern;
+
+/* import modes */
+
+#define IMPORT_MODE 1
+#define IMPORT_MODULE 2
+
+/* C++ access modes */
+
+#define CPLUS_PUBLIC 0
+#define CPLUS_PROTECTED 1
+#define CPLUS_PRIVATE 2
+
+/* ----------------------------------------------------------------------
+ * Dispatcher::emit_one()
+ *
+ * Dispatch a single node
+ * ---------------------------------------------------------------------- */
+
+int Dispatcher::emit_one(Node *n) {
+ String *wrn;
+ int ret = SWIG_OK;
+
+ char *tag = Char(nodeType(n));
+ if (!tag) {
+ Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree node!\n");
+ return SWIG_ERROR;
+ }
+
+ /* Do not proceed if marked with an error */
+
+ if (Getattr(n,"error")) return SWIG_OK;
+
+ /* Look for warnings */
+ wrn = Getattr(n,"feature:warnfilter");
+ if (wrn) {
+ Swig_warnfilter(wrn,1);
+ }
+
+ /* ============================================================
+ * C/C++ parsing
+ * ============================================================ */
+
+ if (strcmp(tag,"extern") == 0) {
+ ret = externDeclaration(n);
+ } else if (strcmp(tag,"cdecl") == 0) {
+ ret = cDeclaration(n);
+ } else if (strcmp(tag,"enum") == 0) {
+ ret = enumDeclaration(n);
+ } else if (strcmp(tag,"enumitem") == 0) {
+ ret = enumvalueDeclaration(n);
+ } else if (strcmp(tag,"class") == 0) {
+ ret = classDeclaration(n);
+ } else if (strcmp(tag,"classforward") == 0) {
+ ret = classforwardDeclaration(n);
+ } else if (strcmp(tag,"constructor") == 0) {
+ ret = constructorDeclaration(n);
+ } else if (strcmp(tag,"destructor") == 0) {
+ ret = destructorDeclaration(n);
+ } else if (strcmp(tag,"access") == 0) {
+ ret = accessDeclaration(n);
+ } else if (strcmp(tag,"using") == 0) {
+ ret = usingDeclaration(n);
+ } else if (strcmp(tag,"namespace") == 0) {
+ ret = namespaceDeclaration(n);
+ } else if (strcmp(tag,"template") == 0) {
+ ret = templateDeclaration(n);
+ }
+
+ /* ===============================================================
+ * SWIG directives
+ * =============================================================== */
+
+ else if (strcmp(tag,"top") == 0) {
+ ret = top(n);
+ } else if (strcmp(tag,"extend") == 0) {
+ ret = extendDirective(n);
+ } else if (strcmp(tag,"apply") == 0) {
+ ret = applyDirective(n);
+ } else if (strcmp(tag,"clear") == 0) {
+ ret = clearDirective(n);
+ } else if (strcmp(tag,"constant") == 0) {
+ ret = constantDirective(n);
+ } else if (strcmp(tag,"fragment") == 0) {
+ ret = fragmentDirective(n);
+ } else if (strcmp(tag,"import") == 0) {
+ ret = importDirective(n);
+ } else if (strcmp(tag,"include") == 0) {
+ ret = includeDirective(n);
+ } else if (strcmp(tag,"insert") == 0) {
+ ret = insertDirective(n);
+ } else if (strcmp(tag,"module") == 0) {
+ ret = moduleDirective(n);
+ } else if (strcmp(tag,"native") == 0) {
+ ret = nativeDirective(n);
+ } else if (strcmp(tag,"pragma") == 0) {
+ ret = pragmaDirective(n);
+ } else if (strcmp(tag,"typemap") == 0) {
+ ret = typemapDirective(n);
+ } else if (strcmp(tag,"typemapcopy") == 0) {
+ ret = typemapcopyDirective(n);
+ } else if (strcmp(tag,"typemapitem") == 0) {
+ ret = typemapitemDirective(n);
+ } else if (strcmp(tag,"types") == 0) {
+ ret = typesDirective(n);
+ } else {
+ Printf(stderr,"%s:%d. Unrecognized parse tree node type '%s'\n", input_file, line_number, tag);
+ ret = SWIG_ERROR;
+ }
+ if (wrn) {
+ Swig_warnfilter(wrn,0);
+ }
+ return ret;
+}
+
+/* ----------------------------------------------------------------------
+ * Dispatcher::emit_children()
+ *
+ * Emit all children.
+ * ---------------------------------------------------------------------- */
+
+int Dispatcher::emit_children(Node *n) {
+ Node *c;
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ emit_one(c);
+ }
+ return SWIG_OK;
+}
+
+/* Stubs for dispatcher class. We don't do anything by default---up to derived class
+ to fill in traversal code */
+
+int Dispatcher::defaultHandler(Node *) { return SWIG_OK; }
+int Dispatcher::extendDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::applyDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::clearDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::constantDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::fragmentDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::importDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::includeDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::insertDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::moduleDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::nativeDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::pragmaDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::typemapDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::typemapitemDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::typemapcopyDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::typesDirective(Node *n) { return defaultHandler(n); }
+int Dispatcher::cDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::externDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::enumDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::enumvalueDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::classDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::templateDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::classforwardDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::constructorDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::destructorDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::accessDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::usingDeclaration(Node *n) { return defaultHandler(n); }
+int Dispatcher::namespaceDeclaration(Node *n) { return defaultHandler(n); }
+
+/* Allocators */
+Language::Language() {
+ symbols = NewHash();
+ classtypes = NewHash();
+ overloading = 0;
+ multiinput = 0;
+}
+
+Language::~Language() {
+ Delete(symbols);
+ Delete(classtypes);
+}
+
+/* ----------------------------------------------------------------------
+ emit_one()
+ ---------------------------------------------------------------------- */
+
+int Language::emit_one(Node *n) {
+ int ret;
+ int oldext;
+ if (!n) return SWIG_OK;
+
+ if (Getattr(n,"feature:ignore")) return SWIG_OK;
+
+ oldext = Extend;
+ if (Getattr(n,"feature:extend")) Extend = 1;
+
+ line_number = Getline(n);
+ input_file = Char(Getfile(n));
+
+ /*
+ symtab = Getattr(n,"symtab");
+ if (symtab) {
+ symtab = Swig_symbol_setscope(symtab);
+ }
+ */
+ ret = Dispatcher::emit_one(n);
+ /*
+ if (symtab) {
+ Swig_symbol_setscope(symtab);
+ }
+ */
+ Extend = oldext;
+ return ret;
+}
+
+
+static Parm *nonvoid_parms(Parm *p) {
+ if (p) {
+ SwigType *t = Getattr(p,"type");
+ if (SwigType_type(t) == T_VOID) return 0;
+ }
+ return p;
+}
+
+/* This is a hack */
+SwigType *cplus_value_type(SwigType *t) {
+ Node *n;
+ if (!CPlusPlus) return 0;
+ if (SwigType_isclass(t)) {
+ SwigType *td = SwigType_typedef_resolve_all(t);
+ if ((n = Swig_symbol_clookup(td,0))) {
+ if ((Strcmp(nodeType(n),"class") == 0) && (!Getattr(n,"allocate:default_constructor") || (Getattr(n,"allocate:noassign")))) {
+ String *s = NewStringf("SwigValueWrapper< %s >",t);
+ Delete(td);
+ return s;
+ }
+ }
+ if (SwigType_issimple(td) && SwigType_istemplate(td)) {
+ String *s = NewStringf("SwigValueWrapper< %s >",t);
+ Delete(td);
+ return s;
+ }
+ Delete(td);
+ }
+ return 0;
+}
+
+/* Patch C++ pass-by-value */
+void Language::patch_parms(Parm *p) {
+ while (p) {
+ SwigType *t = Getattr(p,"type");
+ SwigType *s = cplus_value_type(t);
+ if (s) {
+ Setattr(p,"alttype",s);
+ Delete(s);
+ }
+ p = nextSibling(p);
+ }
+}
+
+static Node *first_nontemplate(Node *n) {
+ while (n) {
+ if (Strcmp(nodeType(n),"template") != 0) return n;
+ n = Getattr(n,"sym:nextSibling");
+ }
+ return n;
+}
+
+/* --------------------------------------------------------------------------
+ * swig_pragma()
+ *
+ * Handle swig pragma directives.
+ * -------------------------------------------------------------------------- */
+
+void swig_pragma(char *lang, char *name, char *value) {
+ if (strcmp(lang,"swig") == 0) {
+ if ((strcmp(name,"make_default") == 0) || ((strcmp(name,"makedefault") == 0))) {
+ GenerateDefault = 1;
+ } else if ((strcmp(name,"no_default") == 0) || ((strcmp(name,"nodefault") == 0))) {
+ GenerateDefault = 0;
+ } else if (strcmp(name,"attributefunction") == 0) {
+ String *nvalue = NewString(value);
+ char *s = strchr(Char(nvalue),':');
+ if (!s) {
+ Swig_error(input_file, line_number, "Bad value for attributefunction. Expected \"fmtget:fmtset\".\n");
+ } else {
+ *s = 0;
+ AttributeFunctionGet = NewString(Char(nvalue));
+ AttributeFunctionSet = NewString(s+1);
+ }
+ Delete(nvalue);
+ } else if (strcmp(name,"noattributefunction") == 0) {
+ AttributeFunctionGet = 0;
+ AttributeFunctionSet = 0;
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ * Language::top() - Top of parsing tree
+ * ---------------------------------------------------------------------- */
+
+int Language::top(Node *n) {
+ return emit_children(n);
+}
+
+/* ----------------------------------------------------------------------
+ * Language::extendDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::extendDirective(Node *n) {
+ int oldam = Extend;
+ int oldmode = cplus_mode;
+ Extend = CWRAP_EXTEND;
+ cplus_mode = CPLUS_PUBLIC;
+
+ emit_children(n);
+
+ Extend = oldam;
+ cplus_mode = oldmode;
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::applyDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::applyDirective(Node *n) {
+
+ Parm *pattern = Getattr(n,"pattern");
+ Node *c = firstChild(n);
+ while (c) {
+ Parm *apattern = Getattr(c,"pattern");
+ if (ParmList_len(pattern) != ParmList_len(apattern)) {
+ Swig_error(input_file, line_number, "Can't apply (%s) to (%s). Number of arguments don't match.\n",
+ ParmList_str(pattern), ParmList_str(apattern));
+ } else {
+ if (!Swig_typemap_apply(pattern,apattern)) {
+ Swig_warning(WARN_TYPEMAP_APPLY_UNDEF,input_file,line_number,"Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern));
+ }
+ }
+ c = nextSibling(c);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::clearDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::clearDirective(Node *n) {
+ Node *p;
+ for (p = firstChild(n); p; p = nextSibling(p)) {
+ ParmList *pattern = Getattr(p,"pattern");
+ Swig_typemap_clear_apply(pattern);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::constantDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::constantDirective(Node *n) {
+
+ if (CurrentClass && (cplus_mode != CPLUS_PUBLIC)) return SWIG_NOWRAP;
+
+ if (!ImportMode) {
+ Swig_require(&n,"name", "?value",NIL);
+ String *name = Getattr(n,"name");
+ String *value = Getattr(n,"value");
+ if (!value) {
+ value = Copy(name);
+ } else {
+ value = NewStringf("%(escape)s", value);
+ }
+ Setattr(n,"value", value);
+ this->constantWrapper(n);
+ Swig_restore(&n);
+ return SWIG_OK;
+ }
+ return SWIG_NOWRAP;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::fragmentDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::fragmentDirective(Node *n) {
+ String *name = Getattr(n,"name");
+ String *code = Getattr(n,"code");
+ String *section = Getattr(n,"section");
+ Swig_fragment_register(name,section,code);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::importDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::importDirective(Node *n) {
+ int oldim = ImportMode;
+ ImportMode = IMPORT_MODE;
+ emit_children(n);
+ ImportMode = oldim;
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::includeDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::includeDirective(Node *n) {
+ emit_children(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::insertDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::insertDirective(Node *n) {
+ /* %insert directive */
+ if ((!ImportMode) || Getattr(n,"generated")) {
+ String *code = Getattr(n,"code");
+ String *section = Getattr(n,"section");
+ File *f = 0;
+ if (!section) { /* %{ ... %} */
+ f = Swig_filebyname("header");
+ } else {
+ f = Swig_filebyname(section);
+ }
+ if (f) {
+ Printf(f,"%s\n",code);
+ } else {
+ Swig_error(input_file,line_number,"Unknown target '%s' for %%insert directive.\n", section);
+ }
+ return SWIG_OK;
+ } else {
+ return SWIG_NOWRAP;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ * Language::moduleDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::moduleDirective(Node *n) {
+ /* %module directive */
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::nativeDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::nativeDirective(Node *n) {
+ if (!ImportMode) {
+ return nativeWrapper(n);
+ } else {
+ return SWIG_NOWRAP;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ * Language::pragmaDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::pragmaDirective(Node *n) {
+ /* %pragma directive */
+ if (!ImportMode) {
+ String *lan = Getattr(n,"lang");
+ String *name = Getattr(n,"name");
+ String *value = Getattr(n,"value");
+ swig_pragma(Char(lan),Char(name),Char(value));
+ /* pragma(Char(lan),Char(name),Char(value)); */
+ return SWIG_OK;
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::typemapDirective()
+ * ---------------------------------------------------------------------- */
+
+extern "C" void Swig_cparse_replace_descriptor(String *s);
+
+int Language::typemapDirective(Node *n) {
+ /* %typemap directive */
+ String *method = Getattr(n,"method");
+ String *code = Getattr(n,"code");
+ Parm *kwargs = Getattr(n,"kwargs");
+ Node *items = firstChild(n);
+ static int namewarn = 0;
+
+
+ if (code && (Strstr(code,"$source") || (Strstr(code,"$target")))) {
+ Swig_warning(WARN_TYPEMAP_SOURCETARGET,Getfile(n),Getline(n),"Deprecated typemap feature ($source/$target).\n");
+ if (!namewarn) {
+ Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n),
+ "The use of $source and $target in a typemap declaration is deprecated.\n\
+For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\
+$source by $input and $target by $1. For typemaps related to return values (out,\n\
+argout,ret,except), replace $source by $1 and $target by $result. See the file\n\
+Doc/Manual/Typemaps.html for complete details.\n");
+ namewarn = 1;
+ }
+ }
+
+ /*
+ if (Strcmp(method,"except") == 0) {
+ Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n),
+ "%%typemap(except) is deprecated. Use the %%exception directive.\n");
+ }
+ */
+
+ if (Strcmp(method,"in") == 0) {
+ Hash *k;
+ k = kwargs;
+ while (k) {
+ if (checkAttribute(k,"name","numinputs")) {
+ if (!multiinput && (GetInt(k,"value") > 1)) {
+ Swig_error(Getfile(n),Getline(n),"Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n");
+ return SWIG_ERROR;
+ }
+ break;
+ }
+ k = nextSibling(k);
+ }
+ if (!k) {
+ k = NewHash();
+ Setattr(k,"name","numinputs");
+ Setattr(k,"value","1");
+ set_nextSibling(k,kwargs);
+ Setattr(n,"kwargs",k);
+ kwargs = k;
+ }
+ }
+
+ if (Strcmp(method,"ignore") == 0) {
+ Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n),
+ "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n");
+
+ Clear(method);
+ Append(method,"in");
+ Hash *k = NewHash();
+ Setattr(k,"name","numinputs");
+ Setattr(k,"value","0");
+ set_nextSibling(k,kwargs);
+ Setattr(n,"kwargs",k);
+ kwargs = k;
+ }
+
+ /* Replace $descriptor() macros */
+
+ if (code) {
+ Setfile(code,Getfile(n));
+ Setline(code,Getline(n));
+ Swig_cparse_replace_descriptor(code);
+ }
+
+ while (items) {
+ Parm *pattern = Getattr(items,"pattern");
+ Parm *parms = Getattr(items,"parms");
+ if (code) {
+ Swig_typemap_register(method,pattern,code,parms,kwargs);
+ } else {
+ Swig_typemap_clear(method,pattern);
+ }
+ items = nextSibling(items);
+ }
+ return SWIG_OK;
+
+}
+
+/* ----------------------------------------------------------------------
+ * Language::typemapcopyDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::typemapcopyDirective(Node *n) {
+ String *method = Getattr(n,"method");
+ Parm *pattern = Getattr(n,"pattern");
+ Node *items = firstChild(n);
+ int nsrc = 0;
+ nsrc = ParmList_len(pattern);
+ while (items) {
+ ParmList *npattern = Getattr(items,"pattern");
+ if (nsrc != ParmList_len(npattern)) {
+ Swig_error(input_file,line_number,"Can't copy typemap. Number of types differ.\n");
+ } else {
+ if (Swig_typemap_copy(method,pattern,npattern) < 0) {
+ Swig_error(input_file, line_number, "Can't copy typemap.\n");
+ }
+ }
+ items = nextSibling(items);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::typesDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::typesDirective(Node *n) {
+ Parm *parms = Getattr(n,"parms");
+ while (parms) {
+ SwigType *t = Getattr(parms,"type");
+ String *v = Getattr(parms,"value");
+ if (!v) {
+ SwigType_remember(t);
+ } else {
+ if (SwigType_issimple(t)) {
+ SwigType_inherit(t,v,0);
+ }
+ }
+ parms = nextSibling(parms);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::cDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::cDeclaration(Node *n) {
+
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ SwigType *decl = Getattr(n,"decl");
+ String *storage = Getattr(n,"storage");
+ Node *over;
+ File *f_header = 0;
+ SwigType *ty, *fullty;
+
+ if (CurrentClass && (cplus_mode != CPLUS_PUBLIC)) return SWIG_NOWRAP;
+
+ if (Cmp(storage,"typedef") == 0) {
+ Swig_save(&n,"type",NIL);
+ SwigType *t = Copy(type);
+ if (t) {
+ SwigType_push(t,decl);
+ Setattr(n,"type",t);
+ typedefHandler(n);
+ }
+ Swig_restore(&n);
+ return SWIG_OK;
+ } else if (Cmp(storage,"friend") == 0) {
+ Swig_warning(WARN_LANG_FRIEND_IGNORE, Getfile(n), Getline(n),
+ "friend function '%s' ignored.\n", name);
+ return SWIG_NOWRAP;
+ }
+
+ /* If in import mode, we proceed no further */
+ if (ImportMode) return SWIG_NOWRAP;
+
+ /* Overloaded symbol check */
+ over = Swig_symbol_isoverloaded(n);
+ if (!overloading) {
+ if (over) over = first_nontemplate(over);
+ if (over && (over != n)) {
+ SwigType *tc = Copy(decl);
+ SwigType *td = SwigType_pop_function(tc);
+ String *oname;
+ String *cname;
+ if (CurrentClass) {
+ oname = NewStringf("%s::%s",ClassName,name);
+ cname = NewStringf("%s::%s",ClassName,Getattr(over,"name"));
+ } else {
+ oname = NewString(name);
+ cname = NewString(Getattr(over,"name"));
+ }
+
+ SwigType *tc2 = Copy(Getattr(over,"decl"));
+ SwigType *td2 = SwigType_pop_function(tc2);
+
+ Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", SwigType_str(td,SwigType_namestr(oname)));
+ Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over),"Previous declaration is %s\n", SwigType_str(td2,SwigType_namestr(cname)));
+
+ Delete(tc2);
+ Delete(td2);
+ Delete(tc);
+ Delete(td);
+ Delete(oname);
+ Delete(cname);
+ return SWIG_NOWRAP;
+ }
+ }
+
+ if (symname && !validIdentifier(symname)) {
+ Swig_warning(WARN_LANG_IDENTIFIER,input_file, line_number, "Can't wrap '%s' unless renamed to a valid identifier.\n",
+ symname);
+ return SWIG_NOWRAP;
+ }
+
+ ty = NewString(type);
+ SwigType_push(ty,decl);
+ fullty = SwigType_typedef_resolve_all(ty);
+ if (SwigType_isfunction(fullty)) {
+ if (!SwigType_isfunction(ty)) {
+ Delete(ty);
+ ty = fullty;
+ fullty = 0;
+ ParmList *parms = SwigType_function_parms(ty);
+ Setattr(n,"parms",parms);
+ }
+ /* Transform the node into a 'function' node and emit */
+ if (!CurrentClass) {
+ f_header = Swig_filebyname("header");
+
+ if (!NoExtern) {
+ if (f_header) {
+ if ((Cmp(storage,"extern") == 0) || (ForceExtern && !storage)) {
+ Printf(f_header,"extern %s;\n", SwigType_str(ty,name));
+ } else if (Cmp(storage,"externc") == 0) {
+ Printf(f_header,"extern \"C\" %s;\n", SwigType_str(ty,name));
+ }
+ }
+ }
+ }
+ /* This needs to check qualifiers */
+ if (SwigType_isqualifier(ty)) {
+ Setattr(n,"qualifier", SwigType_pop(ty));
+ }
+ Delete(SwigType_pop_function(ty));
+ DohIncref(type);
+ Setattr(n,"type",ty);
+ functionHandler(n);
+ Setattr(n,"type",type);
+ Delete(ty);
+ Delete(type);
+ return SWIG_OK;
+ } else {
+ /* Some kind of variable declaration */
+ Delattr(n,"decl");
+ if (Getattr(n,"nested")) Setattr(n,"feature:immutable","1");
+ if (!CurrentClass) {
+ if ((Cmp(storage,"extern") == 0) || ForceExtern) {
+ f_header = Swig_filebyname("header");
+ if (!NoExtern) {
+ if (f_header) {
+ Printf(f_header,"extern %s;\n", SwigType_str(ty,name));
+ }
+ }
+ }
+ }
+ if (!SwigType_ismutable(ty)) {
+ Setattr(n,"feature:immutable","1");
+ }
+ /* If an array and elements are const, then read-only */
+ if (SwigType_isarray(ty)) {
+ SwigType *tya = SwigType_array_type(ty);
+ if (SwigType_isconst(tya)) {
+ Setattr(n,"feature:immutable","1");
+ }
+ }
+ DohIncref(type);
+ Setattr(n,"type",ty);
+ variableHandler(n);
+ Setattr(n,"type",type);
+ Setattr(n,"decl",decl);
+ Delete(ty);
+ Delete(type);
+ Delete(fullty);
+ return SWIG_OK;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ * Language::functionHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::functionHandler(Node *n) {
+ Parm *p;
+ p = Getattr(n,"parms");
+ if (CPlusPlus) patch_parms(p);
+ if (!CurrentClass) {
+ globalfunctionHandler(n);
+ } else {
+ String *storage = Getattr(n,"storage");
+ if (Cmp(storage,"static") == 0) {
+ staticmemberfunctionHandler(n);
+ } else {
+ memberfunctionHandler(n);
+ }
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::globalfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::globalfunctionHandler(Node *n) {
+
+ Swig_require(&n,"name","sym:name","type","?parms",NIL);
+
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ String *storage = Getattr(n,"storage");
+ ParmList *parms = Getattr(n,"parms");
+
+ if (0 && (Cmp(storage,"static") == 0)) {
+ Swig_restore(&n);
+ return SWIG_NOWRAP; /* Can't wrap static functions */
+ } else {
+ /* Check for callback mode */
+ String *cb = Getattr(n,"feature:callback");
+ if (cb) {
+ String *cbname = NewStringf(cb,symname);
+ callbackfunctionHandler(n);
+ if (Cmp(cbname, symname) == 0) {
+ Delete(cbname);
+ Swig_restore(&n);
+ return SWIG_NOWRAP;
+ }
+ Delete(cbname);
+ }
+ Setattr(n,"parms",nonvoid_parms(parms));
+ Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(name,parms)));
+ functionWrapper(n);
+ }
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::callbackfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::callbackfunctionHandler(Node *n) {
+ Swig_require(&n,"name","*sym:name","*type","?value",NIL);
+ String *symname = Getattr(n,"sym:name");
+ String *type = Getattr(n,"type");
+ String *name = Getattr(n,"name");
+ String *parms = Getattr(n,"parms");
+ String *cb = Getattr(n,"feature:callback");
+ String *cbname = NewStringf(cb,symname);
+ SwigType *cbty = Copy(type);
+ SwigType_add_function(cbty,parms);
+ SwigType_add_pointer(cbty);
+
+ Setattr(n,"sym:name", cbname);
+ Setattr(n,"type", cbty);
+ Setattr(n,"value", name);
+
+ constantWrapper(n);
+ Delete(cbname);
+ Delete(cbty);
+
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::memberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::memberfunctionHandler(Node *n) {
+
+ Swig_require(&n,"*name","*sym:name","*type","?parms","?value",NIL);
+
+ String *storage = Getattr(n,"storage");
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ String *value = Getattr(n,"value");
+ ParmList *parms = Getattr(n,"parms");
+ String *cb;
+
+ if (Cmp(storage,"virtual") == 0) {
+ if (Cmp(value,"0") == 0) {
+ IsVirtual = PURE_VIRTUAL;
+ } else {
+ IsVirtual = PLAIN_VIRTUAL;
+ }
+ } else {
+ IsVirtual = 0;
+ }
+ cb = Getattr(n,"feature:callback");
+ if (cb) {
+ Node *cb = NewHash();
+ String *cbname = NewStringf(cb,symname);
+ String *cbvalue;
+ SwigType *cbty = Copy(type);
+ SwigType_add_function(cbty,parms);
+ SwigType_add_memberpointer(cbty,ClassName);
+ cbvalue = NewStringf("&%s::%s",ClassName,name);
+ Setattr(cb,"sym:name", cbname);
+ Setattr(cb,"type", cbty);
+ Setattr(cb,"value", cbvalue);
+ Setattr(cb,"name", name);
+
+ memberconstantHandler(n);
+
+ Delete(cb);
+ Delete(cbvalue);
+ Delete(cbty);
+ Delete(cbname);
+ if (Cmp(cbname,symname) == 0) {
+ Swig_restore(&n);
+ return SWIG_NOWRAP;
+ }
+ }
+
+ String *fname = Swig_name_member(ClassPrefix, symname);
+ /* Transformation */
+ Swig_MethodToFunction(n,ClassType, Getattr(n,"template") ? 0 : Extend | SmartPointer);
+ Setattr(n,"sym:name",fname);
+ functionWrapper(n);
+
+ /* DelWrapper(w);*/
+ Delete(fname);
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::staticmemberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::staticmemberfunctionHandler(Node *n) {
+
+ Swig_require(&n,"*name","*sym:name","*type",NIL);
+ Swig_save(&n,"storage",NIL);
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ ParmList *parms = Getattr(n,"parms");
+ String *code = Getattr(n,"code");
+ String *cname, *mrename;
+
+ if (!Extend) {
+ cname = NewStringf("%s::%s",ClassName,name);
+ } else {
+ cname = Copy(Swig_name_member(ClassPrefix,name));
+ }
+ mrename = Swig_name_member(ClassPrefix, symname);
+
+ Setattr(n,"name",cname);
+ Setattr(n,"sym:name",mrename);
+
+ if ((Extend) && (code)) {
+ /* Hmmm. An added static member. We have to create a little wrapper for this */
+ String *tmp = NewStringf("%s(%s)", cname, ParmList_str(parms));
+ String *wrap = SwigType_str(type,tmp);
+ Printv(wrap,code,"\n",NIL);
+ Setattr(n,"wrap:code",wrap);
+ Delete(tmp);
+ Delete(wrap);
+ }
+ Delattr(n,"storage");
+ globalfunctionHandler(n);
+
+ Delete(cname);
+ Delete(mrename);
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::variableHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::variableHandler(Node *n) {
+ if (!CurrentClass) {
+ globalvariableHandler(n);
+ } else {
+ String *storage = Getattr(n,"storage");
+ if ((Cmp(storage,"static") == 0)) {
+ if (!SmartPointer) {
+ staticmembervariableHandler(n);
+ }
+ } else {
+ membervariableHandler(n);
+ }
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::globalvariableHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::globalvariableHandler(Node *n) {
+ String *storage = Getattr(n,"storage");
+ if (0 && (Cmp(storage,"static") == 0)) return SWIG_NOWRAP;
+ variableWrapper(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::membervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::membervariableHandler(Node *n) {
+
+ Swig_require(&n,"*name","*sym:name","*type",NIL);
+ Swig_save(&n,"parms",NIL);
+
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+
+ /* If not a smart-pointer access or added method. We clear
+ feature:except. There is no way C++ or C would throw
+ an exception merely for accessing a member data
+ */
+
+ if (!(Extend | SmartPointer)) {
+ Delattr(n,"feature:except");
+ }
+
+ if (!AttributeFunctionGet) {
+
+ String *mrename_get, *mrename_set;
+
+ mrename_get = Swig_name_get(Swig_name_member(ClassPrefix, symname));
+ mrename_set = Swig_name_set(Swig_name_member(ClassPrefix, symname));
+
+ /* Create a function to set the value of the variable */
+
+ if (!Getattr(n,"feature:immutable")) {
+ int make_wrapper = 1;
+ String *tm = 0;
+ String *target = 0;
+ if (!Extend) {
+ target = NewStringf("%s->%s", Swig_cparm_name(0,0),name);
+ tm = Swig_typemap_lookup_new("memberin",n,target,0);
+ }
+ Swig_MembersetToFunction(n,ClassType,Extend | SmartPointer);
+ if (!Extend) {
+ /* Check for a member in typemap here */
+
+ /* String *tm = Swig_typemap_lookup((char *) "memberin",type,name,target,Swig_cparm_name(0,1),target,0);*/
+ if (!tm) {
+ if (SwigType_isarray(type)) {
+ /* Printf(stderr,"%s:%d. Warning. Array member %s will be read-only.\n", input_file, line_number, name);*/
+ make_wrapper = 0;
+ }
+ } else {
+ Replace(tm,"$source", Swig_cparm_name(0,1), DOH_REPLACE_ANY);
+ Replace(tm,"$target", target, DOH_REPLACE_ANY);
+ Replace(tm,"$input",Swig_cparm_name(0,1),DOH_REPLACE_ANY);
+ Replace(tm,"$self",Swig_cparm_name(0,0),DOH_REPLACE_ANY);
+ Setattr(n,"wrap:action", tm);
+ Delete(tm);
+ }
+ Delete(target);
+ }
+ if (make_wrapper) {
+ Setattr(n,"sym:name", mrename_set);
+ functionWrapper(n);
+ } else {
+ Setattr(n,"feature:immutable","1");
+ }
+ /* Restore parameters */
+ Setattr(n,"type",type);
+ Setattr(n,"name",name);
+ Setattr(n,"sym:name",symname);
+ }
+ /* Emit get function */
+ {
+ Swig_MembergetToFunction(n,ClassType,Extend | SmartPointer);
+ Setattr(n,"sym:name", mrename_get);
+ functionWrapper(n);
+ }
+ Delete(mrename_get);
+ Delete(mrename_set);
+
+ } else {
+
+ /* This code is used to support the attributefunction directive
+ where member variables are converted automagically to
+ accessor functions */
+
+#if 0
+ Parm *p;
+ String *gname;
+ SwigType *vty;
+ p = NewParm(type,0);
+ gname = NewStringf(AttributeFunctionGet,symname);
+ if (!Extend) {
+ ActionFunc = Copy(Swig_cmemberget_call(name,type));
+ cpp_member_func(Char(gname),Char(gname),type,0);
+ Delete(ActionFunc);
+ } else {
+ String *cname = Copy(Swig_name_get(name));
+ cpp_member_func(Char(cname),Char(gname),type,0);
+ Delete(cname);
+ }
+ Delete(gname);
+ if (!Getattr(n,"feature:immutable")) {
+ gname = NewStringf(AttributeFunctionSet,symname);
+ vty = NewString("void");
+ if (!Extend) {
+ ActionFunc = Copy(Swig_cmemberset_call(name,type));
+ cpp_member_func(Char(gname),Char(gname),vty,p);
+ Delete(ActionFunc);
+ } else {
+ String *cname = Copy(Swig_name_set(name));
+ cpp_member_func(Char(cname),Char(gname),vty,p);
+ Delete(cname);
+ }
+ Delete(gname);
+ }
+ ActionFunc = 0;
+#endif
+ }
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::staticmembervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::staticmembervariableHandler(Node *n)
+{
+ Swig_require(&n,"*name","*sym:name","*type", "?value", NIL);
+ String *value = Getattr(n,"value");
+ if (!value) {
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+ String *cname, *mrename;
+
+ /* Create the variable name */
+ mrename = Swig_name_member(ClassPrefix, symname);
+ cname = NewStringf("%s::%s", ClassName,name);
+
+ Setattr(n,"sym:name",mrename);
+ Setattr(n,"name", cname);
+
+ /* Wrap as an ordinary global variable */
+ variableWrapper(n);
+
+ Delete(mrename);
+ Delete(cname);
+ } else {
+ String *name = Getattr(n,"name");
+ String *cname = NewStringf("%s::%s", ClassName,name);
+ String* value = SwigType_namestr(cname);
+ Setattr(n, "value", value);
+
+ SwigType *t1 = SwigType_typedef_resolve_all(Getattr(n,"type"));
+ SwigType *t2 = SwigType_strip_qualifiers(t1);
+ Setattr(n, "type", t2);
+ Delete(t1);
+ Delete(t2);
+
+ memberconstantHandler(n);
+ Delete(cname);
+ }
+
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+
+/* ----------------------------------------------------------------------
+ * Language::externDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::externDeclaration(Node *n) {
+ return emit_children(n);
+}
+
+/* ----------------------------------------------------------------------
+ * Language::enumDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::enumDeclaration(Node *n) {
+ if (!ImportMode) {
+ emit_children(n);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::enumvalueDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::enumvalueDeclaration(Node *n) {
+ if (CurrentClass && (cplus_mode != CPLUS_PUBLIC)) return SWIG_NOWRAP;
+
+ Swig_require(&n,"*name", "?value",NIL);
+ String *value = Getattr(n,"value");
+ String *name = Getattr(n,"name");
+ String *tmpValue;
+
+ if (value)
+ tmpValue = NewString(value);
+ else
+ tmpValue = NewString(name);
+ Setattr(n, "value", tmpValue);
+
+ if (!CurrentClass) {
+ Setattr(n,"name",tmpValue); /* for wrapping of enums in a namespace when emit_action is used */
+ constantWrapper(n);
+ } else {
+ memberconstantHandler(n);
+ }
+
+ Delete(tmpValue);
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::memberconstantHandler()
+ * ----------------------------------------------------------------------------- */
+
+int Language::memberconstantHandler(Node *n) {
+
+ Swig_require(&n,"*name","*sym:name","*value",NIL);
+
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+ String *value = Getattr(n,"value");
+
+ String *mrename;
+ String *new_value;
+
+ mrename = Swig_name_member(ClassPrefix, symname);
+ /* Fixed by namespace-enum patch
+ if ((!value) || (Cmp(value,name) == 0)) {
+ new_value = NewStringf("%s::%s",ClassName,name);
+ } else {
+ new_value = NewString(value);
+ }
+ */
+ new_value = Copy(value);
+ Setattr(n,"sym:name", mrename);
+ Setattr(n,"value", new_value);
+ Setattr(n,"name", NewStringf("%s::%s", ClassName,name));
+ constantWrapper(n);
+ Delete(mrename);
+ Delete(new_value);
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::typedefHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::typedefHandler(Node *) {
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDeclaration(Node *n) {
+ String *kind = Getattr(n,"kind");
+ String *name = Getattr(n,"name");
+ String *tdname = Getattr(n,"tdname");
+ String *symname = Getattr(n,"sym:name");
+
+ char *classname = tdname ? Char(tdname) : Char(name);
+ char *iname = Char(symname);
+ int strip = (tdname || CPlusPlus) ? 1 : 0;
+
+
+ if (!classname) {
+ Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n");
+ return SWIG_NOWRAP;
+ }
+
+ /* Check symbol name for template. If not renamed. Issue a warning */
+ /* Printf(stdout,"sym:name = %s\n", symname); */
+
+ if (!validIdentifier(symname)) {
+ Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n",
+ SwigType_namestr(symname));
+ return SWIG_NOWRAP;
+ }
+
+ Swig_save(&n,"name",NIL);
+ Setattr(n,"name",classname);
+
+ if (Cmp(kind,"class") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else {
+ cplus_mode = CPLUS_PUBLIC;
+ }
+
+ ClassName = NewString(classname);
+ ClassPrefix = NewString(iname);
+ if (strip) {
+ ClassType = NewString(classname);
+ } else {
+ ClassType = NewStringf("%s %s", kind, classname);
+ }
+ Setattr(n,"classtype", SwigType_namestr(ClassType));
+
+ InClass = 1;
+ CurrentClass = n;
+
+ if (Getattr(n,"abstract")) {
+ Abstract = 1;
+ } else {
+ Abstract = 0;
+ }
+
+ /* Call classHandler() here */
+ if (!ImportMode)
+ classHandler(n);
+ else
+ Language::classHandler(n);
+
+ InClass = 0;
+ CurrentClass = 0;
+ Delete(ClassType); ClassType = 0;
+ Delete(ClassPrefix); ClassPrefix = 0;
+ Delete(ClassName); ClassName = 0;
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::classHandler(Node *n) {
+
+ /* Emit all of the class members */
+ emit_children(n);
+
+ /* Look for smart pointer handling */
+ if (Getattr(n,"allocate:smartpointer")) {
+ List *methods = Getattr(n,"allocate:smartpointer");
+ cplus_mode = CPLUS_PUBLIC;
+ SmartPointer = CWRAP_SMART_POINTER;
+ Node *c;
+ for (c = Firstitem(methods); c; c= Nextitem(methods)) {
+ /* Swig_print_node(c); */
+ emit_one(c);
+ }
+ SmartPointer = 0;
+ }
+
+ cplus_mode = CPLUS_PUBLIC;
+ if (!ImportMode && (GenerateDefault && !Getattr(n,"feature:nodefault"))) {
+ if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) {
+ /* Note: will need to change this to support different kinds of classes */
+ if (!Abstract) {
+ Setattr(CurrentClass,"feature:new","1");
+ constructorHandler(CurrentClass);
+ Delattr(CurrentClass,"feature:new");
+ }
+ }
+ if (!Getattr(n,"has_destructor") && (!Getattr(n,"allocate:has_destructor")) && (Getattr(n,"allocate:default_destructor"))) {
+ destructorHandler(CurrentClass);
+ }
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classforwardDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::classforwardDeclaration(Node *n) {
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::constructorDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::constructorDeclaration(Node *n) {
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+
+ if (!CurrentClass) return SWIG_NOWRAP;
+ if (cplus_mode != CPLUS_PUBLIC) return SWIG_NOWRAP;
+ if (ImportMode) return SWIG_NOWRAP;
+
+ /* Name adjustment for %name */
+ Swig_save(&n,"sym:name",NIL);
+
+ {
+ String *base = Swig_scopename_last(name);
+ if ((Strcmp(base,symname) == 0) && (Strcmp(symname, ClassPrefix) != 0)) {
+ Setattr(n,"sym:name", ClassPrefix);
+ }
+ Delete(base);
+ }
+ /* Only create a constructor if the class is not abstract */
+
+ if (!Abstract) {
+ Node *over;
+ over = Swig_symbol_isoverloaded(n);
+ if (over) over = first_nontemplate(over);
+ if ((over) && (!overloading)) {
+ /* If the symbol is overloaded. We check to see if it is a copy constructor. If so,
+ we invoke copyconstructorHandler() as a special case. */
+ if (Getattr(n,"copy_constructor") && (!Getattr(CurrentClass,"has_copy_constructor"))) {
+ copyconstructorHandler(n);
+ Setattr(CurrentClass,"has_copy_constructor","1");
+ } else {
+ if (Getattr(over,"copy_constructor")) over = Getattr(over,"sym:nextSibling");
+ if (over != n) {
+ String *oname = NewStringf("%s::%s", ClassName, Swig_scopename_last(SwigType_namestr(name)));
+ String *cname = NewStringf("%s::%s", ClassName, Swig_scopename_last(SwigType_namestr(Getattr(over,"name"))));
+ SwigType *decl = Getattr(n,"decl");
+ Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, input_file, line_number,
+ "Overloaded constructor ignored. %s\n", SwigType_str(decl,SwigType_namestr(oname)));
+ Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, Getfile(over), Getline(over),
+ "Previous declaration is %s\n", SwigType_str(Getattr(over,"decl"),SwigType_namestr(cname)));
+ Delete(oname);
+ Delete(cname);
+ } else {
+ constructorHandler(n);
+ }
+ }
+ } else {
+ if (name && (Cmp(name,ClassName)) && !(Getattr(n,"template"))) {
+ Printf(stdout,"name = '%s', ClassName='%s'\n", name, ClassName);
+ Swig_warning(WARN_LANG_RETURN_TYPE, input_file,line_number,"Function %s must have a return type.\n",
+ name);
+ Swig_restore(&n);
+ return SWIG_NOWRAP;
+ }
+ constructorHandler(n);
+ }
+ }
+ Setattr(CurrentClass,"has_constructor","1");
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::constructorHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::constructorHandler(Node *n) {
+ Swig_require(&n,"?name","*sym:name","?type","?parms",NIL);
+ String *symname = Getattr(n,"sym:name");
+ String *mrename;
+ Parm *parms = Getattr(n,"parms");
+
+ mrename = Swig_name_construct(symname);
+ if (CPlusPlus) patch_parms(parms);
+ Swig_ConstructorToFunction(n,ClassType,CPlusPlus,Getattr(n,"template") ? 0 :Extend);
+ Setattr(n,"sym:name", mrename);
+ functionWrapper(n);
+ Delete(mrename);
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::copyconstructorHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::copyconstructorHandler(Node *n) {
+ Swig_require(&n,"?name","*sym:name","?type","?parms", NIL);
+ String *symname = Getattr(n,"sym:name");
+ String *mrename;
+ Parm *parms = Getattr(n,"parms");
+ if (CPlusPlus) patch_parms(parms);
+ mrename = Swig_name_copyconstructor(symname);
+ Swig_ConstructorToFunction(n,ClassType, CPlusPlus, Getattr(n,"template") ? 0 : Extend);
+ Setattr(n,"sym:name", mrename);
+ functionWrapper(n);
+ Delete(mrename);
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::destructorDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::destructorDeclaration(Node *n) {
+
+ if (!CurrentClass) return SWIG_NOWRAP;
+ if (cplus_mode != CPLUS_PUBLIC) return SWIG_NOWRAP;
+ if (ImportMode) return SWIG_NOWRAP;
+
+ Swig_save(&n,"name", "sym:name",NIL);
+
+ char *c = GetChar(n,"name");
+ if (c && (*c == '~')) Setattr(n,"name",c+1);
+
+ c = GetChar(n,"sym:name");
+ if (c && (*c == '~')) Setattr(n,"sym:name",c+1);
+
+ /* Name adjustment for %name */
+
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+
+ if ((Strcmp(name,symname) == 0) || (Strcmp(symname,ClassPrefix) != 0)) {
+ Setattr(n,"sym:name", ClassPrefix);
+ }
+
+ destructorHandler(n);
+
+ Setattr(CurrentClass,"has_destructor","1");
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::destructorHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::destructorHandler(Node *n) {
+ Swig_require(&n,"?name","*sym:name",NIL);
+ Swig_save(&n,"type","parms",NIL);
+
+ String *symname = Getattr(n,"sym:name");
+ String *mrename;
+ char *csymname = Char(symname);
+ if (csymname && (*csymname == '~')) csymname +=1;
+
+ mrename = Swig_name_destroy(csymname);
+
+ Swig_DestructorToFunction(n,ClassType,CPlusPlus,Extend);
+ Setattr(n,"sym:name", mrename);
+ functionWrapper(n);
+ Delete(mrename);
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::accessDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::accessDeclaration(Node *n) {
+ String *kind = Getattr(n,"kind");
+ if (Cmp(kind,"public") == 0) {
+ cplus_mode = CPLUS_PUBLIC;
+ } else if (Cmp(kind,"private") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else if (Cmp(kind,"protected") == 0) {
+ cplus_mode = CPLUS_PROTECTED;
+ }
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::namespaceDeclaration()
+ * ----------------------------------------------------------------------------- */
+
+int Language::namespaceDeclaration(Node *n) {
+ if (Getattr(n,"alias")) return SWIG_OK;
+ emit_children(n);
+ return SWIG_OK;
+}
+
+int Language::validIdentifier(String *s) {
+ char *c = Char(s);
+ while (*c) {
+ if (!(isalnum(*c) || (*c == '_'))) return 0;
+ c++;
+ }
+ return 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::usingDeclaration()
+ * ----------------------------------------------------------------------------- */
+
+int Language::usingDeclaration(Node *n) {
+ if (cplus_mode == CPLUS_PUBLIC) {
+ emit_children(n);
+ }
+ return SWIG_OK;
+}
+
+/* Stubs. Language modules need to implement these */
+
+/* ----------------------------------------------------------------------
+ * Language::constantWrapper()
+ * ---------------------------------------------------------------------- */
+
+int Language::constantWrapper(Node *n) {
+ String *name = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ String *value = Getattr(n,"value");
+
+ Printf(stdout,"constantWrapper : %s = %s\n", SwigType_str(type,name), value);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::variableWrapper()
+ * ---------------------------------------------------------------------- */
+int Language::variableWrapper(Node *n) {
+ Swig_require(&n,"*name","*sym:name","*type","?parms",NIL);
+ String *symname = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ String *name = Getattr(n,"name");
+
+ /* If no way to set variables. We simply create functions */
+ if (!Getattr(n,"feature:immutable")) {
+ int make_wrapper = 1;
+ String *tm = Swig_typemap_lookup_new("globalin", n, name, 0);
+
+ Swig_VarsetToFunction(n);
+ Setattr(n,"sym:name", Swig_name_set(symname));
+
+ /* String *tm = Swig_typemap_lookup((char *) "globalin",type,name,name,Swig_cparm_name(0,0),name,0);*/
+
+ if (!tm) {
+ if (SwigType_isarray(type)) {
+ /* Printf(stderr,"%s:%d. Warning. Array member %s will be read-only.\n", input_file, line_number, name);*/
+ make_wrapper = 0;
+ }
+ } else {
+ Replace(tm,"$source", Swig_cparm_name(0,0), DOH_REPLACE_ANY);
+ Replace(tm,"$target", name, DOH_REPLACE_ANY);
+ Replace(tm,"$input",Swig_cparm_name(0,0),DOH_REPLACE_ANY);
+ Setattr(n,"wrap:action", tm);
+ Delete(tm);
+ }
+ if (make_wrapper) {
+ functionWrapper(n);
+ }
+ Setattr(n,"sym:name",symname);
+ Setattr(n,"type",type);
+ Setattr(n,"name",name);
+ }
+ Swig_VargetToFunction(n);
+ Setattr(n,"sym:name", Swig_name_get(symname));
+ functionWrapper(n);
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::functionWrapper()
+ * ---------------------------------------------------------------------- */
+
+int Language::functionWrapper(Node *n) {
+ String *name = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ ParmList *parms = Getattr(n,"parms");
+
+ Printf(stdout,"functionWrapper : %s\n", SwigType_str(type, NewStringf("%s(%s)", name, ParmList_str(parms))));
+ Printf(stdout," action : %s\n", Getattr(n,"wrap:action"));
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::nativeWrapper()
+ * ----------------------------------------------------------------------------- */
+
+int Language::nativeWrapper(Node *n) {
+ return SWIG_OK;
+}
+
+void Language::main(int argc, char *argv[]) {
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::addSymbol()
+ *
+ * Adds a symbol entry. Returns 1 if the symbol is added successfully.
+ * Prints an error message and returns 0 if a conflict occurs.
+ * ----------------------------------------------------------------------------- */
+
+int
+Language::addSymbol(String *s, Node *n) {
+ Node *c = Getattr(symbols,s);
+ if (c && (c != n)) {
+ Swig_error(input_file, line_number, "Error. '%s' is multiply defined in the generated module.\n", s);
+ Swig_error(Getfile(c),Getline(c), "Previous declaration of '%s'\n", s);
+ return 0;
+ }
+ Setattr(symbols,s,n);
+ return 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::symbolLookup()
+ * ----------------------------------------------------------------------------- */
+
+Node *
+Language::symbolLookup(String *s) {
+ return Getattr(symbols,s);
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::classLookup()
+ *
+ * Tries to locate a class from a type definition
+ * ----------------------------------------------------------------------------- */
+
+Node *
+Language::classLookup(SwigType *s) {
+ Node *n = 0;
+ SwigType *lt, *ty1,*ty2;
+ String *base;
+ String *prefix;
+ Symtab *stab = 0;
+
+ /* Look in hash of cached values */
+ n = Getattr(classtypes,s);
+ if (n) return n;
+
+ lt = SwigType_ltype(s);
+ ty1 = SwigType_typedef_resolve_all(lt);
+ ty2 = SwigType_strip_qualifiers(ty1);
+ Delete(lt);
+ Delete(ty1);
+
+ base = SwigType_base(ty2);
+
+ Replaceall(base,"class ","");
+ Replaceall(base,"struct ","");
+ Replaceall(base,"union ","");
+
+ prefix = SwigType_prefix(ty2);
+
+ while (!n) {
+ Hash *nstab;
+ n = Swig_symbol_clookup(base,stab);
+ if (!n) break;
+ if (Strcmp(nodeType(n),"class") == 0) break;
+ n = parentNode(n);
+ if (!n) break;
+ nstab = Getattr(n,"sym:symtab");
+ n = 0;
+ if ((!nstab) || (nstab == stab)) {
+ break;
+ }
+ stab = nstab;
+ }
+ /* Do a symbol table search on the base type */
+ /* n = Swig_symbol_clookup(base,0); */
+ if (n) {
+ /* Found a match. Look at the prefix. We only allow
+ a few cases: pointers, references, and simple */
+ if ((Len(prefix) == 0) || /* Simple type */
+ (Strcmp(prefix,"p.") == 0) || /* pointer */
+ (Strcmp(prefix,"r.") == 0)) { /* reference */
+ Setattr(classtypes,Copy(s),n);
+ } else {
+ n = 0;
+ }
+ }
+ Delete(ty2);
+ Delete(base);
+ Delete(prefix);
+
+ if (n && (Getattr(n,"feature:ignore"))) return 0;
+ return n;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::allow_overloading()
+ * ----------------------------------------------------------------------------- */
+
+void Language::allow_overloading(int val) {
+ overloading = val;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::allow_multiple_input()
+ * ----------------------------------------------------------------------------- */
+
+void Language::allow_multiple_input(int val) {
+ multiinput = val;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::is_wrapping_class()
+ * ----------------------------------------------------------------------------- */
+
+int Language::is_wrapping_class() {
+ return InClass;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::getCurrentClass()
+ * ----------------------------------------------------------------------------- */
+
+Node * Language::getCurrentClass() const {
+ return CurrentClass;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::getClassName()
+ * ----------------------------------------------------------------------------- */
+
+String * Language::getClassName() const {
+ return ClassName;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::getClassPrefix()
+ * ----------------------------------------------------------------------------- */
+
+String * Language::getClassPrefix() const {
+ return ClassPrefix;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::getClassType()
+ * ----------------------------------------------------------------------------- */
+
+String * Language::getClassType() const {
+ return ClassType;
+}
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
new file mode 100644
index 000000000..2cbdbec66
--- /dev/null
+++ b/Source/Modules/main.cxx
@@ -0,0 +1,622 @@
+/* -----------------------------------------------------------------------------
+ * main.cxx
+ *
+ * Main entry point to the SWIG core.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1998-2000. The University of Chicago
+ * Copyright (C) 1995-1998. The University of Utah and The Regents of the
+ * University of California.
+ *
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_main_cxx[] = "$Header$";
+
+#if defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include
+#endif
+
+#include "swigmod.h"
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+
+#include "swigwarn.h"
+
+extern "C" {
+#include "preprocessor.h"
+}
+
+#include
+
+#ifndef SWIG_LIB
+#define SWIG_LIB "/usr/local/lib/swig1.3"
+#endif
+
+#ifndef SWIG_CC
+#define SWIG_CC "CC"
+#endif
+
+// Global variables
+
+ char LibDir[512]; // Library directory
+ Language *lang; // Language method
+ int CPlusPlus = 0;
+ int Extend = 0; // Extend flag
+ int ForceExtern = 0; // Force extern mode
+ int GenerateDefault = 1; // Generate default constructors
+ char *Config = 0;
+ int NoInclude = 0;
+ int Verbose = 0;
+ int NoExtern = 0;
+ int NoExcept = 0;
+
+extern "C" {
+extern String *ModuleName;
+}
+
+static char *usage = (char*)"\
+\nGeneral Options\n\
+ -c - Produce raw wrapper code (omit support code)\n\
+ -c++ - Enable C++ processing\n\
+ -co - Check a file out of the SWIG library\n\
+ -Dsymbol - Define a symbol (for conditional compilation)\n\
+ -I - Look for SWIG files in \n\
+ -includeall - Follow all #include statements\n\
+ -importall - Follow all #include statements as imports\n\
+ -ignoremissing - Ignore missing include files.\n\
+ -l - Include SWIG library file.\n\
+ -M - List all dependencies. \n\
+ -MM - List dependencies, but omit files in SWIG library.\n\
+ -makedefault - Create default constructors/destructors (the default)\n\
+ -module - Set module name\n\
+ -nodefault - Do not generate constructors/destructors\n\
+ -noexcept - Do not wrap exception specifiers.\n\
+ -noextern - Do not generate extern declarations.\n\
+ -o outfile - Set name of the output file.\n\
+ -swiglib - Report location of SWIG library and exit\n\
+ -v - Run in verbose mode\n\
+ -version - Print SWIG version number\n\
+ -Wall - Enable all warning messages\n\
+ -wn - Suppress warning number n\n\
+ -help - This output.\n\n";
+
+// -----------------------------------------------------------------------------
+// check_suffix(char *name)
+//
+// Checks the suffix of a file to see if we should emit extern declarations.
+// -----------------------------------------------------------------------------
+
+int
+check_suffix(char *name) {
+ char *c;
+ if (!name) return 0;
+ c = Swig_file_suffix(name);
+ if ((strcmp(c,".c") == 0) ||
+ (strcmp(c,".C") == 0) ||
+ (strcmp(c,".cc") == 0) ||
+ (strcmp(c,".cxx") == 0) ||
+ (strcmp(c,".c++") == 0) ||
+ (strcmp(c,".cpp") == 0)) {
+ return 1;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+// install_opts(int argc, char *argv[])
+// Install all command line options as preprocessor symbols
+// -----------------------------------------------------------------------------
+
+static void
+install_opts(int argc, char *argv[]) {
+ int i;
+ int noopt = 0;
+ char *c;
+ for (i = 1; i < (argc-1); i++) {
+ if (argv[i]) {
+ if ((*argv[i] == '-') && (!isupper(*(argv[i]+1)))) {
+ String *opt = NewStringf("SWIGOPT%(upper)s", argv[i]);
+ Replaceall(opt,"-","_");
+ c = Char(opt);
+ noopt = 0;
+ while (*c) {
+ if (!(isalnum(*c) || (*c == '_'))) {
+ noopt = 1;
+ break;
+ }
+ c++;
+ }
+ if (((i+1) < (argc-1)) && (argv[i+1]) && (*argv[i+1] != '-')) {
+ Printf(opt," %s", argv[i+1]);
+ i++;
+ } else {
+ Printf(opt," 1");
+ }
+ if (!noopt) {
+ /* Printf(stdout,"%s\n", opt); */
+ Preprocessor_define(opt, 0);
+ }
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------
+// main()
+//
+// Main program. Initializes the files and starts the parser.
+//-----------------------------------------------------------------
+
+char *SwigLib;
+static int freeze = 0;
+static String *lang_config = 0;
+static char *cpp_extension = (char *) "cxx";
+
+/* This function sets the name of the configuration file */
+
+void SWIG_config_file(const String_or_char *filename) {
+ lang_config = NewString(filename);
+}
+
+void SWIG_library_directory(const char *filename) {
+ strcpy(LibDir,filename);
+}
+
+void SWIG_config_cppext(const char *ext) {
+ cpp_extension = (char *) ext;
+}
+
+extern "C" Node *Swig_cparse(File *);
+extern "C" void Swig_cparse_cplusplus(int);
+extern "C" void Swig_cparse_debug_templates(int);
+
+int SWIG_main(int argc, char *argv[], Language *l) {
+ int i;
+ char *c;
+ char temp[512];
+ char *outfile_name = 0;
+ int help = 0;
+ int checkout = 0;
+ int cpp_only = 0;
+ int tm_debug = 0;
+ char *includefiles[256];
+ int includecount = 0;
+ extern int check_suffix(char *);
+ int dump_tags = 0;
+ int dump_tree = 0;
+ int contracts = 0;
+ int browse = 0;
+ int dump_typedef = 0;
+ int dump_classes = 0;
+ int werror = 0;
+ int depend = 0;
+
+ DOH *libfiles = 0;
+ DOH *cpps = 0 ;
+ extern void Swig_contracts(Node *n);
+ extern void Swig_browser(Node *n, int);
+ extern void Swig_default_allocators(Node *n);
+ extern void Swig_process_types(Node *n);
+
+
+ /* Initialize the SWIG core */
+ Swig_init();
+
+ /* Suppress warning messages for private inheritance, preprocessor evaluation,
+ might be abstract, and overloaded const */
+
+ Swig_warnfilter("202,309,403,512",1);
+
+ // Initialize the preprocessor
+ Preprocessor_init();
+
+ lang = l;
+
+ // Set up some default symbols (available in both SWIG interface files
+ // and C files)
+
+ Preprocessor_define((DOH *) "SWIG 1", 0);
+ Preprocessor_define((DOH *) "__STDC__", 0);
+#ifdef MACSWIG
+ Preprocessor_define((DOH *) "SWIGMAC 1", 0);
+#endif
+#ifdef SWIGWIN32
+ Preprocessor_define((DOH *) "SWIGWIN32 1", 0);
+#endif
+
+ // Set the SWIG version value
+ String *vers;
+ vers = NewStringf("SWIG_VERSION 0x%02d%02d%02d", SWIG_MAJOR_VERSION, SWIG_MINOR_VERSION, SWIG_SPIN);
+ Preprocessor_define(vers,0);
+
+ // Check for SWIG_LIB environment variable
+
+ if ((c = getenv("SWIG_LIB")) == (char *) 0) {
+#if defined(_WIN32)
+ char buf[MAX_PATH];
+ char *p;
+ if (GetModuleFileName(0, buf, MAX_PATH) == 0
+ || (p = strrchr(buf, '\\')) == 0) {
+ Printf(stderr, "Warning: Could not determine SWIG library location. Assuming " SWIG_LIB "\n");
+ sprintf(LibDir,"%s",SWIG_LIB); // Build up search paths
+ } else {
+ strcpy(p+1, "Lib");
+ strcpy(LibDir, buf);
+ }
+#else
+ sprintf(LibDir,"%s",SWIG_LIB); // Build up search paths
+#endif
+ } else {
+ strcpy(LibDir,c);
+ }
+
+ SwigLib = Swig_copy_string(LibDir); // Make a copy of the real library location
+
+ libfiles = NewList();
+
+ // Get options
+ for (i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strncmp(argv[i],"-I",2) == 0) {
+ // Add a new directory search path
+ includefiles[includecount++] = Swig_copy_string(argv[i]+2);
+ Swig_mark_arg(i);
+ } else if (strncmp(argv[i],"-D",2) == 0) {
+ DOH *d = NewString(argv[i]+2);
+ Replace(d,(char*)"=",(char*)" ", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
+ Preprocessor_define((DOH *) d,0);
+ // Create a symbol
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-E") == 0) {
+ cpp_only = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i],"-verbose") == 0) ||
+ (strcmp(argv[i],"-v") == 0)) {
+ Verbose = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-c++") == 0) {
+ CPlusPlus=1;
+ Preprocessor_define((DOH *) "__cplusplus 1", 0);
+ Swig_cparse_cplusplus(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-c") == 0) {
+ NoInclude=1;
+ Preprocessor_define((DOH *) "SWIG_NOINCLUDE 1", 0);
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i],"-make_default") == 0) || (strcmp(argv[i],"-makedefault") == 0)) {
+ GenerateDefault = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i],"-no_default") == 0) || (strcmp(argv[i],"-nodefault") == 0)) {
+ GenerateDefault = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-noexcept") == 0) {
+ NoExcept = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-noextern") == 0) {
+ NoExtern = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-show_templates") == 0) {
+ Swig_cparse_debug_templates(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-swiglib") == 0) {
+ printf("%s\n", LibDir);
+ SWIG_exit (EXIT_SUCCESS);
+ } else if (strcmp(argv[i],"-o") == 0) {
+ Swig_mark_arg(i);
+ if (argv[i+1]) {
+ outfile_name = Swig_copy_string(argv[i+1]);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i],"-version") == 0) {
+ fprintf(stderr,"\nSWIG Version %s\n",
+ SWIG_VERSION);
+ fprintf(stderr,"Copyright (c) 1995-1998\n");
+ fprintf(stderr,"University of Utah and the Regents of the University of California\n");
+ fprintf(stderr,"Copyright (c) 1998-2002\n");
+ fprintf(stderr,"University of Chicago\n");
+ fprintf(stderr,"\nCompiled with %s\n", SWIG_CC);
+ SWIG_exit (EXIT_SUCCESS);
+ } else if (strncmp(argv[i],"-l",2) == 0) {
+ // Add a new directory search path
+ Append(libfiles,argv[i]+2);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-co") == 0) {
+ checkout = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-freeze") == 0) {
+ freeze = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-includeall") == 0) {
+ Preprocessor_include_all(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-importall") == 0) {
+ Preprocessor_import_all(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-ignoremissing") == 0) {
+ Preprocessor_ignore_missing(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-tm_debug") == 0) {
+ tm_debug = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-module") == 0) {
+ Swig_mark_arg(i);
+ if (argv[i+1]) {
+ ModuleName = NewString(argv[i+1]);
+ Swig_mark_arg(i+1);
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i],"-M") == 0) {
+ depend = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-MM") == 0) {
+ depend = 2;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-Wall") == 0) {
+ Swig_mark_arg(i);
+ Swig_warnall();
+ } else if (strcmp(argv[i],"-Werror") == 0) {
+ werror = 1;
+ Swig_mark_arg(i);
+ } else if (strncmp(argv[i],"-w",2) == 0) {
+ Swig_mark_arg(i);
+ Swig_warnfilter(argv[i]+2,1);
+ } else if (strcmp(argv[i],"-dump_tags") == 0) {
+ dump_tags = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-dump_tree") == 0) {
+ dump_tree = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-contracts") == 0) {
+ Swig_mark_arg(i);
+ contracts = 1;
+ } else if (strcmp(argv[i],"-browse") == 0) {
+ browse = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-dump_typedef") == 0) {
+ dump_typedef = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-dump_classes") == 0) {
+ dump_classes = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-help") == 0) {
+ fputs(usage,stderr);
+ Swig_mark_arg(i);
+ help = 1;
+ }
+ }
+ }
+
+ for (i = 0; i < includecount; i++) {
+ Swig_add_directory((DOH *) includefiles[i]);
+ }
+
+ // Define the __cplusplus symbol
+ if (CPlusPlus)
+ Preprocessor_define((DOH *) "__cplusplus 1", 0);
+
+ // Parse language dependent options
+ lang->main(argc,argv);
+
+ if (help) SWIG_exit (EXIT_SUCCESS); // Exit if we're in help mode
+
+ // Check all of the options to make sure we're cool.
+ Swig_check_options();
+
+ install_opts(argc, argv);
+
+ // Add language dependent directory to the search path
+ {
+ DOH *rl = NewString("");
+ Printf(rl,"%s%s%s", SwigLib, SWIG_FILE_DELIMETER, LibDir);
+ Swig_add_directory(rl);
+ rl = NewString("");
+ Printf(rl,".%sswig_lib%s%s", SWIG_FILE_DELIMETER, SWIG_FILE_DELIMETER, LibDir);
+ Swig_add_directory(rl);
+ }
+
+ sprintf(temp,"%s%sconfig", SwigLib, SWIG_FILE_DELIMETER);
+ Swig_add_directory((DOH *) temp);
+ Swig_add_directory((DOH *) "." SWIG_FILE_DELIMETER "swig_lib" SWIG_FILE_DELIMETER "config");
+ Swig_add_directory((DOH *) SwigLib);
+ Swig_add_directory((DOH *) "." SWIG_FILE_DELIMETER "swig_lib");
+
+ if (Verbose) {
+ printf ("LibDir: %s\n", LibDir);
+ List *sp = Swig_search_path();
+ String *s;
+ for (s = Firstitem(sp); s; s = Nextitem(sp)) {
+ Printf(stdout," %s\n", s);
+ }
+ }
+
+ // If we made it this far, looks good. go for it....
+
+ input_file = argv[argc-1];
+
+ // If the user has requested to check out a file, handle that
+ if (checkout) {
+ DOH *s;
+ char *outfile = input_file;
+ if (outfile_name)
+ outfile = outfile_name;
+
+ if (Verbose)
+ printf ("Handling checkout...\n");
+
+ s = Swig_include(input_file);
+ if (!s) {
+ fprintf(stderr,"Unable to locate '%s' in the SWIG library.\n", input_file);
+ } else {
+ FILE *f = fopen(outfile,"r");
+ if (f) {
+ fclose(f);
+ fprintf(stderr,"File '%s' already exists. Checkout aborted.\n", outfile);
+ } else {
+ f = fopen(outfile,"w");
+ if (!f) {
+ fprintf(stderr,"Unable to create file '%s'\n", outfile);
+ } else {
+ fprintf(stderr,"'%s' checked out from the SWIG library.\n", input_file);
+ fputs(Char(s),f);
+ fclose(f);
+ }
+ }
+ }
+ } else {
+ // Check the suffix for a .c file. If so, we're going to
+ // declare everything we see as "extern"
+
+ ForceExtern = check_suffix(input_file);
+
+ // Run the preprocessor
+ if (Verbose)
+ printf ("Preprocessing...\n");
+ {
+ int i;
+ String *fs = NewString("");
+ FILE *df = Swig_open(input_file);
+ if (!df) {
+ Printf(stderr,"Unable to find '%s'\n", input_file);
+ SWIG_exit (EXIT_FAILURE);
+ }
+ fclose(df);
+ Printf(fs,"%%include \"swig.swg\"\n");
+ if (lang_config) {
+ Printf(fs,"\n%%include \"%s\"\n", lang_config);
+ }
+ Printf(fs,"%%include \"%s\"\n", Swig_last_file());
+ for (i = 0; i < Len(libfiles); i++) {
+ Printf(fs,"\n%%include \"%s\"\n", Getitem(libfiles,i));
+ }
+ Seek(fs,0,SEEK_SET);
+ cpps = Preprocessor_parse(fs);
+ if (Swig_error_count()) {
+ SWIG_exit(EXIT_FAILURE);
+ }
+ if (cpp_only) {
+ Printf(stdout,"%s", cpps);
+ while (freeze);
+ SWIG_exit (EXIT_SUCCESS);
+ }
+ if (depend) {
+ String *outfile;
+ if (!outfile_name) {
+ if (CPlusPlus) {
+ outfile = NewStringf("%s_wrap.%s", Swig_file_basename(input_file),cpp_extension);
+ } else {
+ outfile = NewStringf("%s_wrap.c", Swig_file_basename(input_file));
+ }
+ } else {
+ outfile = NewString(outfile_name);
+ }
+ Printf(stdout,"%s: ", outfile);
+ List *files = Preprocessor_depend();
+ for (int i = 0; i < Len(files); i++) {
+ if ((depend != 2) || ((depend == 2) && (Strncmp(Getitem(files,i),SwigLib, Len(SwigLib)) != 0))) {
+ Printf(stdout,"\\\n %s ", Getitem(files,i));
+ }
+ }
+ Printf(stdout,"\n");
+ SWIG_exit(EXIT_SUCCESS);
+ }
+ Seek(cpps, 0, SEEK_SET);
+ }
+
+ /* Register a null file with the file handler */
+ Swig_register_filebyname("null", NewString(""));
+
+ // Pass control over to the specific language interpreter
+ if (Verbose) {
+ fprintf (stdout, "Starting language-specific parse...\n");
+ fflush (stdout);
+ }
+
+ Node *top = Swig_cparse(cpps);
+
+ if (Verbose) {
+ Printf(stdout,"Processing types...\n");
+ }
+ Swig_process_types(top);
+
+ if (Verbose) {
+ Printf(stdout,"C++ analysis...\n");
+ }
+ Swig_default_allocators(top);
+
+ if (Verbose) {
+ Printf(stdout,"Generating wrappers...\n");
+ }
+
+ if (dump_classes) {
+ Hash *classes = Getattr(top,"classes");
+ if (classes) {
+ Printf(stdout,"Classes\n");
+ Printf(stdout,"------------\n");
+ String *key;
+ for (key = Firstkey(classes); key; key = Nextkey(classes)) {
+ Printf(stdout,"%s\n", key);
+ }
+ }
+ }
+
+ if (dump_typedef) {
+ SwigType_print_scope(0);
+ }
+ if (dump_tags) {
+ Swig_print_tags(top,0);
+ }
+ if (dump_tree) {
+ Swig_print_tree(top);
+ }
+ if (top) {
+ if (!Getattr(top,"name")) {
+ Printf(stderr,"*** No module name specified using %%module or -module.\n");
+ SWIG_exit(EXIT_FAILURE);
+ } else {
+ /* Set some filename information on the object */
+ Setattr(top,"infile", input_file);
+ if (!outfile_name) {
+ if (CPlusPlus) {
+ Setattr(top,"outfile", NewStringf("%s_wrap.%s", Swig_file_basename(input_file),cpp_extension));
+ } else {
+ Setattr(top,"outfile", NewStringf("%s_wrap.c", Swig_file_basename(input_file)));
+ }
+ } else {
+ Setattr(top,"outfile", outfile_name);
+ }
+ if (contracts) {
+ Swig_contracts(top);
+ }
+ lang->top(top);
+ if (browse) {
+ Swig_browser(top,0);
+ }
+ }
+ }
+ }
+ if (tm_debug) Swig_typemap_debug();
+ while (freeze);
+ if ((werror) && (Swig_warn_count())) {
+ return Swig_warn_count();
+ }
+ return Swig_error_count();
+}
+
+// --------------------------------------------------------------------------
+// SWIG_exit(int exit_code)
+//
+// Cleanup and either freeze or exit
+// --------------------------------------------------------------------------
+
+void SWIG_exit(int exit_code) {
+ while (freeze);
+ exit (exit_code);
+}
+
diff --git a/Source/Modules/module.cxx b/Source/Modules/module.cxx
new file mode 100644
index 000000000..57aa6c304
--- /dev/null
+++ b/Source/Modules/module.cxx
@@ -0,0 +1,57 @@
+/* -----------------------------------------------------------------------------
+ * module.cxx
+ *
+ * This file is responsible for the module system.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1999-2000. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_module_cxx[] = "$Header$";
+
+#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;
+ }
+};
+
+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;
+}
diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx
new file mode 100644
index 000000000..14e4a3ac2
--- /dev/null
+++ b/Source/Modules/mzscheme.cxx
@@ -0,0 +1,668 @@
+/******************************************************************************
+ * Simplified Wrapper and Interface Generator (SWIG)
+ *
+ * Author : David Beazley
+ *
+ * Department of Computer Science
+ * University of Chicago
+ * 1100 E 58th Street
+ * Chicago, IL 60637
+ * beazley@cs.uchicago.edu
+ *
+ * Please read the file LICENSE for the copyright and terms by which SWIG
+ * can be used and distributed.
+ *****************************************************************************/
+
+char cvsroot_mzscheme_cxx[] = "$Header$";
+
+/***********************************************************************
+ * $Header$
+ *
+ * mzscheme.cxx
+ *
+ * Definitions for adding functions to Mzscheme 101
+ ***********************************************************************/
+
+#include "swigmod.h"
+
+#include
+
+static const char *mzscheme_usage = (char*)"\
+\n\
+Mzscheme Options (available with -mzscheme)\n\
+-help - Print this help\n\
+-prefix name - Set a prefix to be appended to all names\n\
+-declaremodule - Create extension that declares a module\n\
+\n"
+;
+
+static char *prefix=0;
+static bool declaremodule = false;
+static String *module=0;
+static char *mzscheme_path=(char*)"mzscheme";
+static String *init_func_def = 0;
+
+static File *f_runtime = 0;
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+
+class MZSCHEME : public Language {
+public:
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main (int argc, char *argv[]) {
+
+ int i;
+
+ SWIG_library_directory(mzscheme_path);
+
+ // Look for certain command line options
+ for (i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp (argv[i], "-help") == 0) {
+ fputs (mzscheme_usage, stderr);
+ SWIG_exit (0);
+ }
+ else if (strcmp (argv[i], "-prefix") == 0) {
+ if (argv[i + 1]) {
+ prefix = new char[strlen(argv[i + 1]) + 2];
+ strcpy(prefix, argv[i + 1]);
+ Swig_mark_arg (i);
+ Swig_mark_arg (i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ }
+ else if (strcmp (argv[i], "-declaremodule") == 0) {
+ declaremodule = true;
+ Swig_mark_arg (i);
+ }
+ }
+ }
+
+ // If a prefix has been specified make sure it ends in a '_'
+
+ if (prefix) {
+ if (prefix[strlen (prefix)] != '_') {
+ prefix[strlen (prefix) + 1] = 0;
+ prefix[strlen (prefix)] = '_';
+ }
+ } else
+ prefix = (char*)"swig_";
+
+ // Add a symbol for this module
+
+ Preprocessor_define ("SWIGMZSCHEME 1",0);
+
+ // Set name of typemaps
+
+ SWIG_typemap_lang("mzscheme");
+
+ // Read in default typemaps */
+ SWIG_config_file("mzscheme.i");
+ allow_overloading();
+
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
+
+ f_runtime = NewFile(outfile,"w");
+ if (!f_runtime) {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header",f_header);
+ Swig_register_filebyname("wrapper",f_wrappers);
+ Swig_register_filebyname("runtime",f_runtime);
+
+ init_func_def = NewString("");
+ Swig_register_filebyname("init",init_func_def);
+
+ Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n");
+ Swig_banner (f_runtime);
+
+ if (NoInclude) {
+ Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
+ }
+
+ module = Getattr(n,"name");
+
+ Language::top(n);
+
+ SwigType_emit_type_table (f_runtime, f_wrappers);
+ Printf(f_init, "Scheme_Object *scheme_reload(Scheme_Env *env) {\n");
+ Printf(f_init, "\tScheme_Env *menv = env;\n");
+ if (declaremodule) {
+ Printf(f_init, "\tmenv = scheme_primitive_module(scheme_intern_symbol(\"%s\"), env);\n", module);
+ }
+ Printf (f_init, "\tSWIG_RegisterTypes(swig_types, swig_types_initial);\n");
+ Printf(f_init, "%s\n", Char(init_func_def));
+ if (declaremodule) {
+ Printf(f_init, "\tscheme_finish_primitive_module(menv);\n");
+ }
+ Printf (f_init, "\treturn scheme_void;\n}\n");
+ Printf(f_init, "Scheme_Object *scheme_initialize(Scheme_Env *env) {\n");
+ Printf(f_init, "\treturn scheme_reload(env);\n");
+ Printf (f_init, "}\n");
+
+ Printf(f_init,"Scheme_Object *scheme_module_name(void) {\n");
+ if (declaremodule) {
+ Printf(f_init, " return scheme_intern_symbol((char*)\"%s\");\n", module);
+ }
+ else {
+ Printf(f_init," return scheme_make_symbol((char*)\"%s\");\n", module);
+ }
+ Printf(f_init,"}\n");
+
+ /* Close all of the files */
+ Dump(f_header,f_runtime);
+ Dump(f_wrappers,f_runtime);
+ Wrapper_pretty_print(f_init,f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_runtime);
+ Delete(f_runtime);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * Create a function declaration and register it with the interpreter.
+ * ------------------------------------------------------------ */
+
+ void throw_unhandled_mzscheme_type_error (SwigType *d)
+ {
+ Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number,
+ "Unable to handle type %s.\n", SwigType_str(d,0));
+ }
+
+ /* Return true iff T is a pointer type */
+
+ int
+ is_a_pointer (SwigType *t)
+ {
+ return SwigType_ispointer(SwigType_typedef_resolve_all(t));
+ }
+
+ virtual int functionWrapper(Node *n) {
+ char *iname = GetChar(n,"sym:name");
+ SwigType *d = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+ Parm *p;
+
+ Wrapper *f = NewWrapper();
+ String *proc_name = NewString("");
+ String *source = NewString("");
+ String *target = NewString("");
+ String *arg = NewString("");
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *build = NewString("");
+ String *tm;
+ int argout_set = 0;
+ int i = 0;
+ int numargs;
+ int numreq;
+ String *overname = 0;
+
+ // Make a wrapper name for this
+ String *wname = Swig_name_wrapper(iname);
+ if (Getattr(n,"sym:overloaded")) {
+ overname = Getattr(n,"sym:overname");
+ } else {
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+ }
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n,"wrap:name",wname);
+
+ // Build the name for Scheme.
+ Printv(proc_name, iname,NIL);
+ Replaceall(proc_name, "_", "-");
+
+ // writing the function wrapper function
+ Printv(f->def, "static Scheme_Object *", wname, " (", NIL);
+ Printv(f->def, "int argc, Scheme_Object **argv", NIL);
+ Printv(f->def, ")\n{", NIL);
+
+ /* Define the scheme name in C. This define is used by several
+ macros. */
+ Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
+
+ // Declare return variable and arguments
+ // number of parameters
+ // they are called arg0, arg1, ...
+ // the return value is called result
+
+ emit_args(d, l, f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l,f);
+ Setattr(n,"wrap:parms",l);
+
+ numargs = emit_num_arguments(l);
+ numreq = emit_num_required(l);
+
+ // adds local variables
+ Wrapper_add_local(f, "_len", "int _len");
+ Wrapper_add_local(f, "lenv", "int lenv = 1");
+ Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]");
+
+ // Now write code to extract the parameters (this is super ugly)
+
+ for (i = 0, p = l; i < numargs; i++) {
+ /* Skip ignored arguments */
+
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *ln = Getattr(p,"lname");
+
+ // Produce names of source and target
+ Clear(source);
+ Clear(target);
+ Clear(arg);
+ Printf(source, "argv[%d]", i);
+ Printf(target, "%s",ln);
+ Printv(arg, Getattr(p,"name"),NIL);
+
+ if (i >= numreq) {
+ Printf(f->code,"if (argc > %d) {\n",i);
+ }
+ // Handle parameter types.
+ if ((tm = Getattr(p,"tmap:in"))) {
+ Replaceall(tm,"$source",source);
+ Replaceall(tm,"$target",target);
+ Replaceall(tm,"$input",source);
+ Setattr(p,"emit:input",source);
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ // no typemap found
+ // check if typedef and resolve
+ throw_unhandled_mzscheme_type_error (pt);
+ p = nextSibling(p);
+ }
+ if (i >= numreq) {
+ Printf(f->code,"}\n");
+ }
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:check"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Pass output arguments back to the caller.
+
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:argout"))) {
+ Replaceall(tm,"$source",Getattr(p,"emit:input")); /* Deprecated */
+ Replaceall(tm,"$target",Getattr(p,"lname")); /* Deprecated */
+ Replaceall(tm,"$arg",Getattr(p,"emit:input"));
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(outarg,tm,"\n",NIL);
+ p = Getattr(p,"tmap:argout:next");
+ argout_set = 1;
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Free up any memory allocated for the arguments.
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:freearg"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(cleanup,tm,"\n",NIL);
+ p = Getattr(p,"tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Now write code to make the function call
+
+ emit_action(n,f);
+
+ // Now have return value, figure out what to do with it.
+
+ if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Replaceall(tm,"$target","values[0]");
+ Replaceall(tm,"$result","values[0]");
+ Printv(f->code, tm, "\n",NIL);
+ } else {
+ throw_unhandled_mzscheme_type_error (d);
+ }
+
+ // Dump the argument output code
+ Printv(f->code, Char(outarg),NIL);
+
+ // Dump the argument cleanup code
+ Printv(f->code, Char(cleanup),NIL);
+
+ // Look for any remaining cleanup
+
+ if (Getattr(n,"feature:new")) {
+ if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printv(f->code, tm, "\n",NIL);
+ }
+ }
+
+ // Free any memory allocated by the function being wrapped..
+
+ if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printv(f->code, tm, "\n",NIL);
+ }
+
+ // Wrap things up (in a manner of speaking)
+
+ Printv(f->code, tab4, "return swig_package_values(lenv, values);\n", NIL);
+ Printf(f->code, "#undef FUNC_NAME\n");
+ Printv(f->code, "}\n",NIL);
+
+ Wrapper_print(f, f_wrappers);
+
+ if (!Getattr(n,"sym:overloaded")) {
+
+ // Now register the function
+ char temp[256];
+ sprintf(temp, "%d", 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 */
+
+ int maxargs;
+ String *dispatch = Swig_overload_dispatch(n,"return %s(argc,argv);",&maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *df = NewWrapper();
+ String *dname = Swig_name_wrapper(iname);
+
+ 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);
+ 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);
+ DelWrapper(df);
+ Delete(dispatch);
+ Delete(dname);
+ }
+ }
+
+ Delete(proc_name);
+ Delete(source);
+ Delete(target);
+ Delete(arg);
+ Delete(outarg);
+ Delete(cleanup);
+ Delete(build);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ *
+ * Create a link to a C variable.
+ * This creates a single function _wrap_swig_var_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. Either way, we return the variables
+ * value.
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+
+ char *name = GetChar(n,"name");
+ char *iname = GetChar(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+
+ String *proc_name = NewString("");
+ char var_name[256];
+ String *tm;
+ String *tm2 = NewString("");;
+ String *argnum = NewString("0");
+ String *arg = NewString("argv[0]");
+ Wrapper *f;
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ f = NewWrapper();
+
+ // evaluation function names
+
+ strcpy(var_name, Char(Swig_name_wrapper(iname)));
+
+ // Build the name for scheme.
+ Printv(proc_name, iname,NIL);
+ Replaceall(proc_name, "_", "-");
+
+ if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) {
+
+ Printf (f->def, "static Scheme_Object *%s(int argc, Scheme_Object** argv) {\n", var_name);
+ Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
+
+ Wrapper_add_local (f, "swig_result", "Scheme_Object *swig_result");
+
+ if (!Getattr(n,"feature:immutable")) {
+ /* Check for a setting of the variable value */
+ Printf (f->code, "if (argc) {\n");
+ if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) {
+ Replaceall(tm,"$source","argv[0]");
+ Replaceall(tm,"$target",name);
+ Replaceall(tm,"$input","argv[0]");
+ Printv(f->code, tm, "\n",NIL);
+ }
+ else {
+ throw_unhandled_mzscheme_type_error (t);
+ }
+ Printf (f->code, "}\n");
+ }
+
+ // Now return the value of the variable (regardless
+ // of evaluating or setting)
+
+ if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) {
+ Replaceall(tm,"$source",name);
+ Replaceall(tm,"$target","swig_result");
+ Replaceall(tm,"$result","swig_result");
+ Printf (f->code, "%s\n", tm);
+ }
+ else {
+ throw_unhandled_mzscheme_type_error (t);
+ }
+ Printf (f->code, "\nreturn swig_result;\n");
+ Printf (f->code, "#undef FUNC_NAME\n");
+ Printf (f->code, "}\n");
+
+ Wrapper_print (f, f_wrappers);
+
+ // Now add symbol to the MzScheme interpreter
+
+ Printv(init_func_def,
+ "scheme_add_global(\"",
+ proc_name,
+ "\", scheme_make_prim_w_arity(",
+ var_name,
+ ", \"",
+ proc_name,
+ "\", ",
+ "0",
+ ", ",
+ "1",
+ "), menv);\n",NIL);
+
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number,
+ "Unsupported variable type %s (ignored).\n", SwigType_str(t,0));
+ }
+ Delete(proc_name);
+ Delete(argnum);
+ Delete(arg);
+ Delete(tm2);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ char *name = GetChar(n,"name");
+ char *iname = GetChar(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ String *value = Getattr(n,"value");
+
+ String *var_name = NewString("");
+ String *proc_name = NewString("");
+ String *rvalue = NewString("");
+ String *temp = NewString("");
+ String *tm;
+
+ // Make a static variable;
+
+ Printf (var_name, "_wrap_const_%s", Swig_name_mangle(iname));
+
+ // Build the name for scheme.
+ Printv(proc_name, iname,NIL);
+ Replaceall(proc_name, "_", "-");
+
+ if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
+ "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+
+ // 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);
+ }
+ if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
+ Delete(temp);
+ temp = Copy(rvalue);
+ Clear(rvalue);
+ Printv(rvalue, "'", temp, "'",NIL);
+ }
+ if ((tm = Swig_typemap_lookup_new("constant",n,name,0))) {
+ Replaceall(tm,"$source",rvalue);
+ Replaceall(tm,"$value",rvalue);
+ Replaceall(tm,"$target",name);
+ Printf (f_init, "%s\n", tm);
+ } else {
+ // Create variable and assign it a value
+
+ Printf (f_header, "static %s = ", SwigType_lstr(type,var_name));
+ if ((SwigType_type(type) == T_STRING)) {
+ Printf (f_header, "\"%s\";\n", value);
+ } else if (SwigType_type(type) == T_CHAR) {
+ Printf (f_header, "\'%s\';\n", value);
+ } else {
+ Printf (f_header, "%s;\n", value);
+ }
+
+ // Now create a variable declaration
+
+ {
+ /* Hack alert: will cleanup later -- Dave */
+ Node *n = NewHash();
+ Setattr(n,"name",var_name);
+ Setattr(n,"sym:name",iname);
+ Setattr(n,"type", type);
+ variableWrapper(n);
+ Delete(n);
+ }
+ }
+ Delete(proc_name);
+ Delete(rvalue);
+ Delete(temp);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * validIdentifer()
+ * ------------------------------------------------------------ */
+
+ virtual int validIdentifier(String *s) {
+ char *c = Char(s);
+ /* Check whether we have an R5RS identifier.*/
+ /* --> * | */
+ /* --> | */
+ if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~'))) {
+ /* --> + | - | ... */
+ if ((strcmp(c, "+") == 0)
+ || strcmp(c, "-") == 0
+ || strcmp(c, "...") == 0) return 1;
+ else return 0;
+ }
+ /* --> | | */
+ while (*c) {
+ if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+')
+ || (*c == '-') || (*c == '.') || (*c == '@'))) return 0;
+ c++;
+ }
+ return 1;
+ }
+};
+
+/* -----------------------------------------------------------------------------
+ * swig_mzscheme() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+extern "C" Language *
+swig_mzscheme(void) {
+ return new MZSCHEME();
+}
+
+
diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx
new file mode 100755
index 000000000..786fee5dd
--- /dev/null
+++ b/Source/Modules/ocaml.cxx
@@ -0,0 +1,1072 @@
+/* -*- c-indentation-style: gnu -*- */
+/******************************************************************************
+ * Simplified Wrapper and Interface Generator (SWIG)
+ *
+ * Author : Art Yerkes
+ * Modified from mzscheme.cxx : David Beazley
+ *
+ * Please read the file LICENSE for the copyright and terms by which SWIG
+ * can be used and distributed.
+ *****************************************************************************/
+
+char cvsroot_ocaml_cxx[] = "$Header$";
+
+/***********************************************************************
+ * $Header$
+ *
+ * ocaml.cxx
+ *
+ * Definitions for adding functions to Ocaml 101
+ ***********************************************************************/
+
+#include "swigmod.h"
+
+#include
+
+static const char *ocaml_usage = (char*)"\
+\n\
+Ocaml Options (available with -ocaml)\n\
+-help - Print this help\n\
+-prefix name - Set a prefix to be appended to all names\n\
+\n";
+
+static int classmode = 0;
+static int in_constructor = 0, in_destructor = 0, in_copyconst = 0;
+static int const_enum = 0;
+static int static_member_function = 0;
+static char *prefix=0;
+static String *classname=0;
+static String *module=0;
+static char *ocaml_path=(char*)"ocaml";
+static String *init_func_def = 0;
+
+static Hash *seen_enums = 0;
+static Hash *seen_enumvalues = 0;
+static Hash *seen_constructors = 0;
+
+static File *f_header = 0;
+static File *f_runtime = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+static File *f_mlout = 0;
+static File *f_mliout = 0;
+static File *f_mlbody = 0;
+static File *f_mlibody = 0;
+static File *f_enumtypes_type = 0;
+static File *f_enumtypes_value = 0;
+static File *f_class_ctors = 0;
+static File *f_class_ctors_end = 0;
+static File *f_enum_to_int = 0;
+static File *f_int_to_enum = 0;
+
+class OCAML : public Language {
+public:
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main (int argc, char *argv[]) {
+
+ int i;
+
+ SWIG_library_directory(ocaml_path);
+
+ // Look for certain command line options
+ for (i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp (argv[i], "-help") == 0) {
+ fputs (ocaml_usage, stderr);
+ SWIG_exit (0);
+ }
+ else if (strcmp (argv[i], "-prefix") == 0) {
+ if (argv[i + 1]) {
+ prefix = new char[strlen(argv[i + 1]) + 2];
+ strcpy(prefix, argv[i + 1]);
+ Swig_mark_arg (i);
+ Swig_mark_arg (i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ }
+ }
+ }
+
+ // If a prefix has been specified make sure it ends in a '_'
+
+ if (prefix) {
+ if (prefix[strlen (prefix)] != '_') {
+ prefix[strlen (prefix) + 1] = 0;
+ prefix[strlen (prefix)] = '_';
+ }
+ } else
+ prefix = (char*)"swig_";
+
+ // Add a symbol for this module
+
+ Preprocessor_define ("SWIGOCAML 1",0);
+
+ // Set name of typemaps
+
+ SWIG_typemap_lang("ocaml");
+
+ // Read in default typemaps */
+ SWIG_config_file("ocaml.i");
+ allow_overloading();
+
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
+
+ f_runtime = NewFile(outfile,"w");
+ if (!f_runtime) {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+ f_enumtypes_type = NewString("");
+ f_enumtypes_value = NewString("");
+ f_mlbody = NewString("");
+ f_mlibody = NewString("");
+ f_class_ctors = NewString("");
+ f_class_ctors_end = NewString("");
+ f_enum_to_int = NewString("");
+ f_int_to_enum = NewString("");
+
+ module = Getattr(n,"name");
+
+ seen_constructors = NewHash();
+ seen_enums = NewHash();
+ seen_enumvalues = NewHash();
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header",f_header);
+ Swig_register_filebyname("wrapper",f_wrappers);
+ Swig_register_filebyname("runtime",f_runtime);
+ Swig_register_filebyname("mli",f_mlibody);
+ Swig_register_filebyname("ml",f_mlbody);
+
+ init_func_def = NewString("");
+ Swig_register_filebyname("init",init_func_def);
+
+ Swig_name_register("set","%v__set__");
+ Swig_name_register("get","%v__get__");
+
+ Printf(f_runtime,
+ "/* -*- buffer-read-only: t -*- vi: set ro: */\n");
+ Printf( f_runtime, "#define SWIG_MODULE \"%s\"\n", module );
+ /* Module name */
+ Printf( f_mlbody, "let module_name = \"%s\"\n", module );
+ Printf( f_mlibody, "val module_name : string\n" );
+ Printf( f_enum_to_int,
+ "let enum_to_int x v =\n"
+ " match v with C_enum y -> (\n"
+ " match (x : c_enum_type) with\n"
+ " `unknown -> (match (y : c_enum_tag) with\n"
+ " `int (x : int) -> C_int x\n"
+ " | _ -> (raise (LabelNotFromThisEnum v)))\n"
+ );
+
+ Printf( f_int_to_enum,
+ "let int_to_enum x y =\n"
+ " match (x : c_enum_type) with\n"
+ " `unknown -> C_enum (`int y)\n" );
+
+ Swig_banner (f_runtime);
+
+ if (NoInclude) {
+ Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
+ }
+
+ /* Produce the enum_to_int and int_to_enum functions */
+
+ Printf(f_enumtypes_type,"type c_enum_type = [ \n `unknown\n" );
+ Printf(f_enumtypes_value,"type c_enum_tag = [ \n `int of int\n" );
+
+ String *mlfile = NewString("");
+ String *mlifile = NewString("");
+
+ Printv(mlfile,module,".ml",NIL);
+ Printv(mlifile,module,".mli",NIL);
+
+ f_mlout = NewFile(mlfile,"w");
+ f_mliout = NewFile(mlifile,"w");
+
+ Language::top(n);
+
+ 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 -> c_obj\n" );
+
+ Printf( f_int_to_enum,
+ "let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n",
+ module );
+ Printf( f_mlibody,
+ "val int_to_enum : c_enum_type -> int -> c_obj\n" );
+ Printf( f_enumtypes_type, "]\n" );
+ Printf( f_enumtypes_value, "]\n" );
+
+ SwigType_emit_type_table (f_runtime, f_wrappers);
+ /* Close all of the files */
+ Dump(f_header,f_runtime);
+ Dump(f_wrappers,f_runtime);
+ Wrapper_pretty_print(f_init,f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_runtime);
+ Delete(f_runtime);
+
+ Dump(f_enumtypes_type,f_mlout);
+ Dump(f_enumtypes_value,f_mlout);
+ Dump(f_mlbody,f_mlout);
+ Dump(f_enum_to_int,f_mlout);
+ Dump(f_int_to_enum,f_mlout);
+ Delete(f_int_to_enum);
+ Delete(f_enum_to_int);
+ Dump(f_class_ctors,f_mlout);
+ Dump(f_class_ctors_end,f_mlout);
+ Close(f_mlout);
+ Delete(f_mlout);
+
+ Dump(f_enumtypes_type,f_mliout);
+ Dump(f_enumtypes_value,f_mliout);
+ Dump(f_mlibody,f_mliout);
+ Close(f_mliout);
+ Delete(f_mliout);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * Create a function declaration and register it with the interpreter.
+ * ------------------------------------------------------------ */
+
+ void throw_unhandled_ocaml_type_error (SwigType *d)
+ {
+ Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number,
+ "Unable to handle type %s.\n", SwigType_str(d,0));
+ }
+
+ /* Return true iff T is a pointer type */
+
+ int
+ is_a_pointer (SwigType *t)
+ {
+ return SwigType_ispointer(SwigType_typedef_resolve_all(t));
+ }
+
+ virtual int functionWrapper(Node *n) {
+ char *iname = GetChar(n,"sym:name");
+ SwigType *d = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+ Parm *p;
+
+ Wrapper *f = NewWrapper();
+ String *proc_name = NewString("");
+ String *source = NewString("");
+ String *target = NewString("");
+ String *arg = NewString("");
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *build = NewString("");
+ String *tm;
+ int argout_set = 0;
+ int i = 0;
+ int numargs;
+ int numreq;
+ int newobj = Getattr(n,"feature:new") ? 1 : 0;
+ String *overname = 0;
+
+ // Make a wrapper name for this
+ String *wname = Swig_name_wrapper(iname);
+ if (Getattr(n,"sym:overloaded")) {
+ overname = Getattr(n,"sym:overname");
+ } else {
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+ }
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n,"wrap:name",wname);
+
+ // Build the name for Scheme.
+ Printv(proc_name,"_",iname,NIL);
+ String *mangled_name = mangleNameForCaml(proc_name);
+
+ if( classmode && in_constructor ) { // 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 ) {
+ String *opname = Copy(Getattr(n,"name"));
+
+ Replaceall(opname,"operator ","");
+
+ if( strstr( Char(mangled_name), "__get__" ) ) {
+ String *set_name = Copy(mangled_name);
+ if( !Getattr(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);
+ }
+
+ Delete(opname);
+ }
+
+ if( classmode && in_constructor ) {
+ Setattr(seen_constructors,mangled_name,"true");
+ }
+
+ // writing the function wrapper function
+ Printv(f->def,
+ "#ifdef __cplusplus\n"
+ "extern \"C\"\n"
+ "#endif\n"
+ "value ", wname, " (", NIL);
+ Printv(f->def, "value args", NIL);
+ Printv(f->def, ")\n{", NIL);
+
+ /* Define the scheme name in C. This define is used by several
+ macros. */
+ Printv(f->def, "#define FUNC_NAME \"", mangled_name, "\"", NIL);
+
+ // adds local variables
+ Wrapper_add_local(f, "args", "CAMLparam1(args)");
+ Wrapper_add_local(f, "ret", "CAMLlocal2(swig_result,rv)");
+ Wrapper_add_local(f, "_len", "int _len");
+ Wrapper_add_local(f, "lenv", "int lenv = 1");
+ Wrapper_add_local(f, "argc", "int argc = caml_list_length(args)");
+ Wrapper_add_local(f, "argv", "value *argv");
+ Wrapper_add_local(f, "i", "int i");
+
+ Printv( f->code,
+ "argv = (value *)malloc( argc * sizeof( value ) );\n"
+ "for( i = 0; i < argc; i++ ) {\n"
+ " argv[i] = caml_list_nth(args,i);\n"
+ "}\n", NIL );
+
+ // Declare return variable and arguments
+ // number of parameters
+ // they are called arg0, arg1, ...
+ // the return value is called result
+
+ emit_args(d, l, f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l,f);
+ Setattr(n,"wrap:parms",l);
+
+ numargs = emit_num_arguments(l);
+ numreq = emit_num_required(l);
+
+ Printf(f->code,"swig_result = Val_unit;\n" );
+
+ // Now write code to extract the parameters (this is super ugly)
+
+ for (i = 0, p = l; i < numargs; i++) {
+ /* Skip ignored arguments */
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *ln = Getattr(p,"lname");
+
+ // Produce names of source and target
+ Clear(source);
+ Clear(target);
+ Clear(arg);
+ Printf(source, "caml_list_nth(args,%d)", i);
+ Printf(target, "%s",ln);
+ Printv(arg, Getattr(p,"name"),NIL);
+
+ if (i >= numreq) {
+ Printf(f->code,"if (caml_list_length(args) > %d) {\n",i);
+ }
+ // Handle parameter types.
+ if ((tm = Getattr(p,"tmap:in"))) {
+ Replaceall(tm,"$source",source);
+ Replaceall(tm,"$target",target);
+ Replaceall(tm,"$input",source);
+ Setattr(p,"emit:input",source);
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ // no typemap found
+ // check if typedef and resolve
+ throw_unhandled_ocaml_type_error (pt);
+ p = nextSibling(p);
+ }
+ if (i >= numreq) {
+ Printf(f->code,"}\n");
+ }
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:check"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Pass output arguments back to the caller.
+
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:argout"))) {
+ Replaceall(tm,"$source",Getattr(p,"emit:input")); /* Deprecated */
+ Replaceall(tm,"$target",Getattr(p,"lname")); /* Deprecated */
+ Replaceall(tm,"$arg",Getattr(p,"emit:input"));
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(outarg,tm,"\n",NIL);
+ p = Getattr(p,"tmap:argout:next");
+ argout_set = 1;
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Free up any memory allocated for the arguments.
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:freearg"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(cleanup,tm,"\n",NIL);
+ p = Getattr(p,"tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Now write code to make the function call
+
+ emit_action(n,f);
+
+ // Now have return value, figure out what to do with it.
+
+ if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Replaceall(tm,"$target","rv");
+ Replaceall(tm,"$result","rv");
+ Printv(f->code, tm, "\n",NIL);
+ } else {
+ throw_unhandled_ocaml_type_error (d);
+ }
+
+ // Dump the argument output code
+ Printv(f->code, Char(outarg),NIL);
+
+ // Dump the argument cleanup code
+ Printv(f->code, Char(cleanup),NIL);
+
+ // Look for any remaining cleanup
+
+ if (Getattr(n,"feature:new")) {
+ if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printv(f->code, tm, "\n",NIL);
+ }
+ }
+
+ // Free any memory allocated by the function being wrapped..
+
+ if ((tm = Swig_typemap_lookup_new("swig_result",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printv(f->code, tm, "\n",NIL);
+ }
+
+ // Wrap things up (in a manner of speaking)
+
+ Printv(f->code,
+ tab4, "swig_result = caml_list_append(swig_result,rv);\n"
+ tab4, "free( argv );\n"
+ tab4, "if( lenv == 0 )\n"
+ tab4, "{\n"
+ tab4, tab4, "CAMLreturn(Val_unit);\n",
+ tab4, "}\n"
+ tab4, "else\n"
+ tab4, "{\n",
+ tab4, tab4, "CAMLreturn(swig_result);\n",
+ tab4, "}\n", NIL);
+ Printf(f->code, "#undef FUNC_NAME\n");
+ Printv(f->code, "}\n",NIL);
+
+ Wrapper_print(f, f_wrappers);
+
+ if( Getattr(n,"sym:overloaded") ) {
+ if( !Getattr(n,"sym:nextSibling") ) {
+ int maxargs;
+ Wrapper *df = NewWrapper();
+ String *dname = Swig_name_wrapper(iname);
+ String *dispatch =
+ Swig_overload_dispatch(n,
+ "free(argv);\nCAMLreturn(%s(args));\n",
+ &maxargs);
+
+ Wrapper_add_local(df, "argv", "value *argv");
+
+ Printv(df->def,
+ "#ifdef __cplusplus\n"
+ "extern \"C\"\n"
+ "#endif\n"
+ "value ",dname,"(value args) {\n"
+ " CAMLparam1(args);\n"
+ " int i;\n"
+ " int argc = caml_list_length(args);\n",NIL);
+ Printv( df->code,
+ "argv = (value *)malloc( argc * sizeof( 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,"}\n",NIL);
+ Wrapper_print(df,f_wrappers);
+
+ Printf(f_mlbody,
+ "external %s_f : c_obj list -> c_obj list = \"%s\"\n"
+ "let %s = fnhelper %s %s_f\n",
+ mangled_name, dname, mangled_name,
+ newobj ? "true" : "false",
+ mangled_name );
+ if( !classmode || in_constructor || in_destructor ||
+ static_member_function )
+ Printf(f_mlibody,
+ "(* overload *)\n"
+ "val %s : c_obj -> c_obj\n", mangled_name );
+
+ DelWrapper(df);
+ Delete(dispatch);
+ Delete(dname);
+ }
+ } else {
+ Printf(f_mlbody,
+ "external %s_f : c_obj list -> c_obj list = \"%s\"\n"
+ "let %s = fnhelper %s %s_f\n",
+ mangled_name, wname, mangled_name, newobj ? "true" : "false",
+ mangled_name );
+ if( !classmode || in_constructor || in_destructor ||
+ static_member_function )
+ Printf(f_mlibody,
+ "(* Non-overload *)\n"
+ "val %s : c_obj -> c_obj\n", mangled_name );
+ }
+
+ Delete(proc_name);
+ Delete(source);
+ Delete(target);
+ Delete(arg);
+ Delete(outarg);
+ Delete(cleanup);
+ Delete(build);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ *
+ * Create a link to a C variable.
+ * This creates a single function _wrap_swig_var_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. Either way, we return the variables
+ * value.
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+
+ char *name = GetChar(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ String *mname = mangleNameForCaml(iname);
+ SwigType *t = Getattr(n,"type");
+
+ String *proc_name = NewString("");
+ char var_name[256];
+ String *tm;
+ String *tm2 = NewString("");;
+ String *argnum = NewString("0");
+ String *arg = NewString("Field(args,0)");
+ Wrapper *f;
+
+ if (!iname || !addSymbol(iname,n)) return SWIG_ERROR;
+
+ f = NewWrapper();
+
+ // evaluation function names
+
+ strcpy(var_name, Char(Swig_name_wrapper(iname)));
+
+ // Build the name for scheme.
+ Printv(proc_name, iname,NIL);
+ //Replaceall(proc_name, "_", "-");
+
+ if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) {
+
+ Printf (f->def,
+ "#ifdef __cplusplus\n"
+ "extern \"C\"\n"
+ "#endif\n"
+ "value %s(value args) {\n", var_name);
+ Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
+
+ Wrapper_add_local (f, "swig_result", "value swig_result");
+
+ if (!Getattr(n,"feature:immutable")) {
+ /* Check for a setting of the variable value */
+ Printf (f->code, "if (args != Val_int(0)) {\n");
+ if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) {
+ Replaceall(tm,"$source","args");
+ Replaceall(tm,"$target",name);
+ Replaceall(tm,"$input","args");
+ Printv(f->code, tm, "\n",NIL);
+ } else {
+ throw_unhandled_ocaml_type_error (t);
+ }
+ Printf (f->code, "}\n");
+ }
+
+ // Now return the value of the variable (regardless
+ // of evaluating or setting)
+
+ if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) {
+ Replaceall(tm,"$source",name);
+ Replaceall(tm,"$target","swig_result");
+ Replaceall(tm,"$result","swig_result");
+ Printf (f->code, "%s\n", tm);
+ } else {
+ throw_unhandled_ocaml_type_error (t);
+ }
+
+ Printf (f->code, "\nreturn swig_result;\n");
+ Printf (f->code, "#undef FUNC_NAME\n");
+ Printf (f->code, "}\n");
+
+ Wrapper_print (f, f_wrappers);
+
+ // Now add symbol to the Ocaml interpreter
+
+ if( Getattr( n, "feature:immutable" ) ) {
+ Printf( f_mlbody,
+ "external __%s : c_obj -> c_obj = \"%s\"\n"
+ "let _%s = __%s C_void\n",
+ mname, var_name, mname, mname );
+ Printf( f_mlibody, "val _%s : c_obj\n", iname );
+ if( const_enum ) {
+ Printf( f_enum_to_int,
+ " | `%s -> _%s\n",
+ mname, mname );
+ Printf( f_int_to_enum,
+ " if y = (get_int _%s) then `%s else\n",
+ mname, mname );
+ }
+ } else {
+ Printf( f_mlbody, "external _%s : c_obj -> c_obj = \"%s\"\n",
+ mname, var_name );
+ Printf( f_mlibody, "external _%s : c_obj -> c_obj = \"%s\"\n",
+ mname, var_name );
+ }
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number,
+ "Unsupported variable type %s (ignored).\n", SwigType_str(t,0));
+ }
+
+ Delete(proc_name);
+ Delete(argnum);
+ Delete(arg);
+ Delete(tm2);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmemberfunctionHandler --
+ * Overridden to set static_member_function
+ * ------------------------------------------------------------ */
+
+ virtual int staticmemberfunctionHandler( Node *n ) {
+ int rv;
+ static_member_function = 1;
+ rv = Language::staticmemberfunctionHandler( n );
+ static_member_function = 0;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ char *name = GetChar(n,"name");
+ char *iname = GetChar(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ String *value = Getattr(n,"value");
+
+ String *var_name = NewString("");
+ String *proc_name = NewString("");
+ String *rvalue = NewString("");
+ String *temp = NewString("");
+ String *tm;
+
+ // Make a static variable;
+
+ Printf (var_name, "_wrap_const_%s", Swig_name_mangle(iname));
+
+ // Build the name for scheme.
+ Printv(proc_name, iname,NIL);
+ //Replaceall(proc_name, "_", "-");
+
+ if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
+ "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+
+ // 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);
+ }
+ if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
+ Delete(temp);
+ temp = Copy(rvalue);
+ Clear(rvalue);
+ Printv(rvalue, "'", temp, "'",NIL);
+ }
+ if ((tm = Swig_typemap_lookup_new("constant",n,name,0))) {
+ Replaceall(tm,"$source",rvalue);
+ Replaceall(tm,"$value",rvalue);
+ Replaceall(tm,"$target",name);
+ Printf (f_init, "%s\n", tm);
+ } else {
+ // Create variable and assign it a value
+
+ Printf (f_header, "static %s = ", SwigType_lstr(type,var_name));
+ if ((SwigType_type(type) == T_STRING)) {
+ Printf (f_header, "\"%s\";\n", value);
+ } else if (SwigType_type(type) == T_CHAR) {
+ Printf (f_header, "\'%s\';\n", value);
+ } else {
+ Printf (f_header, "%s;\n", value);
+ }
+
+ {
+ /* Hack alert: will cleanup later -- Dave */
+ Node *n = NewHash();
+ Setattr(n,"name",var_name);
+ Setattr(n,"sym:name",iname);
+ Setattr(n,"type", type);
+ Setattr(n,"feature:immutable","1");
+ variableWrapper(n);
+ Delete(n);
+ }
+ }
+ Delete(proc_name);
+ Delete(rvalue);
+ Delete(temp);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * validIdentifer()
+ * ------------------------------------------------------------ */
+
+ virtual int validIdentifier(String *s) {
+#if 0
+ char *c = Char(s);
+ /* Check whether we have an R5RS identifier.*/
+ /* --> * | */
+ /* --> | */
+ if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~'))) {
+ /* --> + | - | ... */
+ if ((strcmp(c, "+") == 0)
+ || strcmp(c, "-") == 0
+ || strcmp(c, "...") == 0) return 1;
+ else return 0;
+ }
+ /* --> | | */
+ while (*c) {
+ if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+')
+ || (*c == '-') || (*c == '.') || (*c == '@'))) return 0;
+ c++;
+ }
+#endif
+ return 1;
+ }
+
+ int constructorHandler(Node *n) {
+ int ret;
+
+ in_constructor = 1;
+ ret = Language::constructorHandler(n);
+ in_constructor = 0;
+
+ return ret;
+ }
+
+ int destructorHandler(Node *n) {
+ int ret;
+
+ in_destructor = 1;
+ ret = Language::destructorHandler(n);
+ in_destructor = 0;
+
+ return ret;
+ }
+
+ int copyconstructorHandler(Node *n) {
+ int ret;
+
+ in_copyconst = 1;
+ in_constructor = 1;
+ ret = Language::copyconstructorHandler(n);
+ in_constructor = 0;
+ in_copyconst = 0;
+
+ return ret;
+ }
+
+ int classHandler( Node *n ) {
+ String *name = Getattr(n,"name");
+ String *mangled_sym_name = mangleNameForCaml(name);
+
+ if( !name ) return SWIG_OK;
+
+ classname = mangled_sym_name;
+
+ Printf( f_class_ctors,
+ "let create_%s_from_ptr raw_ptr =\n"
+ " C_obj (let rec method_table = [\n"
+ " \"nop\", (fun args -> C_void) ;\n",
+ classname );
+
+ Printf( f_mlibody,
+ "val create_%s_from_ptr : c_obj -> c_obj\n",
+ classname );
+
+ classmode = 1;
+ int rv = Language::classHandler(n);
+ classmode = 0;
+
+#if 0
+ Printf(f_mlibody,
+ "val delete_%s : c_obj -> unit\n",
+ mangled_sym_name );
+#endif
+
+ /* Handle up-casts in a nice way */
+ List *baselist = Getattr(n,"bases");
+ if (baselist && Len(baselist)) {
+ Node *base = Firstitem(baselist);
+ while (base) {
+ String *bname = Getattr(base, "ocaml:ctor");
+ if (bname)
+ Printv(f_class_ctors,
+ " \"::",bname,"\", (fun args -> "
+ "create_",bname,"_from_ptr raw_ptr) ;\n",NIL);
+
+ base = Nextitem(baselist);
+ }
+ }
+
+ Printf(f_class_ctors,
+ " \"&\", (fun args -> raw_ptr) ;\n"
+ " \":parents\",\n"
+ " (fun args -> \n"
+ " C_list \n"
+ " (List.map \n"
+ " (fun (x,y) -> \n"
+ " C_string (String.sub x 2 ((String.length x) - 2)))\n"
+ " (List.filter \n"
+ " (fun (x,y) -> \n"
+ " ((String.length x) > 2) && \n"
+ " x.[0] == ':' && \n"
+ " x.[1] == ':') method_table))) ;\n"
+ " \":classof\", (fun args -> (C_string \"%s\")) ;\n"
+ " \":methods\", "
+ "(fun args -> C_list (List.map (fun (x,y) -> C_string x) "
+ "method_table)) ] in\n"
+ " (fun mth arg ->\n"
+ " try\n"
+ " let method_name,application = List.hd (List.filter (fun (x,y) -> x = mth) method_table) in\n"
+ " application \n"
+ " (match arg with C_list l -> (C_list (raw_ptr :: l)) | C_void -> (C_list [ raw_ptr ]) | v -> (C_list [ raw_ptr ; v ]))\n"
+ " with (Failure \"hd\") -> \n"
+ " (* Try parent classes *)\n"
+ " begin\n"
+ " let parent_classes = [ \n",
+ name );
+
+ /* Handle inheritance -- Mostly stolen from python code */
+ baselist = Getattr(n,"bases");
+ if (baselist && Len(baselist)) {
+ Node *base = Firstitem(baselist);
+ while (base) {
+ String *bname = Getattr(base, "ocaml:ctor");
+ if (bname)
+ Printv(f_class_ctors,
+ " create_",bname,"_from_ptr",NIL);
+
+ base = Nextitem(baselist);
+ if (base)
+ Printv(f_class_ctors," ;\n",NIL);
+ else
+ Printv(f_class_ctors,"\n",NIL);
+ }
+ }
+
+ Printv(f_class_ctors," ]\n",NIL);
+
+ Printf(f_class_ctors,
+ " in let rec try_parent plist raw_ptr = \n"
+ " match plist with\n"
+ " p :: tl -> (try\n"
+ " (invoke (p raw_ptr)) mth arg\n"
+ " with (BadMethodName (p,m,s)) -> try_parent tl raw_ptr)\n"
+ " | [] ->\n"
+ " raise (BadMethodName (raw_ptr,mth,\"%s\"))\n"
+ " in try_parent parent_classes raw_ptr\n"
+ " end\n"
+ " | e -> raise e))\n",
+ name );
+
+ Printf( f_class_ctors,
+ "let _ = Callback.register \"create_%s_from_ptr\" "
+ "create_%s_from_ptr\n",
+ classname, classname );
+
+ Setattr(n,"ocaml:ctor",classname);
+
+ return rv;
+ }
+
+ String *mangleNameForCaml( String *s ) {
+ String *out = Copy(s);
+ Replaceall(out," ","_");
+ Replaceall(out,"::","_");
+ Replaceall(out,",","_x_");
+ Replaceall(out,"+","__plus__");
+ Replaceall(out,"-","__minus__");
+ Replaceall(out,"<","__ldbrace__");
+ Replaceall(out,">","__rdbrace__");
+ Replaceall(out,"!","__not__");
+ Replaceall(out,"%","__mod__");
+ Replaceall(out,"^","__xor__");
+ Replaceall(out,"*","__star__");
+ Replaceall(out,"&","__amp__");
+ Replaceall(out,"|","__or__");
+ Replaceall(out,"(","__lparen__");
+ Replaceall(out,")","__rparen__");
+ Replaceall(out,"[","__lbrace__");
+ Replaceall(out,"]","__rbrace__");
+ Replaceall(out,"~","__bnot__");
+ Replaceall(out,"=","__equals__");
+ Replaceall(out,"/","__slash__");
+ Replaceall(out,".","__dot__");
+ return out;
+ }
+
+ /* Benedikt Grundmann inspired --> Enum wrap styles */
+
+ int enumvalueDeclaration(Node *n) {
+ String *name = Getattr(n,"name");
+
+ if( const_enum && name && !Getattr(seen_enumvalues,name) ) {
+ Printf( f_enumtypes_value,"| `%s\n", name );
+ Setattr(seen_enumvalues,name,"true");
+ Setattr(n,"feature:immutable","1");
+
+ return constantWrapper(n);
+ } else return SWIG_OK;
+ }
+
+ int enumDeclaration(Node *n) {
+ String *name = Getattr(n,"name");
+
+ if( name && !Getattr(seen_enums,name) ) {
+ const_enum = 1;
+ Printf( f_enum_to_int, "| `%s -> (match (y : c_enum_tag) with\n", name );
+ Printf( f_int_to_enum, "| `%s -> C_enum (\n", name );
+ Printf( f_mlbody,
+ "let _ = Callback.register \"%s_marker\" (`%s)\n",
+ name, name );
+ Printf( f_enumtypes_type,"| `%s\n", name );
+ Setattr(seen_enumvalues,name,"true");
+ }
+
+ int ret = Language::enumDeclaration(n);
+
+ if( const_enum ) {
+ Printf( f_int_to_enum, "`int y)\n", name );
+ Printf( f_enum_to_int,
+ "| `int (x : int) -> C_int x\n"
+ "| _ -> raise (Failure \"Unknown enum tag\"))\n" );
+ }
+
+ const_enum = 0;
+
+ return ret;
+ }
+};
+
+/* -------------------------------------------------------------------------
+ * swig_ocaml() - Instantiate module
+ * ------------------------------------------------------------------------- */
+
+extern "C" Language *
+swig_ocaml(void) {
+ return new OCAML();
+}
+
diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx
new file mode 100644
index 000000000..f62e63f93
--- /dev/null
+++ b/Source/Modules/overload.cxx
@@ -0,0 +1,338 @@
+/* -----------------------------------------------------------------------------
+ * overload.cxx
+ *
+ * This file is used to analyze overloaded functions and methods.
+ * It looks at signatures and tries to gather information for
+ * building a dispatch function.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1999-2000. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_overload_cxx[] = "$Header$";
+
+#include "swigmod.h"
+
+#define MAX_OVERLOAD 256
+
+extern int emit_num_required(ParmList *);
+
+/* -----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+struct Overloaded {
+ Node *n; /* Node */
+ int argc; /* Argument count */
+ ParmList *parms; /* Parameters used for overload check */
+ int error; /* Ambiguity error */
+};
+
+List *
+Swig_overload_rank(Node *n) {
+ 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")) {
+ 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 %s(%s) not supported (no type checking rule for '%s').\n",
+ Getattr(nodes[i].n,"name"),ParmList_str(Getattr(nodes[i].n,"parms")),
+ 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 %s(%s) not supported (no type checking rule for '%s').\n",
+ Getattr(nodes[j].n,"name"),ParmList_str(Getattr(nodes[j].n,"parms")),
+ 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 (t2 && !t1) 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)) {
+ SwigType_pop(dq1);
+ }
+ if (SwigType_isconst(d2)) {
+ SwigType_pop(dq2);
+ }
+ if (Strcmp(dq1,dq2) == 0) {
+
+ if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ differ = 1;
+ if (!nodes[j].error) {
+ Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n",
+ Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ }
+ nodes[j].error = 1;
+ } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) {
+ differ = 1;
+ if (!nodes[j].error) {
+ Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n",
+ Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ }
+ nodes[j].error = 1;
+ }
+ }
+ Delete(dq1);
+ Delete(dq2);
+ }
+ }
+ if (!differ) {
+ if (!nodes[j].error) {
+ Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded %s(%s) is shadowed by %s(%s) at %s:%d.\n",
+ Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms),
+ Getattr(nodes[i].n,"name"), ParmList_protostr(nodes[i].parms),
+ Getfile(nodes[i].n),Getline(nodes[i].n));
+ nodes[j].error = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ List *result = NewList();
+ {
+ int i;
+ for (i = 0; i < nnodes; i++) {
+ Append(result,nodes[i].n);
+ // Printf(stdout,"[ %d ] %s\n", i, ParmList_protostr(nodes[i].parms));
+ // Swig_print_node(nodes[i].n);
+ }
+ }
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_overload_dispatch()
+ *
+ * Generate a dispatch function. argc is assumed to hold the argument count.
+ * argv is the argument vector.
+ *
+ * Note that for C++ class member functions, Swig_overload_dispatch() assumes
+ * that argc includes the "self" argument and that the first element of argv[]
+ * is the "self" argument. So for a member function:
+ *
+ * Foo::bar(int x, int y, int z);
+ *
+ * the argc should be 4 (not 3!) and the first element of argv[] would be
+ * the appropriate scripting language reference to "self". For regular
+ * functions (and static class functions) the argc and argv only include
+ * the regular function arguments.
+ * ----------------------------------------------------------------------------- */
+
+static bool print_typecheck(String *f, int j, Parm *pj)
+{
+ char tmp[256];
+ sprintf(tmp,"argv[%d]",j);
+ String *tm = Getattr(pj,"tmap:typecheck");
+ if (tm) {
+ Replaceid(tm,Getattr(pj,"lname"),"_v");
+ Replaceall(tm,"$input", tmp);
+ Printv(f,tm,"\n",NIL);
+ return true;
+ }
+ else
+ return false;
+}
+
+String *
+Swig_overload_dispatch(Node *n, const String_or_char *fmt, int *maxargs) {
+ int i,j;
+
+ *maxargs = 1;
+
+ String *f = NewString("");
+
+ /* Get a list of methods ranked by precedence values and argument count */
+ List *dispatch = Swig_overload_rank(n);
+ int nfunc = Len(dispatch);
+
+ /* Loop over the functions */
+
+ for (i = 0; i < nfunc; i++) {
+ Node *ni = Getitem(dispatch,i);
+ Parm *pi = Getattr(ni,"wrap:parms");
+ int num_required = emit_num_required(pi);
+ int num_arguments = emit_num_arguments(pi);
+ if (num_arguments > *maxargs) *maxargs = num_arguments;
+ int varargs = emit_isvarargs(pi);
+
+ if (!varargs) {
+ if (num_required == num_arguments) {
+ Printf(f,"if (argc == %d) {\n", num_required);
+ } else {
+ Printf(f,"if ((argc >= %d) && (argc <= %d)) {\n", num_required, num_arguments);
+ }
+ } else {
+ Printf(f,"if (argc >= %d) {\n", num_required);
+ }
+
+ if (num_arguments) {
+ Printf(f,"int _v;\n");
+ }
+
+ int num_braces = 0;
+ j = 0;
+ Parm *pj = pi;
+ while (pj) {
+ if (checkAttribute(pj,"tmap:in:numinputs","0")) {
+ pj = Getattr(pj,"tmap:in:next");
+ continue;
+ }
+ if (j >= num_required) {
+ Printf(f, "if (argc <= %d) {\n", j);
+ Printf(f, Char(fmt),Getattr(ni,"wrap:name"));
+ Printf(f, "}\n");
+ }
+ if (print_typecheck(f, j, pj)) {
+ Printf(f, "if (_v) {\n");
+ num_braces++;
+ }
+ Parm *pk = Getattr(pj,"tmap:in:next");
+ if (pk) pj = pk;
+ else pj = nextSibling(pj);
+ j++;
+ }
+ Printf(f, Char(fmt),Getattr(ni,"wrap:name"));
+ /* close braces */
+ for (/* empty */; num_braces > 0; num_braces--)
+ Printf(f, "}\n");
+ Printf(f,"}\n"); /* braces closes "if" for this method */
+ }
+ Delete(dispatch);
+ return f;
+}
+
+
diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx
new file mode 100644
index 000000000..94191080d
--- /dev/null
+++ b/Source/Modules/perl5.cxx
@@ -0,0 +1,1594 @@
+/* ----------------------------------------------------------------------------
+ * perl5.cxx
+ *
+ * Generate Perl5 wrappers
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ * Loic Dachary (loic@ceic.com)
+ * David Fletcher
+ * Gary Holt
+ * Jason Stewart (jason@openinformatics.com)
+ *
+ * Copyright (C) 1999-2000. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ------------------------------------------------------------------------- */
+
+char cvsroot_perl5_cxx[] = "$Header$";
+
+#include "swigmod.h"
+
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+
+static const char *usage = (char*)"\
+Perl5 Options (available with -perl5)\n\
+ -ldflags - Print runtime libraries to link with\n\
+ -static - Omit code related to dynamic loading.\n\
+ -nopm - Do not generate the .pm file.\n\
+ -proxy - Create proxy classes.\n\
+ -const - Wrap constants as constants and not variables (implies -shadow).\n\
+ -compat - Compatibility mode.\n\n";
+
+static int compat = 0;
+
+static int no_pmfile = 0;
+
+static int export_all = 0;
+
+/*
+ * pmfile
+ * set by the -pm flag, overrides the name of the .pm file
+ */
+static String *pmfile = 0;
+
+/*
+ * module
+ * set by the %module directive, e.g. "Xerces". It will determine
+ * the name of the .pm file, and the dynamic library.
+ */
+static String *module = 0;
+
+/*
+ * fullmodule
+ * the fully namespace qualified name of the module, e.g. "XML::Xerces"
+ * it will be used to set the package namespace in the .pm file, as
+ * well as the name of the initialization methods in the glue library
+ */
+static String *fullmodule = 0;
+/*
+ * cmodule
+ * the namespace of the internal glue code, set to the value of
+ * module with a 'c' appended
+ */
+static String *cmodule = 0;
+
+static String *command_tab = 0;
+static String *constant_tab = 0;
+static String *variable_tab = 0;
+
+static File *f_runtime = 0;
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+static File *f_pm = 0;
+static String *pm; /* Package initialization code */
+static String *magic; /* Magic variable wrappers */
+
+static int is_static = 0;
+
+/* The following variables are used to manage Perl5 classes */
+
+static int blessed = 0; /* Enable object oriented features */
+static int do_constants = 0; /* Constant wrapping */
+static List *classlist = 0; /* List of classes */
+static int have_constructor = 0;
+static int have_destructor= 0;
+static int have_data_members = 0;
+static String *class_name = 0; /* Name of the class (what Perl thinks it is) */
+static String *real_classname = 0; /* Real name of C/C++ class */
+static String *fullclassname = 0;
+
+static String *pcode = 0; /* Perl code associated with each class */
+static String *blessedmembers = 0; /* Member data associated with each class */
+static int member_func = 0; /* Set to 1 when wrapping a member function */
+static String *func_stubs = 0; /* Function stubs */
+static String *const_stubs = 0; /* Constant stubs */
+static int num_consts = 0; /* Number of constants */
+static String *var_stubs = 0; /* Variable stubs */
+static String *exported = 0; /* Exported symbols */
+static String *pragma_include = 0;
+static Hash *operators = 0;
+static int have_operators = 0;
+
+class PERL5 : public Language {
+public:
+
+ /* Test to see if a type corresponds to something wrapped with a shadow class */
+ Node *is_shadow(SwigType *t) {
+ Node *n;
+ n = classLookup(t);
+ /* Printf(stdout,"'%s' --> '%x'\n", t, n); */
+ if (n) {
+ if (!Getattr(n,"perl5:proxy")) {
+ setclassname(n);
+ }
+ return Getattr(n,"perl5:proxy");
+ }
+ return 0;
+ }
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+ int i = 1;
+
+ SWIG_library_directory("perl5");
+ for (i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if(strcmp(argv[i],"-package") == 0) {
+ Printf(stderr,"*** -package is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n");
+ SWIG_exit(EXIT_FAILURE);
+ } else if(strcmp(argv[i],"-interface") == 0) {
+ Printf(stderr,"*** -interface is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n");
+ SWIG_exit(EXIT_FAILURE);
+ } else if (strcmp(argv[i],"-exportall") == 0) {
+ export_all = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-static") == 0) {
+ is_static = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i],"-shadow") == 0) || ((strcmp(argv[i],"-proxy") == 0))) {
+ blessed = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-const") == 0) {
+ do_constants = 1;
+ blessed = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-nopm") == 0) {
+ no_pmfile = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-pm") == 0) {
+ Swig_mark_arg(i);
+ i++;
+ pmfile = NewString(argv[i]);
+ 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,stderr);
+ } else if (strcmp (argv[i], "-ldflags") == 0) {
+ printf("%s\n", SWIG_PERL_RUNTIME);
+ SWIG_exit (EXIT_SUCCESS);
+ }
+ }
+ }
+
+ Preprocessor_define("SWIGPERL 1", 0);
+ Preprocessor_define("SWIGPERL5 1", 0);
+ SWIG_typemap_lang("perl5");
+ SWIG_config_file("perl5.swg");
+ allow_overloading();
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
+
+ f_runtime = NewFile(outfile,"w");
+ if (!f_runtime) {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header",f_header);
+ Swig_register_filebyname("wrapper",f_wrappers);
+ Swig_register_filebyname("runtime",f_runtime);
+ Swig_register_filebyname("init",f_init);
+
+ classlist = NewList();
+
+ pm = NewString("");
+ func_stubs = NewString("");
+ var_stubs = NewString("");
+ const_stubs = NewString("");
+ exported = NewString("");
+ magic = NewString("");
+ pragma_include = NewString("");
+
+ command_tab = NewString("static swig_command_info swig_commands[] = {\n");
+ constant_tab = NewString("static swig_constant_info swig_constants[] = {\n");
+ variable_tab = NewString("static swig_variable_info swig_variables[] = {\n");
+
+ Swig_banner(f_runtime);
+
+ if (NoInclude) {
+ Printf(f_runtime,"#define SWIG_NOINCLUDE\n");
+ }
+
+ module = Copy(Getattr(n,"name"));
+
+ /* If we're in blessed mode, change the package name to "packagec" */
+
+ if (blessed) {
+ cmodule = NewStringf("%sc",module);
+ } else {
+ cmodule = NewString(module);
+ }
+ fullmodule = NewString(module);
+
+ /* Create a .pm file
+ * Need to strip off any prefixes that might be found in
+ * the module name */
+
+ if (no_pmfile) {
+ f_pm = NewString(0);
+ } else {
+ if (pmfile == NULL) {
+ char *m = Char(module) + Len(module);
+ while (m != Char(module)) {
+ if (*m == ':') {
+ m++;
+ break;
+ }
+ m--;
+ }
+ pmfile = NewStringf("%s.pm", m);
+ }
+ String *filen = NewStringf("%s%s", Swig_file_dirname(outfile),pmfile);
+ if ((f_pm = NewFile(filen,"w")) == 0) {
+ Printf(stderr,"Unable to open %s\n", filen);
+ SWIG_exit (EXIT_FAILURE);
+ }
+ Swig_register_filebyname("pm",f_pm);
+ }
+ {
+ String *tmp = NewString(fullmodule);
+ Replaceall(tmp,":","_");
+ Printf(f_header,"#define SWIG_init boot_%s\n\n", tmp);
+ Printf(f_header,"#define SWIG_name \"%s::boot_%s\"\n", cmodule, tmp);
+ Printf(f_header,"#define SWIG_prefix \"%s::\"\n", cmodule);
+ Delete(tmp);
+ }
+
+ Printf(f_pm,"# This file was automatically generated by SWIG\n");
+ Printf(f_pm,"package %s;\n",fullmodule);
+
+ Printf(f_pm,"require Exporter;\n");
+ if (!is_static) {
+ Printf(f_pm,"require DynaLoader;\n");
+ Printf(f_pm,"@ISA = qw(Exporter DynaLoader);\n");
+ } else {
+ Printf(f_pm,"@ISA = qw(Exporter);\n");
+ }
+
+ /* Start creating magic code */
+
+ Printv(magic,
+ "#ifdef PERL_OBJECT\n",
+ "#define MAGIC_CLASS _wrap_", module, "_var::\n",
+ "class _wrap_", module, "_var : public CPerlObj {\n",
+ "public:\n",
+ "#else\n",
+ "#define MAGIC_CLASS\n",
+ "#endif\n",
+ "SWIGCLASS_STATIC int swig_magic_readonly(pTHX_ SV *sv, MAGIC *mg) {\n",
+ tab4, "MAGIC_PPERL\n",
+ tab4, "sv = sv; mg = mg;\n",
+ tab4, "croak(\"Value is read-only.\");\n",
+ tab4, "return 0;\n",
+ "}\n",
+ NIL);
+
+ Printf(f_wrappers,"#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
+
+ /* emit wrappers */
+ Language::top(n);
+
+ String *base = NewString("");
+
+ /* Dump out variable wrappers */
+
+ Printv(magic,
+ "\n\n#ifdef PERL_OBJECT\n",
+ "};\n",
+ "#endif\n",
+ NIL);
+
+ Printf(f_header,"%s\n", magic);
+
+ String *type_table = NewString("");
+ SwigType_emit_type_table(f_runtime,type_table);
+
+ /* Patch the type table to reflect the names used by shadow classes */
+ if (blessed) {
+ Node *cls;
+ for (cls = Firstitem(classlist); cls; cls = Nextitem(classlist)) {
+ if (Getattr(cls,"perl5:proxy")) {
+ SwigType *type = Copy(Getattr(cls,"classtype"));
+ SwigType_add_pointer(type);
+ String *mangle = NewStringf("\"%s\"", SwigType_manglestr(type));
+ String *rep = NewStringf("\"%s\"", Getattr(cls,"perl5:proxy"));
+ Replaceall(type_table,mangle,rep);
+ Delete(mangle);
+ Delete(rep);
+ Delete(type);
+ }
+ }
+ }
+
+ Printf(f_wrappers,"%s",type_table);
+ Delete(type_table);
+
+ Printf(constant_tab,"{0}\n};\n");
+ Printv(f_wrappers,constant_tab,NIL);
+
+ Printf(f_wrappers,"#ifdef __cplusplus\n}\n#endif\n");
+
+ Printf(f_init,"\t ST(0) = &PL_sv_yes;\n");
+ Printf(f_init,"\t XSRETURN(1);\n");
+ Printf(f_init,"}\n");
+
+ /* Finish off tables */
+ Printf(variable_tab, "{0}\n};\n");
+ Printv(f_wrappers,variable_tab,NIL);
+
+ Printf(command_tab,"{0,0}\n};\n");
+ Printv(f_wrappers,command_tab,NIL);
+
+
+ Printf(f_pm,"package %s;\n", cmodule);
+
+ if (!is_static) {
+ Printf(f_pm,"bootstrap %s;\n", fullmodule);
+ } else {
+ String *tmp = NewString(fullmodule);
+ Replaceall(tmp,":","_");
+ Printf(f_pm,"boot_%s();\n", tmp);
+ Delete(tmp);
+ }
+ Printf(f_pm,"%s",pragma_include);
+ Printf(f_pm,"package %s;\n", fullmodule);
+ Printf(f_pm,"@EXPORT = qw( %s);\n",exported);
+
+ if (blessed) {
+
+ Printv(base,
+ "\n# ---------- BASE METHODS -------------\n\n",
+ "package ", fullmodule, ";\n\n",
+ NIL);
+
+ /* Write out the TIE method */
+
+ Printv(base,
+ "sub TIEHASH {\n",
+ tab4, "my ($classname,$obj) = @_;\n",
+ tab4, "return bless $obj, $classname;\n",
+ "}\n\n",
+ NIL);
+
+ /* Output a CLEAR method. This is just a place-holder, but by providing it we
+ * can make declarations such as
+ * %$u = ( x => 2, y=>3, z =>4 );
+ *
+ * Where x,y,z are the members of some C/C++ object. */
+
+ Printf(base,"sub CLEAR { }\n\n");
+
+ /* Output default firstkey/nextkey methods */
+
+ Printf(base, "sub FIRSTKEY { }\n\n");
+ Printf(base, "sub NEXTKEY { }\n\n");
+
+ /* Output a 'this' method */
+
+ Printv(base,
+ "sub this {\n",
+ tab4, "my $ptr = shift;\n",
+ tab4, "return tied(%$ptr);\n",
+ "}\n\n",
+ NIL);
+
+ Printf(f_pm,"%s",base);
+
+ /* Emit function stubs for stand-alone functions */
+
+ Printf(f_pm,"\n# ------- FUNCTION WRAPPERS --------\n\n");
+ Printf(f_pm,"package %s;\n\n",fullmodule);
+ Printf(f_pm,"%s",func_stubs);
+
+ /* Emit package code for different classes */
+ Printf(f_pm,"%s",pm);
+
+ if (num_consts > 0) {
+ /* Emit constant stubs */
+ Printf(f_pm,"\n# ------- CONSTANT STUBS -------\n\n");
+ Printf(f_pm,"package %s;\n\n",fullmodule);
+ Printf(f_pm,"%s",const_stubs);
+ }
+
+ /* Emit variable stubs */
+
+ Printf(f_pm,"\n# ------- VARIABLE STUBS --------\n\n");
+ Printf(f_pm,"package %s;\n\n",fullmodule);
+ Printf(f_pm,"%s",var_stubs);
+ }
+
+ Printf(f_pm,"1;\n");
+ Close(f_pm);
+ Delete(f_pm);
+ Delete(base);
+
+ /* Close all of the files */
+ Dump(f_header,f_runtime);
+ Dump(f_wrappers,f_runtime);
+ Wrapper_pretty_print(f_init,f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_runtime);
+ Delete(f_runtime);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * importDirective(Node *n)
+ * ------------------------------------------------------------ */
+
+ virtual int importDirective(Node *n) {
+ if (blessed) {
+ String *modname = Getattr(n,"module");
+ if (modname) {
+ Printf(f_pm,"require %s;\n", modname);
+ }
+ }
+ return Language::importDirective(n);
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int functionWrapper(Node *n) {
+ String *name = Getattr(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ SwigType *d = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+ String *overname = 0;
+
+ Parm *p;
+ int i;
+ Wrapper *f;
+ char source[256],target[256],temp[256];
+ String *tm;
+ String *cleanup, *outarg;
+ int num_saved = 0;
+ int num_arguments, num_required;
+ int varargs = 0;
+
+ if (Getattr(n,"sym:overloaded")) {
+ overname = Getattr(n,"sym:overname");
+ } else {
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+ }
+
+ f = NewWrapper();
+ cleanup = NewString("");
+ outarg = NewString("");
+
+ String *wname = Swig_name_wrapper(iname);
+ if (overname) {
+ Append(wname,overname);
+ }
+ Setattr(n,"wrap:name",wname);
+ Printv(f->def, "XS(", wname, ") {\n", NIL);
+ Printv(f->def, "char _swigmsg[SWIG_MAX_ERRMSG] = \"\";\n", NIL);
+ Printv(f->def, "const char *_swigerr = _swigmsg;\n","{\n",NIL);
+
+ emit_args(d, l, f);
+ emit_attach_parmmaps(l,f);
+ Setattr(n,"wrap:parms",l);
+
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+ varargs = emit_isvarargs(l);
+
+ Wrapper_add_local(f,"argvi","int argvi = 0");
+
+ /* Check the number of arguments */
+ if (!varargs) {
+ Printf(f->code," if ((items < %d) || (items > %d)) {\n", num_required, num_arguments);
+ } else {
+ Printf(f->code," if (items < %d) {\n", num_required);
+ }
+ Printf(f->code," SWIG_croak(\"Usage: %s\");\n", usage_func(Char(iname),d,l));
+ Printf(f->code,"}\n");
+
+ /* Write code to extract parameters. */
+ i = 0;
+ for (i = 0, p = l; i < num_arguments; i++) {
+
+ /* Skip ignored arguments */
+
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *ln = Getattr(p,"lname");
+
+ /* Produce string representation of source and target arguments */
+ sprintf(source,"ST(%d)",i);
+ sprintf(target,"%s", Char(ln));
+
+ if (i >= num_required) {
+ Printf(f->code," if (items > %d) {\n", i);
+ }
+ if ((tm = Getattr(p,"tmap:in"))) {
+ Replaceall(tm,"$target",target);
+ Replaceall(tm,"$source",source);
+ Replaceall(tm,"$input", source);
+ Setattr(p,"emit:input",source); /* Save input location */
+ Printf(f->code,"%s\n",tm);
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument.\n",SwigType_str(pt,0));
+ p = nextSibling(p);
+ }
+ if (i >= num_required) {
+ Printf(f->code," }\n");
+ }
+ }
+
+ if (varargs) {
+ if (p && (tm = Getattr(p,"tmap:in"))) {
+ sprintf(source,"ST(%d)",i);
+ Replaceall(tm,"$input", source);
+ Setattr(p,"emit:input", source);
+ Printf(f->code,"if (items >= %d) {\n", i);
+ Printv(f->code, tm, "\n", NIL);
+ Printf(f->code,"}\n");
+ }
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:check"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (i = 0, p = l; p; i++) {
+ if ((tm = Getattr(p,"tmap:freearg"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Replaceall(tm,"$arg",Getattr(p,"emit:input"));
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(cleanup,tm,"\n",NIL);
+ p = Getattr(p,"tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ num_saved = 0;
+ for (i=0,p = l; p;i++) {
+ if ((tm = Getattr(p,"tmap:argout"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Replaceall(tm,"$target","ST(argvi)");
+ Replaceall(tm,"$result","ST(argvi)");
+ String *in = Getattr(p,"emit:input");
+ if (in) {
+ sprintf(temp,"_saved[%d]", num_saved);
+ Replaceall(tm,"$arg",temp);
+ Replaceall(tm,"$input",temp);
+ Printf(f->code,"_saved[%d] = %s;\n", num_saved, in);
+ num_saved++;
+ }
+ Printv(outarg,tm,"\n",NIL);
+ p = Getattr(p,"tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* If there were any saved arguments, emit a local variable for them */
+ if (num_saved) {
+ sprintf(temp,"_saved[%d]",num_saved);
+ Wrapper_add_localv(f,"_saved","SV *",temp,NIL);
+ }
+
+ /* Now write code to make the function call */
+
+ emit_action(n,f);
+
+ if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Replaceall(tm,"$target","ST(argvi)");
+ Replaceall(tm,"$result", "ST(argvi)");
+ Printf(f->code, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s in function %s.\n", SwigType_str(d,0), name);
+ }
+
+ /* If there were any output args, take care of them. */
+
+ Printv(f->code,outarg,NIL);
+
+ /* If there was any cleanup, do that. */
+
+ Printv(f->code,cleanup,NIL);
+
+ if (Getattr(n,"feature:new")) {
+ if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printf(f->code,"%s\n",tm);
+ }
+ }
+
+ if ((tm = Swig_typemap_lookup_new("ret",n,"result", 0))) {
+ Replaceall(tm,"$source","result");
+ Printf(f->code,"%s\n", tm);
+ }
+
+ Printf(f->code," XSRETURN(argvi);\n");
+ Printf(f->code,"fail:\n");
+ Printv(f->code,cleanup,NIL);
+ Printv(f->code,"(void) _swigerr;\n", NIL);
+ Printv(f->code,"}\n",NIL);
+ Printv(f->code,"croak(_swigerr);\n", NIL);
+ Printv(f->code,"}\n",NIL);
+
+ /* Add the dXSARGS last */
+
+ Wrapper_add_local(f,"dXSARGS","dXSARGS");
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code,"$cleanup",cleanup);
+ Replaceall(f->code,"$symname",iname);
+
+ /* Dump the wrapper function */
+
+ Wrapper_print(f,f_wrappers);
+
+ /* Now register the function */
+
+ if (!Getattr(n,"sym:overloaded")) {
+ Printf(command_tab,"{\"%s::%s\", %s},\n", cmodule, iname, wname);
+ } else if (!Getattr(n,"sym:nextSibling")) {
+ /* Generate overloaded dispatch function */
+ int maxargs, ii;
+ String *dispatch = Swig_overload_dispatch(n,"(*PL_markstack_ptr++);SWIG_CALLXS(%s); return;",&maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *df = NewWrapper();
+ String *dname = Swig_name_wrapper(iname);
+
+ Printv(df->def,
+ "XS(", dname, ") {\n", NIL);
+
+ Wrapper_add_local(df,"dXSARGS", "dXSARGS");
+ Replaceid(dispatch,"argc","items");
+ for (ii = 0; ii < maxargs; ii++) {
+ char pat[128];
+ char rep[128];
+ sprintf(pat,"argv[%d]",ii);
+ sprintf(rep,"ST(%d)",ii);
+ Replaceall(dispatch,pat,rep);
+ }
+ Printv(df->code,dispatch,"\n",NIL);
+ Printf(df->code,"croak(\"No matching function for overloaded '%s'\");\n", iname);
+ Printf(df->code,"XSRETURN(0);\n");
+ Printv(df->code,"}\n",NIL);
+ Wrapper_print(df,f_wrappers);
+ Printf(command_tab,"{\"%s::%s\", %s},\n", cmodule, iname, dname);
+ DelWrapper(df);
+ Delete(dispatch);
+ Delete(dname);
+ }
+ if (!Getattr(n,"sym:nextSibling")) {
+ if (export_all) {
+ Printf(exported,"%s ", iname);
+ }
+
+ /* --------------------------------------------------------------------
+ * Create a stub for this function, provided it's not a member function
+ * -------------------------------------------------------------------- */
+
+ if ((blessed) && (!member_func)) {
+ int need_stub = 0;
+ String *func = NewString("");
+
+ /* We'll make a stub since we may need it anyways */
+
+ Printv(func, "sub ", iname, " {\n",
+ tab4, "my @args = @_;\n",
+ NIL);
+
+ Printv(func, tab4, "my $result = ", cmodule, "::", iname, "(@args);\n", NIL);
+
+ /* Now check to see what kind of return result was found.
+ * If this function is returning a result by 'value', SWIG did an
+ * implicit malloc/new. We'll mark the object like it was created
+ * in Perl so we can garbage collect it. */
+
+ if (is_shadow(d)) {
+ Printv(func, tab4, "return undef if (!defined($result));\n", NIL);
+
+ /* If we're returning an object by value, put it's reference
+ into our local hash table */
+
+ if ((!SwigType_ispointer(d) && !SwigType_isreference(d)) || Getattr(n,"feature:new")) {
+ Printv(func, tab4, "$", is_shadow(d), "::OWNER{$result} = 1;\n", NIL);
+ }
+
+ /* We're returning a Perl "object" of some kind. Turn it into a tied hash */
+ Printv(func,
+ tab4, "my %resulthash;\n",
+ tab4, "tie %resulthash, ref($result), $result;\n",
+ tab4, "return bless \\%resulthash, ref($result);\n",
+ "}\n",
+ NIL);
+
+ need_stub = 1;
+ } else {
+ /* Hmmm. This doesn't appear to be anything I know about */
+ Printv(func, tab4, "return $result;\n", "}\n", NIL);
+ }
+
+ /* Now check if we needed the stub. If so, emit it, otherwise
+ * Emit code to hack Perl's symbol table instead */
+
+ if (need_stub) {
+ Printf(func_stubs,"%s",func);
+ } else {
+ Printv(func_stubs,"*", iname, " = *", cmodule, "::", iname, ";\n", NIL);
+ }
+ Delete(func);
+ }
+ }
+ Delete(cleanup);
+ Delete(outarg);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+ String *name = Getattr(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+ Wrapper *getf, *setf;
+ String *tm;
+
+ String *set_name = NewStringf("_wrap_set_%s", iname);
+ String *val_name = NewStringf("_wrap_val_%s", iname);
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ getf = NewWrapper();
+ setf = NewWrapper();
+
+ /* Create a Perl function for setting the variable value */
+
+ if (!Getattr(n,"feature:immutable")) {
+ Printf(setf->def,"SWIGCLASS_STATIC int %s(pTHX_ SV* sv, MAGIC *mg) {\n", set_name);
+ Printv(setf->code,
+ tab4, "MAGIC_PPERL\n",
+ tab4, "mg = mg;\n",
+ NIL);
+
+ /* Check for a few typemaps */
+ tm = Swig_typemap_lookup_new("varin",n,name,0);
+ if (tm) {
+ Replaceall(tm,"$source","sv");
+ Replaceall(tm,"$target",name);
+ Replaceall(tm,"$input","sv");
+ Printf(setf->code,"%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number,
+ "Unable to link with datatype %s (ignored).\n", SwigType_str(t,0));
+ return SWIG_NOWRAP;
+ }
+ Printf(setf->code," return 1;\n}\n");
+ Replaceall(setf->code,"$symname",iname);
+ Wrapper_print(setf,magic);
+ }
+
+ /* Now write a function to evaluate the variable */
+
+ Printf(getf->def,"SWIGCLASS_STATIC int %s(pTHX_ SV *sv, MAGIC *mg) {\n", val_name);
+ Printv(getf->code,
+ tab4, "MAGIC_PPERL\n",
+ tab4, "mg = mg;\n",
+ NIL);
+
+ if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) {
+ Replaceall(tm,"$target","sv");
+ Replaceall(tm,"$result","sv");
+ Replaceall(tm,"$source",name);
+ Printf(getf->code,"%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number,
+ "Unable to link with datatype %s (ignored).\n", SwigType_str(t,0));
+ return SWIG_NOWRAP;
+ }
+ Printf(getf->code," return 1;\n}\n");
+
+ Replaceall(getf->code,"$symname",iname);
+ Wrapper_print(getf,magic);
+
+ String *tt = Getattr(n,"tmap:varout:type");
+ if (tt) {
+ String *tm = NewStringf("&SWIGTYPE%s", SwigType_manglestr(t));
+ if (Replaceall(tt,"$1_descriptor", tm)) {
+ SwigType_remember(t);
+ }
+ Delete(tm);
+ SwigType *st = Copy(t);
+ SwigType_add_pointer(st);
+ tm = NewStringf("&SWIGTYPE%s", SwigType_manglestr(st));
+ if (Replaceall(tt,"$&1_descriptor", tm)) {
+ SwigType_remember(st);
+ }
+ Delete(tm);
+ Delete(st);
+ } else {
+ tt = (String *) "0";
+ }
+ /* Now add symbol to the PERL interpreter */
+ if (Getattr(n,"feature:immutable")) {
+ Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS swig_magic_readonly, MAGIC_CLASS ", val_name,",", tt, " },\n",NIL);
+
+ } else {
+ Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS ", set_name, ", MAGIC_CLASS ", val_name, ",", tt, " },\n",NIL);
+ }
+
+ /* If we're blessed, try to figure out what to do with the variable
+ 1. If it's a Perl object of some sort, create a tied-hash
+ around it.
+ 2. Otherwise, just hack Perl's symbol table */
+
+ if (blessed) {
+ if (is_shadow(t)) {
+ Printv(var_stubs,
+ "\nmy %__", iname, "_hash;\n",
+ "tie %__", iname, "_hash,\"", is_shadow(t), "\", $",
+ cmodule, "::", iname, ";\n",
+ "$", iname, "= \\%__", iname, "_hash;\n",
+ "bless $", iname, ", ", is_shadow(t), ";\n",
+ NIL);
+ } else {
+ Printv(var_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL);
+ }
+ }
+ if (export_all)
+ Printf(exported,"$%s ", iname);
+
+ DelWrapper(setf);
+ DelWrapper(getf);
+ Delete(set_name);
+ Delete(val_name);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *name = Getattr(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ String *value = Getattr(n,"value");
+ String *tm;
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ /* Special hook for member pointer */
+ if (SwigType_type(type) == T_MPOINTER) {
+ String *wname = Swig_name_wrapper(iname);
+ Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type,wname), value);
+ value = Char(wname);
+ }
+
+ if ((tm = Swig_typemap_lookup_new("consttab",n,name,0))) {
+ Replaceall(tm,"$source",value);
+ Replaceall(tm,"$target",name);
+ Replaceall(tm,"$value",value);
+ Printf(constant_tab,"%s,\n", tm);
+ } else if ((tm = Swig_typemap_lookup_new("constcode", n, name, 0))) {
+ Replaceall(tm,"$source", value);
+ Replaceall(tm,"$target", name);
+ Replaceall(tm,"$value",value);
+ Printf(f_init, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
+ "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+
+ if (blessed) {
+ if (is_shadow(type)) {
+ Printv(var_stubs,
+ "\nmy %__", iname, "_hash;\n",
+ "tie %__", iname, "_hash,\"", is_shadow(type), "\", $",
+ cmodule, "::", iname, ";\n",
+ "$", iname, "= \\%__", iname, "_hash;\n",
+ "bless $", iname, ", ", is_shadow(type), ";\n",
+ NIL);
+ } else if (do_constants) {
+ Printv(const_stubs,"sub ", name, " () { $",
+ cmodule, "::", name, " }\n", NIL);
+ num_consts++;
+ } else {
+ Printv(var_stubs, "*",iname," = *", cmodule, "::", iname, ";\n", NIL);
+ }
+ }
+ if (export_all) {
+ if (do_constants && !is_shadow(type)) {
+ Printf(exported,"%s ",name);
+ } else {
+ Printf(exported,"$%s ",iname);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * usage_func()
+ * ------------------------------------------------------------ */
+ char *usage_func(char *iname, SwigType *, ParmList *l) {
+ static String *temp = 0;
+ Parm *p;
+ int i;
+
+ if (!temp) temp = NewString("");
+ Clear(temp);
+ Printf(temp,"%s(",iname);
+
+ /* Now go through and print parameters */
+ p = l;
+ i = 0;
+ while (p != 0) {
+ SwigType *pt = Getattr(p,"type");
+ String *pn = Getattr(p,"name");
+ if (!Getattr(p,"ignore")) {
+ /* If parameter has been named, use that. Otherwise, just print a type */
+ if (SwigType_type(pt) != T_VOID) {
+ if (Len(pn) > 0) {
+ Printf(temp,"%s",pn);
+ } else {
+ Printf(temp,"%s",SwigType_str(pt,0));
+ }
+ }
+ i++;
+ p = nextSibling(p);
+ if (p)
+ if (!Getattr(p,"ignore"))
+ Putc(',',temp);
+ } else {
+ p = nextSibling(p);
+ if (p)
+ if ((i>0) && (!Getattr(p,"ignore")))
+ Putc(',',temp);
+ }
+ }
+ Printf(temp,");");
+ return Char(temp);
+ }
+
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int nativeWrapper(Node *n) {
+ String *name = Getattr(n,"sym:name");
+ String *funcname = Getattr(n,"wrap:name");
+
+ if (!addSymbol(funcname,n)) return SWIG_ERROR;
+
+ Printf(command_tab,"{\"%s::%s\", %s},\n", cmodule,name,funcname);
+ if (export_all)
+ Printf(exported,"%s ",name);
+ if (blessed) {
+ Printv(func_stubs,"*", name, " = *", cmodule, "::", name, ";\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /****************************************************************************
+ *** OBJECT-ORIENTED FEATURES
+ ****************************************************************************
+ *** These extensions provide a more object-oriented interface to C++
+ *** classes and structures. The code here is based on extensions
+ *** provided by David Fletcher and Gary Holt.
+ ***
+ *** I have generalized these extensions to make them more general purpose
+ *** and to resolve object-ownership problems.
+ ***
+ *** The approach here is very similar to the Python module :
+ *** 1. All of the original methods are placed into a single
+ *** package like before except that a 'c' is appended to the
+ *** package name.
+ ***
+ *** 2. All methods and function calls are wrapped with a new
+ *** perl function. While possibly inefficient this allows
+ *** us to catch complex function arguments (which are hard to
+ *** track otherwise).
+ ***
+ *** 3. Classes are represented as tied-hashes in a manner similar
+ *** to Gary Holt's extension. This allows us to access
+ *** member data.
+ ***
+ *** 4. Stand-alone (global) C functions are modified to take
+ *** tied hashes as arguments for complex datatypes (if
+ *** appropriate).
+ ***
+ *** 5. Global variables involving a class/struct is encapsulated
+ *** in a tied hash.
+ ***
+ ****************************************************************************/
+
+
+ void setclassname(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ String *fullname;
+ String *actualpackage;
+ Node *clsmodule = Getattr(n,"module");
+
+ if (!clsmodule) {
+ /* imported module does not define a module name. Oh well */
+ return;
+ }
+
+ /* Do some work on the class name */
+ actualpackage = Getattr(clsmodule,"name");
+ if ((!compat) && (!Strchr(symname,':'))) {
+ fullname = NewStringf("%s::%s",actualpackage,symname);
+ } else {
+ fullname = NewString(symname);
+ }
+ Setattr(n,"perl5:proxy", fullname);
+ }
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+ virtual int classDeclaration(Node *n) {
+ /* Do some work on the class name */
+ if (blessed) {
+ setclassname(n);
+ Append(classlist,n);
+ }
+ return Language::classDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int classHandler(Node *n) {
+
+ if (blessed) {
+ have_constructor = 0;
+ have_operators = 0;
+ have_destructor = 0;
+ have_data_members = 0;
+ operators = NewHash();
+
+ class_name = Getattr(n,"sym:name");
+
+ if (!addSymbol(class_name,n)) return SWIG_ERROR;
+
+ /* Use the fully qualified name of the Perl class */
+ if (!compat) {
+ fullclassname = NewStringf("%s::%s",fullmodule,class_name);
+ } else {
+ fullclassname = NewString(class_name);
+ }
+ real_classname = Getattr(n,"name");
+ pcode = NewString("");
+ blessedmembers = NewString("");
+ }
+
+ /* Emit all of the members */
+ Language::classHandler(n);
+
+
+ /* Finish the rest of the class */
+ if (blessed) {
+ /* Generate a client-data entry */
+ SwigType *ct = NewStringf("p.%s", real_classname);
+ Printv(f_init,"SWIG_TypeClientData(SWIGTYPE", SwigType_manglestr(ct),", (void*) \"",
+ fullclassname, "\");\n", NIL);
+ SwigType_remember(ct);
+ Delete(ct);
+
+ Printv(pm,
+ "\n############# Class : ", fullclassname, " ##############\n",
+ "\npackage ", fullclassname, ";\n",
+ NIL);
+
+ if (have_operators) {
+ Printf(pm, "use overload\n");
+ DOH *key;
+ for (key = Firstkey(operators); key; key = Nextkey(operators)) {
+ char *name = Char(key);
+ // fprintf(stderr,"found name: <%s>\n", name);
+ if (strstr(name, "operator_equal_to")) {
+ Printv(pm, tab4, "\"==\" => sub { $_[0]->operator_equal_to($_[1])},\n",NIL);
+ } else if (strstr(name, "operator_not_equal_to")) {
+ Printv(pm, tab4, "\"!=\" => sub { $_[0]->operator_not_equal_to($_[1])},\n",NIL);
+ } else if (strstr(name, "operator_assignment")) {
+ Printv(pm, tab4, "\"=\" => sub { $_[0]->operator_assignment($_[1])},\n",NIL);
+ } else {
+ fprintf(stderr,"Unknown operator: %s\n", name);
+ }
+ }
+ Printv(pm, tab4, "\"fallback\" => 1;\n",NIL);
+ }
+ /* If we are inheriting from a base class, set that up */
+
+ Printv(pm, "@ISA = qw( ",fullmodule, NIL);
+
+ /* Handle inheritance */
+ List *baselist = Getattr(n,"bases");
+ if (baselist && Len(baselist)) {
+ Node *base = Firstitem(baselist);
+ while (base) {
+ String *bname = Getattr(base, "perl5:proxy");
+ if (!bname) {
+ base = Nextitem(baselist);
+ continue;
+ }
+ Printv(pm," ", bname, NIL);
+ base = Nextitem(baselist);
+ }
+ }
+ Printf(pm, " );\n");
+
+ /* Dump out a hash table containing the pointers that we own */
+ Printf(pm, "%%OWNER = ();\n");
+ if (have_data_members) {
+ Printv(pm,
+ "%BLESSEDMEMBERS = (\n", blessedmembers, ");\n\n",
+ NIL);
+ }
+ if (have_data_members || have_destructor)
+ Printf(pm, "%%ITERATORS = ();\n");
+
+ /* Dump out the package methods */
+
+ Printv(pm,pcode,NIL);
+ Delete(pcode);
+
+ /* Output methods for managing ownership */
+
+ Printv(pm,
+ "sub DISOWN {\n",
+ tab4, "my $self = shift;\n",
+ tab4, "my $ptr = tied(%$self);\n",
+ tab4, "delete $OWNER{$ptr};\n",
+ tab4, "};\n\n",
+ "sub ACQUIRE {\n",
+ tab4, "my $self = shift;\n",
+ tab4, "my $ptr = tied(%$self);\n",
+ tab4, "$OWNER{$ptr} = 1;\n",
+ tab4, "};\n\n",
+ NIL);
+
+ /* Only output the following methods if a class has member data */
+
+ if (have_data_members) {
+
+ /* Output a FETCH method. This is actually common to all classes */
+ Printv(pm,
+ "sub FETCH {\n",
+ tab4, "my ($self,$field) = @_;\n",
+ tab4, "my $member_func = \"swig_${field}_get\";\n",
+ tab4, "my $val = $self->$member_func();\n",
+ tab4, "if (exists $BLESSEDMEMBERS{$field}) {\n",
+ tab8, "return undef if (!defined($val));\n",
+ tab8, "my %retval;\n",
+ tab8, "tie %retval,$BLESSEDMEMBERS{$field},$val;\n",
+ tab8, "return bless \\%retval, $BLESSEDMEMBERS{$field};\n",
+ tab4, "}\n",
+ tab4, "return $val;\n",
+ "}\n\n",
+ NIL);
+
+ /* Output a STORE method. This is also common to all classes (might move to base class) */
+
+ Printv(pm,
+ "sub STORE {\n",
+ tab4, "my ($self,$field,$newval) = @_;\n",
+ tab4, "my $member_func = \"swig_${field}_set\";\n",
+ tab4, "if (exists $BLESSEDMEMBERS{$field}) {\n",
+ tab8, "$self->$member_func(tied(%{$newval}));\n",
+ tab4, "} else {\n",
+ tab8, "$self->$member_func($newval);\n",
+ tab4, "}\n",
+ "}\n\n",
+ NIL);
+ }
+ Delete(operators); operators = 0;
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberfunctionHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+
+ String *func;
+ int need_wrapper = 0;
+
+ member_func = 1;
+ Language::memberfunctionHandler(n);
+ member_func = 0;
+
+ if ((blessed) && (!Getattr(n,"sym:nextSibling"))) {
+ func = NewString("");
+
+ /* Now emit a Perl wrapper function around our member function, we might need
+ to patch up some arguments along the way */
+
+ if (Strstr(symname, "operator") == symname) {
+ if (Strstr(symname, "operator_equal_to")) {
+ DohSetInt(operators,"operator_equal_to",1);
+ have_operators = 1;
+ } else if (Strstr(symname, "operator_not_equal_to")) {
+ DohSetInt(operators,"operator_not_equal_to",1);
+ have_operators = 1;
+ } else if (Strstr(symname, "operator_assignment")) {
+ DohSetInt(operators,"operator_assignment",1);
+ have_operators = 1;
+ } else {
+ Printf(stderr,"Unknown operator: %s\n", symname);
+ }
+ // fprintf(stderr,"Found member_func operator: %s\n", symname);
+ }
+
+ Printv(func,
+ "sub ", symname, " {\n",
+ tab4, "my @args = @_;\n",
+ NIL);
+
+ /* Okay. We've made argument adjustments, now call into the package */
+
+ Printv(func,
+ tab4, "my $result = ", cmodule, "::", Swig_name_member(class_name,symname),
+ "(@args);\n",
+ NIL);
+
+ /* Now check to see what kind of return result was found.
+ * If this function is returning a result by 'value', SWIG did an
+ * implicit malloc/new. We'll mark the object like it was created
+ * in Perl so we can garbage collect it. */
+
+ if (is_shadow(t)) {
+ Printv(func,tab4, "return undef if (!defined($result));\n", NIL);
+
+ /* If we're returning an object by value, put it's reference
+ into our local hash table */
+
+ if ((!SwigType_ispointer(t) && !SwigType_isreference(t)) || Getattr(n,"feature:new")) {
+ Printv(func, tab4, "$", is_shadow(t), "::OWNER{$result} = 1; \n", NIL);
+ }
+
+ /* We're returning a Perl "object" of some kind. Turn it into
+ a tied hash */
+
+ Printv(func,
+ tab4, "my %resulthash;\n",
+ tab4, "tie %resulthash, ref($result), $result;\n",
+ tab4, "return bless \\%resulthash, ref($result);\n",
+ "}\n",
+ NIL);
+
+ need_wrapper = 1;
+ } else {
+
+ /* Hmmm. This doesn't appear to be anything I know about so just
+ return it unmodified */
+
+ Printv(func, tab4,"return $result;\n", "}\n", NIL);
+ }
+
+ if (need_wrapper) {
+ Printv(pcode,func,NIL);
+ } else {
+ Printv(pcode,"*",symname," = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL);
+ }
+ Delete(func);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ *
+ * Adds an instance member. This is a little hairy because data members are
+ * really added with a tied-hash table that is attached to the object.
+ *
+ * On the low level, we will emit a pair of get/set functions to retrieve
+ * values just like before. These will then be encapsulated in a FETCH/STORE
+ * method associated with the tied-hash.
+ *
+ * In the event that a member is an object that we have already wrapped, then
+ * we need to retrieve the data a tied-hash as opposed to what SWIG normally
+ * returns. To determine this, we build an internal hash called 'BLESSEDMEMBERS'
+ * that contains the names and types of tied data members. If a member name
+ * is in the list, we tie it, otherwise, we just return the normal SWIG value.
+ * ----------------------------------------------------------------------------- */
+
+ virtual int membervariableHandler(Node *n) {
+
+ String *symname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+
+ /* Emit a pair of get/set functions for the variable */
+
+ member_func = 1;
+ Language::membervariableHandler(n);
+ member_func = 0;
+
+ if (blessed) {
+
+ Printv(pcode,"*swig_", symname, "_get = *", cmodule, "::", Swig_name_get(Swig_name_member(class_name,symname)), ";\n", NIL);
+ Printv(pcode,"*swig_", symname, "_set = *", cmodule, "::", Swig_name_set(Swig_name_member(class_name,symname)), ";\n", NIL);
+
+ /* Now we need to generate a little Perl code for this */
+
+ if (is_shadow(t)) {
+
+ /* This is a Perl object that we have already seen. Add an
+ entry to the members list*/
+ Printv(blessedmembers,
+ tab4, symname, " => '", is_shadow(t), "',\n",
+ NIL);
+
+ }
+ }
+ have_data_members++;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorDeclaration()
+ *
+ * Emits a blessed constructor for our class. In addition to our construct
+ * we manage a Perl hash table containing all of the pointers created by
+ * the constructor. This prevents us from accidentally trying to free
+ * something that wasn't necessarily allocated by malloc or new
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+
+ String *symname = Getattr(n,"sym:name");
+
+ member_func = 1;
+ Language::constructorHandler(n);
+
+ if ((blessed) && (!Getattr(n,"sym:nextSibling"))) {
+ if ((Cmp(symname,class_name) == 0)) {
+ /* Emit a blessed constructor */
+ Printf(pcode, "sub new {\n");
+ } else {
+ /* Constructor doesn't match classname so we'll just use the normal name */
+ Printv(pcode, "sub ", Swig_name_construct(symname), " () {\n", NIL);
+ }
+
+ Printv(pcode, tab4, "my $pkg = shift;\n",
+ tab4, "my @args = @_;\n", NIL);
+
+ Printv(pcode,
+ tab4, "my $self = ", cmodule, "::", Swig_name_construct(symname), "(@args);\n",
+ tab4, "return undef if (!defined($self));\n",
+ /* tab4, "bless $self, \"", fullclassname, "\";\n", */
+ tab4, "$OWNER{$self} = 1;\n",
+ tab4, "my %retval;\n",
+ tab4, "tie %retval, \"", fullclassname, "\", $self;\n",
+ tab4, "return bless \\%retval, $pkg;\n",
+ "}\n\n",
+ NIL);
+
+ have_constructor = 1;
+ }
+ member_func = 0;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ member_func = 1;
+ Language::destructorHandler(n);
+ if (blessed) {
+ Printv(pcode,
+ "sub DESTROY {\n",
+ tab4, "return unless $_[0]->isa('HASH');\n",
+ tab4, "my $self = tied(%{$_[0]});\n",
+ tab4, "return unless defined $self;\n",
+ tab4, "delete $ITERATORS{$self};\n",
+ tab4, "if (exists $OWNER{$self}) {\n",
+ tab8, cmodule, "::", Swig_name_destroy(symname), "($self);\n",
+ tab8, "delete $OWNER{$self};\n",
+ tab4, "}\n}\n\n",
+ NIL);
+ have_destructor = 1;
+ }
+ member_func = 0;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ member_func = 1;
+ Language::staticmemberfunctionHandler(n);
+ member_func = 0;
+ if ((blessed) && (!Getattr(n,"sym:nextSibling"))) {
+ String *symname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+ if (is_shadow(t)) {
+ Printv(pcode,
+ "sub ", symname, " {\n",
+ tab4, "my @args = @_;\n",
+ NIL);
+
+ /* Okay. We've made argument adjustments, now call into the package */
+
+ Printv(pcode,
+ tab4, "my $result = ", cmodule, "::", Swig_name_member(class_name,symname),
+ "(@args);\n",
+ NIL);
+
+ /* Now check to see what kind of return result was found.
+ * If this function is returning a result by 'value', SWIG did an
+ * implicit malloc/new. We'll mark the object like it was created
+ * in Perl so we can garbage collect it. */
+
+ Printv(pcode,tab4, "return undef if (!defined($result));\n", NIL);
+
+ /* If we're returning an object by value, put it's reference
+ into our local hash table */
+
+ if ((!SwigType_ispointer(t) && !SwigType_isreference(t)) || Getattr(n,"feature:new")) {
+ Printv(pcode, tab4, "$", is_shadow(t), "::OWNER{$result} = 1; \n", NIL);
+ }
+
+ /* We're returning a Perl "object" of some kind. Turn it into
+ a tied hash */
+
+ Printv(pcode,
+ tab4, "my %resulthash;\n",
+ tab4, "tie %resulthash, ref($result), $result;\n",
+ tab4, "return bless \\%resulthash, ref($result);\n",
+ "}\n",
+ NIL);
+ } else {
+ Printv(pcode,"*",symname," = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmembervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ Language::staticmembervariableHandler(n);
+ if (blessed) {
+ String *symname = Getattr(n,"sym:name");
+ Printv(pcode,"*",symname," = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberconstantHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberconstantHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ int oldblessed = blessed;
+
+ /* Create a normal constant */
+ blessed = 0;
+ Language::memberconstantHandler(n);
+ blessed = oldblessed;
+
+ if (blessed) {
+ Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * pragma()
+ *
+ * Pragma directive.
+ *
+ * %pragma(perl5) code="String" # Includes a string in the .pm file
+ * %pragma(perl5) include="file.pl" # Includes a file in the .pm file
+ * ------------------------------------------------------------ */
+
+ virtual int pragmaDirective(Node *n) {
+ String *lang;
+ String *code;
+ String *value;
+ if (!ImportMode) {
+ lang = Getattr(n,"lang");
+ code = Getattr(n,"name");
+ value = Getattr(n,"value");
+ if (Strcmp(lang,"perl5") == 0) {
+ if (Strcmp(code,"code") == 0) {
+ /* Dump the value string into the .pm file */
+ if (value) {
+ Printf(pragma_include, "%s\n", value);
+ }
+ } else if (Strcmp(code,"include") == 0) {
+ /* Include a file into the .pm file */
+ if (value) {
+ FILE *f = Swig_open(value);
+ if (!f) {
+ Printf(stderr,"%s : Line %d. Unable to locate file %s\n", input_file, line_number,value);
+ } else {
+ char buffer[4096];
+ while (fgets(buffer,4095,f)) {
+ Printf(pragma_include,"%s",buffer);
+ }
+ }
+ }
+ } else {
+ Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file,line_number);
+ }
+ }
+ }
+ return Language::pragmaDirective(n);
+ }
+};
+
+/* -----------------------------------------------------------------------------
+ * swig_perl5() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+extern "C" Language *
+swig_perl5(void) {
+ return new PERL5();
+}
diff --git a/Source/Modules/php4.cxx b/Source/Modules/php4.cxx
new file mode 100644
index 000000000..051e24601
--- /dev/null
+++ b/Source/Modules/php4.cxx
@@ -0,0 +1,2113 @@
+/*
+ * PHP4 Support
+ *
+ * Richard Palmer
+ * richard@magicality.org
+ * Nov 2001
+ *
+ * Portions copyright Sun Microsystems (c) 2001
+ * Tim Hockin
+ *
+ * Portions copyright Ananova Ltd (c) 2002
+ * Sam Liddicott
+ *
+ */
+
+char cvsroot_php4_cxx[] = "$Header$";
+
+#include
+
+#include "swigmod.h"
+#include "swigconfig.h"
+
+static const char *usage = (char*)"\
+PHP4 Options (available with -php4)\n\
+ -cppext - cpp file extension (default to .cpp)\n\
+ -proxy - Create proxy classes.\n\
+ -dlname name - Set module prefix.\n\
+ -make - Create simple makefile.\n\
+ -phpfull - Create full make files.\n\
+ -withincs libs - With -phpfull writes needed incs in config.m4\n\
+ -withlibs libs - With -phpfull writes needed libs in config.m4\n\n\
+ -withc libs - With -phpfull makes extra c files in Makefile.in\n\
+ -withcxx libs - With -phpfull makes extra c++ files in Makefile.in\n\n";
+
+static int constructors=0;
+static String *NOTCLASS=NewString("Not a class");
+static Node *classnode=0;
+static String *module = 0;
+static String *cap_module = 0;
+static String *dlname = 0;
+static String *withlibs = 0;
+static String *withincs = 0;
+static String *withc = 0;
+static String *withcxx = 0;
+static String *outfile = 0;
+
+//static char *package = 0; // Name of the package
+static char *shadow_classname;
+
+static Wrapper *f_php;
+static int gen_extra = 0;
+static int gen_make = 0;
+
+static File *f_runtime = 0;
+static File *f_h = 0;
+static File *f_phpcode = 0;
+static String *phpfilename =0;
+
+static String *s_header;
+static String *s_wrappers;
+static String *s_init;
+static String *s_vinit;
+static String *s_vdecl;
+static String *s_cinit;
+static String *s_oinit;
+static String *s_entry;
+static String *cs_entry;
+static String *all_cs_entry;
+static String *pragma_incl;
+static String *pragma_code;
+static String *pragma_phpinfo;
+
+/* Variables for using PHP classes */
+static String *class_name = 0;
+static String *realpackage = 0;
+static String *package = 0;
+
+static Hash *shadow_get_vars;
+static Hash *shadow_set_vars;
+static String *shadow_classdef;
+static String *shadow_code;
+static int have_default_constructor = 0;
+#define NATIVE_CONSTRUCTOR 1
+#define ALTERNATIVE_CONSTRUCTOR 2
+static int native_constructor=0;
+static int destructor=0;
+static int enum_flag = 0; // Set to 1 when wrapping an enum
+static int static_flag = 0; // Set to 1 when wrapping a static functions or member variables
+static int const_flag = 0; // Set to 1 when wrapping a const member variables
+static int variable_wrapper_flag = 0; // Set to 1 when wrapping a member variable/enum/const
+static int wrapping_member = 0;
+static Hash *zend_types = 0;
+
+static String *shadow_enum_code = 0;
+static String *php_enum_code = 0;
+static String *all_shadow_extra_code = 0;
+ //Extra code for all shadow classes from %pragma
+static String *this_shadow_extra_code = 0;
+ //Extra Code for current single shadow class freom %pragma
+static String *all_shadow_import = 0;
+ //import for all shadow classes from %pragma
+static String *this_shadow_import = 0;
+ //import for current shadow classes from %pragma
+static String *module_baseclass = 0;
+ //inheritance for module class from %pragma
+static String *all_shadow_baseclass = 0;
+ //inheritence for all shadow classes from %pragma
+static String *this_shadow_baseclass = 0;
+ //inheritance for shadow class from %pragma and cpp_inherit
+static String *this_shadow_multinherit = 0;
+static int shadow = 1;
+
+
+extern "C" {
+static void (*r_prevtracefunc)(SwigType *t, String *mangled, String *clientdata) = 0;
+}
+
+static const char *php_header =
+"/*"
+"\n +----------------------------------------------------------------------+"
+"\n | PHP version 4.0 |"
+"\n +----------------------------------------------------------------------+"
+"\n | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |"
+"\n +----------------------------------------------------------------------+"
+"\n | This source file is subject to version 2.02 of the PHP license, |"
+"\n | that is bundled with this package in the file LICENSE, and is |"
+"\n | available at through the world-wide-web at |"
+"\n | http://www.php.net/license/2_02.txt. |"
+"\n | If you did not receive a copy of the PHP license and are unable to |"
+"\n | obtain it through the world-wide-web, please send a note to |"
+"\n | license@php.net so we can mail you a copy immediately. |"
+"\n +----------------------------------------------------------------------+"
+"\n | Authors: |"
+"\n | |"
+"\n +----------------------------------------------------------------------+"
+"\n */\n";
+
+void
+SwigPHP_emit_resource_registrations() {
+ DOH *key;
+ String *destructor=0;
+ String *classname=0;
+ String *shadow_classname=0;
+
+ if (!zend_types) return;
+ key = Firstkey(zend_types);
+
+ if (key) Printf(s_oinit,"\n/* Register resource destructors for pointer types */\n");
+ while (key) if (1 /* is pointer type*/) {
+ Node *class_node;
+ if ((class_node=Getattr(zend_types,key))) {
+ // Write out destructor function header
+ Printf(s_wrappers,"/* NEW Destructor style */\nstatic ZEND_RSRC_DTOR_FUNC(_wrap_destroy%s) {\n",key);
+
+ // write out body
+ if ((class_node!=NOTCLASS)) {
+ classname = Getattr(class_node,"name");
+ if (! (shadow_classname = Getattr(class_node,"sym:name"))) shadow_classname=classname;
+ // Do we have a known destructor for this type?
+ if ((destructor = Getattr(class_node,"destructor"))) {
+ Printf(s_wrappers,"/* has destructor: %s */\n",destructor);
+ Printf(s_wrappers,"%s(rsrc, SWIGTYPE%s->name TSRMLS_CC);\n",destructor,key);
+ } else {
+ Printf(s_wrappers,"/* bah! No destructor for this wrapped class!! */\n");
+ }
+ } else {
+ Printf(s_wrappers,"/* bah! No destructor for this simple type!! */\n");
+ }
+
+ // close function
+ Printf(s_wrappers,"}\n");
+
+ // declare le_swig_ to store php registration
+ Printf(s_vdecl,"static int le_swig_%s=0; /* handle for %s */\n", key, shadow_classname);
+
+ // register with php
+ Printf(s_oinit,"le_swig_%s=zend_register_list_destructors_ex"
+ "(_wrap_destroy%s,NULL,(char *)(SWIGTYPE%s->name),module_number);\n",
+ key,key,key);
+
+ // store php type in class struct
+ Printf(s_oinit,"SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n",
+ key,key);
+ }
+ key = Nextkey(zend_types);
+ }
+}
+
+class PHP4 : public Language {
+public:
+
+ /* Test to see if a type corresponds to something wrapped with a shadow class. */
+
+ String *is_shadow(SwigType *t) {
+ String *r = 0;
+ Node *n = classLookup(t);
+ if (n) {
+ r = Getattr(n,"php:proxy"); // Set by classDeclaration()
+ if (!r) {
+ r = Getattr(n,"sym:name"); // Not seen by classDeclaration yet, but this is the name
+ }
+ }
+ return r;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * get_pointer()
+ * ----------------------------------------------------------------------------- */
+ void
+ get_pointer(char *iname, char *srcname, char *src, char *dest,
+ SwigType *t, String *f, char *ret) {
+
+ SwigType_remember(t);
+ SwigType *lt = SwigType_ltype(t);
+ Printv(f, "if (SWIG_ConvertPtr(", src, ",(void **) ", dest, ",", NIL);
+
+ /* If we're passing a void pointer, we give the pointer conversion a NULL
+ pointer, otherwise pass in the expected type. */
+
+ if (Cmp(lt,"p.void") == 0) {
+ Printf(f, " 0 ) < 0) {\n");
+ } else {
+ Printv(f, "SWIGTYPE", SwigType_manglestr(t), ") < 0) {\n",NIL);
+ }
+
+ Printv(f,
+ "zend_error(E_ERROR, \"Type error in ", srcname, " of ", iname,
+ " Expected %s\", SWIGTYPE", SwigType_manglestr(t), "->name);\n", ret,
+ ";\n",
+ "}\n",
+ NIL);
+ Delete(lt);
+ }
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+ int i;
+ SWIG_library_directory("php4");
+ SWIG_config_cppext("cpp");
+
+ for(i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if(strcmp(argv[i], "-phpfull") == 0) {
+ gen_extra = 1;
+ Swig_mark_arg(i);
+ } else if(strcmp(argv[i], "-dlname") == 0) {
+ if (argv[i+1]) {
+ dlname = NewString(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if(strcmp(argv[i], "-withlibs") == 0) {
+ if (argv[i+1]) {
+ withlibs = NewString(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if(strcmp(argv[i], "-withincs") == 0) {
+ if (argv[i+1]) {
+ withincs = NewString(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if(strcmp(argv[i], "-withc") == 0) {
+ if (argv[i+1]) {
+ withc = NewString(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if(strcmp(argv[i], "-withcxx") == 0) {
+ if (argv[i+1]) {
+ withcxx = NewString(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if(strcmp(argv[i], "-cppext") == 0) {
+ if (argv[i+1]) {
+ SWIG_config_cppext(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if((strcmp(argv[i], "-noshadow") == 0) || (strcmp(argv[i],"-noproxy") == 0)) {
+ shadow = 0;
+ Swig_mark_arg(i);
+ } else if(strcmp(argv[i], "-make") == 0) {
+ gen_make = 1;
+ Swig_mark_arg(i);
+ } else if(strcmp(argv[i], "-help") == 0) {
+ fputs(usage, stderr);
+ }
+ }
+ }
+
+ Preprocessor_define((void *) "SWIGPHP 1", 0);
+ Preprocessor_define((void *) "SWIGPHP4 1", 0);
+ Preprocessor_define ("SWIG_NO_OVERLOAD 1", 0);
+ SWIG_typemap_lang("php4");
+ /* DB: Suggest using a language configuration file */
+ SWIG_config_file("php4.swg");
+ }
+
+ void create_simple_make(void) {
+ File *f_make;
+
+ f_make = NewFile((void *)"makefile", "w");
+ if(CPlusPlus)
+ Printf(f_make, "CC=g++\n");
+ else
+ Printf(f_make, "CC=gcc\n");
+
+ Printf(f_make,
+ "OBJS=%s_wrap.o\n"
+ "PROG=lib%s.so\n"
+ "CFLAGS=-fpic\n"
+ "LDFLAGS=-shared\n"
+ "PHP_INC=`php-config --includes`\n"
+ "EXTRA_INC=\n"
+ "EXTRA_LIB=\n\n",
+ module, module);
+
+ Printf(f_make,
+ "$(PROG): $(OBJS)\n"
+ "\t$(CC) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n"
+ "%%.o: %%.%s\n"
+ "\t$(CC) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n",
+ (CPlusPlus?"cpp":"c"));
+
+ Close(f_make);
+ }
+
+ void create_extra_files(void) {
+ File *f_extra;
+
+ static String *configm4=0;
+ static String *makefilein=0;
+ static String *credits=0;
+
+ configm4=NewString("");
+ Printv(configm4, Swig_file_dirname(outfile), "config.m4", NIL);
+
+ makefilein=NewString("");
+ Printv(makefilein, Swig_file_dirname(outfile), "Makefile.in", NIL);
+
+ credits=NewString("");
+ Printv(credits, Swig_file_dirname(outfile), "CREDITS", NIL);
+
+ // are we a --with- or --enable-
+ int with=(withincs || withlibs)?1:0;
+
+ // Note makefile.in only copes with one source file
+ // also withincs and withlibs only take one name each now
+ // the code they generate should be adapted to take multiple lines
+
+ if(gen_extra) {
+ /* Write out Makefile.in */
+ f_extra = NewFile(makefilein, "w");
+ if (!f_extra) {
+ Printf(stderr,"Unable to open %s\n",makefilein);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Printf(f_extra,
+ "# $Id$\n\n"
+ "LTLIBRARY_NAME = php_%s.la\n",
+ module);
+
+ // CPP has more and different entires to C in Makefile.in
+ if (! CPlusPlus) Printf(f_extra,"LTLIBRARY_SOURCES = %s %s\n"
+ "LTLIBRARY_SOURCES_CPP = %s\n",Swig_file_filename(outfile),withc,withcxx);
+ else Printf(f_extra,"LTLIBRARY_SOURCES = %s\n"
+ "LTLIBRARY_SOURCES_CPP = %s %s\n"
+ "LTLIBRARY_OBJECTS_X = $(LTLIBRARY_SOURCES_CPP:.cpp=.lo) $(LTLIBRARY_SOURCES_CPP:.cxx=.lo)\n"
+ ,withc,Swig_file_filename(outfile),withcxx);
+
+ Printf(f_extra,"LTLIBRARY_SHARED_NAME = php_%s.la\n"
+ "LTLIBRARY_SHARED_LIBADD = $(%(upper)s_SHARED_LIBADD)\n\n"
+ "include $(top_srcdir)/build/dynlib.mk\n",
+ module,module);
+
+ Printf(f_extra,"\n# patch in .cxx support to php build system to work like .cpp\n"
+ ".SUFFIXES: .cxx\n\n"
+ ".cxx.o:\n"
+ " $(CXX_COMPILE) -c $<\n\n"
+ ".cxx.lo:\n"
+ " $(CXX_PHP_COMPILE)\n\n"
+ ".cxx.slo:\n"
+ " $(CXX_SHARED_COMPILE)\n\n");
+
+ Printf(f_extra,"\n# make it easy to test module\n"
+ "testmodule:\n"
+ " php -q -d extension_dir=modules %s\n\n",Swig_file_filename(phpfilename));
+ Close(f_extra);
+
+ /* Now config.m4 */
+ // Note: # comments are OK in config.m4 if you don't mind them
+ // appearing in the final ./configure file
+ // (which can help with ./configure debugging)
+
+ // NOTE2: phpize really ought to be able to write out a sample
+ // config.m4 based on some simple data, I'll take this up with
+ // the php folk!
+ f_extra = NewFile(configm4, "w");
+ if (!f_extra) {
+ Printf(stderr, "Unable to open %s\n",configm4);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Printf(f_extra,
+ "dnl $Id$\n"
+ "dnl ***********************************************************************\n"
+ "dnl ** THIS config.m4 is provided for PHPIZE and PHP's consumption NOT\n"
+ "dnl ** for any part of the rest of the %s build system\n"
+ "dnl ***********************************************************************\n\n"
+ ,module);
+
+ if (! with) { // must be enable then
+ Printf(f_extra,
+ "PHP_ARG_ENABLE(%s, whether to enable %s support,\n"
+ "[ --enable-%s Enable %s support])\n\n",
+ module,module,module,module);
+ } else {
+ Printf(f_extra,
+ "PHP_ARG_WITH(%s, for %s support,\n"
+ "[ --with-%s[=DIR] Include %s support.])\n\n",
+ module,module,module,module);
+ // These tests try and file the library we need
+ Printf(f_extra,"dnl THESE TESTS try and find the library and header files\n"
+ "dnl your new php module needs. YOU MAY NEED TO EDIT THEM\n"
+ "dnl as written they assume your header files are all in the same place\n\n");
+
+ Printf(f_extra,"dnl ** are we looking for %s_lib.h or something else?\n",module);
+ if (withincs) Printf(f_extra,"HNAMES=\"%s\"\n\n",withincs);
+ else Printf(f_extra,"HNAMES=\"\"; # %s_lib.h ?\n\n",module);
+
+ Printf(f_extra,"dnl ** Are we looking for lib%s.a or lib%s.so or something else?\n",module,module);
+ if (withlibs) Printf(f_extra,"LIBNAMES=\"%s\"\n\n",withlibs);
+ else Printf(f_extra,"LIBNAMES=\"\"; # lib_%s.so ?\n\n",withlibs);
+ Printf(f_extra,"dnl IF YOU KNOW one of the symbols in the library and you\n"
+ "dnl specify it below then we can have a link test to see if it works\n"
+ "LIBSYMBOL=\"\"\n\n");
+ }
+
+ // Now write out tests to find thing.. they may need to extend tests
+ Printf(f_extra,"if test \"$PHP_%(upper)s\" != \"no\"; then\n\n",module);
+
+ // Ready for when we add libraries as we find them
+ Printf(f_extra," PHP_SUBST(%(upper)s_SHARED_LIBADD)\n\n",module);
+
+ if (withlibs) { // find more than one library
+ Printf(f_extra," for LIBNAME in $LIBNAMES ; do\n");
+ Printf(f_extra," LIBDIR=\"\"\n");
+ // For each path element to try...
+ Printf(f_extra," for i in $PHP_%(upper)s $PHP_%(upper)s/lib /usr/lib /usr/local/lib ; do\n",module,module);
+ Printf(f_extra," if test -r $i/lib$LIBNAME.a -o -r $i/lib$LIBNAME.so ; then\n"
+ " LIBDIR=\"$i\"\n"
+ " break\n"
+ " fi\n"
+ " done\n\n");
+ Printf(f_extra," dnl ** and $LIBDIR should be the library path\n"
+ " if test \"$LIBNAME\" != \"\" -a -z \"$LIBDIR\" ; then\n"
+ " AC_MSG_RESULT(Library files $LIBNAME not found)\n"
+ " AC_MSG_ERROR(Is the %s distribution installed properly?)\n"
+ " else\n"
+ " AC_MSG_RESULT(Library files $LIBNAME found in $LIBDIR)\n"
+ " PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBDIR, %(upper)s_SHARED_LIBADD)\n"
+ " fi\n",module,module);
+ Printf(f_extra," done\n\n");
+ }
+
+ if (withincs) { // Find more than once include
+ Printf(f_extra," for HNAME in $HNAMES ; do\n");
+ Printf(f_extra," INCDIR=\"\"\n");
+ // For each path element to try...
+ Printf(f_extra," for i in $PHP_%(upper)s $PHP_%(upper)s/include $PHP_%(upper)s/includes $PHP_%(upper)s/inc $PHP_%(upper)s/incs /usr/local/include /usr/include; do\n",module,module,module,module,module);
+ // Try and find header files
+ Printf(f_extra," if test \"$HNAME\" != \"\" -a -r $i/$HNAME ; then\n"
+ " INCDIR=\"$i\"\n"
+ " break\n"
+ " fi\n"
+ " done\n\n");
+
+ Printf(f_extra,
+ " dnl ** Now $INCDIR should be the include file path\n"
+ " if test \"$HNAME\" != \"\" -a -z \"$INCDIR\" ; then\n"
+ " AC_MSG_RESULT(Include files $HNAME not found)\n"
+ " AC_MSG_ERROR(Is the %s distribution installed properly?)\n"
+ " else\n"
+ " AC_MSG_RESULT(Include files $HNAME found in $INCDIR)\n"
+ " PHP_ADD_INCLUDE($INCDIR)\n"
+ " fi\n\n",module);
+ Printf(f_extra," done\n\n");
+ }
+
+ if (CPlusPlus) Printf(f_extra,
+ " # As this is a C++ module..\n"
+ " PHP_REQUIRE_CXX\n"
+ " AC_CHECK_LIB(stdc++, cin)\n");
+
+ if (with) {
+ Printf(f_extra," if test \"$LIBSYMBOL\" != \"\" ; then\n"
+ " old_LIBS=\"$LIBS\"\n"
+ " LIBS=\"$LIBS -L$TEST_DIR/lib -lm -ldl\"\n"
+ " AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_TESTLIB,1, [ ])],\n"
+ " [AC_MSG_ERROR(wrong test lib version or lib not found)])\n"
+ " LIBS=\"$old_LIBS\"\n"
+ " fi\n\n");
+ }
+
+ Printf(f_extra," AC_DEFINE(HAVE_%(upper)s, 1, [ ])\n",module);
+ Printf(f_extra,"dnl AC_DEFINE_UNQUOTED(PHP_%(upper)s_DIR, \"$%(upper)s_DIR\", [ ])\n",module,module);
+ Printf(f_extra," PHP_EXTENSION(%s, $ext_shared)\n",module);
+
+ // and thats all!
+ Printf(f_extra,"fi\n");
+
+ Close(f_extra);
+
+ /* CREDITS */
+ f_extra = NewFile(credits, "w");
+ if (!f_extra) {
+ Printf(stderr,"Unable to open %s\n",credits);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Printf(f_extra, "%s\n", module);
+ Close(f_extra);
+ }
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+
+ String *filen;
+ String *s_type;
+
+ /* Initialize all of the output files */
+ outfile = Getattr(n,"outfile");
+
+ /* main output file */
+ f_runtime = NewFile(outfile,"w");
+ if (!f_runtime) {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Swig_banner(f_runtime);
+
+ /* sections of the output file */
+ s_init = NewString("/* init section */\n");
+ s_header = NewString("/* header section */\n");
+ s_wrappers = NewString("/* wrapper section */\n");
+ s_type = NewString("");
+ /* subsections of the init section */
+ s_vinit = NewString("/* vinit subsection */\n");
+ s_vdecl = NewString("/* vdecl subsection */\n");
+ s_cinit = NewString("/* cinit subsection */\n");
+ s_oinit = NewString("/* oinit subsection */\n");
+ pragma_phpinfo = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("runtime",f_runtime);
+ Swig_register_filebyname("init",s_init);
+ Swig_register_filebyname("header",s_header);
+ Swig_register_filebyname("wrapper",s_wrappers);
+
+ shadow_classdef = NewString("");
+ shadow_code = NewString("");
+ php_enum_code = NewString("");
+ module_baseclass = NewString("");
+ all_shadow_extra_code = NewString("");
+ all_shadow_import = NewString("");
+ all_shadow_baseclass = NewString("");
+
+ /* Set the module name */
+ module = Copy(Getattr(n,"name"));
+ cap_module = NewStringf("%(upper)s",module);
+
+ if(shadow) {
+ realpackage = module;
+ package = NewStringf("%sc", module);
+ }
+
+ /* Set the dlname */
+ if (!dlname) {
+#if defined(_WIN32) || defined(__WIN32__)
+ dlname = NewStringf("%s.dll", module);
+#else
+ dlname = NewStringf("%s.so", module);
+#endif
+ }
+
+ /* PHP module file */
+ filen = NewString("");
+ Printv(filen, Swig_file_dirname(outfile), module, ".php", NIL);
+ phpfilename = NewString(filen);
+
+ f_phpcode = NewFile(filen, "w");
+ if (!f_phpcode) {
+ Printf(stderr, "*** Can't open '%s'\n", filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Printf(f_phpcode, "v)\n"
+ "#define %s_FETCH() zend_%s_globals *%s_globals "
+ "= ts_resource(%s_globals_id)\n"
+ "#else\n"
+ "#define %s_D\n"
+ "#define %s_DC\n"
+ "#define %s_C\n"
+ "#define %s_CC\n"
+ "#define %s_SG(v) (%s_globals.v)\n"
+ "#define %s_FETCH()\n"
+ "#endif\n\n"
+ "#endif /* PHP_%s_H */\n",
+ cap_module, module, module, cap_module, cap_module, cap_module, module,
+ cap_module, cap_module, cap_module, module, cap_module, module, module,
+ module, cap_module, cap_module, cap_module, cap_module, cap_module, module,
+ cap_module, cap_module);
+
+ Close(f_h);
+
+ Printf(s_header, "%s\n\n",all_cs_entry);
+ Printf(s_header,
+ "%s"
+ " {NULL, NULL, NULL}\n};\n\n"
+ "zend_module_entry %s_module_entry = {\n"
+ "#if ZEND_MODULE_API_NO > 20010900\n"
+ " STANDARD_MODULE_HEADER,\n"
+ "#endif\n"
+ " \"%s\",\n"
+ " %s_functions,\n"
+ " PHP_MINIT(%s),\n"
+ " PHP_MSHUTDOWN(%s),\n"
+ " PHP_RINIT(%s),\n"
+ " PHP_RSHUTDOWN(%s),\n"
+ " PHP_MINFO(%s),\n"
+ "#if ZEND_MODULE_API_NO > 20010900\n"
+ " NO_VERSION_YET,\n"
+ "#endif\n"
+ " STANDARD_MODULE_PROPERTIES\n"
+ "};\nzend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n",
+ s_entry, module, module, module, module, module, module, module,module,module);
+
+ String *type_table = NewString("");
+ SwigType_emit_type_table(f_runtime,type_table);
+ Printf(s_header,"%s",type_table);
+ Delete(type_table);
+
+ /* Oh dear, more things being called in the wrong order. This whole
+ * function really needs totally redoing.
+ */
+
+ Printv(f_runtime, s_header, NIL);
+
+ // Wrapper_print(f_c, s_wrappers);
+ Wrapper_print(f_php, s_wrappers);
+
+ Printf(s_header, "/* end header section */\n");
+ Printf(s_wrappers, "/* end wrapper section */\n");
+ Printf(s_vdecl, "/* end vdecl subsection */\n");
+
+ Printv(f_runtime, s_vdecl, s_wrappers, s_init, NIL);
+ Delete(s_header);
+ Delete(s_wrappers);
+ Delete(s_init);
+ Delete(s_vdecl);
+ Close(f_runtime);
+ Printf(f_phpcode, "%s\n%s\n?>\n", pragma_incl, pragma_code);
+ Close(f_phpcode);
+
+ create_extra_files();
+
+ if(!gen_extra && gen_make)
+ create_simple_make();
+
+ return SWIG_OK;
+ }
+
+/* Just need to append function names to function table to register with
+ PHP
+*/
+
+ void create_command(char *cname, char *iname) {
+// char *lower_cname = strdup(cname);
+// char *c;
+
+// for(c = lower_cname; *c != '\0'; c++) {
+// if(*c >= 'A' && *c <= 'Z')
+// *c = *c + 32;
+// }
+
+ Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
+
+ // This is for the single main function_entry record
+ if (! cs_entry) Printf(s_entry,
+ " ZEND_NAMED_FE(%(lower)s,\n"
+ " %s, NULL)\n", cname,iname);
+
+// free(lower_cname);
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int functionWrapper(Node *n) {
+ char *name = GetChar(n,"name");
+ char *iname = GetChar(n,"sym:name");
+ SwigType *d = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+ int newobject = (Getattr(n,"feature:new"))?1:0;
+ Parm *p;
+ char source[256],target[256],temp[256],argnum[32],args[32];
+ int i,numopt;
+ String *tm;
+ Wrapper *f;
+ int num_saved = (Getattr(n,"feature:new"))?1:0;
+ String *cleanup, *outarg;
+ bool mvr=(shadow && variable_wrapper_flag && !enum_flag);
+ bool mvrset=0;
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+ mvrset=(mvr && (strcmp(iname, Char(Swig_name_set(Swig_name_member(shadow_classname, name)))) == 0));
+
+ // if shadow and variable wrapper we want to snag the main contents
+ // of this function to stick in to the property handler....
+ if (mvr) { //shadow && variable_wrapper_flag && !enum_flag) {
+ String *member_function_name = NewString("");
+ String *php_function_name = NewString(iname);
+ if(strcmp(iname, Char(Swig_name_set(Swig_name_member(shadow_classname, name)))) == 0) {
+ Setattr(shadow_set_vars, php_function_name, name);
+ }
+ if(strcmp(iname, Char(Swig_name_get(Swig_name_member(shadow_classname, name)))) == 0) {
+ Setattr(shadow_get_vars, php_function_name, name);
+ }
+ Putc(toupper((int )*iname), member_function_name);
+ Printf(member_function_name, "%s", iname+1);
+
+ cpp_func(Char(member_function_name), d, l, php_function_name);
+
+ Delete(php_function_name);
+ Delete(member_function_name);
+ }
+
+ outarg = cleanup = NULL;
+ f = NewWrapper();
+ numopt = 0;
+
+ outarg = NewString("");
+ cleanup = NewString("");
+
+ // Special action for shadowing destructors under php.
+ // The real destructor is the resource list destructor, this is
+ // merely the thing that actually knows how to destroy...
+
+ if (destructor) {
+ String *destructorname=NewString("");
+ Printf(destructorname,"_%s",Swig_name_wrapper(iname));
+ Setattr(classnode,"destructor",destructorname);
+
+ Wrapper *df = NewWrapper();
+ Printf(df->def,"/* This function is designed to be called by the zend list destructors to typecast and do the actual destruction */\n"
+ "void %s(zend_rsrc_list_entry *rsrc, const char *type_name TSRMLS_DC) {\n",destructorname);
+
+ Wrapper_add_localv(df, "value", "swig_object_wrapper *value=(swig_object_wrapper *) rsrc->ptr", NIL);
+ Wrapper_add_localv(df, "ptr", "void *ptr=value->ptr", NIL);
+ Wrapper_add_localv(df, "newobject", "int newobject=value->newobject", NIL);
+ // Magic spell nicked from further down.
+ emit_args(d, l, df);
+ emit_attach_parmmaps(l,f);
+
+ // Get type of first arg, thing to be destructed
+ // Skip ignored arguments
+ {
+ p=l;
+ //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");}
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+
+ Printf(df->code,
+ " efree(value);\n"
+ " if (! newobject) return; /* can't delete it! */\n"
+ " SWIG_ZTS_ConvertResourceData(ptr,rsrc->type,type_name,(void **) &arg1,SWIGTYPE%s TSRMLS_CC);\n"
+ " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n"
+ ,SwigType_manglestr(pt), shadow_classname);
+ }
+ emit_action(n,df);
+
+ Printf(df->code,"}\n");
+
+ Wrapper_print(df,s_wrappers);
+ }
+
+ if (mvr) { // do prop[gs]et header
+ if (mvrset) Printf(f->def, "static int _wrap_%s(zend_property_reference *property_reference, pval *value) {\n",iname);
+ else Printf(f->def, "static pval _wrap_%s(zend_property_reference *property_reference) {\n",iname);
+ } else { // regular header
+ create_command(iname, Char(Swig_name_wrapper(iname)));
+ Printv(f->def, "ZEND_NAMED_FUNCTION(" , Swig_name_wrapper(iname), ") {\n", NIL);
+ }
+
+ emit_args(d, l, f);
+ /* Attach standard typemaps */
+
+ emit_attach_parmmaps(l,f);
+
+ int num_arguments = emit_num_arguments(l);
+ int num_required = emit_num_required(l);
+ numopt = num_arguments - num_required;
+
+ // we do +1 because we are going to push in this_ptr as arg0 if present
+ // or do we need to?
+
+ sprintf(args, "%s[%d]", "zval **args", num_arguments+1);
+
+ Wrapper_add_local(f, "args",args);
+ Wrapper_add_localv(f, "argbase", "int argbase=0", NIL);
+ // This generated code may be called
+ // 1) as an object method, or
+ // 2) as a class-method/function (without a "this_ptr")
+ // Option (1) has "this_ptr" for "this", option (2) needs it as
+ // first parameter
+ // NOTE: possible we ignore this_ptr as a param for native constructor
+
+ if (native_constructor) {
+ if (native_constructor==NATIVE_CONSTRUCTOR) Printf(f->code, "/* NATIVE Constructor */\nint self_constructor=1;\n");
+ else Printf(f->code, "/* ALTERNATIVE Constructor */\n");
+ }
+
+ if (mvr && ! mvrset) {
+ Wrapper_add_local(f, "_return_value", "zval _return_value");
+ Wrapper_add_local(f, "return_value", "zval *return_value=&_return_value");
+ };
+
+ // only let this_ptr count as arg[-1] if we are not a constructor
+ // if we are a constructor and this_ptr is null we are called as a class
+ // method and can make one of us
+ if (! mvr && native_constructor==0) Printf(f->code,
+ "if (this_ptr && this_ptr->type==IS_OBJECT) {\n"
+ " /* fake this_ptr as first arg (till we can work out how to do it better */\n"
+ " argbase++;\n"
+ "}\n");
+
+ // I'd like to write out:
+ //" //args[argbase++]=&this_ptr;\n"
+ // but zend_get_parameters_array_ex can't then be told to leave
+ // the first slot alone, so we have to check whether or not to access
+ // this_ptr explicitly in each case where we normally just read args[]
+
+ if(numopt > 0) { // membervariable wrappers do not have optional args
+ Wrapper_add_local(f, "arg_count", "int arg_count");
+ Printf(f->code,
+ "arg_count = ZEND_NUM_ARGS();\n"
+ "if(arg_count<(%d-argbase) || arg_count>(%d-argbase))\n"
+ "\tWRONG_PARAM_COUNT;\n\n",
+ num_required, num_arguments);
+
+ /* Verified args, retrieve them... */
+ Printf(f->code,
+ "if(zend_get_parameters_array_ex(arg_count-argbase,args)!=SUCCESS)"
+ "\n\t\tWRONG_PARAM_COUNT;\n\n");
+
+ } else if (!mvr) {
+ Printf(f->code,
+ "if(((ZEND_NUM_ARGS() + argbase )!= %d) || (zend_get_parameters_array_ex(%d-argbase, args)"
+ "!= SUCCESS)) {\n"
+ "WRONG_PARAM_COUNT;\n}\n\n",
+ num_arguments, num_arguments);
+ }
+
+ /* Now convert from php to C variables */
+ // At this point, argcount if used is the number of deliberatly passed args
+ // not including this_ptr even if it is used.
+ // It means error messages may be out by argbase with error
+ // reports. We can either take argbase into account when raising
+ // errors, or find a better way of dealing with _thisptr
+ // I would like, if objects are wrapped, to assume _thisptr is always
+ // _this and the and not the first argument
+ // This may mean looking at Lang::memberfunctionhandler
+
+ for (i = 0, p = l; i < num_arguments; i++) {
+ /* Skip ignored arguments */
+ //while (Getattr(p,"tmap:ignore")) { p = Getattr(p,"tmap:ignore:next");}
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+
+
+ if (mvr) { // do we assert that numargs=2, that i<2
+ if (i==0) sprintf(source,"&(property_reference->object)");
+ else sprintf(source,"&value");
+ } else {
+ // Do we fake this_ptr as arg0, or just possibly shift other args by 1 if we did fake?
+ if (i==0) sprintf(source, "((%d= (num_required))
+ Printf(f->code,"\tif(arg_count > %d) {\n", i);
+
+ Setattr(p,"emit:input", source);
+
+ if ((tm = Getattr(p,"tmap:in"))) {
+ Replaceall(tm,"$target",target);
+ Replaceall(tm,"$source",source);
+ Replaceall(tm,"$input", source);
+ Printf(f->code,"%s\n",tm);
+ p = Getattr(p,"tmap:in:next");
+ if (i >= num_required) {
+ Printf(f->code,"}\n");
+ }
+ continue;
+ } else {
+ Printf(stderr,"%s : Line %d, Unable to use type %s as a function argument.\n", input_file, line_number, SwigType_str(pt,0));
+ }
+ if (i>= num_required)
+ Printf(f->code,"\t}\n");
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:check"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (i = 0, p = l; p; i++) {
+ if ((tm = Getattr(p,"tmap:freearg"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Printv(cleanup,tm,"\n",NIL);
+ p = Getattr(p,"tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ num_saved = 0;
+ for (i=0,p = l; p;i++) {
+ if ((tm = Getattr(p,"tmap:argout"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Replaceall(tm,"$input",Getattr(p,"lname"));
+ Replaceall(tm,"$target","return_value");
+ Replaceall(tm,"$result","return_value");
+
+ String *in = Getattr(p,"emit:input");
+ if (in) {
+ sprintf(temp,"_saved[%d]", num_saved);
+ Replaceall(tm,"$arg",temp);
+ Printf(f->code,"_saved[%d] = %s;\n", num_saved, in);
+ num_saved++;
+ }
+ Printv(outarg,tm,"\n",NIL);
+ p = Getattr(p,"tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // These are saved for argout again...
+ if(num_saved) {
+ sprintf(temp, "_saved[%d]",num_saved);
+ // Used to be zval *, perhaps above we should use * %s
+ Wrapper_add_localv(f,"_saved","zval **",temp,NIL);
+ }
+
+ /* emit function call*/
+ if (destructor) {
+ // If it is a registered resource (and it always should be)
+ // then destroy it the resource way
+
+ Printf(f->code,
+ "/*if ((*args[0])->type==IS_RESOURCE) { */\n"
+ "/* Get zend list destructor to free it */\n"
+ "/* zend_list_delete(Z_LVAL_PP(args[0])); */\n"
+ "/* } else {*/ \n",name,name
+ );
+ // but leave the old way in for as long as we accept strings as swig objects
+ emit_action(n,f);
+ Printf(f->code,"/*}*/\n");
+ } else {
+ emit_action(n,f);
+ }
+
+ if((tm = Swig_typemap_lookup((char*)"out",d,iname,(char*)"result",(char*)"result",(char*)"return_value",0))) {
+ Replaceall(tm, "$input", "result");
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$target", "return_value");
+ Replaceall(tm, "$result", "return_value");
+ Replaceall(tm,"$owner", newobject ? "1" : "0");
+ Printf(f->code, "%s\n", tm);
+ // are we returning a wrapable object?
+ // I don't know if this test is comlete, I nicked it
+ if(is_shadow(d) && (SwigType_type(d) != T_ARRAY)) {
+ Printf(f->code,"/* Wrap this return value */\n");
+ if (native_constructor==NATIVE_CONSTRUCTOR) {
+ Printf(f->code, "if (this_ptr) {\n/* NATIVE Constructor, use this_ptr */\n");
+ Printf(f->code,"zval *_cPtr; MAKE_STD_ZVAL(_cPtr);\n"
+ "*_cPtr = *return_value;\n"
+ "INIT_ZVAL(*return_value);\n"
+ "add_property_zval(this_ptr,\"_cPtr\",_cPtr);\n"
+ "} else if (! this_ptr) ",shadow_classname);
+ }
+ { // THIS CODE only really needs writing out if the object to be returned
+ // Is being shadow-wrap-thingied
+ Printf(f->code, "{\n/* ALTERNATIVE Constructor, make an object wrapper */\n");
+ // Make object
+ String *shadowrettype = NewString("");
+ SwigToPhpType(d, iname, shadowrettype, shadow);
+
+ Printf(f->code,
+ "zval *obj, *_cPtr;\n"
+ "MAKE_STD_ZVAL(obj);\n"
+ "MAKE_STD_ZVAL(_cPtr);\n"
+ "*_cPtr = *return_value;\n"
+ "INIT_ZVAL(*return_value);\n");
+
+ if (! shadow) {
+ Printf(f->code,
+ "*return_value=*_cPtr;\n");
+ } else {
+ Printf(f->code,
+ "object_init_ex(obj,ptr_ce_swig_%s);\n"
+ "add_property_zval(obj,\"_cPtr\",_cPtr);\n"
+ "*return_value=*obj;\n",
+ shadowrettype);
+ }
+ Printf(f->code, "}\n");
+ }
+ } // end of if-shadow lark
+ } else {
+ Printf(stderr,"%s: Line %d, Unable to use return type %s in function %s.\n", input_file, line_number, SwigType_str(d,0), name);
+ }
+
+ if(outarg)
+ Printv(f->code,outarg,NIL);
+
+ if(cleanup)
+ Printv(f->code,cleanup,NIL);
+
+ // Whats this bit for?
+ if((tm = Swig_typemap_lookup((char*)"ret",d,iname,(char *)"result", (char*)"result",(char*)"",0))) {
+ Printf(f->code,"%s\n", tm);
+ }
+
+ Replaceall(f->code,"$cleanup",cleanup);
+ Replaceall(f->code,"$symname",iname);
+
+ if (mvr) {
+ if (! mvrset) Printf(f->code,"return _return_value;\n");
+ else Printf(f->code,"return SUCCESS;\n");
+ }
+
+ Printf(f->code, "}\n");
+ Wrapper_print(f,s_wrappers);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int OLDvariableWrapper(Node *n) {
+ char *name = GetChar(n,"name");
+ char *iname = GetChar(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+ String *tm;
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ SwigType_remember(t);
+
+ /* First link C variables to PHP */
+
+ tm = Swig_typemap_lookup_new("varinit", n, name, 0);
+ if(tm) {
+ Replaceall(tm, "$target", name);
+ Printf(s_vinit, "%s\n", tm);
+ } else {
+ Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
+ input_file, line_number, SwigType_str(t,0), name);
+ }
+
+ /* Now generate PHP -> C sync blocks */
+ tm = Swig_typemap_lookup_new("varin", n, name, 0);
+ /*
+ if(tm) {
+ Replaceall(tm, "$symname", iname);
+ Printf(f_c->code, "%s\n", tm);
+ } else {
+ Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
+ input_file, line_number, SwigType_str(t, 0), name);
+ }
+*/
+ /* Now generate C -> PHP sync blocks */
+/*
+ if(!Getattr(n,"feature:immutable")) {
+
+ tm = Swig_typemap_lookup_new("varout", n, name, 0);
+ if(tm) {
+ Replaceall(tm, "$symname", iname);
+ Printf(f_php->code, "%s\n", tm);
+ } else {
+ Printf(stderr,"%s: Line %d, Unable to link with type %s\n",
+ input_file, line_number, SwigType_str(t, 0), name);
+ }
+ }
+*/
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ char *name = GetChar(n,"name");
+ char *iname = GetChar(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ char *value = GetChar(n,"value");
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ String *rval;
+ String *tm;
+
+ SwigType_remember(type);
+
+ switch(SwigType_type(type)) {
+ case T_STRING:
+ rval = NewStringf("\"%s\"", value);
+ break;
+ case T_CHAR:
+ rval = NewStringf("\'%s\'", value);
+ break;
+ default:
+ rval = NewString(value);
+ }
+
+ if((tm = Swig_typemap_lookup_new("consttab", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ Printf(s_cinit, "%s\n", tm);
+ }
+ return SWIG_OK;
+ }
+
+ /*
+ * PHP4::pragma()
+ *
+ * Pragma directive.
+ *
+ * %pragma(php4) code="String" # Includes a string in the .php file
+ * %pragma(php4) include="file.pl" # Includes a file in the .php file
+ */
+
+ virtual int pragmaDirective(Node *n) {
+ if (!ImportMode) {
+ String *lang = Getattr(n,"lang");
+ String *type = Getattr(n,"name");
+ String *value = Getattr(n,"value");
+
+ if (Strcmp(lang,"php4") == 0) {
+
+ if (Strcmp(type, "code") == 0) {
+ if (value)
+ Printf(pragma_code, "%s\n", value);
+ } else if (Strcmp(type, "include") == 0) {
+ if (value)
+ Printf(pragma_incl, "include \"%s\";\n", value);
+ } else if (Strcmp(type, "phpinfo") == 0) {
+ if (value)
+ Printf(pragma_phpinfo, "%s\n", value);
+ } else {
+ Printf(stderr, "%s : Line %d. Unrecognized pragma.\n",
+ input_file, line_number);
+ }
+ }
+ }
+ return Language::pragmaDirective(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int classDeclaration(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ Setattr(n,"php:proxy",symname);
+ return Language::classDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int classHandler(Node *n) {
+ constructors=0;
+ //SwigType *t = Getattr(n, "classtype");
+ if(class_name) free(class_name);
+ class_name = Swig_copy_string(GetChar(n, "name"));
+ // String *use_class_name=SwigType_manglestr(SwigType_ltype(t));
+
+ if(shadow) {
+ char *rename = GetChar(n, "sym:name");
+ if (!addSymbol(rename,n)) return SWIG_ERROR;
+ shadow_classname = Swig_copy_string(rename);
+ cs_entry = NewString("");
+ Printf(cs_entry,"/* Function entries for %s */\n"
+ "static zend_function_entry %s_functions[] = {\n"
+ ,shadow_classname, shadow_classname);
+
+ if(Strcmp(shadow_classname, module) == 0) {
+ Printf(stderr, "class name cannot be equal to module name: %s\n", shadow_classname);
+ SWIG_exit(1);
+ }
+
+ Clear(shadow_classdef);
+ Clear(shadow_code);
+
+ have_default_constructor = 0;
+ shadow_enum_code = NewString("");
+ this_shadow_baseclass = NewString("");
+ this_shadow_multinherit = NewString("");
+ this_shadow_extra_code = NewString("");
+ this_shadow_import = NewString("");
+
+ shadow_get_vars = NewHash();
+ shadow_set_vars = NewHash();
+
+ /* Deal with inheritance */
+ List *baselist = Getattr(n, "bases");
+
+ if(baselist) {
+ int class_count = 0;
+ Node *base = Firstitem(baselist);
+
+ while(base && Getattr(base,"feature:ignore")) base = Nextitem(baselist);
+
+ if (base && is_shadow(Getattr(base, "name"))) {
+ class_count++;
+ Printf(this_shadow_baseclass, "%s", Getattr(base, "name"));
+ }
+
+ if (base) for(base = Nextitem(baselist); base; base = Nextitem(baselist)) {
+ if (Getattr(base,"feature:ignore")) continue;
+ if(is_shadow(Getattr(base, "name"))) {
+ class_count++;
+ Printf(this_shadow_multinherit, "%s ", Getattr(base, "name"));
+ }
+ }
+
+ if(class_count > 1) Printf(stderr, "Error: %s inherits from multiple base classes(%s %s). Multiple inheritance is not directly supported by PHP4, SWIG may support it at some point in the future.\n", shadow_classname, base, this_shadow_multinherit);
+ }
+
+ /* Write out class init code */
+ Printf(s_vdecl,"static zend_class_entry ce_swig_%s;\n",shadow_classname);
+ Printf(s_vdecl,"static zend_class_entry* ptr_ce_swig_%s=NULL;\n",shadow_classname);
+ }
+
+ classnode=n;
+ Language::classHandler(n);
+ classnode=0;
+
+ if(shadow) {
+ DOH *key;
+ int gcount, scount;
+ String *s_propget=NewString("");
+ String *s_propset=NewString("");
+ List *baselist = Getattr(n, "bases");
+ Node *base = NULL;
+
+ // If no constructor was generated (abstract class) we had better
+ // generate a constructor that raises an error about instantiating
+ // abstract classes
+ if (! constructors || Getattr(n,"abstract")) {
+ // have to write out fake constructor which raises an error when called
+ abstractConstructorHandler(n);
+ }
+
+ Printf(s_oinit,"/* Define class %s */\n"
+ "INIT_OVERLOADED_CLASS_ENTRY(ce_swig_%s,\"%(lower)s\",%s_functions,"
+ "NULL,_wrap_propget_%s,_wrap_propset_%s);\n",
+ shadow_classname,shadow_classname,shadow_classname,
+ shadow_classname,shadow_classname,shadow_classname);
+
+ // ******** Write property SET handlers
+ Printf(s_header,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname);
+ Printf(s_propset,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value) { \n"
+ " zval * _value;\n"
+ " zend_llist_element *element = property_reference->elements_list->head;\n"
+ " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n"
+ " if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n"
+ " /* set it ourselves as it is %s */\n"
+ " MAKE_STD_ZVAL(_value);\n"
+ " *_value=*value;\n"
+ " INIT_PZVAL(_value);\n"
+ " zval_copy_ctor(_value);\n"
+ " return add_property_zval_ex(property_reference->object,Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),_value);\n"
+ "}\n", shadow_classname, shadow_classname,shadow_classname);
+ Printf(s_header,"static int _propset_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname);
+ Printf(s_propset,"static int _propset_%s(zend_property_reference *property_reference, pval *value) {\n", shadow_classname);
+
+ if (baselist) base=Firstitem(baselist);
+ else base=NULL;
+ while(base && Getattr(base,"feature:ignore")) base = Nextitem(baselist);
+ key = Firstkey(shadow_set_vars);
+
+ // Print function header; we only need to find property name if there
+ // are properties for this class to look up...
+ if (key || ! base) { // or if we are base class and set it ourselves
+ Printf(s_propset," /* get the property name */\n"
+ " zend_llist_element *element = property_reference->elements_list->head;\n"
+ " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n"
+ " char *propname=Z_STRVAL_P(&(property->element));\n");
+ } else {
+ if (base) {
+ Printf(s_propset," /* No extra properties for subclass %s */\n",shadow_classname);
+ } else {
+ Printf(s_propset," /* No properties for base class %s */\n",shadow_classname);
+ }
+ }
+
+ scount=0;
+ while (key) {
+ if (scount++) Printf(s_propset," else");
+ Printf(s_propset," if (strcmp(propname,\"%s\")==0) {\n"
+ " return _wrap_%s(property_reference, value);\n"
+ " }",Getattr(shadow_set_vars,key),key);
+
+ key=Nextkey(shadow_set_vars);
+ }
+
+ if (scount) Printf(s_propset," else");
+
+ // If there is a base class then chain it's handler else set directly
+ // try each base class handler, else set directly...
+ if (base) {
+ Printf(s_propset, " {\n /* chain to base class */\n");
+ while(base) {
+ Printf(s_propset," if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n",
+ GetChar(base, "sym:name"));
+
+ base=Nextitem(baselist);
+ while (base && Getattr(base,"feature:ignore")) base=Nextitem(baselist);
+ }
+ Printf(s_propset," }\n");
+ }
+ Printf(s_propset," return FAILURE;\n}\n\n");
+
+ // ******** Write property GET handlers
+ Printf(s_header,"static pval _wrap_propget_%s(zend_property_reference *property_reference);\n", shadow_classname);
+ Printf(s_propget,"static pval _wrap_propget_%s(zend_property_reference *property_reference) {\n"
+ " pval result;\n"
+ " pval **_result;\n"
+ " zend_llist_element *element = property_reference->elements_list->head;\n"
+ " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n"
+ " result.type = IS_NULL;\n"
+ " if (_propget_%s(property_reference, &result)==SUCCESS) return result;\n"
+ " /* return it ourselves */\n"
+ " if (zend_hash_find(Z_OBJPROP_P(property_reference->object),Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),(void**)&_result)==SUCCESS) {\n"
+ " zval *_value;\n"
+ " MAKE_STD_ZVAL(_value);"
+ " *_value=**_result;\n"
+ " INIT_PZVAL(_value);\n"
+ " zval_copy_ctor(_value);\n"
+ " return *_value;\n"
+ " }\n"
+ " result.type = IS_NULL;\n"
+ " return result;\n"
+ "}\n", shadow_classname, shadow_classname);
+ Printf(s_header,"static int _propget_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname);
+ Printf(s_propget,"static int _propget_%s(zend_property_reference *property_reference, pval *value) {\n", shadow_classname);
+
+ if (baselist) base=Firstitem(baselist);
+ else base=NULL;
+ while(base && Getattr(base,"feature:ignore")) base = Nextitem(baselist);
+ key = Firstkey(shadow_get_vars);
+
+ // Print function header; we only need to find property name if there
+ // are properties for this class to look up...
+ if (key || !base ) { // or if we are base class...
+ Printf(s_propget," /* get the property name */\n"
+ " zend_llist_element *element = property_reference->elements_list->head;\n"
+ " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n"
+ " char *propname=Z_STRVAL_P(&(property->element));\n");
+ } else {
+ if (base) {
+ Printf(s_propget," /* No extra properties for subclass %s */\n",shadow_classname);
+ } else {
+ Printf(s_propget," /* No properties for base class %s */\n",shadow_classname);
+ }
+ }
+
+ gcount=0;
+ while (key) {
+ if (gcount++) Printf(s_propget," else");
+ Printf(s_propget," if (strcmp(propname,\"%s\")==0) {\n"
+ " *value=_wrap_%s(property_reference);\n"
+ " return SUCCESS;\n"
+ " }",Getattr(shadow_get_vars,key),key);
+
+ key=Nextkey(shadow_get_vars);
+ }
+
+ if (gcount) Printf(s_propget," else");
+
+ // If there is a base class then chain it's handler else return null
+ if (base) {
+ Printf(s_propget, " {\n /* chain to base class */\n");
+ while(base) {
+ Printf(s_propget," if (_propget_%s(property_reference, value)==SUCCESS) return SUCCESS;\n",
+ GetChar(base, "sym:name"));
+
+ base=Nextitem(baselist);
+ while (base && Getattr(base,"feature:ignore")) base=Nextitem(baselist);
+ }
+ Printf(s_propget," }\n");
+ }
+ Printf(s_propget," return FAILURE;\n}\n\n");
+
+ // wrappers generated now...
+
+ // add wrappers to output code
+ Printf(s_wrappers,"/* property handler for class %s */\n",shadow_classname);
+ Printv(s_wrappers,s_propget,s_propset,NIL);
+
+ // Save class in class table
+ if (baselist) base=Firstitem(baselist);
+ else base=NULL;
+ while(base && Getattr(base,"feature:ignore")) base = Nextitem(baselist);
+
+ if (base) {
+ Printf(s_oinit,"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,&ce_swig_%s,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
+ shadow_classname,shadow_classname,GetChar(base, "sym:name"), shadow_classname);
+ } else {
+ Printf(s_oinit,"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,NULL,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
+ shadow_classname,shadow_classname, shadow_classname);
+ }
+ Printf(s_oinit,"\n");
+
+
+ Printv(f_phpcode, shadow_classdef, shadow_code, NIL);
+
+ // Write the enum initialisation code in a static block
+ // These are all the enums defined withing the c++ class.
+
+ // PHP Needs to handle shadow enums properly still
+ if(strlen(Char(shadow_enum_code)) != 0 ) Printv(f_phpcode, "{\n /* enum */\n", shadow_enum_code, " }\n", NIL);
+
+ free(shadow_classname);
+ shadow_classname = NULL;
+
+ Delete(shadow_enum_code); shadow_enum_code = NULL;
+ Delete(this_shadow_baseclass); this_shadow_baseclass = NULL;
+ Delete(this_shadow_extra_code); this_shadow_extra_code = NULL;
+ Delete(this_shadow_import); this_shadow_import = NULL;
+ Delete(shadow_set_vars); shadow_set_vars = NULL;
+ Delete(shadow_get_vars); shadow_get_vars = NULL;
+ Delete(this_shadow_multinherit); this_shadow_multinherit = NULL;
+
+ Printf(all_cs_entry,"%s { NULL, NULL, NULL}\n};\n",cs_entry);
+ //??delete cs_entry;
+ cs_entry=NULL;
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberfunctionHandler(Node *n) {
+ char *name = GetChar(n, "name");
+ char *iname = GetChar(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+
+ this->Language::memberfunctionHandler(n);
+
+ if(shadow) {
+ char *realname = iname ? iname : name;
+ String *php_function_name = Swig_name_member(shadow_classname, realname);
+
+ cpp_func(iname, t, l, realname, php_function_name);
+
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int membervariableHandler(Node *n) {
+
+ wrapping_member = 1;
+ variable_wrapper_flag = 1;
+ Language::membervariableHandler(n);
+ wrapping_member = 0;
+ variable_wrapper_flag = 0;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ char *name = GetChar(n, "name");
+ char *iname = GetChar(n, "sym:name");
+
+ Language::staticmemberfunctionHandler(n);
+
+ if(shadow) {
+ String *symname = Getattr(n, "sym:name");
+ static_flag = 1;
+ char *realname = iname ? iname : name;
+ String *php_function_name = Swig_name_member(shadow_classname, realname);
+ cpp_func(Char(symname), Getattr(n, "type"), Getattr(n, "parms"), symname, php_function_name);
+ static_flag = 0;
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmembervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ SwigType *d = Getattr(n, "type");
+ char *iname = GetChar(n, "sym:name");
+ char *name = GetChar(n, "name");
+ String *static_name = NewStringf("%s::%s", class_name, name);
+// String *use_class_name=SwigType_manglestr(SwigType_ltype(t));
+ Wrapper *f;
+
+ /* A temporary(!) hack for static member variables.
+ * Php currently supports class functions, but not class variables.
+ * Until it does, we convert a class variable to a class function
+ * that returns the current value of the variable. E.g.
+ *
+ * class Example {
+ * public:
+ * static int ncount;
+ * };
+ *
+ * would be available in php as Example::ncount()
+ */
+ static_flag = 1;
+ if(Getattr(n,"feature:immutable")) {
+ const_flag = 1;
+ }
+ cpp_func(iname, d, 0, iname);
+ static_flag = 0;
+
+ create_command(iname, Char(Swig_name_wrapper(iname)));
+
+ f = NewWrapper();
+
+ Printv(f->def, "ZEND_NAMED_FUNCTION(", Swig_name_wrapper(iname), ") {\n", NIL);
+
+ /* If a argument is given we set the variable. Then we return
+ * the current value
+ */
+
+ Printf(f->code,
+ "zval **args[1];\n"
+ "int argcount;\n\n"
+ "argcount = ZEND_NUM_ARGS();\n"
+ "if(argcount > %d) WRONG_PARAM_COUNT;\n\n", (const_flag? 0 : 1));
+
+ if(!const_flag) {
+ Printf(f->code, "if(argcount) {\n");
+
+ Printf(f->code, "if(zend_get_parameters_array_ex(argcount, args) != SUCCESS) WRONG_PARAM_COUNT;\n");
+
+ switch(SwigType_type(d)) {
+ case T_BOOL:
+ case T_INT:
+ case T_SHORT:
+ case T_LONG:
+ case T_SCHAR:
+ case T_UINT:
+ case T_USHORT:
+ case T_ULONG:
+ case T_UCHAR:
+ Printf(f->code,
+ "convert_to_long_ex(args[0]);\n"
+ "%s = Z_LVAL_PP(args[0]);\n", static_name);
+ break;
+ case T_CHAR:
+ Printf(f->code,
+ "convert_to_string_ex(args[0]);\n"
+ "%s = estrdup(Z_STRVAL(args[0]));\n", static_name);
+ break;
+ case T_DOUBLE:
+ case T_FLOAT:
+ Printf(f->code,
+ "convert_to_double_ex(args[0]);\n"
+ "%s = Z_DVAL_PP(args[0]);\n",
+ static_name);
+ break;
+ case T_VOID:
+ break;
+ case T_USER:
+ Printf(f->code, "convert_to_string_ex(args[0]);\n");
+ get_pointer(Char(iname), (char*)"variable", (char*)"args[0]", Char(static_name), d, f->code, (char *)"RETURN_FALSE");
+ break;
+ case T_POINTER:
+ case T_ARRAY:
+ case T_REFERENCE:
+ Printf(f->code, "convert_to_string_ex(args[0]);\n");
+ get_pointer(Char(iname), (char*)"variable", (char*)"args[0]", Char(static_name), d, f->code, (char*)"RETURN_FALSE");
+ break;
+ default:
+ Printf(stderr,"%s : Line %d, Unable to use type %s as a class variable.\n", input_file, line_number, SwigType_str(d,0));
+ break;
+ }
+
+ Printf(f->code, "}\n\n");
+
+ } /* end of const_flag */
+
+ switch(SwigType_type(d)) {
+ case T_BOOL:
+ case T_INT:
+ case T_SHORT:
+ case T_LONG:
+ case T_SCHAR:
+ case T_UINT:
+ case T_USHORT:
+ case T_ULONG:
+ case T_UCHAR:
+ Printf(f->code,
+ "RETURN_LONG(%s);\n", static_name);
+ break;
+ case T_DOUBLE:
+ case T_FLOAT:
+ Printf(f->code,
+ "RETURN_DOUBLE(%s);\n", static_name);
+ break;
+ case T_CHAR:
+ Printf(f->code,
+ "{\nchar ctemp[2];\n"
+ "ctemp[0] = %s;\n"
+ "ctemp[1] = 0;\n"
+ "RETURN_STRING(ctemp, 1);\n}\n",
+ static_name);
+ break;
+
+ case T_USER:
+ case T_POINTER:
+ Printf(f->code,
+ "SWIG_SetPointerZval(return_value, (void *)%s, "
+ "SWIGTYPE%s);\n", static_name, SwigType_manglestr(d));
+ break;
+ case T_STRING:
+ Printf(f->code, "RETURN_STRING(%s, 1);\n", static_name);
+ break;
+ }
+
+
+ Printf(f->code, "}\n");
+
+ const_flag = 0;
+
+ Wrapper_print(f, s_wrappers);
+
+ return SWIG_OK;
+ }
+
+
+ void SwigToPhpType(SwigType *t, String_or_char *pname, String* php_type, int shadow_flag) {
+ char *ptype = 0;
+
+ if(shadow_flag)
+ ptype = PhpTypeFromTypemap((char*)"pstype", t, pname,(char*)"");
+ if(!ptype)
+ ptype = PhpTypeFromTypemap((char*)"ptype",t,pname,(char*)"");
+
+
+ if(ptype) {
+ Printf(php_type, ptype);
+ free(ptype);
+ }
+ else {
+ /* Map type here */
+ switch(SwigType_type(t)) {
+ case T_CHAR:
+ case T_SCHAR:
+ case T_UCHAR:
+ case T_SHORT:
+ case T_USHORT:
+ case T_INT:
+ case T_UINT:
+ case T_LONG:
+ case T_ULONG:
+ case T_FLOAT:
+ case T_DOUBLE:
+ case T_BOOL:
+ case T_STRING:
+ case T_VOID:
+ Printf(php_type, "");
+ break;
+ case T_POINTER:
+ case T_REFERENCE:
+ case T_USER:
+ if(shadow_flag && is_shadow(t))
+ Printf(php_type, Char(is_shadow(t)));
+ else
+ Printf(php_type, "");
+ break;
+ case T_ARRAY:
+ /* TODO */
+ break;
+ default:
+ Printf(stderr, "SwigToPhpType: unhandled data type: %s\n", SwigType_str(t,0));
+ break;
+ }
+ }
+ }
+
+
+ char *PhpTypeFromTypemap(char *op, SwigType *t, String_or_char *pname, String_or_char *lname) {
+ String *tms;
+ char bigbuf[1024];
+ char *tm;
+ char *c = bigbuf;
+ if(!(tms = Swig_typemap_lookup(op, t, pname, lname, (char*)"", (char*)"", NULL))) return NULL;
+
+ tm = Char(tms);
+ while(*tm && (isspace(*tm) || *tm == '{')) tm++;
+ while(*tm && *tm != '}') *c++ = *tm++;
+ *c='\0';
+ return Swig_copy_string(bigbuf);
+ }
+
+ int abstractConstructorHandler(Node *n) {
+ char *iname = GetChar(n, "sym:name");
+ if (shadow) {
+ Wrapper *f;
+ f = NewWrapper();
+
+ // constructor header
+ if (cs_entry) Printf(cs_entry,
+ " ZEND_NAMED_FE(%(lower)s,\n"
+ " _wrap_new_%s, NULL)\n", iname,iname);
+ // now constructor body
+ Printf(f_h, "ZEND_NAMED_FUNCTION(_wrap_new_%s);\n",iname);
+ Printf(f->def, "ZEND_NAMED_FUNCTION(_wrap_new_%s) {\n"
+ "zend_error(E_ERROR,\"Cannot create swig object type: %s as the underlying object is abstract\");\n"
+ "}\n\n", iname, iname);
+ Wrapper_print(f,s_wrappers);
+ DelWrapper(f);
+ }
+ return SWIG_OK;
+ }
+ /* ------------------------------------------------------------
+ * constructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+ char *iname = GetChar(n, "sym:name");
+
+ if (shadow) native_constructor = (strcmp(iname, shadow_classname) == 0)?\
+ NATIVE_CONSTRUCTOR:ALTERNATIVE_CONSTRUCTOR;
+ else native_constructor=0;
+ constructors++;
+ Language::constructorHandler(n);
+
+ if(shadow) {
+ // But we also need one per wrapped-class
+ if (cs_entry) Printf(cs_entry,
+ " ZEND_NAMED_FE(%(lower)s,\n"
+ " _wrap_new_%s, NULL)\n", iname,iname);
+ }
+
+ native_constructor = 0;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorHandler(Node *n) {
+ char *iname = GetChar(n, "sym:name");
+
+ destructor=1;
+ Language::destructorHandler(n);
+ destructor=0;
+
+ // we don't give user access to destructors, they have to unset var
+ // and let php dispose instead
+ if(0 && shadow) {
+ // But we also need one per wrapped-class
+ if (cs_entry) Printf(cs_entry,
+ " ZEND_NAMED_FE(_destroy_%(lower)s,\n"
+ " _wrap_delete_%s, NULL)\n", iname,iname);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberconstantHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberconstantHandler(Node *n) {
+ wrapping_member = 1;
+ Language::memberconstantHandler(n);
+ wrapping_member = 0;
+ return SWIG_OK;
+ }
+
+ // This method is quite stale and ought to be factored out
+ void cpp_func(char *iname, SwigType *t, ParmList *l, String *php_function_name, String *handler_name = NULL) {
+ if(!shadow) return;
+
+ // if they didn't provide a handler name, use the realname
+ if (! handler_name) handler_name=php_function_name;
+
+ if(l) {
+ if(SwigType_type(Getattr(l, "type")) == T_VOID) {
+ l = nextSibling(l);
+ }
+ }
+
+ // But we also need one per wrapped-class
+ // Printf(f_h, "x ZEND_NAMED_FUNCTION(%s);\n", Swig_name_wrapper(handler_name));
+ if (cs_entry && !(variable_wrapper_flag && shadow)) Printf(cs_entry,
+ " ZEND_NAMED_FE(%(lower)s,\n"
+ " %s, NULL)\n", php_function_name,Swig_name_wrapper(handler_name));
+
+ if(variable_wrapper_flag) { return; }
+
+ /* Workaround to overcome Getignore(p) not working - p does not always
+ * have the Getignore attribute set. Noticeable when cpp_func is called
+ * from cpp_member_func()
+ */
+
+ Wrapper *f = NewWrapper();
+ emit_args(NULL, l, f);
+ DelWrapper(f);
+
+ /*Workaround end */
+
+ }
+
+}; /* class PHP4 */
+
+/* -----------------------------------------------------------------------------
+ * swig_php() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static PHP4 *maininstance=0;
+
+// We use this function to be able to write out zend_register_list_destructor_ex
+// lines for most things in the type table
+// NOTE: it's a function NOT A PHP4::METHOD
+extern "C"
+void typetrace(SwigType *ty, String *mangled, String *clientdata) {
+ Node *class_node;
+ if (!zend_types) {
+ zend_types=NewHash();
+ }
+ // we want to know if the type which reduced to this has a constructor
+ if ((class_node=maininstance->classLookup(ty))) {
+ if (! Getattr(zend_types,mangled)) {
+ // OK it may have been set before by a different SwigType but it would
+ // have had the same underlying class node I think
+ // - it is certainly required not to have different originating class
+ // nodes for the same SwigType
+ Setattr(zend_types,mangled,class_node);
+ }
+ } else { // a non-class pointer
+ Setattr(zend_types,mangled,NOTCLASS);
+ }
+ if (r_prevtracefunc) (*r_prevtracefunc)(ty, mangled, (String *) clientdata);
+}
+
+extern "C" Language *
+swig_php(void) {
+ maininstance=new PHP4();
+ if (! r_prevtracefunc) {
+ r_prevtracefunc=SwigType_remember_trace(typetrace);
+ } else {
+ Printf(stderr,"php4 Typetrace vector already saved!\n");
+ assert(0);
+ }
+ return maininstance;
+}
+
diff --git a/Source/Modules/pike.cxx b/Source/Modules/pike.cxx
new file mode 100644
index 000000000..bcd51763e
--- /dev/null
+++ b/Source/Modules/pike.cxx
@@ -0,0 +1,881 @@
+/***********************************************************************
+ * Pike language module for SWIG
+ ***********************************************************************/
+
+char cvsroot_pike_cxx[] = "$Header$";
+
+#include "swigmod.h"
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+
+class PIKE : public Language {
+private:
+
+ File *f_runtime;
+ File *f_header;
+ File *f_wrappers;
+ File *f_init;
+ String *PrefixPlusUnderscore;
+ int current;
+
+ // Wrap modes
+ enum {
+ NO_CPP,
+ MEMBER_FUNC,
+ CONSTRUCTOR,
+ DESTRUCTOR,
+ MEMBER_VAR,
+ CLASS_CONST,
+ STATIC_FUNC,
+ STATIC_VAR
+ };
+
+public:
+
+ /* ---------------------------------------------------------------------
+ * PIKE()
+ *
+ * Initialize member data
+ * --------------------------------------------------------------------- */
+
+ PIKE() {
+ f_runtime = 0;
+ f_header = 0;
+ f_wrappers = 0;
+ f_init = 0;
+ PrefixPlusUnderscore = 0;
+ current = NO_CPP;
+ }
+
+ /* ---------------------------------------------------------------------
+ * main()
+ *
+ * Parse command line options and initializes variables.
+ * --------------------------------------------------------------------- */
+
+ virtual void main(int argc, char *argv[]) {
+
+ /* Set location of SWIG library */
+ SWIG_library_directory("pike");
+
+ /* Look for certain command line options */
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp (argv[i], "-ldflags") == 0) {
+ printf("%s\n", SWIG_PIKE_RUNTIME);
+ SWIG_exit(EXIT_SUCCESS);
+ }
+ }
+ }
+
+ /* Add a symbol to the parser for conditional compilation */
+ Preprocessor_define("SWIGPIKE 1", 0);
+
+ /* Set language-specific configuration file */
+ SWIG_config_file("pike.swg");
+
+ /* Set typemap language */
+ SWIG_typemap_lang("pike");
+
+ /* Enable overloaded methods support */
+ allow_overloading();
+ }
+
+ /* ---------------------------------------------------------------------
+ * top()
+ * --------------------------------------------------------------------- */
+
+ virtual int top(Node *n) {
+ /* Get the module name */
+ String *module = Getattr(n, "name");
+
+ /* Get the output file name */
+ String *outfile = Getattr(n, "outfile");
+
+ /* Open the output file */
+ f_runtime = NewFile(outfile, "w");
+ if (!f_runtime) {
+ Printf(stderr, "*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+
+ /* Standard stuff for the SWIG runtime section */
+ Swig_banner(f_runtime);
+ if (NoInclude) {
+ Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
+ }
+
+ Printf(f_header, "#define SWIG_init pike_module_init\n");
+ Printf(f_header, "#define SWIG_name \"%s\"\n\n", module);
+
+ /* Change naming scheme for constructors and destructors */
+ Swig_name_register("construct","%c_create");
+ Swig_name_register("destroy","%c_destroy");
+
+ /* Current wrap type */
+ current = NO_CPP;
+
+ /* Emit code for children */
+ Language::top(n);
+
+ /* Close the initialization function */
+ Printf(f_init, "}\n");
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+
+ /* Close all of the files */
+ Dump(f_header, f_runtime);
+ Dump(f_wrappers, f_runtime);
+ Wrapper_pretty_print(f_init, f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_runtime);
+ Delete(f_runtime);
+
+ /* Done */
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * importDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int importDirective(Node *n) {
+ String *modname = Getattr(n,"module");
+ if (modname) {
+ Printf(f_init,"pike_require(\"%s\");\n", modname);
+ }
+ return Language::importDirective(n);
+ }
+
+ /* ------------------------------------------------------------
+ * strip()
+ *
+ * For names that begin with the current class prefix plus an
+ * underscore (e.g. "Foo_enum_test"), return the base function
+ * name (i.e. "enum_test").
+ * ------------------------------------------------------------ */
+
+ String *strip(const DOHString_or_char *name) {
+ String *s = Copy(name);
+ if (Strncmp(name, PrefixPlusUnderscore, Len(PrefixPlusUnderscore)) != 0) {
+ return s;
+ }
+ Replaceall(s, PrefixPlusUnderscore, "");
+ return s;
+ }
+
+ /* ------------------------------------------------------------
+ * add_method()
+ * ------------------------------------------------------------ */
+
+ void add_method(Node *n, const DOHString_or_char *name, const DOHString_or_char *function, const DOHString_or_char *description) {
+ String *rename;
+ if (current != NO_CPP) {
+ rename = strip(name);
+ } else {
+ rename = NewString(name);
+ }
+ Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
+ Delete(rename);
+ }
+
+ /* ---------------------------------------------------------------------
+ * functionWrapper()
+ *
+ * Create a function declaration and register it with the interpreter.
+ * --------------------------------------------------------------------- */
+
+ virtual int functionWrapper(Node *n) {
+
+ String *name = Getattr(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ SwigType *d = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+
+ Parm *p;
+ String *tm;
+ int i;
+
+ String *overname = 0;
+ if (Getattr(n,"sym:overloaded")) {
+ overname = Getattr(n,"sym:overname");
+ } else {
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+ }
+
+ Wrapper *f = NewWrapper();
+
+ /* Write code to extract function parameters. */
+ emit_args(d, l, f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l,f);
+ Setattr(n,"wrap:parms",l);
+
+ /* Get number of required and total arguments */
+ int num_arguments = emit_num_arguments(l);
+ int varargs = emit_isvarargs(l);
+
+ /* Which input argument to start with? */
+ int start = (current == MEMBER_FUNC || current == MEMBER_VAR || current == DESTRUCTOR) ? 1 : 0;
+
+ /* Offset to skip over the attribute name */
+ // int offset = (current == MEMBER_VAR) ? 1 : 0;
+ int offset = 0;
+
+ String *wname = Swig_name_wrapper(iname);
+ if (overname) {
+ Append(wname,overname);
+ }
+
+ Printv(f->def, "static void ", wname, "(INT32 args) {", NIL);
+
+ /* Generate code for argument marshalling */
+ String *description = NewString("");
+ char source[64];
+ for (i = 0, p = l; i < num_arguments; i++) {
+
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *ln = Getattr(p,"lname");
+
+ if (i < start) {
+ String *lstr = SwigType_lstr(pt,0);
+ Printf(f->code, "%s = (%s) THIS;\n", ln, lstr);
+ Delete(lstr);
+ } else {
+ /* Look for an input typemap */
+ sprintf(source, "sp[%d-args]", i-start+offset);
+ if ((tm = Getattr(p,"tmap:in"))) {
+ Replaceall(tm, "$source", source);
+ Replaceall(tm, "$target", ln);
+ Replaceall(tm, "$input", source);
+ Setattr(p, "emit:input", source);
+ Printf(f->code, "%s\n", tm);
+ String *pikedesc = Getattr(p, "tmap:in:pikedesc");
+ if (pikedesc) {
+ Printv(description, pikedesc, " ", NIL);
+ }
+ p = Getattr(p,"tmap:in:next");
+ continue;
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument.\n",SwigType_str(pt,0));
+ break;
+ }
+ }
+ p = nextSibling(p);
+ }
+
+ /* Check for trailing varargs */
+ if (varargs) {
+ if (p && (tm = Getattr(p,"tmap:in"))) {
+ Replaceall(tm,"$input", "varargs");
+ Printv(f->code,tm,"\n",NIL);
+ }
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:check"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ String *cleanup = NewString("");
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:freearg"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Printv(cleanup,tm,"\n",NIL);
+ p = Getattr(p,"tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ String *outarg = NewString("");
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:argout"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Replaceall(tm,"$target","resultobj");
+ Replaceall(tm,"$arg",Getattr(p,"emit:input"));
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(outarg,tm,"\n",NIL);
+ p = Getattr(p,"tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Emit the function call */
+ emit_action(n,f);
+
+ /* Clear the return stack */
+ Printf(f->code, "pop_n_elems(args);\n");
+
+ /* Return the function value */
+ if (current == CONSTRUCTOR) {
+ Printv(f->code, "THIS = (void *) result;\n", NIL);
+ Printv(description, ", tVoid", NIL);
+ } else if (current == DESTRUCTOR) {
+ Printv(description, ", tVoid", NIL);
+ } else {
+ Wrapper_add_local(f, "resultobj", "struct object *resultobj");
+ Printv(description, ", ", NIL);
+ if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
+ Replaceall(tm,"$source", "result");
+ Replaceall(tm,"$target", "resultobj");
+ Replaceall(tm,"$result", "resultobj");
+ if (Getattr(n,"feature:new")) {
+ Replaceall(tm,"$owner","1");
+ } else {
+ Replaceall(tm,"$owner","0");
+ }
+ String *pikedesc = Getattr(n, "tmap:out:pikedesc");
+ if (pikedesc) {
+ Printv(description, pikedesc, NIL);
+ }
+ Printf(f->code,"%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s in function %s.\n", SwigType_str(d,0), name);
+ }
+ }
+
+ /* Output argument output code */
+ Printv(f->code,outarg,NIL);
+
+ /* Output cleanup code */
+ Printv(f->code,cleanup,NIL);
+
+ /* Look to see if there is any newfree cleanup code */
+ if (Getattr(n,"feature:new")) {
+ if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printf(f->code,"%s\n",tm);
+ }
+ }
+
+ /* See if there is any return cleanup code */
+ if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) {
+ Replaceall(tm,"$source","result");
+ Printf(f->code,"%s\n",tm);
+ }
+
+ /* Close the function */
+ Printf(f->code, "}\n");
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code,"$cleanup",cleanup);
+
+ /* Substitute the function name */
+ Replaceall(f->code,"$symname",iname);
+ Replaceall(f->code,"$result","resultobj");
+
+ /* Dump the function out */
+ Wrapper_print(f,f_wrappers);
+
+ /* Now register the function with the interpreter. */
+ if (!Getattr(n,"sym:overloaded")) {
+ add_method(n, iname, wname, description);
+ } else {
+ Setattr(n,"wrap:name", wname);
+ if (!Getattr(n,"sym:nextSibling")) {
+ dispatchFunction(n);
+ }
+ }
+
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(description);
+ Delete(wname);
+ DelWrapper(f);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * dispatchFunction()
+ *
+ * Emit overloading dispatch function
+ * ------------------------------------------------------------ */
+
+ void dispatchFunction(Node *n) {
+ /* Last node in overloaded chain */
+
+ int maxargs;
+ String *tmp = NewString("");
+ String *dispatch = Swig_overload_dispatch(n,"return %s(self,args);",&maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *f = NewWrapper();
+ String *symname = Getattr(n,"sym:name");
+ String *wname = Swig_name_wrapper(symname);
+
+ Printv(f->def,
+ "struct object *", wname,
+ "(struct object *self, struct object *args) {",
+ NULL);
+
+
+ Wrapper_add_local(f,"argc","INT32 argc");
+ Printf(tmp,"struct object *argv[%d]", maxargs+1);
+ Wrapper_add_local(f,"argv",tmp);
+ Wrapper_add_local(f,"ii","INT32 ii");
+ Printf(f->code,"argc = sizeof(args);\n");
+ Printf(f->code,"for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n",maxargs);
+ Printf(f->code,"argv[ii] = array_index(args,&argv[ii],ii);\n");
+ Printf(f->code,"}\n");
+
+ Replaceall(dispatch,"$args","self,args");
+ Printv(f->code,dispatch,"\n",NIL);
+ Printf(f->code,"No matching function for overloaded '%s'\n", symname);
+ Printf(f->code,"return NULL;\n");
+ Printv(f->code,"}\n",NIL);
+ Wrapper_print(f,f_wrappers);
+ add_method(n,symname,wname,0);
+
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(tmp);
+ Delete(wname);
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+ // return Language::variableWrapper(n);
+
+ String *name = Getattr(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+
+ String *wname;
+ // static int have_globals = 0;
+ String *tm;
+ Wrapper *getf, *setf;
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ getf = NewWrapper();
+ setf = NewWrapper();
+
+ wname = Swig_name_wrapper(iname);
+
+ /* Create a function for setting the value of the variable */
+
+ Printf(setf->def,"static int %s_set(object *_val) {", wname);
+ if (!Getattr(n,"feature:immutable")) {
+ if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) {
+ Replaceall(tm,"$source","_val");
+ Replaceall(tm,"$target",name);
+ Replaceall(tm,"$input","_val");
+ Printf(setf->code,"%s\n",tm);
+ Delete(tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number,
+ "Unable to set variable of type %s.\n", SwigType_str(t,0));
+ }
+ Printf(setf->code," return 0;\n");
+ } else {
+ /* Is a readonly variable. Issue an error */
+
+ Printv(setf->code,
+ tab4, "Variable $iname is read-only.\n",
+ tab4, "return 1;\n",
+ NIL);
+
+ }
+
+ Printf(setf->code,"}\n");
+ Wrapper_print(setf,f_wrappers);
+
+ /* Create a function for getting the value of a variable */
+ Printf(getf->def,"static object *%s_get() {", wname);
+ Wrapper_add_local(getf,"pikeobj", "object *pyobj");
+ if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) {
+ Replaceall(tm,"$source",name);
+ Replaceall(tm,"$target","pikeobj");
+ Replaceall(tm,"$result","pikeobj");
+ Printf(getf->code,"%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number,
+ "Unable to link with type %s\n", SwigType_str(t,0));
+ }
+
+ Printf(getf->code," return pikeobj;\n}\n");
+ Wrapper_print(getf,f_wrappers);
+
+ /* Now add this to the variable linking mechanism */
+ Printf(f_init,"\t SWIG_addvarlink(SWIG_globals,(char*)\"%s\",%s_get, %s_set);\n", iname, wname, wname);
+
+ DelWrapper(setf);
+ DelWrapper(getf);
+ return SWIG_OK;
+
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+
+ Swig_require(&n, "*sym:name", "type", "value", NIL);
+
+ String *symname = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ String *value = Getattr(n, "value");
+
+ /* Special hook for member pointer */
+ if (SwigType_type(type) == T_MPOINTER) {
+ String *wname = Swig_name_wrapper(symname);
+ Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value);
+ value = wname;
+ }
+
+ /* Perform constant typemap substitution */
+ String *tm = Swig_typemap_lookup_new("constant", n, value, 0);
+ if (tm) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", symname);
+ Replaceall(tm, "$symname", symname);
+ Replaceall(tm, "$value", value);
+ Printf(f_init, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
+ "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value);
+ }
+
+ Swig_restore(&n);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int nativeWrapper(Node *n) {
+ // return Language::nativeWrapper(n);
+ String *name = Getattr(n,"sym:name");
+ String *wrapname = Getattr(n,"wrap:name");
+
+ if (!addSymbol(wrapname,n)) return SWIG_ERROR;
+
+ add_method(n, name, wrapname,0);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * enumDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int enumDeclaration(Node *n) {
+ return Language::enumDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * enumvalueDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int enumvalueDeclaration(Node *n) {
+ return Language::enumvalueDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int classDeclaration(Node *n) {
+ return Language::classDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int classHandler(Node *n) {
+
+ String *symname = Getattr(n, "sym:name");
+ if (!addSymbol(symname, n))
+ return SWIG_ERROR;
+
+ PrefixPlusUnderscore = NewStringf("%s_", getClassPrefix());
+
+ Printf(f_init, "start_new_program();\n");
+
+ /* Handle inheritance */
+ List *baselist = Getattr(n,"bases");
+ if (baselist && Len(baselist) > 0) {
+ Node *base = Firstitem(baselist);
+ while (base) {
+ char *basename = Char(Getattr(base,"name"));
+ if (SwigType_istemplate(basename)) {
+ basename = Char(SwigType_namestr(basename));
+ }
+ SwigType *basetype = NewString(basename);
+ SwigType_add_pointer(basetype);
+ SwigType_remember(basetype);
+ String *basemangle = SwigType_manglestr(basetype);
+ Printf(f_init, "low_inherit((struct program *) SWIGTYPE%s->clientdata, 0, 0, 0, 0, 0);\n", basemangle);
+ Delete(basemangle);
+ Delete(basetype);
+ base = Nextitem(baselist);
+ }
+ } else {
+ Printf(f_init, "ADD_STORAGE(swig_object_wrapper);\n");
+ }
+
+ Language::classHandler(n);
+
+ /* Accessors for member variables */
+ /*
+ List *membervariables = Getattr(n,"membervariables");
+ if (membervariables && Len(membervariables) > 0) {
+ membervariableAccessors(membervariables);
+ }
+ */
+
+ /* Done, close the class */
+ Printf(f_init, "add_program_constant(\"%s\", pr = end_program(), 0);\n", symname);
+
+ SwigType *tt = NewString(symname);
+ SwigType_add_pointer(tt);
+ SwigType_remember(tt);
+ String *tm = SwigType_manglestr(tt);
+ Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) pr);\n", tm);
+ Delete(tm);
+ Delete(tt);
+
+ Delete(PrefixPlusUnderscore); PrefixPlusUnderscore = 0;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ *
+ * Method for adding C++ member function
+ * ------------------------------------------------------------ */
+
+ virtual int memberfunctionHandler(Node *n) {
+ current = MEMBER_FUNC;
+ Language::memberfunctionHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorHandler()
+ *
+ * Method for adding C++ member constructor
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+ current = CONSTRUCTOR;
+ Language::constructorHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorHandler(Node *n) {
+ current = DESTRUCTOR;
+ Language::destructorHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableAccessors()
+ * ------------------------------------------------------------ */
+
+ void membervariableAccessors(List *membervariables) {
+ String *name;
+ Node *n;
+ bool need_setter;
+ String *funcname;
+
+ /* If at least one of them is mutable, we need a setter */
+ need_setter = false;
+ n = Firstitem(membervariables);
+ while (n) {
+ if (!Getattr(n, "feature:immutable")) {
+ need_setter = true;
+ break;
+ }
+ n = Nextitem(membervariables);
+ }
+
+ /* Create a function to set the values of the (mutable) variables */
+ if (need_setter) {
+ Wrapper *wrapper = NewWrapper();
+ String *setter = Swig_name_member(getClassPrefix(), (char *) "`->=");
+ String *wname = Swig_name_wrapper(setter);
+ Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL);
+ Printf(wrapper->locals, "char *name = (char *) STR0(sp[0-args].u.string);\n");
+
+ n = Firstitem(membervariables);
+ while (n) {
+ if (!Getattr(n, "feature:immutable")) {
+ name = Getattr(n, "name");
+ funcname = Swig_name_wrapper(Swig_name_set(Swig_name_member(getClassPrefix(), name)));
+ Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name);
+ Printf(wrapper->code, "%s(args);\n", funcname);
+ Printf(wrapper->code, "return;\n");
+ Printf(wrapper->code, "}\n");
+ Delete(funcname);
+ }
+ n = Nextitem(membervariables);
+ }
+
+ /* Close the function */
+ Printf(wrapper->code, "pop_n_elems(args);\n");
+ Printf(wrapper->code, "}\n");
+
+ /* Dump wrapper code to the output file */
+ Wrapper_print(wrapper, f_wrappers);
+
+ /* Register it with Pike */
+ String *description = NewString("tStr tFloat, tVoid");
+ add_method(Firstitem(membervariables), "`->=", wname, description);
+ Delete(description);
+
+ /* Clean up */
+ Delete(wname);
+ Delete(setter);
+ DelWrapper(wrapper);
+ }
+
+ /* Create a function to get the values of the (mutable) variables */
+ Wrapper *wrapper = NewWrapper();
+ String *getter = Swig_name_member(getClassPrefix(), (char *) "`->");
+ String *wname = Swig_name_wrapper(getter);
+ Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL);
+ Printf(wrapper->locals, "char *name = (char *) STR0(sp[0-args].u.string);\n");
+
+ n = Firstitem(membervariables);
+ while (n) {
+ name = Getattr(n, "name");
+ funcname = Swig_name_wrapper(Swig_name_get(Swig_name_member(getClassPrefix(), name)));
+ Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name);
+ Printf(wrapper->code, "%s(args);\n", funcname);
+ Printf(wrapper->code, "return;\n");
+ Printf(wrapper->code, "}\n");
+ Delete(funcname);
+ n = Nextitem(membervariables);
+ }
+
+ /* Close the function */
+ Printf(wrapper->code, "pop_n_elems(args);\n");
+ Printf(wrapper->code, "}\n");
+
+ /* Dump wrapper code to the output file */
+ Wrapper_print(wrapper, f_wrappers);
+
+ /* Register it with Pike */
+ String *description = NewString("tStr, tMix");
+ add_method(Firstitem(membervariables), "`->", wname, description);
+ Delete(description);
+
+ /* Clean up */
+ Delete(wname);
+ Delete(getter);
+ DelWrapper(wrapper);
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int membervariableHandler(Node *n) {
+ List *membervariables = Getattr(getCurrentClass(),"membervariables");
+ if (!membervariables) {
+ membervariables = NewList();
+ Setattr(getCurrentClass(),"membervariables",membervariables);
+ }
+ Append(membervariables,n);
+ current = MEMBER_VAR;
+ Language::membervariableHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ *
+ * Wrap a static C++ function
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ current = STATIC_FUNC;
+ Language::staticmemberfunctionHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberconstantHandler()
+ *
+ * Create a C++ constant
+ * ------------------------------------------------------------ */
+
+ virtual int memberconstantHandler(Node *n) {
+ current = CLASS_CONST;
+ constantWrapper(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ---------------------------------------------------------------------
+ * staticmembervariableHandler()
+ * --------------------------------------------------------------------- */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ current = STATIC_VAR;
+ Language::staticmembervariableHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+};
+
+/* -----------------------------------------------------------------------------
+ * swig_pike() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+extern "C" Language *
+swig_pike(void) {
+ return new PIKE();
+}
+
+
+
+
+
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
new file mode 100644
index 000000000..6651ace92
--- /dev/null
+++ b/Source/Modules/python.cxx
@@ -0,0 +1,1268 @@
+/* -----------------------------------------------------------------------------
+ * python.cxx
+ *
+ * Python module.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1999-2000. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_python_cxx[] = "$Header$";
+
+#include "swigmod.h"
+
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+
+#include
+
+#define PYSHADOW_MEMBER 0x2
+
+static String *const_code = 0;
+static String *shadow_methods = 0;
+static String *module = 0;
+static String *mainmodule = 0;
+static String *interface = 0;
+static String *global_name = 0;
+static int shadow = 1;
+static int use_kw = 0;
+
+static File *f_runtime = 0;
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+static File *f_shadow = 0;
+static File *f_shadow_stubs = 0;
+
+static String *methods;
+static String *class_name;
+static String *shadow_indent = 0;
+static int in_class = 0;
+static int classic = 0;
+
+/* C++ Support + Shadow Classes */
+
+static int have_constructor;
+static int have_repr;
+static String *real_classname;
+
+static const char *usage = (char *)"\
+Python Options (available with -python)\n\
+ -ldflags - Print runtime libraries to link with\n\
+ -globals name - Set name used to access C global variable ('cvar' by default).\n\
+ -interface name - Set the lib name\n\
+ -keyword - Use keyword arguments\n\
+ -classic - Use classic classes only\n\
+ -noexcept - No automatic exception handling.\n\
+ -noproxy - Don't generate proxy classes. \n\n";
+
+class PYTHON : public Language {
+public:
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+
+ SWIG_library_directory("python");
+
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if(strcmp(argv[i],"-interface") == 0) {
+ if (argv[i+1]) {
+ interface = NewString(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ /* end added */
+ } else if (strcmp(argv[i],"-globals") == 0) {
+ if (argv[i+1]) {
+ global_name = NewString(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if ((strcmp(argv[i],"-shadow") == 0) || ((strcmp(argv[i],"-proxy") == 0))) {
+ shadow = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i],"-noproxy") == 0)) {
+ shadow = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-keyword") == 0) {
+ use_kw = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-classic") == 0) {
+ classic = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-help") == 0) {
+ fputs(usage,stderr);
+ } else if (strcmp (argv[i], "-ldflags") == 0) {
+ printf("%s\n", SWIG_PYTHON_RUNTIME);
+ SWIG_exit (EXIT_SUCCESS);
+ }
+ }
+ }
+ if (!global_name) global_name = NewString("cvar");
+ Preprocessor_define("SWIGPYTHON 1", 0);
+ SWIG_typemap_lang("python");
+ SWIG_config_file("python.swg");
+ allow_overloading();
+ }
+
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
+
+ f_runtime = NewFile(outfile,"w");
+ if (!f_runtime) {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header",f_header);
+ Swig_register_filebyname("wrapper",f_wrappers);
+ Swig_register_filebyname("runtime",f_runtime);
+ Swig_register_filebyname("init",f_init);
+
+ const_code = NewString("");
+ shadow_methods = NewString("");
+ methods = NewString("");
+
+ Swig_banner(f_runtime);
+
+ Printf(f_runtime,"#define SWIGPYTHON\n");
+ if (NoInclude)
+ Printf(f_runtime,"#define SWIG_NOINCLUDE\n");
+
+ /* Set module name */
+ module = Copy(Getattr(n,"name"));
+ mainmodule = Getattr(n,"name");
+
+ char filen[256];
+
+ /* If shadow classing is enabled, we're going to change the module name to "_module" */
+ if (shadow) {
+ sprintf(filen,"%s%s.py", Swig_file_dirname(outfile), Char(module));
+ // If we don't have an interface then change the module name X to _X
+ if (interface) module = interface;
+ else Insert(module,0,"_");
+ if ((f_shadow = NewFile(filen,"w")) == 0) {
+ Printf(stderr,"Unable to open %s\n", filen);
+ SWIG_exit (EXIT_FAILURE);
+ }
+ f_shadow_stubs = NewString("");
+
+ Swig_register_filebyname("shadow",f_shadow);
+ Swig_register_filebyname("python",f_shadow);
+
+ Printv(f_shadow,
+ "# This file was created automatically by SWIG.\n",
+ "# Don't modify this file, modify the SWIG interface instead.\n",
+ "# This file is compatible with both classic and new-style classes.\n",
+ NIL);
+
+ Printf(f_shadow,"import %s\n", module);
+
+ // Python-2.2 object hack
+
+
+ Printv(f_shadow,
+ "def _swig_setattr(self,class_type,name,value):\n",
+ tab4, "if (name == \"this\"):\n",
+ tab4, tab4, "if isinstance(value, class_type):\n",
+ tab4, tab8, "self.__dict__[name] = value.this\n",
+ tab4, tab8, "if hasattr(value,\"thisown\"): self.__dict__[\"thisown\"] = value.thisown\n",
+ tab4, tab8, "del value.thisown\n",
+ tab4, tab8, "return\n",
+ // tab8, "if (name == \"this\") or (name == \"thisown\"): self.__dict__[name] = value; return\n",
+ tab4, "method = class_type.__swig_setmethods__.get(name,None)\n",
+ tab4, "if method: return method(self,value)\n",
+ tab4, "self.__dict__[name] = value\n\n",
+ NIL);
+
+ Printv(f_shadow,
+ "def _swig_getattr(self,class_type,name):\n",
+ tab4, "method = class_type.__swig_getmethods__.get(name,None)\n",
+ tab4, "if method: return method(self)\n",
+ tab4, "raise AttributeError,name\n\n",
+ NIL);
+
+ if (!classic) {
+ Printv(f_shadow,
+ "import types\n",
+ "try:\n",
+ " _object = types.ObjectType\n",
+ " _newclass = 1\n",
+ "except AttributeError:\n",
+ " class _object : pass\n",
+ " _newclass = 0\n",
+ "\n\n",
+ NIL);
+ }
+
+ // Include some information in the code
+ Printf(f_header,"\n/*-----------------------------------------------\n @(target):= %s.so\n\
+ ------------------------------------------------*/\n", module);
+
+ }
+
+ Printf(f_header,"#define SWIG_init init%s\n\n", module);
+ Printf(f_header,"#define SWIG_name \"%s\"\n", module);
+
+ Printf(f_wrappers,"#ifdef __cplusplus\n");
+ Printf(f_wrappers,"extern \"C\" {\n");
+ Printf(f_wrappers,"#endif\n");
+ Printf(const_code,"static swig_const_info swig_const_table[] = {\n");
+ Printf(methods,"static PyMethodDef SwigMethods[] = {\n");
+
+ /* emit code */
+ Language::top(n);
+
+ /* Close language module */
+ Printf(methods,"\t { NULL, NULL }\n");
+ Printf(methods,"};\n");
+ Printf(f_wrappers,"%s\n",methods);
+
+ SwigType_emit_type_table(f_runtime,f_wrappers);
+
+ Printf(const_code, "{0}};\n");
+ Printf(f_wrappers,"%s\n",const_code);
+ Printf(f_init,"}\n");
+
+ Printf(f_wrappers,"#ifdef __cplusplus\n");
+ Printf(f_wrappers,"}\n");
+ Printf(f_wrappers,"#endif\n");
+
+ if (shadow) {
+ Printv(f_shadow, f_shadow_stubs, "\n",NIL);
+ Close(f_shadow);
+ Delete(f_shadow);
+ }
+
+ /* Close all of the files */
+ Dump(f_header,f_runtime);
+ Dump(f_wrappers,f_runtime);
+ Wrapper_pretty_print(f_init,f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_runtime);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * importDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int importDirective(Node *n) {
+ if (shadow) {
+ String *modname = Getattr(n,"module");
+ if (modname) {
+ Printf(f_shadow,"import %s\n", modname);
+ }
+ }
+ return Language::importDirective(n);
+ }
+
+ /* ------------------------------------------------------------
+ * add_method()
+ * ------------------------------------------------------------ */
+
+ void add_method(String *name, String *function, int kw) {
+ if (!kw)
+ Printf(methods,"\t { (char *)\"%s\", %s, METH_VARARGS },\n", name, function);
+ else
+ Printf(methods,"\t { (char *)\"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS },\n", name, function);
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int functionWrapper(Node *n) {
+
+ String *name = Getattr(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ SwigType *d = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+
+ Parm *p;
+ int i;
+ char wname[256];
+ char source[64];
+ Wrapper *f;
+ String *parse_args;
+ String *arglist;
+ String *get_pointers;
+ String *cleanup;
+ String *outarg;
+ String *kwargs;
+ String *tm;
+ String *overname = 0;
+
+ int num_required;
+ int num_arguments;
+ int varargs = 0;
+ int allow_kwargs = (use_kw || Getattr(n,"feature:kwargs")) ? 1 : 0;
+
+ if (Getattr(n,"sym:overloaded")) {
+ overname = Getattr(n,"sym:overname");
+ } else {
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+ }
+
+ f = NewWrapper();
+ parse_args = NewString("");
+ arglist = NewString("");
+ get_pointers = NewString("");
+ cleanup = NewString("");
+ outarg = NewString("");
+ kwargs = NewString("");
+
+ Wrapper_add_local(f,"resultobj", "PyObject *resultobj");
+
+ /* Write code to extract function parameters. */
+ emit_args(d, l, f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l,f);
+ Setattr(n,"wrap:parms",l);
+ /* Get number of required and total arguments */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+ varargs = emit_isvarargs(l);
+
+ strcpy(wname,Char(Swig_name_wrapper(iname)));
+ if (overname) {
+ strcat(wname,Char(overname));
+ }
+
+ if (!allow_kwargs || Getattr(n,"sym:overloaded")) {
+ if (!varargs) {
+ Printv(f->def,
+ "static PyObject *", wname,
+ "(PyObject *self, PyObject *args) {",
+ NIL);
+ } else {
+ Printv(f->def,
+ "static PyObject *", wname, "__varargs__",
+ "(PyObject *self, PyObject *args, PyObject *varargs) {",
+ NIL);
+ }
+ if (allow_kwargs) {
+ Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number,
+ "Can't use keyword arguments with overloaded functions.\n");
+ allow_kwargs = 0;
+ }
+ } else {
+ if (varargs) {
+ Swig_warning(WARN_LANG_VARARGS_KEYWORD, input_file, line_number,
+ "Can't wrap varargs with keyword arguments enabled\n");
+ varargs = 0;
+ }
+ Printv(f->def,
+ "static PyObject *", wname,
+ "(PyObject *self, PyObject *args, PyObject *kwargs) {",
+ NIL);
+ }
+ if (!allow_kwargs) {
+ Printf(parse_args," if(!PyArg_ParseTuple(args,(char *)\"");
+ } else {
+ Printf(parse_args," if(!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)\"");
+ Printf(arglist,",kwnames");
+ }
+
+ /* Generate code for argument marshalling */
+
+ Printf(kwargs,"{ ");
+ for (i = 0, p=l; i < num_arguments; i++) {
+
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *pn = Getattr(p,"name");
+ String *ln = Getattr(p,"lname");
+
+ sprintf(source,"obj%d",i);
+
+ Putc(',',arglist);
+ if (i == num_required) Putc('|', parse_args); /* Optional argument separator */
+
+ /* Keyword argument handling */
+ if (Len(pn)) {
+ Printf(kwargs,"\"%s\",", pn);
+ } else {
+ Printf(kwargs,"\"arg%d\",", i+1);
+ }
+
+ /* Look for an input typemap */
+ if ((tm = Getattr(p,"tmap:in"))) {
+ String *parse = Getattr(p,"tmap:in:parse");
+ if (!parse) {
+ Replaceall(tm,"$source",source);
+ Replaceall(tm,"$target",ln);
+ Replaceall(tm,"$input", source);
+ Setattr(p,"emit:input", source); /* Save the location of the object */
+
+ if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) {
+ Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm,"$disown","0");
+ }
+
+ Putc('O',parse_args);
+ Wrapper_add_localv(f, source, "PyObject *",source, " = 0", NIL);
+ Printf(arglist,"&%s",source);
+ if (i >= num_required)
+ Printv(get_pointers, "if (", source, ") {\n", NIL);
+ Printv(get_pointers,tm,"\n", NIL);
+ if (i >= num_required)
+ Printv(get_pointers, "}\n", NIL);
+
+ } else {
+ Printf(parse_args,"%s",parse);
+ Printf(arglist,"&%s", ln);
+ }
+ p = Getattr(p,"tmap:in:next");
+ continue;
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument.\n",SwigType_str(pt,0));
+ break;
+ }
+ p = nextSibling(p);
+ }
+
+ /* finish argument marshalling */
+ Printf(kwargs," NULL }");
+ if (allow_kwargs) {
+ Printv(f->locals,tab4, "char *kwnames[] = ", kwargs, ";\n", NIL);
+ }
+
+ Printf(parse_args,":%s\"", iname);
+ Printv(parse_args,
+ arglist, ")) goto fail;\n",
+ NIL);
+
+ /* Now piece together the first part of the wrapper function */
+ Printv(f->code, parse_args, get_pointers, NIL);
+
+ /* Check for trailing varargs */
+ if (varargs) {
+ if (p && (tm = Getattr(p,"tmap:in"))) {
+ Replaceall(tm,"$input", "varargs");
+ Printv(f->code,tm,"\n",NIL);
+ }
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:check"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:freearg"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Printv(cleanup,tm,"\n",NIL);
+ p = Getattr(p,"tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:argout"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Replaceall(tm,"$target","resultobj");
+ Replaceall(tm,"$arg",Getattr(p,"emit:input"));
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(outarg,tm,"\n",NIL);
+ p = Getattr(p,"tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Emit the function call */
+ emit_action(n,f);
+
+ /* This part below still needs cleanup */
+
+ /* Return the function value */
+ if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
+ Replaceall(tm,"$source", "result");
+ Replaceall(tm,"$target", "resultobj");
+ Replaceall(tm,"$result", "resultobj");
+ if (Getattr(n,"feature:new")) {
+ Replaceall(tm,"$owner","1");
+ } else {
+ Replaceall(tm,"$owner","0");
+ }
+ Printf(f->code,"%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s in function %s.\n", SwigType_str(d,0), name);
+ }
+
+ /* Output argument output code */
+ Printv(f->code,outarg,NIL);
+
+ /* Output cleanup code */
+ Printv(f->code,cleanup,NIL);
+
+ /* Look to see if there is any newfree cleanup code */
+ if (Getattr(n,"feature:new")) {
+ if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printf(f->code,"%s\n",tm);
+ }
+ }
+
+ /* See if there is any return cleanup code */
+ if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) {
+ Replaceall(tm,"$source","result");
+ Printf(f->code,"%s\n",tm);
+ }
+
+ Printf(f->code," return resultobj;\n");
+
+ /* Error handling code */
+
+ Printf(f->code,"fail:\n");
+ Printv(f->code,cleanup,NIL);
+ Printf(f->code,"return NULL;\n");
+ Printf(f->code,"}\n");
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code,"$cleanup",cleanup);
+
+ /* Substitute the function name */
+ Replaceall(f->code,"$symname",iname);
+ Replaceall(f->code,"$result","resultobj");
+
+ /* Dump the function out */
+ Wrapper_print(f,f_wrappers);
+
+ /* If varargs. Need to emit a varargs stub */
+ if (varargs) {
+ DelWrapper(f);
+ f = NewWrapper();
+ Printv(f->def,
+ "static PyObject *", wname,
+ "(PyObject *self, PyObject *args) {",
+ NIL);
+ Wrapper_add_local(f,"resultobj", "PyObject *resultobj");
+ Wrapper_add_local(f,"varargs", "PyObject *varargs");
+ Wrapper_add_local(f,"newargs", "PyObject *newargs");
+ Printf(f->code,"newargs = PyTuple_GetSlice(args,0,%d);\n", num_arguments);
+ Printf(f->code,"varargs = PyTuple_GetSlice(args,%d,PyTuple_Size(args)+1);\n", num_arguments);
+ Printf(f->code,"resultobj = %s__varargs__(self,newargs,varargs);\n", wname);
+ Printf(f->code,"Py_XDECREF(newargs);\n");
+ Printf(f->code,"Py_XDECREF(varargs);\n");
+ Printf(f->code,"return resultobj;\n");
+ Printf(f->code,"}\n");
+ Wrapper_print(f,f_wrappers);
+ }
+
+ Setattr(n,"wrap:name", wname);
+
+ /* Now register the function with the interpreter. */
+ if (!Getattr(n,"sym:overloaded")) {
+ add_method(iname, wname, allow_kwargs);
+
+ /* Create a shadow for this function (if enabled and not in a member function) */
+ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ if (in_class) {
+ Printv(f_shadow_stubs,iname, " = ", module, ".", iname, "\n\n", NIL);
+ } else {
+ Printv(f_shadow,iname, " = ", module, ".", iname, "\n\n", NIL);
+ }
+ }
+ } else {
+ if (!Getattr(n,"sym:nextSibling")) {
+ dispatchFunction(n);
+ }
+ }
+ Delete(parse_args);
+ Delete(arglist);
+ Delete(get_pointers);
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(kwargs);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * dispatchFunction()
+ * ------------------------------------------------------------ */
+ void dispatchFunction(Node *n) {
+ /* Last node in overloaded chain */
+
+ int maxargs;
+ String *tmp = NewString("");
+ String *dispatch = Swig_overload_dispatch(n,"return %s(self,args);",&maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *f = NewWrapper();
+ String *symname = Getattr(n,"sym:name");
+ String *wname = Swig_name_wrapper(symname);
+
+ Printv(f->def,
+ "static PyObject *", wname,
+ "(PyObject *self, PyObject *args) {",
+ NIL);
+
+ Wrapper_add_local(f,"argc","int argc");
+ Printf(tmp,"PyObject *argv[%d]", maxargs+1);
+ Wrapper_add_local(f,"argv",tmp);
+ Wrapper_add_local(f,"ii","int ii");
+ Printf(f->code,"argc = PyObject_Length(args);\n");
+ Printf(f->code,"for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n",maxargs);
+ Printf(f->code,"argv[ii] = PyTuple_GetItem(args,ii);\n");
+ Printf(f->code,"}\n");
+
+ Replaceall(dispatch,"$args","self,args");
+ Printv(f->code,dispatch,"\n",NIL);
+ Printf(f->code,"PyErr_SetString(PyExc_TypeError,\"No matching function for overloaded '%s'\");\n", symname);
+ Printf(f->code,"return NULL;\n");
+ Printv(f->code,"}\n",NIL);
+ Wrapper_print(f,f_wrappers);
+ add_method(symname,wname,0);
+
+ /* Create a shadow for this function (if enabled and not in a member function) */
+ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ Printv(f_shadow_stubs,symname, " = ", module, ".", symname, "\n\n", NIL);
+ }
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(tmp);
+ Delete(wname);
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+
+ String *name = Getattr(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+
+ String *wname;
+ static int have_globals = 0;
+ String *tm;
+ Wrapper *getf, *setf;
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ getf = NewWrapper();
+ setf = NewWrapper();
+
+ /* If this is our first call, add the globals variable to the
+ Python dictionary. */
+
+ if (!have_globals) {
+ Printf(f_init,"\t PyDict_SetItemString(d,(char*)\"%s\", SWIG_globals);\n",global_name);
+ have_globals=1;
+ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ Printf(f_shadow_stubs,"%s = %s.%s\n", global_name, module, global_name);
+ }
+ }
+
+ if ((shadow) && (SwigType_isconst(t))) {
+ if (!in_class) {
+ Printf(f_shadow_stubs,"%s = %s.%s\n", iname, global_name, iname);
+ }
+ }
+
+ wname = Swig_name_wrapper(iname);
+
+ /* Create a function for setting the value of the variable */
+
+ Printf(setf->def,"static int %s_set(PyObject *_val) {", wname);
+ if (!Getattr(n,"feature:immutable")) {
+ if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) {
+ Replaceall(tm,"$source","_val");
+ Replaceall(tm,"$target",name);
+ Replaceall(tm,"$input","_val");
+ Printf(setf->code,"%s\n",tm);
+ Delete(tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number,
+ "Unable to set variable of type %s.\n", SwigType_str(t,0));
+ }
+ Printf(setf->code," return 0;\n");
+ } else {
+ /* Is a readonly variable. Issue an error */
+ Printv(setf->code,
+ tab4, "PyErr_SetString(PyExc_TypeError,\"Variable ", iname,
+ " is read-only.\");\n",
+ tab4, "return 1;\n",
+ NIL);
+ }
+
+ Printf(setf->code,"}\n");
+ Wrapper_print(setf,f_wrappers);
+
+ /* Create a function for getting the value of a variable */
+ Printf(getf->def,"static PyObject *%s_get() {", wname);
+ Wrapper_add_local(getf,"pyobj", "PyObject *pyobj");
+ if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) {
+ Replaceall(tm,"$source",name);
+ Replaceall(tm,"$target","pyobj");
+ Replaceall(tm,"$result","pyobj");
+ Printf(getf->code,"%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number,
+ "Unable to link with type %s\n", SwigType_str(t,0));
+ }
+
+ Printf(getf->code," return pyobj;\n}\n");
+ Wrapper_print(getf,f_wrappers);
+
+ /* Now add this to the variable linking mechanism */
+ Printf(f_init,"\t SWIG_addvarlink(SWIG_globals,(char*)\"%s\",%s_get, %s_set);\n", iname, wname, wname);
+
+ DelWrapper(setf);
+ DelWrapper(getf);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *name = Getattr(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ String *value = Getattr(n,"value");
+ String *tm;
+ int have_tm = 0;
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ /* Special hook for member pointer */
+ if (SwigType_type(type) == T_MPOINTER) {
+ String *wname = Swig_name_wrapper(iname);
+ Printf(f_header, "static %s = %s;\n", SwigType_str(type,wname), value);
+ value = wname;
+ }
+ if ((tm = Swig_typemap_lookup_new("consttab",n,name,0))) {
+ Replaceall(tm,"$source",value);
+ Replaceall(tm,"$target",name);
+ Replaceall(tm,"$value", value);
+ Printf(const_code,"%s,\n", tm);
+ have_tm = 1;
+ }
+ if ((tm = Swig_typemap_lookup_new("constcode", n, name, 0))) {
+ Replaceall(tm,"$source",value);
+ Replaceall(tm,"$target",name);
+ Replaceall(tm,"$value",value);
+ Printf(f_init, "%s\n", tm);
+ have_tm = 1;
+ }
+ if (!have_tm) {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
+ "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ if (!in_class) {
+ Printv(f_shadow,iname, " = ", module, ".", iname, "\n", NIL);
+ } else {
+ Printv(f_shadow_stubs,iname, " = ", module, ".", iname, "\n", NIL);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int nativeWrapper(Node *n) {
+ String *name = Getattr(n,"sym:name");
+ String *wrapname = Getattr(n,"wrap:name");
+
+ if (!addSymbol(wrapname,n)) return SWIG_ERROR;
+
+ add_method(name, wrapname,0);
+ if (shadow) {
+ Printv(f_shadow_stubs, name, " = ", module, ".", name, "\n\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int classDeclaration(Node *n) {
+ String *importname;
+ Node *mod;
+ if (shadow) {
+ mod = Getattr(n,"module");
+ if (mod) {
+ String *modname = Getattr(mod,"name");
+ if (Strcmp(modname,mainmodule) != 0) {
+ importname = NewStringf("%s.%s", modname, Getattr(n,"sym:name"));
+ } else {
+ importname = NewString(Getattr(n,"sym:name"));
+ }
+ Setattr(n,"python:proxy",importname);
+ }
+ }
+ return Language::classDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int classHandler(Node *n) {
+ int oldclassic = classic;
+
+ if (shadow) {
+
+ /* Create new strings for building up a wrapper function */
+ have_constructor = 0;
+ have_repr = 0;
+
+ if (Getattr(n,"cplus:exceptionclass")) {
+ classic = 1;
+ }
+ if (Getattr(n,"feature:classic")) classic = 1;
+
+ shadow_indent = (String *) tab4;
+
+ class_name = Getattr(n,"sym:name");
+ real_classname = Getattr(n,"name");
+
+ if (!addSymbol(class_name,n)) return SWIG_ERROR;
+
+ /* Handle inheritance */
+ String *base_class = NewString("");
+ List *baselist = Getattr(n,"bases");
+ if (baselist && Len(baselist)) {
+ Node *base = Firstitem(baselist);
+ while (base) {
+ String *bname = Getattr(base, "python:proxy");
+ if (!bname) {
+ base = Nextitem(baselist);
+ continue;
+ }
+ Printv(base_class,bname,NIL);
+ base = Nextitem(baselist);
+ if (base) {
+ Putc(',',base_class);
+ }
+ }
+ }
+ Printv(f_shadow,"class ", class_name, NIL);
+
+ if (Len(base_class)) {
+ Printf(f_shadow,"(%s)", base_class);
+ } else {
+ if (!classic) {
+ Printf(f_shadow,"(_object)");
+ }
+ }
+ Printf(f_shadow,":\n");
+
+ Printv(f_shadow,tab4,"__swig_setmethods__ = {}\n",NIL);
+ if (Len(base_class)) {
+ Printf(f_shadow,"%sfor _s in [%s]: __swig_setmethods__.update(_s.__swig_setmethods__)\n",tab4,base_class);
+ }
+
+ Printv(f_shadow,
+ tab4, "__setattr__ = lambda self, name, value: _swig_setattr(self, ", class_name, ", name, value)\n",
+ NIL);
+
+ Printv(f_shadow,tab4,"__swig_getmethods__ = {}\n",NIL);
+ if (Len(base_class)) {
+ Printf(f_shadow,"%sfor _s in [%s]: __swig_getmethods__.update(_s.__swig_getmethods__)\n",tab4,base_class);
+ }
+
+ Printv(f_shadow,
+ tab4, "__getattr__ = lambda self, name: _swig_getattr(self, ", class_name, ", name)\n",
+ NIL);
+ }
+
+ /* Emit all of the members */
+
+ in_class = 1;
+ Language::classHandler(n);
+ in_class = 0;
+
+ /* Complete the class */
+ if (shadow) {
+ /* Generate a class registration function */
+ {
+ SwigType *ct = NewStringf("p.%s", real_classname);
+ SwigType_remember(ct);
+ Printv(f_wrappers,
+ "static PyObject * ", class_name, "_swigregister(PyObject *self, PyObject *args) {\n",
+ tab4, "PyObject *obj;\n",
+ tab4, "if (!PyArg_ParseTuple(args,(char*)\"O\", &obj)) return NULL;\n",
+ tab4, "SWIG_TypeClientData(SWIGTYPE", SwigType_manglestr(ct),", obj);\n",
+ tab4, "Py_INCREF(obj);\n",
+ tab4, "return Py_BuildValue((char *)\"\");\n",
+ "}\n",NIL);
+ String *cname = NewStringf("%s_swigregister", class_name);
+ add_method(cname, cname, 0);
+ Delete(cname);
+ Delete(ct);
+ }
+ if (!have_constructor) {
+ Printv(f_shadow,tab4,"def __init__(self): raise RuntimeError, \"No constructor defined\"\n",NIL);
+ }
+
+ if (!have_repr) {
+ /* Supply a repr method for this class */
+ Printv(f_shadow,
+ tab4, "def __repr__(self):\n",
+ tab8, "return \"\" % (self.this,)\n",
+ NIL);
+ }
+ /* Now build the real class with a normal constructor */
+ Printv(f_shadow,
+ "\nclass ", class_name, "Ptr(", class_name, "):\n",
+ tab4, "def __init__(self,this):\n",
+ tab8, "self.this = this\n",
+ tab8, "if not hasattr(self,\"thisown\"): self.thisown = 0\n",
+ // tab8,"try: self.this = this.this; self.thisown = getattr(this,'thisown',0); this.thisown=0\n",
+ // tab8,"except AttributeError: self.this = this\n"
+ tab8, "self.__class__ = ", class_name, "\n",
+ NIL);
+
+ Printf(f_shadow,"%s.%s_swigregister(%sPtr)\n", module, class_name, class_name,0);
+ shadow_indent = 0;
+ Printf(f_shadow,"%s\n", f_shadow_stubs);
+ Clear(f_shadow_stubs);
+ }
+ classic = oldclassic;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberfunctionHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ int oldshadow;
+
+ /* Create the default member function */
+ oldshadow = shadow; /* Disable shadowing when wrapping member functions */
+ if (shadow) shadow = shadow | PYSHADOW_MEMBER;
+ Language::memberfunctionHandler(n);
+ shadow = oldshadow;
+
+ if (!Getattr(n,"sym:nextSibling")) {
+ if (shadow) {
+ int allow_kwargs = (use_kw || Getattr(n,"feature:kwargs")) ? 1 : 0;
+ if (Strcmp(symname,"__repr__") == 0)
+ have_repr = 1;
+
+ if (Getattr(n,"feature:shadow")) {
+ String *pycode = pythoncode(Getattr(n,"feature:shadow"),tab4);
+ Printv(f_shadow,pycode,"\n",NIL);
+ } else {
+ if (allow_kwargs && !Getattr(n,"sym:overloaded")) {
+ Printv(f_shadow,tab4, "def ", symname, "(*args, **kwargs): ", NIL);
+ Printv(f_shadow, "return apply(", module, ".", Swig_name_member(class_name,symname), ",args, kwargs)\n", NIL);
+ } else {
+ Printv(f_shadow, tab4, "def ", symname, "(*args): ", NIL);
+ Printv(f_shadow, "return apply(", module, ".", Swig_name_member(class_name,symname), ",args)\n",NIL);
+ }
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ Language::staticmemberfunctionHandler(n);
+ if (shadow) {
+ Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", module, ".", Swig_name_member(class_name, symname), "\n", NIL);
+ if (!classic) {
+ Printv(f_shadow, tab4, "if _newclass:", symname, " = staticmethod(", module, ".",
+ Swig_name_member(class_name, symname), ")\n", NIL);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ int oldshadow = shadow;
+
+ if (shadow) shadow = shadow | PYSHADOW_MEMBER;
+ Language::constructorHandler(n);
+ shadow = oldshadow;
+
+ if (!Getattr(n,"sym:nextSibling")) {
+ if (shadow) {
+ int allow_kwargs = (use_kw || Getattr(n,"feature:kwargs")) ? 1 : 0;
+ if (!have_constructor) {
+ if (Getattr(n,"feature:shadow")) {
+ String *pycode = pythoncode(Getattr(n,"feature:shadow"),tab4);
+ Printv(f_shadow,pycode,"\n",NIL);
+ } else {
+ if ((allow_kwargs) && (!Getattr(n,"sym:overloaded"))) {
+ Printv(f_shadow, tab4, "def __init__(self,*args,**kwargs):\n", NIL);
+ Printv(f_shadow, tab8, "self.this = apply(", module, ".", Swig_name_construct(symname), ",args,kwargs)\n", NIL);
+ } else {
+ Printv(f_shadow, tab4, "def __init__(self,*args):\n",NIL);
+ Printv(f_shadow, tab8, "self.this = apply(", module, ".", Swig_name_construct(symname), ",args)\n", NIL);
+ }
+ Printv(f_shadow,
+ tab8, "self.thisown = 1\n",
+ NIL);
+ }
+ have_constructor = 1;
+ } else {
+ /* Hmmm. We seem to be creating a different constructor. We're just going to create a
+ function for it. */
+
+ if (Getattr(n,"feature:shadow")) {
+ String *pycode = pythoncode(Getattr(n,"feature:shadow"),"");
+ Printv(f_shadow_stubs,pycode,"\n",NIL);
+ } else {
+ if ((allow_kwargs) && (!Getattr(n,"sym:overloaded")))
+ Printv(f_shadow_stubs, "def ", symname, "(*args,**kwargs):\n", NIL);
+ else
+ Printv(f_shadow_stubs, "def ", symname, "(*args):\n", NIL);
+
+ Printv(f_shadow_stubs, tab4, "val = apply(", NIL);
+ if ((allow_kwargs) && (!Getattr(n,"sym:overloaded")))
+ Printv(f_shadow_stubs, module, ".", Swig_name_construct(symname), ",args,kwargs)\n", NIL);
+ else
+ Printv(f_shadow_stubs, module, ".", Swig_name_construct(symname), ",args)\n", NIL);
+ Printv(f_shadow_stubs,tab4, "val.thisown = 1\n",
+ tab4, "return val\n\n", NIL);
+ }
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ int oldshadow = shadow;
+
+ if (shadow) shadow = shadow | PYSHADOW_MEMBER;
+ Language::destructorHandler(n);
+ shadow = oldshadow;
+ if (shadow) {
+ Printv(f_shadow, tab4, "def __del__(self, destroy= ", module, ".", Swig_name_destroy(symname), "):\n", NIL);
+ Printv(f_shadow, tab8, "try:\n", NIL);
+ Printv(f_shadow, tab4, tab8, "if self.thisown: destroy(self)\n", NIL);
+ Printv(f_shadow, tab8, "except: pass\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int membervariableHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+
+ int oldshadow = shadow;
+ if (shadow) shadow = shadow | PYSHADOW_MEMBER;
+ Language::membervariableHandler(n);
+ shadow = oldshadow;
+
+ if (shadow) {
+ int immutable = 0;
+ if (!Getattr(n,"feature:immutable")) {
+ Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", Swig_name_set(Swig_name_member(class_name,symname)), "\n", NIL);
+ } else {
+ immutable = 1;
+ }
+ Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", Swig_name_get(Swig_name_member(class_name,symname)),"\n", NIL);
+
+ if (!classic) {
+ if (immutable) {
+ Printv(f_shadow,tab4,"if _newclass:", symname," = property(", module, ".",
+ Swig_name_get(Swig_name_member(class_name,symname)),")\n", NIL);
+ } else {
+ Printv(f_shadow,tab4,"if _newclass:", symname," = property(",
+ module, ".", Swig_name_get(Swig_name_member(class_name,symname)),",",
+ module, ".", Swig_name_set(Swig_name_member(class_name,symname)),")\n", NIL);
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmembervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ String *symname;
+ SwigType *t;
+
+ Language::staticmembervariableHandler(n);
+ if (shadow) {
+ t = Getattr(n,"type");
+ symname = Getattr(n,"sym:name");
+ if (SwigType_isconst(t) && !Getattr(n, "value")) {
+ Printf(f_shadow,"%s%s = %s.%s.%s\n", tab4, symname, module, global_name, Swig_name_member(class_name,symname));
+ }
+ }
+ return SWIG_OK;
+
+ }
+
+ /* ------------------------------------------------------------
+ * memberconstantHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberconstantHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ int oldshadow = shadow;
+ if (shadow) shadow = shadow | PYSHADOW_MEMBER;
+ Language::memberconstantHandler(n);
+ shadow = oldshadow;
+
+ if (shadow) {
+ Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(class_name,symname), "\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * pythoncode() - Output python code into the shadow file
+ * ------------------------------------------------------------ */
+
+ String *pythoncode(String *code, const String *indent) {
+ String *out = NewString("");
+ String *temp;
+ char *t;
+ if (!indent) indent = "";
+
+ temp = NewString(code);
+
+ t = Char(temp);
+ if (*t == '{') {
+ Delitem(temp,0);
+ Delitem(temp,DOH_END);
+ }
+ /* Split the input text into lines */
+ List *clist = DohSplit(temp,'\n',-1);
+ Delete(temp);
+ int initial = 0;
+ String *s;
+
+ /* Get the initial indentation */
+ for (s = Firstitem(clist); s; s = Nextitem(clist)) {
+ if (Len(s)) {
+ char *c = Char(s);
+ while (*c) {
+ if (!isspace(*c)) break;
+ initial++;
+ c++;
+ }
+ if (*c && !isspace(*c)) break;
+ else {
+ initial = 0;
+ }
+ }
+ }
+ while (s) {
+ if (Len(s) > initial) {
+ char *c = Char(s);
+ c += initial;
+ Printv(out,indent,c,"\n",NIL);
+ } else {
+ Printv(out,"\n",NIL);
+ }
+ s = Nextitem(clist);
+ }
+ Delete(clist);
+ return out;
+ }
+
+ /* ------------------------------------------------------------
+ * insertDirective()
+ *
+ * Hook for %insert directive. We're going to look for special %shadow inserts
+ * as a special case so we can do indenting correctly
+ * ------------------------------------------------------------ */
+
+ virtual int insertDirective(Node *n) {
+ String *code = Getattr(n,"code");
+ String *section = Getattr(n,"section");
+
+ if ((!ImportMode) && ((Cmp(section,"python") == 0) || (Cmp(section,"shadow") == 0))) {
+ if (shadow) {
+ String *pycode = pythoncode(code,shadow_indent);
+ Printv(f_shadow, pycode, "\n", NIL);
+ Delete(pycode);
+ }
+ } else {
+ Language::insertDirective(n);
+ }
+ return SWIG_OK;
+ }
+};
+
+/* -----------------------------------------------------------------------------
+ * swig_python() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+extern "C" Language *
+swig_python(void) {
+ return new PYTHON();
+}
diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx
new file mode 100644
index 000000000..f5f0a796a
--- /dev/null
+++ b/Source/Modules/ruby.cxx
@@ -0,0 +1,1440 @@
+/********************************************************************
+ * Ruby module for SWIG
+ *
+ * $Header$
+ *
+ * Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
+ * Copyright (C) 2000 Information-technology Promotion Agency, Japan
+ *
+ * Masaki Fukushima
+ *
+ ********************************************************************/
+
+char cvsroot_ruby_cxx[] = "$Header$";
+
+#include "swigmod.h"
+
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+
+#include
+#include
+#include /* for INT_MAX */
+
+class RClass {
+ private:
+ String *temp;
+ public:
+ String *name; /* class name (renamed) */
+ String *cname; /* original C class/struct name */
+ String *mname; /* Mangled name */
+ String *vname; /* variable name */
+ String *type;
+ String *prefix;
+ String *header;
+ String *init;
+
+ int constructor_defined;
+ int destructor_defined;
+
+ RClass() {
+ temp = NewString("");
+ name = NewString("");
+ cname = NewString("");
+ mname = NewString("");
+ vname = NewString("");
+ type = NewString("");
+ prefix = NewString("");
+ header = NewString("");
+ init = NewString("");
+ constructor_defined = 0;
+ destructor_defined = 0;
+ }
+
+ ~RClass() {
+ Delete(name);
+ Delete(cname);
+ Delete(vname);
+ Delete(mname);
+ Delete(type);
+ Delete(prefix);
+ Delete(header);
+ Delete(init);
+ Delete(temp);
+ }
+
+ void set_name(const String_or_char *cn, const String_or_char *rn, const String_or_char *valn) {
+ Clear(cname);
+ Append(cname,cn);
+ Delete(mname);
+ mname = Swig_name_mangle(cname);
+ Clear(name);
+ Append(name,valn);
+ Clear(vname);
+ Printf(vname,"c%s.klass",name);
+ Clear(prefix);
+ Printv(prefix,(rn ? rn : cn), "_", NIL);
+ }
+
+ char *strip(const String_or_char *s) {
+ Clear(temp);
+ Append(temp, s);
+ if (Strncmp(s, prefix, Len(prefix)) == 0) {
+ Replaceall(temp,prefix,"");
+ }
+ return Char(temp);
+ }
+};
+
+
+#ifdef RUBY_SUPPORTS_KEYWORD_ARGS
+static const char *
+usage = "\
+Ruby Options (available with -ruby)\n\
+ -ldflags - Print runtime libraries to link with\n\
+ -feature name - Set feature name (used by `require')\n\
+ -keyword - Use keyword arguments\n";
+#else
+static const char *
+usage = "\
+Ruby Options (available with -ruby)\n\
+ -ldflags - Print runtime libraries to link with\n\
+ -feature name - Set feature name (used by `require')\n";
+#endif
+
+#define RCLASS(hash, name) (RClass*)(Getattr(hash, name) ? Data(Getattr(hash, name)) : 0)
+#define SET_RCLASS(hash, name, klass) Setattr(hash, name, NewVoid(klass, 0))
+
+
+class RUBY : public Language {
+private:
+
+ String *module;
+ String *modvar;
+ String *feature;
+ int current;
+ Hash *classes; /* key=cname val=RClass */
+ RClass *klass; /* Currently processing class */
+ Hash *special_methods; /* Python style special method name table */
+ File *f_runtime;
+ File *f_header;
+ File *f_wrappers;
+ File *f_init;
+ bool use_kw;
+
+ // Wrap modes
+ enum {
+ NO_CPP,
+ MEMBER_FUNC,
+ CONSTRUCTOR_ALLOCATE,
+ CONSTRUCTOR_INITIALIZE,
+ DESTRUCTOR,
+ MEMBER_VAR,
+ CLASS_CONST,
+ STATIC_FUNC,
+ STATIC_VAR
+ };
+
+public:
+
+ /* ---------------------------------------------------------------------
+ * RUBY()
+ *
+ * Initialize member data
+ * --------------------------------------------------------------------- */
+
+ RUBY() {
+ module = 0;
+ modvar = 0;
+ feature = 0;
+ current = NO_CPP;
+ classes = 0;
+ klass = 0;
+ special_methods = 0;
+ f_runtime = 0;
+ f_header = 0;
+ f_wrappers = 0;
+ f_init = 0;
+ use_kw = false;
+ }
+
+ /* ---------------------------------------------------------------------
+ * main()
+ *
+ * Parse command line options and initializes variables.
+ * --------------------------------------------------------------------- */
+
+ virtual void main(int argc, char *argv[]) {
+
+ /* Set location of SWIG library */
+ SWIG_library_directory("ruby");
+
+ /* Look for certain command line options */
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i],"-feature") == 0) {
+ if (argv[i+1]) {
+ char *name = argv[i+1];
+ feature = NewString(name);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i],"-help") == 0) {
+ Printf(stderr,"%s\n", usage);
+ } else if (strcmp (argv[i],"-ldflags") == 0) {
+ printf("%s\n", SWIG_RUBY_RUNTIME);
+ SWIG_exit (EXIT_SUCCESS);
+ } else if (strcmp(argv[i],"-keyword") == 0) {
+ use_kw = true;
+ Swig_mark_arg(i);
+ }
+ }
+ }
+
+ /* Add a symbol to the parser for conditional compilation */
+ Preprocessor_define("SWIGRUBY 1", 0);
+
+ /* Add typemap definitions */
+ SWIG_typemap_lang("ruby");
+ SWIG_config_file("ruby.swg");
+ allow_overloading();
+ }
+
+ /* ---------------------------------------------------------------------
+ * top()
+ * --------------------------------------------------------------------- */
+
+ virtual int top(Node *n) {
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
+
+ f_runtime = NewFile(outfile,"w");
+ if (!f_runtime) {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header",f_header);
+ Swig_register_filebyname("wrapper",f_wrappers);
+ Swig_register_filebyname("runtime",f_runtime);
+ Swig_register_filebyname("init",f_init);
+
+ modvar = 0;
+ current = NO_CPP;
+ klass = 0;
+ classes = NewHash();
+ special_methods = NewHash();
+
+ /* Python style special method name. */
+ /* Basic */
+ Setattr(special_methods, "__repr__", "inspect");
+ Setattr(special_methods, "__str__", "to_s");
+ Setattr(special_methods, "__cmp__", "<=>");
+ Setattr(special_methods, "__hash__", "hash");
+ Setattr(special_methods, "__nonzero__", "nonzero?");
+
+ /* Callable */
+ Setattr(special_methods, "__call__", "call");
+
+ /* Collection */
+ Setattr(special_methods, "__len__", "length");
+ Setattr(special_methods, "__getitem__", "[]");
+ Setattr(special_methods, "__setitem__", "[]=");
+
+ /* Operators */
+ Setattr(special_methods, "__add__", "+");
+ Setattr(special_methods, "__pos__", "+@");
+ Setattr(special_methods, "__sub__", "-");
+ Setattr(special_methods, "__neg__", "-@");
+ Setattr(special_methods, "__mul__", "*");
+ Setattr(special_methods, "__div__", "/");
+ Setattr(special_methods, "__mod__", "%");
+ Setattr(special_methods, "__lshift__", "<<");
+ Setattr(special_methods, "__rshift__", ">>");
+ Setattr(special_methods, "__and__", "&");
+ Setattr(special_methods, "__or__", "|");
+ Setattr(special_methods, "__xor__", "^");
+ Setattr(special_methods, "__invert__", "~");
+ Setattr(special_methods, "__lt__", "<");
+ Setattr(special_methods, "__le__", "<=");
+ Setattr(special_methods, "__gt__", ">");
+ Setattr(special_methods, "__ge__", ">=");
+ Setattr(special_methods, "__eq__", "==");
+
+ /* Other numeric */
+ Setattr(special_methods, "__divmod__", "divmod");
+ Setattr(special_methods, "__pow__", "**");
+ Setattr(special_methods, "__abs__", "abs");
+ Setattr(special_methods, "__int__", "to_i");
+ Setattr(special_methods, "__float__", "to_f");
+ Setattr(special_methods, "__coerce__", "coerce");
+
+ Swig_banner(f_runtime);
+
+ if (NoInclude) {
+ Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
+ }
+
+ /* typedef void *VALUE */
+ SwigType *value = NewSwigType(T_VOID);
+ SwigType_add_pointer(value);
+ SwigType_typedef(value,(char*)"VALUE");
+ Delete(value);
+
+ /* Set module name */
+ set_module(Char(Getattr(n,"name")));
+
+ Printf(f_header,"#define SWIG_init Init_%s\n", feature);
+ Printf(f_header,"#define SWIG_name \"%s\"\n\n", module);
+ Printf(f_header,"static VALUE %s;\n", modvar);
+
+ /* Start generating the initialization function */
+ Printv(f_init,
+ "\n",
+ "#ifdef __cplusplus\n",
+ "extern \"C\"\n",
+ "#endif\n",
+ "void Init_", feature, "(void) {\n",
+ "int i;\n",
+ "\n",
+ NIL);
+
+ Printv(f_init, tab4, "SWIG_InitRuntime();\n", NIL);
+
+ /* Account for nested modules */
+ List *modules = Split(module,':',INT_MAX);
+ if (modules != 0 && Len(modules) > 0) {
+ String *mv = 0;
+ String *m = Firstitem(modules);
+ while (m != 0) {
+ if (Len(m) > 0) {
+ if (mv != 0) {
+ Printv(f_init, tab4, modvar,
+ " = rb_define_module_under(", modvar, ", \"", m, "\");\n", NIL);
+ } else {
+ Printv(f_init, tab4, modvar,
+ " = rb_define_module(\"", m, "\");\n", NIL);
+ mv = NewString(modvar);
+ }
+ }
+ m = Nextitem(modules);
+ }
+ Delete(mv);
+ Delete(modules);
+ }
+
+ Printv(f_init,
+ "\n",
+ "for (i = 0; swig_types_initial[i]; i++) {\n",
+ "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n",
+ "SWIG_define_class(swig_types[i]);\n",
+ "}\n",
+ NIL);
+ Printf(f_init,"\n");
+
+ Language::top(n);
+
+ /* Finish off our init function */
+ Printf(f_init,"}\n");
+ SwigType_emit_type_table(f_runtime,f_wrappers);
+
+ /* Close all of the files */
+ Dump(f_header,f_runtime);
+ Dump(f_wrappers,f_runtime);
+ Wrapper_pretty_print(f_init,f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_runtime);
+ Delete(f_runtime);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * importDirective()
+ * ----------------------------------------------------------------------------- */
+
+ virtual int importDirective(Node *n) {
+ String *modname = Getattr(n,"module");
+ if (modname) {
+ Printf(f_init,"rb_require(\"%s\");\n", modname);
+ }
+ return Language::importDirective(n);
+ }
+
+ /* ---------------------------------------------------------------------
+ * set_module(const char *mod_name)
+ *
+ * Sets the module name. Does nothing if it's already set (so it can
+ * be overridden as a command line option).
+ *---------------------------------------------------------------------- */
+
+ void set_module(const char *s) {
+ String *mod_name = NewString(s);
+ if (module == 0) {
+ /* Start with the empty string */
+ module = NewString("");
+
+ /* Account for nested modules */
+ List *modules = Split(mod_name,':',INT_MAX);
+ if (modules != 0 && Len(modules) > 0) {
+ String *last = 0;
+ String *m = Firstitem(modules);
+ while (m != 0) {
+ if (Len(m) > 0) {
+ String *cap = NewString(m);
+ (Char(cap))[0] = toupper((Char(cap))[0]);
+ if (last != 0) {
+ Append(module, "::");
+ }
+ Append(module, cap);
+ last = m;
+ }
+ m = Nextitem(modules);
+ }
+ if (feature == 0) {
+ feature = Copy(last);
+ }
+ (Char(last))[0] = toupper((Char(last))[0]);
+ modvar = NewStringf("m%s", last);
+ Delete(modules);
+ }
+ }
+ Delete(mod_name);
+ }
+
+ /* --------------------------------------------------------------------------
+ * nativeWrapper()
+ * -------------------------------------------------------------------------- */
+ virtual int nativeWrapper(Node *n) {
+ String *funcname = Getattr(n,"wrap:name");
+ Swig_warning(WARN_LANG_NATIVE_UNIMPL, input_file, line_number,
+ "Adding native function %s not supported (ignored).\n", funcname);
+ return SWIG_NOWRAP;
+ }
+
+ /* ---------------------------------------------------------------------
+ * create_command(Node *n, char *iname)
+ *
+ * Creates a new command from a C function.
+ * iname = Name of function in scripting language
+ * --------------------------------------------------------------------- */
+
+ void create_command(Node *n, const String_or_char *iname) {
+
+ String *wname = Swig_name_wrapper(iname);
+ if (CPlusPlus) {
+ Insert(wname,0,"VALUEFUNC(");
+ Append(wname,")");
+ }
+ if (current != NO_CPP)
+ iname = klass->strip(iname);
+ if (Getattr(special_methods, iname)) {
+ iname = GetChar(special_methods, iname);
+ }
+
+ String *s = NewString("");
+ String *temp = NewString("");
+
+ switch (current) {
+ case MEMBER_FUNC:
+ Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"",
+ iname, "\", ", wname, ", -1);\n", NIL);
+ break;
+ case CONSTRUCTOR_ALLOCATE:
+ Printv(s, tab4, "rb_define_singleton_method(", klass->vname,
+ ", \"new\", ", wname, ", -1);\n", NIL);
+ Replaceall(klass->init,"$allocator", s);
+ break;
+ case CONSTRUCTOR_INITIALIZE:
+ Printv(s, tab4, "rb_define_method(", klass->vname,
+ ", \"initialize\", ", wname, ", -1);\n", NIL);
+ Replaceall(klass->init,"$initializer", s);
+ break;
+ case MEMBER_VAR:
+ Append(temp,iname);
+ Replaceall(temp,"_set", "=");
+ Replaceall(temp,"_get", "");
+ Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"",
+ temp, "\", ", wname, ", -1);\n", NIL);
+ break;
+ case STATIC_FUNC:
+ Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname,
+ ", \"", iname, "\", ", wname, ", -1);\n", NIL);
+ break;
+ default:
+ Printv(s, tab4, "rb_define_module_function(", modvar, ", \"",
+ iname, "\", ", wname, ", -1);\n",NIL);
+ Printv(f_init,s,NIL);
+ break;
+ }
+
+ /* Process the comma-separated list of aliases (if any) */
+ String *aliasv = Getattr(n,"feature:alias");
+ if (aliasv) {
+ List *aliases = Split(aliasv,',',INT_MAX);
+ if (aliases && Len(aliases) > 0) {
+ String *alias = Firstitem(aliases);
+ while (alias) {
+ if (Len(alias) > 0) {
+ Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias, "\", \"", iname, "\");\n", NIL);
+ }
+ alias = Nextitem(aliases);
+ }
+ }
+ Delete(aliases);
+ }
+
+ Delete(temp);
+ Delete(s);
+ Delete(wname);
+ }
+
+ /* ---------------------------------------------------------------------
+ * marshalInputArgs(int numarg, int numreq, int start, Wrapper *f)
+ *
+ * Checks each of the parameters in the parameter list for a "check"
+ * typemap and (if it finds one) inserts the typemapping code into
+ * the function wrapper.
+ * --------------------------------------------------------------------- */
+
+ void marshalInputArgs(ParmList *l, int numarg, int numreq, int start, String *kwargs, bool allow_kwargs, Wrapper *f) {
+ int i;
+ Parm *p;
+ String *tm;
+ char source[256], target[256];
+
+ int use_self = (current == MEMBER_FUNC || current == MEMBER_VAR) ? 1 : 0;
+ int varargs = emit_isvarargs(l);
+
+ Printf(kwargs,"{ ");
+ for (i = 0, p = l; i < numarg; i++) {
+
+ /* Skip ignored arguments */
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *pn = Getattr(p,"name");
+ String *ln = Getattr(p,"lname");
+
+ /* Produce string representation of source and target arguments */
+ int selfp = (use_self && i == 0);
+ if (selfp)
+ strcpy(source,"self");
+ else
+ sprintf(source,"argv[%d]",i-start);
+
+ sprintf(target,"%s", Char(ln));
+
+ if (i >= (numreq)) { /* Check if parsing an optional argument */
+ Printf(f->code," if (argc > %d) {\n", i - start);
+ }
+
+ /* Record argument name for keyword argument handling */
+ if (Len(pn)) {
+ Printf(kwargs,"\"%s\",", pn);
+ } else {
+ Printf(kwargs,"\"arg%d\",", i+1);
+ }
+
+ /* Look for an input typemap */
+ if ((tm = Getattr(p,"tmap:in"))) {
+ Replaceall(tm,"$target",ln);
+ Replaceall(tm,"$source",source);
+ Replaceall(tm,"$input",source);
+ Setattr(p,"emit:input",source);
+ Printf(f->code,"%s\n", tm);
+ p = Getattr(p,"tmap:in:next");
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument.\n", SwigType_str(pt,0));
+ p = nextSibling(p);
+ }
+ if (i >= numreq) {
+ Printf(f->code,"}\n");
+ }
+ }
+
+ /* Finish argument marshalling */
+ Printf(kwargs," NULL }");
+ if (allow_kwargs) {
+ Printv(f->locals, tab4, "char *kwnames[] = ", kwargs, ";\n", NIL);
+ }
+
+ /* Trailing varargs */
+ if (varargs) {
+ if (p && (tm = Getattr(p,"tmap:in"))) {
+ sprintf(source,"argv[%d]",i-start);
+ Replaceall(tm,"$input",source);
+ Setattr(p,"emit:input",source);
+ Printf(f->code,"if (argc > %d) {\n", i-start);
+ Printv(f->code,tm,"\n",NIL);
+ Printf(f->code,"}\n");
+ }
+ }
+ }
+
+ /* ---------------------------------------------------------------------
+ * insertConstraintCheckingCode(ParmList *l, Wrapper *f)
+ *
+ * Checks each of the parameters in the parameter list for a "check"
+ * typemap and (if it finds one) inserts the typemapping code into
+ * the function wrapper.
+ * --------------------------------------------------------------------- */
+
+ void insertConstraintCheckingCode(ParmList *l, Wrapper *f) {
+ Parm *p;
+ String *tm;
+ for (p = l; p;) {
+ if ((tm = Getattr(p,"tmap:check"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* ---------------------------------------------------------------------
+ * insertCleanupCode(ParmList *l, String *cleanup)
+ *
+ * Checks each of the parameters in the parameter list for a "freearg"
+ * typemap and (if it finds one) inserts the typemapping code into
+ * the function wrapper.
+ * --------------------------------------------------------------------- */
+
+ void insertCleanupCode(ParmList *l, String *cleanup) {
+ String *tm;
+ for (Parm *p = l; p; ) {
+ if ((tm = Getattr(p,"tmap:freearg"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Printv(cleanup,tm,"\n",NIL);
+ p = Getattr(p,"tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* ---------------------------------------------------------------------
+ * insertCleanupCode(ParmList *l, String *cleanup)
+ *
+ * Checks each of the parameters in the parameter list for a "argout"
+ * typemap and (if it finds one) inserts the typemapping code into
+ * the function wrapper.
+ * --------------------------------------------------------------------- */
+
+ void insertArgOutputCode(ParmList *l, String *outarg, int& need_result) {
+ String *tm;
+ for (Parm *p = l; p; ) {
+ if ((tm = Getattr(p,"tmap:argout"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Replaceall(tm,"$target","vresult");
+ Replaceall(tm,"$result","vresult");
+ Replaceall(tm,"$arg",Getattr(p,"emit:input"));
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(outarg,tm,"\n",NIL);
+ need_result = 1;
+ p = Getattr(p,"tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* ---------------------------------------------------------------------
+ * validIdentifier()
+ *
+ * Is this a valid identifier in the scripting language?
+ * Ruby method names can include any combination of letters, numbers
+ * and underscores. A Ruby method name may optionally end with
+ * a question mark ("?"), exclamation point ("!") or equals sign ("=").
+ *
+ * Methods whose names end with question marks are, by convention,
+ * predicate methods that return true or false (e.g. Array#empty?).
+ *
+ * Methods whose names end with exclamation points are, by convention,
+ * "mutators" that modify the instance in place (e.g. Array#sort!).
+ *
+ * Methods whose names end with an equals sign are attribute setters
+ * (e.g. Thread#critical=).
+ * --------------------------------------------------------------------- */
+
+ virtual int validIdentifier(String *s) {
+ char *c = Char(s);
+ while (*c) {
+ if ( !( isalnum(*c) || (*c == '_') || (*c == '?') || (*c == '!') || (*c == '=') ) ) return 0;
+ c++;
+ }
+ return 1;
+ }
+
+ /* ---------------------------------------------------------------------
+ * functionWrapper()
+ *
+ * Create a function declaration and register it with the interpreter.
+ * --------------------------------------------------------------------- */
+
+ virtual int functionWrapper(Node *n) {
+ String *symname = Copy(Getattr(n,"sym:name"));
+ SwigType *t = Getattr(n,"type");
+ ParmList *l = Getattr(n,"parms");
+ String *tm;
+
+ int need_result = 0;
+
+ /* Ruby needs no destructor wrapper */
+ if (current == DESTRUCTOR)
+ return SWIG_NOWRAP;
+
+ /* If the C++ class constructor is overloaded, we only want to
+ * write out the "new" singleton method once since it is always
+ * the same. (It's the "initialize" method that will handle the
+ * overloading). */
+
+ if (current == CONSTRUCTOR_ALLOCATE &&
+ Swig_symbol_isoverloaded(n) &&
+ Getattr(n, "sym:nextSibling") != 0) return SWIG_OK;
+
+ String *overname = 0;
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(symname, n))
+ return SWIG_ERROR;
+ }
+
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *kwargs = NewString("");
+ Wrapper *f = NewWrapper();
+
+ /* Rename predicate methods */
+ if (Getattr(n, "feature:predicate")) {
+ Append(symname, "?");
+ }
+
+ /* Determine the name of the SWIG wrapper function */
+ String *wname = Swig_name_wrapper(symname);
+ if (overname && current != CONSTRUCTOR_ALLOCATE) {
+ Append(wname,overname);
+ }
+
+ /* Emit arguments */
+ if (current != CONSTRUCTOR_ALLOCATE) {
+ emit_args(t,l,f);
+ }
+
+ /* Attach standard typemaps */
+ if (current != CONSTRUCTOR_ALLOCATE) {
+ emit_attach_parmmaps(l, f);
+ }
+ Setattr(n, "wrap:parms", l);
+
+ /* Get number of arguments */
+ int numarg = emit_num_arguments(l);
+ int numreq = emit_num_required(l);
+ int varargs = emit_isvarargs(l);
+ bool allow_kwargs = use_kw || Getattr(n,"feature:kwargs");
+
+ int start = (current == MEMBER_FUNC || current == MEMBER_VAR) ? 1 : 0;
+
+ /* Now write the wrapper function itself */
+ Printv(f->def, "static VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
+
+ if (current != CONSTRUCTOR_ALLOCATE) {
+ if (!varargs) {
+ Printf(f->code,"if ((argc < %d) || (argc > %d))\n", numreq-start, numarg-start);
+ } else {
+ Printf(f->code,"if (argc < %d)\n", numreq-start);
+ }
+ Printf(f->code,"rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc);\n",numreq-start);
+ }
+
+ /* Now walk the function parameter list and generate code */
+ /* to get arguments */
+ if (current != CONSTRUCTOR_ALLOCATE) {
+ marshalInputArgs(l, numarg, numreq, start, kwargs, allow_kwargs, f);
+ }
+
+ /* Insert constraint checking code */
+ insertConstraintCheckingCode(l, f);
+
+ /* Insert cleanup code */
+ insertCleanupCode(l, cleanup);
+
+ /* Insert argument output code */
+ insertArgOutputCode(l, outarg, need_result);
+
+ /* Now write code to make the function call */
+ if (current != CONSTRUCTOR_ALLOCATE) {
+ if (current == CONSTRUCTOR_INITIALIZE) {
+ String *action = Getattr(n,"wrap:action");
+ if (action) {
+ Append(action,"DATA_PTR(self) = result;");
+ }
+ }
+ emit_action(n,f);
+ }
+
+ int newobj = 0;
+ if (Getattr(n,"feature:new")) newobj = 1;
+
+ /* Return value if necessary */
+ if (SwigType_type(t) != T_VOID && current != CONSTRUCTOR_ALLOCATE && current != CONSTRUCTOR_INITIALIZE) {
+ need_result = 1;
+ if (Getattr(n, "feature:predicate")) {
+ Printv(f->code, tab4, "vresult = (result ? Qtrue : Qfalse);\n", NIL);
+ } else {
+ tm = Swig_typemap_lookup_new("out",n,"result",0);
+ if (tm) {
+ Replaceall(tm,"$result","vresult");
+ Replaceall(tm,"$source","result");
+ Replaceall(tm,"$target","vresult");
+ Replaceall(tm,"$owner", newobj ? "1" : "0");
+ Printv(f->code, tm, "\n", NIL);
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s.\n", SwigType_str(t,0));
+ }
+ }
+ }
+
+ /* Extra code needed for new and initialize methods */
+ if (current == CONSTRUCTOR_ALLOCATE) {
+ need_result = 1;
+ Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(t)));
+ Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n");
+ } else if (current == CONSTRUCTOR_INITIALIZE) {
+ need_result = 1;
+ // Printf(f->code, "DATA_PTR(self) = result;\n");
+ }
+
+ /* Dump argument output code; */
+ Printv(f->code,outarg,NIL);
+
+ /* Dump the argument cleanup code */
+ if (current != CONSTRUCTOR_ALLOCATE)
+ Printv(f->code,cleanup,NIL);
+
+ /* Look for any remaining cleanup. This processes the %new directive */
+ if (newobj) {
+ tm = Swig_typemap_lookup_new("newfree",n,"result",0);
+ if (tm) {
+ Replaceall(tm,"$source","result");
+ Printv(f->code,tm, "\n",NIL);
+ }
+ }
+
+ /* Special processing on return value. */
+ tm = Swig_typemap_lookup_new("ret",n,"result",0);
+ if (tm) {
+ Replaceall(tm,"$source","result");
+ Printv(f->code,tm, NIL);
+ }
+
+ /* Wrap things up (in a manner of speaking) */
+ if (need_result) {
+ if (current == CONSTRUCTOR_ALLOCATE) {
+ Printv(f->code, tab4, "return vresult;\n}\n", NIL);
+ } else if (current == CONSTRUCTOR_INITIALIZE) {
+ Printv(f->code, tab4, "return self;\n}\n", NIL);
+ } else {
+ Wrapper_add_local(f,"vresult","VALUE vresult = Qnil");
+ Printv(f->code, tab4, "return vresult;\n}\n", NIL);
+ }
+ } else {
+ Printv(f->code, tab4, "return Qnil;\n}\n", NIL);
+ }
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code,"$cleanup",cleanup);
+
+ /* Emit the function */
+ Wrapper_print(f, f_wrappers);
+
+ /* Now register the function with the interpreter */
+ if (!Swig_symbol_isoverloaded(n)) {
+ create_command(n, symname);
+ } else {
+ if (current == CONSTRUCTOR_ALLOCATE) {
+ create_command(n, symname);
+ } else {
+ Setattr(n, "wrap:name", wname);
+ if (!Getattr(n, "sym:nextSibling"))
+ dispatchFunction(n);
+ }
+ }
+
+ Delete(kwargs);
+ Delete(cleanup);
+ Delete(outarg);
+ DelWrapper(f);
+ Delete(symname);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * dispatchFunction()
+ * ------------------------------------------------------------ */
+
+ void dispatchFunction(Node *n) {
+ /* Last node in overloaded chain */
+
+ int maxargs;
+ String *tmp = NewString("");
+ String *dispatch = Swig_overload_dispatch(n, "return %s(nargs, args, self);", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *f = NewWrapper();
+ String *symname = Getattr(n, "sym:name");
+ String *wname = Swig_name_wrapper(symname);
+
+ Printv(f->def,
+ "static VALUE ", wname,
+ "(int nargs, VALUE *args, VALUE self) {",
+ NIL);
+
+ Wrapper_add_local(f, "argc", "int argc");
+ if (current == MEMBER_FUNC || current == MEMBER_VAR) {
+ Printf(tmp, "VALUE argv[%d]", maxargs+1);
+ } else {
+ Printf(tmp, "VALUE argv[%d]", maxargs);
+ }
+ Wrapper_add_local(f, "argv", tmp);
+ Wrapper_add_local(f, "ii", "int ii");
+ if (current == MEMBER_FUNC || current == MEMBER_VAR) {
+ Printf(f->code, "argc = nargs + 1;\n");
+ Printf(f->code, "argv[0] = self;\n");
+ Printf(f->code, "for (ii = 1; (ii < argc) && (ii < %d); ii++) {\n", maxargs);
+ Printf(f->code, "argv[ii] = args[ii-1];\n");
+ Printf(f->code, "}\n");
+ } else {
+ Printf(f->code, "argc = nargs;\n");
+ Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n", maxargs);
+ Printf(f->code, "argv[ii] = args[ii];\n");
+ Printf(f->code, "}\n");
+ }
+
+ Replaceall(dispatch, "$args", "nargs, args, self");
+ Printv(f->code, dispatch, "\n", NIL);
+ Printf(f->code, "rb_raise(rb_eArgError, \"No matching function for overloaded '%s'\");\n", symname);
+ Printf(f->code,"return Qnil;\n");
+ Printv(f->code, "}\n", NIL);
+ Wrapper_print(f, f_wrappers);
+ create_command(n, Char(symname));
+
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(tmp);
+ Delete(wname);
+ }
+
+ /* ---------------------------------------------------------------------
+ * variableWrapper()
+ * --------------------------------------------------------------------- */
+
+ virtual int variableWrapper(Node *n) {
+
+ char *name = GetChar(n,"name");
+ char *iname = GetChar(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+ String *tm;
+ String *getfname, *setfname;
+ Wrapper *getf, *setf;
+
+ getf = NewWrapper();
+ setf = NewWrapper();
+
+ /* create getter */
+ getfname = NewString(Swig_name_get(iname));
+ Printv(getf->def, "static VALUE\n", getfname, "(", NIL);
+ Printf(getf->def, "VALUE self");
+ Printf(getf->def, ") {");
+ Wrapper_add_local(getf,"_val","VALUE _val");
+
+ tm = Swig_typemap_lookup_new("varout",n, name, 0);
+ if (tm) {
+ Replaceall(tm,"$result","_val");
+ Replaceall(tm,"$target","_val");
+ Replaceall(tm,"$source",name);
+ Printv(getf->code,tm, NIL);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number,
+ "Unable to read variable of type %s\n", SwigType_str(t,0));
+ }
+ Printv(getf->code, tab4, "return _val;\n}\n", NIL);
+ Wrapper_print(getf,f_wrappers);
+
+ if (Getattr(n,"feature:immutable")) {
+ setfname = NewString("NULL");
+ } else {
+ /* create setter */
+ setfname = NewString(Swig_name_set(iname));
+ Printv(setf->def, "static VALUE\n", setfname, "(VALUE self, ", NIL);
+ Printf(setf->def, "VALUE _val) {");
+
+ tm = Swig_typemap_lookup_new("varin",n,name,0);
+ if (tm) {
+ Replaceall(tm,"$input","_val");
+ Replaceall(tm,"$source","_val");
+ Replaceall(tm,"$target",name);
+ Printv(setf->code,tm,"\n",NIL);
+ } 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,"}\n");
+ Wrapper_print(setf,f_wrappers);
+ }
+
+ /* define accessor method */
+ if (CPlusPlus) {
+ Insert(getfname,0,"VALUEFUNC(");
+ Append(getfname,")");
+ Insert(setfname,0,"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 (!Getattr(n,"feature:immutable")) {
+ Printv(s,
+ tab4, "rb_define_singleton_method(", klass->vname, ", \"",
+ klass->strip(iname), "=\", ", setfname, ", 1);\n",
+ NIL);
+ }
+ Printv(klass->init,s,NIL);
+ break;
+ default:
+ /* C global variable */
+ /* wrapped in Ruby module attribute */
+ Printv(s,
+ tab4, "rb_define_singleton_method(", modvar, ", \"",
+ iname, "\", ", getfname, ", 0);\n",
+ NIL);
+ if (!Getattr(n,"feature:immutable")) {
+ Printv(s,
+ tab4, "rb_define_singleton_method(", modvar, ", \"",
+ iname, "=\", ", setfname, ", 1);\n",
+ NIL);
+ }
+ Printv(f_init,s,NIL);
+ Delete(s);
+ break;
+ }
+ Delete(getfname);
+ Delete(setfname);
+ DelWrapper(setf);
+ DelWrapper(getf);
+ return SWIG_OK;
+ }
+
+
+ /* ---------------------------------------------------------------------
+ * validate_const_name(char *name)
+ *
+ * Validate constant name.
+ * --------------------------------------------------------------------- */
+
+ char *
+ validate_const_name(char *name, const char *reason) {
+ if (!name || name[0] == '\0')
+ return name;
+
+ if (isupper(name[0]))
+ return name;
+
+ if (islower(name[0])) {
+ name[0] = toupper(name[0]);
+ Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number,
+ "Wrong %s name (corrected to `%s')\n", reason, name);
+ return name;
+ }
+
+ Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number,
+ "Wrong %s name\n", reason);
+
+ return name;
+ }
+
+ /* ---------------------------------------------------------------------
+ * constantWrapper()
+ * --------------------------------------------------------------------- */
+
+ virtual int constantWrapper(Node *n) {
+ Swig_require(&n, "*sym:name", "type", "value", NIL);
+
+ char *iname = GetChar(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ char *value = GetChar(n,"value");
+
+ if (current == CLASS_CONST) {
+ iname = klass->strip(iname);
+ }
+ validate_const_name(iname, "constant");
+ SetChar(n, "sym:name", iname);
+
+ /* Special hook for member pointer */
+ if (SwigType_type(type) == T_MPOINTER) {
+ String *wname = Swig_name_wrapper(iname);
+ Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value);
+ value = Char(wname);
+ }
+ String *tm = Swig_typemap_lookup_new("constant", n, value, 0);
+ if (tm) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", iname);
+ Replaceall(tm, "$symname", iname);
+ Replaceall(tm, "$value", value);
+ if (current == CLASS_CONST) {
+ Replaceall(tm, "$module", klass->vname);
+ Printv(klass->init, tm, "\n", NIL);
+ } else {
+ Replaceall(tm,"$module", modvar);
+ Printf(f_init, "%s\n", tm);
+ }
+ } else {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number,
+ "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value);
+ }
+ Swig_restore(&n);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * classDeclaration()
+ *
+ * Records information about classes---even classes that might be defined in
+ * other modules referenced by %import.
+ * ----------------------------------------------------------------------------- */
+
+ virtual int classDeclaration(Node *n) {
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+ String *tdname = Getattr(n,"tdname");
+
+ name = tdname ? tdname : name;
+ String *namestr = SwigType_namestr(name);
+ klass = RCLASS(classes, Char(namestr));
+ if (!klass) {
+ klass = new RClass();
+ String *valid_name = NewString(symname ? symname : namestr);
+ validate_const_name(Char(valid_name), "class");
+ klass->set_name(namestr, symname, valid_name);
+ SET_RCLASS(classes, Char(namestr), klass);
+ Delete(valid_name);
+ }
+ Delete(namestr);
+ return Language::classDeclaration(n);
+ }
+
+ /* ----------------------------------------------------------------------
+ * classHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int classHandler(Node *n) {
+
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+ String *namestr = SwigType_namestr(name); // does template expansion
+
+ klass = RCLASS(classes, Char(namestr));
+ assert(klass);
+ Delete(namestr);
+ String *valid_name = NewString(symname);
+ validate_const_name(Char(valid_name), "class");
+
+ Clear(klass->type);
+ Printv(klass->type, Getattr(n,"classtype"), NIL);
+ Printv(klass->header, "\nswig_class c", valid_name, ";\n", NIL);
+ Printv(klass->init, "\n", tab4, NIL);
+ Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar,
+ ", \"", klass->name, "\", $super);\n", NIL);
+
+ SwigType *tt = NewString(name);
+ SwigType_add_pointer(tt);
+ SwigType_remember(tt);
+ String *tm = SwigType_manglestr(tt);
+ Printf(klass->init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) &c%s);\n", tm, valid_name);
+ Delete(tm);
+ Delete(tt);
+ Delete(valid_name);
+
+ /* Process the comma-separated list of mixed-in module names (if any) */
+ String *mixin = Getattr(n,"feature:mixin");
+ if (mixin) {
+ List *modules = Split(mixin,',',INT_MAX);
+ if (modules && Len(modules) > 0) {
+ String *mod = Firstitem(modules);
+ while (mod) {
+ if (Len(mod) > 0) {
+ Printf(klass->init, "rb_include_module(%s, rb_eval_string(\"%s\"));\n", klass->vname, mod);
+ }
+ mod = Nextitem(modules);
+ }
+ }
+ Delete(modules);
+ }
+
+ Printv(klass->init, "$allocator",NIL);
+ Printv(klass->init, "$initializer",NIL);
+
+ Printv(klass->header,
+ "$freeproto",
+ NIL);
+
+ Language::classHandler(n);
+
+ /* Handle inheritance */
+ List *baselist = Getattr(n,"bases");
+ if (baselist && Len(baselist)) {
+ Node *base = Firstitem(baselist);
+ String *basename = Getattr(base,"name");
+ String *basenamestr = SwigType_namestr(basename);
+ RClass *super = RCLASS(classes, Char(basenamestr));
+ Delete(basenamestr);
+ if (super) {
+ SwigType *btype = NewString(basename);
+ SwigType_add_pointer(btype);
+ SwigType_remember(btype);
+ String *bmangle = SwigType_manglestr(btype);
+ Insert(bmangle,0,"((swig_class *) SWIGTYPE");
+ Append(bmangle,"->clientdata)->klass");
+ Replaceall(klass->init,"$super",bmangle);
+ Delete(bmangle);
+ Delete(btype);
+ }
+
+ /* Warn about multiple inheritance if additional base class(es) listed */
+ base = Nextitem(baselist);
+ while (base) {
+ basename = Getattr(n,"name");
+ Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, input_file, line_number,
+ "Warning for %s: Base %s ignored. Multiple inheritance is not supported in Ruby.\n", basename, basename);
+ base = Nextitem(baselist);
+ }
+ }
+
+ /* Check to see if a %markfunc was specified */
+ String *markfunc = Getattr(n, "feature:markfunc");
+ if (markfunc) {
+ Printf(klass->init, "c%s.mark = (void (*)(void *)) %s;\n", klass->name, markfunc);
+ } else {
+ Printf(klass->init, "c%s.mark = 0;\n", klass->name);
+ }
+
+ /* Check to see if a %freefunc was specified */
+ String *freefunc = Getattr(n, "feature:freefunc");
+ if (freefunc) {
+ Printf(klass->init, "c%s.destroy = (void (*)(void *)) %s;\n", klass->name, freefunc);
+ } else {
+ if (klass->destructor_defined) {
+ Printf(klass->init, "c%s.destroy = (void (*)(void *)) free_%s;\n", klass->name, klass->mname);
+ }
+ }
+ Replaceall(klass->header,"$freeproto", "");
+
+ Printv(f_header, klass->header,NIL);
+
+ String *s = NewString("");
+ Printv(s, tab4, "rb_undef_method(CLASS_OF(", klass->vname,
+ "), \"new\");\n", NIL);
+ Replaceall(klass->init,"$allocator", s);
+ Replaceall(klass->init,"$initializer", "");
+ Replaceall(klass->init,"$super", "rb_cObject");
+ Delete(s);
+
+ Printv(f_init,klass->init,NIL);
+ klass = 0;
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberfunctionHandler()
+ *
+ * Method for adding C++ member function
+ *
+ * By default, we're going to create a function of the form :
+ *
+ * Foo_bar(this,args)
+ *
+ * Where Foo is the classname, bar is the member name and the this pointer
+ * is explicitly attached to the beginning.
+ *
+ * The renaming only applies to the member function part, not the full
+ * classname.
+ *
+ * --------------------------------------------------------------------- */
+
+ virtual int memberfunctionHandler(Node *n) {
+ current = MEMBER_FUNC;
+ Language::memberfunctionHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ---------------------------------------------------------------------
+ * constructorHandler()
+ *
+ * Method for adding C++ member constructor
+ * -------------------------------------------------------------------- */
+
+ virtual int constructorHandler(Node *n) {
+ /* First wrap the new singleton method */
+ current = CONSTRUCTOR_ALLOCATE;
+ Swig_name_register((String_or_char *) "construct", (String_or_char *) "%c_allocate");
+ Language::constructorHandler(n);
+
+ /* Now do the instance initialize method */
+ current = CONSTRUCTOR_INITIALIZE;
+ Swig_name_register((String_or_char *) "construct", (String_or_char *) "new_%c");
+ Language::constructorHandler(n);
+
+ /* Done */
+ Swig_name_unregister((String_or_char *) "construct");
+ current = NO_CPP;
+ klass->constructor_defined = 1;
+ return SWIG_OK;
+ }
+
+ /* ---------------------------------------------------------------------
+ * destructorHandler()
+ * -------------------------------------------------------------------- */
+
+ virtual int destructorHandler(Node *n) {
+ current = DESTRUCTOR;
+ Language::destructorHandler(n);
+
+ String *freefunc = NewString("");
+ String *freeproto = NewString("");
+ String *freebody = NewString("");
+
+ Printv(freefunc, "free_", klass->mname, NIL);
+ Printv(freeproto, "static void ", freefunc, "(", klass->type, " *);\n", NIL);
+ Printv(freebody, "static void\n",
+ freefunc, "(", klass->type, " *", Swig_cparm_name(0,0), ") {\n",
+ tab4, NIL);
+ if (Extend) {
+ String *wrap = Getattr(n, "wrap:code");
+ if (wrap) {
+ File *f_code = Swig_filebyname("header");
+ if (f_code) {
+ Printv(f_code, wrap, NIL);
+ }
+ }
+ /* Printv(freebody, Swig_name_destroy(name), "(", Swig_cparm_name(0,0), ")", NIL); */
+ Printv(freebody,Getattr(n,"wrap:action"), NIL);
+ } else {
+ /* When no extend mode, swig emits no destroy function. */
+ if (CPlusPlus)
+ Printf(freebody, "delete %s", Swig_cparm_name(0,0));
+ else
+ Printf(freebody, "free((char*) %s)", Swig_cparm_name(0,0));
+ }
+ Printv(freebody, ";\n}\n", NIL);
+
+ Replaceall(klass->header,"$freeproto", freeproto);
+ Printv(f_wrappers, freebody, NIL);
+
+ klass->destructor_defined = 1;
+ current = NO_CPP;
+ Delete(freefunc);
+ Delete(freeproto);
+ Delete(freebody);
+ return SWIG_OK;
+ }
+
+ /* ---------------------------------------------------------------------
+ * membervariableHandler()
+ *
+ * This creates a pair of functions to set/get the variable of a member.
+ * -------------------------------------------------------------------- */
+
+ virtual int
+ membervariableHandler(Node *n) {
+ current = MEMBER_VAR;
+ Language::membervariableHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ *
+ * Wrap a static C++ function
+ * ---------------------------------------------------------------------- */
+
+ virtual int
+ staticmemberfunctionHandler(Node *n) {
+ current = STATIC_FUNC;
+ Language::staticmemberfunctionHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberconstantHandler()
+ *
+ * Create a C++ constant
+ * --------------------------------------------------------------------- */
+
+ virtual int
+ memberconstantHandler(Node *n) {
+ current = CLASS_CONST;
+ Language::memberconstantHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ---------------------------------------------------------------------
+ * staticmembervariableHandler()
+ * --------------------------------------------------------------------- */
+
+ virtual int
+ staticmembervariableHandler(Node *n) {
+ current = STATIC_VAR;
+ Language::staticmembervariableHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+}; /* class RUBY */
+
+/* -----------------------------------------------------------------------------
+ * swig_ruby() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+extern "C" Language *
+swig_ruby(void) {
+ return new RUBY();
+}
+
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
+
diff --git a/Source/Modules/s-exp.cxx b/Source/Modules/s-exp.cxx
new file mode 100644
index 000000000..2a9f2dcc1
--- /dev/null
+++ b/Source/Modules/s-exp.cxx
@@ -0,0 +1,401 @@
+/* -----------------------------------------------------------------------------
+ * s-exp.cxx
+ *
+ * A parse tree represented as Lisp s-expressions.
+ *
+ * Author(s) : Matthias Koeppe (mkoeppe@mail.math.uni-magdeburg.de)
+ *
+ * Copyright (C) 2002. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+/* Derived from xml.cxx 1.1.2.2 */
+
+char cvsroot_s_exp_cxx[] = "$Header$";
+static const char *usage = "\
+S-Exp Options (available with -sexp)\n\
+ -typemaplang lang - Typemap language.\n\n";
+
+#include "swigmod.h"
+
+//static Node *view_top = 0;
+static File *out = 0;
+
+class Sexp : public Language {
+public:
+ int indent_level;
+ Sexp() : indent_level( 0 ) {}
+ virtual ~Sexp() {}
+ virtual void main(int argc, char *argv[]) {
+ SWIG_typemap_lang("sexp");
+ for( int iX = 0; iX < argc; iX++ )
+ {
+ if( strcmp( argv[iX], "-typemaplang" ) == 0 )
+ {
+ Swig_mark_arg (iX);
+ iX++;
+ SWIG_typemap_lang(argv[iX]);
+ Swig_mark_arg (iX);
+ continue;
+ }
+ if( strcmp( argv[iX], "-help" ) == 0 )
+ {
+ fputs( usage, stderr );
+ }
+ }
+ }
+
+ DOHHash *print_circle_hash;
+ int print_circle_count;
+ int hanging_parens;
+ bool need_whitespace;
+ bool need_newline;
+
+ /* Top of the parse tree */
+ virtual int top(Node *n)
+ {
+ if( out == 0 )
+ {
+ String *outfile = Getattr(n,"outfile");
+ Replaceall(outfile,"_wrap.cxx", ".lisp");
+ out = NewFile(outfile,"w");
+ if (!out)
+ {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+ Language::top(n);
+ Printf( out, ";;; Lisp parse tree produced by SWIG\n" );
+ print_circle_hash = DohNewHash();
+ print_circle_count = 0;
+ hanging_parens = 0;
+ need_whitespace = 0;
+ need_newline = 0;
+ Sexp_print_node(n);
+ flush_parens();
+ return SWIG_OK;
+ }
+
+ void print_indent()
+ {
+ int i;
+ for (i = 0; i < indent_level; i++)
+ {
+ Printf(out, " ");
+ }
+ }
+
+ void open_paren(const String *oper)
+ {
+ flush_parens();
+ Printf(out, "(");
+ if (oper) Printf(out, "%s ", oper);
+ indent_level += 2;
+ }
+
+ void close_paren(bool need_newline = false)
+ {
+ hanging_parens++;
+ if (need_newline)
+ print_lazy_whitespace();
+ indent_level -= 2;
+ }
+
+ void flush_parens()
+ {
+ int i;
+ if (hanging_parens) {
+ for (i = 0; i", obj);
+ }
+ }
+ }
+ }
+
+ void Sexp_print_as_keyword(const DOH *k)
+ {
+ /* Print key, replacing ":" with "-" because : is CL's package prefix */
+ flush_parens();
+ String *key = NewString(k);
+ Replaceall(key, ":", "-");
+ Replaceall(key, "_", "-");
+ Printf(out,":%s ", key);
+ Delete(key);
+ }
+
+ void Sexp_print_plist_noparens(DOH *obj)
+ {
+ /* attributes map names to objects */
+ String *k;
+ bool first;
+ for (k = Firstkey(obj), first = true; k; k = Nextkey(obj), first=false) {
+ if (!internal_key_p(k)) {
+ DOH *value = Getattr(obj, k);
+ flush_parens();
+ if (!first) {
+ Printf(out, " ");
+ }
+ Sexp_print_as_keyword(k);
+ /* Print value */
+ Sexp_print_value_of_key(value, k);
+ }
+ }
+ }
+
+ void Sexp_print_plist(DOH *obj)
+ {
+ flush_parens();
+ if (print_circle(obj, true)) {
+ open_paren(NIL);
+ Sexp_print_plist_noparens(obj);
+ close_paren();
+ }
+ }
+
+ void Sexp_print_attributes(Node * obj)
+ {
+ Sexp_print_plist_noparens(obj);
+ }
+
+ void Sexp_print_node(Node *obj)
+ {
+ Node *cobj;
+ open_paren(nodeType(obj));
+ /* A node has an attribute list... */
+ Sexp_print_attributes(obj);
+ /* ... and child nodes. */
+ cobj = firstChild(obj);
+ if (cobj) {
+ print_lazy_newline();
+ flush_parens();
+ Sexp_print_as_keyword("children");
+ open_paren(NIL);
+ for (; cobj; cobj = nextSibling(cobj)) {
+ Sexp_print_node(cobj);
+ }
+ close_paren();
+ }
+ close_paren();
+ }
+
+
+ virtual int functionWrapper(Node *n)
+ {
+ ParmList *l = Getattr(n,"parms");
+ Wrapper *f = NewWrapper();
+ emit_attach_parmmaps(l,f);
+ Setattr(n,"wrap:parms",l);
+ return SWIG_OK;
+ }
+
+};
+
+
+extern "C"
+{
+ Language * swig_sexp( void )
+ {
+ return new Sexp();
+ }
+}
diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx
new file mode 100644
index 000000000..2048bb82c
--- /dev/null
+++ b/Source/Modules/swigmain.cxx
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Simplified Wrapper and Interface Generator (SWIG)
+ *
+ * swigmain.cxx
+ *
+ * This file is the main entry point to SWIG. It collects the command
+ * line options, registers built-in language modules, and instantiates
+ * a module for code generation. If adding new language modules
+ * to SWIG, you would modify this file.
+ *
+ * Author : David Beazley
+ *
+ * Department of Computer Science
+ * University of Chicago
+ * 1100 E 58th Street
+ * Chicago, IL 60637
+ * beazley@cs.uchicago.edu
+ *
+ * Please read the file LICENSE for the copyright and terms by which SWIG
+ * can be used and distributed.
+ *******************************************************************************/
+
+char cvsroot_swigmain_cxx[] = "$Header$";
+
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+
+#include "swigmod.h"
+
+/* Module factories. These functions are used to instantiate
+ the built-in language modules. If adding a new language
+ module to SWIG, place a similar function here. Make sure
+ the function has "C" linkage. This is required so that modules
+ 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_guile(void);
+ Language *swig_mzscheme(void);
+ Language *swig_java(void);
+ Language *swig_php(void);
+ Language *swig_ocaml(void);
+ Language *swig_pike(void);
+ Language *swig_sexp(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. */
+
+swig_module modules[] = {
+ {"-guile", swig_guile, "Guile"},
+ {"-java", swig_java, "Java"},
+ {"-mzscheme", swig_mzscheme, "Mzscheme"},
+ {"-ocaml", swig_ocaml, "Ocaml"},
+ {"-perl", swig_perl5, "Perl"},
+ {"-perl5", swig_perl5, 0},
+ {"-php", swig_php, "PHP"},
+ {"-php4", swig_php, 0},
+ {"-pike", swig_pike, "Pike"},
+ {"-python", swig_python, "Python"},
+ {"-ruby", swig_ruby, "Ruby"},
+ {"-sexp", swig_sexp, "Lisp S-Expressions"},
+ {"-tcl", swig_tcl, "Tcl"},
+ {"-tcl8", swig_tcl, 0},
+ {"-xml", swig_xml, "XML"},
+ {NULL, NULL, NULL}
+};
+
+#ifdef MACSWIG
+#include
+#include
+#endif
+
+#ifndef SWIG_LANG
+#define SWIG_LANG "-python"
+#endif
+
+//-----------------------------------------------------------------
+// main()
+//
+// Main program. Initializes the files and starts the parser.
+//-----------------------------------------------------------------
+
+
+int main(int argc, char **argv) {
+ int i;
+ Language *dl = 0;
+ ModuleFactory fac = 0;
+
+ extern int SWIG_main(int, char **, Language *);
+
+#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;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i],"-dnone") == 0) ||
+ (strcmp(argv[i],"-dhtml") == 0) ||
+ (strcmp(argv[i],"-dlatex") == 0) ||
+ (strcmp(argv[i],"-dascii") == 0) ||
+ (strcmp(argv[i],"-stat") == 0))
+ {
+ Printf(stderr,"swig: Warning. %s option deprecated.\n",argv[i]);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-help") == 0) {
+ Printf(stderr,"Target Language Options:\n");
+ for (int j = 0; modules[j].name; j++) {
+ if (modules[j].help) {
+ Printf(stderr," %-15s - Generate %s wrappers.\n", modules[j].name, modules[j].help);
+ }
+ }
+ Swig_mark_arg(i);
+ }
+ }
+ }
+ if (!dl) {
+ fac = Swig_find_module(SWIG_LANG);
+ if (fac) {
+ dl = (fac)();
+ }
+ }
+ return SWIG_main(argc,argv,dl);
+}
+
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
new file mode 100644
index 000000000..2668b0cb5
--- /dev/null
+++ b/Source/Modules/swigmod.h
@@ -0,0 +1,255 @@
+/* -----------------------------------------------------------------------------
+ * swigmod.h
+ *
+ * Main header file for SWIG modules
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1998-2000. The University of Chicago
+ * Copyright (C) 1995-1998. The University of Utah and The Regents of the
+ * University of California.
+ *
+ * See the file LICENSE for information on usage and redistribution.
+ *
+ * $Header$
+ * ----------------------------------------------------------------------------- */
+
+#include
+#include
+#include
+
+#include "swigver.h"
+
+extern "C" {
+#include "swig.h"
+extern Hash *Preprocessor_define(const String_or_char *str, int swigmacro);
+}
+
+#include "swigwarn.h"
+
+#define NOT_VIRTUAL 0
+#define PLAIN_VIRTUAL 1
+#define PURE_VIRTUAL 2
+
+extern char *input_file;
+extern int line_number;
+extern int start_line;
+extern int CPlusPlus; // C++ mode
+extern int Extend; // Extend mode
+extern int NoInclude; // NoInclude flag
+extern int Verbose;
+extern int IsVirtual;
+extern int ImportMode;
+extern int NoExcept; // -no_except option
+
+/* Miscellaneous stuff */
+
+#define tab2 " "
+#define tab4 " "
+#define tab8 " "
+
+class Dispatcher {
+ public:
+
+ virtual int emit_one(Node *n);
+ virtual int emit_children(Node *n);
+ virtual int defaultHandler(Node *n);
+
+ /* Top of the parse tree */
+ virtual int top(Node *n) = 0;
+
+ /* SWIG directives */
+
+ virtual int applyDirective(Node *n);
+ virtual int clearDirective(Node *n);
+ virtual int constantDirective(Node *n);
+ virtual int extendDirective(Node *n);
+ virtual int fragmentDirective(Node *n);
+ virtual int importDirective(Node *n);
+ virtual int includeDirective(Node *n);
+ virtual int insertDirective(Node *n);
+ virtual int moduleDirective(Node *n);
+ virtual int nativeDirective(Node *n);
+ virtual int pragmaDirective(Node *n);
+ virtual int typemapDirective(Node *n);
+ virtual int typemapitemDirective(Node *n);
+ virtual int typemapcopyDirective(Node *n);
+ virtual int typesDirective(Node *n);
+
+ /* C/C++ parsing */
+
+ virtual int cDeclaration(Node *n);
+ virtual int externDeclaration(Node *n);
+ virtual int enumDeclaration(Node *n);
+ virtual int enumvalueDeclaration(Node *n);
+ virtual int classDeclaration(Node *n);
+ virtual int classforwardDeclaration(Node *n);
+ virtual int constructorDeclaration(Node *n);
+ virtual int destructorDeclaration(Node *n);
+ virtual int accessDeclaration(Node *n);
+ virtual int usingDeclaration(Node *n);
+ virtual int namespaceDeclaration(Node *n);
+ virtual int templateDeclaration(Node *n);
+};
+
+/************************************************************************
+ * class language:
+ *
+ * This class defines the functions that need to be supported by the
+ * scripting language being used. The translator calls these virtual
+ * functions to output different types of code for different languages.
+ *************************************************************************/
+
+class Language : public Dispatcher {
+public:
+ Language();
+ virtual ~Language();
+ virtual int emit_one(Node *n);
+
+ /* Parse command line options */
+
+ virtual void main(int argc, char *argv[]);
+
+ /* Top of the parse tree */
+
+ virtual int top(Node *n);
+
+ /* SWIG directives */
+
+
+ virtual int applyDirective(Node *n);
+ virtual int clearDirective(Node *n);
+ virtual int constantDirective(Node *n);
+ virtual int extendDirective(Node *n);
+ virtual int fragmentDirective(Node *n);
+ virtual int importDirective(Node *n);
+ virtual int includeDirective(Node *n);
+ virtual int insertDirective(Node *n);
+ virtual int moduleDirective(Node *n);
+ virtual int nativeDirective(Node *n);
+ virtual int pragmaDirective(Node *n);
+ virtual int typemapDirective(Node *n);
+ virtual int typemapcopyDirective(Node *n);
+ virtual int typesDirective(Node *n);
+
+ /* C/C++ parsing */
+
+ virtual int cDeclaration(Node *n);
+ virtual int externDeclaration(Node *n);
+ virtual int enumDeclaration(Node *n);
+ virtual int enumvalueDeclaration(Node *n);
+ virtual int classDeclaration(Node *n);
+ virtual int classforwardDeclaration(Node *n);
+ virtual int constructorDeclaration(Node *n);
+ virtual int destructorDeclaration(Node *n);
+ virtual int accessDeclaration(Node *n);
+ virtual int namespaceDeclaration(Node *n);
+ virtual int usingDeclaration(Node *n);
+
+ /* Function handlers */
+
+ virtual int functionHandler(Node *n);
+ virtual int globalfunctionHandler(Node *n);
+ virtual int memberfunctionHandler(Node *n);
+ virtual int staticmemberfunctionHandler(Node *n);
+ virtual int callbackfunctionHandler(Node *n);
+
+ /* Variable handlers */
+
+ virtual int variableHandler(Node *n);
+ virtual int globalvariableHandler(Node *n);
+ virtual int membervariableHandler(Node *n);
+ virtual int staticmembervariableHandler(Node *n);
+
+ /* C++ handlers */
+
+ virtual int memberconstantHandler(Node *n);
+ virtual int constructorHandler(Node *n);
+ virtual int copyconstructorHandler(Node *n);
+ virtual int destructorHandler(Node *n);
+ virtual int classHandler(Node *n);
+
+ /* Miscellaneous */
+
+ virtual int typedefHandler(Node *n);
+
+ /* Low-level code generation */
+
+ virtual int constantWrapper(Node *n);
+ virtual int variableWrapper(Node *n);
+ virtual int functionWrapper(Node *n);
+ virtual int nativeWrapper(Node *n);
+
+ /* Miscellaneous */
+
+ virtual int validIdentifier(String *s); /* valid identifier? */
+ virtual int addSymbol(String *s, Node *n); /* Add symbol */
+ virtual Node *symbolLookup(String *s); /* Symbol lookup */
+ virtual Node *classLookup(SwigType *s); /* Class lookup */
+
+ protected:
+ /* Patch C++ pass-by-value */
+ static void patch_parms(Parm *p);
+
+ /* Allow overloaded functions */
+ void allow_overloading(int val = 1);
+
+ /* Allow multiple-input typemaps */
+ void allow_multiple_input(int val = 1);
+
+ /* Wrapping class query */
+ int is_wrapping_class();
+
+ /* Return the node for the current class */
+ Node *getCurrentClass() const;
+
+ /* Return the real name of the current class */
+ String *getClassName() const;
+
+ /* Return the current class prefix */
+ String *getClassPrefix() const;
+
+ /* Fully qualified type name to use */
+ String *getClassType() const;
+
+ private:
+ Hash *symbols;
+ Hash *classtypes;
+ int overloading;
+ int multiinput;
+};
+
+extern int SWIG_main(int, char **, Language *);
+extern void emit_args(SwigType *, ParmList *, Wrapper *f);
+extern void SWIG_exit(int); /* use EXIT_{SUCCESS,FAILURE} */
+extern void SWIG_config_file(const String_or_char *);
+extern void SWIG_config_cppext(const char *ext);
+
+extern "C" void SWIG_typemap_lang(const char *);
+extern void SWIG_library_directory(const char *);
+extern int emit_num_arguments(ParmList *);
+extern int emit_num_required(ParmList *);
+extern int emit_isvarargs(ParmList *);
+extern void emit_attach_parmmaps(ParmList *, Wrapper *f);
+extern void emit_action(Node *n, Wrapper *f);
+extern List *Swig_overload_rank(Node *n);
+extern String *Swig_overload_dispatch(Node *n, const String_or_char *fmt, int *);
+
+
+extern "C" {
+ typedef Language *(*ModuleFactory)(void);
+}
+
+extern void Swig_register_module(const char *name, ModuleFactory fac);
+extern ModuleFactory Swig_find_module(const char *name);
+
+/* swig11.h ends here */
+
+
+
+
+
+
+
+
+
diff --git a/Source/Modules/tcl8.cxx b/Source/Modules/tcl8.cxx
new file mode 100644
index 000000000..0f9738715
--- /dev/null
+++ b/Source/Modules/tcl8.cxx
@@ -0,0 +1,832 @@
+/* -----------------------------------------------------------------------------
+ * tcl8.cxx
+ *
+ * Tcl8.0 wrapper module.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1999-2000. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_tcl8_cxx[] = "$Header$";
+
+#include "swigmod.h"
+
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+
+static const char *usage = (char*)"\
+Tcl 8 Options (available with -tcl)\n\
+ -ldflags - Print runtime libraries to link with\n\
+ -prefix name - Set a prefix to be appended to all names\n\
+ -namespace - Build module into a Tcl 8 namespace. \n\
+ -pkgversion - Set package version.\n\n";
+
+static String *cmd_tab = 0; /* Table of command names */
+static String *var_tab = 0; /* Table of global variables */
+static String *const_tab = 0; /* Constant table */
+static String *methods_tab = 0; /* Methods table */
+static String *attr_tab = 0; /* Attribute table */
+static String *prefix = 0;
+static String *module = 0;
+static int nspace = 0;
+static String *init_name = 0;
+static String *ns_name = 0;
+static int have_constructor;
+static int have_destructor;
+static String *destructor_action = 0;
+static String *version = (String *) "0.0";
+static String *class_name = 0;
+
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+static File *f_runtime = 0;
+
+class TCL8 : public Language {
+public:
+
+ /* ------------------------------------------------------------
+ * TCL8::main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+
+ SWIG_library_directory("tcl");
+
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i],"-prefix") == 0) {
+ if (argv[i+1]) {
+ prefix = NewString(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ } else Swig_arg_error();
+ } else if (strcmp(argv[i],"-pkgversion") == 0) {
+ if (argv[i+1]) {
+ version = NewString(argv[i+1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i+1);
+ i++;
+ }
+ } else if (strcmp(argv[i],"-namespace") == 0) {
+ nspace = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-help") == 0) {
+ fputs(usage,stderr);
+ } else if (strcmp (argv[i], "-ldflags") == 0) {
+ printf("%s\n", SWIG_TCL_RUNTIME);
+ SWIG_exit (EXIT_SUCCESS);
+ }
+ }
+ }
+ Preprocessor_define("SWIGTCL 1",0);
+ Preprocessor_define("SWIGTCL8 1", 0);
+ SWIG_typemap_lang("tcl8");
+ SWIG_config_file("tcl8.swg");
+ allow_overloading();
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
+
+ f_runtime = NewFile(outfile,"w");
+ if (!f_runtime) {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header",f_header);
+ Swig_register_filebyname("wrapper",f_wrappers);
+ Swig_register_filebyname("runtime",f_runtime);
+ Swig_register_filebyname("init",f_init);
+
+ /* Initialize some variables for the object interface */
+
+ cmd_tab = NewString("");
+ var_tab = NewString("");
+ methods_tab = NewString("");
+ const_tab = NewString("");
+
+ Swig_banner(f_runtime);
+
+ /* Include a Tcl configuration file */
+ if (NoInclude) {
+ Printf(f_runtime,"#define SWIG_NOINCLUDE\n");
+ }
+
+ /* Set the module name, namespace, and prefix */
+
+ module = NewStringf("%(lower)s", Getattr(n,"name"));
+ init_name = NewStringf("%(title)s_Init",module);
+
+ ns_name = prefix ? Copy(prefix) : Copy(module);
+ if (prefix) Append(prefix,"_");
+
+ /* Generate some macros used throughout code generation */
+
+ Printf(f_header,"#define SWIG_init %s\n", init_name);
+ Printf(f_header,"#define SWIG_name \"%s\"\n", module);
+ if (nspace) {
+ Printf(f_header,"#define SWIG_prefix \"%s::\"\n", ns_name);
+ Printf(f_header,"#define SWIG_namespace \"%s\"\n\n", ns_name);
+ } else {
+ Printf(f_header,"#define SWIG_prefix \"%s\"\n", prefix);
+ }
+ Printf(f_header,"#define SWIG_version \"%s\"\n", version);
+
+ Printf(cmd_tab, "\nstatic swig_command_info swig_commands[] = {\n");
+ Printf(var_tab, "\nstatic swig_var_info swig_variables[] = {\n");
+ Printf(const_tab, "\nstatic swig_const_info swig_constants[] = {\n");
+
+ Printf(f_wrappers,"#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
+
+ /* Start emitting code */
+ Language::top(n);
+
+ /* Done. Close up the module */
+ Printv(cmd_tab, tab4, "{0, 0, 0}\n", "};\n",NIL);
+ Printv(var_tab, tab4, "{0,0,0,0}\n", "};\n",NIL);
+ Printv(const_tab, tab4, "{0,0,0,0,0,0}\n", "};\n", NIL);
+
+ Printv(f_wrappers, cmd_tab, var_tab, const_tab,NIL);
+
+ /* Dump the pointer equivalency table */
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+
+ Printf(f_wrappers,"#ifdef __cplusplus\n}\n#endif\n");
+
+ /* Close the init function and quit */
+ Printf(f_init,"return TCL_OK;\n}\n");
+
+ /* Close all of the files */
+ Printv(f_runtime, f_header, f_wrappers,NIL);
+ Wrapper_pretty_print(f_init,f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_runtime);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int functionWrapper(Node *n) {
+ String *name = Getattr(n,"name"); /* Like to get rid of this */
+ String *iname = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ ParmList *parms = Getattr(n,"parms");
+ String *overname = 0;
+
+ Parm *p;
+ int i;
+ String *tm;
+ Wrapper *f;
+ String *incode, *cleanup, *outarg, *argstr, *args;
+ int num_arguments = 0;
+ int num_required = 0;
+ int varargs = 0;
+
+ char source[64];
+
+ if (Getattr(n,"sym:overloaded")) {
+ overname = Getattr(n,"sym:overname");
+ } else {
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+ }
+
+ incode = NewString("");
+ cleanup = NewString("");
+ outarg = NewString("");
+ argstr = NewString("\"");
+ args = NewString("");
+
+ f = NewWrapper();
+ String *wname = Swig_name_wrapper(iname);
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n,"wrap:name",wname);
+
+ Printv(f->def,
+ "static int\n ", wname, "(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {",
+ NIL);
+
+ /* Print out variables for storing arguments. */
+ emit_args(type,parms, f);
+
+ /* Attach standard typemaps */
+ emit_attach_parmmaps(parms,f);
+ Setattr(n,"wrap:parms",parms);
+
+ /* Get number of require and total arguments */
+ num_arguments = emit_num_arguments(parms);
+ num_required = emit_num_required(parms);
+ varargs = emit_isvarargs(parms);
+
+ /* Unmarshal parameters */
+
+ for (i = 0, p = parms; i < num_arguments; i++) {
+ /* Skip ignored arguments */
+
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p,"type");
+ String *ln = Getattr(p,"lname");
+
+ /* Produce string representations of the source and target arguments */
+ sprintf(source,"objv[%d]",i+1);
+
+ if (i == num_required) Putc('|',argstr);
+ if ((tm = Getattr(p,"tmap:in"))) {
+ String *parse = Getattr(p,"tmap:in:parse");
+ if (!parse) {
+ Replaceall(tm,"$target",ln);
+ Replaceall(tm,"$source",source);
+ Replaceall(tm,"$input",source);
+ Setattr(p,"emit:input",source);
+
+ if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) {
+ Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm,"$disown","0");
+ }
+
+ Putc('o',argstr);
+ Printf(args,",0");
+ if (i >= num_required) {
+ Printf(incode, "if (objc > %d) {\n", i+1);
+ }
+ Printf(incode,"%s\n", tm);
+ if (i >= num_required) {
+ Printf(incode, "}\n");
+ }
+ } else {
+ Printf(argstr,"%s",parse);
+ Printf(args,",&%s",ln);
+ if (Strcmp(parse,"p") == 0) {
+ SwigType *lt = SwigType_ltype(pt);
+ SwigType_remember(pt);
+ if (Cmp(lt,"p.void") == 0) {
+ Printf(args,",0");
+ } else {
+ Printf(args,",SWIGTYPE%s", SwigType_manglestr(pt));
+ }
+ Delete(lt);
+ }
+ }
+ p = Getattr(p,"tmap:in:next");
+ continue;
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument.\n", SwigType_str(pt,0));
+ }
+ p = nextSibling(p);
+ }
+
+ if (!varargs) {
+ Putc(':',argstr);
+ } else {
+ Putc(';',argstr);
+ /* If variable length arguments we need to emit the in typemap here */
+ if (p && (tm = Getattr(p,"tmap:in"))) {
+ sprintf(source,"objv[%d]", i+1);
+ Printf(incode,"if (objc > %d) {\n", i);
+ Replaceall(tm,"$input",source);
+ Printv(incode,tm,"\n", NIL);
+ Printf(incode,"}\n");
+ }
+ }
+
+ Printf(argstr,"%s\"",usage_string(Char(iname),type,parms));
+
+ Printv(f->code,
+ "if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) SWIG_fail;\n",
+ NIL);
+
+ Printv(f->code,incode,NIL);
+
+ /* Insert constraint checking code */
+ for (p = parms; p;) {
+ if ((tm = Getattr(p,"tmap:check"))) {
+ Replaceall(tm,"$target",Getattr(p,"lname"));
+ Printv(f->code,tm,"\n",NIL);
+ p = Getattr(p,"tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (i = 0, p = parms; p; i++) {
+ if ((tm = Getattr(p,"tmap:freearg"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Printv(cleanup,tm,"\n",NIL);
+ p = Getattr(p,"tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ for (i=0,p = parms; p;i++) {
+ if ((tm = Getattr(p,"tmap:argout"))) {
+ Replaceall(tm,"$source",Getattr(p,"lname"));
+ Replaceall(tm,"$target","(Tcl_GetObjResult(interp))");
+ Replaceall(tm,"$result","(Tcl_GetObjResult(interp))");
+ Replaceall(tm,"$arg",Getattr(p,"emit:input"));
+ Replaceall(tm,"$input",Getattr(p,"emit:input"));
+ Printv(outarg,tm,"\n",NIL);
+ p = Getattr(p,"tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Now write code to make the function call */
+ emit_action(n,f);
+
+ /* Need to redo all of this code (eventually) */
+
+ /* Return value if necessary */
+ if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
+ Replaceall(tm,"$source", "result");
+ Replaceall(tm,"$target", "Tcl_GetObjResult(interp)");
+ Replaceall(tm,"$result", "Tcl_GetObjResult(interp)");
+ Printf(f->code,"%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s in function %s.\n", SwigType_str(type,0), name);
+ }
+
+ /* Dump output argument code */
+ Printv(f->code,outarg,NIL);
+
+ /* Dump the argument cleanup code */
+ Printv(f->code,cleanup,NIL);
+
+ /* Look for any remaining cleanup */
+ if (Getattr(n,"feature:new")) {
+ if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printf(f->code,"%s\n", tm);
+ }
+ }
+
+ if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) {
+ Replaceall(tm,"$source","result");
+ Printf(f->code,"%s\n", tm);
+ }
+ Printv(f->code, "return TCL_OK;\n", NIL);
+ Printv(f->code, "fail:\n", cleanup, "return TCL_ERROR;\n", NIL);
+ Printv(f->code,"}\n", NIL);
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code,"$cleanup",cleanup);
+ Replaceall(f->code,"$symname", iname);
+
+ /* Dump out the function */
+ Wrapper_print(f,f_wrappers);
+
+ if (!Getattr(n,"sym:overloaded")) {
+ /* Register the function with Tcl */
+ Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", Swig_name_wrapper(iname), ", NULL},\n", NIL);
+ } else {
+ if (!Getattr(n,"sym:nextSibling")) {
+ /* Emit overloading dispatch function */
+
+ int maxargs;
+ String *dispatch = Swig_overload_dispatch(n,"return %s(clientData, interp, objc, objv);",&maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *df = NewWrapper();
+ String *dname = Swig_name_wrapper(iname);
+
+ Printv(df->def,
+ "static int\n", dname,
+ "(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {",
+ NIL);
+ Printf(df->code,"Tcl_Obj *CONST *argv = objv+1;\n");
+ Printf(df->code,"int argc = objc-1;\n");
+ Printv(df->code,dispatch,"\n",NIL);
+ Printf(df->code,"Tcl_SetResult(interp,(char *) \"No matching function for overloaded '%s'\", TCL_STATIC);\n", iname);
+ Printf(df->code,"return TCL_ERROR;\n");
+ Printv(df->code,"}\n",NIL);
+ Wrapper_print(df,f_wrappers);
+ Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", dname, ", NULL},\n", NIL);
+ DelWrapper(df);
+ Delete(dispatch);
+ Delete(dname);
+ }
+ }
+
+ Delete(incode);
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(argstr);
+ Delete(args);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+
+ String *name = Getattr(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
+
+ String *setname = 0;
+ String *getname = 0;
+ Wrapper *setf = 0, *getf = 0;
+ int readonly = 0;
+ String *tm;
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ /* Create a function for getting a variable */
+ getf = NewWrapper();
+ getname = Swig_name_wrapper(Swig_name_get(iname));
+ Printv(getf->def,"static char *",getname,"(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {",NIL);
+ Wrapper_add_local(getf,"value", "Tcl_Obj *value = 0");
+
+ if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) {
+ Replaceall(tm,"$source", name);
+ Replaceall(tm,"$target","value");
+ Replaceall(tm,"$result", "value");
+ Printf(getf->code, "%s\n",tm);
+ Printf(getf->code, "if (value) {\n");
+ Printf(getf->code, "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n");
+ Printf(getf->code, "Tcl_DecrRefCount(value);\n");
+ Printf(getf->code, "}\n");
+ Printf(getf->code, "return NULL;\n");
+ Printf(getf->code,"}\n");
+ Wrapper_print(getf,f_wrappers);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number,
+ "Can't link to variable of type %s\n", SwigType_str(t,0));
+ DelWrapper(getf);
+ return SWIG_NOWRAP;
+ }
+ DelWrapper(getf);
+
+ /* Try to create a function setting a variable */
+ if (!Getattr(n,"feature:immutable")) {
+ setf = NewWrapper();
+ setname = Swig_name_wrapper(Swig_name_set(iname));
+ Printv(setf->def,"static char *",setname, "(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {",NIL);
+ Wrapper_add_local(setf,"value", "Tcl_Obj *value = 0");
+ Wrapper_add_local(setf,"name1o", "Tcl_Obj *name1o = 0");
+
+ if ((tm = Swig_typemap_lookup_new("varin", n, name, 0))) {
+ Replaceall(tm,"$source","value");
+ Replaceall(tm,"$target",name);
+ Replaceall(tm,"$input", "value");
+ Printf(setf->code,"name1o = Tcl_NewStringObj(name1,-1);\n");
+ Printf(setf->code,"value = Tcl_ObjGetVar2(interp, name1o, 0, flags);\n");
+ Printf(setf->code,"Tcl_DecrRefCount(name1o);\n");
+ Printf(setf->code,"if (!value) return NULL;\n");
+ Printf(setf->code,"%s\n", tm);
+ Printf(setf->code,"return NULL;\n");
+ Printf(setf->code,"}\n");
+ if (setf) Wrapper_print(setf,f_wrappers);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF,input_file, line_number,
+ "Variable %s will be read-only without a varin typemap.\n", name);
+ readonly = 1;
+ }
+ DelWrapper(setf);
+ }
+
+ Printv(var_tab, tab4,"{ SWIG_prefix \"", iname, "\", 0, (swig_variable_func) ", getname, ",", NIL);
+ if (readonly || Getattr(n,"feature:immutable")) {
+ static int readonlywrap = 0;
+ if (!readonlywrap) {
+ Wrapper *ro = NewWrapper();
+ Printf(ro->def, "static const char *swig_readonly(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {");
+ Printv(ro->code, "return (char*) \"Variable is read-only\";\n", "}\n", NIL);
+ Wrapper_print(ro,f_wrappers);
+ readonlywrap = 1;
+ DelWrapper(ro);
+ }
+ Printf(var_tab, "(swig_variable_func) swig_readonly},\n");
+ } else {
+ Printv(var_tab, "(swig_variable_func) ", setname, "},\n",NIL);
+ }
+ Delete(setname);
+ Delete(getname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *name = Getattr(n,"name");
+ String *iname = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ String *value = Getattr(n,"value");
+ String *tm;
+
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
+
+ /* Special hook for member pointer */
+ if (SwigType_type(type) == T_MPOINTER) {
+ String *wname = Swig_name_wrapper(iname);
+ Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type,wname), value);
+ value = Char(wname);
+ }
+ if ((tm = Swig_typemap_lookup_new("consttab",n,name,0))) {
+ Replaceall(tm,"$source",value);
+ Replaceall(tm,"$target",name);
+ Replaceall(tm,"$value",value);
+ Printf(const_tab,"%s,\n", tm);
+ } else if ((tm = Swig_typemap_lookup_new("constcode", n, name, 0))) {
+ Replaceall(tm,"$source", value);
+ Replaceall(tm,"$target", name);
+ Replaceall(tm,"$value",value);
+ Printf(f_init, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF,
+ input_file, line_number, "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int nativeWrapper(Node *n) {
+ String *name = Getattr(n,"sym:name");
+ String *funcname = Getattr(n,"wrap:name");
+ if (!addSymbol(funcname,n)) return SWIG_ERROR;
+
+ Printf(f_init,"\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", (swig_wrapper_func) %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",name, funcname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int classHandler(Node *n) {
+
+ String *mangled_classname = 0;
+ String *real_classname = 0;
+
+ have_constructor = 0;
+ have_destructor = 0;
+ destructor_action = 0;
+
+ class_name = Getattr(n,"sym:name");
+ if (!addSymbol(class_name,n)) return SWIG_ERROR;
+
+ real_classname = Getattr(n,"name");
+ mangled_classname = Swig_name_mangle(real_classname);
+
+ attr_tab = NewString("");
+ Printf(attr_tab, "static swig_attribute swig_");
+ Printv(attr_tab, mangled_classname, "_attributes[] = {\n", NIL);
+
+ methods_tab = NewStringf("");
+ Printf(methods_tab,"static swig_method swig_");
+ Printv(methods_tab, mangled_classname, "_methods[] = {\n", NIL);
+
+ /* Generate normal wrappers */
+ Language::classHandler(n);
+
+ SwigType *t = Copy(Getattr(n,"name"));
+ SwigType_add_pointer(t);
+
+ // Catch all: eg. a class with only static functions and/or variables will not have 'remembered'
+ // SwigType_remember(t);
+ String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname);
+ SwigType_remember_clientdata(t,wrap_class);
+
+ // t = Copy(Getattr(n,"classtype"));
+ // SwigType_add_pointer(t);
+
+ String *rt = Copy(Getattr(n,"classtype"));
+ SwigType_add_pointer(rt);
+
+ // Register the class structure with the type checker
+ /* Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname); */
+ if (have_destructor) {
+ Printv(f_wrappers, "static void swig_delete_", class_name, "(void *obj) {\n", NIL);
+ if (destructor_action) {
+ Printv(f_wrappers, SwigType_str(rt,"arg1"), " = (", SwigType_str(rt,0), ") obj;\n", NIL);
+ Printv(f_wrappers, destructor_action, NIL);
+ } else {
+ if (CPlusPlus) {
+ Printv(f_wrappers," delete (", SwigType_str(rt,0), ") obj;\n",NIL);
+ } else {
+ Printv(f_wrappers," free((char *) obj);\n",NIL);
+ }
+ }
+ Printf(f_wrappers,"}\n");
+ }
+
+ Printf(methods_tab, " {0,0}\n};\n");
+ Printv(f_wrappers,methods_tab,NIL);
+
+ Printf(attr_tab, " {0,0,0}\n};\n");
+ Printv(f_wrappers,attr_tab,NIL);
+
+ /* Handle inheritance */
+
+ String *base_class = NewString("");
+ List *baselist = Getattr(n,"bases");
+ if (baselist && Len(baselist)) {
+ Node *base = Firstitem(baselist);
+ while (base) {
+ String *bname = Getattr(base, "name");
+ if ((!bname) || Getattr(base,"feature:ignore") || (!Getattr(base,"module"))) {
+ base = Nextitem(baselist);
+ continue;
+ }
+ String *bmangle = Swig_name_mangle(bname);
+ Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL);
+ Printf(base_class,"&_wrap_class_%s",bmangle);
+ base = Nextitem(baselist);
+ Putc(',',base_class);
+ Delete(bmangle);
+ }
+ }
+
+ Printv(f_wrappers,"static swig_class *swig_",mangled_classname,"_bases[] = {", base_class,"0};\n", NIL);
+ Delete(base_class);
+
+ Printv(f_wrappers, "swig_class _wrap_class_", mangled_classname, " = { \"", class_name,
+ "\", &SWIGTYPE", SwigType_manglestr(t), ",",NIL);
+
+ if (have_constructor) {
+ Printf(f_wrappers,"%s", Swig_name_wrapper(Swig_name_construct(class_name)));
+ } else {
+ Printf(f_wrappers,"0");
+ }
+ if (have_destructor) {
+ Printv(f_wrappers, ", swig_delete_", class_name,NIL);
+ } else {
+ Printf(f_wrappers,",0");
+ }
+ Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname,"_bases };\n", NIL);
+ Printv(cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_classname, "},\n", NIL);
+ Delete(t);
+ Delete(mangled_classname);
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberfunctionHandler(Node *n) {
+ String *name = Getattr(n,"name");
+ String *iname = GetChar(n,"sym:name");
+
+ String *realname, *rname;
+
+ Language::memberfunctionHandler(n);
+
+ realname = iname ? iname : name;
+ rname = Swig_name_wrapper(Swig_name_member(class_name, realname));
+ if (!Getattr(n,"sym:nextSibling")) {
+ Printv(methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL);
+ }
+ Delete(rname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int membervariableHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ String *rname;
+
+ Language::membervariableHandler(n);
+ Printv(attr_tab, tab4, "{ \"-", symname, "\",", NIL);
+ rname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name,symname)));
+ Printv(attr_tab, rname, ", ", NIL);
+ Delete(rname);
+ if (!Getattr(n,"feature:immutable")) {
+ rname = Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name,symname)));
+ Printv(attr_tab, rname, "},\n",NIL);
+ Delete(rname);
+ } else {
+ Printf(attr_tab, "0 },\n");
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+ Language::constructorHandler(n);
+ have_constructor = 1;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorHandler(Node *n) {
+ Language::destructorHandler(n);
+ have_destructor = 1;
+ destructor_action = Getattr(n,"wrap:action");
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * validIdentifier()
+ * ------------------------------------------------------------ */
+
+ virtual int validIdentifier(String *s) {
+ if (Strchr(s,' ')) return 0;
+ return 1;
+ }
+
+ /* ------------------------------------------------------------
+ * usage_string()
+ * ------------------------------------------------------------ */
+
+ char *
+ usage_string(char *iname, SwigType *, ParmList *l) {
+ static String *temp = 0;
+ Parm *p;
+ int i, numopt,pcount;
+
+ if (!temp) temp = NewString("");
+ Clear(temp);
+ if (nspace) {
+ Printf(temp,"%s::%s", ns_name,iname);
+ } else {
+ Printf(temp,"%s ", iname);
+ }
+ /* Now go through and print parameters */
+ i = 0;
+ pcount = ParmList_len(l);
+ numopt = 0; /*check_numopt(l); */
+ for (p = l; p; p = nextSibling(p)) {
+
+ SwigType *pt = Getattr(p,"type");
+ String *pn = Getattr(p,"name");
+ /* Only print an argument if not ignored */
+ if (!checkAttribute(p,"tmap:in:numinputs","0")) {
+ if (i >= (pcount-numopt))
+ Putc('?',temp);
+ if (Len(pn) > 0) {
+ Printf(temp, "%s",pn);
+ } else {
+ Printf(temp,"%s", SwigType_str(pt,0));
+ }
+ if (i >= (pcount-numopt)) Putc('?',temp);
+ Putc(' ',temp);
+ i++;
+ }
+ }
+ return Char(temp);
+ }
+};
+
+/* ----------------------------------------------------------------------
+ * swig_tcl() - Instantiate module
+ * ---------------------------------------------------------------------- */
+
+extern "C" Language *
+swig_tcl(void) {
+ return new TCL8();
+}
+
+
+
+
diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx
new file mode 100644
index 000000000..3e4f74338
--- /dev/null
+++ b/Source/Modules/typepass.cxx
@@ -0,0 +1,966 @@
+/* -----------------------------------------------------------------------------
+ * typepass.cxx
+ *
+ * This module builds all of the internal type information by collecting
+ * typedef declarations as well as registering classes, structures, and unions.
+ * This information is needed to correctly handle shadow classes and other
+ * advanced features. This phase of compilation is also used to perform
+ * type-expansion. All types are fully qualified with namespace prefixes
+ * and other information needed for compilation.
+ *
+ * This module also handles the %varargs directive by looking for
+ * "feature:varargs" and substituting ... with an alternative set of
+ * arguments.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1998-2002. The University of Chicago
+ * Copyright (C) 1995-1998. The University of Utah and The Regents of the
+ * University of California.
+ *
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_typepass_cxx[] = "$Header$";
+
+#include "swigmod.h"
+
+struct normal_node {
+ Symtab *symtab;
+ Hash *typescope;
+ List *normallist;
+ normal_node *next;
+};
+
+static normal_node *patch_list = 0;
+
+class TypePass : public Dispatcher {
+ Node *inclass;
+ Node *module;
+ int importmode;
+ String *nsname;
+ Hash *classhash;
+ List *normalize;
+
+ /* Normalize a type. Replaces type with fully qualified version */
+
+ void normalize_type(SwigType *ty) {
+ SwigType *qty;
+ /*qty = Swig_symbol_type_qualify(ty,0);*/
+ /* if (SwigType_istemplate(ty)) {
+ qty = Swig_symbol_type_qualify(ty,0);
+ Clear(ty);
+ Append(ty,qty);
+ }
+ */
+
+ if (CPlusPlus) {
+ Replaceall(ty,"struct ","");
+ Replaceall(ty,"union ","");
+ Replaceall(ty,"class ","");
+ }
+
+ qty = SwigType_typedef_qualified(ty);
+ /* Printf(stdout,"%s --> %s\n", ty, qty);*/
+ Clear(ty);
+ Append(ty,qty);
+ Delete(qty);
+ }
+
+ /* Normalize a parameter list */
+
+ void normalize_parms(ParmList *p) {
+ while (p) {
+ SwigType *ty = Getattr(p,"type");
+ normalize_type(ty);
+ String *value = Getattr(p,"value");
+ if (value) {
+ Node *n = Swig_symbol_clookup(value,0);
+ if (n) {
+ String *q = Swig_symbol_qualified(n);
+ if (q && Len(q)) {
+ String *vb = Swig_scopename_last(value);
+ Clear(value);
+ Printf(value,"%s::%s", SwigType_namestr(q), vb);
+ Delete(q);
+ }
+ }
+ }
+ if (value && SwigType_istemplate(value)) {
+ String *nv = SwigType_namestr(value);
+ Setattr(p,"value",nv);
+ }
+ p = nextSibling(p);
+ }
+ }
+
+ void normalize_later(ParmList *p) {
+ while (p) {
+ SwigType *ty = Getattr(p,"type");
+ Append(normalize,ty);
+ p = nextSibling(p);
+ }
+ }
+
+ /* Walk through entries in normalize list and patch them up */
+ void normalize_list() {
+ Hash *currentsym = Swig_symbol_current();
+
+ normal_node *nn = patch_list;
+ normal_node *np;
+ while (nn) {
+ Swig_symbol_setscope(nn->symtab);
+ SwigType_set_scope(nn->typescope);
+ SwigType *t;
+ for (t = Firstitem(nn->normallist); t; t = Nextitem(nn->normallist)) {
+ normalize_type(t);
+ }
+ Delete(nn->normallist);
+ np = nn->next;
+ delete(nn);
+ nn = np;
+ }
+ Swig_symbol_setscope(currentsym);
+ }
+
+ /* generate C++ inheritance type-relationships */
+ void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) {
+
+ if (first == cls) return; /* The Marcelo check */
+ if (!cls) cls = first;
+
+ List *ilist = Getattr(cls,"bases");
+ if (!ilist) {
+ List *nlist = Getattr(cls,"baselist");
+ if (nlist) {
+ int len = Len(nlist);
+ int i;
+ for (i = 0; i < len; i++) {
+ Node *bcls = 0;
+ int clsforward = 0;
+ String *bname = Getitem(nlist,i);
+ String *sname = bname;
+ String *tname = 0;
+
+ /* Try to locate the base class. We look in the symbol table and we chase
+ typedef declarations to get to the base class if necessary */
+ Symtab *st = Getattr(cls,"sym:symtab");
+
+ if (SwigType_istemplate(bname)) {
+ tname = SwigType_typedef_resolve_all(bname);
+ sname = tname;
+ }
+ while (1) {
+ String *qsname = SwigType_typedef_qualified(sname);
+ bcls = Swig_symbol_clookup(qsname,st);
+ Delete(qsname);
+ if (bcls) {
+ if (Strcmp(nodeType(bcls),"class") != 0) {
+ /* Not a class. The symbol could be a typedef. */
+ if (checkAttribute(bcls,"storage","typedef")) {
+ SwigType *decl = Getattr(bcls,"decl");
+ if (!decl || !(Len(decl))) {
+ sname = Getattr(bcls,"type");
+ st = Getattr(bcls,"sym:symtab");
+ if (SwigType_istemplate(sname)) {
+ if (tname) Delete(tname);
+ tname = SwigType_typedef_resolve_all(sname);
+ sname = tname;
+ }
+ continue;
+ }
+ }
+ if (Strcmp(nodeType(bcls),"classforward") != 0) {
+ Swig_error(Getfile(bname),Getline(bname),"'%s' is not a class. \n",bname);
+ } else {
+ Swig_warning(WARN_TYPE_INCOMPLETE,Getfile(bname),Getline(bname),"Base class '%s' is incomplete.\n", bname);
+ clsforward = 1;
+ }
+ bcls = 0;
+ } else {
+ if (Getattr(bcls,"typepass:visit")) {
+ if (!ilist) ilist = NewList();
+ Append(ilist,bcls);
+ } else {
+ Swig_error(Getfile(bcls),Getline(bcls),"class '%s' must be defined before it is used as a base class.\n", bname);
+ }
+ }
+ }
+ break;
+ }
+
+ if (tname) Delete(tname);
+ if (!bcls) {
+ if (!clsforward) {
+ if (!Getmeta(bname,"already_warned")) {
+ Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname),Getline(bname),"Nothing known about class '%s'. Ignored.\n", SwigType_namestr(bname));
+ if (Strchr(bname,'<')) {
+ Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Maybe you forgot to instantiate '%s' using %%template.\n", SwigType_namestr(bname));
+ }
+ Setmeta(bname,"already_warned","1");
+ }
+ }
+ SwigType_inherit(clsname,bname, cast);
+ }
+ }
+ }
+ if (ilist) {
+ Setattr(cls,"bases",ilist);
+ }
+ }
+ if (!ilist) return;
+ int len = Len(ilist);
+ int i;
+ for (i = 0; i < len; i++) {
+ Node *n = Getitem(ilist,i);
+ String *bname = Getattr(n,"name");
+ Node *bclass = n; /* Getattr(n,"class"); */
+ Hash *scopes = Getattr(bclass,"typescope");
+ SwigType_inherit(clsname,bname, cast);
+ if (!importmode) {
+ String *btype = Copy(bname);
+ SwigType_add_pointer(btype);
+ SwigType_remember(btype);
+ Delete(btype);
+ }
+ if (scopes) {
+ SwigType_inherit_scope(scopes);
+ }
+ /* Set up inheritance in the symbol table */
+ Symtab *s = Swig_symbol_current();
+ Symtab *st = Getattr(cls,"symtab");
+ Swig_symbol_setscope(st);
+ Swig_symbol_inherit(Getattr(bclass,"symtab"));
+ Swig_symbol_setscope(s);
+
+ /* Recursively hit base classes */
+ String *newcast = NewStringf("(%s *)%s", SwigType_namestr(Getattr(bclass,"name")), cast);
+ cplus_inherit_types(first,bclass,clsname, newcast);
+ Delete(newcast);
+ }
+ }
+
+ /* Clean overloaded list. Removes templates, friends, ignored, and errors */
+
+ void clean_overloaded(Node *n) {
+ Node *nn = Getattr(n,"sym:overloaded");
+ Node *first = 0;
+ int cnt = 0;
+ while (nn) {
+ if ((Strcmp(nodeType(nn),"template") == 0) ||
+ (Getattr(nn,"feature:ignore")) ||
+ (Getattr(nn,"error")) ||
+ ((Strcmp(nodeType(nn),"using") == 0) && !firstChild(nn)) ||
+ (checkAttribute(nn,"storage","friend"))) {
+ /* Remove from overloaded list */
+ Node *ps = Getattr(nn,"sym:previousSibling");
+ Node *ns = Getattr(nn,"sym:nextSibling");
+ if (ps) {
+ Setattr(ps,"sym:nextSibling",ns);
+ }
+ if (ns) {
+ Setattr(ns,"sym:previousSibling",ps);
+ }
+ Delattr(nn,"sym:previousSibling");
+ Delattr(nn,"sym:nextSibling");
+ Delattr(nn,"sym:overloaded");
+ nn = ns;
+ continue;
+ } else if ((Strcmp(nodeType(nn),"using") == 0)) {
+ /* A possibly dangerous parse tree hack. We're going to
+ cut the parse tree node out and stick in the resolved
+ using declarations */
+
+ Node *ps = Getattr(nn,"sym:previousSibling");
+ Node *ns = Getattr(nn,"sym:nextSibling");
+ Node *un = firstChild(nn);
+ Node *pn = un;
+
+ if (!first) {
+ first = un;
+ }
+ while (pn) {
+ Node *ppn = Getattr(pn,"sym:nextSibling");
+ Setattr(pn,"sym:overloaded",first);
+ Setattr(pn,"sym:overname", NewStringf("%s_%d", Getattr(nn,"sym:overname"), cnt++));
+ if (ppn) pn = ppn;
+ else break;
+ }
+ if (ps) {
+ Setattr(ps,"sym:nextSibling",un);
+ Setattr(un,"sym:previousSibling",ps);
+ }
+ if (ns) {
+ Setattr(ns,"sym:previousSibling", pn);
+ Setattr(pn,"sym:nextSibling",ns);
+ }
+ if (!first) {
+ first = un;
+ Setattr(nn,"sym:overloaded",first);
+ }
+ } else {
+ if (!first) first = nn;
+ Setattr(nn,"sym:overloaded",first);
+ }
+ nn = Getattr(nn,"sym:nextSibling");
+ }
+ if (!first || (first && !Getattr(first,"sym:nextSibling"))) {
+ Delattr(n,"sym:overloaded");
+ }
+ }
+
+public:
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+ importmode = 0;
+ module = Getattr(n,"module");
+ inclass = 0;
+ normalize = 0;
+ nsname = 0;
+ classhash = Getattr(n,"classes");
+ emit_children(n);
+ normalize_list();
+ SwigType_set_scope(0);
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * moduleDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int moduleDirective(Node *n) {
+ if (!module) {
+ module = n;
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * importDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int importDirective(Node *n) {
+ String *oldmodule = module;
+ int oldimport = importmode;
+ importmode = 1;
+ module = 0;
+ emit_children(n);
+ importmode = oldimport;
+ module = oldmodule;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * includeDirective()
+ * externDirective()
+ * extendDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int includeDirective(Node *n) { return emit_children(n); }
+ virtual int externDeclaration(Node *n) { return emit_children(n); }
+ virtual int extendDirective(Node *n) { return emit_children(n); }
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int classDeclaration(Node *n) {
+ String *name = Getattr(n,"name");
+ String *tdname = Getattr(n,"tdname");
+ String *unnamed = Getattr(n,"unnamed");
+ String *storage = Getattr(n,"storage");
+ String *kind = Getattr(n,"kind");
+ Node *oldinclass = inclass;
+ List *olist = normalize;
+ Symtab *symtab;
+ String *nname = 0;
+ String *fname = 0;
+ String *scopename = 0;
+
+ normalize = NewList();
+
+ if (name) {
+
+ if (SwigType_istemplate(name)) {
+ // We need to fully resolve the name to make templates work correctly */
+ Node *cn;
+ fname = SwigType_typedef_resolve_all(name);
+ if (Strcmp(fname,name) != 0) {
+ cn = Swig_symbol_clookup_local(fname,0);
+ if ((!cn) || (Strcmp(nodeType(cn),"template") == 0)) {
+ Swig_symbol_cadd(fname,n);
+ SwigType_typedef_class(fname);
+ scopename = Copy(fname);
+ } else {
+ Swig_warning(WARN_TYPE_REDEFINED,Getfile(n),Getline(n),"Template '%s' was already wrapped as '%s' at %s:%d.\n",
+ SwigType_namestr(name), SwigType_namestr(Getattr(cn,"name")), Getfile(cn), Getline(cn));
+ scopename = 0;
+ }
+ } else {
+ Swig_symbol_cadd(fname,n);
+ SwigType_typedef_class(fname);
+ scopename = Copy(fname);
+ }
+ } else {
+ if ((CPlusPlus) || (unnamed)) {
+ SwigType_typedef_class(name);
+ } else {
+ SwigType_typedef_class(NewStringf("%s %s", kind, name));
+ }
+ scopename = Copy(name);
+ }
+ } else {
+ scopename = 0;
+ }
+
+ Setattr(n,"typepass:visit","1");
+
+ /* Need to set up a typedef if unnamed */
+ if (unnamed && tdname && (Cmp(storage,"typedef") == 0)) {
+ SwigType_typedef(unnamed,tdname);
+ }
+
+ if (nsname) {
+ nname = NewStringf("%s::%s", nsname, name);
+ }
+ SwigType_new_scope(scopename);
+ SwigType_attach_symtab(Getattr(n,"symtab"));
+
+ /* Inherit type definitions into the class */
+ if (name) {
+ cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name));
+ }
+
+ inclass = n;
+ symtab = Swig_symbol_setscope(Getattr(n,"symtab"));
+ emit_children(n);
+ Swig_symbol_setscope(symtab);
+
+ Hash *ts = SwigType_pop_scope();
+ Setattr(n,"typescope",ts);
+ Setattr(n,"module",module);
+
+ /* Normalize deferred types */
+ {
+ normal_node *nn = new normal_node();
+ nn->normallist = normalize;
+ nn->symtab = Getattr(n,"symtab");
+ nn->next = patch_list;
+ nn->typescope = Getattr(n,"typescope");
+ patch_list = nn;
+ }
+
+ normalize = olist;
+
+ inclass = oldinclass;
+
+ /* If in a namespace, patch the class name */
+ if (nname) {
+ Setattr(n,"name",nname);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * namespaceDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int templateDeclaration(Node *n) {
+ String *name = Getattr(n,"name");
+ String *ttype = Getattr(n,"templatetype");
+ if (Strcmp(ttype,"class") == 0) {
+ String *rname = SwigType_typedef_resolve_all(name);
+ SwigType_typedef_class(rname);
+ Delete(rname);
+ } else if (Strcmp(ttype,"classforward") == 0) {
+ String *rname = SwigType_typedef_resolve_all(name);
+ SwigType_typedef_class(rname);
+ Delete(rname);
+ /* SwigType_typedef_class(name);*/
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classforwardDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int classforwardDeclaration(Node *n) {
+
+ /* Temporary hack. Can't do inside a class because it breaks
+ C nested structure wrapping */
+
+ if ((!inclass) || (CPlusPlus)) {
+ String *name = Getattr(n,"name");
+ String *nname;
+ SwigType_typedef_class(name);
+ if (nsname) {
+ nname = NewStringf("%s::%s", nsname, name);
+ Setattr(n,"name",nname);
+ }
+
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * namespaceDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int namespaceDeclaration(Node *n) {
+ Symtab *symtab;
+ String *name = Getattr(n,"name");
+ String *alias = Getattr(n,"alias");
+ List *olist = normalize;
+ normalize = NewList();
+ if (alias) {
+ Typetab *ts = Getattr(n,"typescope");
+ if (!ts) {
+ Node *ns;
+ /* Create a empty scope for the alias */
+ ns = Getattr(n,"namespace");
+ if (ns) {
+ SwigType_scope_alias(name, Getattr(ns,"typescope"));
+ }
+ ts = Getattr(ns,"typescope");
+ Setattr(n,"typescope",ts);
+ }
+ /* Namespace alias */
+ return SWIG_OK;
+ } else {
+ if (name) {
+ Node *nn = Swig_symbol_clookup(name,n);
+ Hash *ts = Getattr(nn,"typescope");
+ if (!ts) {
+ SwigType_new_scope(name);
+ SwigType_attach_symtab(Getattr(n,"symtab"));
+ } else {
+ SwigType_set_scope(ts);
+ }
+ }
+ String *oldnsname = nsname;
+ nsname = Swig_symbol_qualified(Getattr(n,"symtab"));
+ symtab = Swig_symbol_setscope(Getattr(n,"symtab"));
+ emit_children(n);
+ Swig_symbol_setscope(symtab);
+
+ if (name) {
+ Hash *ts = SwigType_pop_scope();
+ Setattr(n,"typescope",ts);
+ }
+
+ /* Normalize deferred types */
+ {
+ normal_node *nn = new normal_node();
+ nn->normallist = normalize;
+ nn->symtab = Getattr(n,"symtab");
+ nn->next = patch_list;
+ nn->typescope = Getattr(n,"typescope");
+ patch_list = nn;
+ }
+ normalize = olist;
+
+ Delete(nsname);
+ nsname = oldnsname;
+ return SWIG_OK;
+ }
+ }
+
+ /* ------------------------------------------------------------
+ * cDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int cDeclaration(Node *n) {
+
+ if (NoExcept) {
+ Delattr(n,"throws");
+ }
+
+ /* Search for var args */
+ if (Getattr(n,"feature:varargs")) {
+ ParmList *v = Getattr(n,"feature:varargs");
+ Parm *p = Getattr(n,"parms");
+ Parm *pp = 0;
+ while (p) {
+ SwigType *t = Getattr(p,"type");
+ if (Strcmp(t,"v(...)") == 0) {
+ if (pp) {
+ set_nextSibling(pp,Copy(v));
+ } else {
+ Setattr(n,"parms", Copy(v));
+ }
+ break;
+ }
+ pp = p;
+ p = nextSibling(p);
+ }
+ }
+
+ /* Normalize types. */
+ SwigType *ty = Getattr(n,"type");
+ normalize_type(ty);
+ SwigType *decl = Getattr(n,"decl");
+ if (decl) {
+ normalize_type(decl);
+ }
+ normalize_parms(Getattr(n,"parms"));
+ normalize_parms(Getattr(n,"throws"));
+
+ if (checkAttribute(n,"storage","typedef")) {
+ String *name = Getattr(n,"name");
+ ty = Getattr(n,"type");
+ decl = Getattr(n,"decl");
+ SwigType *t = Copy(ty);
+ {
+ /* If the typename is qualified, make sure the scopename is fully qualified when making a typedef */
+ if (Swig_scopename_check(t)) {
+ String *base, *prefix, *qprefix;
+ base = Swig_scopename_last(t);
+ prefix = Swig_scopename_prefix(t);
+ qprefix = SwigType_typedef_qualified(prefix);
+ Delete(t);
+ t = NewStringf("%s::%s", qprefix,base);
+ Delete(base);
+ Delete(prefix);
+ Delete(qprefix);
+ }
+ }
+ SwigType_push(t,decl);
+ if (CPlusPlus) {
+ Replaceall(t,"struct ","");
+ Replaceall(t,"union ","");
+ Replaceall(t,"class ","");
+ }
+ SwigType_typedef(t,name);
+ }
+ /* If namespaces are active. We need to patch the name with a namespace prefix */
+ if (nsname && !inclass) {
+ String *name = Getattr(n,"name");
+ if (name) {
+ String *nname = NewStringf("%s::%s", nsname, name);
+ Setattr(n,"name", nname);
+ Delete(nname);
+ }
+ }
+ clean_overloaded(n);
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * constructorDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int constructorDeclaration(Node *n) {
+ if (NoExcept) {
+ Delattr(n,"throws");
+ }
+
+ /* Search for var args */
+ if (Getattr(n,"feature:varargs")) {
+ ParmList *v = Getattr(n,"feature:varargs");
+ Parm *p = Getattr(n,"parms");
+ Parm *pp = 0;
+ while (p) {
+ SwigType *t = Getattr(p,"type");
+ if (Strcmp(t,"v(...)") == 0) {
+ if (pp) {
+ set_nextSibling(pp,Copy(v));
+ } else {
+ Setattr(n,"parms", Copy(v));
+ }
+ break;
+ }
+ pp = p;
+ p = nextSibling(p);
+ }
+ }
+ normalize_parms(Getattr(n,"parms"));
+ normalize_parms(Getattr(n,"throws"));
+
+ /* If in a namespace, patch the class name */
+ if (nsname) {
+ String *nname = NewStringf("%s::%s", nsname, Getattr(n,"name"));
+ Setattr(n,"name",nname);
+ }
+ clean_overloaded(n);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorDeclaration(Node *n) {
+ /* If in a namespace, patch the class name */
+ if (nsname) {
+ String *nname = NewStringf("%s::%s", nsname, Getattr(n,"name"));
+ Setattr(n,"name",nname);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int constantDirective(Node *n) {
+ SwigType *ty = Getattr(n,"type");
+ if (ty) {
+ Setattr(n,"type",SwigType_typedef_qualified(ty));
+ }
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * enumDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int enumDeclaration(Node *n) {
+ String *name = Getattr(n,"name");
+ if (name) {
+ SwigType *t = NewStringf("enum %s", name);
+ SwigType_typedef(t,name);
+ Delete(t);
+ }
+ emit_children(n);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * enumvalueDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int enumvalueDeclaration(Node *n) {
+ String *name = Getattr(n,"name");
+ String *value = Getattr(n,"value");
+ if (!value) value = name;
+ if (Strcmp(value,name) == 0) {
+ String *new_value;
+ if ((nsname) || (inclass)) {
+ new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
+ } else {
+ new_value = NewString(value);
+ }
+ Setattr(n,"value",new_value);
+ Delete(new_value);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * usingDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int usingDeclaration(Node *n) {
+ if (Getattr(n,"namespace")) {
+ /* using namespace id */
+
+ /* For a namespace import. We set up inheritance in the type system */
+ Node *ns = Getattr(n,"node");
+ if (ns) {
+ Typetab *ts = Getattr(ns,"typescope");
+ if (ts) {
+ SwigType_using_scope(ts);
+ }
+ }
+ return SWIG_OK;
+ } else {
+ Node *ns;
+ /* using id */
+
+ if (Getattr(n,"sym:symtab")) {
+ ns = Swig_symbol_clookup(Getattr(n,"uname"), Getattr(n,"sym:symtab"));
+ } else {
+ ns = 0;
+ }
+ if (!ns) {
+ if (!Getattr(n,"access") || ((Strcmp(Getattr(n,"access"),"public") == 0))) {
+ Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n,"uname")));
+ }
+ } else {
+
+ /* Only a single symbol is being used. There are only a few symbols that
+ we actually care about. These are typedef, class declarations, and enum */
+
+ String *ntype = nodeType(ns);
+ if (Strcmp(ntype,"cdecl") == 0) {
+ if (checkAttribute(ns,"storage","typedef")) {
+ /* A typedef declaration */
+ String *uname = Getattr(n,"uname");
+ SwigType_typedef_using(uname);
+ } else {
+ /* A normal C declaration. */
+ if ((inclass) && (!Getattr(n,"feature:ignore")) && (Getattr(n,"sym:name"))) {
+ Node *c = ns;
+ Node *unodes = 0, *last_unodes = 0;
+ int ccount = 0;
+ String *symname = Getattr(n,"sym:name");
+ while (c) {
+ if (Strcmp(nodeType(c),"cdecl") == 0) {
+ if (!(checkAttribute(c,"storage","static")
+ || checkAttribute(c,"storage","typedef")
+ || checkAttribute(c,"storage","friend")
+ || (Getattr(c,"feature:extend") && !Getattr(c,"code"))
+ || Getattr(c,"feature:ignore"))) {
+
+ String *csymname = Getattr(c,"sym:name");
+ if (!csymname || (Strcmp(csymname,symname) == 0)) {
+ /* Check for existence in overload list already */
+ {
+ String *decl = Getattr(c,"decl");
+ Node *over = Getattr(n,"sym:overloaded");
+ int match = 0;
+ while (over) {
+ String *odecl = Getattr(over,"decl");
+ if (Cmp(decl, odecl) == 0) {
+ match = 1;
+ break;
+ }
+ over = Getattr(over,"sym:nextSibling");
+ }
+ if (match) {
+ c = Getattr(c,"csym:nextSibling");
+ continue;
+ }
+ }
+ Node *nn = copyNode(c);
+ if (!Getattr(nn,"sym:name")) Setattr(nn,"sym:name", symname);
+
+ if (!Getattr(nn,"feature:ignore")) {
+ Setattr(nn,"parms",CopyParmList(Getattr(c,"parms")));
+ ccount++;
+ if (!last_unodes) {
+ last_unodes = nn;
+ unodes = nn;
+ } else {
+ Setattr(nn,"previousSibling",last_unodes);
+ Setattr(last_unodes,"nextSibling", nn);
+ Setattr(nn,"sym:previousSibling", last_unodes);
+ Setattr(last_unodes,"sym:nextSibling", nn);
+ Setattr(nn,"sym:overloaded", unodes);
+ Setattr(unodes,"sym:overloaded", unodes);
+ last_unodes = nn;
+ }
+ } else {
+ Delete(nn);
+ }
+ }
+ }
+ }
+ c = Getattr(c,"csym:nextSibling");
+ }
+ if (unodes) {
+ set_firstChild(n,unodes);
+ if (ccount > 1) {
+ if (!Getattr(n,"sym:overloaded")) {
+ Setattr(n,"sym:overloaded",n);
+ Setattr(n,"sym:overname","_SWIG_0");
+ }
+ }
+ }
+ }
+ }
+ } else if ((Strcmp(ntype,"class") == 0) || ((Strcmp(ntype,"classforward") == 0))) {
+ /* We install the using class name as kind of a typedef back to the original class */
+ String *uname = Getattr(n,"uname");
+ /* Import into current type scope */
+ SwigType_typedef_using(uname);
+ } else if (Strcmp(ntype,"enum") == 0) {
+ SwigType_typedef_using(Getattr(n,"uname"));
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * typemapDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int typemapDirective(Node *n) {
+ if (inclass || nsname) {
+ Node *items = firstChild(n);
+ while (items) {
+ Parm *pattern = Getattr(items,"pattern");
+ Parm *parms = Getattr(items,"parms");
+ normalize_later(pattern);
+ normalize_later(parms);
+ items = nextSibling(items);
+ }
+ }
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * typemapcopyDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int typemapcopyDirective(Node *n) {
+ if (inclass || nsname) {
+ Node *items = firstChild(n);
+ ParmList *pattern = Getattr(n,"pattern");
+ normalize_later(pattern);
+ while (items) {
+ ParmList *npattern = Getattr(items,"pattern");
+ normalize_later(npattern);
+ items = nextSibling(items);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * applyDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int applyDirective(Node *n) {
+ if (inclass || nsname) {
+ ParmList *pattern = Getattr(n,"pattern");
+ normalize_later(pattern);
+ Node *items = firstChild(n);
+ while (items) {
+ Parm *apattern = Getattr(items,"pattern");
+ normalize_later(apattern);
+ items = nextSibling(items);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * clearDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int clearDirective(Node *n) {
+ if (inclass || nsname) {
+ Node *p;
+ for (p = firstChild(n); p; p = nextSibling(p)) {
+ ParmList *pattern = Getattr(p,"pattern");
+ normalize_later(pattern);
+ }
+ }
+ return SWIG_OK;
+ }
+};
+
+void Swig_process_types(Node *n) {
+ if (!n) return;
+ TypePass *t = new TypePass;
+ t->top(n);
+ delete t;
+}
+
+
+
+
+
+
+
diff --git a/Source/Modules/xml.cxx b/Source/Modules/xml.cxx
new file mode 100644
index 000000000..261f3e348
--- /dev/null
+++ b/Source/Modules/xml.cxx
@@ -0,0 +1,318 @@
+/* -----------------------------------------------------------------------------
+ * Xml.cxx
+ *
+ * A web-base parse tree Xml using SWILL. This is an optional
+ * feature that's normally disabled.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 2002. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_xml_cxx[] = "$Header$";
+static const char *usage = "\
+XML Options (available with -xml)\n\
+ -xml output.xml - Use output.xml as output file (extension .xml mandatory)\n\
+ -xmllang lang - Typedef language.\n\n";
+
+#include "swigmod.h"
+
+//static Node *view_top = 0;
+static File *out = 0;
+
+class XML
+: public Language
+{
+
+
+
+public:
+
+ int indent_level;
+ long id;
+ XML()
+ : indent_level( 0 )
+ , id( 0 )
+ {
+ }
+
+ virtual ~XML()
+ {
+ }
+
+ virtual void main(int argc, char *argv[])
+ {
+ SWIG_typemap_lang("xml");
+ for( int iX = 0; iX < argc; iX++ )
+ {
+ if( strcmp( argv[iX], "-xml" ) == 0 )
+ {
+ char * extension = argv[iX+1]+strlen(argv[iX+1])-4;
+ if( strcmp( extension, ".xml" ) )
+ continue;
+ iX++;
+ Swig_mark_arg (iX);
+ String * outfile = NewString( argv[iX] );
+ out = NewFile(outfile,"w");
+ if (!out)
+ {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ continue;
+ }
+ if( strcmp( argv[iX], "-xmllang" ) == 0 )
+ {
+ Swig_mark_arg (iX);
+ iX++;
+ SWIG_typemap_lang(argv[iX]);
+ Swig_mark_arg (iX);
+ continue;
+ }
+ if( strcmp( argv[iX], "-help" ) == 0 )
+ {
+ fputs( usage, stderr );
+ }
+ }
+ }
+
+ /* Top of the parse tree */
+
+ virtual int top(Node *n)
+ {
+ if( out == 0 )
+ {
+ String *outfile = Getattr(n,"outfile");
+ Replaceall(outfile,"_wrap.cxx", ".xml");
+ out = NewFile(outfile,"w");
+ if (!out)
+ {
+ Printf(stderr,"*** Can't open '%s'\n", outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+ Printf( out, " \n" );
+ Xml_print_tree(n);
+ return SWIG_OK;
+ }
+
+
+
+ void print_indent(int l)
+ {
+ int i;
+ for (i = 0; i < indent_level; i++)
+ {
+ Printf(out, " ");
+ }
+ if (l)
+ {
+ Printf(out, " ");
+ }
+ }
+
+ void Xml_print_tree(DOH *obj)
+ {
+ while (obj)
+ {
+ Xml_print_node(obj);
+ obj = nextSibling(obj);
+ }
+ }
+
+ void Xml_print_attributes(Node * obj)
+ {
+ String *k;
+ indent_level += 4;
+ print_indent(0);
+ Printf( out, "\n", ++id, obj );
+ indent_level += 4;
+
+ k = Firstkey(obj);
+ while (k)
+ {
+ if ((Cmp(k,"nodeType") == 0)
+ || (Cmp(k,"firstChild") == 0)
+ || (Cmp(k,"lastChild") == 0)
+ || (Cmp(k,"parentNode") == 0)
+ || (Cmp(k,"nextSibling") == 0)
+ || (Cmp(k,"previousSibling") == 0)
+ || (*(Char(k)) == '$'))
+ {
+ /* Do nothing */
+ }
+ else if (Cmp(k,"module") == 0)
+ {
+ Xml_print_module( Getattr(obj,k) );
+ }
+ else if (Cmp(k,"baselist") == 0)
+ {
+ Xml_print_baselist( Getattr(obj,k) );
+ }
+ else if (Cmp(k,"typescope") == 0)
+ {
+ Xml_print_typescope( Getattr(obj,k) );
+ }
+ else if (Cmp(k,"typetab") == 0)
+ {
+ Xml_print_typetab( Getattr(obj,k) );
+ }
+ else if (Cmp(k,"kwargs") == 0)
+ {
+ Xml_print_kwargs( Getattr(obj,k) );
+ }
+ else if (Cmp(k,"parms") == 0 || Cmp(k, "pattern") == 0 )
+ {
+ Xml_print_parmlist( Getattr(obj,k) );
+ }
+ else
+ {
+ DOH *o;
+ print_indent(0);
+ if (DohIsString(Getattr(obj,k)))
+ {
+ o = Str(Getattr(obj,k));
+ Replaceall( k, ":", "_" );
+ Replaceall( o, "<", "<" );
+ Replaceall( o, "&", "&" );
+ Replaceall( o, "\"", """ );
+ Replaceall( o, "\\", "\\\\" );
+ Printf(out,"\n", k, o, ++id, o );
+ Delete(o);
+ }
+ else
+ {
+ o = Getattr(obj,k);
+ Replaceall( k, ":", "_" );
+ Printf(out,"\n", k, o, ++id, o );
+ }
+ }
+ k = Nextkey(obj);
+ }
+ indent_level -= 4;
+ print_indent(0);
+ Printf( out, "\n" );
+ indent_level -= 4;
+ }
+
+ void Xml_print_node(Node *obj)
+ {
+ Node *cobj;
+
+ print_indent(0);
+ Printf(out,"<%s id=\"%ld\" addr=\"%x\" >\n", nodeType(obj), ++id, obj);
+ Xml_print_attributes( obj );
+ cobj = firstChild(obj);
+ if (cobj)
+ {
+ indent_level += 4;
+ Printf(out,"\n");
+ Xml_print_tree(cobj);
+ indent_level -= 4;
+ }
+ else
+ {
+ print_indent(1);
+ Printf(out,"\n");
+ }
+ print_indent(0);
+ Printf(out,"%s >\n", nodeType(obj));
+ }
+
+
+ void Xml_print_parmlist(ParmList *p)
+ {
+
+ print_indent(0);
+ Printf( out, "\n", ++id, p );
+ indent_level += 4;
+ while(p)
+ {
+ print_indent(0);
+ Printf( out, "\n", ++id );
+ Xml_print_attributes( p );
+ print_indent(0);
+ Printf( out, "\n" );
+ p = nextSibling(p);
+ }
+ indent_level -= 4;
+ print_indent(0);
+ Printf( out, "\n" );
+ }
+
+ void Xml_print_baselist(List *p)
+ {
+
+ print_indent(0);
+ Printf( out, "\n", ++id, p );
+ indent_level += 4;
+ String *s;
+ for (s = Firstitem(p); s; s = Nextitem(p))
+ {
+ print_indent(0);
+ Printf( out, "\n", s, ++id, s );
+ }
+ indent_level -= 4;
+ print_indent(0);
+ Printf( out, "\n" );
+ }
+
+ void Xml_print_module(Node *p)
+ {
+
+ print_indent(0);
+ Printf( out, "\n", Getattr( p, "name"), ++id, p );
+ }
+
+ void Xml_print_kwargs(Hash *p)
+ {
+ Xml_print_hash( p, "kwargs" );
+ }
+
+ void Xml_print_typescope(Hash *p)
+ {
+
+ Xml_print_hash( p, "typescope" );
+ }
+
+ void Xml_print_typetab(Hash *p)
+ {
+
+ Xml_print_hash( p, "typetab" );
+ }
+
+
+ void Xml_print_hash(Hash *p, const char * markup)
+ {
+
+ print_indent(0);
+ Printf( out, "<%s id=\"%ld\" addr=\"%x\" >\n", markup, ++id, p );
+ Xml_print_attributes( p );
+ indent_level += 4;
+ Node * n = Firstitem( p );
+ while(n)
+ {
+ print_indent(0);
+ Printf( out, "<%ssitem id=\"%ld\" addr=\"%x\" >\n", markup, ++id, n );
+ Xml_print_attributes( n );
+ Printf( out, "%ssitem >\n", markup );
+ print_indent(0);
+ Printf( out, " />\n" );
+ n = Nextkey(p);
+ }
+ indent_level -= 4;
+ print_indent(0);
+ Printf( out, "%s >\n", markup );
+ }
+
+};
+
+
+extern "C"
+{
+ Language * swig_xml( void )
+ {
+ return new XML();
+ }
+}