summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorDave Beazley <dave-swig@dabeaz.com>2002-11-30 22:01:28 +0000
committerDave Beazley <dave-swig@dabeaz.com>2002-11-30 22:01:28 +0000
commit12a43edc2df8853e8e0315f742e57be88f0c4269 (patch)
treee3237f5f8c0a67c9bfa9bb5d6d095a739a49e4b2 /Source
parent5fcae5eb66d377e1c3f81da7465c44a62295a72b (diff)
downloadswig-12a43edc2df8853e8e0315f742e57be88f0c4269.tar.gz
The great merge
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@4141 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Diffstat (limited to 'Source')
-rw-r--r--Source/CParse/.cvsignore9
-rw-r--r--Source/CParse/Makefile.in69
-rw-r--r--Source/CParse/cparse.h12
-rw-r--r--Source/CParse/cscanner.c1290
-rw-r--r--Source/CParse/parser.y4568
-rw-r--r--Source/CParse/templ.c495
-rw-r--r--Source/CParse/util.c71
-rw-r--r--Source/DOH/.cvsignore1
-rw-r--r--Source/DOH/Doh/Makefile50
-rw-r--r--Source/DOH/Doh/Makefile.in14
-rw-r--r--Source/DOH/Doh/base.c175
-rw-r--r--Source/DOH/Doh/file.c59
-rw-r--r--Source/DOH/Doh/fio.c17
-rw-r--r--Source/DOH/Doh/hash.c109
-rw-r--r--Source/DOH/Doh/list.c50
-rw-r--r--Source/DOH/Doh/memory.c14
-rw-r--r--Source/DOH/Doh/string.c203
-rw-r--r--Source/DOH/Doh/void.c11
-rw-r--r--Source/DOH/Include/doh.h319
-rw-r--r--Source/DOH/Include/dohobj.h36
-rw-r--r--Source/DOH/Makefile.in4
-rw-r--r--Source/DOH/configure.in4
-rw-r--r--Source/Include/.cvsignore3
-rw-r--r--Source/Include/swigconfig.h.in19
-rw-r--r--Source/Include/swigver.h10
-rw-r--r--Source/Include/swigver.h.in10
-rw-r--r--Source/Include/swigwarn.h186
-rw-r--r--Source/Modules1.1/Makefile.in27
-rw-r--r--Source/Modules1.1/README9
-rw-r--r--Source/Modules1.1/allocate.cxx453
-rw-r--r--Source/Modules1.1/browser.cxx415
-rw-r--r--Source/Modules1.1/contract.cxx118
-rw-r--r--Source/Modules1.1/emit.cxx552
-rw-r--r--Source/Modules1.1/generate.cxx909
-rw-r--r--Source/Modules1.1/guile.cxx1919
-rw-r--r--Source/Modules1.1/guile.h55
-rw-r--r--Source/Modules1.1/java.cxx2807
-rw-r--r--Source/Modules1.1/java.h49
-rw-r--r--Source/Modules1.1/lang.cxx2046
-rw-r--r--Source/Modules1.1/main.cxx723
-rw-r--r--Source/Modules1.1/module.cxx57
-rw-r--r--Source/Modules1.1/mzscheme.cxx1281
-rw-r--r--Source/Modules1.1/mzscheme.h43
-rwxr-xr-xSource/Modules1.1/ocaml.cxx1072
-rw-r--r--Source/Modules1.1/overload.cxx338
-rw-r--r--Source/Modules1.1/perl5.cxx3046
-rw-r--r--Source/Modules1.1/perl5.h53
-rw-r--r--Source/Modules1.1/php4.cxx2113
-rw-r--r--Source/Modules1.1/pike.cxx881
-rw-r--r--Source/Modules1.1/python.cxx2442
-rw-r--r--Source/Modules1.1/python.h62
-rw-r--r--Source/Modules1.1/ruby.cxx2556
-rw-r--r--Source/Modules1.1/ruby.h55
-rw-r--r--Source/Modules1.1/s-exp.cxx401
-rw-r--r--Source/Modules1.1/swig11.h121
-rw-r--r--Source/Modules1.1/swigmod.h255
-rw-r--r--Source/Modules1.1/tcl8.cxx1738
-rw-r--r--Source/Modules1.1/tcl8.h53
-rw-r--r--Source/Modules1.1/typepass.cxx966
-rw-r--r--Source/Modules1.1/xml.cxx594
-rw-r--r--Source/Modules1.1/xml.dtd119
-rw-r--r--Source/Modules1.1/xml.h18
-rw-r--r--Source/Preprocessor/Makefile.in10
-rw-r--r--Source/Preprocessor/cpp.c512
-rw-r--r--Source/Preprocessor/expr.c228
-rw-r--r--Source/Preprocessor/preprocessor.h20
-rw-r--r--Source/README32
-rw-r--r--Source/Swig/Makefile.in16
-rw-r--r--Source/Swig/cwrap.c1034
-rw-r--r--Source/Swig/error.c198
-rw-r--r--Source/Swig/fragment.c64
-rw-r--r--Source/Swig/getopt.c2
-rw-r--r--Source/Swig/include.c89
-rw-r--r--Source/Swig/main.c103
-rw-r--r--Source/Swig/map.c352
-rw-r--r--Source/Swig/misc.c376
-rw-r--r--Source/Swig/module.c210
-rw-r--r--Source/Swig/naming.c495
-rw-r--r--Source/Swig/parms.c84
-rw-r--r--Source/Swig/scanner.c32
-rw-r--r--Source/Swig/stype.c1598
-rw-r--r--Source/Swig/swig.h460
-rw-r--r--Source/Swig/swig.i4
-rw-r--r--Source/Swig/symbol.c1124
-rw-r--r--Source/Swig/tree.c664
-rw-r--r--Source/Swig/typemap.c1246
-rw-r--r--Source/Swig/typesys.c1609
-rw-r--r--Source/Swig/warn.c42
-rw-r--r--Source/Swig/wrapfunc.c312
89 files changed, 32438 insertions, 14632 deletions
diff --git a/Source/CParse/.cvsignore b/Source/CParse/.cvsignore
new file mode 100644
index 000000000..82e5e2e10
--- /dev/null
+++ b/Source/CParse/.cvsignore
@@ -0,0 +1,9 @@
+Makefile
+.deps
+parser.c
+parser.h
+libcparse.a
+cscanner.o
+parser.o
+y.tab.c
+y.tab.h
diff --git a/Source/CParse/Makefile.in b/Source/CParse/Makefile.in
new file mode 100644
index 000000000..648d1b9f9
--- /dev/null
+++ b/Source/CParse/Makefile.in
@@ -0,0 +1,69 @@
+#######################################################################
+# $Header$
+#######################################################################
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SHELL = /bin/sh
+CC = @CC@
+CFLAGS = @CFLAGS@
+YACC = @YACC@
+AR = @AR@
+RANLIB = @RANLIB@
+
+TARGET = libcparse.a
+
+OBJS = parser.@OBJEXT@ cscanner.@OBJEXT@ templ.@OBJEXT@ util.@OBJEXT@
+
+SRCS = cscanner.c templ.c util.c
+
+PARSER = $(srcdir)/parser.y
+INCLUDES = -I$(srcdir)/../Include \
+ -I$(srcdir)/. \
+ -I$(srcdir)/../Swig \
+ -I$(srcdir)/../Preprocessor \
+ -I$(srcdir)/../DOH/Include \
+ -I../Include \
+ -I.
+
+.c.@OBJEXT@:
+ $(CC) $(CFLAGS) $(INCLUDES) -c -o $*.@OBJEXT@ $<
+
+cparse: $(TARGET)
+
+$(TARGET): $(OBJS)
+ $(AR) cr $(TARGET) $(OBJS)
+ $(RANLIB) $(TARGET)
+
+parser.@OBJEXT@: parser.c
+ $(CC) $(INCLUDES) $(CFLAGS) $< -c -o parser.@OBJEXT@
+
+parser.c parser.h: $(PARSER)
+ $(YACC) @YFLAGS@ $(PARSER)
+ @cp y.tab.h parser.h
+ @cp y.tab.c parser.c
+
+scanner.@OBJEXT@: parser.h
+
+parser::
+ @cp y.tab.c.bison parser.c
+ @cp y.tab.h.bison parser.h
+ @cp y.tab.h.bison y.tab.h
+ $(CC) $(CFLAGS) parser.c -c -o parser.@OBJEXT@
+
+clean::
+ rm -f *.@OBJEXT@ $(TARGET) y.tab.c y.tab.h
+
+nuke::
+ rm -f Makefile *~
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h
new file mode 100644
index 000000000..fa323768e
--- /dev/null
+++ b/Source/CParse/cparse.h
@@ -0,0 +1,12 @@
+#include "swig.h"
+#include "swigwarn.h"
+#include "swigver.h"
+
+extern char *cparse_file;
+extern int cparse_line;
+extern int cparse_cplusplus;
+extern int cparse_start_line;
+extern void Swig_cparse_replace_descriptor(String *s);
+extern void Swig_cparse_cplusplus(int);
+extern void Swig_cparse_debug_templates(int);
+
diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c
new file mode 100644
index 000000000..1d185f597
--- /dev/null
+++ b/Source/CParse/cscanner.c
@@ -0,0 +1,1290 @@
+/* -----------------------------------------------------------------------------
+ * scanner.cxx
+ *
+ * SWIG1.1 tokenizer.
+ *
+ * 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_cscanner_c[] = "$Header$";
+
+#include "cparse.h"
+#include "parser.h"
+#include <string.h>
+#include <ctype.h>
+
+#define YYBSIZE 8192
+
+typedef struct InFile {
+ DOHFile *f;
+ int line_number;
+ char *in_file;
+ struct InFile *prev;
+} InFile;
+
+InFile *in_head;
+
+DOHFile *LEX_in = 0;
+static DOHString *header = 0;
+static DOHString *comment = 0;
+DOHString *scanner_ccode = 0; /* String containing C code */
+static char *yybuffer = 0;
+
+static char yytext[YYBSIZE];
+static int yylen = 0;
+int cparse_line = 1;
+char *cparse_file;
+int cparse_start_line = 0;
+static int comment_start;
+static int scan_init = 0;
+static int num_brace = 0;
+static int last_brace = 0;
+static int last_id = 0;
+static int rename_active = 0;
+ int cparse_cplusplus;
+
+/* -----------------------------------------------------------------------------
+ * Swig_cparse_cplusplus()
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_cparse_cplusplus(int v) {
+ cparse_cplusplus = v;
+}
+
+/* ----------------------------------------------------------------------
+ * locator()
+ *
+ * Support for locator strings. These are strings of the form
+ * @filename,line,id@ emitted by the SWIG preprocessor. They
+ * are primarily used for macro line number reporting
+ * ---------------------------------------------------------------------- */
+
+typedef struct Locator {
+ char *filename;
+ int line_number;
+ struct Locator *next;
+} Locator;
+
+static Locator *locs = 0;
+
+static void
+scanner_locator(String *loc) {
+ int c;
+ Locator *l;
+ Seek(loc,1,SEEK_SET);
+ c = Getc(loc);
+ if (c == '@') {
+ /* Empty locator. We pop the last location off */
+ if (locs) {
+ cparse_file = locs->filename;
+ cparse_line = locs->line_number;
+ l = locs->next;
+ free(locs);
+ locs = l;
+ }
+ /* Printf(stderr,"location: %s:%d\n",cparse_file,cparse_line);*/
+ return;
+ }
+
+ /* We're going to push a new location */
+ l = (Locator *) malloc(sizeof(Locator));
+ l->filename = cparse_file;
+ l->line_number = cparse_line;
+ l->next = locs;
+ locs = l;
+
+ /* Now, parse the new location out of the locator string */
+ {
+ String *fn = NewString("");
+ Putc(c,fn);
+
+ while ((c = Getc(loc)) != EOF) {
+ if ((c == '@') || (c == ',')) break;
+ Putc(c,fn);
+ }
+
+ cparse_file = Swig_copy_string(Char(fn));
+ Clear(fn);
+
+ cparse_line = 1;
+ /* Get the line number */
+ while ((c = Getc(loc)) != EOF) {
+ if ((c == '@') || (c == ',')) break;
+ Putc(c,fn);
+ }
+
+ cparse_line = atoi(Char(fn));
+ Clear(fn);
+
+ /* Get the rest of it */
+ while (( c= Getc(loc)) != EOF) {
+ if (c == '@') break;
+ Putc(c,fn);
+ }
+ /* Printf(stderr,"location: %s:%d\n",cparse_file,cparse_line); */
+ Delete(fn);
+ }
+}
+
+/**************************************************************
+ * scanner_init()
+ *
+ * Initialize buffers
+ **************************************************************/
+
+void scanner_init() {
+ yybuffer = (char *) malloc(YYBSIZE);
+ scan_init = 1;
+ header = NewString("");
+ comment = NewString("");
+ scanner_ccode = NewString("");
+}
+
+/**************************************************************
+ * scanner_file(FILE *f)
+ *
+ * Start reading from new file
+ **************************************************************/
+void scanner_file(DOHFile *f) {
+ InFile *in;
+
+ in = (InFile *) malloc(sizeof(InFile));
+ in->f = f;
+ in->in_file = cparse_file;
+ in->line_number = 1;
+ if (!in_head) in->prev = 0;
+ else in->prev = in_head;
+ in_head = in;
+ LEX_in = f;
+ cparse_line = 1;
+}
+
+/**************************************************************
+ * scanner_close()
+ *
+ * Close current input file and go to next
+ **************************************************************/
+
+void scanner_close() {
+ InFile *p;
+ if (!in_head) return;
+ Delete(LEX_in);
+ p = in_head->prev;
+ if (p != 0) {
+ LEX_in = p->f;
+ cparse_line = p->line_number;
+ cparse_file = p->in_file;
+ } else {
+ LEX_in = 0;
+ }
+ free(in_head);
+ in_head = p;
+}
+
+/**************************************************************
+ * char nextchar()
+ *
+ * gets next character from input.
+ * If we're in inlining mode, we actually retrieve a character
+ * from inline_yybuffer instead.
+ **************************************************************/
+
+char nextchar() {
+ int c = 0;
+
+ while (LEX_in) {
+ c = Getc(LEX_in);
+ if (c == EOF) {
+ scanner_close();
+ } else {
+ break;
+ }
+ }
+ if (!LEX_in) return 0;
+ if (yylen >= YYBSIZE) {
+ Printf(stderr,"** FATAL ERROR. Buffer overflow in scanner.cxx.\nReport this to swig-dev@cs.uchicago.edu.\n");
+ exit (EXIT_FAILURE);
+ }
+ yytext[yylen] = c;
+ yylen++;
+ if (c == '\n') {
+ cparse_line++;
+ }
+ return(c);
+}
+
+void retract(int n) {
+ int i;
+ for (i = 0; i < n; i++) {
+ yylen--;
+ if (yylen >= 0) {
+ Ungetc(yytext[yylen],LEX_in);
+ if (yytext[yylen] == '\n') {
+ cparse_line--;
+ }
+ }
+ }
+ if (yylen < 0) yylen = 0;
+}
+
+/**************************************************************
+ * start_inline(char *text, int line)
+ *
+ * This grabs a chunk of text and tries to inline it into
+ * the current file. (This is kind of wild, but cool when
+ * it works).
+ *
+ * If we're already in inlining mode, we will save the code
+ * as a new fragment.
+ **************************************************************/
+
+void start_inline(char *text, int line) {
+ InFile *in;
+
+ /* Save current state */
+ in_head->line_number = cparse_line;
+ in_head->in_file = cparse_file;
+
+ in = (InFile *) malloc(sizeof(InFile));
+ in->f = NewString(text);
+ Seek(in->f,0,SEEK_SET);
+ in->in_file = Swig_copy_string(cparse_file);
+ in->line_number = line;
+ in->prev = in_head;
+ in_head = in;
+ LEX_in = in->f;
+ cparse_line = line;
+}
+
+/**************************************************************
+ * yycomment(char *, int line)
+ *
+ * Inserts a comment into a documentation entry.
+ **************************************************************/
+
+void yycomment(char *a, int b, int c) {
+}
+
+
+/* -----------------------------------------------------------------------------
+ * skip_balanced()
+ *
+ * Skips a piece of code enclosed in begin/end symbols such as '{...}' or
+ * (...). Ignores symbols inside comments or strings.
+ * ----------------------------------------------------------------------------- */
+
+void
+skip_balanced(int startchar, int endchar) {
+ char c;
+ int num_levels = 1;
+ int state = 0;
+ char temp[2] = {0,0};
+ int start_line = cparse_line;
+
+ Clear(scanner_ccode);
+ Putc(startchar,scanner_ccode);
+ temp[0] = (char) startchar;
+ while (num_levels > 0) {
+ c = nextchar();
+ if (c == 0) {
+ Swig_error(cparse_file, start_line, "Missing '%c'. Reached end of input.\n", endchar);
+ return;
+ }
+ Putc(c,scanner_ccode);
+ switch(state) {
+ case 0:
+ if (c == startchar) num_levels++;
+ else if (c == endchar) num_levels--;
+ else if (c == '/') state = 10;
+ else if (c == '\"') state = 20;
+ else if (c == '\'') state = 30;
+ break;
+ case 10:
+ if (c == '/') state = 11;
+ else if (c == '*') state = 12;
+ else state = 0;
+ break;
+ case 11:
+ if (c == '\n') state = 0;
+ else state = 11;
+ break;
+ case 12:
+ if (c == '*') state = 13;
+ break;
+ case 13:
+ if (c == '*') state = 13;
+ else if (c == '/') state = 0;
+ else state = 12;
+ break;
+ case 20:
+ if (c == '\"') state = 0;
+ else if (c == '\\') state = 21;
+ break;
+ case 21:
+ state = 20;
+ break;
+ case 30:
+ if (c == '\'') state = 0;
+ else if (c == '\\') state = 31;
+ break;
+ case 31:
+ state = 30;
+ break;
+ default:
+ break;
+ }
+ yylen = 0;
+ }
+ if (endchar == '}') num_brace--;
+ return;
+}
+
+/**************************************************************
+ * void skip_decl(void)
+ *
+ * This tries to skip over an entire declaration. For example
+ *
+ * friend ostream& operator<<(ostream&, const char *s);
+ *
+ * or
+ * friend ostream& operator<<(ostream&, const char *s) { };
+ *
+ **************************************************************/
+
+void skip_decl(void) {
+ char c;
+ int done = 0;
+ while (!done) {
+ if ((c = nextchar()) == 0) {
+ Swig_error(cparse_file,cparse_line,"Missing semicolon. Reached end of input.\n");
+ return;
+ }
+ if (c == '{') {
+ last_brace = num_brace;
+ num_brace++;
+ break;
+ }
+ yylen = 0;
+ if (c == ';') done = 1;
+ }
+ if (!done) {
+ while (num_brace > last_brace) {
+ if ((c = nextchar()) == 0) {
+ Swig_error(cparse_file,cparse_line,"Missing '}'. Reached end of input.\n");
+ return;
+ }
+ if (c == '{') num_brace++;
+ if (c == '}') num_brace--;
+ yylen = 0;
+ }
+ }
+}
+
+/* This function is called when a backslash is found in a string */
+static void get_escape() {
+ int result = 0;
+ int state = 0;
+ char c;
+
+ while(1) {
+ c = nextchar();
+ if (c == 0) break;
+ switch(state) {
+ case 0:
+ if (c == 'n') {
+ yytext[yylen-1] = '\n';
+ return;
+ }
+ if (c == 'r') {
+ yytext[yylen-1] = '\r';
+ return;
+ }
+ if (c == 't') {
+ yytext[yylen-1] = '\t';
+ return;
+ }
+ if (c == 'a') {
+ yytext[yylen-1] = '\a';
+ return;
+ }
+ if (c == 'b') {
+ yytext[yylen-1] = '\b';
+ return;
+ }
+ if (c == 'f') {
+ yytext[yylen-1] = '\f';
+ return;
+ }
+ if (c == '\\') {
+ yytext[yylen-1] = '\\';
+ return;
+ }
+ if (c == 'v') {
+ yytext[yylen-1] = '\v';
+ return;
+ }
+ if (c == 'e') {
+ yytext[yylen-1] = '\033';
+ return;
+ }
+ if (c == '\'') {
+ yytext[yylen-1] = '\'';
+ return;
+ }
+ if (c == '\"') {
+ yytext[yylen-1] = '\"';
+ return;
+ }
+ if (c == '\n') {
+ yylen--;
+ return;
+ }
+ if (c == '0') {
+ state = 10;
+ }
+ else if (c == 'x') {
+ state = 20;
+ } else {
+ yytext[yylen-1] = '\\';
+ yytext[yylen] = c;
+ yylen++;
+ return;
+ }
+ break;
+ case 10:
+ if (!isdigit(c)) {
+ retract(1);
+ yytext[yylen-1] = (char) result;
+ return;
+ }
+ result = (result << 3) + (c - '0');
+ yylen--;
+ break;
+ case 20:
+ if (!isxdigit(c)) {
+ retract(1);
+ yytext[yylen-1] = (char) result;
+ return;
+ }
+ if (isdigit(c))
+ result = (result << 4) + (c - '0');
+ else
+ result = (result << 4) + (10 + tolower(c) - 'a');
+ yylen--;
+ break;
+ }
+ }
+ return;
+}
+
+/**************************************************************
+ * int yylook()
+ *
+ * Lexical scanner.
+ * See Aho,Sethi, and Ullman, pg. 106
+ **************************************************************/
+
+int yylook(void) {
+
+ int state;
+ char c = 0;
+
+ state = 0;
+ yylen = 0;
+ while(1) {
+
+/* printf("State = %d\n", state); */
+ switch(state) {
+
+ case 0 :
+ if((c = nextchar()) == 0) return (0);
+
+ /* Process delimeters */
+
+ if (c == '\n') {
+ state = 0;
+ yylen = 0;
+ last_id = 0;
+ } else if (isspace(c) || (c=='\\')) {
+ state = 0;
+ yylen = 0;
+ last_id = 0;
+ }
+
+ else if ((isalpha(c)) || (c == '_')) state = 7;
+ else if (c == '$') state = 75;
+
+ /* Look for single character symbols */
+
+ else if (c == '(') return (LPAREN);
+ else if (c == ')') return (RPAREN);
+ else if (c == ';') return (SEMI);
+ else if (c == ',') return (COMMA);
+ else if (c == '*') return (STAR);
+ else if (c == '}') {
+ num_brace--;
+ if (num_brace < 0) {
+ Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '}'\n");
+ state = 0;
+ num_brace = 0;
+ } else {
+ return (RBRACE);
+ }
+ }
+ else if (c == '{') {
+ last_brace = num_brace;
+ num_brace++;
+ return (LBRACE);
+ }
+ else if (c == '=') return (EQUAL);
+ else if (c == '+') return (PLUS);
+ else if (c == '-') return (MINUS);
+ else if (c == '&') {
+ state = 300;
+ }
+ else if (c == '|') {
+ state = 301;
+ }
+ else if (c == '^') return (XOR);
+ else if (c == '<') state = 60;
+ else if (c == '>') state = 61;
+ else if (c == '~') {
+ return (NOT);
+ }
+ else if (c == '!') return (LNOT);
+ else if (c == '\\') {
+ state = 99;
+ }
+ else if (c == '[') return (LBRACKET);
+ else if (c == ']') return (RBRACKET);
+
+ /* Look for multi-character sequences */
+
+ else if (c == '/') state = 1; /* Comment (maybe) */
+ else if (c == '\"') state = 2; /* Possibly a string */
+ else if (c == '#') state = 3; /* CPP */
+ else if (c == '%') state = 4; /* Directive */
+ else if (c == '@') state = 4; /* Objective C keyword */
+ else if (c == ':') state = 5; /* maybe double colon */
+ else if (c == '0') state = 83; /* An octal or hex value */
+ else if (c == '\'') state = 9; /* A character constant */
+ else if (c == '.') state = 100; /* Maybe a number, maybe just a period */
+ else if (c == '`') {
+ state = 200; /* Back-tick type */
+ yylen = 0;
+ }
+ else if (isdigit(c)) state = 8; /* A numerical value */
+
+ else state = 99;
+ break;
+ case 1: /* Comment block */
+ if ((c = nextchar()) == 0) return(0);
+ if (c == '/') {
+ comment_start = cparse_line;
+ Clear(comment);
+ state = 10; /* C++ style comment */
+ } else if (c == '*') {
+ comment_start = cparse_line;
+ Clear(comment);
+ state = 12; /* C style comment */
+ } else {
+ retract(1);
+ return(SLASH);
+ }
+ break;
+ case 300: /* & or && */
+ if ((c = nextchar()) == 0) return(AND);
+ if (c == '&') return(LAND);
+ else {
+ retract(1);
+ return(AND);
+ }
+
+ case 301: /* | or || */
+ if ((c = nextchar()) == 0) return(OR);
+ if (c == '|') return(LOR);
+ else {
+ retract(1);
+ return(OR);
+ }
+ case 10: /* C++ style comment */
+ if ((c = nextchar()) == 0) {
+ Swig_error(cparse_file,-1, "Unterminated comment detected.\n");
+ return 0;
+ }
+ if (c == '\n') {
+ Putc(c,comment);
+ /* Add the comment to documentation */
+ /* yycomment(Char(comment),comment_start, column_start);*/
+ yylen = 0;
+ state = 0;
+ } else {
+ state = 10;
+ Putc(c,comment);
+ yylen = 0;
+ }
+ break;
+
+ case 12: /* C style comment block */
+ if ((c = nextchar()) == 0) {
+ Swig_error(cparse_file,-1,"Unterminated comment detected.\n");
+ return 0;
+ }
+ if (c == '*') {
+ state = 13;
+ } else {
+ Putc(c,comment);
+ yylen = 0;
+ state = 12;
+ }
+ break;
+ case 13: /* Still in C style comment */
+ if ((c = nextchar()) == 0) {
+ Swig_error(cparse_file,-1,"Unterminated comment detected.\n");
+ return 0;
+ }
+ if (c == '*') {
+ Putc(c,comment);
+ state = 13;
+ } else if (c == '/') {
+
+ /* Look for locator markers */
+ {
+ char *loc = Char(comment);
+ if (Len(comment)) {
+ if ((*loc == '@') && (*(loc+Len(comment)-1) == '@')) {
+ /* Locator */
+ scanner_locator(comment);
+ }
+ }
+ }
+ /* yycomment(Char(comment),comment_start,column_start); */
+ yylen = 0;
+ state = 0;
+ } else {
+ Putc('*',comment);
+ Putc(c,comment);
+ yylen = 0;
+ state = 12;
+ }
+ break;
+
+ case 2: /* Processing a string */
+ if ((c = nextchar()) == 0) {
+ Swig_error(cparse_file,-1, "Unterminated string detected.\n");
+ return 0;
+ }
+ if (c == '\"') {
+ yytext[yylen-1] = 0;
+ yylval.id = Swig_copy_string(yytext+1);
+ return(STRING);
+ } else if (c == '\\') {
+ yylen--;
+ get_escape();
+ break;
+ } else state = 2;
+ break;
+
+ case 3: /* a CPP directive */
+ if (( c= nextchar()) == 0) return 0;
+ if (c == '\n') {
+ retract(1);
+ yytext[yylen] = 0;
+ yylval.id = yytext;
+ return(POUND);
+ }
+ break;
+
+ case 4: /* A wrapper generator directive (maybe) */
+ if (( c= nextchar()) == 0) return 0;
+ if (c == '{') {
+ state = 40; /* Include block */
+ Clear(header);
+ cparse_start_line = cparse_line;
+ } else if ((isalpha(c)) || (c == '_')) state = 7;
+ else if (c == '}') {
+ Swig_error(cparse_file,cparse_line, "Misplaced %%}.\n");
+ return 0;
+ } else {
+ retract(1);
+ return(MODULO);
+ }
+ break;
+
+ case 40: /* Process an include block */
+ if ((c = nextchar()) == 0) {
+ Swig_error(cparse_file,-1, "Unterminated include block detected.\n");
+ return 0;
+ }
+ yylen = 0;
+ if (c == '%') state = 41;
+ else {
+ Putc(c,header);
+ yylen = 0;
+ state = 40;
+ }
+ break;
+ case 41: /* Still processing include block */
+ if ((c = nextchar()) == 0) {
+ Swig_error(cparse_file,-1, "Unterminated include block detected.\n");
+ return 0;
+ }
+ if (c == '}') {
+ yylval.str = NewString(header);
+ return(HBLOCK);
+ } else {
+ Putc('%',header);
+ Putc(c,header);
+ yylen = 0;
+ state = 40;
+ }
+ break;
+
+ case 5: /* Maybe a double colon */
+
+ if (( c= nextchar()) == 0) return 0;
+ if ( c == ':') {
+ state = 51;
+ } else {
+ retract(1);
+ return COLON;
+ }
+ break;
+ case 51: /* Maybe a ::*, ::~, or :: */
+ if (( c = nextchar()) == 0) return 0;
+ if (c == '*') {
+ return DSTAR;
+ } if (c == '~') {
+ return DCNOT;
+ } else {
+ retract(1);
+ if (!last_id) {
+ retract(2);
+ return NONID;
+ } else {
+ return DCOLON;
+ }
+ }
+
+ case 60: /* shift operators */
+ if ((c = nextchar()) == 0) return (0);
+ if (c == '<') return LSHIFT;
+ else {
+ retract(1);
+ return LESSTHAN;
+ }
+ break;
+ case 61:
+ if ((c = nextchar()) == 0) return (0);
+ if (c == '>') return RSHIFT;
+ else {
+ retract(1);
+ return GREATERTHAN;
+ }
+ break;
+ case 7: /* Identifier */
+ if ((c = nextchar()) == 0) return(0);
+ if (isalnum(c) || (c == '_') || (c == '.') || (c == '$')) {
+ state = 7;
+ } else {
+ retract(1);
+ return(ID);
+ }
+ break;
+ case 75: /* Special identifier $*/
+ if ((c = nextchar()) == 0) return(0);
+ if (isalnum(c) || (c == '_') || (c == '*') || (c == '&')) {
+ state = 7;
+ } else {
+ retract(1);
+ return(ID);
+ }
+ break;
+
+ case 8: /* A numerical digit */
+ if ((c = nextchar()) == 0) return(0);
+ if (c == '.') {state = 81;}
+ else if ((c == 'e') || (c == 'E')) {state = 86;}
+ else if ((c == 'f') || (c == 'F')) {
+ return(NUM_FLOAT);
+ }
+ else if (isdigit(c)) { state = 8;}
+ else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(1);
+ return(NUM_INT);
+ }
+ break;
+ case 81: /* A floating pointer number of some sort */
+ if ((c = nextchar()) == 0) return(0);
+ if (isdigit(c)) state = 81;
+ else if ((c == 'e') || (c == 'E')) state = 82;
+ else if ((c == 'f') || (c == 'F') || (c == 'l') || (c == 'L')) {
+ return(NUM_FLOAT);
+ } else {
+ retract(1);
+ return(NUM_FLOAT);
+ }
+ break;
+ case 82:
+ if ((c = nextchar()) == 0) return(0);
+ if ((isdigit(c)) || (c == '-') || (c == '+')) state = 86;
+ else {
+ retract(2);
+ yytext[yylen-1] = 0;
+ return(NUM_INT);
+ }
+ break;
+ case 83:
+ /* Might be a hexidecimal or octal number */
+ if ((c = nextchar()) == 0) return(0);
+ if (isdigit(c)) state = 84;
+ else if ((c == 'x') || (c == 'X')) state = 85;
+ else if (c == '.') state = 81;
+ else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(1);
+ return(NUM_INT);
+ }
+ break;
+ case 84:
+ /* This is an octal number */
+ if ((c = nextchar()) == 0) return (0);
+ if (isdigit(c)) state = 84;
+ else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(1);
+ return(NUM_INT);
+ }
+ break;
+ case 85:
+ /* This is an hex number */
+ if ((c = nextchar()) == 0) return (0);
+ if ((isdigit(c)) || (c=='a') || (c=='b') || (c=='c') ||
+ (c=='d') || (c=='e') || (c=='f') || (c=='A') ||
+ (c=='B') || (c=='C') || (c=='D') || (c=='E') ||
+ (c=='F'))
+ state = 85;
+ else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(1);
+ return(NUM_INT);
+ }
+ break;
+
+ case 86:
+ /* Rest of floating point number */
+
+ if ((c = nextchar()) == 0) return (0);
+ if (isdigit(c)) state = 86;
+ else if ((c == 'f') || (c == 'F') || (c == 'l') || (c == 'L')) {
+ return(NUM_FLOAT);
+ } else {
+ retract(1);
+ return(NUM_FLOAT);
+ }
+ /* Parse a character constant. ie. 'a' */
+ break;
+
+ case 87 :
+ /* A long integer of some sort */
+ if ((c = nextchar()) == 0) return (NUM_LONG);
+ if ((c == 'u') || (c == 'U')) {
+ return(NUM_ULONG);
+ } else if ((c == 'l') || (c == 'L')) {
+ state = 870;
+ } else {
+ retract(1);
+ return(NUM_LONG);
+ }
+ break;
+
+ case 870:
+ if ((c = nextchar()) == 0) return (NUM_LONGLONG);
+ if ((c == 'u') || (c == 'U')) {
+ return (NUM_ULONGLONG);
+ } else {
+ retract(1);
+ return(NUM_LONGLONG);
+ }
+
+ case 88:
+ /* An unsigned integer of some sort */
+ if ((c = nextchar()) == 0) return (NUM_UNSIGNED);
+ if ((c == 'l') || (c == 'L')) {
+ state = 880;
+ } else {
+ retract(1);
+ return(NUM_UNSIGNED);
+ }
+ break;
+
+ case 880:
+ if ((c = nextchar()) == 0) return (NUM_ULONG);
+ if ((c == 'l') || (c == 'L')) return (NUM_ULONGLONG);
+ else {
+ retract(1);
+ return(NUM_ULONG);
+ }
+
+ case 9:
+ if ((c = nextchar()) == 0) return (0);
+ if (c == '\\') {
+ yylen--;
+ get_escape();
+ } else if (c == '\'') {
+ yytext[yylen-1] = 0;
+ yylval.str = NewString(yytext+1);
+ if (yylen == 2) {
+ Swig_error(cparse_file, cparse_line, "Empty character constant\n");
+ }
+ return(CHARCONST);
+ }
+ break;
+
+ case 100:
+ if ((c = nextchar()) == 0) return (0);
+ if (isdigit(c)) state = 81;
+ else {
+ retract(1);
+ return(PERIOD);
+ }
+ break;
+ case 200:
+ if ((c = nextchar()) == 0) return (0);
+ if (c == '`') {
+ yytext[yylen-1] = 0;
+ yylval.type = NewString(yytext);
+ return(TYPE_RAW);
+ }
+ break;
+
+ default:
+ Swig_error(cparse_file, cparse_line, "Illegal character '%c'=%d.\n",c,c);
+ state = 0;
+ return(ILLEGAL);
+ }
+ }
+}
+
+static int check_typedef = 0;
+
+void scanner_check_typedef() {
+ check_typedef = 1;
+}
+
+void scanner_ignore_typedef() {
+ check_typedef = 0;
+}
+
+void scanner_last_id(int x) {
+ last_id = x;
+}
+
+void scanner_clear_rename() {
+ rename_active = 0;
+}
+
+static int next_token = 0;
+void scanner_next_token(int tok) {
+ next_token = tok;
+}
+
+/**************************************************************
+ * int yylex()
+ *
+ * Gets the lexene and returns tokens.
+ *************************************************************/
+
+int yylex(void) {
+
+ int l;
+
+ if (!scan_init) {
+ scanner_init();
+ }
+
+ if (next_token) {
+ l = next_token;
+ next_token = 0;
+ return l;
+ }
+ l = yylook();
+
+
+ if (l == NONID) {
+ last_id = 1;
+ } else {
+ last_id = 0;
+ }
+
+ /* We got some sort of non-white space object. We set the start_line
+ variable unless it has already been set */
+
+ if (!cparse_start_line) {
+ cparse_start_line = cparse_line;
+ }
+
+ /* Copy the lexene */
+
+ yytext[yylen] = 0;
+ switch(l) {
+
+ case NUM_INT:
+ case NUM_FLOAT:
+ case NUM_ULONG:
+ case NUM_LONG:
+ case NUM_UNSIGNED:
+ case NUM_LONGLONG:
+ case NUM_ULONGLONG:
+ if (l == NUM_INT) yylval.dtype.type = T_INT;
+ if (l == NUM_FLOAT) yylval.dtype.type = T_DOUBLE;
+ if (l == NUM_ULONG) yylval.dtype.type = T_ULONG;
+ if (l == NUM_LONG) yylval.dtype.type = T_LONG;
+ if (l == NUM_UNSIGNED) yylval.dtype.type = T_UINT;
+ if (l == NUM_LONGLONG) yylval.dtype.type = T_LONGLONG;
+ if (l == NUM_ULONGLONG) yylval.dtype.type = T_ULONGLONG;
+ yylval.dtype.val = NewString(yytext);
+ yylval.dtype.bitfield = 0;
+ yylval.dtype.throws = 0;
+ return(l);
+ break;
+
+ case ID:
+
+ if (yytext[0] != '%') {
+ /* Look for keywords now */
+
+ if (strcmp(yytext,"int") == 0) {
+ yylval.type = NewSwigType(T_INT);
+ return(TYPE_INT);
+ }
+ if (strcmp(yytext,"double") == 0) {
+ yylval.type = NewSwigType(T_DOUBLE);
+ return(TYPE_DOUBLE);
+ }
+ if (strcmp(yytext,"void") == 0) {
+ yylval.type = NewSwigType(T_VOID);
+ return(TYPE_VOID);
+ }
+ if (strcmp(yytext,"char") == 0) {
+ yylval.type = NewSwigType(T_CHAR);
+ return(TYPE_CHAR);
+ }
+ if (strcmp(yytext,"short") == 0) {
+ yylval.type = NewSwigType(T_SHORT);
+ return(TYPE_SHORT);
+ }
+ if (strcmp(yytext,"long") == 0) {
+ yylval.type = NewSwigType(T_LONG);
+ return(TYPE_LONG);
+ }
+ if (strcmp(yytext,"float") == 0) {
+ yylval.type = NewSwigType(T_FLOAT);
+ return(TYPE_FLOAT);
+ }
+ if (strcmp(yytext,"signed") == 0) {
+ yylval.type = NewSwigType(T_INT);
+ return(TYPE_SIGNED);
+ }
+ if (strcmp(yytext,"unsigned") == 0) {
+ yylval.type = NewSwigType(T_UINT);
+ return(TYPE_UNSIGNED);
+ }
+ if (strcmp(yytext,"bool") == 0) {
+ yylval.type = NewSwigType(T_BOOL);
+ return(TYPE_BOOL);
+ }
+ /* C++ keywords */
+
+ if (cparse_cplusplus) {
+ if (strcmp(yytext,"class") == 0) return(CLASS);
+ if (strcmp(yytext,"private") == 0) return(PRIVATE);
+ if (strcmp(yytext,"public") == 0) return(PUBLIC);
+ if (strcmp(yytext,"protected") == 0) return(PROTECTED);
+ if (strcmp(yytext,"friend") == 0) return(FRIEND);
+ if (strcmp(yytext,"virtual") == 0) return(VIRTUAL);
+ if (strcmp(yytext,"operator") == 0) {
+ String *s = NewString("operator");
+ int c;
+ int state = 0;
+ int sticky = 0;
+ int isconversion = 0;
+ int count = 0;
+ while ((c = nextchar())) {
+ if (((c == '(') || (c == ';')) && state) {
+ retract(1);
+ break;
+ }
+ count++;
+ if (!isspace(c)) {
+ if ((!state) && (isalpha(c))) isconversion = 1;
+ if (!state && !sticky) Putc(' ',s);
+ Putc(c,s);
+ sticky = 0;
+ state = 1;
+ } else {
+ if (!sticky) Putc(' ',s);
+ sticky = 1;
+ }
+ }
+ Chop(s);
+ yylval.str = s;
+ while(Replaceall(s,"[ ", "["));
+ if (isconversion) {
+ String *ns = Swig_symbol_string_qualify(s,0);
+ yylval.str = ns;
+ }
+ if (isconversion && !rename_active) {
+ char *t = Char(s) + 9;
+ if (!((strcmp(t,"new") == 0) || (strcmp(t,"delete") == 0)
+ || (strcmp(t,"new[]") == 0) || (strcmp(t,"delete[]") == 0))) {
+ /* retract(strlen(t));*/
+ retract(count);
+ return COPERATOR;
+ }
+ }
+ return(OPERATOR);
+ }
+ if (strcmp(yytext,"throw") == 0) return(THROW);
+ if (strcmp(yytext,"try") == 0) return (yylex());
+ if (strcmp(yytext,"catch") == 0) return (CATCH);
+ if (strcmp(yytext,"inline") == 0) return(yylex());
+ if (strcmp(yytext,"mutable") == 0) return(yylex());
+ if (strcmp(yytext,"explicit") == 0) return(yylex());
+ if (strcmp(yytext,"export") == 0) return(yylex());
+ if (strcmp(yytext,"typename") == 0) return (TYPENAME);
+ if (strcmp(yytext,"template") == 0) {
+ yylval.ivalue = cparse_line;
+ return(TEMPLATE);
+ }
+ if (strcmp(yytext,"delete") == 0) {
+ return(DELETE);
+ }
+ if (strcmp(yytext,"using") == 0) {
+ return(USING);
+ }
+ if (strcmp(yytext,"namespace") == 0) {
+ return(NAMESPACE);
+ }
+ } else {
+ if (strcmp(yytext,"class") == 0) {
+ Swig_warning(WARN_PARSE_CLASS_KEYWORD,cparse_file,cparse_line, "class keyword used, but not in C++ mode.\n");
+ }
+ }
+
+ /* Objective-C keywords */
+#ifdef OBJECTIVEC
+ if ((ObjC) && (yytext[0] == '@')) {
+ if (strcmp(yytext,"@interface") == 0) return (OC_INTERFACE);
+ if (strcmp(yytext,"@end") == 0) return (OC_END);
+ if (strcmp(yytext,"@public") == 0) return (OC_PUBLIC);
+ if (strcmp(yytext,"@private") == 0) return (OC_PRIVATE);
+ if (strcmp(yytext,"@protected") == 0) return (OC_PROTECTED);
+ if (strcmp(yytext,"@class") == 0) return(OC_CLASS);
+ if (strcmp(yytext,"@implementation") == 0) return(OC_IMPLEMENT);
+ if (strcmp(yytext,"@protocol") == 0) return(OC_PROTOCOL);
+ }
+#endif
+
+ /* Misc keywords */
+
+ if (strcmp(yytext,"extern") == 0) return(EXTERN);
+ if (strcmp(yytext,"const") == 0) return(CONST);
+ if (strcmp(yytext,"static") == 0) return(STATIC);
+ if (strcmp(yytext,"struct") == 0) return(STRUCT);
+ if (strcmp(yytext,"union") == 0) return(UNION);
+ if (strcmp(yytext,"enum") == 0) return(ENUM);
+ if (strcmp(yytext,"sizeof") == 0) return(SIZEOF);
+
+ if (strcmp(yytext,"typedef") == 0) {
+ yylval.ivalue = 0;
+ return(TYPEDEF);
+ }
+
+ /* Ignored keywords */
+
+ if (strcmp(yytext,"volatile") == 0) return(VOLATILE);
+
+ /* SWIG directives */
+ } else {
+ if (strcmp(yytext,"%module") == 0) return(MODULE);
+ if (strcmp(yytext,"%insert") == 0) return(INSERT);
+ if (strcmp(yytext,"%name") == 0) return(NAME);
+ if (strcmp(yytext,"%rename") == 0) {
+ rename_active = 1;
+ return(RENAME);
+ }
+ if (strcmp(yytext,"%namewarn") == 0) {
+ rename_active = 1;
+ return (NAMEWARN);
+ }
+ if (strcmp(yytext,"%includefile") == 0) return(INCLUDE);
+ if (strcmp(yytext,"%val") == 0) {
+ Swig_warning(WARN_DEPRECATED_VAL, cparse_file, cparse_line, "%%val directive deprecated (ignored).\n");
+ return (yylex());
+ }
+ if (strcmp(yytext,"%out") == 0) {
+ Swig_warning(WARN_DEPRECATED_OUT, cparse_file, cparse_line, "%%out directive deprecated (ignored).\n");
+ return(yylex());
+ }
+ if (strcmp(yytext,"%constant") == 0) return(CONSTANT);
+ if (strcmp(yytext,"%typedef") == 0) {
+ yylval.ivalue = 1;
+ return(TYPEDEF);
+ }
+ if (strcmp(yytext,"%native") == 0) return(NATIVE);
+ if (strcmp(yytext,"%pragma") == 0) return(PRAGMA);
+ if (strcmp(yytext,"%extend") == 0) return(EXTEND);
+ if (strcmp(yytext,"%fragment") == 0) return(FRAGMENT);
+ if (strcmp(yytext,"%inline") == 0) return(INLINE);
+ if (strcmp(yytext,"%typemap") == 0) return(TYPEMAP);
+ if (strcmp(yytext,"%feature") == 0) return(FEATURE);
+ if (strcmp(yytext,"%except") == 0) return(EXCEPT);
+ if (strcmp(yytext,"%importfile") == 0) return(IMPORT);
+ if (strcmp(yytext,"%echo") == 0) return(ECHO);
+ if (strcmp(yytext,"%apply") == 0) return(APPLY);
+ if (strcmp(yytext,"%clear") == 0) return(CLEAR);
+ if (strcmp(yytext,"%types") == 0) return(TYPES);
+ if (strcmp(yytext,"%parms") == 0) return(PARMS);
+ if (strcmp(yytext,"%varargs") == 0) return(VARARGS);
+ if (strcmp(yytext,"%template") == 0) return (SWIGTEMPLATE);
+ if (strcmp(yytext,"%warn") == 0) return(WARN);
+ }
+ /* Have an unknown identifier, as a last step, we'll do a typedef lookup on it. */
+
+ /* Need to fix this */
+ if (check_typedef) {
+ if (SwigType_istypedef(yytext)) {
+ yylval.type = NewString(yytext);
+ return(TYPE_TYPEDEF);
+ }
+ }
+ yylval.id = Swig_copy_string(yytext);
+ last_id = 1;
+ return(ID);
+ case POUND:
+ return yylex();
+ default:
+ return(l);
+ }
+}
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
new file mode 100644
index 000000000..350e4cdc4
--- /dev/null
+++ b/Source/CParse/parser.y
@@ -0,0 +1,4568 @@
+%{
+/* -----------------------------------------------------------------------------
+ * parser.y
+ *
+ * YACC parser for SWIG. The grammar is a somewhat broken subset of C/C++.
+ * This file is a bit of a mess and probably needs to be rewritten at
+ * some point. Beware.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1998-2001. 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.
+ * ----------------------------------------------------------------------------- */
+
+#define yylex yylex
+
+char cvsroot_parser_y[] = "$Header$";
+
+#include "cparse.h"
+#include "preprocessor.h"
+#include <ctype.h>
+
+/* We do this for portability */
+#undef alloca
+#define alloca malloc
+
+/* -----------------------------------------------------------------------------
+ * Externals
+ * ----------------------------------------------------------------------------- */
+
+extern int yylex();
+extern void yyerror (const char *s);
+
+/* scanner.cxx */
+
+extern int cparse_line;
+extern int cparse_start_line;
+extern void skip_balanced(int startchar, int endchar);
+extern void skip_decl(void);
+extern void scanner_check_typedef(void);
+extern void scanner_ignore_typedef(void);
+extern void scanner_last_id(int);
+extern void scanner_clear_rename(void);
+extern void start_inline(char *, int);
+extern String *scanner_ccode;
+extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms);
+extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms);
+
+/* NEW Variables */
+
+extern void generate_all(Node *);
+
+static Node *top = 0; /* Top of the generated parse tree */
+static int unnamed = 0; /* Unnamed datatype counter */
+static Hash *extendhash = 0; /* Hash table of added methods */
+static Hash *classes = 0; /* Hash table of classes */
+static Symtab *prev_symtab = 0;
+static Node *current_class = 0;
+ String *ModuleName = 0;
+static Node *module_node = 0;
+static String *Classprefix = 0;
+static String *Namespaceprefix = 0;
+static int inclass = 0;
+static char *last_cpptype = 0;
+static int inherit_list = 0;
+static Parm *template_parameters = 0;
+
+/* -----------------------------------------------------------------------------
+ * Assist Functions
+ * ----------------------------------------------------------------------------- */
+
+static Node *new_node(const String_or_char *tag) {
+ Node *n = NewHash();
+ set_nodeType(n,tag);
+ Setfile(n,cparse_file);
+ Setline(n,cparse_line);
+ return n;
+}
+
+/* Copies a node. Does not copy tree links or symbol table data (except for
+ sym:name) */
+
+static Node *copy_node(Node *n) {
+ Node *nn;
+ String *key;
+ nn = NewHash();
+ Setfile(nn,Getfile(n));
+ Setline(nn,Getline(n));
+ for (key = Firstkey(n); key; key = Nextkey(n)) {
+ if ((Strcmp(key,"nextSibling") == 0) ||
+ (Strcmp(key,"previousSibling") == 0) ||
+ (Strcmp(key,"parentNode") == 0) ||
+ (Strcmp(key,"lastChild") == 0)) {
+ continue;
+ }
+ if (Strncmp(key,"csym:",5) == 0) continue;
+ /* We do copy sym:name. For templates */
+ if ((Strcmp(key,"sym:name") == 0) ||
+ (Strcmp(key,"sym:weak") == 0) ||
+ (Strcmp(key,"sym:typename") == 0)) {
+ Setattr(nn,key, Copy(Getattr(n,key)));
+ continue;
+ }
+ if (Strcmp(key,"sym:symtab") == 0) {
+ Setattr(nn,"sym:needs_symtab", "1");
+ }
+ /* We don't copy any other symbol table attributes */
+ if (Strncmp(key,"sym:",4) == 0) {
+ continue;
+ }
+ /* If children. We copy them recursively using this function */
+ if (Strcmp(key,"firstChild") == 0) {
+ /* Copy children */
+ Node *cn = Getattr(n,key);
+ while (cn) {
+ appendChild(nn,copy_node(cn));
+ cn = nextSibling(cn);
+ }
+ continue;
+ }
+ /* We don't copy the symbol table. But we drop an attribute
+ requires_symtab so that functions know it needs to be built */
+
+ if (Strcmp(key,"symtab") == 0) {
+ /* Node defined a symbol table. */
+ Setattr(nn,"requires_symtab","1");
+ continue;
+ }
+ /* Can't copy nodes */
+ if (Strcmp(key,"node") == 0) {
+ continue;
+ }
+ if ((Strcmp(key,"parms") == 0) || (Strcmp(key,"pattern") == 0) || (Strcmp(key,"throws") == 0)) {
+ Setattr(nn,key,CopyParmList(Getattr(n,key)));
+ continue;
+ }
+ /* Looks okay. Just copy the data using Copy */
+ Setattr(nn, key, Copy(Getattr(n,key)));
+ }
+ return nn;
+}
+
+/* -----------------------------------------------------------------------------
+ * Variables
+ * ----------------------------------------------------------------------------- */
+
+ char *typemap_lang = 0; /* Current language setting */
+
+static int cplus_mode = 0;
+static String *class_rename = 0;
+
+/* C++ modes */
+
+#define CPLUS_PUBLIC 1
+#define CPLUS_PRIVATE 2
+#define CPLUS_PROTECTED 3
+
+void SWIG_typemap_lang(const char *tm_lang) {
+ typemap_lang = Swig_copy_string(tm_lang);
+}
+
+/* -----------------------------------------------------------------------------
+ * Assist functions
+ * ----------------------------------------------------------------------------- */
+
+/* Perform type-promotion for binary operators */
+static int promote(int t1, int t2) {
+ return t1 > t2 ? t1 : t2;
+}
+
+static String *yyrename = 0;
+
+/* Forward renaming operator */
+static Hash *rename_hash = 0;
+static Hash *namewarn_hash = 0;
+static Hash *features_hash = 0;
+
+static String *feature_identifier_fix(String *s) {
+ if (SwigType_istemplate(s)) {
+ String *tp, *ts, *ta, *tq;
+ tp = SwigType_templateprefix(s);
+ ts = SwigType_templatesuffix(s);
+ ta = SwigType_templateargs(s);
+ tq = Swig_symbol_type_qualify(ta,0);
+ Append(tp,tq);
+ Append(tp,ts);
+ Delete(ts);
+ Delete(ta);
+ Delete(tq);
+ return tp;
+ } else {
+ return NewString(s);
+ }
+}
+
+static void
+rename_add(char *name, SwigType *decl, char *newname) {
+ String *nname;
+ if (!rename_hash) rename_hash = NewHash();
+ if (Namespaceprefix) {
+ nname = NewStringf("%s::%s",Namespaceprefix, name);
+ } else {
+ nname = NewString(name);
+ }
+ Swig_name_object_set(rename_hash,nname,decl,NewString(newname));
+ Delete(nname);
+}
+
+static void
+namewarn_add(char *name, SwigType *decl, char *warning) {
+ String *nname;
+ if (!namewarn_hash) namewarn_hash = NewHash();
+ if (Namespaceprefix) {
+ nname = NewStringf("%s::%s",Namespaceprefix, name);
+ } else {
+ nname = NewString(name);
+ }
+
+ Swig_name_object_set(namewarn_hash,nname,decl,NewString(warning));
+ Delete(nname);
+}
+
+static void
+rename_inherit(String *base, String *derived) {
+ /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */
+ Swig_name_object_inherit(rename_hash,base,derived);
+ Swig_name_object_inherit(namewarn_hash,base,derived);
+ Swig_name_object_inherit(features_hash,base,derived);
+}
+
+/* Generate the symbol table name for an object */
+/* This is a bit of a mess. Need to clean up */
+static String *add_oldname = 0;
+
+static String *make_name(String *name,SwigType *decl) {
+ String *rn = 0;
+ String *origname = name;
+ int destructor = 0;
+
+ if (name && (*(Char(name)) == '~')) {
+ destructor = 1;
+ }
+ if (yyrename) {
+ String *s = yyrename;
+ yyrename = 0;
+ if (destructor) {
+ Insert(s,0,"~");
+ }
+ return s;
+ }
+ if (!name) return 0;
+ /* Check to see if the name is in the hash */
+ if (!rename_hash) {
+ if (add_oldname) return Copy(add_oldname);
+ return origname;
+ }
+ rn = Swig_name_object_get(rename_hash, Namespaceprefix, name, decl);
+ if (!rn) {
+ if (add_oldname) return Copy(add_oldname);
+ return name;
+ }
+ if (destructor) {
+ if (Strcmp(rn,"$ignore") != 0) {
+ String *s = NewStringf("~%s", rn);
+ return s;
+ }
+ }
+ return Copy(rn);
+}
+
+/* Generate an unnamed identifier */
+static String *make_unnamed() {
+ unnamed++;
+ return NewStringf("$unnamed%d$",unnamed);
+}
+
+/* Generate the symbol table name for an object */
+static String *name_warning(String *name,SwigType *decl) {
+ String *rn = 0;
+ if (!name) return 0;
+
+ /* Check to see if the name is in the hash */
+ if (!namewarn_hash) return 0;
+ rn = Swig_name_object_get(namewarn_hash, Namespaceprefix,name,decl);
+ if (!rn) return 0;
+ return rn;
+}
+
+/* Add declaration list to symbol table */
+static int add_only_one = 0;
+
+
+static void add_symbols(Node *n) {
+ String *decl;
+ String *wrn = 0;
+
+ /* Don't add symbols for private/protected members */
+ if (inclass && (cplus_mode != CPLUS_PUBLIC)) {
+ while (n) {
+ Swig_symbol_add(0, n); /* Add to C symbol table */
+ if (cplus_mode == CPLUS_PRIVATE) {
+ Setattr(n,"access", "private");
+ } else {
+ Setattr(n,"access", "protected");
+ }
+ if (add_only_one) break;
+ n = nextSibling(n);
+ }
+ return;
+ }
+ while (n) {
+ String *symname;
+ if (Getattr(n,"sym:name")) {
+ n = nextSibling(n);
+ continue;
+ }
+ decl = Getattr(n,"decl");
+ if (!SwigType_isfunction(decl)) {
+ symname = make_name(Getattr(n,"name"),0);
+ if (!symname) {
+ symname = Getattr(n,"unnamed");
+ }
+ if (symname) {
+ wrn = name_warning(symname,0);
+ Swig_features_get(features_hash, Namespaceprefix, Getattr(n,"name"), 0, n);
+ }
+ } else {
+ SwigType *fdecl = Copy(decl);
+ SwigType *fun = SwigType_pop_function(fdecl);
+ symname = make_name(Getattr(n,"name"),fun);
+ wrn = name_warning(symname,fun);
+
+ Swig_features_get(features_hash,Namespaceprefix,Getattr(n,"name"),fun,n);
+ Delete(fdecl);
+ Delete(fun);
+ }
+ if (!symname) {
+ n = nextSibling(n);
+ continue;
+ }
+ if (strncmp(Char(symname),"$ignore",7) == 0) {
+ char *c = Char(symname)+7;
+ Setattr(n,"feature:ignore","1");
+ if (strlen(c)) {
+ Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1);
+ }
+ Swig_symbol_add(0, n);
+ } else {
+ Node *c;
+ if ((wrn) && (Len(wrn))) {
+ Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn);
+ }
+ if (Strcmp(nodeType(n),"enum") != 0) {
+ c = Swig_symbol_add(symname,n);
+ if (c != n) {
+ if (Getattr(n,"sym:weak")) {
+ Setattr(n,"sym:name",symname);
+ } else if ((Strcmp(nodeType(n),"template") == 0) && (Strcmp(Getattr(n,"templatetype"),"cdecl") == 0)) {
+ Setattr(n,"sym:name",symname);
+ } else {
+ String *e = NewString("");
+ Printf(e,"Identifier '%s' redeclared (ignored).", symname);
+ if (Cmp(symname,Getattr(n,"name"))) {
+ Printf(e," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name")));
+ }
+ Printf(e,"\n%s:%d: Previous declaration of '%s'", Getfile(c),Getline(c),symname);
+ if (Cmp(symname,Getattr(c,"name"))) {
+ Printf(e," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name")));
+ }
+ Swig_warning(WARN_PARSE_REDEFINED,Getfile(n), Getline(n),"%s\n", e);
+ Setattr(n,"error",e);
+ }
+ }
+ } else {
+ Setattr(n,"sym:name", symname);
+ }
+ }
+ if (add_only_one) return;
+ n = nextSibling(n);
+ }
+}
+
+
+/* add symbols a parse tree node copy */
+
+void add_symbols_copy(Node *n) {
+ String *name;
+ int emode = 0;
+
+ while (n) {
+
+ if (Strcmp(nodeType(n),"access") == 0) {
+ String *kind = Getattr(n,"kind");
+ if (Strcmp(kind,"public") == 0) {
+ cplus_mode = CPLUS_PUBLIC;
+ } else if (Strcmp(kind,"private") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else if (Strcmp(kind,"protected") == 0) {
+ cplus_mode = CPLUS_PROTECTED;
+ }
+ n = nextSibling(n);
+ continue;
+ }
+
+ add_oldname = Getattr(n,"sym:name");
+ if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) {
+ if (add_oldname) {
+ DohIncref(add_oldname);
+ /* If already renamed, we used that name */
+ if (Strcmp(add_oldname, Getattr(n,"name")) != 0) {
+ yyrename = add_oldname;
+ }
+ }
+ Delattr(n,"sym:needs_symtab");
+ Delattr(n,"sym:name");
+
+ add_only_one = 1;
+ add_symbols(n);
+
+ if (Getattr(n,"partialargs")) {
+ Swig_symbol_cadd(Getattr(n,"partialargs"),n);
+ }
+ add_only_one = 0;
+ name = Getattr(n,"name");
+ if (Getattr(n,"requires_symtab")) {
+ Swig_symbol_newscope();
+ Swig_symbol_setscopename(name);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+ if (Strcmp(nodeType(n),"class") == 0) {
+ inclass = 1;
+ if (Strcmp(Getattr(n,"kind"),"class") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else {
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ }
+ if (Strcmp(nodeType(n),"extend") == 0) {
+ emode = cplus_mode;
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ add_symbols_copy(firstChild(n));
+ if (Strcmp(nodeType(n),"extend") == 0) {
+ cplus_mode = emode;
+ }
+ if (Getattr(n,"requires_symtab")) {
+ Setattr(n,"symtab", Swig_symbol_popscope());
+ Delattr(n,"requires_symtab");
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+ if (add_oldname) {
+ Delete(add_oldname);
+ }
+ if (Strcmp(nodeType(n),"class") == 0) {
+ inclass = 0;
+ }
+ add_oldname = 0;
+ } else {
+ if (Strcmp(nodeType(n),"extend") == 0) {
+ emode = cplus_mode;
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ add_symbols_copy(firstChild(n));
+ if (Strcmp(nodeType(n),"extend") == 0) {
+ cplus_mode = emode;
+ }
+ }
+ n = nextSibling(n);
+ }
+}
+
+/* Extension merge. This function is used to handle the %extend directive
+ when it appears before a class definition. To handle this, the %extend
+ actually needs to take precedence. Therefore, we will selectively nuke symbols
+ from the current symbol table, replacing them with the added methods */
+
+static void merge_extensions(Node *am) {
+ Node *n;
+ Node *csym;
+
+ n = firstChild(am);
+ while (n) {
+ String *symname;
+ symname = Getattr(n,"sym:name");
+ DohIncref(symname);
+ if ((symname) && (!Getattr(n,"error"))) {
+ /* Remove node from its symbol table */
+ Swig_symbol_remove(n);
+ csym = Swig_symbol_add(symname,n);
+ if (csym != n) {
+ /* Conflict with previous definition. Nuke previous definition */
+ String *e = NewString("");
+ Printf(e,"Identifier '%s' redeclared (ignored).\n", symname);
+ Printf(e,"%s:%d: Previous definition of tag '%s'", Getfile(n),Getline(n), symname);
+ Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym), Getline(csym), "%s\n", e);
+ Setattr(csym,"error",e);
+ Swig_symbol_remove(csym); /* Remove class definition */
+ Swig_symbol_add(symname,n); /* Insert extend definition */
+ }
+ }
+ n = nextSibling(n);
+ }
+}
+
+/* Check for unused %extend. Special case, don't report unused
+ extensions for templates */
+
+ static void check_extensions() {
+ String *key;
+ if (!extendhash) return;
+ for (key = Firstkey(extendhash); key; key = Nextkey(extendhash)) {
+ Node *n = Getattr(extendhash,key);
+ if (!Strstr(key,"<")) {
+ Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(n), Getline(n), "%%extend defined for an undeclared class %s.\n", key);
+ }
+ }
+ }
+
+/* Check a set of declarations to see if any are pure-abstract */
+
+ static List *pure_abstract(Node *n) {
+ List *abs = 0;
+ while (n) {
+ if (Cmp(nodeType(n),"cdecl") == 0) {
+ String *decl = Getattr(n,"decl");
+ if (SwigType_isfunction(decl)) {
+ String *init = Getattr(n,"value");
+ if (Cmp(init,"0") == 0) {
+ if (!abs) {
+ abs = NewList();
+ }
+ Append(abs,n);
+ Setattr(n,"abstract","1");
+ }
+ }
+ } else if (Cmp(nodeType(n),"destructor") == 0) {
+ if (Cmp(Getattr(n,"value"),"0") == 0) {
+ if (!abs) {
+ abs = NewList();
+ }
+ Append(abs,n);
+ Setattr(n,"abstract","1");
+ }
+ }
+ n = nextSibling(n);
+ }
+ return abs;
+ }
+
+ /* Make a classname */
+
+ static String *make_class_name(String *name) {
+ String *nname = 0;
+ if (Namespaceprefix) {
+ nname= NewStringf("%s::%s", Namespaceprefix, name);
+ } else {
+ nname = NewString(name);
+ }
+ if (SwigType_istemplate(nname)) {
+ String *prefix, *args, *qargs;
+ prefix = SwigType_templateprefix(nname);
+ args = SwigType_templateargs(nname);
+ qargs = Swig_symbol_type_qualify(args,0);
+ Append(prefix,qargs);
+ Delete(nname);
+ nname = prefix;
+ }
+ return nname;
+ }
+
+ static List *make_inherit_list(String *clsname, List *names) {
+ int i;
+ String *derived;
+ List *bases = NewList();
+
+ if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname);
+ else derived = NewString(clsname);
+
+ for (i = 0; i < Len(names); i++) {
+ Node *s;
+ String *base;
+ String *n = Getitem(names,i);
+ /* Try to figure out where this symbol is */
+ s = Swig_symbol_clookup(n,0);
+ if (s) {
+ while (s && (Strcmp(nodeType(s),"class") != 0)) {
+ /* Not a class. Could be a typedef though. */
+ String *storage = Getattr(s,"storage");
+ if (storage && (Strcmp(storage,"typedef") == 0)) {
+ String *nn = Getattr(s,"type");
+ s = Swig_symbol_clookup(nn,Getattr(s,"sym:symtab"));
+ } else {
+ break;
+ }
+ }
+ if (s && ((Strcmp(nodeType(s),"class") == 0) || (Strcmp(nodeType(s),"template") == 0))) {
+ String *q = Swig_symbol_qualified(s);
+ Append(bases,s);
+ if (q) {
+ base = NewStringf("%s::%s", q, Getattr(s,"name"));
+ } else {
+ base = NewString(Getattr(s,"name"));
+ }
+ } else {
+ base = NewString(n);
+ }
+ } else {
+ base = NewString(n);
+ }
+ if (base) {
+ rename_inherit(base,derived);
+ Delete(base);
+ }
+ }
+ return bases;
+ }
+
+/* Structures for handling code fragments built for nested classes */
+
+typedef struct Nested {
+ String *code; /* Associated code fragment */
+ int line; /* line number where it starts */
+ char *name; /* Name associated with this nested class */
+ char *kind; /* Kind of class */
+ SwigType *type; /* Datatype associated with the name */
+ struct Nested *next; /* Next code fragment in list */
+} Nested;
+
+/* Some internal variables for saving nested class information */
+
+static Nested *nested_list = 0;
+
+/* Add a function to the nested list */
+
+static void add_nested(Nested *n) {
+ Nested *n1;
+ if (!nested_list) nested_list = n;
+ else {
+ n1 = nested_list;
+ while (n1->next) n1 = n1->next;
+ n1->next = n;
+ }
+}
+
+/* Dump all of the nested class declarations to the inline processor
+ * However. We need to do a few name replacements and other munging
+ * first. This function must be called before closing a class! */
+
+static Node *dump_nested(char *parent) {
+ Nested *n,*n1;
+ Node *ret = 0;
+ n = nested_list;
+ if (!parent) {
+ nested_list = 0;
+ return 0;
+ }
+ while (n) {
+ char temp[256];
+ Node *retx;
+ /* Token replace the name of the parent class */
+ Replace(n->code, "$classname", parent, DOH_REPLACE_ANY);
+ /* Fix up the name of the datatype (for building typedefs and other stuff) */
+ sprintf(temp,"%s_%s", parent,n->name);
+
+ Append(n->type,parent);
+ Append(n->type,"_");
+ Append(n->type,n->name);
+
+ /* Add the appropriate declaration to the C++ processor */
+ retx = new_node("cdecl");
+ Setattr(retx,"name",n->name);
+ Setattr(retx,"type",Copy(n->type));
+ Setattr(retx,"nested",parent);
+ add_symbols(retx);
+ if (ret) {
+ set_nextSibling(retx,ret);
+ }
+ ret = retx;
+
+ /* Insert a forward class declaration */
+ /* Disabled: [ 597599 ] union in class: incorrect scope
+ retx = new_node("classforward");
+ Setattr(retx,"kind",n->kind);
+ Setattr(retx,"name",Copy(n->type));
+ Setattr(retx,"sym:name", make_name(n->type,0));
+ set_nextSibling(retx,ret);
+ ret = retx;
+ */
+
+ /* Make all SWIG created typedef structs/unions/classes unnamed else
+ redefinition errors occur - nasty hack alert.*/
+
+ {
+ const char* types_array[3] = {"struct", "union", "class"};
+ int i;
+ for (i=0; i<3; i++) {
+ char* code_ptr = Char(n->code);
+ while (code_ptr) {
+ /* Replace struct name (as in 'struct name {' ) with whitespace
+ name will be between struct and { */
+
+ code_ptr = strstr(code_ptr, types_array[i]);
+ if (code_ptr) {
+ char *open_bracket_pos;
+ code_ptr += strlen(types_array[i]);
+ open_bracket_pos = strstr(code_ptr, "{");
+ if (open_bracket_pos) {
+ /* Make sure we don't have something like struct A a; */
+ char* semi_colon_pos = strstr(code_ptr, ";");
+ if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
+ while (code_ptr < open_bracket_pos)
+ *code_ptr++ = ' ';
+ }
+ }
+ }
+ }
+ }
+
+ {
+ /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
+ char* code_ptr = Char(n->code);
+ while (code_ptr) {
+ code_ptr = strstr(code_ptr, "%constant");
+ if (code_ptr) {
+ char* directive_end_pos = strstr(code_ptr, ";");
+ if (directive_end_pos) {
+ while (code_ptr <= directive_end_pos)
+ *code_ptr++ = ' ';
+ }
+ }
+ }
+ }
+ {
+ Node *head;
+ head = new_node("insert");
+ Setattr(head,"code",NewStringf("\n%s\n",n->code));
+ set_nextSibling(head,ret);
+ ret = head;
+ }
+
+ /* Dump the code to the scanner */
+ start_inline(Char(n->code),n->line);
+
+ n1 = n->next;
+ Delete(n->code);
+ free(n);
+ n = n1;
+ }
+ nested_list = 0;
+ return ret;
+}
+
+Node *Swig_cparse(File *f) {
+ extern void scanner_file(File *);
+ extern int yyparse();
+ scanner_file(f);
+ top = 0;
+ yyparse();
+ return top;
+}
+
+%}
+
+%union {
+ char *id;
+ List *bases;
+ struct Define {
+ String *val;
+ String *rawval;
+ int type;
+ String *qualifier;
+ String *bitfield;
+ Parm *throws;
+ } dtype;
+ struct {
+ char *type;
+ char *filename;
+ int line;
+ } loc;
+ struct {
+ char *id;
+ SwigType *type;
+ String *defarg;
+ ParmList *parms;
+ short have_parms;
+ ParmList *throws;
+ } decl;
+ Parm *tparms;
+ struct {
+ String *op;
+ Hash *kwargs;
+ } tmap;
+ struct {
+ String *type;
+ String *us;
+ } ptype;
+ SwigType *type;
+ String *str;
+ Parm *p;
+ ParmList *pl;
+ int ivalue;
+ Node *node;
+};
+
+%token <id> ID
+%token <str> HBLOCK
+%token <id> POUND
+%token <id> STRING
+%token <loc> INCLUDE IMPORT INSERT
+%token <str> CHARCONST
+%token <dtype> NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG
+%token <ivalue> TYPEDEF
+%token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_TYPEDEF TYPE_RAW
+%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD
+%token CONST VOLATILE STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET
+%token ILLEGAL CONSTANT
+%token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS
+%token ENUM
+%token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH
+%token USING
+%token <node> NAMESPACE
+%token NATIVE INLINE
+%token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT
+%token WARN
+%token LESSTHAN GREATERTHAN MODULO DELETE
+%token TYPES PARMS
+%token NONID DSTAR DCNOT
+%token <ivalue> TEMPLATE
+%token <str> OPERATOR
+%token <str> COPERATOR
+%token PARSETYPE
+
+%left CAST
+%left LOR
+%left LAND
+%left OR
+%left XOR
+%left AND
+%left LSHIFT RSHIFT
+%left PLUS MINUS
+%left STAR SLASH
+%left UMINUS NOT LNOT
+%left DCOLON
+
+%type <node> program interface declaration swig_directive ;
+
+/* SWIG directives */
+%type <node> extend_directive apply_directive clear_directive constant_directive ;
+%type <node> echo_directive except_directive fragment_directive include_directive inline_directive ;
+%type <node> insert_directive module_directive name_directive native_directive ;
+%type <node> pragma_directive rename_directive feature_directive varargs_directive typemap_directive ;
+%type <node> types_directive template_directive warn_directive ;
+
+/* C declarations */
+%type <node> c_declaration c_decl c_decl_tail c_enum_decl c_constructor_decl ;
+%type <node> enumlist edecl;
+
+/* C++ declarations */
+%type <node> cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl;
+%type <node> cpp_members cpp_member;
+%type <node> cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator;
+%type <node> cpp_swig_directive cpp_temp_possible cpp_nested cpp_opt_declarators ;
+%type <node> cpp_using_decl cpp_namespace_decl cpp_catch_decl ;
+%type <node> kwargs options;
+
+/* Misc */
+%type <dtype> initializer cpp_const ;
+%type <id> storage_class;
+%type <pl> parms ptail rawparms varargs_parms ;
+%type <p> parm valparm rawvalparms valparms valptail ;
+%type <p> typemap_parm tm_list tm_tail ;
+%type <id> cpptype access_specifier;
+%type <node> base_specifier
+%type <type> type rawtype type_right ;
+%type <bases> base_list inherit raw_inherit;
+%type <dtype> definetype def_args etype;
+%type <dtype> expr exprnum exprcompound ;
+%type <id> ename ;
+%type <id> template_decl;
+%type <str> type_qualifier ;
+%type <id> type_qualifier_raw;
+%type <id> idstring idstringopt;
+%type <id> pragma_lang;
+%type <str> pragma_arg;
+%type <loc> includetype;
+%type <type> pointer primitive_type;
+%type <decl> declarator direct_declarator notso_direct_declarator parameter_declarator typemap_parameter_declarator nested_decl;
+%type <decl> abstract_declarator direct_abstract_declarator ctor_end;
+%type <tmap> typemap_type;
+%type <str> idcolon idcolontail idcolonnt idcolontailnt idtemplate stringbrace stringbracesemi;
+%type <id> string stringnum ;
+%type <tparms> template_parms;
+%type <dtype> cpp_vend;
+%type <ivalue> rename_namewarn;
+%type <ptype> type_specifier primitive_type_list ;
+
+%%
+
+/* ======================================================================
+ * High-level Interface file
+ *
+ * An interface is just a sequence of declarations which may be SWIG directives
+ * or normal C declarations.
+ * ====================================================================== */
+
+program : interface {
+ Setattr($1,"classes",classes);
+ Setattr($1,"name",ModuleName);
+
+ if ((!module_node) && ModuleName) {
+ module_node = new_node("module");
+ Setattr(module_node,"name",ModuleName);
+ }
+ Setattr($1,"module",module_node);
+ check_extensions();
+ top = $1;
+ }
+ | PARSETYPE parm SEMI {
+ top = Getattr($2,"type");
+ }
+ | PARSETYPE error {
+ top = 0;
+ }
+ ;
+
+interface : interface declaration {
+ appendChild($1,$2);
+ $$ = $1;
+ }
+ | empty {
+ $$ = new_node("top");
+ }
+ ;
+
+declaration : swig_directive { $$ = $1; }
+ | c_declaration { $$ = $1; }
+ | cpp_declaration { $$ = $1; }
+ | SEMI { $$ = 0; }
+ | error {
+ $$ = 0;
+ if (!Swig_error_count()) {
+ static int last_error_line = -1;
+ if (last_error_line != cparse_line) {
+ Swig_error(cparse_file, cparse_line,"Syntax error in input.\n");
+ last_error_line = cparse_line;
+ skip_decl();
+ }
+ }
+ }
+/* Out of class constructor/destructor declarations */
+ | c_constructor_decl {
+ if ($$) {
+ add_symbols($$);
+ }
+ $$ = $1;
+ }
+ ;
+
+
+/* ======================================================================
+ * SWIG DIRECTIVES
+ * ====================================================================== */
+
+swig_directive : extend_directive { $$ = $1; }
+ | apply_directive { $$ = $1; }
+ | clear_directive { $$ = $1; }
+ | constant_directive { $$ = $1; }
+ | echo_directive { $$ = $1; }
+ | except_directive { $$ = $1; }
+ | fragment_directive { $$ = $1; }
+ | include_directive { $$ = $1; }
+ | inline_directive { $$ = $1; }
+ | insert_directive { $$ = $1; }
+ | module_directive { $$ = $1; }
+ | name_directive { $$ = $1; }
+ | native_directive { $$ = $1; }
+ | pragma_directive { $$ = $1; }
+ | rename_directive { $$ = $1; }
+ | feature_directive { $$ = $1; }
+ | varargs_directive { $$ = $1; }
+ | typemap_directive { $$ = $1; }
+ | types_directive { $$ = $1; }
+ | template_directive { $$ = $1; }
+ | warn_directive { $$ = $1; }
+ ;
+
+/* ------------------------------------------------------------
+ %extend classname { ... }
+ ------------------------------------------------------------ */
+
+extend_directive : EXTEND options idcolon LBRACE {
+ Node *cls;
+ String *clsname;
+ cplus_mode = CPLUS_PUBLIC;
+ if (!classes) classes = NewHash();
+ if (!extendhash) extendhash = NewHash();
+ clsname = make_class_name($3);
+ /* Printf(stdout,"clsname = '%s'\n",clsname);*/
+ cls = Getattr(classes,clsname);
+ if (!cls) {
+ /* No previous definition. Create a new scope */
+ Node *am = Getattr(extendhash,clsname);
+ if (!am) {
+ Swig_symbol_newscope();
+ Swig_symbol_setscopename($3);
+ prev_symtab = 0;
+ } else {
+ prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab"));
+ }
+ current_class = 0;
+ } else {
+ /* Previous class definition. Use its symbol table */
+ prev_symtab = Swig_symbol_setscope(Getattr(cls,"symtab"));
+ current_class = cls;
+ }
+ Classprefix = NewString($3);
+ Namespaceprefix= Swig_symbol_qualifiedscopename(0);
+ Delete(clsname);
+ } cpp_members RBRACE {
+ String *clsname;
+ $$ = new_node("extend");
+ Setattr($$,"symtab",Swig_symbol_popscope());
+ if (prev_symtab) {
+ Swig_symbol_setscope(prev_symtab);
+ }
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ clsname = make_class_name($3);
+ Setattr($$,"name",clsname);
+
+ /* Mark members as extend */
+
+ Swig_tag_nodes($6,"feature:extend",(char*) "1");
+ if (current_class) {
+ /* We add the extension to the previously defined class */
+ appendChild($$,$6);
+ appendChild(current_class,$$);
+ } else {
+ /* We store the extensions in the extensions hash */
+ Node *am = Getattr(extendhash,clsname);
+ if (am) {
+ /* Append the members to the previous extend methods */
+ appendChild(am,$6);
+ } else {
+ appendChild($$,$6);
+ Setattr(extendhash,clsname,$$);
+ }
+ }
+ current_class = 0;
+ Delete(Classprefix);
+ Delete(clsname);
+ Classprefix = 0;
+ prev_symtab = 0;
+ $$ = 0;
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %apply
+ ------------------------------------------------------------ */
+
+apply_directive : APPLY typemap_parm LBRACE tm_list RBRACE {
+ $$ = new_node("apply");
+ Setattr($$,"pattern",Getattr($2,"pattern"));
+ appendChild($$,$4);
+ };
+
+/* ------------------------------------------------------------
+ %clear
+ ------------------------------------------------------------ */
+
+clear_directive : CLEAR tm_list SEMI {
+ $$ = new_node("clear");
+ appendChild($$,$2);
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %constant name = value;
+ %constant type name = value;
+ ------------------------------------------------------------ */
+
+constant_directive : CONSTANT ID EQUAL definetype SEMI {
+ if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) {
+ $$ = new_node("constant");
+ Setattr($$,"name",$2);
+ Setattr($$,"type",NewSwigType($4.type));
+ Setattr($$,"value",$4.val);
+ Setattr($$,"storage","%constant");
+ Setattr($$,"feature:immutable","1");
+ add_symbols($$);
+ } else {
+ if ($4.type == T_ERROR) {
+ Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n");
+ }
+ $$ = 0;
+ }
+
+ }
+
+ | CONSTANT type declarator def_args SEMI {
+ if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) {
+ SwigType_push($2,$3.type);
+ /* Sneaky callback function trick */
+ if (SwigType_isfunction($2)) {
+ SwigType_add_pointer($2);
+ }
+ $$ = new_node("constant");
+ Setattr($$,"name",$3.id);
+ Setattr($$,"type",$2);
+ Setattr($$,"value",$4.val);
+ Setattr($$,"storage","%constant");
+ Setattr($$,"feature:immutable","1");
+ add_symbols($$);
+ } else {
+ if ($4.type == T_ERROR) {
+ Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value\n");
+ }
+ $$ = 0;
+ }
+ }
+ | CONSTANT error SEMI {
+ Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n");
+ $$ = 0;
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %echo "text"
+ %echo %{ ... %}
+ ------------------------------------------------------------ */
+
+echo_directive : ECHO HBLOCK {
+ char temp[64];
+ Replace($2,"$file",cparse_file, DOH_REPLACE_ANY);
+ sprintf(temp,"%d", cparse_line);
+ Replace($2,"$line",temp,DOH_REPLACE_ANY);
+ Printf(stderr,"%s\n", $2);
+ Delete($2);
+ $$ = 0;
+ }
+ | ECHO string {
+ char temp[64];
+ String *s = NewString($2);
+ Replace(s,"$file",cparse_file, DOH_REPLACE_ANY);
+ sprintf(temp,"%d", cparse_line);
+ Replace(s,"$line",temp,DOH_REPLACE_ANY);
+ Printf(stderr,"%s\n", s);
+ Delete(s);
+ $$ = 0;
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %except(lang) { ... }
+ %except { ... }
+ %except(lang);
+ %except;
+ ------------------------------------------------------------ */
+
+except_directive : EXCEPT LPAREN ID RPAREN LBRACE {
+ skip_balanced('{','}');
+ $$ = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.");
+ }
+
+ | EXCEPT LBRACE {
+ skip_balanced('{','}');
+ $$ = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.");
+ }
+
+ | EXCEPT LPAREN ID RPAREN SEMI {
+ $$ = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.");
+ }
+
+ | EXCEPT SEMI {
+ $$ = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.");
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %fragment(name,location) { ... }
+ ------------------------------------------------------------ */
+
+fragment_directive: FRAGMENT LPAREN idstring COMMA idstring RPAREN HBLOCK {
+ $$ = new_node("fragment");
+ Setattr($$,"section", $5);
+ Setattr($$,"name",$3);
+ Setattr($$,"code",$7);
+ }
+ | FRAGMENT LPAREN idstring COMMA idstring RPAREN LBRACE {
+ skip_balanced('{','}');
+ $$ = new_node("fragment");
+ Setattr($$,"section",$5);
+ Setattr($$,"name",$3);
+ Delitem(scanner_ccode,0);
+ Delitem(scanner_ccode,DOH_END);
+ Setattr($$,"code",Copy(scanner_ccode));
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %includefile "filename" [ declarations ]
+ %importfile "filename" [ declarations ]
+ ------------------------------------------------------------ */
+
+include_directive: includetype options string LBRACKET {
+ $1.filename = Swig_copy_string(cparse_file);
+ $1.line = cparse_line;
+ cparse_file = Swig_copy_string($3);
+ cparse_line = 0;
+ } interface RBRACKET {
+ $$ = $6;
+ cparse_file = $1.filename;
+ cparse_line = $1.line;
+ if (strcmp($1.type,"include") == 0) set_nodeType($$,"include");
+ if (strcmp($1.type,"import") == 0) set_nodeType($$,"import");
+ Setattr($$,"name",$3);
+ /* Search for the module (if any) */
+ {
+ Node *n = firstChild($$);
+ while (n) {
+ if (Strcmp(nodeType(n),"module") == 0) {
+ Setattr($$,"module",Getattr(n,"name"));
+ break;
+ }
+ n = nextSibling(n);
+ }
+ }
+ Setattr($$,"options",$2);
+ }
+ ;
+
+includetype : INCLUDE { $$.type = (char *) "include"; }
+ | IMPORT { $$.type = (char *) "import"; }
+ ;
+
+/* ------------------------------------------------------------
+ %inline %{ ... %}
+ ------------------------------------------------------------ */
+
+inline_directive : INLINE HBLOCK {
+ String *cpps;
+ if (Namespaceprefix) {
+ Swig_error(cparse_file, cparse_start_line, "Error. %%inline directive inside a namespace is disallowed.\n");
+
+ $$ = 0;
+ } else {
+ $$ = new_node("insert");
+ Setattr($$,"code",$2);
+ /* Need to run through the preprocessor */
+ Setline($2,cparse_start_line);
+ Setfile($2,cparse_file);
+ Seek($2,0,SEEK_SET);
+ cpps = Preprocessor_parse($2);
+ start_inline(Char(cpps), cparse_start_line);
+ Delete($2);
+ Delete(cpps);
+ }
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %{ ... %}
+ %insert(section) "filename"
+ %insert("section") "filename"
+ %insert(section) %{ ... %}
+ %insert("section") %{ ... %}
+ ------------------------------------------------------------ */
+
+insert_directive : HBLOCK {
+ $$ = new_node("insert");
+ Setattr($$,"code",$1);
+ }
+ | INSERT LPAREN idstring RPAREN string {
+ String *code = NewString("");
+ $$ = new_node("insert");
+ Setattr($$,"section",$3);
+ Setattr($$,"code",code);
+ if (Swig_insert_file($5,code) < 0) {
+ Swig_error(cparse_file, cparse_line, "Couldn't find '%s'.\n", $5);
+ $$ = 0;
+ }
+ }
+ | INSERT LPAREN idstring RPAREN HBLOCK {
+ $$ = new_node("insert");
+ Setattr($$,"section",$3);
+ Setattr($$,"code",$5);
+ }
+ | INSERT LPAREN idstring RPAREN LBRACE {
+ skip_balanced('{','}');
+ $$ = new_node("insert");
+ Setattr($$,"section",$3);
+ Delitem(scanner_ccode,0);
+ Delitem(scanner_ccode,DOH_END);
+ Setattr($$,"code", Copy(scanner_ccode));
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %module modname
+ %module "modname"
+ ------------------------------------------------------------ */
+
+module_directive: MODULE options idstring {
+ $$ = new_node("module");
+ Setattr($$,"name",$3);
+ if ($2) Setattr($$,"options",$2);
+ if (!ModuleName) ModuleName = NewString($3);
+ if (!module_node) module_node = $$;
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %name(newname) declaration
+ %name("newname") declaration
+ ------------------------------------------------------------ */
+
+name_directive : NAME LPAREN idstring RPAREN {
+ yyrename = NewString($3);
+ $$ = 0;
+ }
+ | NAME LPAREN RPAREN {
+ $$ = 0;
+ Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n");
+ }
+ ;
+
+
+/* ------------------------------------------------------------
+ %native(scriptname) name;
+ %native(scriptname) type name (parms);
+ ------------------------------------------------------------ */
+
+native_directive : NATIVE LPAREN ID RPAREN storage_class ID SEMI {
+ $$ = new_node("native");
+ Setattr($$,"name",$3);
+ Setattr($$,"wrap:name",$6);
+ add_symbols($$);
+ }
+ | NATIVE LPAREN ID RPAREN storage_class type declarator SEMI {
+ if (!SwigType_isfunction($7.type)) {
+ Swig_error(cparse_file,cparse_line,"%%native declaration '%s' is not a function.\n", $7.id);
+ $$ = 0;
+ } else {
+ Delete(SwigType_pop_function($7.type));
+ /* Need check for function here */
+ SwigType_push($6,$7.type);
+ $$ = new_node("native");
+ Setattr($$,"name",$3);
+ Setattr($$,"wrap:name",$7.id);
+ Setattr($$,"type",$6);
+ Setattr($$,"parms",$7.parms);
+ Setattr($$,"decl",$7.type);
+ }
+ add_symbols($$);
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %pragma(lang) name=value
+ %pragma(lang) name
+ %pragma name = value
+ %pragma name
+ ------------------------------------------------------------ */
+
+pragma_directive : PRAGMA pragma_lang ID EQUAL pragma_arg {
+ $$ = new_node("pragma");
+ Setattr($$,"lang",$2);
+ Setattr($$,"name",$3);
+ Setattr($$,"value",$5);
+ }
+ | PRAGMA pragma_lang ID {
+ $$ = new_node("pragma");
+ Setattr($$,"lang",$2);
+ Setattr($$,"name",$3);
+ }
+ ;
+
+pragma_arg : string { $$ = NewString($1); }
+ | HBLOCK { $$ = $1; }
+ ;
+
+pragma_lang : LPAREN ID RPAREN { $$ = $2; }
+ | empty { $$ = (char *) "swig"; }
+ ;
+
+/* ------------------------------------------------------------
+ %rename identifier newname;
+ %rename identifier "newname";
+ ------------------------------------------------------------ */
+
+rename_directive : rename_namewarn declarator idstring SEMI {
+ SwigType *t = $2.type;
+ if (!Len(t)) t = 0;
+ if ($1) {
+ rename_add($2.id,t,$3);
+ } else {
+ namewarn_add($2.id,t,$3);
+ }
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ | rename_namewarn LPAREN idstring RPAREN declarator cpp_const SEMI {
+ String *fixname;
+ SwigType *t = $5.type;
+ fixname = feature_identifier_fix($5.id);
+ if (!Len(t)) t = 0;
+ /* Special declarator check */
+ if (t) {
+ if ($6.qualifier) SwigType_push(t,$6.qualifier);
+ if (SwigType_isfunction(t)) {
+ SwigType *decl = SwigType_pop_function(t);
+ if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",fixname);
+ if ($1) {
+ rename_add(Char(nname),decl,$3);
+ } else {
+ namewarn_add(Char(nname),decl,$3);
+ }
+ Delete(nname);
+ } else {
+ if ($1) {
+ rename_add(Char(fixname),decl,$3);
+ } else {
+ namewarn_add(Char(fixname),decl,$3);
+ }
+ }
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",fixname);
+ if ($1) {
+ rename_add(Char(nname),0,$3);
+ } else {
+ namewarn_add(Char(nname),0,$3);
+ }
+ Delete(nname);
+ }
+ } else {
+ if ($1) {
+ rename_add(Char(fixname),0,$3);
+ } else {
+ namewarn_add(Char(fixname),0,$3);
+ }
+ }
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ | rename_namewarn LPAREN idstring RPAREN string SEMI {
+ if ($1) {
+ rename_add($5,0,$3);
+ } else {
+ namewarn_add($5,0,$3);
+ }
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ ;
+
+rename_namewarn : RENAME {
+ $$ = 1;
+ }
+ | NAMEWARN {
+ $$ = 0;
+ };
+
+
+/* ------------------------------------------------------------
+ %feature(featurename) name { val }
+ %feature(featurename) name "val";
+ %feature(featurename) name %{ val % }
+ %feature(featurename,val) name;
+ ------------------------------------------------------------ */
+
+
+feature_directive : FEATURE LPAREN idstring RPAREN declarator cpp_const stringbracesemi {
+ String *fname;
+ String *val;
+ String *name;
+ String *fixname;
+ SwigType *t;
+ if (!features_hash) features_hash = NewHash();
+ fname = NewStringf("feature:%s",$3);
+ fixname = feature_identifier_fix($5.id);
+ if (Namespaceprefix) {
+ name = NewStringf("%s::%s",Namespaceprefix, fixname);
+ } else {
+ name = fixname;
+ }
+ val = $7 ? NewString($7) : NewString("1");
+ if ($5.parms) {
+ Setmeta(val,"parms",$5.parms);
+ }
+ t = $5.type;
+ if ($5.parms) Setmeta(val,"parms",$5.parms);
+ if (!Len(t)) t = 0;
+ if (t) {
+ if ($6.qualifier) SwigType_push(t,$6.qualifier);
+ if (SwigType_isfunction(t)) {
+ SwigType *decl = SwigType_pop_function(t);
+ if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(features_hash, nname, decl, fname, val);
+ Delete(nname);
+ } else {
+ Swig_feature_set(features_hash, name, decl, fname, val);
+ }
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(features_hash,nname,0,fname,val);
+ Delete(nname);
+ }
+ } else {
+ Swig_feature_set(features_hash,name,0,fname,val);
+ }
+ Delete(fname);
+ Delete(name);
+ $$ = 0;
+ }
+
+ /* Special form where value is included in (...) part */
+
+ | FEATURE LPAREN idstring COMMA idstring RPAREN declarator cpp_const SEMI {
+ String *fname;
+ String *val;
+ String *name;
+ String *fixname;
+ SwigType *t;
+
+ if (!features_hash) features_hash = NewHash();
+ fname = NewStringf("feature:%s",$3);
+ fixname = feature_identifier_fix($7.id);
+ if (Namespaceprefix) {
+ name = NewStringf("%s::%s",Namespaceprefix, fixname);
+ } else {
+ name = fixname;
+ }
+ if (Len($5)) {
+ val = NewString($5);
+ } else {
+ val = 0;
+ }
+ if ($7.parms) {
+ Setmeta(val,"parms",$7.parms);
+ }
+ t = $7.type;
+ if ($7.parms) Setmeta(val,"parms",$7.parms);
+ if (!Len(t)) t = 0;
+ if (t) {
+ if ($8.qualifier) SwigType_push(t,$8.qualifier);
+ if (SwigType_isfunction(t)) {
+ SwigType *decl = SwigType_pop_function(t);
+ if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(features_hash, nname, decl, fname, val);
+ Delete(nname);
+ } else {
+ Swig_feature_set(features_hash, name, decl, fname, val);
+ }
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(features_hash,nname,0,fname,val);
+ Delete(nname);
+ }
+ } else {
+ Swig_feature_set(features_hash,name,0,fname,val);
+ }
+ Delete(fname);
+ Delete(name);
+ $$ = 0;
+ }
+
+ /* Global feature */
+
+ | FEATURE LPAREN idstring RPAREN stringbracesemi {
+ String *name;
+ String *fname = NewStringf("feature:%s",$3);
+ if (!features_hash) features_hash = NewHash();
+ if (Namespaceprefix) name = NewStringf("%s::", Namespaceprefix);
+ else name = NewString("");
+ Swig_feature_set(features_hash,name,0,fname,($5 ? NewString($5) : NewString("1")));
+ Delete(name);
+ Delete(fname);
+ $$ = 0;
+ }
+ | FEATURE LPAREN idstring COMMA idstring RPAREN SEMI {
+ String *name;
+ String *fname = NewStringf("feature:%s",$3);
+ if (!features_hash) features_hash = NewHash();
+ if (Namespaceprefix) name = NewStringf("%s::", Namespaceprefix);
+ else name = NewString("");
+ Swig_feature_set(features_hash,name,0,fname,(Len($5) ? NewString($5) : 0));
+ Delete(name);
+ Delete(fname);
+ $$ = 0;
+ }
+ ;
+
+stringbracesemi : stringbrace { $$ = $1; }
+ | SEMI { $$ = 0; }
+ | PARMS LPAREN parms RPAREN SEMI { $$ = $3; }
+ ;
+
+/* %varargs() directive. */
+
+varargs_directive : VARARGS LPAREN varargs_parms RPAREN declarator cpp_const SEMI {
+ Parm *val;
+ String *name;
+ SwigType *t;
+ if (!features_hash) features_hash = NewHash();
+ if (Namespaceprefix) name = NewStringf("%s::%s", Namespaceprefix, $5.id);
+ else name = NewString($5.id);
+ val = $3;
+ if ($5.parms) {
+ Setmeta(val,"parms",$5.parms);
+ }
+ t = $5.type;
+ if (!Len(t)) t = 0;
+ if (t) {
+ if ($6.qualifier) SwigType_push(t,$6.qualifier);
+ if (SwigType_isfunction(t)) {
+ SwigType *decl = SwigType_pop_function(t);
+ if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(features_hash, nname, decl, "feature:varargs", val);
+ Delete(nname);
+ } else {
+ Swig_feature_set(features_hash, name, decl, "feature:varargs", val);
+ }
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(features_hash,nname,0,"feature:varargs",val);
+ Delete(nname);
+ }
+ } else {
+ Swig_feature_set(features_hash,name,0,"feature:varargs",val);
+ }
+ Delete(name);
+ $$ = 0;
+ };
+
+varargs_parms : parms { $$ = $1; }
+ | NUM_INT COMMA parm {
+ int i;
+ int n;
+ Parm *p;
+ n = atoi(Char($1.val));
+ if (n <= 0) {
+ Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n");
+ $$ = 0;
+ } else {
+ $$ = Copy($3);
+ Setattr($$,"name","VARARGS_SENTINEL");
+ for (i = 0; i < n; i++) {
+ p = Copy($3);
+ set_nextSibling(p,$$);
+ $$ = p;
+ }
+ }
+ }
+ ;
+
+
+/* ------------------------------------------------------------
+ %typemap(method) type { ... }
+ %typemap(method) type "..."
+ %typemap(method) type; - typemap deletion
+ %typemap(method) type1,type2,... = type; - typemap copy
+ %typemap type1,type2,... = type; - typemap copy
+ ------------------------------------------------------------ */
+
+typemap_directive : TYPEMAP LPAREN typemap_type RPAREN tm_list stringbrace {
+ $$ = 0;
+ if ($3.op) {
+ $$ = new_node("typemap");
+ Setattr($$,"method",$3.op);
+ Setattr($$,"code",NewString($6));
+ if ($3.kwargs) {
+ Setattr($$,"kwargs", $3.kwargs);
+ }
+ appendChild($$,$5);
+ }
+ }
+ | TYPEMAP LPAREN typemap_type RPAREN tm_list SEMI {
+ $$ = 0;
+ if ($3.op) {
+ $$ = new_node("typemap");
+ Setattr($$,"method",$3.op);
+ appendChild($$,$5);
+ }
+ }
+ | TYPEMAP LPAREN typemap_type RPAREN tm_list EQUAL typemap_parm SEMI {
+ $$ = 0;
+ if ($3.op) {
+ $$ = new_node("typemapcopy");
+ Setattr($$,"method",$3.op);
+ Setattr($$,"pattern", Getattr($7,"pattern"));
+ appendChild($$,$5);
+ }
+ }
+ ;
+
+/* typemap method type (lang,method) or (method) */
+
+typemap_type : kwargs {
+ Hash *p;
+ String *name;
+ p = nextSibling($1);
+ if (p && (!Getattr(p,"value"))) {
+ /* two argument typemap form */
+ name = Getattr($1,"name");
+ if (!name || (Strcmp(name,typemap_lang))) {
+ $$.op = 0;
+ $$.kwargs = 0;
+ } else {
+ $$.op = Getattr(p,"name");
+ $$.kwargs = nextSibling(p);
+ }
+ } else {
+ /* one-argument typemap-form */
+ $$.op = Getattr($1,"name");
+ $$.kwargs = p;
+ }
+ }
+ ;
+
+tm_list : typemap_parm tm_tail {
+ $$ = $1;
+ set_nextSibling($$,$2);
+ }
+ ;
+
+tm_tail : COMMA typemap_parm tm_tail {
+ $$ = $2;
+ set_nextSibling($$,$3);
+ }
+ | empty { $$ = 0;}
+ ;
+
+typemap_parm : type typemap_parameter_declarator {
+ SwigType_push($1,$2.type);
+ $$ = new_node("typemapitem");
+ Setattr($$,"pattern",NewParm($1,$2.id));
+ Setattr($$,"parms", $2.parms);
+ /* $$ = NewParm($1,$2.id);
+ Setattr($$,"parms",$2.parms); */
+ }
+ | LPAREN parms RPAREN {
+ $$ = new_node("typemapitem");
+ Setattr($$,"pattern",$2);
+ /* Setattr($$,"multitype",$2); */
+ }
+ | LPAREN parms RPAREN LPAREN parms RPAREN {
+ $$ = new_node("typemapitem");
+ Setattr($$,"pattern", $2);
+ /* Setattr($$,"multitype",$2); */
+ Setattr($$,"parms",$5);
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %types(parmlist);
+ ------------------------------------------------------------ */
+
+types_directive : TYPES LPAREN parms RPAREN SEMI {
+ $$ = new_node("types");
+ Setattr($$,"parms",$3);
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %template(name) tname<args>;
+ ------------------------------------------------------------ */
+
+template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI {
+ Parm *p, *tp;
+ Node *n;
+ Node *nspace = 0, *nspace_inner = 0;
+ Node *tnode = 0;
+ Symtab *tscope = 0;
+ int specialized = 0;
+ $$ = 0;
+
+ tscope = Swig_symbol_current(); /* Get the current scope */
+
+ /* If the template name is qualified. We need to create or lookup namespace entries */
+ if (Swig_scopename_check($5)) {
+ String *prefix, *base;
+ Node *ns;
+ prefix = Swig_scopename_prefix($5);
+ base = Swig_scopename_last($5);
+
+ /* Try to locate the scope */
+ ns = Swig_symbol_clookup(prefix,0);
+ if (!ns) {
+ Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix);
+ } else {
+ if (Strcmp(nodeType(ns),"namespace") != 0) {
+ Swig_error(cparse_file,cparse_line,"'%s' is not defined as namespace.\n", prefix);
+ ns = 0;
+ } else {
+ /* Swig_symbol_setscope(Getattr(ns,"symtab"));
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0); */
+ }
+ }
+
+ /* Create namespace nodes to enclose the template declaration */
+ if (ns) {
+ List *scopes;
+ String *sname;
+ String *name = NewString(prefix);
+ scopes = NewList();
+ while (name) {
+ String *tprefix;
+ String *base = Swig_scopename_last(name);
+ Insert(scopes,0,base);
+ tprefix = Swig_scopename_prefix(name);
+ Delete(name);
+ name = tprefix;
+ }
+ for (sname = Firstitem(scopes); sname; sname = Nextitem(scopes)) {
+ Node *ns1,*ns2;
+
+ ns1 = Swig_symbol_clookup(sname,0);
+ assert(ns1);
+ if (Strcmp(nodeType(ns1),"namespace") == 0) {
+ if (Getattr(ns1,"alias")) {
+ ns1 = Getattr(ns1,"namespace");
+ }
+ } else {
+ assert(0);
+ }
+ ns2 = new_node("namespace");
+ Setattr(ns2,"name",sname);
+ Setattr(ns2,"symtab", Getattr(ns1,"symtab"));
+ add_symbols(ns2);
+ Swig_symbol_setscope(Getattr(ns1,"symtab"));
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ if (nspace_inner) {
+ appendChild(nspace_inner,ns2);
+ }
+ nspace_inner = ns2;
+ if (!nspace) nspace = ns2;
+ }
+ $5 = base;
+ }
+ }
+
+ n = Swig_cparse_template_locate($5,$7);
+
+ /* Patch the argument types to respect namespaces */
+ p = $7;
+ while (p) {
+ if (!Getattr(p,"value")) {
+ SwigType *ty = Getattr(p,"type");
+ if (ty) {
+ ty = Swig_symbol_type_qualify(ty,0);
+ /* ty = Swig_symbol_typedef_reduce(ty,0); */
+ Setattr(p,"type",ty);
+ }
+ }
+ p = nextSibling(p);
+ }
+ /* Look for the template */
+
+ if (n && (Strcmp(nodeType(n),"template") == 0)) {
+ Parm *tparms = Getattr(n,"templateparms");
+ if (!tparms) specialized = 1;
+ if (!specialized && ((ParmList_len($7) > ParmList_len(tparms)))) {
+ Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms));
+ } else if (!specialized && ((ParmList_len($7) < ParmList_numrequired(tparms)))) {
+ Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", ParmList_numrequired(tparms));
+ } else {
+ int def_supplied = 0;
+ /* Expand the template */
+ ParmList *temparms;
+ if (specialized) temparms = CopyParmList($7);
+ else temparms = CopyParmList(tparms);
+ /* Create typedef's and arguments */
+ p = $7;
+ tp = temparms;
+ while (p) {
+ String *value = Getattr(p,"value");
+ if (def_supplied) {
+ Setattr(p,"default","1");
+ }
+ if (value) {
+ Setattr(tp,"value",value);
+ } else {
+ SwigType *ty = Getattr(p,"type");
+ if (ty) {
+ Setattr(tp,"type",ty);
+ }
+ Delattr(tp,"value");
+ }
+ p = nextSibling(p);
+ tp = nextSibling(tp);
+ if (!p && tp) {
+ p = tp;
+ def_supplied = 1;
+ }
+ }
+
+ $$ = copy_node(n);
+ /* We need to set the node name based on name used to instantiate */
+ Setattr($$,"name",Copy($5));
+ if (!specialized) {
+ Delattr($$,"sym:typename");
+ } else {
+ Setattr($$,"sym:typename","1");
+ }
+ if ($3) {
+ Swig_cparse_template_expand($$,$3,temparms);
+ Setattr($$,"sym:name",$3);
+ } else {
+ static int cnt = 0;
+ String *nname = NewStringf("__dummy_%d__", cnt++);
+ Swig_cparse_template_expand($$,nname,temparms);
+ Setattr($$,"sym:name",nname);
+ Setattr($$,"feature:ignore","1");
+ }
+ Delattr($$,"templatetype");
+ Setattr($$,"template",n);
+ tnode = $$;
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Delete(temparms);
+
+ add_symbols_copy($$);
+ if (Strcmp(nodeType($$),"class") == 0) {
+
+ /* Identify pure abstract methods */
+ Setattr($$,"abstract", pure_abstract(firstChild($$)));
+
+ /* Set up inheritance in symbol table */
+ {
+ Symtab *csyms;
+ List *baselist = Getattr($$,"baselist");
+ csyms = Swig_symbol_current();
+ Swig_symbol_setscope(Getattr($$,"symtab"));
+ if (baselist) {
+ List *bases = make_inherit_list(Getattr($$,"name"),baselist);
+ if (bases) {
+ Node *s;
+ for (s = Firstitem(bases); s; s = Nextitem(bases)) {
+ Symtab *st = Getattr(s,"symtab");
+ if (st) {
+ Swig_symbol_inherit(st);
+ }
+ }
+ }
+ }
+ Swig_symbol_setscope(csyms);
+ }
+
+ /* Merge in addmethods for this class */
+
+ /* !!! This may be broken. We may have to
+ add the addmethods at the beginning of
+ the class */
+
+ if (extendhash) {
+ String *clsname;
+ Node *am;
+ if (Namespaceprefix) {
+ clsname = NewStringf("%s::%s", Namespaceprefix, Getattr($$,"name"));
+ } else {
+ clsname = Getattr($$,"name");
+ }
+ am = Getattr(extendhash,clsname);
+ if (am) {
+ merge_extensions(am);
+ appendChild($$,am);
+ Delattr(extendhash,clsname);
+ }
+ }
+ /* Add to classes hash */
+ if (!classes) classes = NewHash();
+ Setattr(classes,Swig_symbol_qualifiedscopename($$),$$);
+ }
+ }
+ if ($$ && nspace) {
+ appendChild(nspace_inner,$$);
+ $$ = nspace;
+ }
+ }
+ Swig_symbol_setscope(tscope);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %warn "text"
+ %warn(no)
+ ------------------------------------------------------------ */
+
+warn_directive : WARN string {
+ Swig_warning(0,cparse_file, cparse_line,"%s\n", $2);
+ $$ = 0;
+ }
+ ;
+
+/* ======================================================================
+ * C Parsing
+ * ====================================================================== */
+
+c_declaration : c_decl {
+ $$ = $1;
+ if ($$) {
+ add_symbols($$);
+ }
+ }
+ | c_enum_decl { $$ = $1; }
+
+/* A an extern C type declaration. Does nothing, but is ignored */
+
+ | EXTERN string LBRACE interface RBRACE {
+ if (Strcmp($2,"C") == 0) {
+ $$ = new_node("extern");
+ Setattr($$,"name",$2);
+ appendChild($$,firstChild($4));
+ } else {
+ Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\" (ignored).\n", $2);
+ $$ = 0;
+ }
+ }
+ ;
+
+/* ------------------------------------------------------------
+ A C global declaration of some kind (may be variable, function, typedef, etc.)
+ ------------------------------------------------------------ */
+
+c_decl : storage_class type declarator initializer c_decl_tail {
+ $$ = new_node("cdecl");
+ if ($4.qualifier) SwigType_push($3.type,$4.qualifier);
+ Setattr($$,"type",$2);
+ Setattr($$,"storage",$1);
+ Setattr($$,"name",$3.id);
+ Setattr($$,"decl",$3.type);
+ Setattr($$,"parms",$3.parms);
+ Setattr($$,"value",$4.val);
+ Setattr($$,"throws",$4.throws);
+ if (!$5) {
+ if (Len(scanner_ccode)) {
+ Setattr($$,"code",Copy(scanner_ccode));
+ }
+ } else {
+ Node *n = $5;
+ /* Inherit attributes */
+ while (n) {
+ Setattr(n,"type",Copy($2));
+ Setattr(n,"storage",$1);
+ n = nextSibling(n);
+ }
+ }
+ if ($4.bitfield) {
+ Setattr($$,"bitfield", $4.bitfield);
+ }
+
+ /* Look for "::" declarations (ignored) */
+ if (Strstr($3.id,"::")) {
+ Delete($$);
+ $$ = $5;
+ } else {
+ set_nextSibling($$,$5);
+ }
+ }
+ ;
+
+/* Allow lists of variables and functions to be built up */
+
+c_decl_tail : SEMI {
+ $$ = 0;
+ Clear(scanner_ccode);
+ }
+ | COMMA declarator initializer c_decl_tail {
+ $$ = new_node("cdecl");
+ if ($3.qualifier) SwigType_push($2.type,$3.qualifier);
+ Setattr($$,"name",$2.id);
+ Setattr($$,"decl",$2.type);
+ Setattr($$,"parms",$2.parms);
+ Setattr($$,"value",$3.val);
+ Setattr($$,"throws",$3.throws);
+ if ($3.bitfield) {
+ Setattr($$,"bitfield", $3.bitfield);
+ }
+ if (!$4) {
+ if (Len(scanner_ccode)) {
+ Setattr($$,"code",Copy(scanner_ccode));
+ }
+ } else {
+ set_nextSibling($$,$4);
+ }
+ }
+ | LBRACE {
+ skip_balanced('{','}');
+ $$ = 0;
+ }
+ ;
+
+initializer : def_args {
+ $$ = $1;
+ $$.qualifier = 0;
+ $$.throws = 0;
+ }
+ | type_qualifier def_args {
+ $$ = $2;
+ $$.qualifier = $1;
+ $$.throws = 0;
+ }
+ | THROW LPAREN parms RPAREN def_args {
+ $$ = $5;
+ $$.qualifier = 0;
+ $$.throws = $3;
+ }
+ | type_qualifier THROW LPAREN parms RPAREN def_args {
+ $$ = $6;
+ $$.qualifier = $1;
+ $$.throws = $4;
+ }
+ ;
+
+
+/* ------------------------------------------------------------
+ enum { ... }
+ * ------------------------------------------------------------ */
+
+c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI {
+ $$ = new_node("enum");
+ Setattr($$,"name",$3);
+ appendChild($$,$5);
+ add_symbols($$); /* Add to tag space */
+ add_symbols($5); /* Add enum values to id space */
+ }
+
+ | storage_class ENUM ename LBRACE enumlist RBRACE declarator c_decl_tail {
+ Node *n;
+ SwigType *ty = 0;
+ String *unnamed = 0;
+
+ $$ = new_node("enum");
+ if ($3) {
+ Setattr($$,"name",$3);
+ ty = NewStringf("enum %s", $3);
+ } else if ($7.id){
+ unnamed = make_unnamed();
+ ty = NewStringf("enum %s", unnamed);
+ Setattr($$,"unnamed",unnamed);
+ /* WF 20/12/2001: Cannot get sym:name and symtab set without setting name - fix!
+ // I don't think sym:name should be set. */
+ Setattr($$,"name",$7.id);
+ Setattr($$,"tdname",$7.id);
+ Setattr($$,"storage",$1);
+ }
+ appendChild($$,$5);
+ n = new_node("cdecl");
+ Setattr(n,"type",ty);
+ Setattr(n,"name",$7.id);
+ Setattr(n,"storage",$1);
+ Setattr(n,"decl",$7.type);
+ Setattr(n,"parms",$7.parms);
+ Setattr(n,"unnamed",unnamed);
+ if ($8) {
+ Node *p = $8;
+ set_nextSibling(n,p);
+ while (p) {
+ Setattr(p,"type",Copy(ty));
+ Setattr(p,"unnamed",unnamed);
+ Setattr(p,"storage",$1);
+ p = nextSibling(p);
+ }
+ } else {
+ if (Len(scanner_ccode)) {
+ Setattr(n,"code",Copy(scanner_ccode));
+ }
+ }
+ add_symbols($$); /* Add enum to tag space */
+ set_nextSibling($$,n);
+ add_symbols($5); /* Add to id space */
+ add_symbols(n);
+ }
+ ;
+
+c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
+ /* This is a sick hack. If the ctor_end has parameters,
+ and the parms paremeter only has 1 parameter, this
+ could be a declaration of the form:
+
+ type (id)(parms)
+
+ Otherwise it's an error. */
+ int err = 0;
+ $$ = 0;
+
+ if ((ParmList_len($4) == 1) && (!Swig_scopename_check($2))) {
+ SwigType *ty = Getattr($4,"type");
+ String *name = Getattr($4,"name");
+ err = 1;
+ if (!name) {
+ $$ = new_node("cdecl");
+ Setattr($$,"type",$2);
+ Setattr($$,"storage",$1);
+ Setattr($$,"name",ty);
+
+ if ($6.have_parms) {
+ SwigType *decl = NewString("");
+ SwigType_add_function(decl,$6.parms);
+ Setattr($$,"decl",decl);
+ Setattr($$,"parms",$6.parms);
+ if (Len(scanner_ccode)) {
+ Setattr($$,"code",Copy(scanner_ccode));
+ }
+ }
+ if ($6.defarg) {
+ Setattr($$,"value",$6.defarg);
+ }
+ Setattr($$,"throws",$6.throws);
+ err = 0;
+ }
+ }
+ if (err) {
+ Swig_error(cparse_file,cparse_line,"Syntax error in input.\n");
+ }
+ }
+ ;
+
+/* ======================================================================
+ * C++ Support
+ * ====================================================================== */
+
+cpp_declaration : cpp_class_decl { $$ = $1; }
+ | cpp_forward_class_decl { $$ = $1; }
+ | cpp_template_decl { $$ = $1; }
+ | cpp_using_decl { $$ = $1; }
+ | cpp_namespace_decl { $$ = $1; }
+ | cpp_catch_decl { $$ = 0; }
+ ;
+
+cpp_class_decl :
+
+/* A simple class/struct/union definition */
+ storage_class cpptype idcolon inherit LBRACE {
+ List *bases = 0;
+ class_rename = make_name($3,0);
+ Classprefix = NewString($3);
+ /* Deal with inheritance */
+ if ($4) {
+ bases = make_inherit_list($3,$4);
+ }
+ if (SwigType_istemplate($3)) {
+ String *fbase, *tbase, *prefix;
+ prefix = SwigType_templateprefix($3);
+ if (Namespaceprefix) {
+ fbase = NewStringf("%s::%s", Namespaceprefix,$3);
+ tbase = NewStringf("%s::%s", Namespaceprefix, prefix);
+ } else {
+ fbase = Copy($3);
+ tbase = Copy(prefix);
+ }
+ rename_inherit(tbase,fbase);
+ Delete(fbase);
+ Delete(tbase);
+ Delete(prefix);
+ }
+ if (strcmp($2,"class") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else {
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ Swig_symbol_newscope();
+ Swig_symbol_setscopename($3);
+ if (bases) {
+ Node *s;
+ for (s = Firstitem(bases); s; s = Nextitem(bases)) {
+ Symtab *st = Getattr(s,"symtab");
+ if (st) {
+ Swig_symbol_inherit(st);
+ }
+ }
+ }
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ cparse_start_line = cparse_line;
+
+ /* If there are active template parameters, we need to make sure they are
+ placed in the class symbol table so we can catch shadows */
+
+ if (template_parameters) {
+ Parm *tp = template_parameters;
+ while(tp) {
+ Node *tn = new_node("templateparm");
+ Setattr(tn,"name",Getattr(tp,"name"));
+ Swig_symbol_cadd(Copy(Getattr(tp,"name")),tn);
+ tp = nextSibling(tp);
+ }
+ }
+ inclass = 1;
+ } cpp_members RBRACE cpp_opt_declarators {
+ Node *p;
+ SwigType *ty;
+ inclass = 0;
+ $$ = new_node("class");
+ Setline($$,cparse_start_line);
+ Setattr($$,"name",$3);
+ Setattr($$,"kind",$2);
+ Setattr($$,"baselist",$4);
+ Setattr($$,"allows_typedef","1");
+ /* Check for pure-abstract class */
+ Setattr($$,"abstract", pure_abstract($7));
+
+ /* This bit of code merges in a previously defined %extend directive (if any) */
+ if (extendhash) {
+ String *clsname = Swig_symbol_qualifiedscopename(0);
+ Node *am = Getattr(extendhash,clsname);
+ if (am) {
+ merge_extensions(am);
+ appendChild($$,am);
+ Delattr(extendhash,clsname);
+ }
+ Delete(clsname);
+ }
+ if (!classes) classes = NewHash();
+ Setattr(classes,Swig_symbol_qualifiedscopename(0),$$);
+
+
+ appendChild($$,$7);
+ p = $9;
+ if (p) {
+ set_nextSibling($$,p);
+ }
+
+ if (cparse_cplusplus) {
+ ty = NewString($3);
+ } else {
+ ty = NewStringf("%s %s", $2,$3);
+ }
+ while (p) {
+ Setattr(p,"storage",$1);
+ Setattr(p,"type",ty);
+ p = nextSibling(p);
+ }
+ /* Dump nested classes */
+ {
+ String *name = $3;
+ if ($9) {
+ SwigType *decltype = Getattr($9,"decl");
+ if (Cmp($1,"typedef") == 0) {
+ if (!decltype || !Len(decltype)) {
+ name = Getattr($9,"name");
+ Setattr($$,"tdname",Copy(name));
+
+ /* Use typedef name as class name */
+ if (class_rename && (Strcmp(class_rename,$3) == 0)) {
+ class_rename = NewString(name);
+ }
+ if (!Getattr(classes,name)) {
+ Setattr(classes,name,$$);
+ }
+ Setattr($$,"decl",decltype);
+ }
+ }
+ }
+ appendChild($$,dump_nested(Char(name)));
+ }
+ Setattr($$,"symtab",Swig_symbol_popscope());
+
+ yyrename = NewString(class_rename);
+ Classprefix = 0;
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols($$);
+ if ($9)
+ add_symbols($9);
+
+ }
+
+/* An unnamed struct, possibly with a typedef */
+
+ | storage_class cpptype LBRACE {
+ class_rename = make_name(0,0);
+ if (strcmp($2,"class") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else {
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ Swig_symbol_newscope();
+ cparse_start_line = cparse_line;
+ inclass = 1;
+ Classprefix = NewString("");
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ } cpp_members RBRACE declarator c_decl_tail {
+ String *unnamed;
+ Node *n, *p, *pp = 0;
+ Classprefix = 0;
+ inclass = 0;
+ unnamed = make_unnamed();
+ $$ = new_node("class");
+ Setline($$,cparse_start_line);
+ Setattr($$,"kind",$2);
+ Setattr($$,"storage",$1);
+ Setattr($$,"unnamed",unnamed);
+ Setattr($$,"allows_typedef","1");
+
+ /* Check for pure-abstract class */
+ Setattr($$,"abstract", pure_abstract($5));
+
+ n = new_node("cdecl");
+ Setattr(n,"name",$7.id);
+ Setattr(n,"unnamed",unnamed);
+ Setattr(n,"type",unnamed);
+ Setattr(n,"decl",$7.type);
+ Setattr(n,"parms",$7.parms);
+ Setattr(n,"storage",$1);
+ pp = n;
+ if ($8) {
+ set_nextSibling(n,$8);
+ p = $8;
+ while (p) {
+ pp = p;
+ Setattr(p,"unnamed",unnamed);
+ Setattr(p,"type",Copy(unnamed));
+ Setattr(p,"storage",$1);
+ p = nextSibling(p);
+ }
+ }
+ set_nextSibling($$,n);
+ {
+ /* If a proper typedef name was given, we'll use it to set the scope name */
+ String *name = 0;
+ if ($1 && (strcmp($1,"typedef") == 0)) {
+ if (!Len($7.type)) {
+ name = $7.id;
+ Setattr($$,"tdname",name);
+ Setattr($$,"name",name);
+ if (!class_rename) class_rename = NewString(name);
+ Swig_symbol_setscopename(name);
+
+ /* If a proper name given, we use that as the typedef, not unnamed */
+ Clear(unnamed);
+ Append(unnamed, name);
+
+ n = nextSibling(n);
+ set_nextSibling($$,n);
+
+ /* Check for previous extensions */
+ if (extendhash) {
+ String *clsname = Swig_symbol_qualifiedscopename(0);
+ Node *am = Getattr(extendhash,clsname);
+ if (am) {
+ /* Merge the extension into the symbol table */
+ merge_extensions(am);
+ appendChild($$,am);
+ Delattr(extendhash,clsname);
+ }
+ Delete(clsname);
+ }
+ if (!classes) classes = NewHash();
+ Setattr(classes,Swig_symbol_qualifiedscopename(0),$$);
+ } else {
+ Swig_symbol_setscopename((char*)"<unnamed>");
+ }
+ }
+ appendChild($$,$5);
+ appendChild($$,dump_nested(Char(name)));
+ }
+ /* Pop the scope */
+ Setattr($$,"symtab",Swig_symbol_popscope());
+ if (class_rename) {
+ yyrename = NewString(class_rename);
+ }
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols($$);
+ add_symbols(n);
+ }
+ ;
+
+cpp_opt_declarators : SEMI { $$ = 0; }
+ | declarator c_decl_tail {
+ $$ = new_node("cdecl");
+ Setattr($$,"name",$1.id);
+ Setattr($$,"decl",$1.type);
+ Setattr($$,"parms",$1.parms);
+ set_nextSibling($$,$2);
+ }
+ ;
+/* ------------------------------------------------------------
+ class Name;
+ ------------------------------------------------------------ */
+
+cpp_forward_class_decl : storage_class cpptype idcolon SEMI {
+ if ($1 && (Strcmp($1,"friend") == 0)) {
+ /* Ignore */
+ $$ = 0;
+ } else {
+ $$ = new_node("classforward");
+ Setattr($$,"kind",$2);
+ Setattr($$,"name",$3);
+ Setattr($$,"sym:weak", "1");
+ add_symbols($$);
+ }
+ }
+ ;
+
+/* ------------------------------------------------------------
+ template<...> decl
+ ------------------------------------------------------------ */
+
+cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_parameters = $3; } cpp_temp_possible {
+ String *tname = 0;
+ int error = 0;
+
+ template_parameters = 0;
+ $$ = $6;
+ if ($$) tname = Getattr($$,"name");
+
+ /* Check if the class is a template specialization */
+ if (($$) && (Strstr(tname,"<")) && (Strncmp(tname,"operator ",9) != 0)) {
+ /* If a specialization. Check if defined. */
+ Node *tempn = 0;
+ {
+ String *tbase = SwigType_templateprefix(tname);
+ tempn = Swig_symbol_clookup_local(tbase,0);
+ if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) {
+ Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase);
+ tempn = 0;
+ error = 1;
+ }
+ Delete(tbase);
+ }
+ Setattr($$,"specialization","1");
+ Setattr($$,"templatetype",nodeType($$));
+ set_nodeType($$,"template");
+ /* Template partial specialization */
+ if (tempn && ($3) && ($6)) {
+ List *tlist;
+ String *targs = SwigType_templateargs(tname);
+ tlist = SwigType_parmlist(targs);
+ /* Printf(stdout,"targs = '%s'\n", targs); */
+ if (!Getattr($$,"sym:weak")) {
+ Setattr($$,"sym:typename","1");
+ }
+ /* Patch the parameter list */
+ if (tempn) {
+ Parm *p,*p1;
+ ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
+ p = $3;
+ p1 = tp;
+ while (p && p1) {
+ String *pn = Getattr(p,"name");
+ if (pn) Setattr(p1,"name",pn);
+ pn = Getattr(p,"type");
+ if (pn) Setattr(p1,"type",pn);
+ p = nextSibling(p);
+ p1 = nextSibling(p1);
+ }
+ Setattr($$,"templateparms",tp);
+ } else {
+ Setattr($$,"templateparms",$3);
+ }
+ Delattr($$,"specialization");
+ Setattr($$,"partialspecialization","1");
+ /* Create a specialized name for matching */
+ {
+ Parm *p = $3;
+ String *fname = NewString(Getattr($$,"name"));
+ String *ffname = 0;
+
+ char tmp[32];
+ int i;
+ while (p) {
+ String *n = Getattr(p,"name");
+ if (!n) {
+ p = nextSibling(p);
+ continue;
+ }
+ for (i = 0; i < Len(tlist); i++) {
+ if (Strstr(Getitem(tlist,i),n)) {
+ sprintf(tmp,"$%d",i+1);
+ Replaceid(fname,n,tmp);
+ }
+ }
+ p = nextSibling(p);
+ }
+ /* Patch argument names with typedef */
+ {
+ SwigType *tt;
+ List *tparms = SwigType_parmlist(fname);
+ ffname = SwigType_templateprefix(fname);
+ Append(ffname,"<(");
+ for (tt = Firstitem(tparms); tt; ) {
+ SwigType *ttr = Swig_symbol_typedef_reduce(tt,0);
+ ttr = Swig_symbol_type_qualify(ttr,0);
+ Append(ffname,ttr);
+ tt = Nextitem(tparms);
+ if (tt) Putc(',',ffname);
+ }
+ Append(ffname,")>");
+ }
+ {
+ String *partials = Getattr(tempn,"partials");
+ if (!partials) {
+ partials = NewList();
+ Setattr(tempn,"partials",partials);
+ }
+ /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */
+ Append(partials,ffname);
+ }
+ Setattr($$,"partialargs",ffname);
+ Swig_symbol_cadd(ffname,$$);
+ }
+ Delete(tlist);
+ Delete(targs);
+ } else {
+ /* Need to resolve exact specialization name */
+ /* This needs to be rewritten */
+ List *tparms;
+ String *fname;
+ SwigType *tt;
+ fname = SwigType_templateprefix(tname);
+ tparms = SwigType_parmlist(tname);
+ Append(fname,"<(");
+ for (tt = Firstitem(tparms); tt; ) {
+ SwigType *ttr = Swig_symbol_typedef_reduce(tt,0);
+ ttr = Swig_symbol_type_qualify(ttr,0);
+ Append(fname,ttr);
+ tt = Nextitem(tparms);
+ if (tt) Putc(',',fname);
+ }
+ Append(fname,")>");
+ Swig_symbol_cadd(fname,$$);
+ }
+ } else if ($$) {
+ Setattr($$,"templatetype",nodeType($6));
+ set_nodeType($$,"template");
+ Setattr($$,"templateparms", $3);
+ if (!Getattr($$,"sym:weak")) {
+ Setattr($$,"sym:typename","1");
+ }
+ add_symbols($$);
+ /* We also place a fully parameterized version in the symbol table */
+ {
+ Parm *p;
+ String *fname = NewStringf("%s<(",Getattr($$,"name"));
+ p = $3;
+ while (p) {
+ String *n = Getattr(p,"name");
+ if (!n) n = Getattr(p,"type");
+ Printf(fname,"%s", n);
+ p = nextSibling(p);
+ if (p) Putc(',',fname);
+ }
+ Printf(fname,")>");
+ Swig_symbol_cadd(fname,$$);
+ }
+ }
+ if (error) $$ = 0;
+ }
+ ;
+
+cpp_temp_possible: c_decl {
+ $$ = $1;
+ }
+ | cpp_class_decl {
+ $$ = $1;
+ }
+ | cpp_constructor_decl {
+ $$ = $1;
+ }
+ | cpp_template_decl {
+ $$ = 0;
+ }
+ | cpp_forward_class_decl {
+ $$ = $1;
+ }
+ ;
+
+template_parms : rawparms {
+ /* Rip out the parameter names */
+ Parm *p = $1;
+ $$ = $1;
+
+ while (p) {
+ String *name = Getattr(p,"name");
+ if (!name) {
+ /* Hmmm. Maybe it's a 'class T' parameter */
+ char *type = Char(Getattr(p,"type"));
+ /* Template template parameter */
+ if (strncmp(type,"template<class> ",16) == 0) {
+ type += 16;
+ }
+ if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) {
+ char *t = strchr(type,' ');
+ Setattr(p,"name", t+1);
+ } else {
+ /*
+ Swig_error(cparse_file, cparse_line, "Missing template parameter name\n");
+ $$.rparms = 0;
+ $$.parms = 0;
+ break; */
+ }
+ }
+ p = nextSibling(p);
+ }
+ }
+ ;
+
+/* Namespace support */
+
+cpp_using_decl : USING idcolon SEMI {
+ $$ = new_node("using");
+ Setattr($$,"uname",$2);
+ Setattr($$,"name", Swig_scopename_last($2));
+ add_symbols($$);
+ }
+ | USING NAMESPACE idcolon SEMI {
+ Node *n = Swig_symbol_clookup($3,0);
+ if (!n) {
+ Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", $3);
+ $$ = 0;
+ } else {
+
+ while (Strcmp(nodeType(n),"using") == 0) {
+ n = Getattr(n,"node");
+ }
+ if (n) {
+ if (Strcmp(nodeType(n),"namespace") == 0) {
+ $$ = new_node("using");
+ Setattr($$,"node",n);
+ Setattr($$,"namespace", $3);
+ Swig_symbol_inherit(Getattr(n,"symtab"));
+ } else {
+ Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", $3);
+ $$ = 0;
+ }
+ } else {
+ $$ = 0;
+ }
+ }
+ }
+ ;
+
+cpp_namespace_decl : NAMESPACE idcolon LBRACE {
+ Hash *h;
+ $1 = Swig_symbol_current();
+ h = Swig_symbol_clookup($2,0);
+ if (h && (Strcmp(nodeType(h),"namespace") == 0)) {
+ if (Getattr(h,"alias")) {
+ h = Getattr(h,"namespace");
+ Swig_warning(WARN_PARSE_NAMESPACE_ALIAS, cparse_file, cparse_line, "Namespace alias '%s' not allowed here. Assuming '%s'\n",
+ $2, Getattr(h,"name"));
+ $2 = Getattr(h,"name");
+ }
+ Swig_symbol_setscope(Getattr(h,"symtab"));
+ } else {
+ Swig_symbol_newscope();
+ Swig_symbol_setscopename($2);
+ }
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ } interface RBRACE {
+ Node *n = $5;
+ set_nodeType(n,"namespace");
+ Setattr(n,"name",$2);
+ Setattr(n,"symtab", Swig_symbol_popscope());
+ Swig_symbol_setscope($1);
+ $$ = n;
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols($$);
+ }
+ | NAMESPACE LBRACE {
+ Hash *h;
+ $1 = Swig_symbol_current();
+ h = Swig_symbol_clookup("",0);
+ if (h && (Strcmp(nodeType(h),"namespace") == 0)) {
+ Swig_symbol_setscope(Getattr(h,"symtab"));
+ } else {
+ Swig_symbol_newscope();
+ Swig_symbol_setscopename("__unnamed__");
+ }
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ } interface RBRACE {
+ $$ = $4;
+ set_nodeType($$,"namespace");
+ Setattr($$,"unnamed","1");
+ Setattr($$,"symtab", Swig_symbol_popscope());
+ Swig_symbol_setscope($1);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols($$);
+ }
+ | NAMESPACE ID EQUAL idcolon SEMI {
+ /* Namespace alias */
+ Node *n;
+ $$ = new_node("namespace");
+ Setattr($$,"name",$2);
+ Setattr($$,"alias",$4);
+ n = Swig_symbol_clookup($4,0);
+ if (!n) {
+ Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", $4);
+ $$ = 0;
+ } else {
+ if (Strcmp(nodeType(n),"namespace") != 0) {
+ Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",$4);
+ $$ = 0;
+ } else {
+ while (Getattr(n,"alias")) {
+ n = Getattr(n,"namespace");
+ }
+ Setattr($$,"namespace",n);
+ add_symbols($$);
+ /* Set up a scope alias */
+ Swig_symbol_alias($2,Getattr(n,"symtab"));
+ }
+ }
+ }
+ ;
+
+cpp_members : cpp_member cpp_members {
+ $$ = $1;
+ if ($$) {
+ Node *p = $$;
+ Node *pp =0;
+ while (p) {
+ pp = p;
+ p = nextSibling(p);
+ }
+ set_nextSibling(pp,$2);
+ } else {
+ $$ = $2;
+ }
+ }
+ | EXTEND LBRACE {
+ if (cplus_mode != CPLUS_PUBLIC) {
+ Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n");
+ }
+ } cpp_members RBRACE cpp_members {
+ $$ = new_node("extend");
+ Swig_tag_nodes($4,"feature:extend",(char*) "1");
+ appendChild($$,$4);
+ set_nextSibling($$,$6);
+ }
+ | empty { $$ = 0;}
+ | error {
+ skip_decl();
+ {
+ static int last_error_line = -1;
+ if (last_error_line != cparse_line) {
+ Swig_error(cparse_file, cparse_line,"Syntax error in input.\n");
+ last_error_line = cparse_line;
+ }
+ }
+ } cpp_members {
+ $$ = $3;
+ }
+ ;
+
+/* ======================================================================
+ * C++ Class members
+ * ====================================================================== */
+
+/* A class member. May be data or a function. Static or virtual as well */
+
+cpp_member : c_declaration { $$ = $1; }
+ | cpp_constructor_decl {
+ $$ = $1;
+ add_symbols($$);
+ }
+ | cpp_destructor_decl { $$ = $1; }
+ | cpp_protection_decl { $$ = $1; }
+ | cpp_swig_directive { $$ = $1; }
+ | cpp_conversion_operator { $$ = $1; }
+ | cpp_forward_class_decl { $$ = $1; }
+ | cpp_nested { $$ = $1; }
+ | storage_class idcolon SEMI { $$ = 0; }
+ | cpp_using_decl { $$ = $1; }
+ | cpp_template_decl { $$ = $1; }
+ | cpp_catch_decl { $$ = 0; }
+ | template_directive { $$ = $1; }
+ | warn_directive { $$ = $1; }
+ | SEMI { $$ = 0; }
+ ;
+
+/* Possibly a constructor */
+/* Note: the use of 'type' is here to resolve a shift-reduce conflict. For example:
+ typedef Foo ();
+ typedef Foo (*ptr)();
+*/
+
+cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
+ if (Classprefix) {
+ SwigType *decl = NewString("");
+ $$ = new_node("constructor");
+
+ /* Since the parse performs type-corrections in template mode, we
+ have to undo the correction here. Ugh. */
+
+ /* Check for template names. If the class is a template
+ and the constructor is missing the template part, we
+ add it */
+ /* {
+ char *c = Strstr(Classprefix,"<");
+ if (c) {
+ if (!Strstr($2,"<")) {
+ Append($2,c);
+ }
+ }
+ }
+ */
+ Setattr($$,"name",$2);
+ Setattr($$,"parms",$4);
+ SwigType_add_function(decl,$4);
+ Setattr($$,"decl",decl);
+ Setattr($$,"throws",$6.throws);
+ if (Len(scanner_ccode)) {
+ Setattr($$,"code",Copy(scanner_ccode));
+ }
+ Setattr($$,"feature:new","1");
+ } else {
+ $$ = 0;
+ }
+ }
+ ;
+
+/* A destructor (hopefully) */
+
+cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
+ $$ = new_node("destructor");
+ Setattr($$,"name",NewStringf("~%s",$2));
+ if (Len(scanner_ccode)) {
+ Setattr($$,"code",Copy(scanner_ccode));
+ }
+ {
+ String *decl = NewString("");
+ SwigType_add_function(decl,$4);
+ Setattr($$,"decl",decl);
+ }
+ add_symbols($$);
+ }
+
+/* A virtual destructor */
+
+ | VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend {
+ $$ = new_node("destructor");
+ /* Check for template names. If the class is a template
+ and the constructor is missing the template part, we
+ add it */
+ {
+ char *c = Strstr(Classprefix,"<");
+ if (c) {
+ if (!Strstr($3,"<")) {
+ $3 = NewStringf("%s%s",$3,c);
+ }
+ }
+ }
+ Setattr($$,"storage","virtual");
+ Setattr($$,"name",NewStringf("~%s",$3));
+ if ($7.val) {
+ Setattr($$,"value","0");
+ }
+ if (Len(scanner_ccode)) {
+ Setattr($$,"code",Copy(scanner_ccode));
+ }
+ {
+ String *decl = NewString("");
+ SwigType_add_function(decl,$5);
+ Setattr($$,"decl",decl);
+ }
+
+ add_symbols($$);
+ }
+ ;
+
+
+/* C++ type conversion operator */
+cpp_conversion_operator : storage_class COPERATOR type pointer LPAREN parms RPAREN cpp_vend {
+ $$ = new_node("cdecl");
+ Setattr($$,"type",$3);
+ Setattr($$,"name",$2);
+
+ SwigType_add_function($4,$6);
+ if ($8.qualifier) {
+ SwigType_push($4,$8.qualifier);
+ }
+ Setattr($$,"decl",$4);
+ Setattr($$,"parms",$6);
+ Setattr($$,"conversion_operator","1");
+ add_symbols($$);
+ }
+ | storage_class COPERATOR type AND LPAREN parms RPAREN cpp_vend {
+ SwigType *decl;
+ $$ = new_node("cdecl");
+ Setattr($$,"type",$3);
+ Setattr($$,"name",$2);
+ decl = NewString("");
+ SwigType_add_reference(decl);
+ SwigType_add_function(decl,$6);
+ if ($8.qualifier) {
+ SwigType_push(decl,$8.qualifier);
+ }
+ Setattr($$,"decl",decl);
+ Setattr($$,"parms",$6);
+ Setattr($$,"conversion_operator","1");
+ add_symbols($$);
+ }
+
+ | storage_class COPERATOR type LPAREN parms RPAREN cpp_vend {
+ String *t = NewString("");
+ $$ = new_node("cdecl");
+ Setattr($$,"type",$3);
+ Setattr($$,"name",$2);
+ SwigType_add_function(t,$5);
+ if ($7.qualifier) {
+ SwigType_push(t,$7.qualifier);
+ }
+ Setattr($$,"decl",t);
+ Setattr($$,"parms",$5);
+ Setattr($$,"conversion_operator","1");
+ add_symbols($$);
+ }
+ ;
+
+/* isolated catch clause. */
+
+cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE {
+ skip_balanced('{','}');
+ $$ = 0;
+ }
+ ;
+
+/* public: */
+cpp_protection_decl : PUBLIC COLON {
+ $$ = new_node("access");
+ Setattr($$,"kind","public");
+ cplus_mode = CPLUS_PUBLIC;
+ }
+
+/* private: */
+ | PRIVATE COLON {
+ $$ = new_node("access");
+ Setattr($$,"kind","private");
+ cplus_mode = CPLUS_PRIVATE;
+ }
+
+/* protected: */
+
+ | PROTECTED COLON {
+ $$ = new_node("access");
+ Setattr($$,"kind","protected");
+ cplus_mode = CPLUS_PROTECTED;
+ }
+ ;
+
+
+/* ----------------------------------------------------------------------
+ Nested structure. This is a sick "hack". If we encounter
+ a nested structure, we're going to grab the text of its definition and
+ feed it back into the scanner. In the meantime, we need to grab
+ variable declaration information and generate the associated wrapper
+ code later. Yikes!
+
+ This really only works in a limited sense. Since we use the
+ code attached to the nested class to generate both C/C++ code,
+ it can't have any SWIG directives in it. It also needs to be parsable
+ by SWIG or this whole thing is going to puke.
+ ---------------------------------------------------------------------- */
+
+/* A struct sname { } id; declaration */
+
+cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
+ } nested_decl SEMI {
+ $$ = 0;
+ if (cplus_mode == CPLUS_PUBLIC) {
+ if ($6.id) {
+ if (strcmp($2,"class") == 0) {
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested classes not currently supported (ignored).\n");
+ /* Generate some code for a new class */
+ } else {
+ Nested *n = (Nested *) malloc(sizeof(Nested));
+ n->code = NewString("");
+ Printv(n->code, "typedef ", $2, " ",
+ Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL);
+
+ n->name = Swig_copy_string($6.id);
+ n->line = cparse_start_line;
+ n->type = NewString("");
+ n->kind = $2;
+ SwigType_push(n->type, $6.type);
+ n->next = 0;
+ add_nested(n);
+ }
+ } else {
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
+ }
+ }
+ }
+
+/* An unnamed nested structure definition */
+ | storage_class cpptype LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
+ } nested_decl SEMI {
+ $$ = 0;
+ if (cplus_mode == CPLUS_PUBLIC) {
+ if (strcmp($2,"class") == 0) {
+ Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
+ /* Generate some code for a new class */
+ } else if ($5.id) {
+ /* Generate some code for a new class */
+ Nested *n = (Nested *) malloc(sizeof(Nested));
+ n->code = NewString("");
+ Printv(n->code, "typedef ", $2, " " ,
+ Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL);
+ n->name = Swig_copy_string($5.id);
+ n->line = cparse_start_line;
+ n->type = NewString("");
+ n->kind = $2;
+ SwigType_push(n->type,$5.type);
+ n->next = 0;
+ add_nested(n);
+ } else {
+ Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
+ }
+ }
+ }
+ ;
+
+nested_decl : declarator { $$ = $1;}
+ | empty { $$.id = 0; }
+ ;
+
+
+/* These directives can be included inside a class definition */
+
+cpp_swig_directive: pragma_directive { $$ = $1; }
+
+/* A constant (includes #defines) inside a class */
+ | constant_directive { $$ = $1; }
+
+/* This is the new style rename */
+
+ | name_directive { $$ = $1; }
+
+/* rename directive */
+ | rename_directive { $$ = $1; }
+ | feature_directive { $$ = $1; }
+ | varargs_directive { $$ = $1; }
+ | insert_directive { $$ = $1; }
+ | typemap_directive { $$ = $1; }
+ | apply_directive { $$ = $1; }
+ | clear_directive { $$ = $1; }
+ | echo_directive { $$ = $1; }
+ ;
+
+cpp_end : cpp_const SEMI {
+ Clear(scanner_ccode);
+ }
+ | cpp_const LBRACE { skip_balanced('{','}'); }
+ ;
+
+cpp_vend : cpp_const SEMI {
+ Clear(scanner_ccode);
+ $$.val = 0;
+ $$.qualifier = $1.qualifier;
+ $$.bitfield = 0;
+ $$.throws = $1.throws;
+ }
+ | cpp_const EQUAL definetype SEMI {
+ Clear(scanner_ccode);
+ $$.val = $3.val;
+ $$.qualifier = $1.qualifier;
+ $$.bitfield = 0;
+ $$.throws = $1.throws;
+ }
+ | cpp_const LBRACE {
+ skip_balanced('{','}');
+ $$.val = 0;
+ $$.qualifier = $1.qualifier;
+ $$.bitfield = 0;
+ $$.throws = $1.throws;
+ }
+ ;
+
+
+/* ======================================================================
+ * PRIMITIVES
+ * ====================================================================== */
+
+storage_class : EXTERN { $$ = "extern"; }
+ | EXTERN string {
+ if (strcmp($2,"C") == 0) {
+ $$ = "externc";
+ } else {
+ Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\" (ignored).\n", $2);
+ $$ = 0;
+ }
+ }
+ | STATIC { $$ = "static"; }
+ | TYPEDEF { $$ = "typedef"; }
+ | VIRTUAL { $$ = "virtual"; }
+ | FRIEND { $$ = "friend"; }
+ | empty { $$ = 0; }
+ ;
+
+/* ------------------------------------------------------------------------------
+ Function parameter lists
+ ------------------------------------------------------------------------------ */
+
+parms : rawparms {
+ Parm *p;
+ $$ = $1;
+ p = $1;
+ while (p) {
+ Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
+ p = nextSibling(p);
+ }
+ }
+ ;
+
+rawparms : parm ptail {
+ if (1) {
+ set_nextSibling($1,$2);
+ $$ = $1;
+ } else {
+ $$ = $2;
+ }
+ }
+ | empty { $$ = 0; }
+ ;
+
+ptail : COMMA parm ptail {
+ set_nextSibling($2,$3);
+ $$ = $2;
+ }
+ | empty { $$ = 0; }
+ ;
+
+
+parm : rawtype parameter_declarator {
+ SwigType_push($1,$2.type);
+ $$ = NewParm($1,$2.id);
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ if ($2.defarg) {
+ Setattr($$,"value",$2.defarg);
+ }
+ }
+
+ | TEMPLATE LESSTHAN cpptype GREATERTHAN cpptype idcolon {
+ $$ = NewParm(NewStringf("template<class> %s %s", $5,$6), 0);
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ }
+ | PERIOD PERIOD PERIOD {
+ SwigType *t = NewString("v(...)");
+ $$ = NewParm(t, 0);
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ }
+ ;
+
+valparms : rawvalparms {
+ Parm *p;
+ $$ = $1;
+ p = $1;
+ while (p) {
+ if (Getattr(p,"type")) {
+ Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
+ }
+ p = nextSibling(p);
+ }
+ }
+ ;
+
+rawvalparms : valparm valptail {
+ if (1) {
+ set_nextSibling($1,$2);
+ $$ = $1;
+ } else {
+ $$ = $2;
+ }
+ }
+ | empty { $$ = 0; }
+ ;
+
+valptail : COMMA valparm valptail {
+ set_nextSibling($2,$3);
+ $$ = $2;
+ }
+ | empty { $$ = 0; }
+ ;
+
+
+valparm : parm {
+ $$ = $1;
+ {
+ /* We need to make a possible adjustment for integer parameters. */
+ SwigType *type;
+ Node *n = 0;
+
+ while (!n) {
+ type = Getattr($1,"type");
+ n = Swig_symbol_clookup(type,0); /* See if we can find a node that matches the typename */
+ if ((n) && (Strcmp(nodeType(n),"cdecl") == 0)) {
+ SwigType *decl = Getattr(n,"decl");
+ if (!SwigType_isfunction(decl)) {
+ String *value = Getattr(n,"value");
+ if (value) {
+ Setattr($1,"type",Copy(value));
+ n = 0;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ }
+ | exprnum {
+ $$ = NewParm(0,0);
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Setattr($$,"value",$1.val);
+ }
+ | STRING {
+ $$ = NewParm(0,0);
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Setattr($$,"value",NewString($1));
+ }
+ ;
+
+def_args : EQUAL definetype {
+ $$ = $2;
+ if ($2.type == T_ERROR) {
+ Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
+ $$.val = 0;
+ $$.rawval = 0;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ }
+ }
+ | EQUAL AND idcolon {
+ Node *n = Swig_symbol_clookup($3,0);
+ if (n) {
+ String *q = Swig_symbol_qualified(n);
+ if (Getattr(n,"access")) {
+ if (cplus_mode == CPLUS_PUBLIC) {
+ Swig_warning(WARN_PARSE_PRIVATE, cparse_file, cparse_line,"'%s' is private in this context.\n", $3);
+ Swig_warning(WARN_PARSE_BAD_DEFAULT, cparse_file, cparse_line,"Can't set default argument value (ignored)\n");
+ }
+ $$.val = 0;
+ } else {
+ if (q) {
+ $$.val = NewStringf("&%s::%s", q,Getattr(n,"name"));
+ Delete(q);
+ } else {
+ $$.val = NewStringf("&%s", $3);
+ }
+ }
+ } else {
+ $$.val = NewStringf("&%s",$3);
+ }
+ $$.rawval = 0;
+ $$.type = T_USER;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ }
+ | EQUAL LBRACE {
+ skip_balanced('{','}');
+ $$.val = 0;
+ $$.rawval = 0;
+ $$.type = T_INT;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ }
+ | COLON NUM_INT {
+ $$.val = 0;
+ $$.rawval = 0;
+ $$.type = 0;
+ $$.bitfield = $2.val;
+ $$.throws = 0;
+ }
+ | empty {
+ $$.val = 0;
+ $$.rawval = 0;
+ $$.type = T_INT;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ }
+ ;
+
+parameter_declarator : declarator def_args {
+ $$ = $1;
+ $$.defarg = $2.rawval ? $2.rawval : $2.val;
+ }
+ | abstract_declarator def_args {
+ $$ = $1;
+ $$.defarg = $2.rawval ? $2.rawval : $2.val;
+ }
+ | def_args {
+ $$.type = 0;
+ $$.id = 0;
+ $$.defarg = $1.rawval ? $1.rawval : $1.val;
+ }
+ ;
+
+typemap_parameter_declarator : declarator {
+ $$ = $1;
+ if (SwigType_isfunction($1.type)) {
+ Delete(SwigType_pop_function($1.type));
+ } else if (SwigType_isarray($1.type)) {
+ SwigType *ta = SwigType_pop_arrays($1.type);
+ if (SwigType_isfunction($1.type)) {
+ Delete(SwigType_pop_function($1.type));
+ } else {
+ $$.parms = 0;
+ }
+ SwigType_push($1.type,ta);
+ Delete(ta);
+ } else {
+ $$.parms = 0;
+ }
+ }
+ | abstract_declarator {
+ $$ = $1;
+ if (SwigType_isfunction($1.type)) {
+ Delete(SwigType_pop_function($1.type));
+ } else if (SwigType_isarray($1.type)) {
+ SwigType *ta = SwigType_pop_arrays($1.type);
+ if (SwigType_isfunction($1.type)) {
+ Delete(SwigType_pop_function($1.type));
+ } else {
+ $$.parms = 0;
+ }
+ SwigType_push($1.type,ta);
+ Delete(ta);
+ } else {
+ $$.parms = 0;
+ }
+ }
+ | empty {
+ $$.type = 0;
+ $$.id = 0;
+ $$.parms = 0;
+ }
+ ;
+
+
+declarator : pointer notso_direct_declarator {
+ $$ = $2;
+ if ($$.type) {
+ SwigType_push($1,$$.type);
+ Delete($$.type);
+ }
+ $$.type = $1;
+ }
+ | pointer AND notso_direct_declarator {
+ $$ = $3;
+ SwigType_add_reference($1);
+ if ($$.type) {
+ SwigType_push($1,$$.type);
+ Delete($$.type);
+ }
+ $$.type = $1;
+ }
+ | direct_declarator {
+ $$ = $1;
+ if (!$$.type) $$.type = NewString("");
+ }
+ | AND notso_direct_declarator {
+ $$ = $2;
+ $$.type = NewString("");
+ SwigType_add_reference($$.type);
+ if ($2.type) {
+ SwigType_push($$.type,$2.type);
+ Delete($2.type);
+ }
+ }
+ | idcolon DSTAR notso_direct_declarator {
+ SwigType *t = NewString("");
+
+ $$ = $3;
+ SwigType_add_memberpointer(t,$1);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | pointer idcolon DSTAR notso_direct_declarator {
+ SwigType *t = NewString("");
+ $$ = $4;
+ SwigType_add_memberpointer(t,$2);
+ SwigType_push($1,t);
+ if ($$.type) {
+ SwigType_push($1,$$.type);
+ Delete($$.type);
+ }
+ $$.type = $1;
+ Delete(t);
+ }
+ | pointer idcolon DSTAR AND notso_direct_declarator {
+ $$ = $5;
+ SwigType_add_memberpointer($1,$2);
+ SwigType_add_reference($1);
+ if ($$.type) {
+ SwigType_push($1,$$.type);
+ Delete($$.type);
+ }
+ $$.type = $1;
+ }
+ | idcolon DSTAR AND notso_direct_declarator {
+ SwigType *t = NewString("");
+ $$ = $4;
+ SwigType_add_memberpointer(t,$1);
+ SwigType_add_reference(t);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ ;
+
+notso_direct_declarator : idcolon {
+ /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */
+ $$.id = Char($1);
+ $$.type = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ }
+
+ | NOT idcolon {
+ $$.id = Char(NewStringf("~%s",$2));
+ $$.type = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ }
+
+/* This generate a shift-reduce conflict with constructors */
+ | LPAREN idcolon RPAREN {
+ $$.id = Char($2);
+ $$.type = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ }
+
+/* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */
+ | LPAREN pointer notso_direct_declarator RPAREN {
+ $$ = $3;
+ if ($$.type) {
+ SwigType_push($2,$$.type);
+ Delete($$.type);
+ }
+ $$.type = $2;
+ }
+ | LPAREN idcolon DSTAR notso_direct_declarator RPAREN {
+ SwigType *t;
+ $$ = $4;
+ t = NewString("");
+ SwigType_add_memberpointer(t,$2);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | notso_direct_declarator LBRACKET RBRACKET {
+ SwigType *t;
+ $$ = $1;
+ t = NewString("");
+ SwigType_add_array(t,(char*)"");
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | notso_direct_declarator LBRACKET expr RBRACKET {
+ SwigType *t;
+ $$ = $1;
+ t = NewString("");
+ SwigType_add_array(t,$3.val);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | notso_direct_declarator LPAREN parms RPAREN {
+ SwigType *t;
+ $$ = $1;
+ t = NewString("");
+ SwigType_add_function(t,$3);
+ if (!$$.have_parms) {
+ $$.parms = $3;
+ $$.have_parms = 1;
+ }
+ if (!$$.type) {
+ $$.type = t;
+ } else {
+ SwigType_push(t, $$.type);
+ Delete($$.type);
+ $$.type = t;
+ }
+ }
+ ;
+
+direct_declarator : idcolon {
+ /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */
+ $$.id = Char($1);
+ $$.type = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ }
+
+ | NOT idcolon {
+ $$.id = Char(NewStringf("~%s",$2));
+ $$.type = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ }
+
+/* This generate a shift-reduce conflict with constructors */
+/*
+ | LPAREN idcolon RPAREN {
+ $$.id = Char($2);
+ $$.type = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ }
+*/
+/* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */
+ | LPAREN pointer direct_declarator RPAREN {
+ $$ = $3;
+ if ($$.type) {
+ SwigType_push($2,$$.type);
+ Delete($$.type);
+ }
+ $$.type = $2;
+ }
+ | LPAREN idcolon DSTAR direct_declarator RPAREN {
+ SwigType *t;
+ $$ = $4;
+ t = NewString("");
+ SwigType_add_memberpointer(t,$2);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | direct_declarator LBRACKET RBRACKET {
+ SwigType *t;
+ $$ = $1;
+ t = NewString("");
+ SwigType_add_array(t,(char*)"");
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | direct_declarator LBRACKET expr RBRACKET {
+ SwigType *t;
+ $$ = $1;
+ t = NewString("");
+ SwigType_add_array(t,$3.val);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | direct_declarator LPAREN parms RPAREN {
+ SwigType *t;
+ $$ = $1;
+ t = NewString("");
+ SwigType_add_function(t,$3);
+ if (!$$.have_parms) {
+ $$.parms = $3;
+ $$.have_parms = 1;
+ }
+ if (!$$.type) {
+ $$.type = t;
+ } else {
+ SwigType_push(t, $$.type);
+ Delete($$.type);
+ $$.type = t;
+ }
+ }
+ ;
+
+abstract_declarator : pointer {
+ $$.type = $1;
+ $$.id = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ }
+ | pointer direct_abstract_declarator {
+ $$ = $2;
+ SwigType_push($1,$2.type);
+ $$.type = $1;
+ Delete($2.type);
+ }
+ | pointer AND {
+ $$.type = $1;
+ SwigType_add_reference($$.type);
+ $$.id = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ }
+ | pointer AND direct_abstract_declarator {
+ $$ = $3;
+ SwigType_add_reference($1);
+ if ($$.type) {
+ SwigType_push($1,$$.type);
+ Delete($$.type);
+ }
+ $$.type = $1;
+ }
+ | direct_abstract_declarator {
+ $$ = $1;
+ }
+ | AND direct_abstract_declarator {
+ $$ = $2;
+ $$.type = NewString("");
+ SwigType_add_reference($$.type);
+ if ($2.type) {
+ SwigType_push($$.type,$2.type);
+ Delete($2.type);
+ }
+ }
+ | AND {
+ $$.id = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ $$.type = NewString("");
+ SwigType_add_reference($$.type);
+ }
+ | idcolon DSTAR {
+ $$.type = NewString("");
+ SwigType_add_memberpointer($$.type,$1);
+ $$.id = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ }
+ | pointer idcolon DSTAR {
+ SwigType *t = NewString("");
+ $$.type = $1;
+ $$.id = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ SwigType_add_memberpointer(t,$2);
+ SwigType_push($$.type,t);
+ Delete(t);
+ }
+ | pointer idcolon DSTAR direct_abstract_declarator {
+ $$ = $4;
+ SwigType_add_memberpointer($1,$2);
+ if ($$.type) {
+ SwigType_push($1,$$.type);
+ Delete($$.type);
+ }
+ $$.type = $1;
+ }
+ ;
+
+direct_abstract_declarator : direct_abstract_declarator LBRACKET RBRACKET {
+ SwigType *t;
+ $$ = $1;
+ t = NewString("");
+ SwigType_add_array(t,(char*)"");
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | direct_abstract_declarator LBRACKET expr RBRACKET {
+ SwigType *t;
+ $$ = $1;
+ t = NewString("");
+ SwigType_add_array(t,$3.val);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | LBRACKET RBRACKET {
+ $$.type = NewString("");
+ $$.id = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ SwigType_add_array($$.type,(char*)"");
+ }
+ | LBRACKET expr RBRACKET {
+ $$.type = NewString("");
+ $$.id = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ SwigType_add_array($$.type,$2.val);
+ }
+ | LPAREN abstract_declarator RPAREN {
+ $$ = $2;
+ }
+ | direct_abstract_declarator LPAREN parms RPAREN {
+ SwigType *t;
+ $$ = $1;
+ t = NewString("");
+ SwigType_add_function(t,$3);
+ if (!$$.type) {
+ $$.type = t;
+ } else {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ $$.type = t;
+ }
+ if (!$$.have_parms) {
+ $$.parms = $3;
+ $$.have_parms = 1;
+ }
+ }
+ | LPAREN parms RPAREN {
+ $$.type = NewString("");
+ SwigType_add_function($$.type,$2);
+ $$.parms = $2;
+ $$.have_parms = 1;
+ $$.id = 0;
+ }
+ ;
+
+
+pointer : STAR type_qualifier pointer {
+ $$ = NewString("");
+ SwigType_add_pointer($$);
+ SwigType_push($$,$2);
+ SwigType_push($$,$3);
+ Delete($3);
+ }
+ | STAR pointer {
+ $$ = NewString("");
+ SwigType_add_pointer($$);
+ SwigType_push($$,$2);
+ Delete($2);
+ }
+ | STAR type_qualifier {
+ $$ = NewString("");
+ SwigType_add_pointer($$);
+ SwigType_push($$,$2);
+ }
+ | STAR {
+ $$ = NewString("");
+ SwigType_add_pointer($$);
+ }
+ ;
+
+type_qualifier : type_qualifier_raw {
+ $$ = NewString("");
+ SwigType_add_qualifier($$,$1);
+ }
+ | type_qualifier_raw type_qualifier {
+ $$ = $2;
+ SwigType_add_qualifier($$,$1);
+ }
+ ;
+
+type_qualifier_raw : CONST { $$ = "const"; }
+ | VOLATILE { $$ = "volatile"; }
+ ;
+
+/* Data type must be a built in type or an identifier for user-defined types
+ This type can be preceded by a modifier. */
+
+type : rawtype {
+ $$ = $1;
+ Replace($$,"typename ","", DOH_REPLACE_ANY);
+ }
+ ;
+
+rawtype : type_qualifier type_right {
+ $$ = $2;
+ SwigType_push($$,$1);
+ }
+ | type_right { $$ = $1; }
+ ;
+
+type_right : primitive_type { $$ = $1;
+ /* Printf(stdout,"primitive = '%s'\n", $$);*/
+ }
+ | TYPE_BOOL { $$ = $1; }
+ | TYPE_VOID { $$ = $1; }
+ | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }
+ | ENUM idcolon { $$ = NewStringf("enum %s", $2); }
+ | TYPE_RAW { $$ = $1; }
+ | type_right type_qualifier {
+ $$ = $1;
+ SwigType_push($$,$2);
+ }
+
+ | idcolon {
+ $$ = $1;
+ }
+ | cpptype idcolon {
+ $$ = NewStringf("%s %s", $1, $2);
+ }
+ ;
+
+primitive_type : primitive_type_list {
+ if (!$1.type) $1.type = NewString("int");
+ if ($1.us) {
+ $$ = NewStringf("%s %s", $1.us, $1.type);
+ Delete($1.us);
+ Delete($1.type);
+ } else {
+ $$ = $1.type;
+ }
+ if (Cmp($$,"signed int") == 0) {
+ Delete($$);
+ $$ = NewString("int");
+ } else if (Cmp($$,"signed long") == 0) {
+ Delete($$);
+ $$ = NewString("long");
+ } else if (Cmp($$,"signed short") == 0) {
+ Delete($$);
+ $$ = NewString("short");
+ } else if (Cmp($$,"signed long long") == 0) {
+ Delete($$);
+ $$ = NewString("long long");
+ }
+ }
+ ;
+
+primitive_type_list : type_specifier {
+ $$ = $1;
+ }
+ | type_specifier primitive_type_list {
+ if ($1.us && $2.us) {
+ Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $2.us);
+ }
+ $$ = $2;
+ if ($1.us) $$.us = $1.us;
+ if ($1.type) {
+ if (!$2.type) $$.type = $1.type;
+ else {
+ int err = 0;
+ if ((Cmp($1.type,"long") == 0)) {
+ if ((Cmp($2.type,"long") == 0) || (Cmp($2.type,"double") == 0)) {
+ $$.type = NewStringf("long %s", $2.type);
+ } else if (Cmp($2.type,"int") == 0) {
+ $$.type = $1.type;
+ } else {
+ err = 1;
+ }
+ } else if ((Cmp($1.type,"short")) == 0) {
+ if (Cmp($2.type,"int") == 0) {
+ $$.type = $1.type;
+ } else {
+ err = 1;
+ }
+ } else if (Cmp($1.type,"int") == 0) {
+ $$.type = $2.type;
+ } else if (Cmp($1.type,"double") == 0) {
+ if (Cmp($2.type,"long") == 0) {
+ $$.type = NewString("long double");
+ } else {
+ err = 1;
+ }
+ }
+ if (err) {
+ Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $1.type);
+ }
+ }
+ }
+ }
+ ;
+
+
+type_specifier : TYPE_INT {
+ $$.type = NewString("int");
+ $$.us = 0;
+ }
+ | TYPE_SHORT {
+ $$.type = NewString("short");
+ $$.us = 0;
+ }
+ | TYPE_LONG {
+ $$.type = NewString("long");
+ $$.us = 0;
+ }
+ | TYPE_CHAR {
+ $$.type = NewString("char");
+ $$.us = 0;
+ }
+ | TYPE_FLOAT {
+ $$.type = NewString("float");
+ $$.us = 0;
+ }
+ | TYPE_DOUBLE {
+ $$.type = NewString("double");
+ $$.us = 0;
+ }
+ | TYPE_SIGNED {
+ $$.us = NewString("signed");
+ $$.type = 0;
+ }
+ | TYPE_UNSIGNED {
+ $$.us = NewString("unsigned");
+ $$.type = 0;
+ }
+ ;
+
+definetype : { /* scanner_check_typedef(); */ } expr {
+ $$ = $2;
+ $$.rawval = 0;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ scanner_ignore_typedef();
+ }
+ | string {
+ $$.val = NewString($1);
+ $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
+ $$.type = T_STRING;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ }
+ | CHARCONST {
+ $$.val = NewString($1);
+ if (Len($$.val)) {
+ $$.rawval = NewStringf("\'%(escape)s\'",$$.val);
+ } else {
+ $$.rawval = NewString("\'\\0'");
+ }
+ $$.type = T_CHAR;
+ $$.bitfield = 0;
+ $$.throws;
+ }
+ ;
+
+/* Some stuff for handling enums */
+
+ename : ID { $$ = $1; }
+ | empty { $$ = (char *) 0;}
+ ;
+
+/* SWIG enum list */
+
+enumlist : enumlist COMMA edecl {
+ Node *n = Getattr($1,"_last");
+ if (!n) {
+ set_nextSibling($1,$3);
+ Setattr($1,"_last",$3);
+ } else {
+ set_nextSibling(n,$3);
+ Setattr($1,"_last",$3);
+ }
+ $$ = $1;
+ }
+ | edecl { $$ = $1; }
+ ;
+
+edecl : ID {
+ $$ = new_node("enumitem");
+ Setattr($$,"name",$1);
+ Setattr($$,"type",NewSwigType(T_INT));
+ Setattr($$,"feature:immutable","1");
+ }
+ | ID EQUAL etype {
+ $$ = new_node("enumitem");
+ Setattr($$,"name",$1);
+ Setattr($$,"enumvalue", $3.val);
+ if ($3.type == T_CHAR) {
+ Setattr($$,"value",$3.val);
+ Setattr($$,"type",NewSwigType(T_CHAR));
+ } else {
+ Setattr($$,"value",$1);
+ Setattr($$,"type",NewSwigType(T_INT));
+ }
+ Setattr($$,"feature:immutable","1");
+ }
+ | empty { $$ = 0; }
+ ;
+
+etype : expr {
+ $$ = $1;
+ if (($$.type != T_INT) && ($$.type != T_UINT) &&
+ ($$.type != T_LONG) && ($$.type != T_ULONG) &&
+ ($$.type != T_SHORT) && ($$.type != T_USHORT) &&
+ ($$.type != T_SCHAR) && ($$.type != T_UCHAR)) {
+ Swig_error(cparse_file,cparse_line,"Type error. Expecting an int\n");
+ }
+ }
+ | CHARCONST {
+ $$.val = NewString($1);
+ $$.type = T_INT;
+ }
+ ;
+
+/* Arithmetic expressions. Used for constants and other cool stuff.
+ Really, we're not doing anything except string concatenation, but
+ this does allow us to parse many constant declarations.
+ */
+
+expr : exprnum { $$ = $1; }
+ | SIZEOF LPAREN type parameter_declarator RPAREN {
+ SwigType_push($3,$4.type);
+ $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0));
+ $$.type = T_INT;
+ }
+ | exprcompound { $$ = $1; }
+ | type {
+ Node *n;
+ $$.val = $1;
+ $$.type = T_INT;
+ /* Check if value is in scope */
+ n = Swig_symbol_clookup($1,0);
+ if (n) {
+ if (Getattr(n,"access")) {
+ if (cplus_mode == CPLUS_PUBLIC) {
+ Swig_warning(WARN_PARSE_PRIVATE,cparse_file, cparse_line, "'%s' is private in this context.\n", $1);
+ $$.type = T_ERROR;
+ }
+
+ }
+ }
+ }
+
+/* grouping */
+ | LPAREN expr RPAREN %prec CAST {
+ $$.val = NewStringf("(%s)",$2.val);
+ $$.type = $2.type;
+ }
+
+/* A few common casting operations */
+
+ | LPAREN expr RPAREN expr %prec CAST {
+ $$ = $4;
+ $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $4.val);
+ }
+ | LPAREN expr pointer RPAREN expr %prec CAST {
+ $$ = $5;
+ SwigType_push($2.val,$3);
+ $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
+ }
+ | LPAREN expr AND RPAREN expr %prec CAST {
+ $$ = $5;
+ SwigType_add_reference($2.val);
+ $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
+ }
+ | LPAREN expr pointer AND RPAREN expr %prec CAST {
+ $$ = $6;
+ SwigType_push($2.val,$3);
+ SwigType_add_reference($2.val);
+ $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val);
+ }
+ ;
+
+exprnum : NUM_INT { $$ = $1; }
+ | NUM_FLOAT { $$ = $1; }
+ | NUM_UNSIGNED { $$ = $1; }
+ | NUM_LONG { $$ = $1; }
+ | NUM_ULONG { $$ = $1; }
+ | NUM_LONGLONG { $$ = $1; }
+ | NUM_ULONGLONG { $$ = $1; }
+ ;
+
+exprcompound : expr PLUS expr {
+ $$.val = NewStringf("%s+%s",$1.val,$3.val);
+ $$.type = promote($1.type,$3.type);
+ }
+ | expr MINUS expr {
+ $$.val = NewStringf("%s-%s",$1.val,$3.val);
+ $$.type = promote($1.type,$3.type);
+ }
+ | expr STAR expr {
+ $$.val = NewStringf("%s*%s",$1.val,$3.val);
+ $$.type = promote($1.type,$3.type);
+ }
+ | expr SLASH expr {
+ $$.val = NewStringf("%s/%s",$1.val,$3.val);
+ $$.type = promote($1.type,$3.type);
+ }
+ | expr AND expr {
+ $$.val = NewStringf("%s&%s",$1.val,$3.val);
+ $$.type = promote($1.type,$3.type);
+ }
+ | expr OR expr {
+ $$.val = NewStringf("%s|%s",$1.val,$3.val);
+ $$.type = promote($1.type,$3.type);
+ }
+ | expr XOR expr {
+ $$.val = NewStringf("%s^%s",$1.val,$3.val);
+ $$.type = promote($1.type,$3.type);
+ }
+ | expr LSHIFT expr {
+ $$.val = NewStringf("%s<<%s",$1.val,$3.val);
+ $$.type = promote($1.type,$3.type);
+ }
+ | expr RSHIFT expr {
+ $$.val = NewStringf("%s>>%s",$1.val,$3.val);
+ $$.type = promote($1.type,$3.type);
+ }
+ | expr LAND expr {
+ $$.val = NewStringf("%s&&%s",$1.val,$3.val);
+ $$.type = T_INT;
+ }
+ | expr LOR expr {
+ $$.val = NewStringf("%s||%s",$1.val,$3.val);
+ $$.type = T_INT;
+ }
+ | MINUS expr %prec UMINUS {
+ $$.val = NewStringf("-%s",$2.val);
+ $$.type = $2.type;
+ }
+ | NOT expr {
+ $$.val = NewStringf("~%s",$2.val);
+ $$.type = $2.type;
+ }
+ | LNOT expr {
+ $$.val = NewStringf("!%s",$2.val);
+ $$.type = T_INT;
+ }
+ | type LPAREN {
+ skip_balanced('(',')');
+ if (SwigType_istemplate($1)) {
+ $1 = SwigType_namestr($1);
+ }
+ $$.val = NewStringf("%s%s",$1,scanner_ccode);
+ Clear(scanner_ccode);
+ $$.type = T_INT;
+ }
+ ;
+
+inherit : raw_inherit {
+ $$ = $1;
+ }
+ ;
+
+raw_inherit : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list = 0; }
+ | empty { $$ = 0; }
+ ;
+
+base_list : base_specifier {
+ $$ = NewList();
+ if ($1) Append($$,$1);
+ }
+
+ | base_list COMMA base_specifier {
+ $$ = $1;
+ if ($3) Append($$,$3);
+ }
+ ;
+
+base_specifier : opt_virtual idcolon {
+ if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) {
+ Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file, cparse_line,"No access specifier given for base class %s (ignored).\n",$2);
+ $$ = (char *) 0;
+ } else {
+ $$ = $2;
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ }
+ }
+ | opt_virtual access_specifier opt_virtual idcolon {
+ $$ = 0;
+ if (strcmp($2,"public") == 0) {
+ $$ = $4;
+ Setfile($$, cparse_file);
+ Setline($$, cparse_line);
+ } else {
+ Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file, cparse_line, "%s inheritance ignored.\n", $2);
+ }
+ }
+ ;
+
+access_specifier : PUBLIC { $$ = (char*)"public"; }
+ | PRIVATE { $$ = (char*)"private"; }
+ | PROTECTED { $$ = (char*)"protected"; }
+ ;
+
+
+cpptype : CLASS {
+ $$ = (char*)"class";
+ if (!inherit_list) last_cpptype = $$;
+ }
+ | STRUCT {
+ $$ = (char*)"struct";
+ if (!inherit_list) last_cpptype = $$;
+ }
+ | UNION {
+ $$ = (char*)"union";
+ if (!inherit_list) last_cpptype = $$;
+ }
+ | TYPENAME {
+ $$ = (char *)"typename";
+ if (!inherit_list) last_cpptype = $$;
+ }
+ ;
+
+opt_virtual : VIRTUAL
+ | empty
+ ;
+
+cpp_const : type_qualifier {
+ $$.qualifier = $1;
+ $$.throws = 0;
+ }
+ | THROW LPAREN parms RPAREN {
+ $$.qualifier = 0;
+ $$.throws = $3;
+ }
+ | type_qualifier THROW LPAREN parms RPAREN {
+ $$.qualifier = $1;
+ $$.throws = $4;
+ }
+ | empty {
+ $$.qualifier = 0;
+ $$.throws = 0;
+ }
+ ;
+
+ctor_end : cpp_const ctor_initializer SEMI {
+ Clear(scanner_ccode);
+ $$.have_parms = 0;
+ $$.defarg = 0;
+ $$.throws = $1.throws;
+ }
+ | cpp_const ctor_initializer LBRACE {
+ skip_balanced('{','}');
+ $$.have_parms = 0;
+ $$.defarg = 0;
+ $$.throws = $1.throws;
+ }
+ | LPAREN parms RPAREN SEMI {
+ Clear(scanner_ccode);
+ $$.parms = $2;
+ $$.have_parms = 1;
+ $$.defarg = 0;
+ $$.throws = 0;
+ }
+ | LPAREN parms RPAREN LBRACE {
+ skip_balanced('{','}');
+ $$.parms = $2;
+ $$.have_parms = 1;
+ $$.defarg = 0;
+ $$.throws = 0;
+ }
+ | EQUAL definetype SEMI {
+ $$.have_parms = 0;
+ $$.defarg = $2.val;
+ $$.throws = 0;
+ }
+ ;
+
+ctor_initializer : COLON mem_initializer_list
+ | empty
+ ;
+
+mem_initializer_list : mem_initializer
+ | mem_initializer_list COMMA mem_initializer
+ ;
+
+mem_initializer : idcolon LPAREN {
+ skip_balanced('(',')');
+ Clear(scanner_ccode);
+ }
+ ;
+
+template_decl : LESSTHAN valparms GREATERTHAN {
+ String *s = NewString("");
+ SwigType_add_template(s,$2);
+ $$ = Char(s);
+ }
+ | empty { $$ = (char*)""; }
+ ;
+
+idstring : ID { $$ = $1; }
+ | string { $$ = $1; }
+ ;
+
+idstringopt : idstring { $$ = $1; }
+ | empty { $$ = 0; }
+ ;
+
+idcolon : idtemplate idcolontail {
+ $$ = 0;
+ if (!$$) $$ = NewStringf("%s%s", $1,$2);
+ Delete($2);
+ }
+ | NONID DCOLON idtemplate idcolontail {
+ $$ = NewStringf("::%s%s",$3,$4);
+ Delete($4);
+ }
+ | idtemplate {
+ $$ = NewString($1);
+ }
+ | NONID DCOLON idtemplate {
+ $$ = NewStringf("::%s",$3);
+ }
+ | OPERATOR {
+ $$ = NewString($1);
+ }
+ | NONID DCOLON OPERATOR {
+ $$ = NewStringf("::%s",$3);
+ }
+ ;
+
+idcolontail : DCOLON idtemplate idcolontail {
+ $$ = NewStringf("::%s%s",$2,$3);
+ Delete($3);
+ }
+ | DCOLON idtemplate {
+ $$ = NewStringf("::%s",$2);
+ }
+ | DCOLON OPERATOR {
+ $$ = NewStringf("::%s",$2);
+ }
+ | DCNOT idtemplate {
+ $$ = NewStringf("::~%s",$2);
+ }
+ ;
+
+
+idtemplate : ID template_decl {
+ $$ = NewStringf("%s%s",$1,$2);
+ scanner_last_id(1);
+ }
+ ;
+
+/* Identifier, but no templates */
+idcolonnt : ID idcolontailnt {
+ $$ = 0;
+ if (!$$) $$ = NewStringf("%s%s", $1,$2);
+ Delete($2);
+ }
+ | NONID DCOLON ID idcolontailnt {
+ $$ = NewStringf("::%s%s",$3,$4);
+ Delete($4);
+ }
+ | ID {
+ $$ = NewString($1);
+ }
+ | NONID DCOLON ID {
+ $$ = NewStringf("::%s",$3);
+ }
+ | OPERATOR {
+ $$ = NewString($1);
+ }
+ | NONID DCOLON OPERATOR {
+ $$ = NewStringf("::%s",$3);
+ }
+ ;
+
+idcolontailnt : DCOLON ID idcolontailnt {
+ $$ = NewStringf("::%s%s",$2,$3);
+ Delete($3);
+ }
+ | DCOLON ID {
+ $$ = NewStringf("::%s",$2);
+ }
+ | DCOLON OPERATOR {
+ $$ = NewStringf("::%s",$2);
+ }
+ | DCNOT ID {
+ $$ = NewStringf("::~%s",$2);
+ }
+ ;
+
+/* Concatenated strings */
+string : string STRING {
+ $$ = (char *) malloc(strlen($1)+strlen($2)+1);
+ strcpy($$,$1);
+ strcat($$,$2);
+ }
+ | STRING { $$ = $1;}
+ ;
+
+stringbrace : string {
+ $$ = NewString($1);
+ }
+ | LBRACE {
+ skip_balanced('{','}');
+ $$ = NewString(scanner_ccode);
+ }
+ | HBLOCK {
+ $$ = $1;
+ }
+ ;
+
+options : LPAREN kwargs RPAREN {
+ Hash *n;
+ $$ = NewHash();
+ n = $2;
+ while(n) {
+ String *name, *value;
+ name = Getattr(n,"name");
+ value = Getattr(n,"value");
+ if (!value) value = (String *) "1";
+ Setattr($$,name, value);
+ n = nextSibling(n);
+ }
+ }
+ | empty { $$ = 0; };
+
+
+/* Keyword arguments */
+kwargs : idstring EQUAL stringnum {
+ $$ = NewHash();
+ Setattr($$,"name",$1);
+ Setattr($$,"value",$3);
+ }
+ | idstring EQUAL stringnum COMMA kwargs {
+ $$ = NewHash();
+ Setattr($$,"name",$1);
+ Setattr($$,"value",$3);
+ set_nextSibling($$,$5);
+ }
+ | idstring {
+ $$ = NewHash();
+ Setattr($$,"name",$1);
+ }
+ | idstring COMMA kwargs {
+ $$ = NewHash();
+ Setattr($$,"name",$1);
+ set_nextSibling($$,$3);
+ }
+ ;
+
+stringnum : string {
+ $$ = $1;
+ }
+ | exprnum {
+ $$ = $1.val;
+ }
+ ;
+
+empty : ;
+
+%%
+
+/* Called by the parser (yyparse) when an error is found.*/
+void yyerror (const char *e) {
+}
+
+SwigType *Swig_cparse_type(String *s) {
+ String *ns;
+ extern void scanner_file(File *);
+ extern int yyparse();
+ extern void scanner_next_token(int);
+ ns = NewStringf("%s;",s);
+ Seek(ns,0,SEEK_SET);
+ scanner_file(ns);
+ top = 0;
+ scanner_next_token(PARSETYPE);
+ yyparse();
+ /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
+ return top;
+}
+
+
+
+
+
+
+
+
+
diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c
new file mode 100644
index 000000000..b9b7fb4cd
--- /dev/null
+++ b/Source/CParse/templ.c
@@ -0,0 +1,495 @@
+/* -----------------------------------------------------------------------------
+ * templ.c
+ *
+ * Expands a template into a specialized version.
+ *
+ * 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_templ_c[] = "$Header$";
+
+#include "swig.h"
+#include "cparse.h"
+
+static int template_debug = 0;
+
+static void add_parms(ParmList *p, List *patchlist, List *typelist) {
+ while (p) {
+ SwigType *ty = Getattr(p,"type");
+ SwigType *val = Getattr(p,"value");
+ Append(typelist,ty);
+ Append(patchlist,val);
+ p = nextSibling(p);
+ }
+}
+
+void Swig_cparse_debug_templates(int x) {
+ template_debug = x;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cparse_template_expand()
+ *
+ * Expands a template node into a specialized version. This is done by
+ * patching typenames and other aspects of the node according to a list of
+ * template parameters
+ * ----------------------------------------------------------------------------- */
+
+static int
+cparse_template_expand(Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) {
+ static int expanded = 0;
+ int ret;
+
+ if (!n) return 0;
+ if (Getattr(n,"error")) return 0;
+
+ if (Strcmp(nodeType(n),"template") == 0) {
+ /* Change the node type back to normal */
+ if (!expanded) {
+ expanded = 1;
+ set_nodeType(n,Getattr(n,"templatetype"));
+ ret = cparse_template_expand(n,tname, rname, templateargs, patchlist,typelist, cpatchlist);
+ expanded = 0;
+ return ret;
+ } else {
+ /* Called when template appears inside another template */
+ /* Member templates */
+
+ set_nodeType(n,Getattr(n,"templatetype"));
+ ret = cparse_template_expand(n,tname, rname, templateargs, patchlist,typelist, cpatchlist);
+ set_nodeType(n,"template");
+ return ret;
+ }
+ } else if (Strcmp(nodeType(n),"cdecl") == 0) {
+ /* A simple C declaration */
+ SwigType *t, *v, *d;
+ String *code;
+ t = Getattr(n,"type");
+ v = Getattr(n,"value");
+ d = Getattr(n,"decl");
+
+ code = Getattr(n,"code");
+
+ Append(typelist,t);
+ Append(typelist,d);
+ Append(patchlist,v);
+ Append(cpatchlist,code);
+
+ if (Getattr(n,"conversion_operator")) {
+ Append(cpatchlist, Getattr(n,"name"));
+ if (Getattr(n,"sym:name")) {
+ Append(cpatchlist, Getattr(n,"sym:name"));
+ }
+ }
+
+ add_parms(Getattr(n,"parms"), cpatchlist, typelist);
+ add_parms(Getattr(n,"throws"), cpatchlist, typelist);
+
+ } else if (Strcmp(nodeType(n),"class") == 0) {
+ /* Patch base classes */
+ {
+ List *bases = Getattr(n,"baselist");
+ if (bases) {
+ int i;
+ for (i = 0; i < Len(bases); i++) {
+ String *name = Copy(Getitem(bases,i));
+ Setitem(bases,i,name);
+ Append(typelist,name);
+ }
+ }
+ }
+ /* Patch children */
+ {
+ Node *cn = firstChild(n);
+ while (cn) {
+ cparse_template_expand(cn,tname, rname, templateargs, patchlist,typelist,cpatchlist);
+ cn = nextSibling(cn);
+ }
+ }
+ } else if (Strcmp(nodeType(n),"constructor") == 0) {
+ String *name = Getattr(n,"name");
+ if (!(Getattr(n,"templatetype"))) {
+ String *symname;
+ String *stripped_name = SwigType_templateprefix(name);
+ if (Strstr(tname,stripped_name)) {
+ Replaceid(name,stripped_name,tname);
+ }
+ Delete(stripped_name);
+ symname = Getattr(n,"sym:name");
+ if (symname) {
+ stripped_name = SwigType_templateprefix(symname);
+ if (Strstr(tname,stripped_name)) {
+ Replaceid(symname,stripped_name,tname);
+ }
+ Delete(stripped_name);
+ }
+ if (Strstr(name,"<")) {
+ Append(patchlist,Getattr(n,"name"));
+ } else {
+ Append(name,templateargs);
+ }
+ name = Getattr(n,"sym:name");
+ if (name && (Strstr(name,"<"))) {
+ Clear(name);
+ Append(name,rname);
+ } else {
+ Replace(name,tname,rname, DOH_REPLACE_ANY);
+ }
+ Setattr(n,"sym:name",name);
+ }
+ Append(cpatchlist,Getattr(n,"code"));
+ Append(typelist, Getattr(n,"decl"));
+ add_parms(Getattr(n,"parms"), cpatchlist, typelist);
+ add_parms(Getattr(n,"throws"), cpatchlist, typelist);
+ } else if (Strcmp(nodeType(n),"destructor") == 0) {
+ String *name = Getattr(n,"name");
+ if (Strstr(name,"<")) {
+ Append(patchlist,Getattr(n,"name"));
+ } else {
+ Append(name,templateargs);
+ }
+ name = Getattr(n,"sym:name");
+ if (name && Strstr(name,"<")) {
+ Setattr(n,"sym:name", Copy(tname));
+ } else {
+ Replace(name,tname,rname, DOH_REPLACE_ANY);
+ }
+ Setattr(n,"sym:name",name);
+ Append(cpatchlist,Getattr(n,"code"));
+ } else if (Strcmp(nodeType(n),"using") == 0) {
+ String *uname = Getattr(n,"uname");
+ if (uname) {
+ if (Strstr(uname,"<")) {
+ Append(patchlist, uname);
+ }
+ }
+ if (Getattr(n,"namespace")) {
+ /* Namespace link. This is nasty. Is other namespace defined? */
+
+ }
+ } else {
+ /* Look for obvious parameters */
+ Node *cn;
+ Append(cpatchlist,Getattr(n,"code"));
+ Append(typelist, Getattr(n,"type"));
+ Append(typelist, Getattr(n,"decl"));
+ add_parms(Getattr(n,"parms"), cpatchlist, typelist);
+ add_parms(Getattr(n,"pattern"), cpatchlist, typelist);
+ add_parms(Getattr(n,"throws"), cpatchlist, typelist);
+ cn = firstChild(n);
+ while (cn) {
+ cparse_template_expand(cn,tname, rname, templateargs, patchlist, typelist, cpatchlist);
+ cn = nextSibling(cn);
+ }
+ }
+ return 0;
+}
+
+int
+Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms) {
+ List *patchlist, *cpatchlist, *typelist;
+ String *templateargs;
+ String *tname;
+ String *iname;
+ String *tbase;
+ patchlist = NewList();
+ cpatchlist = NewList();
+ typelist = NewList();
+
+ {
+ String *tmp = NewString("");
+ if (tparms) {
+ SwigType_add_template(tmp,tparms);
+ }
+ templateargs = Copy(tmp);
+ Delete(tmp);
+ }
+
+ tname = Copy(Getattr(n,"name"));
+ tbase = Swig_scopename_last(tname);
+
+ if (0) {
+ Parm *p = tparms;
+ while (p) {
+ Printf(stdout,"tparm: '%s' '%s'\n", Getattr(p,"name"), Getattr(p,"value"));
+ p = nextSibling(p);
+ }
+ }
+
+ cparse_template_expand(n,tname, rname, templateargs, patchlist, typelist, cpatchlist);
+
+ /* Set the name */
+ {
+ String *name = Getattr(n,"name");
+ if (name) {
+ Append(name,templateargs);
+ }
+ iname = name;
+ }
+
+ /* Patch all of the types */
+ {
+ Parm *tp = Getattr(n,"templateparms");
+ Parm *p = tparms;
+
+ if (tp) {
+ while (p && tp) {
+ String *name, *value, *valuestr, *tydef, *tmp, *tmpr;
+ int sz, i;
+
+ name = Getattr(tp,"name");
+ value = Getattr(p,"value");
+ tydef = Getattr(p,"typedef");
+ if (name) {
+ if (!value) {
+ value = Getattr(p,"type");
+ valuestr = SwigType_str(value,0);
+ } else {
+ valuestr = SwigType_namestr(value);
+ }
+ assert(value);
+ /* Need to patch default arguments */
+ {
+ Parm *rp = nextSibling(p);
+ while (rp) {
+ String *rvalue = Getattr(rp,"value");
+ if (rvalue) {
+ Replace(rvalue,name,value, DOH_REPLACE_ID);
+ }
+ rp = nextSibling(rp);
+ }
+ }
+ sz = Len(patchlist);
+ for (i = 0; i < sz; i++) {
+ String *s = Getitem(patchlist,i);
+ Replace(s,name,value, DOH_REPLACE_ID);
+ }
+ sz = Len(typelist);
+ for (i = 0; i < sz; i++) {
+ String *s = Getitem(typelist,i);
+ Replace(s,name,value, DOH_REPLACE_ID);
+ SwigType_typename_replace(s,tbase,iname);
+ }
+
+ if (!tydef) {
+ tydef = value;
+ }
+ tmp = NewStringf("#%s",name);
+ tmpr = NewStringf("\"%s\"", value);
+
+ sz = Len(cpatchlist);
+ for (i = 0; i < sz; i++) {
+ String *s = Getitem(cpatchlist,i);
+ Replace(s,tmp,tmpr, DOH_REPLACE_ID);
+ /* Replace(s,name,tydef, DOH_REPLACE_ID); */
+ Replace(s,name,valuestr, DOH_REPLACE_ID);
+ }
+ Delete(tmp);
+ Delete(tmpr);
+ Delete(valuestr);
+ }
+ p = nextSibling(p);
+ tp = nextSibling(tp);
+ if (!p) p = tp;
+ }
+ } else {
+ /* No template parameters at all. This could be a specialization */
+ int i, sz;
+ sz = Len(typelist);
+ for (i = 0; i < sz; i++) {
+ String *s = Getitem(typelist,i);
+ SwigType_typename_replace(s,tbase,iname);
+ }
+ }
+ }
+
+ /* Patch bases */
+ {
+ List *bases = Getattr(n,"baselist");
+ if (bases) {
+ String *b;
+ for (b = Firstitem(bases); b; b = Nextitem(bases)) {
+ String *qn = Swig_symbol_type_qualify(b,0);
+ Clear(b);
+ Append(b,qn);
+ }
+ }
+ }
+ Delete(patchlist);
+ Delete(cpatchlist);
+ Delete(typelist);
+ Delete(tbase);
+
+ /* set_nodeType(n,"template");*/
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * cparse_template_locate()
+ *
+ * Search for a template that matches name with given parameters.
+ * ----------------------------------------------------------------------------- */
+
+Node *
+Swig_cparse_template_locate(String *name, Parm *tparms) {
+ Node *n;
+ String *tname, *rname = 0;
+ Node *templ;
+ List *mpartials = 0;
+ Parm *p;
+ Parm *parms;
+
+ tname = NewString(name);
+ parms = CopyParmList(tparms);
+
+ p = parms;
+ while (p) {
+ SwigType *ty = Getattr(p,"type");
+ if (ty) {
+ SwigType *nt = Swig_symbol_typedef_reduce(ty,0);
+ nt = Swig_symbol_type_qualify(nt,0);
+ Setattr(p,"type",nt);
+ }
+ p = nextSibling(p);
+ }
+
+ SwigType_add_template(tname,parms);
+
+ if (template_debug) {
+ Printf(stdout,"\n%s:%d: template_debug: Searching for %s\n", cparse_file, cparse_line, tname);
+ }
+
+ /* Search for an exact specialization.
+ Example: template<> class name<int> { ... } */
+ {
+ if (template_debug) {
+ Printf(stdout," searching: '%s' (exact specialization)\n", tname);
+ }
+ n = Swig_symbol_clookup_local(tname,0);
+ if (n) {
+ Node *tn;
+ if (Strcmp(nodeType(n),"template") == 0) goto success;
+ tn = Getattr(n,"template");
+ if (tn) {
+ n = tn;
+ goto success; /* Previously wrapped by a template return that */
+ }
+ Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n));
+ Delete(tname);
+ Delete(parms);
+ return 0; /* Found a match, but it's not a template of any kind. */
+ }
+ }
+
+ /* Search for generic template */
+ templ = Swig_symbol_clookup_local(name,0);
+
+ /* Search for partial specialization.
+ Example: template<typename T> class name<T *> { ... } */
+
+ /* Generate reduced template name (stripped of extraneous pointers, etc.) */
+
+ rname = NewStringf("%s<(",name);
+ p = parms;
+ while (p) {
+ String *t;
+ t = Getattr(p,"type");
+ if (t) {
+ String *tbase = SwigType_base(t);
+ t = SwigType_default(t);
+ Replaceid(t,"SWIGTYPE",tbase);
+ Replaceid(t,"SWIGENUM",tbase);
+ Printf(rname,"%s",t);
+ Delete(t);
+ } else {
+ String *v = Getattr(p,"value");
+ Printf(rname,"%s",v);
+ }
+ p = nextSibling(p);
+ if (p) {
+ Printf(rname,",");
+ }
+ }
+ Printf(rname,")>");
+
+ mpartials = NewList();
+ if (templ) {
+ /* First, we search using an exact type prototype */
+ Parm *p;
+ char tmp[32];
+ int i;
+ List *partials;
+ String *s, *ss;
+
+ partials = Getattr(templ,"partials");
+ if (partials) {
+ for (s = Firstitem(partials); s; s= Nextitem(partials)) {
+ ss = Copy(s);
+ p = parms;
+ i = 1;
+ while (p) {
+ String *t,*tn;
+ sprintf(tmp,"$%d",i);
+ t = Getattr(p,"type");
+ if (t) {
+ tn = SwigType_base(t);
+ Replaceid(ss,tmp,tn);
+ Delete(tn);
+ } else {
+ String *v = Getattr(p,"value");
+ Replaceid(ss,tmp,v);
+ }
+ i++;
+ p = nextSibling(p);
+ }
+ if (template_debug) {
+ Printf(stdout," searching: '%s' (partial specialization - %s)\n", ss, s);
+ }
+ if ((Strcmp(ss,tname) == 0) || (Strcmp(ss,rname) == 0)) {
+ Append(mpartials,s);
+ }
+ Delete(ss);
+ }
+ }
+ }
+
+ if (template_debug) {
+ Printf(stdout," Matched partials: %s\n", mpartials);
+ }
+
+ if (Len(mpartials)) {
+ String *s = Getitem(mpartials,0);
+ n = Swig_symbol_clookup_local(s,0);
+ if (Len(mpartials) > 1) {
+ if (n) {
+ Swig_warning(WARN_PARSE_TEMPLATE_AMBIG,cparse_file,cparse_line,"Instantiation of template %s is ambiguous. Using %s at %s:%d\n",
+ SwigType_namestr(tname), SwigType_namestr(Getattr(n,"name")), Getfile(n),Getline(n));
+ }
+ }
+ }
+
+ if (!n) {
+ n = templ;
+ }
+ if (!n) {
+ Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name);
+ } else if (n && (Strcmp(nodeType(n),"template") != 0)) {
+ Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n));
+ n = 0;
+ }
+ success:
+ Delete(tname);
+ Delete(rname);
+ Delete(mpartials);
+ if ((template_debug) && (n)) {
+ Printf(stdout,"Node: %x\n", n);
+ Swig_print_node(n);
+ }
+ Delete(parms);
+ return n;
+}
+
+
diff --git a/Source/CParse/util.c b/Source/CParse/util.c
new file mode 100644
index 000000000..33f4976c8
--- /dev/null
+++ b/Source/CParse/util.c
@@ -0,0 +1,71 @@
+/* -----------------------------------------------------------------------------
+ * util.c
+ *
+ * Parsing utilities
+ *
+ * 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_util_c[] = "$Header$";
+
+#include "swig.h"
+
+extern SwigType *Swig_cparse_type(String *);
+
+/* -----------------------------------------------------------------------------
+ * Swig_cparse_replace_descriptor()
+ *
+ * Replaces type descriptor string $descriptor() with the SWIG type descriptor
+ * string.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_cparse_replace_descriptor(String *s) {
+ char tmp[512];
+ String *arg = 0;
+ SwigType *t;
+
+ while (Strstr(s,"$descriptor(")) {
+ char *d = tmp;
+ int level = 0;
+ char *c = Strstr(s,"$descriptor(");
+ while (*c) {
+ if (*c == '(') level++;
+ if (*c == ')') {
+ level--;
+ if (level == 0) {
+ break;
+ }
+ }
+ *d = *c;
+ d++;
+ c++;
+ }
+ *d = 0;
+ arg = NewString(tmp+12);
+ t = Swig_cparse_type(arg);
+ Delete(arg);
+ arg = 0;
+
+ if (t) {
+ String *mangle;
+ String *descriptor;
+
+ mangle = SwigType_manglestr(t);
+ descriptor = NewStringf("SWIGTYPE%s",mangle);
+ SwigType_remember(t);
+ *d = ')';
+ d++;
+ *d = 0;
+ Replace(s,tmp,descriptor,DOH_REPLACE_ANY);
+ Delete(mangle);
+ Delete(descriptor);
+ } else {
+ Swig_error(Getfile(s),Getline(s),"Bad $descriptor() macro.\n");
+ break;
+ }
+ }
+}
+
diff --git a/Source/DOH/.cvsignore b/Source/DOH/.cvsignore
index 3e4a1f00a..2599bc761 100644
--- a/Source/DOH/.cvsignore
+++ b/Source/DOH/.cvsignore
@@ -2,3 +2,4 @@ Makefile
config.*
*.tar.gz
configure
+autom4te.cache
diff --git a/Source/DOH/Doh/Makefile b/Source/DOH/Doh/Makefile
deleted file mode 100644
index 0908946e0..000000000
--- a/Source/DOH/Doh/Makefile
+++ /dev/null
@@ -1,50 +0,0 @@
-# Generated automatically from Makefile.in by configure.
-#######################################################################
-# $Header$
-# DOH
-#######################################################################
-
-#.KEEP_STATE:
-
-# Set your C++ compiler here. g++ works on most machines,
-# but you might have to change it depending on your installation.
-#
-CC = cc
-prefix = /r0/beazley/Projects
-
-# Comment out the following line if you're on an SGI or don't have ranlib!
-RANLIB = ranlib
-AR = ar
-
-########################################################################
-# Normally, you shouldn't have to change anything below this point #
-########################################################################
-
-LIBOBJS = callable.o void.o fio.o memory.o base.o file.o list.o hash.o string.o
-
-LIBSRCS = callable.c void.c fio.c memory.c base.c file.c list.c hash.c string.c
-
-LIBHEADERS = ../Include/doh.h
-LIB = ../libdoh.a
-INCLUDE = -I../Include
-CFLAGS = -DDOH_STRING_UPDATE_LINES
-SHELL = /bin/sh
-
-#
-# Rules for creation of a .o file from .cxx
-.SUFFIXES: .c
-.c.o:
- $(CC) $(INCLUDE) $(CFLAGS) -c -o $*.o $<
-
-all: $(LIB)
-
-$(LIB): $(LIBOBJS)
- @echo "Building library"
- $(AR) cr $(LIB) $(LIBOBJS)
- $(RANLIB) $(LIB)
-
-clean::
- rm -f *.o ../libdoh.a
-nuke::
- rm -f Makefile *~ #* core a.out
-
diff --git a/Source/DOH/Doh/Makefile.in b/Source/DOH/Doh/Makefile.in
index fadad36e2..44078fd2f 100644
--- a/Source/DOH/Doh/Makefile.in
+++ b/Source/DOH/Doh/Makefile.in
@@ -24,21 +24,21 @@ DOHOPT =
# Normally, you shouldn't have to change anything below this point #
########################################################################
-LIBOBJS = void.o fio.o memory.o base.o file.o list.o hash.o string.o
+LIBOBJS = void.@OBJEXT@ fio.@OBJEXT@ memory.@OBJEXT@ base.@OBJEXT@ file.@OBJEXT@ list.@OBJEXT@ hash.@OBJEXT@ string.@OBJEXT@
LIBSRCS = void.c fio.c memory.c base.c file.c list.c hash.c string.c
LIBHEADERS = $(srcdir)/../Include/doh.h
LIB = libdoh.a
-INCLUDE = -I$(srcdir)/../Include
+INCLUDES = -I$(srcdir)/../Include
CFLAGS = @CFLAGS@
SHELL = /bin/sh
#
-# Rules for creation of a .o file from .c
+# Rules for creation of a .@OBJEXT@ file from .c
.SUFFIXES: .c
-.c.o:
- $(CC) $(DOHOPT) $(INCLUDE) $(CFLAGS) -c -o $*.o $<
+.c.@OBJEXT@:
+ $(CC) $(DOHOPT) $(INCLUDES) $(CFLAGS) -c -o $*.@OBJEXT@ $<
all: $(LIB)
@@ -49,6 +49,6 @@ $(LIB): $(LIBOBJS)
cp -f $(LIB) ..
clean::
- rm -f *.o $(LIB) ../$(LIB)
+ rm -f *.@OBJEXT@ $(LIB) ../$(LIB)
nuke::
- rm -f Makefile *~ #* core a.out
+ rm -f Makefile *~
diff --git a/Source/DOH/Doh/base.c b/Source/DOH/Doh/base.c
index 8787d6204..a5063389d 100644
--- a/Source/DOH/Doh/base.c
+++ b/Source/DOH/Doh/base.c
@@ -10,21 +10,10 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_base_c[] = "$Header$";
#include "dohint.h"
-static DohObjInfo *dohtypes[MAX_DOHTYPE];
-
-/* -----------------------------------------------------------------------------
- * DohRegisterType()
- * ----------------------------------------------------------------------------- */
-
-void
-DohRegisterType(int type, DohObjInfo *objinfo) {
- dohtypes[type] = objinfo;
-}
-
/* -----------------------------------------------------------------------------
* DohDelete()
* ----------------------------------------------------------------------------- */
@@ -43,7 +32,7 @@ DohDelete(DOH *obj) {
assert(b->refcount > 0);
b->refcount--;
if (b->refcount <= 0) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_del) {
(objinfo->doh_del)(b);
} else {
@@ -63,9 +52,14 @@ DohCopy(const DOH *obj) {
DohObjInfo *objinfo;
if (!obj) return 0;
- objinfo = dohtypes[b->type];
- if (objinfo->doh_copy)
- return (objinfo->doh_copy)(b);
+ objinfo = b->type;
+ if (objinfo->doh_copy) {
+ DohBase *bc = (DohBase *) (objinfo->doh_copy)(b);
+ if ((bc) && b->meta) {
+ bc->meta = Copy(b->meta);
+ }
+ return (DOH *) bc;
+ }
return 0;
}
@@ -81,7 +75,7 @@ DohIncref(DOH *obj) {
void
DohClear(DOH *obj) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_clear)
(objinfo->doh_clear)(b);
}
@@ -96,11 +90,11 @@ DohStr(const DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (DohCheck(b)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_str) {
return (objinfo->doh_str)(b);
}
- sprintf(buffer,"<Object '%s' at %x>", objinfo->objname, b);
+ sprintf(buffer,"<Object '%s' at %x>", objinfo->objname, (unsigned int)b);
return NewString(buffer);
} else {
return NewString(obj);
@@ -114,7 +108,7 @@ DohStr(const DOH *obj) {
int
DohDump(const DOH *obj, DOH *out) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_dump) {
return (objinfo->doh_dump)(b,out);
}
@@ -130,7 +124,7 @@ DohLen(const DOH *obj) {
DohObjInfo *objinfo;
if (!b) return 0;
if (DohCheck(b)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_len) {
return (objinfo->doh_len)(b);
}
@@ -149,7 +143,7 @@ DohHashval(const DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (DohCheck(b)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_hashval) {
return (objinfo->doh_hashval)(b);
}
@@ -166,7 +160,7 @@ DohData(const DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (DohCheck(obj)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_data) {
return (objinfo->doh_data)(b);
}
@@ -191,8 +185,8 @@ DohCmp(const DOH *obj1, const DOH *obj2) {
if (!b1 && b2) return -1;
return strcmp((char *) DohData(b1),(char *) DohData(b2));
}
- b1info = dohtypes[b1->type];
- b2info = dohtypes[b2->type];
+ b1info = b1->type;
+ b2info = b2->type;
if ((b1info == b2info) && (b1info->doh_cmp))
return (b1info->doh_cmp)(b1,b2);
return 1;
@@ -206,7 +200,7 @@ DohIsMapping(const DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (!DohCheck(b)) return 0;
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_hash) return 1;
else return 0;
}
@@ -218,7 +212,7 @@ DohIsMapping(const DOH *obj) {
DOH *
DohGetattr(DOH *obj, const DOH *name) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_hash && objinfo->doh_hash->doh_getattr) {
return (objinfo->doh_hash->doh_getattr)(b,(DOH *) name);
}
@@ -232,7 +226,7 @@ DohGetattr(DOH *obj, const DOH *name) {
int
DohSetattr(DOH *obj, const DOH *name, const DOH *value) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_hash && objinfo->doh_hash->doh_setattr) {
return (objinfo->doh_hash->doh_setattr)(b,(DOH *) name,(DOH *) value);
}
@@ -243,13 +237,14 @@ DohSetattr(DOH *obj, const DOH *name, const DOH *value) {
* DohDelattr()
* ----------------------------------------------------------------------------- */
-void
+int
DohDelattr(DOH *obj, const DOH *name) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_hash && objinfo->doh_hash->doh_delattr) {
- (objinfo->doh_hash->doh_delattr)(b,(DOH *) name);
+ return (objinfo->doh_hash->doh_delattr)(b,(DOH *) name);
}
+ return 0;
}
/* -----------------------------------------------------------------------------
@@ -259,7 +254,7 @@ DohDelattr(DOH *obj, const DOH *name) {
DOH *
DohFirstkey(DOH *obj) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_hash && objinfo->doh_hash->doh_firstkey) {
return (objinfo->doh_hash->doh_firstkey)(b);
}
@@ -273,7 +268,7 @@ DohFirstkey(DOH *obj) {
DOH *
DohNextkey(DOH *obj) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo && objinfo->doh_hash->doh_nextkey) {
return (objinfo->doh_hash->doh_nextkey)(b);
}
@@ -281,6 +276,20 @@ DohNextkey(DOH *obj) {
}
/* -----------------------------------------------------------------------------
+ * DohNextkey()
+ * ----------------------------------------------------------------------------- */
+
+DOH *
+DohKeys(DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo && objinfo->doh_hash->doh_keys) {
+ return (objinfo->doh_hash->doh_keys)(b);
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
* DohGetInt()
* ----------------------------------------------------------------------------- */
@@ -388,7 +397,7 @@ DohIsSequence(const DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (!DohCheck(b)) return 0;
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_list) return 1;
else return 0;
}
@@ -400,7 +409,7 @@ DohIsSequence(const DOH *obj) {
DOH *
DohGetitem(DOH *obj, int index) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_list && objinfo->doh_list->doh_getitem) {
return (objinfo->doh_list->doh_getitem)(b,index);
}
@@ -414,7 +423,7 @@ DohGetitem(DOH *obj, int index) {
int
DohSetitem(DOH *obj, int index, const DOH *value) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_list && objinfo->doh_list->doh_setitem) {
return (objinfo->doh_list->doh_setitem)(b,index,(DOH *) value);
}
@@ -428,7 +437,7 @@ DohSetitem(DOH *obj, int index, const DOH *value) {
int
DohDelitem(DOH *obj, int index) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_list && objinfo->doh_list->doh_delitem) {
return (objinfo->doh_list->doh_delitem)(b,index);
}
@@ -442,7 +451,7 @@ DohDelitem(DOH *obj, int index) {
int
DohInsertitem(DOH *obj, int index, const DOH *value) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_list && objinfo->doh_list->doh_insitem) {
return (objinfo->doh_list->doh_insitem)(b,index,(DOH *) value);
}
@@ -456,7 +465,7 @@ DohInsertitem(DOH *obj, int index, const DOH *value) {
DOH *
DohFirstitem(DOH *obj) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_list && objinfo->doh_list->doh_firstitem) {
return (objinfo->doh_list->doh_firstitem)(b);
}
@@ -470,7 +479,7 @@ DohFirstitem(DOH *obj) {
DOH *
DohNextitem(DOH *obj) {
DohBase *b = (DohBase *) obj;
- DohObjInfo *objinfo = dohtypes[b->type];
+ DohObjInfo *objinfo = b->type;
if (objinfo->doh_list && objinfo->doh_list->doh_nextitem) {
return (objinfo->doh_list->doh_nextitem)(b);
}
@@ -486,7 +495,7 @@ DohIsFile(const DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (!DohCheck(b)) return 0;
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_file) return 1;
else return 0;
}
@@ -500,7 +509,7 @@ DohRead(DOH *obj, void *buffer, int length) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (DohCheck(obj)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if ((objinfo->doh_file) && (objinfo->doh_file->doh_read)) {
return (objinfo->doh_file->doh_read)(b,buffer,length);
}
@@ -519,7 +528,7 @@ DohWrite(DOH *obj, void *buffer, int length) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (DohCheck(obj)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if ((objinfo->doh_file) && (objinfo->doh_file->doh_write)) {
return (objinfo->doh_file->doh_write)(b,buffer,length);
}
@@ -538,7 +547,7 @@ DohSeek(DOH *obj, long offset, int whence) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (DohCheck(obj)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if ((objinfo->doh_file) && (objinfo->doh_file->doh_seek)) {
return (objinfo->doh_file->doh_seek)(b,offset,whence);
}
@@ -556,7 +565,7 @@ DohTell(DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (DohCheck(obj)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if ((objinfo->doh_file) && (objinfo->doh_file->doh_tell)) {
return (objinfo->doh_file->doh_tell)(b);
}
@@ -575,11 +584,11 @@ DohGetc(DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (obj == lastdoh) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
return (objinfo->doh_file->doh_getc)(b);
}
if (DohCheck(obj)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_file->doh_getc) {
lastdoh = obj;
return (objinfo->doh_file->doh_getc)(b);
@@ -600,11 +609,11 @@ DohPutc(int ch, DOH *obj) {
DohObjInfo *objinfo;
if (obj == lastdoh) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
return (objinfo->doh_file->doh_putc)(b,ch);
}
if (DohCheck(obj)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_file->doh_putc) {
lastdoh = obj;
return (objinfo->doh_file->doh_putc)(b,ch);
@@ -623,7 +632,7 @@ DohUngetc(int ch, DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (DohCheck(obj)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_file->doh_ungetc) {
return (objinfo->doh_file->doh_ungetc)(b,ch);
}
@@ -641,7 +650,7 @@ DohClose(DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (DohCheck(obj)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_file->doh_close) {
return (objinfo->doh_file->doh_close)(b);
}
@@ -659,7 +668,7 @@ DohIsString(const DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo;
if (!DohCheck(b)) return 0;
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_string) return 1;
else return 0;
}
@@ -672,8 +681,10 @@ int
DohReplace(DOH *src, const DOH *token, const DOH *rep, int flags) {
DohBase *b = (DohBase *) src;
DohObjInfo *objinfo;
+ if (!token) return 0;
+ if (!rep) rep = "";
if (DohIsString(src)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_string->doh_replace) {
return (objinfo->doh_string->doh_replace)(b,(DOH *) token, (DOH *) rep,flags);
}
@@ -690,7 +701,7 @@ DohChop(DOH *src) {
DohBase *b = (DohBase *) src;
DohObjInfo *objinfo;
if (DohIsString(src)) {
- objinfo = dohtypes[b->type];
+ objinfo = b->type;
if (objinfo->doh_string->doh_chop) {
(objinfo->doh_string->doh_chop)(b);
}
@@ -705,7 +716,7 @@ DohSetfile(DOH *ho, DOH *file) {
DohBase *h = (DohBase *) ho;
DohObjInfo *objinfo;
if (!h) return;
- objinfo = dohtypes[h->type];
+ objinfo = h->type;
if (objinfo->doh_setfile)
(objinfo->doh_setfile)(h,file);
}
@@ -718,7 +729,7 @@ DohGetfile(DOH *ho) {
DohBase *h = (DohBase *) ho;
DohObjInfo *objinfo;
if (!h) return 0;
- objinfo = dohtypes[h->type];
+ objinfo = h->type;
if (objinfo->doh_getfile)
return (objinfo->doh_getfile)(h);
return 0;
@@ -732,7 +743,7 @@ DohSetline(DOH *ho, int l) {
DohBase *h = (DohBase *) ho;
DohObjInfo *objinfo;
if (!h) return;
- objinfo = dohtypes[h->type];
+ objinfo = h->type;
if (objinfo->doh_setline)
(objinfo->doh_setline)(h,l);
}
@@ -745,12 +756,60 @@ DohGetline(DOH *ho) {
DohBase *h = (DohBase *) ho;
DohObjInfo *objinfo;
if (!h) return 0;
- objinfo = dohtypes[h->type];
+ objinfo = h->type;
if (objinfo->doh_getline)
return (objinfo->doh_getline)(h);
return 0;
}
+/* -----------------------------------------------------------------------------
+ * DohGetmeta()
+ * ----------------------------------------------------------------------------- */
+DOH *
+DohGetmeta(DOH *ho, const DOH *name) {
+ DohBase *h = (DohBase *) ho;
+ if (!DohCheck(ho)) return 0;
+ if (!h->meta) return 0;
+ return DohGetattr(h->meta,name);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohGetmeta()
+ * ----------------------------------------------------------------------------- */
+
+int
+DohSetmeta(DOH *ho, const DOH *name, const DOH *value) {
+ DohBase *h = (DohBase *) ho;
+ if (!DohCheck(ho)) return 0;
+ if (!h->meta) h->meta = NewHash();
+ return DohSetattr(h->meta, name, value);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohDelmeta()
+ * ----------------------------------------------------------------------------- */
+
+int
+DohDelmeta(DOH *ho, const DOH *name) {
+ DohBase *h = (DohBase *) ho;
+ if (!DohCheck(ho)) return 0;
+ if (!h->meta) return 0;
+ return DohDelattr(h->meta, name);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSetmark()
+ * ----------------------------------------------------------------------------- */
+void
+DohSetmark(DOH *ho, int x) {
+ DohBase *h = (DohBase *) ho;
+ h->flag_usermark = x;
+}
+int
+DohGetmark(DOH *ho) {
+ DohBase *h = (DohBase *) ho;
+ return h->flag_usermark;
+}
diff --git a/Source/DOH/Doh/file.c b/Source/DOH/Doh/file.c
index 4e901e91c..70e8c3d4e 100644
--- a/Source/DOH/Doh/file.c
+++ b/Source/DOH/Doh/file.c
@@ -10,7 +10,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_file_c[] = "$Header$";
#include "dohint.h"
@@ -41,6 +41,7 @@ DelFile(DOH *fo) {
}
#endif
}
+ DohFree(f);
}
/* -----------------------------------------------------------------------------
@@ -118,12 +119,12 @@ File_tell(DOH *fo) {
static int
File_putc(DOH *fo, int ch) {
- char c;
DohFile *f = (DohFile *) ObjData(fo);
if (f->filep) {
return fputc(ch,f->filep);
} else if (f->fd) {
#ifdef DOH_INTFILE
+ char c;
c = (char) ch;
return write(f->fd,&c,1);
#endif
@@ -137,12 +138,12 @@ File_putc(DOH *fo, int ch) {
static int
File_getc(DOH *fo) {
- char c;
DohFile *f = (DohFile *) ObjData(fo);
if (f->filep) {
return fgetc(f->filep);
} else if (f->fd) {
#ifdef DOH_INTFILE
+ char c;
if (read(f->fd,&c,1) < 0) return EOF;
return c;
#endif
@@ -169,6 +170,28 @@ File_ungetc(DOH *fo, int ch) {
return -1;
}
+/* -----------------------------------------------------------------------------
+ * File_close()
+ *
+ * Close the file
+ * ----------------------------------------------------------------------------- */
+
+static int
+File_close(DOH *fo) {
+ int ret = 0;
+ DohFile *f = (DohFile *) ObjData(fo);
+ if (f->filep) {
+ ret = fclose(f->filep);
+ f->filep = 0;
+ } else if (f->fd) {
+#ifdef DOH_INTFILE
+ ret = close(f->fd);
+ f->fd = 0;
+#endif
+ }
+ return ret;
+}
+
static DohFileMethods FileFileMethods = {
File_read,
File_write,
@@ -177,7 +200,7 @@ static DohFileMethods FileFileMethods = {
File_ungetc,
File_seek,
File_tell,
- 0, /* close */
+ File_close, /* close */
};
static DohObjInfo DohFileType = {
@@ -209,20 +232,13 @@ static DohObjInfo DohFileType = {
* Create a new file from a given filename and mode.
* ----------------------------------------------------------------------------- */
-static int init = 0;
-
DOH *
-NewFile(DOH *fn, char *mode)
+DohNewFile(DOH *fn, const char *mode)
{
DohFile *f;
FILE *file;
char *filename;
- if (!init) {
- DohRegisterType(DOHTYPE_FILE, &DohFileType);
- init = 1;
- }
-
filename = Char(fn);
file = fopen(filename,mode);
if (!file) return 0;
@@ -235,7 +251,7 @@ NewFile(DOH *fn, char *mode)
f->filep = file;
f->fd = 0;
f->closeondel = 1;
- return DohObjMalloc(DOHTYPE_FILE,f);
+ return DohObjMalloc(&DohFileType,f);
}
/* -----------------------------------------------------------------------------
@@ -245,20 +261,15 @@ NewFile(DOH *fn, char *mode)
* ----------------------------------------------------------------------------- */
DOH *
-NewFileFromFile(FILE *file)
+DohNewFileFromFile(FILE *file)
{
DohFile *f;
-
- if (!init) {
- DohRegisterType(DOHTYPE_FILE, &DohFileType);
- init = 1;
- }
f = (DohFile *) DohMalloc(sizeof(DohFile));
if (!f) return 0;
f->filep = file;
f->fd = 0;
f->closeondel = 0;
- return DohObjMalloc(DOHTYPE_FILE,f);
+ return DohObjMalloc(&DohFileType,f);
}
/* -----------------------------------------------------------------------------
@@ -268,17 +279,13 @@ NewFileFromFile(FILE *file)
* ----------------------------------------------------------------------------- */
DOH *
-NewFileFromFd(int fd)
+DohNewFileFromFd(int fd)
{
DohFile *f;
- if (!init) {
- DohRegisterType(DOHTYPE_FILE, &DohFileType);
- init = 1;
- }
f = (DohFile *) DohMalloc(sizeof(DohFile));
if (!f) return 0;
f->filep = 0;
f->fd = fd;
f->closeondel = 0;
- return DohObjMalloc(DOHTYPE_FILE,f);
+ return DohObjMalloc(&DohFileType,f);
}
diff --git a/Source/DOH/Doh/fio.c b/Source/DOH/Doh/fio.c
index 2d8e03efd..db7e5eb1c 100644
--- a/Source/DOH/Doh/fio.c
+++ b/Source/DOH/Doh/fio.c
@@ -10,7 +10,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_fio_c[] = "$Header$";
#include "dohint.h"
@@ -265,7 +265,7 @@ DohvPrintf(DOH *so, const char *format, va_list ap)
doh = va_arg(ap, DOH *);
if (DohCheck(doh)) {
/* Is a DOH object. */
- if (DohIsString(doh) && (ObjType(doh) == DOHTYPE_STRING)) {
+ if (DohIsString(doh)) {
Sval = doh;
} else {
Sval = Str(doh);
@@ -411,7 +411,7 @@ int DohPrintv(DOHFile *f, ...) {
va_start(ap,f);
while(1) {
obj = va_arg(ap,void *);
- if (!obj) break;
+ if ((!obj) || (obj == DohNone)) break;
if (DohCheck(obj)) {
ret += DohDump(obj,f);
} else {
@@ -459,12 +459,12 @@ DohCopyto(DOH *in, DOH *out) {
/* -----------------------------------------------------------------------------
* DohSplit()
*
- * Split an input stream into a list of strings delimeted by characters in a
- * string. Optionally accepts a maximum number of splits to perform.
+ * Split an input stream into a list of strings delimited by the specified
+ * character. Optionally accepts a maximum number of splits to perform.
* ----------------------------------------------------------------------------- */
DOH *
-DohSplit(DOH *in, char *chs, int nsplits) {
+DohSplit(DOH *in, char ch, int nsplits) {
DOH *list;
DOH *str;
int c;
@@ -479,17 +479,18 @@ DohSplit(DOH *in, char *chs, int nsplits) {
str = NewString("");
do {
c = Getc(in);
- } while ((c != EOF) && (c == *chs));
+ } while ((c != EOF) && (c == ch));
if (c != EOF) {
Putc(c,str);
while (1) {
c = Getc(in);
- if ((c == EOF) || ((c == *chs) && (nsplits != 0))) break;
+ if ((c == EOF) || ((c == ch) && (nsplits != 0))) break;
Putc(c,str);
}
nsplits--;
}
Append(list,str);
+ Delete(str);
if (c == EOF) break;
}
return list;
diff --git a/Source/DOH/Doh/hash.c b/Source/DOH/Doh/hash.c
index 246242c20..4738a2312 100644
--- a/Source/DOH/Doh/hash.c
+++ b/Source/DOH/Doh/hash.c
@@ -9,10 +9,12 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_hash_c[] = "$Header$";
#include "dohint.h"
+extern DohObjInfo DohHashType;
+
/* Hash node */
typedef struct HashNode {
DOH *key;
@@ -46,6 +48,9 @@ static DOH *find_key (DOH *doh_c) {
char *c = (char *) doh_c;
KeyValue *r, *s;
int d = 0;
+ /* OK, sure, we use a binary tree for maintaining interned
+ symbols. Then we use their hash values for accessing secondary
+ hash tables. */
r = root;
s = 0;
while (r) {
@@ -199,8 +204,10 @@ Hash_setattr(DOH *ho, DOH *k, DOH *obj) {
int hv;
HashNode *n, *prev;
Hash *h = (Hash *) ObjData(ho);
-
- if (!obj) return 0;
+
+ if (!obj) {
+ return DohDelattr(ho,k);
+ }
if (!DohCheck(k)) k = find_key(k);
if (!DohCheck(obj)) {
obj = NewString((char *) obj);
@@ -211,16 +218,15 @@ Hash_setattr(DOH *ho, DOH *k, DOH *obj) {
prev = 0;
while (n) {
if (Cmp(n->key,k) == 0) {
- HashNode *nn;
- if (prev) {
- prev->next = n->next;
- } else {
- h->hashtable[hv] = n->next;
+ /* Node already exists. Just replace its contents */
+ if (n->object == obj) {
+ /* Whoa. Same object. Do nothing */
+ return 1;
}
- nn = n->next;
- DelNode(n);
- h->nitems--;
- n = nn;
+ Delete(n->object);
+ n->object = obj;
+ Incref(obj);
+ return 1; /* Return 1 to indicate a replacement */
} else {
prev = n;
n = n->next;
@@ -276,11 +282,17 @@ Hash_delattr(DOH *ho, DOH *k) {
while (n) {
if (Cmp(n->key, k) == 0) {
/* Found it, kill it */
+
if (prev) {
prev->next = n->next;
} else {
h->hashtable[hv] = n->next;
}
+ /* Need to check for iterator location */
+ if (n == h->current) {
+ h->current = prev; /* Move back to previous node. When next is called, will move to next node */
+ if (!h->current) h->currentindex--; /* No previous node. Move back one slot */
+ }
DelNode(n);
h->nitems--;
return 1;
@@ -307,10 +319,12 @@ hash_first(DOH *ho) {
static HashNode *
hash_next(DOH *ho) {
Hash *h = (Hash *) ObjData(ho);
- if (h->currentindex < 0) return hash_first(h);
+ if (h->currentindex < 0) return hash_first(ho);
/* Try to move to the next entry */
- h->current = h->current->next;
+ if (h->current) {
+ h->current = h->current->next;
+ }
if (h->current) {
return h->current;
}
@@ -349,6 +363,26 @@ Hash_nextkey(DOH *ho) {
}
/* -----------------------------------------------------------------------------
+ * Hash_keys(DOH *)
+ *
+ * Return a list of keys
+ * ----------------------------------------------------------------------------- */
+
+static DOH *
+Hash_keys(DOH *so) {
+ DOH *keys;
+ DOH *k;
+
+ keys = NewList();
+ k = Firstkey(so);
+ while (k) {
+ Append(keys,k);
+ k = Nextkey(so);
+ }
+ return keys;
+}
+
+/* -----------------------------------------------------------------------------
* Hash_str()
*
* Create a string representation of a hash table (mainly for debugging).
@@ -398,26 +432,6 @@ Hash_len(DOH *ho) {
}
/* -----------------------------------------------------------------------------
- * Hash_keys(DOH *)
- *
- * Return a list of keys
- * ----------------------------------------------------------------------------- */
-DOH *
-Hash_keys(DOH *so) {
- DOH *keys;
- DOH *k;
-
- keys = NewList();
- k = Firstkey(so);
- while (k) {
- Append(keys,k);
- k = Nextkey(so);
- }
- /* List_sort(keys); */
- return keys;
-}
-
-/* -----------------------------------------------------------------------------
* CopyHash()
*
* Make a copy of a hash table. Note: this is a shallow copy.
@@ -444,7 +458,7 @@ CopyHash(DOH *ho) {
nh->file = h->file;
if (nh->file) Incref(nh->file);
- nho = DohObjMalloc(DOHTYPE_HASH, nh);
+ nho = DohObjMalloc(&DohHashType, nh);
for (i = 0; i < h->hashsize; i++) {
if ((n = h->hashtable[i])) {
while (n) {
@@ -458,7 +472,8 @@ CopyHash(DOH *ho) {
-void Hash_setfile(DOH *ho, DOH *file) {
+static void
+Hash_setfile(DOH *ho, DOH *file) {
DOH *fo;
Hash *h = (Hash *) ObjData(ho);
@@ -471,17 +486,20 @@ void Hash_setfile(DOH *ho, DOH *file) {
h->file = fo;
}
-DOH *Hash_getfile(DOH *ho) {
+static DOH *
+Hash_getfile(DOH *ho) {
Hash *h = (Hash *) ObjData(ho);
return h->file;
}
-void Hash_setline(DOH *ho, int line) {
+static void
+Hash_setline(DOH *ho, int line) {
Hash *h = (Hash *) ObjData(ho);
h->line = line;
}
-int Hash_getline(DOH *ho) {
+static int
+Hash_getline(DOH *ho) {
Hash *h = (Hash *) ObjData(ho);
return h->line;
}
@@ -496,9 +514,10 @@ static DohHashMethods HashHashMethods = {
Hash_delattr,
Hash_firstkey,
Hash_nextkey,
+ Hash_keys,
};
-static DohObjInfo HashType = {
+DohObjInfo DohHashType = {
"Hash", /* objname */
DelHash, /* doh_del */
CopyHash, /* doh_copy */
@@ -528,14 +547,9 @@ static DohObjInfo HashType = {
* ----------------------------------------------------------------------------- */
DOH *
-NewHash() {
+DohNewHash() {
Hash *h;
int i;
- static int init = 0;
- if (!init) {
- DohRegisterType(DOHTYPE_HASH, &HashType);
- init = 1;
- }
h = (Hash *) DohMalloc(sizeof(Hash));
h->hashsize = HASH_INIT_SIZE;
h->hashtable = (HashNode **) DohMalloc(h->hashsize*sizeof(HashNode *));
@@ -547,6 +561,5 @@ NewHash() {
h->nitems = 0;
h->file = 0;
h->line = 0;
- return DohObjMalloc(DOHTYPE_HASH,h);
+ return DohObjMalloc(&DohHashType,h);
}
-
diff --git a/Source/DOH/Doh/list.c b/Source/DOH/Doh/list.c
index 876fd9120..fff505b39 100644
--- a/Source/DOH/Doh/list.c
+++ b/Source/DOH/Doh/list.c
@@ -9,7 +9,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_list_c[] = "$Header$";
#include "dohint.h"
@@ -22,6 +22,8 @@ typedef struct List {
DOH **items;
} List;
+extern DohObjInfo DohListType;
+
/* Doubles amount of memory in a list */
static
void more(List *l) {
@@ -52,7 +54,7 @@ CopyList(DOH *lo) {
nl->file = l->file;
if (nl->file) Incref(nl->file);
nl->line = l->line;
- return DohObjMalloc(DOHTYPE_LIST, nl);
+ return DohObjMalloc(&DohListType, nl);
}
/* -----------------------------------------------------------------------------
@@ -261,27 +263,8 @@ List_dump(DOH *lo, DOH *out) {
return nsent;
}
-
-/* -----------------------------------------------------------------------------
- * List_sort()
- * ----------------------------------------------------------------------------- */
-
-
-static int objcmp(const void *s1, const void *s2) {
- DOH **so1, **so2;
- so1 = (DOH **) s1;
- so2 = (DOH **) s2;
- return Cmp(*so1,*so2);
-}
-
-void
-List_sort(DOH *lo, int opt) {
- List *l = (List *) ObjData(lo);
- qsort(l->items,l->nitems,sizeof(DOH *),objcmp);
-}
-
-
-void List_setfile(DOH *lo, DOH *file) {
+static void
+List_setfile(DOH *lo, DOH *file) {
DOH *fo;
List *l = (List *) ObjData(lo);
@@ -294,17 +277,19 @@ void List_setfile(DOH *lo, DOH *file) {
l->file = fo;
}
-DOH *List_getfile(DOH *lo) {
+static DOH *
+List_getfile(DOH *lo) {
List *l = (List *) ObjData(lo);
return l->file;
}
-void List_setline(DOH *lo, int line) {
+static void
+List_setline(DOH *lo, int line) {
List *l = (List *) ObjData(lo);
l->line = line;
}
-int List_getline(DOH *lo) {
+static int List_getline(DOH *lo) {
List *l = (List *) ObjData(lo);
return l->line;
}
@@ -316,10 +301,9 @@ static DohListMethods ListListMethods = {
List_insert,
List_first,
List_next,
- List_sort
};
-static DohObjInfo ListType = {
+DohObjInfo DohListType = {
"List", /* objname */
DelList, /* doh_del */
CopyList, /* doh_copy */
@@ -351,14 +335,9 @@ static DohObjInfo ListType = {
#define MAXLISTITEMS 8
DOH *
-NewList() {
+DohNewList() {
List *l;
int i;
- static int init = 0;
- if (!init) {
- DohRegisterType(DOHTYPE_LIST, &ListType);
- init = 1;
- }
l = (List *) DohMalloc(sizeof(List));
l->nitems = 0;
l->maxitems = MAXLISTITEMS;
@@ -369,5 +348,6 @@ NewList() {
l->iter = 0;
l->file = 0;
l->line = 0;
- return DohObjMalloc(DOHTYPE_LIST,l);
+ return DohObjMalloc(&DohListType,l);
}
+
diff --git a/Source/DOH/Doh/memory.c b/Source/DOH/Doh/memory.c
index fcf5ba341..b0ddc5ff1 100644
--- a/Source/DOH/Doh/memory.c
+++ b/Source/DOH/Doh/memory.c
@@ -10,7 +10,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_memory_c[] = "$Header$";
#include "dohint.h"
@@ -30,8 +30,7 @@ typedef struct pool {
struct pool *next; /* Next pool */
} Pool;
-DohBase *FreeList = 0; /* List of free objects */
-
+static DohBase *FreeList = 0; /* List of free objects */
static Pool *Pools = 0;
static int pools_initialized = 0;
@@ -105,7 +104,7 @@ DohIntern(DOH *obj) {
* ---------------------------------------------------------------------- */
DOH *
-DohObjMalloc(int type, void *data) {
+DohObjMalloc(DohObjInfo *type, void *data) {
DohBase *obj;
if (!pools_initialized) InitPools();
if (FreeList) {
@@ -121,9 +120,12 @@ DohObjMalloc(int type, void *data) {
}
obj->type = type;
obj->data = data;
+ obj->meta = 0;
obj->refcount = 1;
obj->flag_intern = 0;
obj->flag_marked = 0;
+ obj->flag_user = 0;
+ obj->flag_usermark = 0;
return (DOH *) obj;
}
@@ -137,6 +139,10 @@ DohObjFree(DOH *ptr) {
b = (DohBase *) ptr;
if (b->flag_intern) return;
b->data = (void *) FreeList;
+ if (b->meta) {
+ Delete(b->meta);
+ b->meta = 0;
+ }
b->type = 0;
FreeList = b;
}
diff --git a/Source/DOH/Doh/string.c b/Source/DOH/Doh/string.c
index 96d11d9a7..04e6d184a 100644
--- a/Source/DOH/Doh/string.c
+++ b/Source/DOH/Doh/string.c
@@ -10,13 +10,11 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_string_c[] = "$Header$";
#include "dohint.h"
-#ifndef DOH_STRING_UPDATE_LINES
-#define DOH_STRING_UPDATE_LINES
-#endif
+extern DohObjInfo DohStringType;
typedef struct String {
DOH *file;
@@ -31,7 +29,9 @@ typedef struct String {
/* -----------------------------------------------------------------------------
* void *String_data() - Return as a 'void *'
* ----------------------------------------------------------------------------- */
-void *String_data(DOH *so) {
+
+static void *
+String_data(DOH *so) {
String *s = (String *) ObjData(so);
s->str[s->len] = 0;
return (void *) s->str;
@@ -41,7 +41,8 @@ void *String_data(DOH *so) {
* int String_dump() - Serialize a string onto out
* ----------------------------------------------------------------------------- */
-int String_dump(DOH *so, DOH *out) {
+static int
+String_dump(DOH *so, DOH *out) {
int nsent;
int ret;
String *s = (String *) ObjData(so);
@@ -57,32 +58,37 @@ int String_dump(DOH *so, DOH *out) {
/* -----------------------------------------------------------------------------
* CopyString() - Copy a string
* ----------------------------------------------------------------------------- */
-DOH *
+
+static DOH *
CopyString(DOH *so) {
- String *s = (String *) ObjData(so);
int max;
String *str;
+ String *s = (String *) ObjData(so);
str = (String *) DohMalloc(sizeof(String));
str->hashkey = -1;
- str->sp = 0;
+ str->sp = s->sp;
str->line = s->line;
str->file = s->file;
if (str->file) Incref(str->file);
max = s->maxsize;
- str->str = (char *) DohMalloc(max);
+ str->str = (char *) DohMalloc(max+1);
memmove(str->str, s->str, max);
str->maxsize= max;
str->len = s->len;
str->str[str->len] = 0;
- return DohObjMalloc(DOHTYPE_STRING,str);
+
+ return DohObjMalloc(&DohStringType,str);
}
/* -----------------------------------------------------------------------------
* DelString() - Delete a string
* ----------------------------------------------------------------------------- */
-void
+
+static void
DelString(DOH *so) {
String *s = (String *) ObjData(so);
+ s->hashkey = -1;
+ s->str = 0;
DohFree(s->str);
DohFree(s);
}
@@ -91,7 +97,7 @@ DelString(DOH *so) {
* String_len() - Length of a string
* ----------------------------------------------------------------------------- */
-int
+static int
String_len(DOH *so) {
String *s = (String *) ObjData(so);
return s->len;
@@ -102,7 +108,7 @@ String_len(DOH *so) {
* int String_cmp() - Compare two strings
* ----------------------------------------------------------------------------- */
-int
+static int
String_cmp(DOH *so1, DOH *so2)
{
String *s1, *s2;
@@ -130,7 +136,8 @@ String_cmp(DOH *so1, DOH *so2)
* int String_hash() - Compute string hash value
* ----------------------------------------------------------------------------- */
-int String_hash(DOH *so) {
+static int
+String_hash(DOH *so) {
String *s = (String *) ObjData(so);
char *c;
int i, h = 0, len;
@@ -179,43 +186,11 @@ add(String *s, const char *newstr) {
s->len += l;
}
-/* Add a single character to s */
-void
-String_addchar(String *s, char c) {
- register char *tc;
- register int len = s->len;
- register int maxsize = s->maxsize;
- s->hashkey = -1;
- if (len > (maxsize-2)) {
- s->str = (char *) DohRealloc(s->str,2*maxsize);
- assert(s->str);
- s->maxsize = 2*maxsize;
- }
- tc = s->str;
- tc[len] = c;
- if (s->sp >= len) {
- s->sp = len+1;
- tc[len+1] = 0;
- if (c == '\n') s->line++;
- }
- s->len++;
-}
-
-/* Expand a string to accomodate a write */
-void
-String_expand(String *s, int width) {
- if ((s->len + width) > (s->maxsize-1)) {
- s->str = (char *) DohRealloc(s->str,(s->len + width)+1);
- assert(s->str);
- s->maxsize = s->len + width + 1;
- }
-}
-
/* -----------------------------------------------------------------------------
* void String_clear() - Clear a string
* ----------------------------------------------------------------------------- */
-void
+static void
String_clear(DOH *so)
{
String *s = (String *) ObjData(so);
@@ -230,7 +205,9 @@ String_clear(DOH *so)
* void String_insert() - Insert a string
* ----------------------------------------------------------------------------- */
-int String_insert(DOH *so, int pos, DOH *str) {
+static int
+String_insert(DOH *so, int pos, DOH *str)
+{
String *s = (String *) ObjData(so);
char *nstr;
int len;
@@ -274,7 +251,8 @@ int String_insert(DOH *so, int pos, DOH *str) {
* int String_delitem() - Delete a character
* ----------------------------------------------------------------------------- */
-int String_delitem(DOH *so, int pos)
+static int
+String_delitem(DOH *so, int pos)
{
String *s = (String *) ObjData(so);
s->hashkey = -1;
@@ -297,8 +275,9 @@ int String_delitem(DOH *so, int pos)
* DOH *String_str() - Returns a string (used by printing commands)
* ----------------------------------------------------------------------------- */
-DOH *
-String_str(DOH *so) {
+static DOH *
+String_str(DOH *so)
+{
String *s = (String *) ObjData(so);
s->str[s->len] = 0;
return NewString(s->str);
@@ -307,8 +286,10 @@ String_str(DOH *so) {
/* -----------------------------------------------------------------------------
* int String_read() - Read data from a string
* ----------------------------------------------------------------------------- */
-int
-String_read(DOH *so, void *buffer, int len) {
+
+static int
+String_read(DOH *so, void *buffer, int len)
+{
int reallen, retlen;
char *cb;
String *s = (String *) ObjData(so);
@@ -328,8 +309,9 @@ String_read(DOH *so, void *buffer, int len) {
/* -----------------------------------------------------------------------------
* int String_write() - Write data to a string
* ----------------------------------------------------------------------------- */
-int
-String_write(DOH *so, void *buffer, int len) {
+static int
+String_write(DOH *so, void *buffer, int len)
+{
int newlen;
String *s = (String *) ObjData(so);
s->hashkey = -1;
@@ -351,8 +333,10 @@ String_write(DOH *so, void *buffer, int len) {
/* -----------------------------------------------------------------------------
* int String_seek() - Seek to a new position
* ----------------------------------------------------------------------------- */
-int
-String_seek(DOH *so, long offset, int whence) {
+
+static int
+String_seek(DOH *so, long offset, int whence)
+{
int pos, nsp, inc;
int prev;
String *s = (String *) ObjData(so);
@@ -391,8 +375,10 @@ String_seek(DOH *so, long offset, int whence) {
/* -----------------------------------------------------------------------------
* long String_tell() - Return current position
* ----------------------------------------------------------------------------- */
-long
-String_tell(DOH *so) {
+
+static long
+String_tell(DOH *so)
+{
String *s = (String *) ObjData(so);
return (long) (s->sp);
}
@@ -401,8 +387,9 @@ String_tell(DOH *so) {
* int String_putc()
* ----------------------------------------------------------------------------- */
-int
-String_putc(DOH *so, int ch) {
+static int
+String_putc(DOH *so, int ch)
+{
register int len, maxsize, sp;
String *s = (String *) ObjData(so);
s->hashkey = -1;
@@ -435,7 +422,9 @@ String_putc(DOH *so, int ch) {
* int String_getc()
* ----------------------------------------------------------------------------- */
-int String_getc(DOH *so) {
+static int
+String_getc(DOH *so)
+{
int c;
String *s = (String *) ObjData(so);
if (s->sp >= s->len)
@@ -450,7 +439,9 @@ int String_getc(DOH *so) {
* int String_ungetc()
* ----------------------------------------------------------------------------- */
-int String_ungetc(DOH *so, int ch) {
+static int
+String_ungetc(DOH *so, int ch)
+{
String *s = (String *) ObjData(so);
if (ch == EOF) return ch;
if (s->sp <= 0) return EOF;
@@ -466,7 +457,9 @@ int String_ungetc(DOH *so, int ch) {
* Replaces count non-overlapping occurrences of token with rep in a string.
* ----------------------------------------------------------------------------- */
-static char *end_quote(char *s) {
+static char *
+end_quote(char *s)
+{
char qc;
char *q;
qc = *s;
@@ -478,11 +471,15 @@ static char *end_quote(char *s) {
}
}
-static char *match_simple(char *base, char *s, char *token, int tokenlen) {
+static char *
+match_simple(char *base, char *s, char *token, int tokenlen)
+{
return strstr(s,token);
}
-static char *match_identifier(char *base, char *s, char *token, int tokenlen) {
+static char *
+match_identifier(char *base, char *s, char *token, int tokenlen)
+{
while (s) {
s = strstr(s,token);
if (!s) return 0;
@@ -499,8 +496,8 @@ static char *match_identifier(char *base, char *s, char *token, int tokenlen) {
return 0;
}
-static
-int replace_simple(String *str, char *token, char *rep, int flags, int count, char *(*match)(char *, char *, char *, int))
+static int
+replace_simple(String *str, char *token, char *rep, int flags, int count, char *(*match)(char *, char *, char *, int))
{
int tokenlen; /* Length of the token */
int replen; /* Length of the replacement */
@@ -513,7 +510,10 @@ int replace_simple(String *str, char *token, char *rep, int flags, int count, ch
register char *base;
int i;
+ str->hashkey = -1;
+
/* Figure out if anything gets replaced */
+ if (!strlen(token)) return 0;
base = str->str;
tokenlen = strlen(token);
@@ -706,11 +706,12 @@ int replace_simple(String *str, char *token, char *rep, int flags, int count, ch
* int String_replace()
* ----------------------------------------------------------------------------- */
-int
+static int
String_replace(DOH *stro, DOH *token, DOH *rep, int flags)
{
int count = -1;
String *str = (String *) ObjData(stro);
+
if (flags & DOH_REPLACE_FIRST) count = 1;
if (flags & DOH_REPLACE_ID) {
@@ -724,8 +725,9 @@ String_replace(DOH *stro, DOH *token, DOH *rep, int flags)
* void String_chop(DOH *str)
* ----------------------------------------------------------------------------- */
-void
-String_chop(DOH *so) {
+static void
+String_chop(DOH *so)
+{
char *c;
String *str = (String *) ObjData(so);
/* Replace trailing whitespace */
@@ -743,7 +745,9 @@ String_chop(DOH *so) {
str->hashkey = -1;
}
-void String_setfile(DOH *so, DOH *file) {
+static void
+String_setfile(DOH *so, DOH *file)
+{
DOH *fo;
String *str = (String *) ObjData(so);
@@ -756,17 +760,23 @@ void String_setfile(DOH *so, DOH *file) {
str->file = fo;
}
-DOH *String_getfile(DOH *so) {
+static DOH *
+String_getfile(DOH *so)
+{
String *str = (String *) ObjData(so);
return str->file;
}
-void String_setline(DOH *so, int line) {
+static void
+String_setline(DOH *so, int line)
+{
String *str = (String *) ObjData(so);
str->line = line;
}
-int String_getline(DOH *so) {
+static int
+String_getline(DOH *so)
+{
String *str = (String *) ObjData(so);
return str->line;
}
@@ -778,7 +788,6 @@ static DohListMethods StringListMethods = {
String_insert, /* doh_insitem */
0, /* doh_first */
0, /* doh_next */
- 0, /* doh_sort */
};
static DohFileMethods StringFileMethods = {
@@ -797,7 +806,7 @@ static DohStringMethods StringStringMethods = {
String_chop,
};
-static DohObjInfo StringType = {
+DohObjInfo DohStringType = {
"String", /* objname */
DelString, /* doh_del */
CopyString, /* doh_copy */
@@ -823,21 +832,16 @@ static DohObjInfo StringType = {
#define INIT_MAXSIZE 16
-
/* -----------------------------------------------------------------------------
* NewString(const char *c) - Create a new string
* ----------------------------------------------------------------------------- */
+
DOHString *
-NewString(const DOH *so)
+DohNewString(const DOH *so)
{
int l = 0, max;
String *str;
char *s;
- static int init = 0;
- if (!init) {
- DohRegisterType(DOHTYPE_STRING, &StringType);
- init = 1;
- }
if (DohCheck(so)) s = Char(so);
else s = (char *) so;
str = (String *) DohMalloc(sizeof(String));
@@ -860,7 +864,7 @@ NewString(const DOH *so)
str->str[0] = 0;
str->len = 0;
}
- return DohObjMalloc(DOHTYPE_STRING,str);
+ return DohObjMalloc(&DohStringType,str);
}
/* -----------------------------------------------------------------------------
@@ -870,7 +874,7 @@ NewString(const DOH *so)
* ----------------------------------------------------------------------------- */
DOHString *
-NewStringf(const DOH *fmt, ...)
+DohNewStringf(const DOH *fmt, ...)
{
va_list ap;
DOH *r;
@@ -880,3 +884,28 @@ NewStringf(const DOH *fmt, ...)
va_end(ap);
return (DOHString *) r;
}
+
+/* -----------------------------------------------------------------------------
+ * Strcmp()
+ * Strncmp()
+ * Strstr()
+ * Strchr()
+ *
+ * Some utility functions.
+ * ----------------------------------------------------------------------------- */
+
+int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2) {
+ return strcmp(Char(s1),Char(s2));
+}
+
+int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n) {
+ return strncmp(Char(s1),Char(s2),n);
+}
+
+char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2) {
+ return strstr(Char(s1),Char(s2));
+}
+
+char *DohStrchr(const DOHString_or_char *s1, int ch) {
+ return strchr(Char(s1),ch);
+}
diff --git a/Source/DOH/Doh/void.c b/Source/DOH/Doh/void.c
index 63a94ea91..387062e1f 100644
--- a/Source/DOH/Doh/void.c
+++ b/Source/DOH/Doh/void.c
@@ -10,7 +10,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_void_c[] = "$Header$";
#include "dohint.h"
@@ -88,15 +88,10 @@ static DohObjInfo DohVoidType = {
* ----------------------------------------------------------------------------- */
DOH *
-NewVoid(void *obj, void (*del)(void *)) {
- static int init = 0;
+DohNewVoid(void *obj, void (*del)(void *)) {
VoidObj *v;
- if (!init) {
- DohRegisterType(DOHTYPE_VOID, &DohVoidType);
- init = 1;
- }
v = (VoidObj *) DohMalloc(sizeof(VoidObj));
v->ptr = obj;
v->del = del;
- return DohObjMalloc(DOHTYPE_VOID,v);
+ return DohObjMalloc(&DohVoidType,v);
}
diff --git a/Source/DOH/Include/doh.h b/Source/DOH/Include/doh.h
index e40ced2f3..29c4acf95 100644
--- a/Source/DOH/Include/doh.h
+++ b/Source/DOH/Include/doh.h
@@ -14,6 +14,105 @@
#ifndef _DOH_H
#define _DOH_H
+/* Set the namespace prefix for DOH API functions. This can be used to control
+ visibility of the functions in libraries */
+
+/* Set this macro if you want to change DOH linkage. You would do this if you
+ wanted to hide DOH in a library using a different set of names. Note: simply
+ change "Doh" to a new name. */
+
+/*
+#define DOH_NAMESPACE(x) Doh ## x
+*/
+
+#ifdef DOH_NAMESPACE
+
+/* Namespace control. These macros define all of the public API names in DOH */
+
+#define DohCheck DOH_NAMESPACE(Check)
+#define DohIntern DOH_NAMESPACE(Intern)
+#define DohDelete DOH_NAMESPACE(Delete)
+#define DohCopy DOH_NAMESPACE(Copy)
+#define DohClear DOH_NAMESPACE(Clear)
+#define DohStr DOH_NAMESPACE(Str)
+#define DohData DOH_NAMESPACE(Data)
+#define DohDump DOH_NAMESPACE(Dump)
+#define DohLen DOH_NAMESPACE(Len)
+#define DohHashval DOH_NAMESPACE(Hashval)
+#define DohCmp DOH_NAMESPACE(Cmp)
+#define DohIncref DOH_NAMESPACE(Incref)
+#define DohGetattr DOH_NAMESPACE(Getattr)
+#define DohSetattr DOH_NAMESPACE(Setattr)
+#define DohDelattr DOH_NAMESPACE(Delattr)
+#define DohFirstkey DOH_NAMESPACE(Firstkey)
+#define DohNextkey DOH_NAMESPACE(Nextkey)
+#define DohKeys DOH_NAMESPACE(Keys)
+#define DohGetInt DOH_NAMESPACE(GetInt)
+#define DohGetDouble DOH_NAMESPACE(GetDouble)
+#define DohGetChar DOH_NAMESPACE(GetChar)
+#define DohSetChar DOH_NAMESPACE(SetChar)
+#define DohSetInt DOH_NAMESPACE(SetInt)
+#define DohSetDouble DOH_NAMESPACE(SetDouble)
+#define DohSetVoid DOH_NAMESPACE(SetVoid)
+#define DohGetVoid DOH_NAMESPACE(GetVoid)
+#define DohGetitem DOH_NAMESPACE(Getitem)
+#define DohSetitem DOH_NAMESPACE(Setitem)
+#define DohDelitem DOH_NAMESPACE(Delitem)
+#define DohInsertitem DOH_NAMESPACE(Insertitem)
+#define DohFirstitem DOH_NAMESPACE(Firstitem)
+#define DohNextitem DOH_NAMESPACE(Nextitem)
+#define DohWrite DOH_NAMESPACE(Write)
+#define DohRead DOH_NAMESPACE(Read)
+#define DohSeek DOH_NAMESPACE(Seek)
+#define DohTell DOH_NAMESPACE(Tell)
+#define DohGetc DOH_NAMESPACE(Getc)
+#define DohPutc DOH_NAMESPACE(Putc)
+#define DohUngetc DOH_NAMESPACE(Ungetc)
+#define DohGetline DOH_NAMESPACE(Getline)
+#define DohSetline DOH_NAMESPACE(Setline)
+#define DohGetfile DOH_NAMESPACE(Getfile)
+#define DohSetfile DOH_NAMESPACE(Setfile)
+#define DohReplace DOH_NAMESPACE(Replace)
+#define DohChop DOH_NAMESPACE(Chop)
+#define DohGetmeta DOH_NAMESPACE(Getmeta)
+#define DohSetmeta DOH_NAMESPACE(Setmeta)
+#define DohDelmeta DOH_NAMESPACE(Delmeta)
+#define DohEncoding DOH_NAMESPACE(Encoding)
+#define DohPrintf DOH_NAMESPACE(Printf)
+#define DohvPrintf DOH_NAMESPACE(vPrintf)
+#define DohPrintv DOH_NAMESPACE(Printv)
+#define DohReadline DOH_NAMESPACE(Readline)
+#define DohIsMapping DOH_NAMESPACE(IsMapping)
+#define DohIsSequence DOH_NAMESPACE(IsSequence)
+#define DohIsString DOH_NAMESPACE(IsString)
+#define DohIsFile DOH_NAMESPACE(IsFile)
+#define DohNewString DOH_NAMESPACE(NewString)
+#define DohNewStringf DOH_NAMESPACE(NewStringf)
+#define DohStrcmp DOH_NAMESPACE(Strcmp)
+#define DohStrncmp DOH_NAMESPACE(Strncmp)
+#define DohStrstr DOH_NAMESPACE(Strstr)
+#define DohStrchr DOH_NAMESPACE(Strchr)
+#define DohNewFile DOH_NAMESPACE(NewFile)
+#define DohNewFileFromFile DOH_NAMESPACE(NewFileFromFile)
+#define DohNewFileFromFd DOH_NAMESPACE(NewFileFromFd)
+#define DohClose DOH_NAMESPACE(Close)
+#define DohCopyto DOH_NAMESPACE(Copyto)
+#define DohNewList DOH_NAMESPACE(NewList)
+#define DohNewHash DOH_NAMESPACE(NewHash)
+#define DohNewVoid DOH_NAMESPACE(NewVoid)
+#define DohSplit DOH_NAMESPACE(Split)
+#define DohNone DOH_NAMESPACE(None)
+
+#define DohObjMalloc DOH_NAMESPACE(ObjMalloc)
+#define DohObjFree DOH_NAMESPACE(ObjFree)
+#define DohStringType DOH_NAMESPACE(StringType)
+#define DohListType DOH_NAMESPACE(ListType)
+#define DohHashType DOH_NAMESPACE(HashType)
+#define DohFileType DOH_NAMESPACE(FileType)
+#define DohVoidType DOH_NAMESPACE(VoidType)
+
+#endif
+
#include <stdio.h>
#include <stdarg.h>
@@ -53,8 +152,8 @@ typedef void DOH;
#define DohFree free
#endif
-extern int DohCheck(const DOH *ptr); /* Check if a DOH object */
-extern void DohIntern(DOH *); /* Intern an object */
+extern int DohCheck(const DOH *ptr); /* Check if a DOH object */
+extern void DohIntern(DOH *); /* Intern an object */
/* Basic object methods. Common to most objects */
@@ -71,64 +170,126 @@ extern void DohIncref(DOH *obj);
/* Mapping methods */
-extern DOH *DohGetattr(DOH *obj, const DOHString_or_char *name);
-extern int DohSetattr(DOH *obj, const DOHString_or_char *name, const DOHObj_or_char *value);
-extern void DohDelattr(DOH *obj, const DOHString_or_char *name);
-extern DOH *DohFirstkey(DOH *obj);
-extern DOH *DohNextkey(DOH *obj);
-extern int DohGetInt(DOH *obj, const DOHString_or_char *name);
-extern double DohGetDouble(DOH *obj, const DOHString_or_char *name);
-extern char *DohGetChar(DOH *obj, const DOHString_or_char *name);
-extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int);
-extern void DohSetDouble(DOH *obj, const DOHString_or_char *name, double);
-extern void *DohGetVoid(DOH *obj, const DOHString_or_char *name);
-extern void DohSetVoid(DOH *obj, const DOHString_or_char *name, void *value);
+extern DOH *DohGetattr(DOH *obj, const DOHString_or_char *name);
+extern int DohSetattr(DOH *obj, const DOHString_or_char *name, const DOHObj_or_char *value);
+extern int DohDelattr(DOH *obj, const DOHString_or_char *name);
+extern DOH *DohFirstkey(DOH *obj);
+extern DOH *DohNextkey(DOH *obj);
+extern DOH *DohKeys(DOH *obj);
+extern int DohGetInt(DOH *obj, const DOHString_or_char *name);
+extern double DohGetDouble(DOH *obj, const DOHString_or_char *name);
+extern char *DohGetChar(DOH *obj, const DOHString_or_char *name);
+extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int);
+extern void DohSetDouble(DOH *obj, const DOHString_or_char *name, double);
+extern void *DohGetVoid(DOH *obj, const DOHString_or_char *name);
+extern void DohSetVoid(DOH *obj, const DOHString_or_char *name, void *value);
/* Sequence methods */
-extern DOH *DohGetitem(DOH *obj, int index);
-extern int DohSetitem(DOH *obj, int index, const DOHObj_or_char *value);
-extern int DohDelitem(DOH *obj, int index);
-extern int DohInsertitem(DOH *obj, int index, const DOHObj_or_char *value);
-extern DOH *DohFirstitem(DOH *obj);
-extern DOH *DohNextitem(DOH *obj);
+extern DOH *DohGetitem(DOH *obj, int index);
+extern int DohSetitem(DOH *obj, int index, const DOHObj_or_char *value);
+extern int DohDelitem(DOH *obj, int index);
+extern int DohInsertitem(DOH *obj, int index, const DOHObj_or_char *value);
+extern DOH *DohFirstitem(DOH *obj);
+extern DOH *DohNextitem(DOH *obj);
/* File methods */
-extern int DohWrite(DOHFile *obj, void *buffer, int length);
-extern int DohRead(DOHFile *obj, void *buffer, int length);
-extern int DohSeek(DOHFile *obj, long offset, int whence);
-extern long DohTell(DOHFile *obj);
-extern int DohGetc(DOHFile *obj);
-extern int DohPutc(int ch, DOHFile *obj);
-extern int DohUngetc(int ch, DOHFile *obj);
+extern int DohWrite(DOHFile *obj, void *buffer, int length);
+extern int DohRead(DOHFile *obj, void *buffer, int length);
+extern int DohSeek(DOHFile *obj, long offset, int whence);
+extern long DohTell(DOHFile *obj);
+extern int DohGetc(DOHFile *obj);
+extern int DohPutc(int ch, DOHFile *obj);
+extern int DohUngetc(int ch, DOHFile *obj);
/* Positional */
-extern int DohGetline(DOH *obj);
-extern void DohSetline(DOH *obj, int line);
-extern DOH *DohGetfile(DOH *obj);
-extern void DohSetfile(DOH *obj, DOH *file);
+extern int DohGetline(DOH *obj);
+extern void DohSetline(DOH *obj, int line);
+extern DOH *DohGetfile(DOH *obj);
+extern void DohSetfile(DOH *obj, DOH *file);
/* String Methods */
-extern int DohReplace(DOHString *src, const DOHString_or_char *token, const DOHString_or_char *rep, int flags);
-extern void DohChop(DOHString *src);
+extern int DohReplace(DOHString *src, const DOHString_or_char *token, const DOHString_or_char *rep, int flags);
+extern void DohChop(DOHString *src);
+
+/* Meta-variables */
+extern DOH *DohGetmeta(DOH *, const DOH *);
+extern int DohSetmeta(DOH *, const DOH *, const DOH *value);
+extern int DohDelmeta(DOH *, const DOH *);
/* Utility functions */
-extern void DohEncoding(char *name, DOH *(*fn)(DOH *s));
-extern int DohPrintf(DOHFile *obj, const char *format, ...);
-extern int DohvPrintf(DOHFile *obj, const char *format, va_list ap);
-extern int DohPrintv(DOHFile *obj, ...);
-extern DOH *DohReadline(DOHFile *in);
+extern void DohEncoding(char *name, DOH *(*fn)(DOH *s));
+extern int DohPrintf(DOHFile *obj, const char *format, ...);
+extern int DohvPrintf(DOHFile *obj, const char *format, va_list ap);
+extern int DohPrintv(DOHFile *obj, ...);
+extern DOH *DohReadline(DOHFile *in);
/* Miscellaneous */
-extern int DohIsMapping(const DOH *obj);
-extern int DohIsSequence(const DOH *obj);
-extern int DohIsString(const DOH *obj);
-extern int DohIsFile(const DOH *obj);
+extern int DohIsMapping(const DOH *obj);
+extern int DohIsSequence(const DOH *obj);
+extern int DohIsString(const DOH *obj);
+extern int DohIsFile(const DOH *obj);
+
+extern void DohSetmark(DOH *obj, int x);
+extern int DohGetmark(DOH *obj);
+
+/* -----------------------------------------------------------------------------
+ * Strings.
+ * ----------------------------------------------------------------------------- */
+
+extern DOHString *DohNewString(const DOH *c);
+extern DOHString *DohNewStringf(const DOH *fmt, ...);
+
+extern int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2);
+extern int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n);
+extern char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2);
+extern char *DohStrchr(const DOHString_or_char *s1, int ch);
+
+/* String replacement flags */
+
+#define DOH_REPLACE_ANY 0x01
+#define DOH_REPLACE_NOQUOTE 0x02
+#define DOH_REPLACE_ID 0x04
+#define DOH_REPLACE_FIRST 0x08
+
+#define Replaceall(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ANY)
+#define Replaceid(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ID)
+
+/* -----------------------------------------------------------------------------
+ * Files
+ * ----------------------------------------------------------------------------- */
+
+extern DOHFile *DohNewFile(DOH *file, const char *mode);
+extern DOHFile *DohNewFileFromFile(FILE *f);
+extern DOHFile *DohNewFileFromFd(int fd);
+extern int DohClose(DOH *file);
+extern int DohCopyto(DOHFile *input, DOHFile *output);
+
+
+/* -----------------------------------------------------------------------------
+ * List
+ * ----------------------------------------------------------------------------- */
+
+extern DOHList *DohNewList();
+
+/* -----------------------------------------------------------------------------
+ * Hash
+ * ----------------------------------------------------------------------------- */
+
+extern DOHHash *DohNewHash();
+
+/* -----------------------------------------------------------------------------
+ * Void
+ * ----------------------------------------------------------------------------- */
+
+extern DOHVoid *DohNewVoid(void *ptr, void (*del)(void *));
+extern DOHList *DohSplit(DOHFile *input, char ch, int nsplits);
+extern DOH *DohNone;
#ifndef DOH_LONG_NAMES
/* Macros to invoke the above functions. Includes the location of
@@ -168,6 +329,7 @@ extern int DohIsFile(const DOH *obj);
#define Getc DohGetc
#define Putc DohPutc
#define Ungetc DohUngetc
+#define Close DohClose
#define vPrintf DohvPrintf
#define GetInt DohGetInt
#define GetDouble DohGetDouble
@@ -182,57 +344,36 @@ extern int DohIsFile(const DOH *obj);
#define Readline DohReadline
#define Replace DohReplace
#define Chop DohChop
+#define Getmeta DohGetmeta
+#define Setmeta DohSetmeta
+#define Delmeta DohDelmeta
+#define NewString DohNewString
+#define NewStringf DohNewStringf
+#define NewHash DohNewHash
+#define NewList DohNewList
+#define NewFile DohNewFile
+#define NewFileFromFile DohNewFileFromFile
+#define NewFileFromFd DohNewFileFromFd
+#define Close DohClose
+#define NewVoid DohNewVoid
+#define Keys DohKeys
+#define Strcmp DohStrcmp
+#define Strncmp DohStrncmp
+#define Strstr DohStrstr
+#define Strchr DohStrchr
+#define Copyto DohCopyto
+#define Split DohSplit
+#define Setmark DohSetmark
+#define Getmark DohGetmark
+#define None DohNone
#endif
-/* -----------------------------------------------------------------------------
- * Strings.
- * ----------------------------------------------------------------------------- */
-
-extern DOHString *NewString(const DOH *c);
-extern DOHString *NewStringf(const DOH *fmt, ...);
-
-/* String replacement flags */
-
-#define DOH_REPLACE_ANY 0x01
-#define DOH_REPLACE_NOQUOTE 0x02
-#define DOH_REPLACE_ID 0x04
-#define DOH_REPLACE_FIRST 0x08
-
-/* -----------------------------------------------------------------------------
- * Files
- * ----------------------------------------------------------------------------- */
-
-extern DOHFile *NewFile(DOH *file, char *mode);
-extern DOHFile *NewFileFromFile(FILE *f);
-extern DOHFile *NewFileFromFd(int fd);
-
-extern int DohCopyto(DOHFile *input, DOHFile *output);
-
-#define Copyto DohCopyto
-
-/* -----------------------------------------------------------------------------
- * List
- * ----------------------------------------------------------------------------- */
-
-extern DOHList *NewList();
-
-/* -----------------------------------------------------------------------------
- * Hash
- * ----------------------------------------------------------------------------- */
-
-extern DOHHash *NewHash();
-extern DOHList *Hash_keys(DOHHash *);
-
-/* -----------------------------------------------------------------------------
- * Void
- * ----------------------------------------------------------------------------- */
-
-extern DOHVoid *NewVoid(void *ptr, void (*del)(void *));
+#ifdef NIL
+#undef NIL
+#endif
-extern DOHList *DohSplit(DOHFile *input, char *chs, int nsplits);
-#define Split DohSplit
+#define NIL (char *) NULL
-extern DOH *DohNone;
#endif /* DOH_H */
diff --git a/Source/DOH/Include/dohobj.h b/Source/DOH/Include/dohobj.h
index da270e855..1f3ff19c7 100644
--- a/Source/DOH/Include/dohobj.h
+++ b/Source/DOH/Include/dohobj.h
@@ -23,6 +23,7 @@ typedef struct {
int (*doh_delattr)(DOH *obj, DOH *name); /* Del attribute */
DOH *(*doh_firstkey)(DOH *obj); /* First key */
DOH *(*doh_nextkey)(DOH *obj); /* Next key */
+ DOH *(*doh_keys)(DOH *obj); /* All keys as a list */
} DohHashMethods;
/* List objects */
@@ -33,7 +34,6 @@ typedef struct {
int (*doh_insitem)(DOH *obj, int index, DOH *value); /* Insert item */
DOH *(*doh_firstitem)(DOH *obj); /* Iterators */
DOH *(*doh_nextitem)(DOH *obj);
- void (*doh_sort)(DOH *obj, int opt); /* Sort */
} DohListMethods;
/* File methods */
@@ -93,37 +93,29 @@ typedef struct DohObjInfo {
} DohObjInfo;
typedef struct {
- void *data; /* Data pointer */
- unsigned int type : 4; /* Object type (max 16 -- deal with it) */
+ void *data; /* Data pointer */
+ DohObjInfo *type;
+ void *meta; /* Meta data */
int flag_intern : 1; /* Interned object */
int flag_marked : 1; /* Mark flag. Used to avoid recursive loops in places */
int flag_user : 1; /* User flag */
- int flag_reserved : 1; /* Reserved flag */
- int refcount : 24; /* Reference count (max 16 million) */
+ int flag_usermark : 1; /* User marked */
+ int refcount : 28; /* Reference count (max 16 million) */
} DohBase;
/* Macros for decrefing and increfing (safe for null objects). */
-#define Decref(a) if (a) ((DohBase *) a)->refcount--
-#define Incref(a) if (a) ((DohBase *) a)->refcount++
-#define Refcount(a) ((DohBase *) a)->refcount
+#define Decref(a) if (a) ((DohBase *) a)->refcount--
+#define Incref(a) if (a) ((DohBase *) a)->refcount++
+#define Refcount(a) ((DohBase *) a)->refcount
/* Macros for manipulating objects in a safe manner */
-#define ObjData(a) ((DohBase *)a)->data
-#define ObjSetMark(a,x) ((DohBase *)a)->flag_marked = x
-#define ObjGetMark(a) ((DohBase *)a)->flag_marked
-#define ObjType(a) ((DohBase *)a)->type
+#define ObjData(a) ((DohBase *)a)->data
+#define ObjSetMark(a,x) ((DohBase *)a)->flag_marked = x
+#define ObjGetMark(a) ((DohBase *)a)->flag_marked
+#define ObjType(a) ((DohBase *)a)->type
-extern DOH *DohObjMalloc(int type, void *data); /* Allocate a DOH object */
+extern DOH *DohObjMalloc(DohObjInfo *type, void *data); /* Allocate a DOH object */
extern void DohObjFree(DOH *ptr); /* Free a DOH object */
-extern void DohRegisterType(int type, DohObjInfo *objinfo);
-
-#define MAX_DOHTYPE 16
-
-#define DOHTYPE_STRING 1
-#define DOHTYPE_LIST 2
-#define DOHTYPE_HASH 3
-#define DOHTYPE_VOID 4
-#define DOHTYPE_FILE 5
#endif /* DOHOBJ_H */
diff --git a/Source/DOH/Makefile.in b/Source/DOH/Makefile.in
index f5d9b775c..bfa253c43 100644
--- a/Source/DOH/Makefile.in
+++ b/Source/DOH/Makefile.in
@@ -10,8 +10,6 @@ exec_prefix= @exec_prefix@
INCLUDE_DIR = $(prefix)/include
LIB_DIR = $(exec_prefix)/lib
-DOHOPT =
-
# Installer
INSTALL = ./install-sh -c
@@ -19,7 +17,7 @@ INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM= ${INSTALL} -m 755
all:
- cd Doh; $(MAKE) DOHOPT='$(DOHOPT)'
+ cd Doh; $(MAKE)
install:
@echo "Installing $(LIB_DIR)/libdoh.a..."
diff --git a/Source/DOH/configure.in b/Source/DOH/configure.in
index 61c8240f9..11f2272ea 100644
--- a/Source/DOH/configure.in
+++ b/Source/DOH/configure.in
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(Include/doh.h)
-AC_PREREQ(2.0)
+AC_PREREQ(2.53)
# Set name for machine-dependent library files
AC_SUBST(MACHDEP)
@@ -41,4 +41,4 @@ dnl Checks for header files.
AC_HEADER_STDC
dnl Checks for library functions.
-AC_OUTPUT(Makefile Doh/Makefile )
+AC_OUTPUT(Makefile Doh/Makefile)
diff --git a/Source/Include/.cvsignore b/Source/Include/.cvsignore
new file mode 100644
index 000000000..1c3642b87
--- /dev/null
+++ b/Source/Include/.cvsignore
@@ -0,0 +1,3 @@
+swigconfig.h
+swigver.h
+
diff --git a/Source/Include/swigconfig.h.in b/Source/Include/swigconfig.h.in
index 7a02d27fb..f5f3e6e18 100644
--- a/Source/Include/swigconfig.h.in
+++ b/Source/Include/swigconfig.h.in
@@ -1,6 +1,19 @@
-/* This file contains SWIG specific configuration data for those modules
+/* This -*-c-*- file contains SWIG specific configuration data for those modules
that care */
-#define SWIG_LIB "@prefix@/lib/swig1.3"
-#define SWIG_LANG TCL8
+/* Directory where to find the machine-independent SWIG files */
+#define SWIG_LIB "@-swig_lib-@"
+
+/* Default language */
+
+#define SWIG_LANG "-tcl"
+
+/* Values returned by swig when invoked with the -ldflags option */
+
+#define SWIG_PERL_RUNTIME "-L@-exec_prefix-@/lib -lswigpl@-release_suffix-@"
+#define SWIG_PYTHON_RUNTIME "-L@-exec_prefix-@/lib -lswigpy@-release_suffix-@"
+#define SWIG_TCL_RUNTIME "-L@-exec_prefix-@/lib -lswigtcl@-release_suffix-@"
+#define SWIG_RUBY_RUNTIME "-L@-exec_prefix-@/lib -lswigrb@-release_suffix-@"
+#define SWIG_GUILE_RUNTIME "-L@-exec_prefix-@/lib -lswigguile@-release_suffix-@"
+#define SWIG_PIKE_RUNTIME "-L@-exec_prefix-@/lib -lswigpike@-release_suffix-@"
diff --git a/Source/Include/swigver.h b/Source/Include/swigver.h
deleted file mode 100644
index c71b6b080..000000000
--- a/Source/Include/swigver.h
+++ /dev/null
@@ -1,10 +0,0 @@
-
-/* SWIG version information */
-
-#ifndef SWIG_VERSION
-#define SWIG_VERSION "1.3u-20001219-1815"
-#endif
-
-#ifndef SWIG_SPIN
-#define SWIG_SPIN "(Alpha 6)"
-#endif
diff --git a/Source/Include/swigver.h.in b/Source/Include/swigver.h.in
index 3f6f4acdd..7d35580ea 100644
--- a/Source/Include/swigver.h.in
+++ b/Source/Include/swigver.h.in
@@ -5,6 +5,14 @@
#define SWIG_VERSION "@SWIG_VERSION@"
#endif
+#ifndef SWIG_MAJOR_VERSION
+#define SWIG_MAJOR_VERSION @SWIG_MAJOR_VERSION@
+#endif
+
+#ifndef SWIG_MINOR_VERSION
+#define SWIG_MINOR_VERSION @SWIG_MINOR_VERSION@
+#endif
+
#ifndef SWIG_SPIN
-#define SWIG_SPIN "@SWIG_SPIN@"
+#define SWIG_SPIN @SWIG_SPIN@
#endif
diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h
new file mode 100644
index 000000000..cb4a96346
--- /dev/null
+++ b/Source/Include/swigwarn.h
@@ -0,0 +1,186 @@
+/* SWIG warning message numbers
+
+ This file serves as the main registry of warning message numbers. Some of these
+ numbers are used internally in the C/C++ source code of SWIG. However, some
+ of the numbers are used in SWIG configuration files (swig.swg and others).
+
+ The numbers are roughly organized into a few different classes by functionality.
+
+ Even though symbolic constants are used in the SWIG source, this is
+ not always the case in SWIG interface files. Do not change the
+ numbers in this file.
+
+ */
+
+
+
+
+#ifndef _SWIGWARN_H
+#define _SWIGWARN_H 1
+
+#define WARN_NONE 0
+
+/* -- Deprecated features -- */
+
+#define WARN_DEPRECATED_EXTERN 101
+#define WARN_DEPRECATED_VAL 102
+#define WARN_DEPRECATED_OUT 103
+#define WARN_DEPRECATED_DISABLEDOC 104
+#define WARN_DEPRECATED_ENABLEDOC 105
+#define WARN_DEPRECATED_DOCONLY 106
+#define WARN_DEPRECATED_STYLE 107
+#define WARN_DEPRECATED_LOCALSTYLE 108
+#define WARN_DEPRECATED_TITLE 109
+#define WARN_DEPRECATED_SECTION 110
+#define WARN_DEPRECATED_SUBSECTION 111
+#define WARN_DEPRECATED_SUBSUBSECTION 112
+#define WARN_DEPRECATED_ADDMETHODS 113
+#define WARN_DEPRECATED_READONLY 114
+#define WARN_DEPRECATED_READWRITE 115
+#define WARN_DEPRECATED_EXCEPT 116
+#define WARN_DEPRECATED_NEW 117
+#define WARN_DEPRECATED_EXCEPT_TM 118
+#define WARN_DEPRECATED_IGNORE_TM 119
+
+/* -- Preprocessor -- */
+
+#define WARN_PP_MISSING_FILE 201
+#define WARN_PP_EVALUATION 202
+
+/* -- C/C++ Parser -- */
+
+#define WARN_PARSE_CLASS_KEYWORD 301
+#define WARN_PARSE_REDEFINED 302
+#define WARN_PARSE_EXTEND_UNDEF 303
+#define WARN_PARSE_UNSUPPORTED_VALUE 304
+#define WARN_PARSE_BAD_VALUE 305
+#define WARN_PARSE_PRIVATE 306
+#define WARN_PARSE_BAD_DEFAULT 307
+#define WARN_PARSE_NAMESPACE_ALIAS 308
+#define WARN_PARSE_PRIVATE_INHERIT 309
+#define WARN_PARSE_TEMPLATE_REPEAT 310
+#define WARN_PARSE_TEMPLATE_PARTIAL 311
+#define WARN_PARSE_NESTED_CLASS 312
+#define WARN_PARSE_UNDEFINED_EXTERN 313
+#define WARN_PARSE_KEYWORD 314
+#define WARN_PARSE_USING_UNDEF 315
+#define WARN_PARSE_MODULE_REPEAT 316
+#define WARN_PARSE_TEMPLATE_SP_UNDEF 317
+#define WARN_PARSE_TEMPLATE_AMBIG 318
+#define WARN_PARSE_NO_ACCESS 319
+
+#define WARN_IGNORE_OPERATOR_NEW 350 /* new */
+#define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */
+#define WARN_IGNORE_OPERATOR_PLUS 352 /* + */
+#define WARN_IGNORE_OPERATOR_MINUS 353 /* - */
+#define WARN_IGNORE_OPERATOR_MUL 354 /* * */
+#define WARN_IGNORE_OPERATOR_DIV 355 /* / */
+#define WARN_IGNORE_OPERATOR_MOD 356 /* % */
+#define WARN_IGNORE_OPERATOR_XOR 357 /* ^ */
+#define WARN_IGNORE_OPERATOR_AND 358 /* & */
+#define WARN_IGNORE_OPERATOR_OR 359 /* | */
+#define WARN_IGNORE_OPERATOR_NOT 360 /* ~ */
+#define WARN_IGNORE_OPERATOR_LNOT 361 /* ! */
+#define WARN_IGNORE_OPERATOR_EQ 362 /* = */
+#define WARN_IGNORE_OPERATOR_LT 363 /* < */
+#define WARN_IGNORE_OPERATOR_GT 364 /* > */
+#define WARN_IGNORE_OPERATOR_PLUSEQ 365 /* += */
+#define WARN_IGNORE_OPERATOR_MINUSEQ 366 /* -= */
+#define WARN_IGNORE_OPERATOR_MULEQ 367 /* *= */
+#define WARN_IGNORE_OPERATOR_DIVEQ 368 /* /= */
+#define WARN_IGNORE_OPERATOR_MODEQ 369 /* %= */
+#define WARN_IGNORE_OPERATOR_XOREQ 370 /* ^= */
+#define WARN_IGNORE_OPERATOR_ANDEQ 371 /* &= */
+#define WARN_IGNORE_OPERATOR_OREQ 372 /* |= */
+#define WARN_IGNORE_OPERATOR_LSHIFT 373 /* << */
+#define WARN_IGNORE_OPERATOR_RSHIFT 374 /* >> */
+#define WARN_IGNORE_OPERATOR_LSHIFTEQ 375 /* <<= */
+#define WARN_IGNORE_OPERATOR_RSHIFTEQ 376 /* >>= */
+#define WARN_IGNORE_OPERATOR_EQUALTO 377 /* == */
+#define WARN_IGNORE_OPERATOR_NOTEQUAL 378 /* != */
+#define WARN_IGNORE_OPERATOR_LTEQUAL 379 /* <= */
+#define WARN_IGNORE_OPERATOR_GTEQUAL 380 /* >= */
+#define WARN_IGNORE_OPERATOR_LAND 381 /* && */
+#define WARN_IGNORE_OPERATOR_LOR 382 /* || */
+#define WARN_IGNORE_OPERATOR_PLUSPLUS 383 /* ++ */
+#define WARN_IGNORE_OPERATOR_MINUSMINUS 384 /* -- */
+#define WARN_IGNORE_OPERATOR_COMMA 385 /* , */
+#define WARN_IGNORE_OPERATOR_ARROWSTAR 386 /* ->* */
+#define WARN_IGNORE_OPERATOR_ARROW 387 /* -> */
+#define WARN_IGNORE_OPERATOR_CALL 388 /* () */
+#define WARN_IGNORE_OPERATOR_INDEX 389 /* [] */
+#define WARN_IGNORE_OPERATOR_UPLUS 390 /* + */
+#define WARN_IGNORE_OPERATOR_UMINUS 391 /* - */
+#define WARN_IGNORE_OPERATOR_UMUL 392 /* * */
+#define WARN_IGNORE_OPERATOR_UAND 393 /* & */
+#define WARN_IGNORE_OPERATOR_NEWARR 394 /* new [] */
+#define WARN_IGNORE_OEPRATOR_DELARR 395 /* delete [] */
+
+/* 394-399 are reserved */
+
+/* -- Type system and typemaps -- */
+
+#define WARN_TYPE_UNDEFINED_CLASS 401
+#define WARN_TYPE_INCOMPLETE 402
+#define WARN_TYPE_ABSTRACT 403
+#define WARN_TYPE_REDEFINED 404
+
+#define WARN_TYPEMAP_SOURCETARGET 450
+#define WARN_TYPEMAP_CHARLEAK 451
+#define WARN_TYPEMAP_SWIGTYPE 452
+#define WARN_TYPEMAP_APPLY_UNDEF 453
+
+#define WARN_TYPEMAP_IN_UNDEF 460
+#define WARN_TYPEMAP_OUT_UNDEF 461
+#define WARN_TYPEMAP_VARIN_UNDEF 462
+#define WARN_TYPEMAP_VAROUT_UNDEF 463
+#define WARN_TYPEMAP_CONST_UNDEF 464
+#define WARN_TYPEMAP_UNDEF 465
+#define WARN_TYPEMAP_VAR_UNDEF 466
+#define WARN_TYPEMAP_TYPECHECK 467
+#define WARN_TYPEMAP_THROW 468
+
+/* -- General code generation -- */
+
+#define WARN_LANG_OVERLOAD_DECL 501
+#define WARN_LANG_OVERLOAD_CONSTRUCT 502
+#define WARN_LANG_IDENTIFIER 503
+#define WARN_LANG_RETURN_TYPE 504
+#define WARN_LANG_VARARGS 505
+#define WARN_LANG_VARARGS_KEYWORD 506
+#define WARN_LANG_NATIVE_UNIMPL 507
+#define WARN_LANG_DEREF_SHADOW 508
+#define WARN_LANG_OVERLOAD_SHADOW 509
+#define WARN_LANG_FRIEND_IGNORE 510
+#define WARN_LANG_OVERLOAD_KEYWORD 511
+#define WARN_LANG_OVERLOAD_CONST 512
+#define WARN_LANG_CLASS_UNNAMED 513
+
+/* -- Reserved (600-799) -- */
+
+/* -- Language module specific warnings (800 - 999) -- */
+
+#define WARN_RUBY_WRONG_NAME 801
+#define WARN_RUBY_MULTIPLE_INHERITANCE 802
+
+#define WARN_JAVA_TYPEMAP_JNI_UNDEF 810
+#define WARN_JAVA_TYPEMAP_JTYPE_UNDEF 811
+#define WARN_JAVA_TYPEMAP_JSTYPE_UNDEF 812
+#define WARN_JAVA_MULTIPLE_INHERITANCE 813
+#define WARN_JAVA_TYPEMAP_GETCPTR_UNDEF 814
+#define WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF 815
+#define WARN_JAVA_TYPEMAP_PTRCONSTMOD_UNDEF 816
+#define WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF 817
+#define WARN_JAVA_TYPEMAP_JAVAIN_UNDEF 818
+
+/* please leave 810-830 free for Java */
+
+
+
+/* Feel free to claim any number in this space that's not currently being used. Just make sure you
+ add an entry here */
+
+#endif
+
+
+
diff --git a/Source/Modules1.1/Makefile.in b/Source/Modules1.1/Makefile.in
index 509f7effe..bfa308a2f 100644
--- a/Source/Modules1.1/Makefile.in
+++ b/Source/Modules1.1/Makefile.in
@@ -7,32 +7,25 @@ VPATH = @srcdir@
SHELL = /bin/sh
CXX = @CXX@
-CFLAGS = @CFLAGS@
+CFLAGS = @CFLAGS@ @SWILL@
YACC = @YACC@
AR = @AR@
RANLIB = @RANLIB@
TARGET = libmodules11.a
-COREOBJS = main.o emit.o lang.o generate.o
-CORESRCS = main.cxx emit.cxx lang.cxx generate.cxx
+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
-LANGOBJS = tcl8.o python.o perl5.o guile.o ruby.o mzscheme.o #java.o
-LANGSRCS = tcl8.cxx python.cxx perl5.cxx guile.cxx ruby.cxx mzscheme.cxx #java.cxx
-
-OBJS = $(COREOBJS) $(LANGOBJS) xml.o
-SRCS = $(CORESRCS) $(LANGSRCS) xml.cxx
-
-INCLUDE = -I$(srcdir)/../Include \
- -I$(srcdir)/../Preprocessor \
- -I$(srcdir)/../LParse \
+INCLUDES = -I$(srcdir)/../Include \
-I$(srcdir)/../DOH/Include \
+ -I$(srcdir)/../Preprocessor \
-I$(srcdir)/../Swig \
-I../Include
-# Rules for creation of a .o file from .cxx
+# Rules for creation of a .@OBJEXT@ file from .cxx
.SUFFIXES: .cxx
-.cxx.o:
- $(CXX) $(INCLUDE) $(CFLAGS) -c -o $*.o $<
+.cxx.@OBJEXT@:
+ $(CXX) $(INCLUDES) $(CFLAGS) -c -o $*.@OBJEXT@ $<
swig: $(TARGET)
@@ -42,7 +35,7 @@ $(TARGET): $(OBJS)
$(RANLIB) $(TARGET)
clean::
- rm -f *.o *~ $(TARGET)
+ rm -f *.@OBJEXT@ *~ $(TARGET)
nuke::
- rm -f Makefile *~ #* core a.out
+ rm -f Makefile *~
diff --git a/Source/Modules1.1/README b/Source/Modules1.1/README
new file mode 100644
index 000000000..058779d22
--- /dev/null
+++ b/Source/Modules1.1/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/Modules1.1/allocate.cxx b/Source/Modules1.1/allocate.cxx
new file mode 100644
index 000000000..4d7db5fae
--- /dev/null
+++ b/Source/Modules1.1/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/Modules1.1/browser.cxx b/Source/Modules1.1/browser.cxx
new file mode 100644
index 000000000..da90a81b8
--- /dev/null
+++ b/Source/Modules1.1/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,"<a name=\"n%x\"></a>[<a href=\"hide.html?node=0x%x&hn=0x%x#n%x\">-</a>] ", n, t, n,n);
+ } else {
+ Printf(out,"<a name=\"n%x\"></a>[<a href=\"show.html?node=0x%x&hn=0x%x#n%x\">+</a>] ", 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,"&","&amp;");
+ Replaceall(o,"<","&lt;");
+ Replaceall(o,">","&gt;");
+ Printf(os,"<a href=\"data.html?n=0x%x\">?</a> %-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,"&","&amp;");
+ Replaceall(o,"<","&lt;");
+ Printf(os,"<a href=\"data.html?n=0x%x\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj,k), k, o, trunc);
+ Delete(o);
+ } else {
+ Printf(os,"<a href=\"data.html?n=0x%x\">?</a> %-12s - 0x%x\n", Getattr(obj,k), k, Getattr(obj,k));
+ }
+ }
+ k = Nextkey(obj);
+ }
+ Printf(out,"<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\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,"<b><a href=\"index.html?node=0x%x\">%s</a></b>", n, tag);
+ if (name) {
+ Printf(out," (%s)", name);
+ }
+ Printf(out,". %s:%d\n", file, line);
+ Printf(out,"<br>");
+ Dispatcher::emit_one(n);
+ return SWIG_OK;
+ }
+ virtual int emit_children(Node *n) {
+ if (Getmeta(n,"visible")) {
+ Printf(out,"<blockquote>\n");
+ Dispatcher::emit_children(n);
+ Printf(out,"</blockquote>\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,"<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", SWIG_VERSION);
+ Printf(f,"<b>SWIG-%s</b><br>\n", SWIG_VERSION);
+ Printf(f,"[ <a href=\"exit.html\">Exit</a> ]");
+ Printf(f," [ <a href=\"index.html?node=0x%x\">Top</a> ]", tree_top);
+ if (n != tree_top) {
+ Printf(f," [ <a href=\"index.html?node=0x%x\">Up</a> ]", parentNode(n));
+ }
+ Printf(f," [ <a href=\"symbol.html\">Symbols</a> ]");
+ Printf(f,"<br><hr><p>\n");
+
+ out = f;
+
+ browse->emit_one(n);
+
+ /* Print standard footer */
+ Printf(f,"<br><hr></BODY></HTML>\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,"<","&lt;");
+ Printf(os," <a href=\"data.html?n=0x%x\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj,k), k, o, trunc);
+ Delete(o);
+ } else {
+ Printf(os," <a href=\"data.html?n=0x%x\">?</a> %-12s - 0x%x\n", Getattr(obj,k), k, Getattr(obj,k));
+ }
+ k = Nextkey(obj);
+ }
+ Printf(os,"}\n");
+ Printf(out,"<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
+ Delete(os);
+ } else if (DohIsString(obj)) {
+ String *o = Str(obj);
+ Replaceall(o,"<","&lt;");
+ Printf(out,"<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\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,"<","&lt;");
+ Printf(os," <a href=\"data.html?n=0x%x\">?</a> [%d] - \"%(escape)-0.70s%s\"\n", o,i,s, trunc);
+ Delete(s);
+ } else {
+ Printf(os," <a href=\"data.html?n=0x%x\">?</a> [%d] - 0x%x\n", o, i, o);
+ }
+ }
+ Printf(os,"\n]\n");
+ Printf(out,"<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
+ Delete(os);
+ }
+}
+
+void data_handler(FILE *f) {
+ DOH *n = 0;
+ if (!swill_getargs("p(n)", &n)) {
+ n = 0;
+ }
+ Printf(f,"<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", SWIG_VERSION);
+ Printf(f,"<b>SWIG-%s</b><br>\n", SWIG_VERSION);
+ Printf(f,"[ <a href=\"exit.html\">Exit</a> ]");
+ Printf(f," [ <a href=\"index.html?node=0x%x\">Top</a> ]", tree_top);
+ Printf(f,"<br><hr><p>\n");
+ if (n) {
+ raw_data(f,n);
+ }
+ /* Print standard footer */
+ Printf(f,"<br><hr></BODY></HTML>\n");
+}
+
+void symbol_handler(FILE *f) {
+ Symtab *sym;
+ char *name = 0;
+
+ Printf(f,"<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", SWIG_VERSION);
+ Printf(f,"<b>SWIG-%s</b><br>\n", SWIG_VERSION);
+ Printf(f,"[ <a href=\"exit.html\">Exit</a> ]");
+ Printf(f," [ <a href=\"index.html?node=0x%x\">Top</a> ]", tree_top);
+ Printf(f," [ <a href=\"symbol.html\">Symbols</a> ]");
+ Printf(f,"<br><hr><p>\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,"<b>Symbol table: :: (global)</b><br>\n");
+ } else {
+ Printf(f,"<b>Symbol table: %s</b><br>\n", q);
+ }
+ Delete(q);
+ }
+
+ fprintf(f,"<p><form action=\"symbol.html\" method=GET>\n");
+ fprintf(f,"Symbol lookup: <input type=text name=name size=40></input><br>\n");
+ fprintf(f,"<input type=hidden name=sym value=\"0x%x\">\n", sym);
+ fprintf(f,"Submit : <input type=submit></input>\n");
+ fprintf(f,"</form>");
+
+ if (name) {
+ Node *n = Swig_symbol_clookup(name,sym);
+ Printf(f,"Symbol '%s':\n", name);
+ Printf(f,"<blockquote>\n");
+ if (!n) {
+ Printf(f,"Not defined!\n");
+ } else {
+ raw_data(f,n);
+ }
+ Printf(f,"</blockquote>\n");
+ }
+
+ Printf(f,"<p><b>Nested scopes</b><br>\n");
+ Printf(f,"<blockquote><pre>\n");
+ {
+ Hash *h;
+ h = firstChild(sym);
+ while (h) {
+ Printf(f,"<a href=\"symbol.html?sym=0x%x\">%s</a>\n", h, Getattr(h,"name"));
+ h = nextSibling(h);
+ }
+ }
+ Printf(f,"</pre></blockquote>\n");
+
+ Printf(f,"<p><b>Symbol table contents</b></br>\n");
+ raw_data(f,Getattr(sym,"symtab"));
+ Printf(f,"<br><hr></BODY></HTML>\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/Modules1.1/contract.cxx b/Source/Modules1.1/contract.cxx
new file mode 100644
index 000000000..fba5827aa
--- /dev/null
+++ b/Source/Modules1.1/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/Modules1.1/emit.cxx b/Source/Modules1.1/emit.cxx
index 02b98855d..1f4bcf8bb 100644
--- a/Source/Modules1.1/emit.cxx
+++ b/Source/Modules1.1/emit.cxx
@@ -12,26 +12,11 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-#include "swig11.h"
+#include "swigmod.h"
-static char cvsroot[] = "$Header$";
+char cvsroot_emit_cxx[] = "$Header$";
-/* -----------------------------------------------------------------------------
- * new_create_function()
- *
- * Create a new function
- * ----------------------------------------------------------------------------- */
-
-void new_create_function(char *name, char *iname, SwigType *type, ParmList *l) {
- Hash *h;
- h = NewHash();
- Setattr(h,"name",name);
- Setattr(h,"scriptname",iname);
- Setattr(h,"type",type);
- Setattr(h,"parms",l);
- lang->function(h);
- Delete(h);
-}
+extern SwigType *cplus_value_type(SwigType *t);
/* -----------------------------------------------------------------------------
* emit_args()
@@ -43,209 +28,424 @@ void new_create_function(char *name, char *iname, SwigType *type, ParmList *l) {
* Returns the number of parameters associated with a function.
* ----------------------------------------------------------------------------- */
-int emit_args(DOH *node, Wrapper *f) {
+void emit_args(SwigType *rt, ParmList *l, Wrapper *f) {
- SwigType *rt;
- ParmList *l;
Parm *p;
- int i;
- char *tm;
- SwigType *pt;
- DOHString *pvalue;
- DOHString *pname;
- DOHString *lname;
-
- rt = Getattr(node,"type");
- l = Getattr(node,"parms");
+ String *tm;
/* Emit function arguments */
Swig_cargs(f, l);
- i = 0;
- p = l;
- while (p != 0) {
- lname = Getlname(p);
- pt = Gettype(p);
- pname = Getname(p);
- pvalue = Getvalue(p);
+ /* 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);
- tm = Swig_typemap_lookup((char*)"arginit",pt,pname,(char*)"",lname,f);
+ /* Apply the arginit and default */
+ p = l;
+ while (p) {
+ tm = Getattr(p,"tmap:arginit");
if (tm) {
- Printv(f,tm,"\n",0);
+ 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);
}
- /* Check for ignore or default typemaps */
- tm = Swig_typemap_lookup((char*)"default",pt,pname,(char*)"",lname,f);
+ }
+
+ /* Apply the default typemap */
+ p = l;
+ while (p) {
+ tm = Getattr(p,"tmap:default");
if (tm) {
- Printv(f,tm,"\n",0);
+ 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);
}
- tm = Swig_typemap_lookup((char*)"ignore",pt,pname,(char*)"",lname,f);
+ }
+
+#ifdef DEPRECATED
+ /* Apply the ignore typemap */
+ p = l;
+ while (p) {
+ tm = Getattr(p,"tmap:ignore");
if (tm) {
- Printv(f,tm,"\n",0);
- Setignore(p,1);
+ 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);
}
- i++;
- p = Getnext(p);
}
- return(i);
+#endif
+ return;
}
/* -----------------------------------------------------------------------------
- * int emit_func_call(char *decl, DataType *t, ParmList *l, Wrapper*f)
- *
- * Emits code for a function call (new version).
- *
- * Exception handling support :
+ * emit_attach_parmmaps()
*
- * - This function checks to see if any sort of exception mechanism
- * has been defined. If so, we emit the function call in an exception
- * handling block.
+ * Attach the standard parameter related typemaps.
* ----------------------------------------------------------------------------- */
-static DOH *fcall = 0;
+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);
+ }
+ }
+ }
-void emit_set_action(DOHString_or_char *decl) {
- if (fcall) Delete (fcall);
- fcall = NewString(decl);
+ /* 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);
+ }
+ }
+ }
}
-void emit_func_call(DOH *node, Wrapper *f) {
- char *decl;
- SwigType *t;
- ParmList *l;
- char *tm;
-
- decl = GetChar(node,"name");
- t = Getattr(node,"type");
- l = Getattr(node,"parms");
-
- if ((tm = Swig_typemap_lookup((char*)"except",t,decl,(char*)"result",(char*)"",0))) {
- Printv(f,tm,0);
- Replace(f,"$name",decl,DOH_REPLACE_ANY);
- } else if ((tm = Swig_except_lookup())) {
- Printv(f,tm,0);
- Replace(f,"$name",decl,DOH_REPLACE_ANY);
- } else {
- Printv(f,"$function",0);
+/* -----------------------------------------------------------------------------
+ * 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);
+ }
}
-
- if (!fcall) fcall = NewString(Swig_cfunction_call(decl,l));
- if (CPlusPlus) {
- Swig_cppresult(f, t, (char*)"result", Char(fcall));
- } else {
- Swig_cresult(f, t, (char*)"result", Char(fcall));
+#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--;
+ }
}
- Delete(fcall);
- fcall = 0;
+ return nargs;
}
/* -----------------------------------------------------------------------------
- * void emit_set_get()
- *
- * Emits a pair of functions to set/get the value of a variable. This is
- * only used in the event the target language can't provide variable linking
- * on its own.
- *
- * double foo;
- *
- * Gets translated into the following :
+ * emit_num_required() ** new in 1.3.10
*
- * double foo_set(double x) {
- * return foo = x;
- * }
- *
- * double foo_get() {
- * return foo;
- * }
+ * 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.
* ----------------------------------------------------------------------------- */
-/* How to assign a C allocated string */
+int emit_num_required(ParmList *parms) {
+ Parm *p = parms;
+ int nargs = 0;
-static char *c_str = (char *)"\
-if ($target) free($target);\n\
-$target = ($rtype) malloc(strlen($source)+1);\n\
-strcpy((char *)$target,$source);\n\
-return $ltype $target;\n";
+ 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);
+ }
+ }
+ }
-/* How to assign a C allocated string */
+ /* 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);
+ }
+ }
+ }
-static char *cpp_str = (char *)"\
-if ($target) delete [] $target;\n\
-$target = ($rtype) (new char[strlen($source)+1]);\n\
-strcpy((char *)$target,$source);\n\
-return ($ltype) $target;\n;";
+ if (parms && (p = Getattr(parms,"emit:varargs"))) {
+ if (!nextSibling(p)) {
+ nargs--;
+ }
+ }
+ return nargs;
+}
+/* -----------------------------------------------------------------------------
+ * emit_isvarargs()
+ *
+ * Checks if a function is a varargs function
+ * ----------------------------------------------------------------------------- */
-void emit_set_get(DOH *node) {
- char *name, *iname;
- SwigType *t;
- Wrapper *w;
- DOHString *new_iname;
- char *code = 0;
-
- name = GetChar(node,"name");
- iname = GetChar(node,"iname");
- t = Getattr(node,"type");
-
- /* First write a function to set the variable of the variable */
- if (!ReadOnly) {
-
- if (SwigType_type(t) == T_STRING) {
- if (CPlusPlus)
- code = cpp_str;
- else
- code = c_str;
- }
- w = Swig_cvarset_wrapper(name, t, code);
- Printf(f_header,"%s", w);
- new_iname = Swig_name_set(iname);
- DohIncref(new_iname);
- new_create_function(GetChar(w,"name"), Char(new_iname), Gettype(w), Getparms(w));
- Delete(new_iname);
- Delete(w);
- }
-
- w = Swig_cvarget_wrapper(name,t,0);
- Printf(f_header,"%s", w);
- new_iname = Swig_name_get(iname);
- DohIncref(new_iname);
- new_create_function(GetChar(w,"name"), Char(new_iname), Gettype(w), Getparms(w));
- Delete(new_iname);
- Delete(w);
+int
+emit_isvarargs(ParmList *p) {
+ if (!p) return 0;
+ if (Getattr(p,"emit:varargs")) return 1;
+ return 0;
}
-/* ------------------------------------------------------------------
- * int check_numopt()
+/* -----------------------------------------------------------------------------
+ * 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()
*
- * Gets the number of optional arguments for a ParmList.
- * ------------------------------------------------------------------ */
-
-int check_numopt(ParmList *p) {
- int n = 0;
- int i = 0;
- int state = 0;
-
- for (;p; p = Getnext(p),i++) {
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
- if (Getvalue(p)) {
- n++;
- state = 1;
- } else if (Swig_typemap_search((char*)"default",pt,pn)) {
- n++;
- state = 1;
- } else if (Swig_typemap_search((char*)"ignore",pt,pn)) {
- n++;
- } else {
- if (state) {
- Printf(stderr,"%s:%d. Argument %d must have a default value!\n", Getfile(p), Getline(p),i+1);
+ * 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);
}
}
- return n;
-}
+ /* 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/Modules1.1/generate.cxx b/Source/Modules1.1/generate.cxx
deleted file mode 100644
index 51b885ed4..000000000
--- a/Source/Modules1.1/generate.cxx
+++ /dev/null
@@ -1,909 +0,0 @@
-/* -----------------------------------------------------------------------------
- * generate.cxx
- *
- * This file manages the code generation process and serves as a bridge between
- * the new SWIG parser and the old set of C++-based language modules.
- *
- * 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.
- * ----------------------------------------------------------------------------- */
-
-#include "swig11.h"
-
-static char cvstag[] = "$Header$";
-
-int ReadOnly = 0;
-int WrapExtern = 0;
-
-/* Access permissions: public, private, protected */
-enum { PUBLIC, PRIVATE, PROTECTED };
-int Access = PUBLIC;
-
-/* Miscellaneous modes */
-int Native = 0;
-
-/* This function tries to locate the module name within the parse tree */
-static String *find_module(DOH *node) {
- DOH *n;
-
- if (!node) return 0;
- n = node;
- while (n) {
- if (Swig_tag_check(n,"module")) {
- return Getname(n);
- }
- if (Swig_tag_check(n,"file")) {
- String *ty;
- ty = Getattr(n,"type");
- if (Cmp(ty,"include") == 0) {
- DOH *m;
- /* Might be in an include file */
- m = find_module(Getchild(n));
- if (m) return m;
- }
- }
- n = Getnext(n);
- }
- return find_module(Getchild(node));
-}
-
-/* This helper function emits external function declarations */
-static
-void emit_extern_func(DOH *node, File *f) {
- Parm *p;
- SwigType *tc;
- char *c;
- String *storage;
- storage = Getattr(node,"storage");
- if (!storage) return;
- c = Char(storage);
- if (strncmp(c,"extern",6) == 0) {
- List *tl = NewList();
- p = Getparms(node);
- while (p) {
- Append(tl,Gettype(p));
- p = Getnext(p);
- }
- tc = Copy(Gettype(node));
- SwigType_add_function(tc,tl);
- Printf(f,"%s %s;\n", storage, SwigType_str(tc,Getname(node)));
- Delete(tc);
- Delete(tl);
- }
-}
-
-/* Test if static */
-static int
-check_static(DOH *node) {
- String *storage = Getattr(node,"storage");
- if (!storage) return 0;
- if (Cmp(storage,"static") == 0) return 1;
- return 0;
-}
-
-/* Test if extern */
-static int
-check_extern(DOH *node) {
- String *storage = Getattr(node,"storage");
- if (!storage) return 0;
- if (strncmp(Char(storage),"extern",6) == 0) return 1;
- return 0;
-}
-
-static String *new_name = 0;
-
-/* Handle renaming */
-static
-void set_scriptname(DOH *node) {
- if (new_name) {
- Setattr(node,"scriptname",new_name);
- } else {
- String *aname = Getattr(node,"altname");
- if (aname) {
- Setattr(node,"scriptname",aname);
- } else {
- Setattr(node,"scriptname", Getname(node));
- }
- }
- new_name = 0;
-}
-
-/* -----------------------------------------------------------------------------
- * C++ Support
- * ----------------------------------------------------------------------------- */
-
-static DOH *class_hash = 0; /* Hash table of classes that have been seen so far */
-static DOH *current_class = 0; /* Set when wrapping a class */
-static DOH *class_name = 0; /* Real name of current class */
-static DOH *class_types = 0; /* Types defined within this class */
-static String *construct_name = 0; /* Expected name of a constructor */
-int AddMethods = 0; /* Set when in addmethods mode */
-int Abstract = 0; /* Set when the class is determined to be abstract */
-static int have_destructor = 0;
-static int have_constructor = 0;
-
-/* Check for abstract classes */
-
-int cplus_check_abstract(DOH *node) {
- while (node) {
- if (Getattr(node,"abstract")) return 1;
- node = Getnext(node);
- }
- return 0;
-}
-
-/* Given a class object, this function builds an internal symbol table */
-void cplus_build_symbols(DOH *node) {
- Hash *sym;
- DOH *c;
- sym = Getattr(node,"symbols");
- if (!sym) {
- sym = NewHash();
- Setattr(node,"symbols",sym);
- }
- c = Getchild(node);
- while (c) {
- String *name = Getname(c);
- String *tag = Gettag(c);
- if (Cmp(tag,"c:destructor") == 0) {
- name = NewStringf("~%s",name);
- }
- if (name) {
- DOH *pnode = Getattr(sym,name);
- if (pnode) {
- Printf(stderr,"%s:%d. '%s' redefined. Previous definition at %s:%d.\n",
- Getfile(c),Getline(c), name, Getfile(pnode), Getline(pnode));
- } else {
- Setattr(sym,name,c);
- }
- }
- c = Getnext(c);
- }
- return;
-}
-
-/* Inherit certain types of declarations from another class */
-
-
-
-/* Add a class type */
-static void
-class_addtype(String *name, String *cname) {
- String *s;
- if (!cname)
- s = NewStringf("%s::%s", class_name, name);
- else
- s = NewStringf("%s::%s", cname, name);
-
- if (!class_types) class_types = NewHash();
- Setattr(class_types,name,s);
-}
-
-/* Updates a type with a fully qualified version */
-static void
-class_update_type(String *type) {
- String *base, *rep;
- if (!type) return;
- base = SwigType_base(type);
- if (!class_types) return;
- rep = Getattr(class_types,base);
- if (rep) {
- SwigType_setbase(type,rep);
- /* Printf(stdout,"updated type = '%s'\n", type); */
- }
-}
-
-/* Updates a list of parms with fully qualified names */
-static void
-class_update_parms(ParmList *p) {
- while (p) {
- class_update_type(Gettype(p));
- p = Getnext(p);
- }
-}
-
-/* Traverse the inheritance hierarchy of a class */
-void
-cplus_walk_inherit(DOH *cls, void (*action)(DOH *base, void *clientdata), void *clientdata) {
- DOH *base;
- List *bases;
- int i, nbase;
-
- bases = Getattr(cls,"bases");
- if (bases) {
- nbase = Len(bases);
- for (i = 0; i < nbase; i++) {
- base = Getattr(class_hash, Getitem(bases,i));
- if (base) {
- (*action)(base,clientdata);
-
- }
- }
- }
-}
-
-/* Action for inheriting type definitions */
-static void inherit_types(DOH *cls, void *clientdata) {
- DOH *ty;
- ty = Getattr(cls,"types");
- if (ty) {
- String *key;
- SwigType_merge_scope(ty,0);
- for (key = Firstkey(ty); key; key = Nextkey(ty)) {
- class_addtype(key, Getname(cls));
- }
- }
- cplus_walk_inherit(cls,inherit_types,clientdata);
-}
-
-/* Action for inheriting typemaps */
-static void inherit_typemaps(DOH *cls, void *clientdata) {
- DOH *ty;
-
- cplus_walk_inherit(cls,inherit_typemaps,clientdata);
- ty = Getattr(cls,"typemaps");
- if (ty) {
- if (!clientdata)
- Swig_typemap_new_scope(ty);
- else
- Swig_typemap_pop_scope();
- }
-}
-
-extern "C" {
-int swig11_unknown(DOH *node, void *clientdata) {
- Printf(stdout,"::: Unknown tag - '%s'\n", Getattr(node,"tag"));
- return 0;
-}
-
-int swig11_nil(DOH *node, void *clientdata) {
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_file()
- *
- * File inclusion directives. %include, %extern, and %import.
- * ----------------------------------------------------------------------------- */
-
-int swig11_file(DOH *node, void *clientdata) {
- DOH *c;
- String *type;
- int old_we = WrapExtern;
-
- type = Getattr(node,"type");
- if ((Cmp(type, "extern") == 0) || (Cmp(type,"import") == 0)) {
- WrapExtern = 1;
- }
- c = Getchild(node);
- if (Cmp(type,"import") == 0) {
- /* If importing a module, we try to find the module name and pass it to
- the language modules */
- String *modname;
- modname = find_module(c);
- if (modname) {
- lang->import(modname);
- }
- }
- Swig_emit_all(c,clientdata);
- WrapExtern = old_we;
- return 0;
-}
-/* -----------------------------------------------------------------------------
- * swig11_scope()
- *
- * Handle the %scope directive. This is a new feature not present in SWIG1.1.
- * Creates a new typemap scope and has other side effects.
- * ----------------------------------------------------------------------------- */
-
-int swig11_scope(DOH *node, void *clientdata) {
- DOH *c;
- String *name;
-
- c = Getchild(node);
- name = Getname(node);
-
- Swig_typemap_new_scope(0);
- if (name) {
- if (Cmp(name,"native") == 0) {
- int oldnative = Native;
- Native = 1;
- Swig_emit_all(c,clientdata);
- Native = oldnative;
- } else if (Cmp(name,"readonly") == 0) {
- int oldro = ReadOnly;
- ReadOnly = 1;
- Swig_emit_all(c,clientdata);
- ReadOnly = oldro;
- } else {
- Swig_emit_all(c,clientdata);
- }
- }
- Hash *scp = Swig_typemap_pop_scope();
- Setattr(node,"typemaps", scp);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_insert()
- *
- * Code insertion with various %{ %} directives.
- * ----------------------------------------------------------------------------- */
-
-int swig11_insert(DOH *node, void *clientdata) {
- String *section;
- String *filename;
- String *code;
- File *out;
-
- if (WrapExtern) return 0;
-
- section = Getattr(node,"section");
- if (!section) {
- section = (void *) "header";
- }
- out = Swig_filebyname(section);
- if (!out) {
- Printf(stderr,"%s:%d. Can't insert code into unknown section '%s'\n", Getfile(node), Getline(node), section);
- return 0;
- }
- filename = Getattr(node,"filename");
- if (filename) {
- /* The user is inserting the contents of a file */
- if (Swig_insert_file(filename,out) < 0) {
- Printf(stderr,"%s:%d. File '%s' not found.\n", Getfile(node), Getline(node), filename);
- }
- return 0;
- }
- code = Getattr(node,"code");
- if (code) {
- Printf(out,"%s",code);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_pragma()
- *
- * %pragma directive.
- * ----------------------------------------------------------------------------- */
-
-int swig11_pragma(DOH *node, void *clientdata) {
- String *name;
- String *value;
-
- if (WrapExtern) return 0;
-
- name = Getname(node);
- value = Getvalue(node);
-
- if (Cmp(name,"readonly") == 0) {
- ReadOnly = 1;
- } else if (Cmp(name,"readwrite") == 0) {
- ReadOnly = 0;
- } else if (Cmp(name,"name") == 0) {
- new_name = value;
- }
- lang->pragma(node);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_typemap()
- *
- * Handle the %typemap directive.
- * ----------------------------------------------------------------------------- */
-
-int swig11_typemap(DOH *node, void *clientdata) {
- String *name;
- SwigType *type;
- String *code;
- DOH *parms;
- String *method;
-
- if (WrapExtern) return 0;
- method = Getattr(node,"method");
- name = Getname(node);
- type = Gettype(node);
- code = Getattr(node,"code");
- parms = Getparms(node);
-
- if (current_class) {
- class_update_type(type);
- class_update_type(parms);
- }
-
- if (code) {
- Swig_typemap_register(method,type,name,code,parms);
- } else {
- String *srcname;
- String *srctype;
- srcname = Getattr(node,"srcname");
- srctype = Getattr(node,"srctype");
- if (srcname && srctype) {
- Swig_typemap_copy(method,srctype,srcname,type,name);
- } else {
- Swig_typemap_clear(method,type,name);
- }
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_apply()
- *
- * The %apply directive.
- * ----------------------------------------------------------------------------- */
-
-int swig11_apply(DOH *node, void *clientdata) {
- DOH *parms;
- String *name;
- SwigType *type;
-
- if (WrapExtern) return 0;
-
- name = Getname(node);
- type = Gettype(node);
- parms = Getparms(node);
-
- while (parms) {
- Swig_typemap_apply(type,name,Gettype(parms),Getname(parms));
- parms = Getnext(parms);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_exception()
- *
- * The %except directive.
- * ----------------------------------------------------------------------------- */
-
-int swig11_exception(DOH *node, void *clientdata) {
- String *code = Getattr(node,"code");
- if (WrapExtern) return 0;
- if (code) {
- Swig_except_register(code);
- } else {
- Swig_except_clear();
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_clear()
- *
- * The %clear directive.
- * ----------------------------------------------------------------------------- */
-
-int swig11_clear(DOH *node, void *clientdata) {
- DOH *parms = Getattr(node,"parms");
- if (WrapExtern) return 0;
- while (parms) {
- Swig_typemap_clear_apply(Gettype(parms),Getname(parms));
- parms = Getnext(parms);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_constant
- *
- * The %constant directive
- * ----------------------------------------------------------------------------- */
-
-int swig11_constant(DOH *node, void *clientdata) {
- if (WrapExtern) return 0;
- if (Access != PUBLIC) return 0;
-
- set_scriptname(node);
- lang->constant(node);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_function()
- *
- * Emit a wrapper function.
- * ----------------------------------------------------------------------------- */
-
-int swig11_function(DOH *node, void *clientdata) {
- int is_static;
- if (WrapExtern) return 0;
- if (Access != PUBLIC) return 0;
-
- is_static = check_static(node);
- set_scriptname(node);
-
- /* Will need some kind of class check in here */
-
- if (current_class) {
- /* Function has been declared inside a class definition. */
- class_update_parms(Getparms(node));
- class_update_type(Gettype(node));
- String *name = Getname(node);
- if (Cmp(name,construct_name) == 0) {
- have_constructor =1;
- if (!Abstract) {
- lang->cpp_constructor(node);
- }
- } else {
- if (is_static) lang->cpp_staticfunction(node);
- else lang->cpp_memberfunction(node);
- }
- } else {
-
- /* Can't wrap a static function. Oh well. */
- if (is_static) return 0;
- emit_extern_func(node,f_header);
-
- if (Native) {
- lang->nativefunction(node);
- } else {
- lang->function(node);
- }
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_variable()
- *
- * Wrap a variable.
- * ----------------------------------------------------------------------------- */
-
-int swig11_variable(DOH *node, void *clientdata) {
- int is_static;
- SwigType *type;
-
- if (WrapExtern) return 0;
- if (Access != PUBLIC) return 0;
-
- if (Native) {
- Printf(stderr,"%s:%d. Can't wrap variables in %%native mode (ignored).\n", Getfile(node),Getline(node));
- return 0;
- }
-
- type = Gettype(node);
-
- is_static = check_static(node);
- set_scriptname(node);
-
- if (current_class) {
- /* Inside a class definition */
- if (is_static) {
- lang->cpp_staticvariable(node);
- } else {
- lang->cpp_variable(node);
- }
- } else {
- if (check_extern(node)) {
- Printf(f_header,"extern %s;\n", SwigType_str(type, Getname(node)));
- }
- if (is_static) return 0;
-
- if (SwigType_isconst(type)) {
- swig11_constant(node,clientdata);
- } else {
- lang->variable(node);
- }
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_typedef()
- *
- * Handle a typedef declaration.
- * ----------------------------------------------------------------------------- */
-
-int swig11_typedef(DOH *node, void *clientdata) {
- String *name;
- SwigType *type;
-
- type = Gettype(node);
- name = Getname(node);
- SwigType_typedef(type,name);
-
- if (current_class) {
- class_addtype(name,0);
- }
- lang->add_typedef(type, Char(name));
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_enum()
- *
- * Support for enumerations.
- * ----------------------------------------------------------------------------- */
-
-int swig11_enum(DOH *node, void *clientdata) {
- DOH *c;
- String *name;
- if (WrapExtern) return 0;
- if (Access != PUBLIC) return 0;
-
- name = Getname(node);
- if (name && CPlusPlus) {
- /* Add a typedef */
- String *t = NewStringf("enum %s", name);
- SwigType_typedef(t,name);
- class_addtype(name,0);
- Delete(t);
- }
- c = Getchild(node);
- Swig_emit_all(c,clientdata);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_enumvalue()
- *
- * Create a constant corresponding to an enum value.
- * ----------------------------------------------------------------------------- */
-int swig11_enumvalue(DOH *node, void *clientdata) {
- set_scriptname(node);
- Setattr(node,"type","int"); /* Enums wrapped as ints */
- if (!Getvalue(node)) { /* If no value, use the name itself */
- if (class_name) {
- Setvalue(node,NewStringf("%s::%s",class_name, Getname(node)));
- } else {
- Setvalue(node,Getname(node));
- }
- }
- if (current_class) {
- lang->cpp_constant(node);
- } else {
- swig11_constant(node,clientdata);
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_class()
- *
- * Wrapping of C++ classes
- * ----------------------------------------------------------------------------- */
-
-int swig11_class(DOH *node, void *clientdata) {
- DOH *c;
- List *bases;
-
- /* Save the class */
- String *name = Getname(node);
- Setattr(class_hash,name,node);
- if (WrapExtern) return 0;
-
- if (Native) {
- Printf(stderr,"%s:%d. Can't wrap structures or classes in %%native mode (ignored).\n", Getfile(node),Getline(node));
- return 0;
- }
-
- set_scriptname(node);
- class_name = name;
- class_types = 0;
-
- have_destructor = 0;
- have_constructor = 0;
-
- /* Need to merge in data from other scopes. For typemaps, can include scopes
- for each base class one after the other. For types, need to merge type information */
-
- SwigType_new_scope();
- if (name) {
- SwigType_set_scope_name(name);
- }
-
- cplus_walk_inherit(node, inherit_types, 0);
-
- /* Merge in typemaps */
- cplus_walk_inherit(node, inherit_typemaps, 0);
-
- /* Create a typemap scope for this class */
- Swig_typemap_new_scope(0);
-
- cplus_build_symbols(node);
- lang->cpp_open_class(node);
- current_class = node;
-
- construct_name = Getname(node);
- if (!CPlusPlus) {
- String *altname = Getattr(node,"altname");
- if (altname) construct_name = altname;
- }
-
- c = Getchild(node);
- Abstract = cplus_check_abstract(c);
-
- Swig_emit_all(c,clientdata);
-
- bases = Getattr(node,"bases");
- if (bases) {
- String *b;
- lang->cpp_inherit(bases);
- b = Firstitem(bases);
- while (b) {
- SwigType_inherit(Getname(current_class),b);
- b = Nextitem(bases);
- }
- }
-
- /* Check for constructors and destructors */
-
- if (CPlusPlus) {
- if (!have_constructor && !Abstract) {
- DOH *cn = NewHash();
- Setname(cn, Getname(current_class));
- Setattr(cn,"scriptname", Getname(current_class));
- lang->cpp_constructor(cn);
- }
- if (!have_destructor) {
- DOH *dn = NewHash();
- Setname(dn, Getname(current_class));
- Setattr(dn,"scriptname", Getname(current_class));
- lang->cpp_destructor(dn);
- }
- }
-
- lang->cpp_close_class();
-
- /* Pop the type scope and save with the class */
-
- Hash *scp = SwigType_pop_scope();
- Setattr(node,"types",scp);
-
- scp = Swig_typemap_pop_scope();
- Setattr(node,"typemaps",scp);
- Setattr(node,"classtypes",class_types);
-
- /* Pop off all of the typemap scopes we added */
- cplus_walk_inherit(node,inherit_typemaps, (void *) 1);
-
- current_class = 0;
- construct_name = 0;
- class_name = 0;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_classdecl()
- *
- * Empty class declaration. Used to register classes with language modules.
- * ----------------------------------------------------------------------------- */
-
-int swig11_classdecl(DOH *node, void *clientdata) {
- if (WrapExtern) return 0;
- set_scriptname(node);
-
- lang->cpp_class_decl(node);
- return 0;
-}
-
-int swig11_addmethods(DOH *node, void *clientdata) {
- DOH *c;
- int oldaddmethods = AddMethods;
- if (WrapExtern) return 0;
- if (!current_class) {
- Printf(stderr,"%s:%d. %%addmethods ignored (does not appear inside a class).\n", Getfile(node),Getline(node));
- return 0;
- }
- AddMethods = 1;
- c = Getchild(node);
- Swig_emit_all(c,clientdata);
- AddMethods = oldaddmethods;;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_destructor()
- *
- * C++ Destructor
- * ----------------------------------------------------------------------------- */
-
-int swig11_destructor(DOH *node, void *clientdata) {
- if (WrapExtern) return 0;
- if (Access != PUBLIC) return 0;
- if (!current_class) return 0;
-
- set_scriptname(node);
- lang->cpp_destructor(node);
- have_destructor = 1;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_access()
- *
- * Handle an access specifier (public, private, protected)
- * ----------------------------------------------------------------------------- */
-
-int swig11_access(DOH *node, void *clientdata) {
- String *name = Getname(node);
- if (Cmp(name,"public") == 0) Access = PUBLIC;
- else if (Cmp(name,"private") == 0) Access = PRIVATE;
- else if (Cmp(name,"protected") == 0) Access = PROTECTED;
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * swig11_types()
- *
- * Handle the types directive.
- * ----------------------------------------------------------------------------- */
-
-int swig11_types(DOH *node, void *clientdata) {
- Parm *p;
- p = Getparms(node);
- while (p) {
- SwigType *t = Gettype(p);
- SwigType_remember(t);
- p = Getnext(p);
- }
- return 0;
-}
-
-static SwigRule rules[] = {
- { "file", swig11_file},
- { "scope", swig11_scope},
- { "insert", swig11_insert},
- { "pragma", swig11_pragma},
- { "typemap", swig11_typemap},
- { "apply", swig11_apply},
- { "exception", swig11_exception},
- { "clear", swig11_clear},
- { "addmethods", swig11_addmethods},
- { "constant", swig11_constant},
- { "function", swig11_function},
- { "variable", swig11_variable},
- { "typedef", swig11_typedef},
- { "enum", swig11_enum},
- { "enumvalue", swig11_enumvalue},
- { "class", swig11_class},
- { "classdecl", swig11_classdecl},
- { "destructor", swig11_destructor},
- { "access", swig11_access},
- { "types", swig11_types},
- { "module", swig11_nil},
- { "*", swig11_unknown},
- { 0 }
-};
-
-}
-
-/* -----------------------------------------------------------------------------
- * generate()
- *
- * Called by the SWIG1.1 system to emit code
- * ----------------------------------------------------------------------------- */
-
-void generate(DOH *node) {
- DOH *c;
- extern String *swig_module;
-
- /* Initialize globals */
- class_hash = NewHash();
-
- Swig_add_rules(rules);
- c = Getattr(node,"child");
-
- /* Find the module name */
- if (!swig_module) {
- swig_module = find_module(c);
- }
- if (!swig_module) {
- Printf(stderr,"SWIG: No module name specified! Please use %%module or -module.\n");
- Swig_exit(EXIT_FAILURE);
- }
-
- lang->initialize(swig_module);
- Swig_emit_all(c,0);
- lang->close();
-
- /* Swig_dump_tags(node,0); */
-
-}
-
-
diff --git a/Source/Modules1.1/guile.cxx b/Source/Modules1.1/guile.cxx
index 18d59f5b8..a6b53b536 100644
--- a/Source/Modules1.1/guile.cxx
+++ b/Source/Modules1.1/guile.cxx
@@ -13,7 +13,7 @@
* can be used and distributed.
*****************************************************************************/
-static char cvsroot[] = "$Header$";
+char cvsroot_guile_cxx[] = "$Header$";
/***********************************************************************
* $Header$
@@ -23,895 +23,1186 @@ static char cvsroot[] = "$Header$";
* Definitions for adding functions to Guile
***********************************************************************/
-#include "swig11.h"
-#include "guile.h"
+#include "swigmod.h"
-static char *guile_usage = (char*)"\
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+#include <ctype.h>
+
+static const char *guile_usage = (char*)"\
Guile Options (available with -guile)\n\
- -module name - Set base name of module\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\
- -Linkage lstyle - Use linkage protocol LSTYLE [default `ltdlmod']\n\
- -procdoc file - Output procedure documentation to file\n\
-\n\
- The module option does not create a guile module with a separate name\n\
- space. It specifies the name of the initialization function and is\n\
- called a module here so that it is compadible with the rest of SWIG.\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 `ltdlmod' for libtool ltdl\n\
- modules. Other LSTYLE values are: `hobbit' for hobbit modules.\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";
-// ---------------------------------------------------------------------
-// GUILE ()
-// ---------------------------------------------------------------------
+static File *f_runtime = 0;
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
-GUILE::GUILE ()
-{
- // Set class vars
+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;
- prefix = (char*)"gswig_";
- module = NULL;
- package = NULL;
- linkage = GUILE_LSTYLE_SIMPLE;
- procdoc = NULL;
- emit_setters = 0;
- struct_member = 0;
-}
+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;
-// ---------------------------------------------------------------------
-// GUILE::parse_args(int argc, char *argv[])
-//
-// Parse arguments.
-// ---------------------------------------------------------------------
+class GUILE : public Language {
+public:
-void
-GUILE::parse_args (int argc, char *argv[])
-{
- int i, orig_len;
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
- Swig_swiglib_set("guile");
+ 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();
+ 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], "-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);
+ 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 {
- Swig_arg_error();
}
- }
- /* Bogus upcase requirement due to top-level parsing not respecting
- language specification. Top-level should stop when it sees "-guile"
- or other languages. */
- else if (strcmp (argv[i], "-Linkage") == 0) {
- if (argv[i + 1]) {
- if (0 == strcmp (argv[i + 1], "ltdlmod"))
- linkage = GUILE_LSTYLE_LTDLMOD;
- else if (0 == strcmp (argv[i + 1], "hobbit"))
- linkage = GUILE_LSTYLE_HOBBIT;
- 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], "w");
+ else if (strcmp (argv[i], "-emit-setters") == 0) {
+ emit_setters = 1;
Swig_mark_arg (i);
- Swig_mark_arg (i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- }
- 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 ((void *) "SWIGGUILE",0);
+ // Make sure `prefix' ends in an underscore
- /* Read in default typemaps */
- Swig_set_config_file("guile.i");
-}
-
-// --------------------------------------------------------------------
-// GUILE::initialize()
-//
-// Output initialization code that registers functions with the
-// interface.
-// ---------------------------------------------------------------------
-
-void
-GUILE::initialize (String *modname)
-{
- printf ("Generating wrappers for Guile\n");
-
- 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");
- }
+ orig_len = strlen (prefix);
+ if (prefix[orig_len - 1] != '_') {
+ prefix[1 + orig_len] = 0;
+ prefix[orig_len] = '_';
+ }
- if (!module) {
- module = new char[Len(modname)+1];
- strcpy(module, Char(modname));
+ /* Add a symbol for this module */
+ Preprocessor_define ("SWIGGUILE 1",0);
+ /* Read in default typemaps */
+ SWIG_config_file("guile.i");
+ allow_overloading();
+
}
- 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;
+ /* ------------------------------------------------------------
+ * 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;
}
- Printf (f_init, "\tSWIG_Guile_Init();\n");
-}
-
-void
-GUILE::emit_linkage (char *module_name)
-{
- DOHString *module_func = NewString("");
-
- Printv(module_func,module_name,0);
- Replace(module_func,"-", "_", DOH_REPLACE_ANY);
-
- switch (linkage) {
- case GUILE_LSTYLE_SIMPLE:
- Printf (f_init, "\n/* Linkage: simple */\n");
- break;
- case GUILE_LSTYLE_LTDLMOD:
- Printf (f_init, "\n/* Linkage: ltdlmod */\n");
- Replace(module_func,"/", "_", DOH_REPLACE_ANY);
- Insert(module_func,0, "scm_init_");
- Append(module_func,"_module");
- Printf (f_init, "SCM\n%s (void)\n{\n", module_func);
- {
- DOHString *mod = NewString(module_name);
- Replace(mod,"/", " ", DOH_REPLACE_ANY);
- Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n",
- mod);
- Printf (f_init, " return SCM_UNSPECIFIED;\n");
- Delete(mod);
+
+ void emit_linkage (char *module_name) {
+ String *module_func = NewString("");
+
+ if (CPlusPlus) {
+ Printf(f_init, "extern \"C\" {\n\n");
}
- Printf (f_init, "}\n");
- break;
- case GUILE_LSTYLE_HOBBIT:
- Printf (f_init, "\n/* Linkage: hobbit */\n");
- Replace(module_func,"/", "_slash_", DOH_REPLACE_ANY);
- Insert(module_func,0, "scm_init_");
- Printf (f_init, "SCM\n%s (void)\n{\n", module_func);
- {
- DOHString *mod = NewString(module_name);
- Replace(mod,"/", " ", DOH_REPLACE_ANY);
- Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n",
- mod);
- Printf (f_init, " return SCM_UNSPECIFIED;\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");
}
- Printf (f_init, "}\n");
- break;
- default:
- abort(); // for now
- }
- Delete(module_func);
-}
-
-// ---------------------------------------------------------------------
-// GUILE::close(void)
-//
-// Wrap things up. Close initialization function.
-// ---------------------------------------------------------------------
-
-void
-GUILE::close (void)
-{
- SwigType_emit_type_table (f_runtime, f_wrappers);
-
- Printf (f_init, "SWIG_Guile_RegisterTypes(swig_types);\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;
}
-}
-
-// ----------------------------------------------------------------------
-// get_pointer()
-//
-// Emits code to get a pointer from a parameter and do type checking.
-// parm is the parameter number. This function is only used
-// in create_function().
-// ----------------------------------------------------------------------
-
-static void
-get_pointer (char *iname, int parm, SwigType *t,
- Wrapper *f, DOHString_or_char *proc_name,
- int num_scheme_parm)
-{
- SwigType_remember(t);
- /* Pointers are smobs */
- Printf(f, " if (SWIG_Guile_GetPtr(s_%d,(void **) &arg%d", parm, parm);
- if (SwigType_type(t) == T_VOID)
- Printf(f, ", NULL)) {\n");
- else
- Printv(f, ", SWIGTYPE", SwigType_manglestr(t), ")) {\n", 0);
- /* Raise exception */
- Printv(f,
- tab8,
- "scm_wrong_type_arg(\"",proc_name, "\", ",
- 0);
- Printf(f,"%d, s_%d);\n", num_scheme_parm, parm);
- Printv(f, tab4, "}\n", 0);
-}
-/* Return true iff T is a pointer type */
+ /* Return true iff T is a pointer type */
-static int
-is_a_pointer (SwigType *t)
-{
- return SwigType_ispointer(SwigType_typedef_resolve_all(t));
-}
-
-/* Same as Swig_typemap_lookup but fall back to `int' when `enum' is
- requested -- enum handling is somewhat broken in the 1.1 parser.
- But we don't want to change it now since it is deprecated. */
-
-static char *
-guile_typemap_lookup(const char *op, SwigType *type, const String_or_char *pname, String_or_char *source,
- String_or_char *target, Wrapper *f)
-{
- char *tm;
- tm = Swig_typemap_lookup((char*) op, type, (char*)pname, source, target, f);
- if (!tm) {
- SwigType *base = SwigType_typedef_resolve_all(type);
- if (strncmp(Char(base), "enum ", 5)==0)
- tm = Swig_typemap_lookup((char*) op, (char*) "int", (char*)pname, source, target, f);
+ int is_a_pointer (SwigType *t) {
+ return SwigType_ispointer(SwigType_typedef_resolve_all(t));
}
- return tm;
-}
-/* Lookup a typemap, replace all relevant parameters and write it to
- the given generalized file. Return 0 if no typemap found. */
-
-static int
-guile_do_typemap(DOHFile *file, const char *op,
- SwigType *type, const String_or_char *arg,
- String_or_char *source, String_or_char *target,
- int argnum, DOHString *name, Wrapper *f,
- int nonewline_p)
-{
- char *tm;
- if ((tm = guile_typemap_lookup(op, type, arg,
- source, target, f))) {
- String *s = NewString(tm);
- char argnum_s[10];
- sprintf(argnum_s, "%d", argnum);
- Replace(s,"$argnum", argnum_s, DOH_REPLACE_ANY);
- Replace(s,"$arg", arg, DOH_REPLACE_ANY);
- Replace(s,"$name", name, DOH_REPLACE_ANY);
- if (nonewline_p)
- Printv(file, s, 0);
- else Printv(file, s, "\n", 0);
- Delete(s);
- return 1;
- }
- else return 0;
-}
+ /* Report an error handling the given type. */
-/* Lookup a documentation typemap, replace all relevant parameters and
- write it to the given generalized file, providing a sensible
- default value. */
-
-static void
-guile_do_doc_typemap(DOHFile *file, const char *op,
- SwigType *type, const String_or_char *arg,
- int argnum, DOHString *name, Wrapper *f)
-{
- if (!guile_do_typemap(file, op, type, arg,
- NULL, NULL, argnum, name, f, 1)) {
- /* FIXME: Can't we provide this default via a typemap as well? */
- String *s = NewString(SwigType_str(type, 0));
- Chop(s);
- if (arg) Printf(file, "(%s <%s>)", arg, s);
- else Printf(file, "<%s>", s);
- Delete(s);
+ 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));
}
-}
-
-/* Report an error handling the given type. */
-
-static void
-throw_unhandled_guile_type_error (SwigType *d)
-{
- Printf (stderr, "%s:%d. Unable to handle type %s.\n",Getfile(d), Getline(d), SwigType_str(d,0));
-}
-
-// ----------------------------------------------------------------------
-// GUILE::create_function()
-// Create a function declaration and register it with the interpreter.
-// ----------------------------------------------------------------------
-
-void
-GUILE::function (DOH *node) {
- char *name, *iname;
- SwigType *d;
- ParmList *l;
- Parm *p;
- DOHString *proc_name = 0;
- char source[256], target[256];
- Wrapper *f = NewWrapper();;
- String *cleanup = NewString("");
- String *outarg = NewString("");
- String *signature = NewString("");
- String *returns = NewString("");
- int returns_list = 0;
- String *tmp = NewString("");
- int i;
- int numargs = 0;
- int numopt = 0;
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- d = Getattr(node,"type");
- l = Getattr(node,"parms");
-
- // Make a wrapper name for this
- char * wname = new char [strlen (prefix) + strlen (iname) + 2];
- sprintf (wname, "%s%s", prefix, iname);
-
- // Build the name for scheme.
- proc_name = NewString(iname);
- Replace(proc_name,"_", "-", DOH_REPLACE_ANY);
-
- /* Emit locals etc. into f; figure out which args to ignore */
- emit_args (node, f);
-
- /* Declare return variable */
-
- Wrapper_add_local (f,"gswig_result", "SCM gswig_result");
-
- if (procdoc)
- guile_do_doc_typemap(returns, "outdoc", d, NULL,
- 0, proc_name, f);
-
- /* Open prototype and signature */
- /* <DB> The function prototype must be produced first */
-
- Printv(f, "static SCM\n", wname," (", 0);
- for (p = l, i = 0; p; p = Getnext(p), i++) {
- if (i != 0) Printf(f,", ");
- Printf(f,"SCM s_%d", i);
+ /* 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;
+ }
}
- Printf(f,")\n{\n");
-
- /* Define the scheme name in C. This define is used by several Guile
- macros. */
-
- Printv(f,"#define FUNC_NAME \"", proc_name, "\"\n", 0);
-
- Printv(signature, "(", proc_name, 0);
- /* Now write code to extract the parameters */
-
- for (p = l, i = 0; p; p=Getnext(p), i++) {
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
- int opt_p = (Getvalue(p)
- || Swig_typemap_search((char*)"default",pt,pn));
- // Produce names of source and target
- sprintf(source,"s_%d",i);
- sprintf(target,"%s", Char(Getlname(p)));
-
- // Handle parameter types.
-
- if (Getignore(p))
- Printv(f, "/* ", pn, " ignored... */\n", 0);
- else {
- if (opt_p) {
- numopt++;
- Printf(f," if (s_%d != GH_NOT_PASSED) {\n", i);
- }
- ++numargs;
- if (guile_do_typemap(f, "in", pt, pn,
- source, target, numargs, proc_name, f, 0)) {
- /* nothing to do */
+ /* 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");
}
- else if (is_a_pointer(pt)) {
- get_pointer (iname, i, pt, f, proc_name, numargs);
+
+ 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);
}
- else {
- throw_unhandled_guile_type_error (pt);
+ if (opt_p) {
+ Printf(f->code," if (%s != GH_NOT_PASSED) {\n", source);
}
- if (procdoc) {
- /* Add to signature */
- Printf(signature, " ");
- guile_do_doc_typemap(signature, "indoc", pt, pn,
- numargs, proc_name, f);
+ 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," }\n");
+ 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);
+ }
}
-
- /* Check if there are any constraints. */
-
- guile_do_typemap(f, "check", pt, pn,
- source, target, numargs, proc_name, f, 0);
-
/* Pass output arguments back to the caller. */
-
- guile_do_typemap(outarg, "argout", pt, pn,
- source, target, numargs, proc_name, f, 0);
-
- if (procdoc) {
- /* Document output arguments */
- Clear(tmp);
- if (guile_do_typemap(tmp, "argoutdoc", pt, pn,
- source, target, numargs, proc_name, f, 1)) {
- if (Len(returns) == 0) { /* unspecified -> singleton */
- Printv(returns, tmp, 0);
- }
- else { /* append to list */
- Printv(returns, " ", tmp, 0);
- returns_list = 1;
+
+ /* 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);
}
}
-
- // free up any memory allocated for the arguments.
-
- guile_do_typemap(cleanup, "freearg", pt, pn,
- source, target, numargs, proc_name, f, 0);
- }
-
- /* Close prototype and signature */
-
- Printv(signature, ")\n", 0);
-
-
- // Now write code to make the function call
- Printv(f, tab4, "gh_defer_ints();\n", 0);
- emit_func_call (node, f);
- Printv(f, tab4, "gh_allow_ints();\n", 0);
-
- // Now have return value, figure out what to do with it.
-
- if (guile_do_typemap(f, "out", d, name,
- (char*)"result", (char*)"gswig_result",
- 0, proc_name, f, 0)) {
- /* nothing */
- }
- else if (is_a_pointer(d)) {
- SwigType_remember(d);
- Printv(f, tab4,
- "gswig_result = SWIG_Guile_MakePtr (",
- "result, ",
- "SWIGTYPE", SwigType_manglestr(d),
- ");\n",
- 0);
- }
- else {
- throw_unhandled_guile_type_error (d);
- }
-
- // Dump the argument output code
- Printv(f,outarg,0);
-
- // Dump the argument cleanup code
- Printv(f,cleanup,0);
-
- // Look for any remaining cleanup
-
- if (NewObject) {
- guile_do_typemap(f, "newfree", d, iname,
- (char*)"result", (char*)"", 0, proc_name, f, 0);
- }
-
- // Free any memory allocated by the function being wrapped..
-
- guile_do_typemap(f, "ret", d, name,
- (char*)"result", (char*)"", 0, proc_name, f, 0);
-
- // Wrap things up (in a manner of speaking)
-
- Printv(f, "return gswig_result;\n", 0);
-
- // Undefine the scheme name
-
- Printf(f, "#undef FUNC_NAME\n");
- Printf(f, "}\n");
-
- Printf(f_wrappers,"%s", f);
-
- 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", 0);
- Printv(f_wrappers, "{\n", 0);
- Printf(f_wrappers, "SCM arg[%d];\n", numargs);
- Printf(f_wrappers, "SWIG_Guile_GetArgs (arg, rest, %d, %d, \"%s\");\n",
- numargs-numopt, numopt, proc_name);
- Printv(f_wrappers, "return ", wname, "(", 0);
- Printv(f_wrappers, "arg[0]", 0);
- for (i = 1; i<numargs; i++)
- Printf(f_wrappers, ", arg[%d]", i);
- Printv(f_wrappers, ");\n", 0);
- Printv(f_wrappers, "}\n", 0);
- /* Register it */
- Printf (f_init, "gh_new_procedure(\"%s\", %s_rest, 0, 0, 1);\n",
- proc_name, wname, numargs-numopt, numopt);
- }
- else if (emit_setters && struct_member && strlen(Char(proc_name))>3) {
- 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\", %s, %d, %d, 0);\n",
- proc_name, wname, numargs-numopt, numopt);
- 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);
+
+ /* 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);
}
- free(pws_name);
- }
- }
- else {
- /* Register the function */
- Printf (f_init, "gh_new_procedure(\"%s\", %s, %d, %d, 0);\n",
- proc_name, wname, numargs-numopt, numopt);
- }
- if (procdoc) {
- /* Write out procedure documentation */
- Printv(signature, "Returns ", 0);
- if (Len(returns)==0) Printv(signature, "unspecified", 0);
- else if (returns_list) Printv(signature, "list (", returns, ")", 0);
- else Printv(signature, returns, 0);
- Printv(signature, "\n", 0);
- Printv(procdoc, "\f\n", signature, 0);
- }
-
- Delete(proc_name);
- Delete(outarg);
- Delete(cleanup);
- Delete(signature);
- Delete(returns);
- Delete(tmp);
- Delete(f);
- delete[] wname;
-}
-
-// -----------------------------------------------------------------------
-// GUILE::variable()
-//
-// 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.
-// -----------------------------------------------------------------------
-
-void
-GUILE::variable (DOH *node)
-{
- char *name, *iname;
- SwigType *t;
-
- DOHString *proc_name;
- char var_name[256];
- char *tm;
- Wrapper *f;
-
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
-
- f = NewWrapper();
- // evaluation function names
-
- sprintf (var_name, "%svar_%s", prefix, iname);
-
- // Build the name for scheme.
- proc_name = NewString(iname);
- Replace(proc_name,"_", "-",DOH_REPLACE_ANY);
-
- if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) {
-
- Printf (f_wrappers, "SCM %s(SCM s_0) {\n", var_name);
-
- if (!(ReadOnly) && SwigType_type(t) == T_STRING) {
- Printf (f_wrappers, "\t char *_temp;\n");
- Printf (f_wrappers, "\t int _len;\n");
}
- Printf (f_wrappers, "\t SCM gswig_result;\n");
-
- // Check for a setting of the variable value
-
- Printf (f_wrappers, "\t if (s_0 != GH_NOT_PASSED) {\n");
-
- // Yup. Extract the type from s_0 and set variable value
-
- if (ReadOnly) {
- Printf (f_wrappers, "\t\t scm_misc_error(\"%s\", "
- "\"Unable to set %s. Variable is read only.\", SCM_EOL);\n",
- proc_name, proc_name);
+
+ /* 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 if ((tm = guile_typemap_lookup ("varin",
- t, name, (char*)"s_0", name, f))) {
- Printf (f_wrappers, "%s\n", tm);
+ else {
+ throw_unhandled_guile_type_error (d);
}
- else if (is_a_pointer(t)) {
- if (SwigType_type(t) == T_STRING) {
- Printf (f_wrappers, "\t\t _temp = gh_scm2newstr(s_0, &_len);\n");
- Printf (f_wrappers, "\t\t if (%s) { free(%s);}\n", name, name);
- Printf (f_wrappers, "\t\t %s = (char *) "
- "malloc((_len+1)*sizeof(char));\n", name);
- Printf (f_wrappers, "\t\t strncpy(%s,_temp,_len);\n", name);
- Printf (f_wrappers, "\t\t %s[_len] = 0;\n", name);
- } else {
- // Set the value of a pointer
- Printf (f_wrappers, "\t if (SWIG_Guile_GetPtr(s_0, "
- "(void **) &%s, ", name);
- if (SwigType_type(t) == T_VOID)
- Printf (f_wrappers, "NULL)) {\n");
- else
- Printf (f_wrappers, "SWIGTYPE%s)) {\n", SwigType_manglestr(t));
- /* Raise exception */
- Printf(f_wrappers, "\tscm_wrong_type_arg(\"%s\", "
- "%d, s_0);\n", proc_name, 1);
- Printf (f_wrappers, "\t}\n");
+
+ // 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);
}
}
- else {
- throw_unhandled_guile_type_error (t);
+
+ // 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);
}
- Printf (f_wrappers, "\t}\n");
-
- // Now return the value of the variable (regardless
- // of evaluating or setting)
-
- if ((tm = guile_typemap_lookup ("varout",
- t, name, name, (char*)"gswig_result", f))) {
- Printf (f_wrappers, "%s\n", tm);
+
+ // 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; i<numargs; i++)
+ Printf(f_wrappers, ", arg[%d]", i);
+ Printv(f_wrappers, ");\n", NIL);
+ Printv(f_wrappers, "}\n", NIL);
+ /* Register it */
+ Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s_rest, 0, 0, 1);\n",
+ proc_name, wname, numreq, numargs-numreq);
}
- else if (is_a_pointer(t)) {
- if (SwigType_type(t) == T_STRING) {
- Printf (f_wrappers, "\t gswig_result = gh_str02scm(%s);\n", name);
- } else {
- // Is an ordinary pointer type.
- Printf (f_wrappers, "\t gswig_result = SWIG_Guile_MakePtr ("
- "%s, SWIGTYPE%s);\n", name, SwigType_manglestr(t));
+ else if (emit_setters && struct_member && strlen(Char(proc_name))>3) {
+ 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 {
- throw_unhandled_guile_type_error (t);
+ /* Register the function */
+ Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n",
+ proc_name, wname, numreq, numargs-numreq);
}
- Printf (f_wrappers, "\t return gswig_result;\n");
- Printf (f_wrappers, "}\n");
-
- // Now add symbol to the Guile interpreter
-
- if (!emit_setters
- || ReadOnly) {
- /* Read-only variables become a simple procedure returning the
- value. */
- Printf (f_init, "\t gh_new_procedure(\"%s\", %s, 0, 1, 0);\n",
- proc_name, var_name);
}
- else {
- /* Read/write variables become a procedure with setter. */
- Printf (f_init, "\t{ SCM p = gh_new_procedure(\"%s\", %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);
+ 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) {
- /* Compute documentation */
- String *signature = NewString("");
-
- if (ReadOnly) {
- Printv(signature, "(", proc_name, ")\n", 0);
- Printv(signature, "Returns constant ", 0);
- guile_do_doc_typemap(signature, "varoutdoc", t, NULL,
- 0, proc_name, f);
- Printv(signature, "\n", 0);
+ 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 {
- Printv(signature, "(", proc_name,
- " #:optional ", 0);
- guile_do_doc_typemap(signature, "varindoc", t, "new-value",
- 1, proc_name, f);
- Printv(signature, ")\n", 0);
- Printv(signature, "If NEW-VALUE is provided, "
- "set C variable to this value.\n", 0);
- Printv(signature, "Returns variable value ", 0);
- guile_do_doc_typemap(signature, "varoutdoc", t, NULL,
- 0, proc_name, f);
- Printv(signature, "\n", 0);
+ /* 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);
}
- Printv(procdoc, "\f\n", signature, 0);
- Delete(signature);
+
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number,
+ "Unsupported variable type %s (ignored).\n", SwigType_str(t,0));
}
-
- } else {
- Printf (stderr, "%s:%d. ** Warning. Unable to link with "
- " type %s (ignored).\n",
- Getfile(node), Getline(node), SwigType_str(t,0));
+ Delete(proc_name);
+ DelWrapper(f);
+ return SWIG_OK;
}
- Delete(proc_name);
- Delete(f);
-}
-// -----------------------------------------------------------------------
-// GUILE::constant()
-//
-// Makes a constant. Not sure how this is really supposed to work.
-// I'm going to fake out SWIG and create a variable instead.
-// ------------------------------------------------------------------------
-
-void
-GUILE::constant(DOH *node)
-{
- char *name;
- SwigType *type;
- char *value;
- int OldStatus = ReadOnly; // Save old status flags
- DOHString *proc_name;
- char var_name[256];
- DOHString *rvalue;
- char *tm;
- Wrapper *f;
-
- name = GetChar(node,"name");
- type = Getattr(node,"type");
- value = GetChar(node,"value");
-
- f = NewWrapper();
- ReadOnly = 1; // Enable readonly mode.
-
- // Make a static variable;
-
- sprintf (var_name, "%sconst_%s", prefix, name);
-
- // Build the name for scheme.
- proc_name = NewString(name);
- Replace(proc_name,"_", "-", DOH_REPLACE_ANY);
-
- if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) {
- Printf (stderr, "%s:%d. Unsupported constant value.\n",
- Getfile(node), Getline(node));
- return;
+ /* ------------------------------------------------------------
+ * 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;
}
- // See if there's a typemap
-
- if (SwigType_type(type) == T_STRING) {
- rvalue = NewStringf("\"%s\"", value);
- } else if (SwigType_type(type) == T_CHAR) {
- rvalue = NewStringf("\'%s\'", value);
- } else {
- rvalue = NewString(value);
+ /* ------------------------------------------------------------
+ * 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;
}
- if ((tm = guile_typemap_lookup ("const", type, name,
- Char(rvalue), name, f))) {
- Printf (f_init, "%s\n", tm);
- } else {
- // Create variable and assign it a value
-
- Printf (f_header, "static %s %s = ", SwigType_lstr(type,0), 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);
+
+ /* ------------------------------------------------------------
+ * 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
+ }
}
- // Now create a variable declaration
-
- Hash *nnode = Copy(node);
- Setattr(nnode,"name",var_name);
- variable(nnode);
- Delete(nnode);
- ReadOnly = OldStatus;
+ return Language::pragmaDirective(n);
}
- Delete(proc_name);
- Delete(rvalue);
- Delete(f);
-}
-void GUILE::cpp_variable(DOH *node)
-{
- if (emit_setters) {
- struct_member = 1;
- Printf(f_init, "{\n");
- Language::cpp_variable(node);
- Printf(f_init, "}\n");
- struct_member = 0;
- }
- else {
- /* Only emit traditional VAR-get and VAR-set procedures */
- Language::cpp_variable(node);
+ /* ------------------------------------------------------------
+ * 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. */
+ /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */
+ /* <initial> --> <letter> | <special initial> */
+ if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~'))) {
+ /* <peculiar identifier> --> + | - | ... */
+ if ((strcmp(c, "+") == 0)
+ || strcmp(c, "-") == 0
+ || strcmp(c, "...") == 0) return 1;
+ else return 0;
+ }
+ /* <subsequent> --> <initial> | <digit> | <special subsequent> */
+ 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/Modules1.1/guile.h b/Source/Modules1.1/guile.h
deleted file mode 100644
index a9aef3374..000000000
--- a/Source/Modules1.1/guile.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*****************************************************************************
- * 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.
- *****************************************************************************/
-
-/**************************************************************************
- * $Header$
- *
- * class GUILE
- *
- * Guile implementation
- *
- **************************************************************************/
-
-#include "swig.h"
-
-class GUILE : public Language
-{
-private:
- char *prefix;
- char *module;
- char *package;
- enum {
- GUILE_LSTYLE_SIMPLE, // call `SWIG_init()'
- GUILE_LSTYLE_LTDLMOD, // "native" guile?
- GUILE_LSTYLE_HOBBIT // use (hobbit4d link)
- } linkage;
- File *procdoc;
- int emit_setters;
- int struct_member;
- void emit_linkage(char *module_name);
-
-public :
- GUILE ();
- void parse_args (int, char *argv[]);
- void initialize(String *module);
- void function (DOH *node);
- void variable (DOH *node);
- void constant (DOH *node);
- void close (void);
- void create_command (String *, String *) { };
- void cpp_variable(DOH *node);
-};
-
-/* guile.h ends here */
diff --git a/Source/Modules1.1/java.cxx b/Source/Modules1.1/java.cxx
index 18b7011d5..499a58b24 100644
--- a/Source/Modules1.1/java.cxx
+++ b/Source/Modules1.1/java.cxx
@@ -1,1347 +1,1900 @@
-/*******************************************************************************
- * SWIG Java module
- * Author: Harco de Hilster
- * AT Consultancy
- * Toernooiveld 104
- * P.O. Box 1428
- * 6501 BK Nijmegen
- * +31 24 3527282
- * harcoh@ATConsultancy.nl
+/* -----------------------------------------------------------------------------
+ * java.cxx
*
- * thanks to the following persons for submitting bug-reports:
+ * Java wrapper module.
*
- * James Hicks <jamey@crl.dec.com>
- * Lars Schmidt-Thieme <lschmidt@ix.urz.uni-heidelberg.de>
- * Per OEyvind Hvidsten Per-Oyvind.Hvidsten@ffi.no
- * Geoff Dillon <gdillon@pervasive.com>
- * Michael Haller <haller@lionbio.co.uk>
- * "Simon J. Julier" <sjulier@erols.com>
- * "Pritam Kamat" <pritam@alier.com>
- * Marc Hadley <marc_hadley@chrystal.co.uk>
- *******************************************************************************
-*/
-
-/* !!!!!!!
- * DB 7/24/00: Is there any way to clean up the implementation of this module?
- * I've tried to bring it as far as I can with core changes, but it's getting
- * to be a little rough.
- * !!!!!!!
- */
+ * 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 <ctype.h>
+#include <limits.h> // 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)
+
+ {
+ }
-#include "mod11.h"
-#include "java.h"
-
-char bigbuf[1024];
-
-static char *usage = (char*)"\
-Java Options\n\
- -jnic - use c syntax for jni calls\n\
- -jnicpp - use c++ syntax for jni calls\n\
- -module name - set name of module\n\
- -package name - set name of package\n\
- -shadow - enable shadow classes\n\
- -finalize - generate finalize methods\n\
- -rn - generate register natives code\n\n";
-
-static char *module = 0; // Name of the module
-static char *java_path = (char*)"java";
-static char *package = 0; // Name of the package
-static char *c_pkgstr; // Name of the package
-static char *jni_pkgstr; // Name of the package
-static char *shadow_classname;
-static char *jimport = 0;
-static char *method_modifiers = (char*)"public final static";
-static FILE *f_java = 0;
-static FILE *f_shadow = 0;
-static int shadow = 0;
-static DOHHash *shadow_classes;
-static DOHString *shadow_classdef;
-static char *shadow_name = 0;
-static char *shadow_baseclass = 0;
-static int classdef_emitted = 0;
-static int shadow_classdef_emitted = 0;
-static int have_default_constructor = 0;
-static int native_func = 0; // Set to 1 when wrapping a native function
-static int member_func = 0; // Set to 1 when wrapping a member function
-static int jnic = -1; // 1: use c syntax jni; 0: use c++ syntax jni
-static int finalize = 0; // generate finalize methods
-static int useRegisterNatives = 0; // Set to 1 when doing stuff with register natives
-static DOHString *registerNativesList = 0;
-
-char *JAVA::SwigTcToJniType(DataType *t, int ret) {
- if(DataType_is_pointer(t) == 1) {
- switch(DataType_Gettypecode(t)) {
- case T_INT: return (char*)"jintArray";
- case T_SHORT: return (char*)"jshortArray";
- case T_LONG: return (char*)"jlongArray";
- case T_CHAR: return (char*)"jstring";
- case T_FLOAT: return (char*)"jfloatArray";
- case T_DOUBLE: return (char*)"jdoubleArray";
- case T_UINT: return (char*)"jintArray";
- case T_USHORT: return (char*)"jshortArray";
- case T_ULONG: return (char*)"jlongArray";
- case T_UCHAR: return (char*)"jbyteArray";
- case T_SCHAR: return (char*)"jbyteArray";
- case T_BOOL: return (char*)"jbooleanArray";
- case T_VOID:
- case T_USER: return (char*)"jlong";
- }
- } else if(DataType_is_pointer(t) > 1) {
- if(ret)
- return (char*)"jlong";
- else return (char*)"jlongArray";
- } else {
- switch(DataType_Gettypecode(t)) {
- case T_INT: return (char*)"jint";
- case T_SHORT: return (char*)"jshort";
- case T_LONG: return (char*)"jlong";
- case T_CHAR: return (char*)"jbyte";
- case T_FLOAT: return (char*)"jfloat";
- case T_DOUBLE: return (char*)"jdouble";
- case T_UINT: return (char*)"jint";
- case T_USHORT: return (char*)"jshort";
- case T_ULONG: return (char*)"jlong";
- case T_UCHAR: return (char*)"jbyte";
- case T_SCHAR: return (char*)"jbyte";
- case T_BOOL: return (char*)"jboolean";
- case T_VOID: return (char*)"void";
- case T_USER: return (char*)"jlong";
- }
+ /* -----------------------------------------------------------------------------
+ * 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;
}
- Printf(stderr, "SwigTcToJniType: unhandled SWIG type %s\n", DataType_str(t,0));
- return NULL;
-}
-char *JAVA::SwigTcToJavaType(DataType *t, int ret, int inShadow) {
- if(DataType_is_pointer(t) == 1) {
- switch(DataType_Gettypecode(t)) {
- case T_INT: return (char*)"int []";
- case T_SHORT: return (char*)"short []";
- case T_LONG: return (char*)"long []";
- case T_CHAR: return (char*)"String";
- case T_FLOAT: return (char*)"float []";
- case T_DOUBLE: return (char*)"double []";
- case T_UINT: return (char*)"int []";
- case T_USHORT: return (char*)"short []";
- case T_ULONG: return (char*)"long []";
- case T_UCHAR: return (char*)"byte []";
- case T_SCHAR: return (char*)"byte []";
- case T_BOOL: return (char*)"boolean []";
- case T_VOID:
- case T_USER: if(inShadow && Getattr(shadow_classes,DataType_Getname(t)))
- return GetChar(shadow_classes,DataType_Getname(t));
- else return (char*)"long";
- }
- } else if(DataType_is_pointer(t) > 1) {
- if(ret)
- return (char*)"long";
- else return (char*)"long []";
- } else {
- switch(DataType_Gettypecode(t)) {
- case T_INT: return (char*)"int";
- case T_SHORT: return (char*)"short";
- case T_LONG: return (char*)"long";
- case T_CHAR: return (char*)"byte";
- case T_FLOAT: return (char*)"float";
- case T_DOUBLE: return (char*)"double";
- case T_UINT: return (char*)"int";
- case T_USHORT: return (char*)"short";
- case T_ULONG: return (char*)"long";
- case T_UCHAR: return (char*)"byte";
- case T_SCHAR: return (char*)"byte";
- case T_BOOL: return (char*)"boolean";
- case T_VOID: return (char*)"void";
- case T_USER: return (char*)"long";
- }
- }
- Printf(stderr, "SwigTcToJavaType: unhandled SWIG type %s\n", DataType_str(t,0));
- return NULL;
-}
+ /* -----------------------------------------------------------------------------
+ * makeValidJniName()
+ * ----------------------------------------------------------------------------- */
-char *JAVA::SwigTcToJniScalarType(DataType *t) {
- if(DataType_is_pointer(t) == 1) {
- switch(DataType_Gettypecode(t)) {
- case T_INT: return (char*)"Int";
- case T_SHORT: return (char*)"Short";
- case T_LONG: return (char*)"Long";
- case T_CHAR: return (char*)"Byte";
- case T_FLOAT: return (char*)"Float";
- case T_DOUBLE: return (char*)"Double";
- case T_UINT: return (char*)"Int";
- case T_USHORT: return (char*)"Short";
- case T_ULONG: return (char*)"Long";
- case T_UCHAR: return (char*)"Byte";
- case T_SCHAR: return (char*)"Byte";
- case T_BOOL: return (char*)"Boolean";
- case T_VOID:
- case T_USER: return (char*)"Long";
- }
- } else {
- return (char*)"Long";
+ String *makeValidJniName(const String *name) {
+ String *valid_jni_name = NewString(name);
+ Replaceall(valid_jni_name,"_","_1");
+ return valid_jni_name;
}
- Printf(stderr, "SwigTcToJniScalarType: unhandled SWIG type %s\n", DataType_str(t,0));
- return NULL;
-}
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
-char *JAVA::JavaMethodSignature(DataType *t, int ret, int inShadow) {
- if(DataType_is_pointer(t) == 1) {
- switch(DataType_Gettypecode(t)) {
- case T_INT: return (char*)"[I";
- case T_SHORT: return (char*)"[S";
- case T_LONG: return (char*)"[J";
- case T_CHAR: return (char*)"Ljava/lang/String;";
- case T_FLOAT: return (char*)"[F";
- case T_DOUBLE: return (char*)"[D";
- case T_UINT: return (char*)"[I";
- case T_USHORT: return (char*)"[S";
- case T_ULONG: return (char*)"[J";
- case T_UCHAR: return (char*)"[B";
- case T_SCHAR: return (char*)"[B";
- case T_BOOL: return (char*)"[Z";
- case T_VOID:
- case T_USER: if(inShadow && Getattr(shadow_classes,DataType_Getname(t)))
- return GetChar(shadow_classes,DataType_Getname(t));
- else return (char*)"J";
- }
- } else if(DataType_is_pointer(t) > 1) {
- if(ret) return (char*)"J";
- else return (char*)"[J";
- } else {
- switch(DataType_Gettypecode(t)) {
- case T_INT: return (char*)"I";
- case T_SHORT: return (char*)"S";
- case T_LONG: return (char*)"J";
- case T_CHAR: return (char*)"B";
- case T_FLOAT: return (char*)"F";
- case T_DOUBLE: return (char*)"D";
- case T_UINT: return (char*)"I";
- case T_USHORT: return (char*)"S";
- case T_ULONG: return (char*)"J";
- case T_UCHAR: return (char*)"B";
- case T_SCHAR: return (char*)"B";
- case T_BOOL: return (char*)"Z";
- case T_VOID: return (char*)"V";
- case T_USER: return (char*)"J";
- }
- }
- Printf(stderr, "JavaMethodSignature: unhandled SWIG type %s\n", DataType_str(t,0));
- return NULL;
-}
+ virtual void main(int argc, char *argv[]) {
-char *JAVA::JavaTypeFromTypemap(char *op, char *lang, DataType *t, char *pname) {
- char *tm;
- char *c = bigbuf;
- if(!(tm = typemap_lookup(op, lang, t, pname, (char*)"", (char*)""))) return NULL;
- while(*tm && (isspace(*tm) || *tm == '{')) tm++;
- while(*tm && *tm != '}') *c++ = *tm++;
- *c='\0';
+ SWIG_library_directory("java");
- return strdup(bigbuf);
-}
+ // 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);
-char *JAVA::makeValidJniName(char *name) {
- char *c = name;
- char *b = bigbuf;
+ // Add typemap definitions
+ SWIG_typemap_lang("java");
+ SWIG_config_file("java.swg");
- while(*c) {
- *b++ = *c;
- if(*c == '_') *b++ = '1';
- c++;
+ allow_overloading();
}
- *b = '\0';
- return strdup(bigbuf);
-}
+ /* ---------------------------------------------------------------------
+ * top()
+ * --------------------------------------------------------------------- */
-// !! this approach fails for functions without arguments
-char *JAVA::JNICALL(DOHString_or_char *func) {
- if(jnic)
- sprintf(bigbuf, "(*jenv)->%s(jenv, ", Char(func));
- else
- sprintf(bigbuf, "jenv->%s(", Char(func));
+ virtual int top(Node *n) {
- return strdup(bigbuf);
-}
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
-void JAVA::writeRegisterNatives()
-{
- if(Len(registerNativesList) == 0)
- return;
-
- Printf(f_wrappers,"\n");
- Printf(f_wrappers,"JNINativeMethod nativeMethods[] = {\n");
- Printv(f_wrappers, registerNativesList, 0);
- Printf(f_wrappers, "};\n");
-
- Printf(f_wrappers,"\nint numberOfNativeMethods=sizeof(nativeMethods)/sizeof(JNINativeMethod);\n\n");
-
- // The registerNatives function
-
- Printv(f_wrappers,
- "jint registerNatives(JNIEnv *jenv) {", "\n",
- tab4, "jclass nativeClass = ", JNICALL((char*)"FindClass"),
- "\"", jni_pkgstr, module, "\");","\n",
- 0);
-
- Printv(f_wrappers,
- tab4, "if (nativeClass == 0)", "\n", tab8, "return -1;", "\n",
- tab4, "return ", JNICALL((char*)"RegisterNatives"), "nativeClass, nativeMethods, ", "numberOfNativeMethods);", "\n",
- "}", "\n", "\n",
- 0);
-
- // The unregisterNatives function
-
- Printv(f_wrappers,
- "jint unregisterNatives(JNIEnv *jenv) {", "\n",
- tab4, "jclass nativeClass = ", JNICALL((char*)"FindClass"),
- "\"", jni_pkgstr, module, "\");","\n",
- 0);
-
- Printv(f_wrappers,
- tab4, "if (nativeClass == 0)", "\n", tab8, "return -1;", "\n",
- tab4, "// Sun documentation suggests that this method should not be invoked in ",
- "\"normal native code\".", "\n",
- tab4, "// return ", JNICALL((char*)"UnregisterNatives"), "nativeClass);", "\n",
- tab4, "return 0;", "\n",
- "}", "\n",
- 0);
-}
+ 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"));
+ }
-// ---------------------------------------------------------------------
-// JAVA::parse_args(int argc, char *argv[])
-//
-// Parse my command line options and initialize by variables.
-// ---------------------------------------------------------------------
-
-void JAVA::parse_args(int argc, char *argv[]) {
-
- // file::set_library(java_path);
- sprintf(LibDir,"%s", "java");
-
-
- // Look for certain command line options
- for (int i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i],"-module") == 0) {
- if (argv[i+1]) {
- set_module(argv[i+1],0);
- 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])+1];
- strcpy(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) {
- Swig_mark_arg(i);
- shadow = 1;
- } else if (strcmp(argv[i],"-jnic") == 0) {
- Swig_mark_arg(i);
- jnic = 1;
- } else if (strcmp(argv[i],"-finalize") == 0) {
- Swig_mark_arg(i);
- finalize = 1;
- } else if (strcmp(argv[i],"-rn") == 0) {
- Swig_mark_arg(i);
- useRegisterNatives = 1;
- } else if (strcmp(argv[i],"-jnicpp") == 0) {
- Swig_mark_arg(i);
- jnic = 0;
- } else if (strcmp(argv[i],"-help") == 0) {
- Printf(stderr,"%s\n", usage);
+
+ 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);
}
- }
- if(jnic == -1) {
- if(CPlusPlus)
- jnic = 0;
- else jnic = 1;
- }
+ // 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;
- // Add a symbol to the parser for conditional compilation
- // cpp::define("SWIGJAVA");
- Preprocessor_define((void *) "SWIGJAVA 1",0);
+ // Start writing out the Java module class
+ if(Len(package) > 0)
+ Printf(f_module, "package %s;\n\n", package);
- // Add typemap definitions
- typemap_lang = (char*)"java";
-}
+ emitBanner(f_module);
+ if(module_imports)
+ Printf(f_module, "%s\n", module_imports);
-// ---------------------------------------------------------------------
-// void JAVA::parse()
-//
-// Start parsing an interface file for JAVA.
-// ---------------------------------------------------------------------
+ if (Len(module_class_modifiers) > 0)
+ Printf(f_module, "%s ", module_class_modifiers);
+ Printf(f_module, "class %s ", module_class_name);
-void JAVA::parse() {
+ 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");
- Printf(stderr,"Generating wrappers for Java\n");
+ // Add the wrapper methods
+ Printv(f_module, module_class_code, NIL);
- shadow_classes = NewHash();
- shadow_classdef = NewString("");
- registerNativesList = NewString("");
+ // Write out all the enums constants
+ if (Len(module_constants_code) != 0 )
+ Printv(f_module, " // enums and constants\n", module_constants_code, NIL);
- headers(); // Emit header files and other supporting code
- yyparse(); // Run the SWIG parser
-}
+ // Finish off the Java class
+ Printf(f_module, "}\n");
+ Close(f_module);
+ }
-// ---------------------------------------------------------------------
-// JAVA::set_module(char *mod_name,char **mod_list)
-//
-// Sets the module name. Does nothing if it's already set (so it can
-// be overriddent as a command line option).
-//
-// mod_list is a NULL-terminated list of additional modules. This
-// is really only useful when building static executables.
-//----------------------------------------------------------------------
-
-void JAVA::set_module(char *mod_name, char **mod_list) {
- if (module) return;
- module = new char[strlen(mod_name)+1];
- strcpy(module,mod_name);
-}
+ if(wrapper_conversion_code)
+ Printv(f_wrappers,wrapper_conversion_code,NIL);
-// ---------------------------------------------------------------------
-// JAVA::headers(void)
-//
-// Generate the appropriate header files for JAVA interface.
-// ----------------------------------------------------------------------
-
-void JAVA::headers(void)
-{
- Swig_banner(f_header); // Print the SWIG banner message
- Printf(f_header,"/* Implementation : Java */\n\n");
-
- // Include header file code fragment into the output
- // if (file::include("java.swg",f_header) == -1) {
- if (Swig_insert_file("java.swg",f_header) == -1) {
- Printf(stderr,"Fatal Error. Unable to locate 'java.swg'.\n");
- SWIG_exit (EXIT_FAILURE);
- }
-}
+ Printf(f_wrappers,"#ifdef __cplusplus\n");
+ Printf(f_wrappers,"}\n");
+ Printf(f_wrappers,"#endif\n");
-// --------------------------------------------------------------------
-// JAVA::initialize(void)
-//
-// Produces an initialization function. Assumes that the init function
-// name has already been specified.
-// ---------------------------------------------------------------------
-
-void JAVA::initialize()
-{
- if (!module) {
- Printf(stderr,"*** Error. No module name specified.\n");
- SWIG_exit(1);
- }
+ // 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));
+ }
- if(package) {
- DOHString *s = NewString(package);
- Replace(s,".","_", DOH_REPLACE_ANY);
- Append(s,"_");
- c_pkgstr = Swig_copy_string(Char(s));
- Delete(s);
-
- DOHString *s2 = NewString(package);
- Replace(s2,".","/", DOH_REPLACE_ANY);
- Append(s2,"/");
- jni_pkgstr = Swig_copy_string(Char(s2));
- Delete(s2);
- } else {
- package = c_pkgstr = jni_pkgstr = (char*)"";
+ 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;
}
- sprintf(bigbuf, "Java_%s%s", c_pkgstr, module);
- c_pkgstr = Swig_copy_string(bigbuf);
- sprintf(bigbuf, "%s_%%f", c_pkgstr);
- Swig_name_register((char*)"wrapper", Swig_copy_string(bigbuf));
- Swig_name_register((char*)"set", (char*)"set_%v");
- Swig_name_register((char*)"get", (char*)"get_%v");
- Swig_name_register((char*)"member", (char*)"%c_%m");
-
- // Generate the java class
- sprintf(bigbuf, "%s.java", module);
- if((f_java = fopen(bigbuf, "w")) == 0) {
- Printf(stderr,"Unable to open %s\n", bigbuf);
- SWIG_exit(1);
+ /* -----------------------------------------------------------------------------
+ * 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");
}
- Printf(f_header, "#define J_CLASSNAME %s\n", module);
- if(package && *package) {
- Printf(f_java, "package %s;\n\n", package);
- Printf(f_header, "#define J_PACKAGE %s\n", package);
- } else {
- Printf(f_header, "#define J_PACKAGE\n");
- }
-}
+ /* ----------------------------------------------------------------------
+ * nativeWrapper()
+ * ---------------------------------------------------------------------- */
-void JAVA::emit_classdef() {
- if(!classdef_emitted)
- Printf(f_java, "public class %s {\n", module);
- classdef_emitted = 1;
-}
+ virtual int nativeWrapper(Node *n) {
+ String *wrapname = Getattr(n,"wrap:name");
-// ---------------------------------------------------------------------
-// JAVA::close(void)
-//
-// Wrap things up. Close initialization function.
-// ---------------------------------------------------------------------
+ if (!addSymbol(wrapname,n)) return SWIG_ERROR;
-void JAVA::close(void)
-{
- if(!classdef_emitted) emit_classdef();
+ 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"));
+ }
- // Finish off the java class
- Printf(f_java, "}\n");
- fclose(f_java);
+ return SWIG_OK;
+ }
- if(useRegisterNatives)
- writeRegisterNatives();
-}
+ /* ----------------------------------------------------------------------
+ * 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;
+ }
-// ----------------------------------------------------------------------
-// JAVA::create_command(char *cname, char *iname)
-//
-// Creates a JAVA command from a C function.
-// ----------------------------------------------------------------------
+ /*
+ 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);
+ }
-void JAVA::create_command(char *cname, char *iname) {
-}
+ /*
+ 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.
+ */
-void JAVA::add_native(char *name, char *iname, DataType *t, ParmList *l) {
- native_func = 1;
- create_function(name, iname, t, l);
- native_func = 0;
-}
+ // A new wrapper function object
+ Wrapper *f = NewWrapper();
-// ----------------------------------------------------------------------
-// JAVA::create_function(char *name, char *iname, DataType *d, ParmList *l)
-//
-// Create a function declaration and register it with the interpreter.
-// ----------------------------------------------------------------------
-
-void JAVA::create_function(char *name, char *iname, DataType *t, ParmList *l)
-{
- char source[256], target[256];
- char *tm;
- DOHString *cleanup, *outarg, *body;
- char *javaReturnSignature = 0;
- DOHString *javaParameterSignature;
- Parm *p;
-
- cleanup = NewString("");
- outarg = NewString("");
- body = NewString("");
- javaParameterSignature = NewString("");
-
- // A new wrapper function object
- Wrapper *f = NewWrapper();
-
- if(!classdef_emitted) emit_classdef();
-
- // Make a wrapper name for this function
-
- char *jniname = makeValidJniName(iname);
- char *wname = Swig_name_wrapper(jniname);
- free(jniname);
-
- char *jnirettype = JavaTypeFromTypemap((char*)"jni", typemap_lang, t, iname);
- if(!jnirettype) jnirettype = SwigTcToJniType(t, 1);
- char *javarettype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, t, iname);
- if(!javarettype) javarettype = SwigTcToJavaType(t, 1, 0);
-
- // If dumping the registerNative outputs, store the method return type
- // signature
- if (useRegisterNatives) {
- javaReturnSignature = JavaMethodSignature(t, 1, 0);
- }
+ // Make a wrapper name for this function
+ String *jniname = makeValidJniName(overloaded_name);
+ String *wname = Swig_name_wrapper(jniname);
+ Delete(jniname);
- if (DataType_type(t) != T_VOID) {
- Wrapper_add_localv(f,"_jresult", jnirettype, "_jresult = 0",0);
- }
+ /* Attach the non-standard typemaps to the parameter list. */
+ Swig_typemap_attach_parms("jni", l, f);
+ Swig_typemap_attach_parms("jtype", l, f);
- Printf(f_java, " %s ", method_modifiers);
- Printf(f_java, "native %s %s(", javarettype, iname);
- if(shadow && member_func) {
- DOHString *member_name = NewString("");
- if(strcmp(iname, Swig_name_set(Swig_name_member(shadow_classname, shadow_name))) == 0)
- Printf(member_name,"set");
- else Printf(member_name,"get");
- Putc(toupper((int) *shadow_name), member_name);
- Printf(member_name, "%s", shadow_name+1);
- Printf(f_shadow, " public %s %s(", javarettype, member_name);
- Printv(body, tab4, "return ", module, ".", iname, "(_self", 0);
- Delete(member_name);
- }
+ /* 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(!jnic) Printf(f->def,"extern \"C\"\n");
- Printv(f->def, "JNIEXPORT ", jnirettype, " JNICALL ", wname, "(JNIEnv *jenv, jclass jcls", 0);
-
- // Emit all of the local variables for holding arguments.
- int pcount = emit_args(t,l,f);
-
- int gencomma = 0;
-
- // Now walk the function parameter list and generate code to get arguments
- p = l;
- for (int i = 0; i < pcount ; i++, p = Getnext(p)) {
- DataType *pt = Gettype(p);
- char *pn = Getname(p);
- char *target_copy = NULL;
- char *target_length = NULL;
- char *local_i = NULL;
-
- // Produce string representation of source and target arguments
- sprintf(source,"jarg%d",i);
- sprintf(target,"%s", Getlname(p));
-
- char *jnitype = JavaTypeFromTypemap((char*)"jni", typemap_lang, pt, pn);
- if(!jnitype) jnitype = SwigTcToJniType(pt, 0);
- char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn);
- if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0);
- if (useRegisterNatives) {
- Printv(javaParameterSignature, JavaMethodSignature(pt, 0, 0), 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));
}
- if(Getignore(p)) continue;
+ is_void_return = (Cmp(jnirettype, "void") == 0);
+ if (!is_void_return)
+ Wrapper_add_localv(f,"jresult", jnirettype, "jresult = 0",NIL);
- // Add to java function header
- if(shadow && member_func) {
- if(i > 0) {
- if(i>1) Printf(f_shadow, ", ");
- Printf(f_shadow, "%s %s", jtype, source);
- Printv(body,", ", source, 0);
- }
+ 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));
}
- if(gencomma) Printf(f_java, ", ");
- Printf(f_java, "%s %s", jtype, source);
+ /* 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, ", ", jnitype, " ", source, 0);
+ Printv(f->def, ", ", jni_param_type, " ", arg, NIL);
// Get typemap for this argument
- tm = typemap_lookup((char*)"in",typemap_lang,pt,pn,source,target,f);
- if (tm) {
- Printf(f->code,"%s\n", tm);
- Replace(f->code,"$arg",source, DOH_REPLACE_ANY);
+ 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 {
- if(!DataType_is_pointer(pt))
- Printv(f->code, tab4, target, " = (", DataType_lstr(pt,0), ") ", source, ";\n", 0);
- else if((DataType_Gettypecode(pt) == T_VOID && (DataType_is_pointer(pt) == 1)) ||
- (DataType_Gettypecode(pt) == T_USER && (DataType_is_pointer(pt) == 1))) {
- DataType_add_pointer(pt);
- Printv(f->code, tab4, target, " = *(", DataType_lstr(pt,0), ")&", source, ";\n", 0);
- DataType_del_pointer(pt);
- } else {
- if(DataType_type(pt) == T_STRING) {
- Printv(f->code, tab4, target, " = (", source, ") ? (char *)", JNICALL((char*)"GetStringUTFChars"), source, ", 0) : NULL;\n", 0);
- } else {
- char *scalarType = SwigTcToJniScalarType(pt);
-
- DataType_del_pointer(pt);
- const char *basic_jnitype = (DataType_is_pointer(pt) > 0) ? "jlong" : SwigTcToJniType(pt, 0);
- char *ctype = DataType_lstr(pt,0);
- if(scalarType == NULL || basic_jnitype == NULL) {
- Printf(stderr, "\'%s\' does not have a in/jni typemap, and is not a basic type.\n", ctype);
- SWIG_exit(1);
- };
- DataType_add_pointer(pt);
-
- DOHString *basic_jniptrtype = NewStringf("%s*",basic_jnitype);
- DOHString *source_length = NewStringf("%s%s)", JNICALL((char*)"GetArrayLength"), source);
-
- target_copy = Swig_copy_string(Wrapper_new_localv(f,target,Char(basic_jniptrtype), target, 0));
- target_length = Swig_copy_string(Wrapper_new_localv(f,target,"jsize", target, "=", Char(source_length),0));
- if(local_i == NULL) local_i = Swig_copy_string(Wrapper_new_local(f,"i","int i"));
-
- DOHString *scalarFunc = NewStringf("Get%sArrayElements",scalarType);
-
- Printv(f->code, tab4, target_copy, " = ", JNICALL(scalarFunc), source, ", 0);\n", 0);
- Printv(f->code, tab4, target, " = (", DataType_lstr(pt,0), ") malloc(", target_length, " * sizeof(", ctype, "));\n", 0);
- Printv(f->code, tab4, "for(i=0; i<", target_length, "; i++)\n", 0);
- if(DataType_is_pointer(pt) > 1) {
- Printv(f->code, tab8, target, "[i] = *(", DataType_lstr(pt,0), ")&", target_copy, "[i];\n", 0);
- } else {
- DataType_del_pointer(pt);
- Printv(f->code, tab8, target, "[i] = (", DataType_lstr(pt,0), ")", target_copy, "[i];\n", 0);
- DataType_add_pointer(pt);
- }
- Delete(scalarFunc);
- Delete(source_length);
- Delete(basic_jniptrtype);
- }
- }
+ 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);
}
-
- // Check to see if there was any sort of a constaint typemap
- if ((tm = typemap_lookup((char*)"check",typemap_lang,pt,pn,source,target))) {
- // Yep. Use it instead of the default
- Printf(f->code,"%s\n", tm);
- Replace(f->code,"$arg",source, DOH_REPLACE_ANY);
+ Delete(javaparamtype);
+ Delete(jni_param_type);
+ Delete(arg);
}
- // Check if there was any cleanup code (save it for later)
- if ((tm = typemap_lookup((char*)"freearg",typemap_lang,pt,pn,source,target))) {
- // Yep. Use it instead of the default
- Printf(cleanup,"%s\n", tm);
- Replace(cleanup,"$arg",source, DOH_REPLACE_ANY);
+ /* 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);
+ }
}
- if ((tm = typemap_lookup((char*)"argout",typemap_lang,pt,pn,source,target))) {
- // Yep. Use it instead of the default
- Printf(outarg,"%s\n", tm);
- Replace(outarg,"$arg",source, DOH_REPLACE_ANY);
- } else {
- // if(pt->is_pointer && pt->type != T_USER && pt->type != T_VOID) {
- if(DataType_is_pointer(pt)) {
- if(DataType_type(pt) == T_STRING) {
- Printv(outarg, tab4, "if(", target,") ", JNICALL((char*)"ReleaseStringUTFChars"), source, ", ", target, ");\n", 0);
- } else if(((DataType_Gettypecode(pt) == T_VOID) && DataType_is_pointer(pt) == 1) ||
- ((DataType_Gettypecode(pt) == T_USER) && DataType_is_pointer(pt) == 1)) {
- // nothing to do
- } else {
- char *scalarType = SwigTcToJniScalarType(pt);
-
- DataType_del_pointer(pt);
- const char *basic_jnitype = (DataType_is_pointer(pt) > 0) ? "jlong" : SwigTcToJniType(pt, 0);
- char *ctype = DataType_lstr(pt,0);
- if(scalarType == NULL || basic_jnitype == NULL) {
- Printf(stderr, "\'%s\' does not have a argout/jni typemap, and is not a basic type.\n", ctype);
- SWIG_exit(1);
- };
- DataType_add_pointer(pt);
- Printf(outarg, " for(i=0; i< %d; i++)\n", target_length);
- if(DataType_is_pointer(pt) > 1) {
- Printv(outarg, tab8, "*(", DataType_lstr(pt,0), ")&", target_copy, "[i] = ", target, "[i];\n", 0);
- } else {
- Printv(outarg, tab8, target_copy, "[i] = (", basic_jnitype, ") ", target, "[i];\n", 0);
- }
- DOHString *scalarFunc = NewStringf("Release%sArrayElements",scalarType);
- Printv(outarg, tab4, JNICALL(scalarFunc), source, ", ", target_copy, ", 0);\n", 0);
- Printv(outarg, tab4, "free(", target, ");\n", 0);
- Delete(scalarFunc);
- free(target_copy);
- free(target_length);
- free(local_i);
- }
- }
+ /* 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);
+ }
}
- }
- Printf(f_java, ");\n");
- if(shadow && member_func) {
- Printf(f_shadow, ") {\n");
- Printf(body,")");
- Printf(f_shadow, "%s;\n }\n\n",body);
- }
- Printf(f->def,") {");
+ /* 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);
+ }
+ }
- // Now write code to make the function call
+ // 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(!native_func)
- emit_func_call(name,t,l,f);
+ if (Cmp(nodeType(n), "constant") == 0) {
+ // Wrapping a constant hack
+ Swig_save(&n,"wrap:action",NIL);
- // Return value if necessary
+ // 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")));
+ }
- if((DataType_type(t) != T_VOID) && !native_func) {
- if ((tm = typemap_lookup((char*)"out",typemap_lang,t,iname,(char*)"result",(char*)"_jresult"))) {
- Printf(f->code,"%s\n", tm);
- } else {
- if(DataType_type(t) == T_USER) { /* return by value */
- DataType_add_pointer(t);
- DataType_add_pointer(t);
- Printv(f->code, tab4, "*(", DataType_lstr(t,0), ")&_jresult = result;\n", 0);
- DataType_del_pointer(t);
- DataType_del_pointer(t);
- } else if(DataType_is_pointer(t) == 0 && (DataType_Gettypecode(t) != T_USER)) {
- Printv(f->code, tab4, "_jresult = (", jnirettype, ") result;\n", 0);
- } else if(((DataType_Gettypecode(t) == T_VOID) && DataType_is_pointer(t) == 1) ||
- ((DataType_Gettypecode(t) == T_USER) && DataType_is_pointer(t) == 1)) {
- DataType_add_pointer(t);
- Printv(f->code, tab4, "*(", DataType_lstr(t,0), ")&_jresult = result;\n", 0);
- DataType_del_pointer(t);
+ // 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 {
- if(DataType_type(t) == T_STRING) {
- Printv(f->code, tab4, "if(result != NULL)\n", 0);
- Printv(f->code, tab8, "_jresult = (jstring)", JNICALL((char*)"NewStringUTF"), "result);\n", 0);
- } else {
- Printf(stderr,"%s : Line %d. Warning: no return typemap for datatype %s\n", input_file,line_number,DataType_str(t,0));
- DataType_add_pointer(t);
- Printv(f->code, tab4, "*(", DataType_lstr(t,0), ")&_jresult = result;\n", 0);
- DataType_del_pointer(t);
- }
+ 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"));
}
}
- }
- // Dump argument output code;
- Printv(f->code, outarg, 0);
+ /* Output argument output code */
+ Printv(f->code,outarg,NIL);
- // Dump the argument cleanup code
- Printv(f->code,cleanup, 0);
+ /* Output cleanup code */
+ Printv(f->code,cleanup,NIL);
- // Look for any remaining cleanup
+ /* 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);
+ }
+ }
- if (NewObject) {
- if ((tm = typemap_lookup((char*)"newfree",typemap_lang,t,iname,(char*)"result",(char*)""))) {
- 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);
+ }
}
- }
- if((DataType_type(t) != T_VOID) && !native_func) {
- if ((tm = typemap_lookup((char*)"ret",typemap_lang,t,iname,(char*)"result",(char*)"_jresult", NULL))) {
- 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);
}
- }
- // Wrap things up (in a manner of speaking)
- if(DataType_type(t) != T_VOID)
- Printv(f->code, tab4, "return _jresult;\n", 0);
- Printf(f->code, "}\n");
+ Delete(jnirettype);
+ Delete(javarettype);
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(body);
+ Delete(javaParameterSignature);
+ Delete(overloaded_name);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
- // Substitute the cleanup code (some exception handlers like to have this)
- Replace(f->code,"$cleanup",cleanup, DOH_REPLACE_ANY);
+ /* -----------------------------------------------------------------------
+ * variableWrapper()
+ *
+ * Create a JAVA link to a C variable.
+ * ----------------------------------------------------------------------- */
- // Emit the function
+ virtual int variableWrapper(Node *n) {
+ Language::variableWrapper(n); /* Default to functions */
+ return SWIG_OK;
+ }
- if(!native_func)
- Wrapper_print(f,f_wrappers);
+ /* -----------------------------------------------------------------------
+ * globalvariableHandler()
+ * ------------------------------------------------------------------------ */
- // If registerNatives is active, store the table entry for this method
- if (useRegisterNatives) {
- Printv(registerNativesList,
- tab4, "{",
- "\"", name, "\", \"(", javaParameterSignature, ")", javaReturnSignature, "\", ", wname,
- "},\n",
- 0);
+ 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;
}
- Delete(cleanup);
- Delete(outarg);
- Delete(body);
- Delete(javaParameterSignature);
- DelWrapper(f);
-}
+ /* -----------------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------------------ */
-// -----------------------------------------------------------------------
-// JAVA::link_variable(char *name, char *iname, DataType *t)
-//
-// Create a JAVA link to a C variable.
-// -----------------------------------------------------------------------
+ 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("");
-void JAVA::link_variable(char *name, char *iname, DataType *t)
-{
- emit_set_get(name,iname, t);
-}
+ if (!addSymbol(symname,n)) return SWIG_ERROR;
-// -----------------------------------------------------------------------
-// JAVA::declare_const(char *name, char *iname, DataType *type, char *value)
-// ------------------------------------------------------------------------
+ /* Attach the non-standard typemaps to the parameter list. */
+ Swig_typemap_attach_parms("jstype", l, NULL);
-void JAVA::declare_const(char *name, char *iname, DataType *type, char *value) {
- char *tm;
- FILE *jfile;
- char *jname;
+ /* 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));
+ }
- if(!classdef_emitted) emit_classdef();
+ // 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);
+ }
- if(shadow && member_func) {
- jfile = f_shadow;
- jname = shadow_name;
- } else {
- jfile = f_java;
- jname = name;
- }
+ // 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));
- if ((tm = typemap_lookup((char*)"const",typemap_lang,type,name,name,iname))) {
- DOHString *str = NewString(tm);
- Replace(str,"$value",value, DOH_REPLACE_ANY);
- Printf(jfile," %s\n\n", str);
- Delete(str);
- } else {
- if((DataType_is_pointer(type) == 0)) {
- char *jtype = typemap_lookup((char*)"jtype", typemap_lang, type, name, name, iname);
- if(!jtype) jtype = SwigTcToJavaType(type, 0, 0);
- if(strcmp(jname, value) == 0 || strstr(value,"::") != NULL) {
- Printf(stderr, "ignoring enum constant: %s\n", jname);
- } else
- Printf(jfile, " public final static %s %s = %s;\n\n", jtype, jname, value);
+ // 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 {
- if(DataType_type(type) == T_STRING) {
- Printf(jfile, " public final static String %s = \"%s\";\n\n", jname, value);
- } else {
- emit_set_get(name,iname, type);
+ // 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);
}
-}
-void emit_shadow_banner(FILE *f) {
- Printf(f, "/*\n");
- Printf(f, " *\n");
- Printf(f, " * This file was automatically generated by :\n");
- Printf(f, " * Simplified Wrapper and Interface Generator (SWIG)\n");
- Printf(f, " * Version: %s\n", SWIG_VERSION);
- Printf(f, " *\n");
- Printf(f, " * Portions Copyright (c) 1995-1997\n");
- Printf(f, " * The University of Utah and The Regents of the University of California.\n");
- Printf(f, " * Permission is granted to distribute this file in any manner provided\n");
- Printf(f, " * this notice remains intact.\n");
- Printf(f, " *\n");
- Printf(f, " * Portions Copyright (c) 1997-1999\n");
- Printf(f, " * Harco de Hilster, Harco.de.Hilster@ATConsultancy.nl\n");
- Printf(f, " *\n");
- Printf(f, " * Do not make changes to this file--changes will be lost!\n");
- Printf(f, " *\n");
- Printf(f, " */\n\n\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);
+ }
-void JAVA::pragma(char *lang, char *code, char *value) {
- if(strcmp(lang, "java") != 0) return;
-
- DOHString *s = NewString(value);
- Replace(s,"\\\"", "\"", DOH_REPLACE_ANY);
- if(strcmp(code, "import") == 0) {
- jimport = Swig_copy_string(Char(s));
- Printf(f_java, "// pragma\nimport %s;\n\n", jimport);
- } else if(strcmp(code, "module") == 0) {
- if(!classdef_emitted) emit_classdef();
- Printf(f_java, "// pragma\n");
- Printf(f_java, "%s", s);
- Printf(f_java, "\n\n");
- } else if(strcmp(code, "shadow") == 0) {
- if(shadow && f_shadow) {
- Printf(f_shadow, "// pragma\n");
- Printf(f_shadow, "%s", s);
- Printf(f_shadow, "\n\n");
+ // 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);
}
- } else if(strcmp(code, "modifiers") == 0) {
- method_modifiers = Swig_copy_string(value);
- } else {
- Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file,line_number);
+ Delete(baseclass);
}
- Delete(s);
-}
-// ---------------------------------------------------------------------
-// C++ Handling
-//
-// The following functions provide some support for C++ classes and
-// C structs.
-// ---------------------------------------------------------------------
+ /* ----------------------------------------------------------------------
+ * classHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int classHandler(Node *n) {
-void JAVA::add_typedef(DataType *t, char *name) {
- if(!shadow) return;
+ File *f_shadow = NULL;
+ if (proxy_flag) {
+ shadow_classname = NewString(Getattr(n,"sym:name"));
- // First check to see if there aren't too many pointers
+ 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 (DataType_is_pointer(t) > 1) return;
+ 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);
+ }
- if(Getattr(shadow_classes,name)) return; // Already added
+ 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;
- // Now look up the datatype in our shadow class hash table
+ emitBanner(f_shadow);
- if (Getattr(shadow_classes,DataType_Getname(t))) {
+ if(Len(package) > 0)
+ Printf(f_shadow, "package %s;\n\n", package);
- // Yep. This datatype is in the hash
- // Put this types 'new' name into the hash
- Setattr(shadow_classes,name,GetChar(shadow_classes,DataType_Getname(t)));
- }
-}
+ Clear(shadow_classdef);
+ Clear(shadow_code);
-void JAVA::cpp_open_class(char *classname, char *rename, char *ctype, int strip) {
+ have_default_constructor_flag = false;
+ destructor_call = NewString("");
+ shadow_constants_code = NewString("");
+ }
+ Language::classHandler(n);
- this->Language::cpp_open_class(classname,rename,ctype,strip);
+ if (proxy_flag) {
- if(!shadow) return;
+ emitShadowClassDefAndCPPCasts(n);
- if(rename)
- shadow_classname = Swig_copy_string(rename);
- else shadow_classname = Swig_copy_string(classname);
+ Printv(f_shadow, shadow_classdef, shadow_code, NIL);
- if (strcmp(shadow_classname, module) == 0) {
- Printf(stderr, "class name cannot be equal to module name: %s\n", shadow_classname);
- SWIG_exit(1);
- }
+ // Write out all the enums and constants
+ if (Len(shadow_constants_code) != 0 )
+ Printv(f_shadow, " // enums and constants\n", shadow_constants_code, NIL);
- Setattr(shadow_classes,classname, shadow_classname);
- if(ctype && strcmp(ctype, "struct") == 0) {
- sprintf(bigbuf, "struct %s", classname);
- Setattr(shadow_classes, bigbuf, shadow_classname);
- }
+ Printf(f_shadow, "}\n");
+ Close(f_shadow);
+ f_shadow = NULL;
- sprintf(bigbuf, "%s.java", shadow_classname);
- if(!(f_shadow = fopen(bigbuf, "w"))) {
- Printf(stderr, "Unable to create shadow class file: %s\n", bigbuf);
+ Delete(shadow_classname); shadow_classname = NULL;
+ Delete(destructor_call); destructor_call = NULL;
+ Delete(shadow_constants_code); shadow_constants_code = NULL;
+ }
+ return SWIG_OK;
}
- emit_shadow_banner(f_shadow);
+ /* ----------------------------------------------------------------------
+ * memberfunctionHandler()
+ * ---------------------------------------------------------------------- */
- if(*package)
- Printf(f_shadow, "package %s;\n\n", package);
- else Printf(f_shadow, "import %s;\n\n", module);
- if(jimport != NULL)
- Printf(f_shadow, "import %s;\n\n", jimport);
+ virtual int memberfunctionHandler(Node *n) {
+ Language::memberfunctionHandler(n);
- Clear(shadow_classdef);
- Printv(shadow_classdef, "public class ", shadow_classname, " %BASECLASS% ", "{\n", 0);
+ 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;
+ }
- shadow_baseclass = (char*) "";
- shadow_classdef_emitted = 0;
- have_default_constructor = 0;
-}
+ /* ----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ---------------------------------------------------------------------- */
-void JAVA::emit_shadow_classdef() {
- if(*shadow_baseclass) {
- sprintf(bigbuf, "extends %s", shadow_baseclass);
- Replace(shadow_classdef,"%BASECLASS%", bigbuf, DOH_REPLACE_ANY);
- Printv(shadow_classdef, " public ", shadow_classname, "(java.lang.Long obj) {\n", tab4, "_self = obj.longValue();\n }\n\n", 0);
- } else {
- Replace(shadow_classdef,"%BASECLASS%", "",DOH_REPLACE_ANY);
+ virtual int staticmemberfunctionHandler(Node *n) {
- Printv(shadow_classdef,
- " public long _self = 0;\n",
- " public boolean _selfown = false;\n\n",
- " public static Object newInstance(long p) {\n",
- " return new ", shadow_classname, "(new Long(p));\n",
- " };\n\n",
-
- " public ", shadow_classname, "(java.lang.Long obj) {\n", tab4, "_self = obj.longValue();\n }\n\n",
- 0);
+ 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;
}
- Printv(shadow_classdef, " public Class _selfClass() {\n", tab4, "return ", shadow_classname, ".class;\n", " };\n\n", 0);
- Printv(f_shadow, shadow_classdef,0);
- shadow_classdef_emitted = 1;
-}
+ /* -----------------------------------------------------------------------------
+ * 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));
+ }
-void JAVA::cpp_close_class() {
- this->Language::cpp_close_class();
- if(!shadow) return;
+ /* 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);
- if(!shadow_classdef_emitted) emit_shadow_classdef();
+ Printv(nativecall, jniclass_name, ".", java_function_name, "(", NIL);
+ if (!static_flag)
+ Printv(nativecall, "swigCPtr", NIL);
- if(have_default_constructor == 0) {
- Printf(f_shadow, " public %s() {}\n\n", shadow_classname);
- }
+ int gencomma = !static_flag;
- Printf(f_shadow, "}\n");
- fclose(f_shadow);
- f_shadow = NULL;
+ /* Output each parameter */
+ for (i = 0, p=l; p; i++) {
- free(shadow_classname);
- shadow_classname = NULL;
-}
+ /* Ignored parameters */
+ if (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ continue;
+ }
-void JAVA::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) {
- char arg[256];
- DOHString *nativecall;
+ /* Ignore the 'this' argument for variable wrappers */
+ if (!(variable_wrapper_flag && i==0))
+ {
+ SwigType *pt = Getattr(p,"type");
+ String *javaparamtype = NewString("");
- nativecall = 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));
+ }
- this->Language::cpp_member_func(name,iname,t,l);
+ if (gencomma)
+ Printf(nativecall, ", ");
- if(!shadow) return;
- if(!shadow_classdef_emitted) emit_shadow_classdef();
+ String *arg = makeParameterName(n, p, i);
- char *javarettype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, t, iname);
- if(!javarettype) javarettype = SwigTcToJavaType(t, 1, 0);
- char *shadowrettype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, t, iname);
- if(!shadowrettype && (DataType_Gettypecode(t) == T_USER) && DataType_is_pointer(t) <= 1) {
- shadowrettype = GetChar(shadow_classes,DataType_Getname(t));
- }
+ // 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));
+ }
- Printf(f_shadow, " public %s %s(", (shadowrettype) ? shadowrettype : javarettype, iname);
+ /* 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");
+ }
- if(DataType_type(t) != T_VOID) {
- Printf(nativecall,"return ");
- if(shadowrettype) {
- Printv(nativecall, "new ", shadowrettype, "(new Long(", 0);
+ 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);
}
- Printv(nativecall, module, ".", Swig_name_member(shadow_classname,iname), "(_self", 0);
- int pcount = ParmList_len(l);
+ /* ----------------------------------------------------------------------
+ * constructorHandler()
+ * ---------------------------------------------------------------------- */
- Parm *p = l;
- for (int i = 0; i < pcount ; i++, p = Getnext(p)) {
- DataType *pt = Gettype(p);
- char *pn = Getname(p);
+ virtual int constructorHandler(Node *n) {
- // Produce string representation of source and target arguments
- if(pn && *(pn))
- strcpy(arg,pn);
- else {
- sprintf(arg,"arg%d",i);
- }
+ ParmList *l = Getattr(n,"parms");
+ String *tm;
+ Parm *p;
+ int i;
+ String *user_arrays = NewString("");
- if((DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1) && Getattr(shadow_classes,DataType_Getname(pt))) {
- Printv(nativecall, ", ", arg, "._self", 0);
- } else Printv(nativecall, ", ", arg, 0);
+ Language::constructorHandler(n);
- char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn);
- if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0);
+ if(proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *nativecall = NewString("");
- char *jstype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, pt, pn);
- if(!jstype && (DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1)) {
- jstype = GetChar(shadow_classes,DataType_Getname(pt));
- }
+ Printf(shadow_code, " %s %s(", Getattr(n,"feature:java:methodmodifiers"), shadow_classname);
+ Printv(nativecall, "this(", jniclass_name, ".", Swig_name_construct(overloaded_name), "(", NIL);
- // Add to java function header
- Printf(f_shadow, "%s %s", (jstype) ? jstype : jtype, arg);
- if(i != pcount-1) {
- Printf(f_shadow, ", ");
- }
- }
+ /* 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);
- if((DataType_Gettypecode(t) != T_VOID) && shadowrettype)
- Printf(nativecall, "))");
+ int gencomma = 0;
- Printf(nativecall,");\n");
+ /* Output each parameter */
+ for (i = 0, p=l; p; i++) {
- Printf(f_shadow, ") {\n");
- Printf(f_shadow, "\t%s\n", nativecall);
- Printf(f_shadow, " }\n\n");
- Delete(nativecall);
+ /* Ignored parameters */
+ if (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ continue;
+ }
-}
+ SwigType *pt = Getattr(p,"type");
+ String *javaparamtype = NewString("");
-void JAVA::cpp_static_func(char *name, char *iname, DataType *t, ParmList *l) {
- char arg[256];
- DOHString *nativecall;
+ /* 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));
+ }
- this->Language::cpp_static_func(name,iname,t,l);
+ if (gencomma)
+ Printf(nativecall, ", ");
- if(!shadow) return;
- nativecall = NewString("");
- if(!shadow_classdef_emitted) emit_shadow_classdef();
+ String *arg = makeParameterName(n, p, i);
- char *javarettype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, t, iname);
- if(!javarettype) javarettype = SwigTcToJavaType(t, 1, 0);
- char *shadowrettype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, t, iname);
- if(!shadowrettype && (DataType_Gettypecode(t) == T_USER) && (DataType_is_pointer(t) <= 1)) {
- shadowrettype = GetChar(shadow_classes,DataType_Getname(t));
- }
+ // 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));
+ }
- Printf(f_shadow, " public static %s %s(", (shadowrettype) ? shadowrettype : javarettype, iname);
+ /* Add to java shadow function header */
+ if(gencomma)
+ Printf(shadow_code, ", ");
+ Printf(shadow_code, "%s %s", javaparamtype, arg);
+ gencomma = 1;
- if(DataType_type(t) != T_VOID) {
- Printf(nativecall, "return ");
- if(shadowrettype) {
- Printv(nativecall, "new ", shadowrettype, "(new Long(", 0);
- }
- }
- Printv(nativecall, module, ".", Swig_name_member(shadow_classname,iname), "(", 0);
+ Delete(arg);
+ Delete(javaparamtype);
+ p = Getattr(p,"tmap:in:next");
+ }
+
+ Printf(nativecall, "), true);\n");
- int pcount = ParmList_len(l);
- int gencomma = 0;
+ 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");
- Parm *p = l;
- for (int i = 0; i < pcount ; i++, p = Getnext(p)) {
- DataType *pt = Gettype(p);
- char *pn = Getname(p);
+ if(!gencomma) // We must have a default constructor
+ have_default_constructor_flag = true;
- // Produce string representation of source and target arguments
- if(pn && *(pn))
- strcpy(arg,pn);
- else {
- sprintf(arg,"arg%d",i);
+ Delete(overloaded_name);
+ Delete(nativecall);
}
- if(gencomma) Printf(nativecall,", ");
+ Delete(user_arrays);
- if((DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1) && Getattr(shadow_classes,DataType_Getname(pt))) {
- Printv(nativecall, arg, "._self", 0);
- } else Printv(nativecall,arg,0);
+ return SWIG_OK;
+ }
- gencomma = 1;
+ /* ----------------------------------------------------------------------
+ * destructorHandler()
+ * ---------------------------------------------------------------------- */
- char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn);
- if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0);
+ virtual int destructorHandler(Node *n) {
+ Language::destructorHandler(n);
+ String *symname = Getattr(n,"sym:name");
- char *jstype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, pt, pn);
- if(!jstype && (DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1)) {
- jstype = GetChar(shadow_classes, DataType_Getname(pt));
+ if(proxy_flag) {
+ Printv(destructor_call, " ", jniclass_name, ".", Swig_name_destroy(symname), "(swigCPtr);\n", NIL);
}
+ return SWIG_OK;
+ }
- // Add to java function header
- Printf(f_shadow, "%s %s", (jstype) ? jstype : jtype, arg);
- if(i != pcount-1) {
- Printf(f_shadow, ", ");
- }
+ /* ----------------------------------------------------------------------
+ * 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;
+ }
- if((DataType_type(t) != T_VOID) && shadowrettype)
- Printf(nativecall,"))");
+ /* ----------------------------------------------------------------------
+ * memberconstantHandler()
+ * ---------------------------------------------------------------------- */
- Printf(nativecall,");\n");
+ 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;
+ }
- Printf(f_shadow, ") {\n");
- Printf(f_shadow, "\t%s\n", nativecall);
- Printf(f_shadow, " }\n\n");
- Delete(nativecall);
-}
+ /* -----------------------------------------------------------------------------
+ * getOverloadedName()
+ * ----------------------------------------------------------------------------- */
-void JAVA::cpp_constructor(char *name, char *iname, ParmList *l) {
- this->Language::cpp_constructor(name,iname,l);
+ String *getOverloadedName(Node *n) {
- if(!shadow) return;
- if(!shadow_classdef_emitted) emit_shadow_classdef();
+ /* 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"));
- DOHString *nativecall = NewString("");
- char arg[256];
+ if (Getattr(n,"sym:overloaded")) {
+ Printv(overloaded_name, Getattr(n,"sym:overname"), NIL);
+ }
- Printf(f_shadow, " public %s(", shadow_classname);
+ return overloaded_name;
+ }
- Printv(nativecall, " if(_self == 0 && ", shadow_classname, ".class == _selfClass()) {\n", 0);
- if (iname != NULL)
- Printv(nativecall, tab8, " _self = ", module, ".", Swig_name_construct(iname), "(", 0);
- else
- Printv(nativecall, tab8, " _self = ", module, ".", Swig_name_construct(shadow_classname), "(", 0);
+ /* -----------------------------------------------------------------------------
+ * 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);
+ }
+ }
- int pcount = ParmList_len(l);
- if(pcount == 0) // We must have a default constructor
- have_default_constructor = 1;
+ /* Attach the non-standard typemaps to the parameter list */
+ Swig_typemap_attach_parms("jstype", l, NULL);
+ Swig_typemap_attach_parms("javain", l, NULL);
- Parm *p = l;
- for (int i = 0; i < pcount ; i++, p = Getnext(p)) {
- DataType *pt = Gettype(p);
- char *pn = Getname(p);
+ /* 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));
+ }
- // Produce string representation of source and target arguments
- if(pn && *(pn))
- strcpy(arg,pn);
- else {
- sprintf(arg,"arg%d",i);
+ /* 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"));
}
- char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn);
- if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0);
+ /* 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);
- char *jstype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, pt, pn);
- if(!jstype && (DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1)) {
- jstype = GetChar(shadow_classes, DataType_Getname(pt));
- }
+ /* Get number of required and total arguments */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
- // Add to java function header
- Printf(f_shadow, "%s %s", (jstype) ? jstype : jtype, arg);
+ int gencomma = 0;
- if((DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1) && Getattr(shadow_classes,DataType_Getname(pt))) {
- Printv(nativecall,arg, "._self", 0);
- } else Printv(nativecall, arg, 0);
+ /* Output each parameter */
+ for (i = 0, p=l; i < num_arguments; i++) {
- if(i != pcount-1) {
- Printf(nativecall, ", ");
- Printf(f_shadow, ", ");
- }
- }
+ /* Ignored parameters */
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
+ SwigType *pt = Getattr(p,"type");
+ String *javaparamtype = NewString("");
- Printf(f_shadow, ") {\n");
- Printv(nativecall,
- ");\n",
- tab8, " _selfown = true;\n",
- " }\n",
- 0);
+ /* 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));
+ }
- Printf(f_shadow, "%s", nativecall);
- Printf(f_shadow, " }\n\n");
- Delete(nativecall);
-}
+ if (gencomma)
+ Printf(nativecall, ", ");
-void JAVA::cpp_destructor(char *name, char *newname) {
- this->Language::cpp_destructor(name,newname);
+ String *arg = makeParameterName(n, p, i);
- if(!shadow) return;
- if(!shadow_classdef_emitted) emit_shadow_classdef();
+ // 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));
+ }
- char *realname = (newname) ? newname : name;
+ /* Add to java shadow function header */
+ if (gencomma >= 2)
+ Printf(module_class_code, ", ");
+ gencomma = 2;
+ Printf(module_class_code, "%s %s", javaparamtype, arg);
- if(finalize) {
- Printf(f_shadow, " protected void finalize() {\n");
- Printf(f_shadow, " if(_selfown) {\n");
- Printf(f_shadow, " _delete();\n");
- Printf(f_shadow, " }\n");
- Printf(f_shadow, " };\n\n");
+ 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);
}
- Printf(f_shadow, " public void _delete() {\n");
- Printf(f_shadow, " if(_self != 0 && %s.class == _selfClass()) {\n", shadow_classname);
- Printf(f_shadow, "\t%s.%s(_self);\n", module, Swig_name_destroy(realname));
- Printf(f_shadow, "\t_self = 0;\n");
- Printf(f_shadow, " }\n");
- Printf(f_shadow, " }\n\n");
-}
+ /* -----------------------------------------------------------------------------
+ * 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);
+ }
-void JAVA::cpp_class_decl(char *name, char *rename, char *type) {
- this->Language::cpp_class_decl(name,rename, type);
+ // 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;
+ }
- if(!shadow) return;
+ /* -----------------------------------------------------------------------------
+ * 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"));
- char *realname = (rename) ? rename : name;
+ return arg;
+ }
- Setattr(shadow_classes,name, realname);
- if(type && strcmp(type, "struct") == 0) {
- sprintf(bigbuf, "struct %s", name);
- Setattr(shadow_classes, bigbuf, rename);
+ /* -----------------------------------------------------------------------------
+ * 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);
}
-}
-void JAVA::cpp_inherit(char **baseclass, int) {
- this->Language::cpp_inherit(baseclass, 0);
+ /* -----------------------------------------------------------------------------
+ * javaTypemapLookup()
+ * ----------------------------------------------------------------------------- */
- if(!shadow) return;
+ const String *javaTypemapLookup(const String *op, String *type, int warning) {
+ String *tm = NULL;
+ const String *code = NULL;
- int cnt = 0;
- char **bc = baseclass;
- while(*bc++) cnt++;
+ if((tm = Swig_typemap_search(op, type, NULL, NULL))) {
+ code = Getattr(tm,"code");
+ }
- if(cnt > 1)
- Printf(stderr, "Warning: %s inherits from multiple base classes. Multiple inheritance is not supported.\n", shadow_classname);
+ 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);
+ }
- shadow_baseclass = Swig_copy_string(*baseclass);
-}
+ return code ? code : empty_string;
+ }
-void JAVA::cpp_variable(char *name, char *iname, DataType *t) {
- if(shadow && !shadow_classdef_emitted) emit_shadow_classdef();
+ /* -----------------------------------------------------------------------------
+ * addThrows()
+ * ----------------------------------------------------------------------------- */
- if(shadow) member_func = 1;
- shadow_name = Swig_copy_string((iname) ? iname : name);
- this->Language::cpp_variable(name, iname, t);
- member_func = 0;
-}
+ 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);
-void JAVA::cpp_static_var(char *name, char *iname, DataType *t) {
- if(shadow) member_func = 1;
- shadow_name = Swig_copy_string((iname) ? iname : name);
- this->Language::cpp_static_var(name, iname, t);
- member_func = 0;
-}
+ if (throws) {
+ String *throws_list = Getattr(n,"java:throwslist");
+ if (!throws_list) {
+ throws_list = NewList();
+ Setattr(n,"java:throwslist", throws_list);
+ }
-void JAVA::cpp_declare_const(char *name, char *iname, DataType *type, char *value) {
- if(shadow && !shadow_classdef_emitted) emit_shadow_classdef();
+ // 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);
+ }
+ }
- if(shadow) member_func = 1;
- shadow_name = Swig_copy_string((iname) ? iname : name);
- this->Language::cpp_declare_const(name, iname, type, value);
- member_func = 0;
+}; /* 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 <name> - set name of the Java package\n\
+ -noproxy - Generate the low-level functional interface instead of proxy classes\n";
diff --git a/Source/Modules1.1/java.h b/Source/Modules1.1/java.h
deleted file mode 100644
index 6c86b452e..000000000
--- a/Source/Modules1.1/java.h
+++ /dev/null
@@ -1,49 +0,0 @@
-
-// ------------------------------------------------------------------------
-// A Java SWIG Language module
-//
-// ------------------------------------------------------------------------
-
-class JAVA : public Language {
-public :
-
- // Virtual functions required by the SWIG parser
-
- void parse_args(int, char *argv[]);
- void parse();
- void add_native(char *, char *, SwigType *, ParmList *);
- void create_function(char *, char *, SwigType *, ParmList *);
- void link_variable(char *, char *, SwigType *);
- void declare_const(char *, char *, SwigType *, char *);
- void initialize(void);
- void headers(void);
- void close(void);
- void set_module(char *,char **);
- void create_command(char *, char *);
-
- void pragma(char *lang, char *code, char *value);
- void add_typedef(SwigType *t, char *name);
- void cpp_open_class(char *classname, char *rename, char *ctype, int strip);
- void cpp_close_class();
- void cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l);
- void cpp_static_func(char *name, char *iname, SwigType *t, ParmList *l);
- void cpp_constructor(char *name, char *iname, ParmList *l);
- void cpp_destructor(char *name, char *newname);
- void cpp_class_decl(char *name, char *rename, char *type);
- void cpp_inherit(char **baseclass, int);
- void cpp_variable(char *name, char *iname, SwigType *t);
- void cpp_static_var(char *, char *, SwigType *);
- void cpp_declare_const(char *name, char *iname, SwigType *type, char *value);
-
- /* Java Module methods */
- void emit_classdef();
- void emit_shadow_classdef();
- char *JNICALL(DOHString_or_char *func);
- char *SwigTcToJniType(SwigType *t, int ret);
- char *SwigTcToJavaType(SwigType *t, int ret, int inShadow);
- char *SwigTcToJniScalarType(SwigType *t);
- char *JavaTypeFromTypemap(char *op, char *lang, SwigType *t, char *pname);
- char *makeValidJniName(char *name);
- char *JavaMethodSignature(SwigType *t, int ret, int inShadow);
- void writeRegisterNatives();
-};
diff --git a/Source/Modules1.1/lang.cxx b/Source/Modules1.1/lang.cxx
index faf69918f..4245b7193 100644
--- a/Source/Modules1.1/lang.cxx
+++ b/Source/Modules1.1/lang.cxx
@@ -12,464 +12,1842 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_lang_cxx[] = "$Header$";
-#include "swig11.h"
+#include "swigmod.h"
+#include <ctype.h>
-/* -----------------------------------------------------------------
- * Language::create_command()
- * ----------------------------------------------------------------- */
+/* Some status variables used during parsing */
-void Language::create_command(String *, String *) {
- Printf(stderr,"SWIG Warning. No command creation procedure defined.\n");
- Printf(stderr,"C++ inheritance may not work correctly.\n");
+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;
}
-/* -----------------------------------------------------------------
- * Language::nativefunction()
- * ----------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ * Dispatcher::emit_children()
+ *
+ * Emit all children.
+ * ---------------------------------------------------------------------- */
-void
-Language::nativefunction(DOH *node) {
- Printf(stderr,"%s:%d. Adding native function %s not supported (ignored).\n", Getfile(node), Getline(node), Getattr(node,"scriptname"));
+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;
+}
-/* The following strings are used during code generation and contain various
- permutations of the class name:
+Language::~Language() {
+ Delete(symbols);
+ Delete(classtypes);
+}
- ClassName - This is the name of the class as it appears in C/C++
- source code. It does not include a type specifier
- such as "struct" or "class"
+/* ----------------------------------------------------------------------
+ emit_one()
+ ---------------------------------------------------------------------- */
- ClassRename - If non-NULL, the class has been renamed.
- ClassType - The type of the class (struct, class, union)
- ClassFullname - The full name of the class including its type specifier.
- For example, "class Foo" or "struct Vector".
- ClassPrefix - The class prefix as used in the scripting language
- interface. This is either ClassName or ClassRename.
-*/
+int Language::emit_one(Node *n) {
+ int ret;
+ int oldext;
+ if (!n) return SWIG_OK;
-static String *ClassName = 0;
-static String *ClassRename = 0;
-static String *ClassType = 0;
-static String *ClassFullname = 0;
-static String *ClassPrefix = 0;
+ if (Getattr(n,"feature:ignore")) return SWIG_OK;
-/* -----------------------------------------------------------------------------
- * Language::cpp_open_class()
- * ----------------------------------------------------------------------------- */
+ oldext = Extend;
+ if (Getattr(n,"feature:extend")) Extend = 1;
+
+ line_number = Getline(n);
+ input_file = Char(Getfile(n));
-void Language::cpp_open_class(DOH *node) {
- String *classname;
- String *classrename;
- String *ctype;
- String *altname;
- int strip = CPlusPlus;
+ /*
+ 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;
+}
- classname = Getname(node);
- classrename = Getattr(node,"scriptname");
- ctype = Getattr(node,"classtype");
- altname = Getattr(node,"altname");
- if (altname) {
- strip = 1;
- classname = altname; /* Use the alt name instead of the class name */
+static Parm *nonvoid_parms(Parm *p) {
+ if (p) {
+ SwigType *t = Getattr(p,"type");
+ if (SwigType_type(t) == T_VOID) return 0;
}
+ return p;
+}
- if (strip) SetInt(node,"strip",1);
+/* 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;
+}
- /* Copy the class name */
- if (ClassName) Delete(ClassName);
- ClassName = NewString(classname);
+/* 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);
+ }
+}
- /* Copy the class renaming */
+static Node *first_nontemplate(Node *n) {
+ while (n) {
+ if (Strcmp(nodeType(n),"template") != 0) return n;
+ n = Getattr(n,"sym:nextSibling");
+ }
+ return n;
+}
- if (ClassRename) Delete(ClassRename);
- ClassRename = NewString(classrename);
+/* --------------------------------------------------------------------------
+ * 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()
+ * ---------------------------------------------------------------------- */
- if (ClassType) Delete(ClassType);
- ClassType = strip ? 0 : NewString(ctype);
+int Language::extendDirective(Node *n) {
+ int oldam = Extend;
+ int oldmode = cplus_mode;
+ Extend = CWRAP_EXTEND;
+ cplus_mode = CPLUS_PUBLIC;
- if (ClassFullname) Delete(ClassFullname);
+ emit_children(n);
- ClassFullname = ClassType ? NewStringf("%s %s", ClassType, ClassName) : NewString(ClassName);
- ClassPrefix = ClassRename;
+ Extend = oldam;
+ cplus_mode = oldmode;
+ return SWIG_OK;
}
-/* -----------------------------------------------------------------------------
- * Language::cpp_close_class()
- * ----------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ * Language::applyDirective()
+ * ---------------------------------------------------------------------- */
-void Language::cpp_close_class() {
+int Language::applyDirective(Node *n) {
- /* Doesn't really do anything */
+ 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::cpp_memberfunction()
- * ----------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ * 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;
+}
-void Language::cpp_memberfunction(DOH *node) {
- String *name;
- String *iname;
- String *ccode;
- String *script_name;
- SwigType *type;
- ParmList *parms;
- Wrapper *w;
+/* ----------------------------------------------------------------------
+ * Language::fragmentDirective()
+ * ---------------------------------------------------------------------- */
- name = Getattr(node,"name");
- iname = Getattr(node,"scriptname");
- type = Getattr(node,"type");
- parms = Getattr(node,"parms");
- ccode = Getattr(node,"code");
+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;
+}
- /* Generate the C wrapper function name and interpreter name of this function*/
- /* Create the actual function name */
+/* ----------------------------------------------------------------------
+ * Language::importDirective()
+ * ---------------------------------------------------------------------- */
- script_name = Swig_name_member(ClassPrefix, iname ? iname : name);
+int Language::importDirective(Node *n) {
+ int oldim = ImportMode;
+ ImportMode = IMPORT_MODE;
+ emit_children(n);
+ ImportMode = oldim;
+ return SWIG_OK;
+}
- /* Now do a symbol table lookup on it */
+/* ----------------------------------------------------------------------
+ * Language::includeDirective()
+ * ---------------------------------------------------------------------- */
- /* Create the C wrapper function for this */
- w = Swig_cmethod_wrapper(ClassFullname, name, type, parms, ccode);
- if (AddMethods && ccode) {
- /* Dump the C wrappers */
- Printf(f_wrappers,"%s",w);
- } else if (!AddMethods) {
- /* Just create a string that does what we want */
- emit_set_action(Swig_cmethod_call(name, Getparms(w)));
+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;
}
- Setattr(w,"scriptname",script_name);
- lang->function(w);
- Delete(w);
}
-/* -----------------------------------------------------------------------------
- * Language::cpp_constructor()
- * ----------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ * Language::moduleDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::moduleDirective(Node *n) {
+ /* %module directive */
+ return SWIG_OK;
+}
-void Language::cpp_constructor(DOH *node) {
- String *name;
- String *iname;
- String *cname;
- String *ccode;
- ParmList *parms;
- Wrapper *w;
+/* ----------------------------------------------------------------------
+ * Language::nativeDirective()
+ * ---------------------------------------------------------------------- */
- name = Getattr(node,"name");
- iname = Getattr(node,"scriptname");
- parms = Getattr(node,"parms");
- ccode = Getattr(node,"code");
+int Language::nativeDirective(Node *n) {
+ if (!ImportMode) {
+ return nativeWrapper(n);
+ } else {
+ return SWIG_NOWRAP;
+ }
+}
- if ((Cmp(name,ClassName))) {
- Printf(stderr,"%s:%d. Function %s must have a return type.\n",
- Getfile(node), Getline(node), name);
- return;
+/* ----------------------------------------------------------------------
+ * 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;
}
-
- cname = Swig_name_construct(iname ? iname : ClassPrefix);
+ return SWIG_OK;
+}
- /* Add this function to the SWIG symbol table */
+/* ----------------------------------------------------------------------
+ * 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);
+ }
- if (CPlusPlus) {
- w = Swig_cppconstructor_wrapper(ClassFullname, parms, ccode);
+ 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 {
- w = Swig_cconstructor_wrapper(ClassFullname, parms, ccode);
+ /* 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;
}
- Setattr(w,"scriptname", cname);
+}
+
+/* ----------------------------------------------------------------------
+ * 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()
+ * ---------------------------------------------------------------------- */
- if (!AddMethods) {
- if (CPlusPlus) {
- emit_set_action(Swig_cppconstructor_call(ClassFullname, parms));
+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 {
- emit_set_action(Swig_cconstructor_call(ClassFullname));
+ IsVirtual = PLAIN_VIRTUAL;
}
} else {
- if (ccode) {
- Printf(f_wrappers,"%s",w);
+ 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;
}
}
- lang->function(w);
- Delete(w);
- /* Call our default method */
- /* cplus_emit_constructor(Char(ClassName), Char(ClassType), Char(ClassRename), name, iname, l, AddMethods); */
+ 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::cpp_destructor()
- * ----------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ * Language::staticmemberfunctionHandler()
+ * ---------------------------------------------------------------------- */
-void Language::cpp_destructor(DOH *node) {
- String *name;
- String *iname;
- String *cname;
- String *ccode;
- Wrapper *w;
+int
+Language::staticmemberfunctionHandler(Node *n) {
- name = Getattr(node,"name");
- iname = Getattr(node,"scriptname");
- cname = Swig_name_destroy(ClassRename ? ClassRename : ClassName);
- ccode = Getattr(node,"code");
+ 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;
- /* Add this function to the SWIG symbol table */
+ 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);
- if (CPlusPlus) {
- w = Swig_cppdestructor_wrapper(ClassFullname,ccode);
+ Delete(cname);
+ Delete(mrename);
+ Swig_restore(&n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::variableHandler()
+ * ---------------------------------------------------------------------- */
+
+int
+Language::variableHandler(Node *n) {
+ if (!CurrentClass) {
+ globalvariableHandler(n);
} else {
- w = Swig_cdestructor_wrapper(ClassFullname, ccode);
- }
- Setattr(w,"scriptname",cname);
- if (AddMethods && ccode) {
- Printf(f_wrappers,"%s", w);
- lang->function(w);
- } else if (AddMethods) {
- lang->function(w);
+ 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 {
- if (CPlusPlus)
- emit_set_action(Swig_cppdestructor_call());
- else
- emit_set_action(Swig_cdestructor_call());
- lang->function(w);
- }
- Delete(w);
+
+ /* 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::cpp_inherit()
+ * Language::memberconstantHandler()
* ----------------------------------------------------------------------------- */
-void Language::cpp_inherit(List *bases) {
+int Language::memberconstantHandler(Node *n) {
- if (!bases) return;
- /*
- while (baseclass[i]) {
- // cplus_inherit_members(baseclass[i],mode);
- i++;
- }
+ 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::cpp_variable()
+ * Language::namespaceDeclaration()
* ----------------------------------------------------------------------------- */
-void Language::cpp_variable(DOH *node) {
- String *name;
- String *iname;
- String *cname;
- String *setcode, *getcode;
- SwigType *type;
- Wrapper *w;
-
- name = Getattr(node,"name");
- iname = Getattr(node,"scriptname");
- type = Getattr(node,"type");
- setcode = Getattr(node,"setcode");
- getcode = Getattr(node,"getcode");
-
- /* Set the class prefix */
-
- cname = Swig_name_get(Swig_name_member(ClassPrefix, iname ? iname : name));
-
- /* Check the symbol table */
-
- /* Create a function to set the value of the variable */
- if (!ReadOnly) {
- w = Swig_cmemberset_wrapper(ClassFullname, name, type, setcode);
- Setattr(w,"scriptname",Swig_name_set(Swig_name_member(ClassPrefix,iname ? iname : name)));
- if (AddMethods && setcode) {
- Printf(f_wrappers,"%s",w);
- } else if (!AddMethods) {
- /* Check for a member in typemap here */
- String *target = NewStringf("%s->%s", Swig_cparm_name(0,0),name);
- char *tm = Swig_typemap_lookup("memberin",type,name,Swig_cparm_name(0,1),target,0);
- if (!tm)
- emit_set_action(Swig_cmemberset_call(name,type));
- else
- emit_set_action(tm);
- Delete(target);
- }
- lang->function(w);
- Delete(w);
- }
- w = Swig_cmemberget_wrapper(ClassFullname, name, type, getcode);
- Setattr(w,"scriptname", Swig_name_get(Swig_name_member(ClassPrefix, iname ? iname : name)));
- if (AddMethods && getcode) {
- Printf(f_wrappers,"%s",w);
- } else if (!AddMethods) {
- emit_set_action(Swig_cmemberget_call(name,type));
- }
- lang->function(w);
- Delete(w);
+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::cpp_static_func()
+ * Language::usingDeclaration()
* ----------------------------------------------------------------------------- */
-void Language::cpp_staticfunction(DOH *node) {
- String *name;
- String *iname;
- SwigType *type;
- ParmList *parms;
- String *ccode;
- String *script_name;
- String *real_name;
- DOH *nnode;
- Wrapper *w;
-
- name = Getattr(node,"name");
- iname = Getattr(node,"scriptname");
- type = Getattr(node,"type");
- parms = Getattr(node,"parms");
- ccode = Getattr(node,"code");
-
- /* Set the member function name */
- script_name = Swig_name_member(ClassPrefix,iname ? iname : name);
-
- /* Now do a symbol table lookup on it : */
-
- /* Figure out the name of the function */
- if (AddMethods) {
- real_name = Swig_name_member(ClassName, name);
- if (!ccode) {
- nnode = Copy(node);
- Setattr(nnode,"name", real_name);
- Setattr(nnode,"scriptname", script_name);
- lang->function(nnode);
- Delete(nnode);
- } else {
- w = Swig_cfunction_wrapper(real_name,type,parms,ccode);
- Printf(f_wrappers,"%s",w);
- Setattr(w,"scriptname",script_name);
- lang->function(w);
- Delete(w);
+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);
}
- } else {
- nnode = Copy(node);
- real_name = NewStringf("%s::%s", ClassName, name);
- Setattr(nnode,"name", real_name);
- Setattr(nnode,"scriptname", script_name);
- lang->function(nnode);
- Delete(nnode);
- Delete(real_name);
+ 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::cpp_constant()
- * ----------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ * Language::functionWrapper()
+ * ---------------------------------------------------------------------- */
-void Language::cpp_constant(DOH *node)
-{
- String *name;
- String *iname;
- String *value;
- SwigType *type;
- String *cname;
- String *mname;
- String *new_value;
+int Language::functionWrapper(Node *n) {
+ String *name = Getattr(n,"sym:name");
+ SwigType *type = Getattr(n,"type");
+ ParmList *parms = Getattr(n,"parms");
- name = Getattr(node,"name");
- iname = Getattr(node,"scriptname");
- value = Getattr(node,"value");
- type = Getattr(node,"type");
+ 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;
+}
- /* Set the constant name */
+/* -----------------------------------------------------------------------------
+ * Language::nativeWrapper()
+ * ----------------------------------------------------------------------------- */
- cname = Swig_name_member(ClassPrefix, iname ? iname : name);
+int Language::nativeWrapper(Node *n) {
+ return SWIG_OK;
+}
- /* Now do a symbol table lookup on it : */
+void Language::main(int argc, char *argv[]) {
+}
- /* Form correct C++ name */
- mname = NewStringf("%s::%s", ClassName,name);
+/* -----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------- */
- /* Declare a constant */
- if (!value) {
- new_value = NewStringf("%s::%s", ClassName, name);
- } else {
- new_value = NewString(value);
+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;
}
- Hash *n;
- n = NewHash();
- Setattr(n,"name",cname);
- Setattr(n,"scriptname",cname);
- Setattr(n,"type",type);
- Setattr(n,"value",new_value);
- lang->constant(n);
- Delete(n);
- Delete(new_value);
- Delete(mname);
+ Setattr(symbols,s,n);
+ return 1;
}
/* -----------------------------------------------------------------------------
- * Language::cpp_staticvariable()
+ * Language::symbolLookup()
* ----------------------------------------------------------------------------- */
-void Language::cpp_staticvariable(DOH *node) {
- char *name, *iname;
- SwigType *t;
- char *cname;
- char mname[256];
+Node *
+Language::symbolLookup(String *s) {
+ return Getattr(symbols,s);
+}
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
+/* -----------------------------------------------------------------------------
+ * Language::classLookup()
+ *
+ * Tries to locate a class from a type definition
+ * ----------------------------------------------------------------------------- */
- /* Create the variable name */
+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);
- cname = Char(Swig_name_member(ClassPrefix, iname ? iname : name));
+ if (n && (Getattr(n,"feature:ignore"))) return 0;
+ return n;
+}
- /* Now do a symbol table lookup on it : */
+/* -----------------------------------------------------------------------------
+ * Language::allow_overloading()
+ * ----------------------------------------------------------------------------- */
- /* Form correct C++ name */
- sprintf(mname,"%s::%s",Char(ClassName),name);
+void Language::allow_overloading(int val) {
+ overloading = val;
+}
- /* Link with this variable */
+/* -----------------------------------------------------------------------------
+ * Language::allow_multiple_input()
+ * ----------------------------------------------------------------------------- */
- Hash *n = NewHash();
- Setattr(n,"name",mname);
- Setattr(n,"scriptname", cname);
- Setattr(n,"type",t);
- lang->variable(n);
- Delete(n);
+void Language::allow_multiple_input(int val) {
+ multiinput = val;
}
/* -----------------------------------------------------------------------------
- * Language::cpp_class_decl()
+ * Language::is_wrapping_class()
* ----------------------------------------------------------------------------- */
-void Language::cpp_class_decl(DOH *) {
- /* Does nothing by default */
+int Language::is_wrapping_class() {
+ return InClass;
}
/* -----------------------------------------------------------------------------
- * Language::add_typedef()
+ * Language::getCurrentClass()
* ----------------------------------------------------------------------------- */
-void Language::add_typedef(SwigType *, String *) {
- /* Does nothing by default */
+Node * Language::getCurrentClass() const {
+ return CurrentClass;
}
/* -----------------------------------------------------------------------------
- * Language::pragma()
+ * Language::getClassName()
* ----------------------------------------------------------------------------- */
-void Language::pragma(DOH *node) {
- /* Does nothing by default */
+String * Language::getClassName() const {
+ return ClassName;
}
/* -----------------------------------------------------------------------------
- * Language::import()
+ * Language::getClassPrefix()
* ----------------------------------------------------------------------------- */
-void Language::import(String *) {
- /* Does nothing by default */
+String * Language::getClassPrefix() const {
+ return ClassPrefix;
}
+/* -----------------------------------------------------------------------------
+ * Language::getClassType()
+ * ----------------------------------------------------------------------------- */
-
+String * Language::getClassType() const {
+ return ClassType;
+}
diff --git a/Source/Modules1.1/main.cxx b/Source/Modules1.1/main.cxx
index c3e221f61..2cbdbec66 100644
--- a/Source/Modules1.1/main.cxx
+++ b/Source/Modules1.1/main.cxx
@@ -12,54 +12,77 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_main_cxx[] = "$Header$";
-#include "swig11.h"
+#if defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#include "swigmod.h"
#ifndef MACSWIG
#include "swigconfig.h"
#endif
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
+#include "swigwarn.h"
+
extern "C" {
#include "preprocessor.h"
}
-#ifndef SWIG_LANG
-#define SWIG_LANG PYTHON
+#include <ctype.h>
+
+#ifndef SWIG_LIB
+#define SWIG_LIB "/usr/local/lib/swig1.3"
#endif
-#include "tcl8.h"
-#include "python.h"
-#include "perl5.h"
-#include "guile.h"
-#ifdef OLD
-#include "java.h"
+#ifndef SWIG_CC
+#define SWIG_CC "CC"
#endif
-#include "mzscheme.h"
-#include "ruby.h"
-#include "xml.h"
// Global variables
- FILE *f_runtime = 0;
- DOH *f_header = 0; // Some commonly used
- DOH *f_wrappers = 0; // FILE pointers
- DOH *f_init = 0;
+ char LibDir[512]; // Library directory
Language *lang; // Language method
int CPlusPlus = 0;
- int NewObject = 0; // NewObject flag
+ int Extend = 0; // Extend flag
int ForceExtern = 0; // Force extern mode
- int GenerateDefault = 0; // Generate default constructors
+ int GenerateDefault = 1; // Generate default constructors
+ char *Config = 0;
int NoInclude = 0;
int Verbose = 0;
- String *swig_module = 0;
+ int NoExtern = 0;
+ int NoExcept = 0;
+
+extern "C" {
+extern String *ModuleName;
+}
static char *usage = (char*)"\
-\nSWIG1.1 Options\n\
-";
+\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<dir> - Look for SWIG files in <dir>\n\
+ -includeall - Follow all #include statements\n\
+ -importall - Follow all #include statements as imports\n\
+ -ignoremissing - Ignore missing include files.\n\
+ -l<ifile> - 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)
@@ -67,18 +90,11 @@ static char *usage = (char*)"\
// Checks the suffix of a file to see if we should emit extern declarations.
// -----------------------------------------------------------------------------
-static
int
check_suffix(char *name) {
char *c;
if (!name) return 0;
- if (strlen(name) == 0) return 0;
- c = name+strlen(name)-1;
- while (c != name) {
- if (*c == '.') break;
- c--;
- }
- if (c == name) return 0;
+ c = Swig_file_suffix(name);
if ((strcmp(c,".c") == 0) ||
(strcmp(c,".C") == 0) ||
(strcmp(c,".cc") == 0) ||
@@ -90,208 +106,517 @@ check_suffix(char *name) {
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 infilename[256];
-char filename[256];
-char output_dir[512];
-char fn_runtime[256];
-static char *outfile_name = 0;
-
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);
+}
-extern "C"
-int swig11_init(int argc, char *argv[]) {
+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 infile[512];
+ 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);
- lang = new SWIG_LANG;
- f_wrappers = 0;
- f_init = 0;
- f_header = 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(strcmp(argv[i],"-tcl") == 0) {
- fprintf(stderr,"swig: -tcl option now implies -tcl8\n");
- lang = new TCL8;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-tcl8") == 0) {
- lang = new TCL8;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-python") == 0) {
- lang = new PYTHON;
- Swig_mark_arg(i);
-
- } else if (strcmp(argv[i],"-perl5") == 0) {
- lang = new PERL5;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-guile") == 0) {
- lang = new GUILE;
- Swig_mark_arg(i);
-#ifdef OLD
- } else if (strcmp(argv[i],"-java") == 0) {
- lang = new JAVA;
- Swig_mark_arg(i);
-#endif
- } else if (strcmp(argv[i],"-mzscheme") == 0) {
- lang = new MZSCHEME;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-ruby") == 0) {
- lang = new RUBY;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-help") == 0) {
- fputs(usage,stderr);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-c++") == 0) {
- CPlusPlus=1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-c") == 0) {
- NoInclude=1;
- Preprocessor_define((void *) "SWIG_NOINCLUDE 1", 0);
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-make_default") == 0) {
- GenerateDefault = 1;
- Swig_mark_arg(i);
- } else if(strcmp(argv[i],"-module") == 0) {
- if (argv[i+1]) {
- swig_module = NewString(argv[i+1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i+1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i],"-o") == 0) {
- if (argv[i+1]) {
- outfile_name = argv[i+1];
- Swig_mark_arg(i);
- Swig_mark_arg(i+1);
- i++;
- }
- } else if (strcmp(argv[i],"-help") == 0) {
- fputs(usage,stderr);
- Swig_mark_arg(i);
- help = 1;
+ 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->parse_args(argc,argv);
+ lang->main(argc,argv);
- if (help) return 0;
+ if (help) SWIG_exit (EXIT_SUCCESS); // Exit if we're in help mode
- // Create names of temporary files that are created
- sprintf(infilename,"%s", argv[argc-1]);
+ // Check all of the options to make sure we're cool.
+ Swig_check_options();
- // Check the suffix for a .c file. If so, we're going to
- // declare everything we see as "extern"
+ install_opts(argc, argv);
- ForceExtern = check_suffix(infilename);
- // Strip off suffix
+ // 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);
+ }
- c = infilename + strlen(infilename);
- while (c != infilename) {
- if (*c == '.') {
- *c = 0;
- break;
- } else {
- c--;
+ 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 (!outfile_name) {
- char *cc = infilename + strlen(infilename);
- while (cc != infilename) {
- if (*cc == '/') {
- cc++;
- break;
+
+ // 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);
+ }
}
- cc--;
}
- sprintf(fn_runtime,"%s_wrap.c",infilename);
- strcpy(infile,infilename);
- outfile_name = fn_runtime;
} else {
- sprintf(fn_runtime,"%s",outfile_name);
- }
- {
- // Try to identify the output directory
- char *cc = outfile_name;
- char *lastc = outfile_name;
- while (*cc) {
- if (*cc == '/') lastc = cc+1;
- cc++;
- }
- cc = outfile_name;
- char *dd = output_dir;
- while (cc != lastc) {
- *dd = *cc;
- dd++;
- cc++;
- }
- *dd = 0;
- // Patch up the input filename
- cc = infilename + strlen(infilename);
- while (cc != infilename) {
- if (*cc == '/') {
- cc++;
- break;
+ // 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);
}
- cc--;
+ Seek(cpps, 0, SEEK_SET);
}
- strcpy(infile,cc);
- }
- return 0;
-}
+ /* Register a null file with the file handler */
+ Swig_register_filebyname("null", NewString(""));
-extern void generate(DOH *top);
+ // Pass control over to the specific language interpreter
+ if (Verbose) {
+ fprintf (stdout, "Starting language-specific parse...\n");
+ fflush (stdout);
+ }
-extern "C"
-DOH *swig11_run(DOH *node) {
- if ((f_runtime = fopen(fn_runtime,"w")) == 0) {
- fprintf(stderr,"Unable to open %s\n", fn_runtime);
- Swig_exit(1);
- }
- f_header = NewString("");
- f_wrappers = NewString("");
- f_init = NewString("");
+ Node *top = Swig_cparse(cpps);
- Swig_register_filebyname("header",f_header);
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("wrapper", f_wrappers);
- Swig_register_filebyname("init", f_init);
+ if (Verbose) {
+ Printf(stdout,"Processing types...\n");
+ }
+ Swig_process_types(top);
- // Set up the typemap for handling new return strings
- if (CPlusPlus)
- Swig_typemap_register((char*)"newfree",(char*)"p.char",(char*)"",(char*)"delete [] $source;\n",0);
- else
- Swig_typemap_register((char*)"newfree",(char*)"p.char",(char*)"",(char*)"free($source);\n",0);
+ if (Verbose) {
+ Printf(stdout,"C++ analysis...\n");
+ }
+ Swig_default_allocators(top);
- generate(node);
+ 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);
+ }
+ }
+ }
- Dump(f_header,f_runtime);
- Dump(f_wrappers, f_runtime);
- Wrapper_pretty_print(f_init,f_runtime);
- fclose(f_runtime);
- return node;
+ 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();
}
-extern "C"
-void swig11module() {
- Swig_register_module("tcl8","swig:top", swig11_init, swig11_run);
- Swig_register_module("python","swig:top", swig11_init, swig11_run);
- Swig_register_module("perl5","swig:top", swig11_init, swig11_run);
- Swig_register_module("ruby","swig:top", swig11_init, swig11_run);
- Swig_register_module("guile","swig:top", swig11_init, swig11_run);
- Swig_register_module("mzscheme","swig:top", swig11_init, swig11_run);
- Swig_register_module("swig11","swig:top", swig11_init, swig11_run);
- Swig_register_module("xml","swig:top", xml_init, xml_run);
+// --------------------------------------------------------------------------
+// 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/Modules1.1/module.cxx b/Source/Modules1.1/module.cxx
new file mode 100644
index 000000000..57aa6c304
--- /dev/null
+++ b/Source/Modules1.1/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/Modules1.1/mzscheme.cxx b/Source/Modules1.1/mzscheme.cxx
index f3ac22096..14e4a3ac2 100644
--- a/Source/Modules1.1/mzscheme.cxx
+++ b/Source/Modules1.1/mzscheme.cxx
@@ -13,7 +13,7 @@
* can be used and distributed.
*****************************************************************************/
-static char cvsroot[] = "$Header$";
+char cvsroot_mzscheme_cxx[] = "$Header$";
/***********************************************************************
* $Header$
@@ -23,751 +23,646 @@ static char cvsroot[] = "$Header$";
* Definitions for adding functions to Mzscheme 101
***********************************************************************/
-#include "swig11.h"
-#include "mzscheme.h"
+#include "swigmod.h"
-static char *mzscheme_usage = (char*)"\
+#include <ctype.h>
+
+static const char *mzscheme_usage = (char*)"\
\n\
Mzscheme Options (available with -mzscheme)\n\
-help - Print this help\n\
--module name - Set base name of module (not implemented) \n\
--prefix name - Set a prefix to be appended to all name\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 char *module=0;
+static bool declaremodule = false;
+static String *module=0;
static char *mzscheme_path=(char*)"mzscheme";
static String *init_func_def = 0;
-// ---------------------------------------------------------------------
-// MZSCHEME::parse_args(int argc, char *argv[])
-//
-// Parse arguments.
-// ---------------------------------------------------------------------
-
-void
-MZSCHEME::parse_args (int argc, char *argv[])
-{
- int i;
-
- Swig_swiglib_set("mzscheme");
-
- // 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();
+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);
}
- }
- }
- }
-
- // 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 ((void *) "SWIGMZSCHEME",0);
-}
-
-// --------------------------------------------------------------------
-// MZSCHEME::initialize()
-//
-// Output initialization code that registers functions with the
-// interface.
-// ---------------------------------------------------------------------
-
-void
-MZSCHEME::initialize (String *modname)
-{
- init_func_def = NewString("");
- printf ("Generating wrappers for Mzscheme\n");
- init_func_def = NewString("");
-
- Swig_banner (f_header);
-
- Printf (f_header, "/* Implementation : MZSCHEME */\n\n");
- Printf (f_header, "#include <stdio.h>\n");
- Printf (f_header, "#include <string.h>\n");
- Printf (f_header, "#include <stdlib.h>\n");
-
- // insert mzscheme.swg
-
- if (!NoInclude) {
- if (Swig_insert_file ("mzscheme.swg", f_header) == -1) {
- Printf (stderr, "SWIG : Fatal error. ");
- Printf (stderr, "Unable to locate 'mzscheme.swg' in SWIG library.\n");
- Swig_exit (1);
- }
- }
-
- if (!module) {
- module = new char[Len(modname)+1];
- strcpy(module, Char(modname));
- }
-
- Printf (f_init, "static void\nSWIG_init (void)\n{\n");
-}
-
-// ---------------------------------------------------------------------
-// MZSCHEME::close(void)
-//
-// Wrap things up. Close initialization function.
-// ---------------------------------------------------------------------
-
-void
-MZSCHEME::close (void)
-{
- Printf (f_init, "}\n\n");
- Printf(f_init, "Scheme_Object *scheme_reload(Scheme_Env *env) {\n");
- Printf(f_init, "%s\n", Char(init_func_def));
- 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");
-}
-
-// ----------------------------------------------------------------------
-// MZSCHEME::get_pointer(int parm, SwigType *t, Wrapper *f)
-//
-// Emits code to get a pointer from a parameter and do type checking.
-// parm is the parameter number. This function is only used
-// in create_function().
-// ----------------------------------------------------------------------
-
-void
-MZSCHEME::get_pointer (String *name, int parm, SwigType *t, Wrapper *f)
-{
- char p[256];
- sprintf(p, "%d", parm);
- Printv(f, tab4, "if (!swig_get_c_pointer(argv[", p, "], \"", SwigType_manglestr(t),
- "\", (void **) &arg", p, "))\n",0);
- Printv(f, tab8, "scheme_wrong_type(\"", name,
- "\", \"", SwigType_manglestr(t), "\", ", p, ", argc, argv);\n",0);
-}
-// ----------------------------------------------------------------------
-// MZSCHEME::create_function()
-//
-// Create a function declaration and register it with the interpreter.
-// ----------------------------------------------------------------------
-
-static void
-mreplace (String *s, String *argnum, String *arg, String *proc_name)
-{
- Replace(s, "$argnum", argnum, DOH_REPLACE_ANY);
- Replace(s, "$arg", arg, DOH_REPLACE_ANY);
- Replace(s, "$name", proc_name, DOH_REPLACE_ANY);
-}
-
-static void
-throw_unhandled_mzscheme_type_error (SwigType *d)
-{
- fflush (stdout);
- fprintf (stderr, "ERROR: Unhandled MZSCHEME type error.\n");
- fprintf (stderr, "str: %s\n", Char(SwigType_str(d,0)));
- fprintf (stderr, "lstr: %s\n", Char(SwigType_lstr(d,0)));
- fprintf (stderr, "manglestr: %s\n", Char(SwigType_manglestr(d)));
- Printf (stderr, "\n\nBAILING...\n"); // for now -ttn
- abort(); // for now -ttn
-}
-
-void
-MZSCHEME::function(DOH *node)
-{
- char *name, *iname;
- SwigType *d;
- ParmList *l;
- Parm *p;
- Wrapper *f = NewWrapper();
- String *proc_name = NewString("");
- String *source = NewString("");
- String *target = NewString("");
- String *argnum = NewString("");
- String *arg = NewString("");
- String *cleanup = NewString("");
- String *outarg = NewString("");
- String *build = NewString("");
- SwigType *t;
- char *tm;
- int need_len = 0;
- int need_tempc = 0;
- int have_build = 0;
- int argout_set = 0;
- int i = 0;
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- d = Getattr(node,"type");
- l = Getattr(node,"parms");
-
- // Make a wrapper name for this
- char *wname = Char(Swig_name_wrapper(iname));
-
- // Build the name for Scheme.
- Printv(proc_name, iname,0);
- Replace(proc_name, "_", "-", DOH_REPLACE_ANY);
-
- // writing the function wrapper function
- Printv(f, "static Scheme_Object *", wname, " (", 0);
- Printv(f, "int argc, Scheme_Object **argv", 0);
- Printv(f, ")\n{\n", 0);
-
- // Declare return variable and arguments
- // number of parameters
- // they are called arg0, arg1, ...
- // the return value is called result
-
- int pcount = emit_args(node, f);
- int numargs = 0;
- int numopt = 0;
-
- // adds local variables
- Wrapper_add_local(f, "_tempc", "char *_tempc");
- Wrapper_add_local(f, "_len", "int _len");
- Wrapper_add_local(f, "swig_result", "Scheme_Object *swig_result");
-
- // Now write code to extract the parameters (this is super ugly)
-
- for(p = l; p; p = Getnext(p)) {
- // Produce names of source and target
- Clear(source);
- Clear(target);
- Clear(argnum);
- Clear(arg);
- Printf(source, "argv[%d]", i);
- Printf(target, "arg%d", i);
- Printf(argnum, "%d", i);
- Printv(arg, Getname(p),0);
-
- // Handle parameter types.
-
- if (Getignore(p))
- Printv(f, "/* ", Char(Getname(p)), " ignored... */\n", 0);
- else {
- ++numargs;
- if ((tm = Swig_typemap_lookup ((char*)"in",
- Gettype(p), Getname(p), source, target, f))) {
- Printv(f, tm, "\n", 0);
- mreplace (f, argnum, arg, proc_name);
- }
- // no typemap found
- // check if typedef and resolve
- else if (SwigType_istypedef(Gettype(p))) {
- t = SwigType_typedef_resolve(Gettype(p));
-
- // if a pointer then get it
- if (SwigType_ispointer(t)) {
- get_pointer (proc_name, i, t, f);
+ 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);
}
- // not a pointer
- else throw_unhandled_mzscheme_type_error (Gettype(p));
}
}
+
+ // 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();
- // Check if there are any constraints.
-
- if ((tm = Swig_typemap_lookup ((char*)"check",
- Gettype(p), Getname(p), source, target, f))) {
- // Yep. Use it instead of the default
- Printv(f, tm, "\n", 0);
- mreplace (f, argnum, arg, proc_name);
- }
-
- // Pass output arguments back to the caller.
-
- if ((tm = Swig_typemap_lookup ((char*)"argout",
- Gettype(p), Getname(p), source, target, f))) {
- // Yep. Use it instead of the default
- Printv(outarg, tm, "\n",0);
- mreplace (outarg, argnum, arg, proc_name);
- argout_set = 1;
+ }
+
+ /* ------------------------------------------------------------
+ * 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);
}
-
- // Free up any memory allocated for the arguments.
- if ((tm = Swig_typemap_lookup ((char*)"freearg",
- Gettype(p), Getname(p), source, target, f))) {
- // Yep. Use it instead of the default
- Printv(cleanup, tm, "\n",0);
- mreplace (cleanup, argnum, arg, proc_name);
+ 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");
}
- i++;
- }
-
- // Now write code to make the function call
-
- emit_func_call (node, f);
-
- // Now have return value, figure out what to do with it.
-
- if (SwigType_type(d) == T_VOID) {
- if(!argout_set)
- Printv(f, tab4, "swig_result = scheme_void;\n",0);
- }
-
- else if ((tm = Swig_typemap_lookup ((char*)"out",
- d, name, (char*)"result", (char*)"swig_result", f))) {
- Printv(f, tm, "\n",0);
- mreplace (f, argnum, arg, proc_name);
- }
- // no typemap found and not void then create a Scheme_Object holding
- // the C pointer and return it
- else if (SwigType_ispointer(d)) {
- Printv(f, tab4,
- "swig_result = swig_make_c_pointer(",
- "result, \"",
- SwigType_manglestr(d),
- "\");\n", 0);
+
+ 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;
}
- else {
- throw_unhandled_mzscheme_type_error (d);
+
+ /* ------------------------------------------------------------
+ * 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));
}
- // Dump the argument output code
- Printv(f, Char(outarg),0);
-
- // Dump the argument cleanup code
- Printv(f, Char(cleanup),0);
+ /* Return true iff T is a pointer type */
- // Look for any remaining cleanup
-
- if (NewObject) {
- if ((tm = Swig_typemap_lookup ((char*)"newfree",
- d, iname, (char*)"result", (char*)"", f))) {
- Printv(f, tm, "\n",0);
- mreplace (f, argnum, arg, proc_name);
- }
- }
-
- // Free any memory allocated by the function being wrapped..
-
- if ((tm = Swig_typemap_lookup ((char*)"ret",
- d, name, (char*)"result", (char*)"", f))) {
- // Yep. Use it instead of the default
- Printv(f, tm, "\n",0);
- mreplace (f, argnum, arg, proc_name);
+ int
+ is_a_pointer (SwigType *t)
+ {
+ return SwigType_ispointer(SwigType_typedef_resolve_all(t));
}
- // returning multiple values
- if(argout_set) {
- if(SwigType_type(d) == T_VOID) {
- Wrapper_add_local(f, "_lenv", "int _lenv = 0");
- Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]");
- Printv(f, tab4, "swig_result = scheme_values(_lenv, _values);\n",0);
- }
- else {
- Wrapper_add_local(f, "_lenv", "int _lenv = 1");
- Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]");
- Printv(f, tab4, "_values[0] = swig_result;\n",0);
- Printv(f, tab4, "swig_result = scheme_values(_lenv, _values);\n",0);
+ 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;
}
- }
-
- // Wrap things up (in a manner of speaking)
-
- Printv(f, tab4, "return swig_result;\n",0);
- Printv(f, "}\n",0);
-
- Printf(f_wrappers,"%s", f);
-
- // Now register the function
- char temp[256];
- sprintf(temp, "%d", numargs);
- Printv(init_func_def, "scheme_add_global(\"", proc_name,
- "\", scheme_make_prim_w_arity(", wname,
- ", \"", proc_name, "\", ", temp, ", ", temp,
- "), env);\n",0);
-
- Delete(proc_name);
- Delete(source);
- Delete(target);
- Delete(argnum);
- Delete(arg);
- Delete(outarg);
- Delete(cleanup);
- Delete(build);
- Delete(f);
-}
-
-// -----------------------------------------------------------------------
-// MZSCHEME::variable()
-//
-// 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.
-// -----------------------------------------------------------------------
-
-void
-MZSCHEME::variable (DOH *node)
-{
- char *name, *iname;
- SwigType *t;
- String *proc_name = NewString("");
- char var_name[256];
- char *tm;
- String *tm2 = NewString("");;
- String *argnum = NewString("0");
- String *arg = NewString("argv[0]");
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
-
- // evaluation function names
-
- sprintf (var_name, "_wrap_%svar_%s", prefix, iname);
-
- // Build the name for scheme.
- Printv(proc_name, iname,0);
- Replace(proc_name, "_", "-", DOH_REPLACE_ANY);
-
- if ((SwigType_type(t) != T_USER) || (SwigType_ispointer(t))) {
-
- Printf (f_wrappers, "static Scheme_Object *%s(int argc, Scheme_Object** argv) {\n", var_name);
-
- if ((SwigType_type(t) == T_CHAR) || (SwigType_ispointer(t))){
- Printf (f_wrappers, "\t char *_temp, _ptemp[128];\n");
- Printf (f_wrappers, "\t int _len;\n");
+ if (overname) {
+ Append(wname, overname);
}
- Printf (f_wrappers, "\t Scheme_Object *swig_result;\n");
-
- // Check for a setting of the variable value
-
- Printf (f_wrappers, "\t if (argc) {\n");
-
- // Yup. Extract the type from argv[0] and set variable value
-
- // if (Status & STAT_READONLY) {
- // Printf (f_wrappers, "\t\t GSWIG_ASSERT(0,\"Unable to set %s. "
- // "Variable is read only.\", argv[0]);\n", iname);
- // }
- if (ReadOnly) {
- Printf (f_wrappers, "\t\t scheme_signal_error(\"Unable to set %s. "
- "Variable is read only.\");\n", iname);
+ 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");
+ }
}
- else if ((tm = Swig_typemap_lookup ((char*)"varin",
- t, name, (char*)"argv[0]", name,0))) {
- Printv(tm2, tm,0);
- mreplace(tm2, argnum, arg, proc_name);
- Printv(f_wrappers, tm2, "\n",0);
+
+ /* 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);
+ }
}
- else if (SwigType_ispointer(t)) {
- if ((SwigType_type(t) == T_CHAR) && (SwigType_ispointer(t) == 1)) {
- Printf (f_wrappers, "\t\t _temp = SCHEME_STR_VAL(argv[0]);\n");
- Printf (f_wrappers, "\t\t _len = SCHEME_STRLEN_VAL(argv[0]);\n");
- Printf (f_wrappers, "\t\t if (%s) { free(%s);}\n", name, name);
- Printf (f_wrappers, "\t\t %s = (char *) "
- "malloc((_len+1)*sizeof(char));\n", name);
- Printf (f_wrappers, "\t\t strncpy(%s,_temp,_len);\n", name);
+
+ // 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 {
- // Set the value of a pointer
- Printf(f_wrappers, "\t\tif (!swig_get_c_pointer(argv[0], \"%s\", (void **) &arg0))\n",
- SwigType_manglestr(t));
- Printf(f_wrappers, "\t\t\tscheme_wrong_type(\"%s\", %s, 0, argc, argv", \
- var_name, SwigType_manglestr(t));
+ p = nextSibling(p);
}
}
- else {
- throw_unhandled_mzscheme_type_error (t);
+
+ // 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);
+ }
}
- Printf (f_wrappers, "\t}\n");
-
- // Now return the value of the variable (regardless
- // of evaluating or setting)
-
- if ((tm = Swig_typemap_lookup ((char*)"varout",
- t, name, name, (char*)"swig_result",0))) {
- Printf (f_wrappers, "%s\n", tm);
+
+ // 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);
}
- else if (SwigType_ispointer(t)) {
- if ((SwigType_type(t) == T_CHAR) && (SwigType_ispointer(t) == 1)) {
- Printf (f_wrappers, "\t swig_result = scheme_make_string(%s);\n", name);
- } else {
- // Is an ordinary pointer type.
- Printf(f_wrappers, "\tswig_result = swig_make_c_pointer(%s, \"%s\");\n",
- name, SwigType_manglestr(t));
+
+ // 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);
}
}
- else {
- throw_unhandled_mzscheme_type_error (t);
+
+ // 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);
}
- Printf (f_wrappers, "\t return swig_result;\n");
- Printf (f_wrappers, "}\n");
-
- // 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",
- "), env);\n",0);
-
- } else {
- Printf (stderr, "%s:%d. ** Warning. Unable to link with "
- " type %s (ignored).\n",
- Getfile(node), Getline(node), SwigType_manglestr(t));
- }
- Delete(proc_name);
- Delete(argnum);
- Delete(arg);
- Delete(tm2);
-}
+
+ // 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);
-// -----------------------------------------------------------------------
-// MZSCHEME::constant()
-//
-// Makes a constant. Not sure how this is really supposed to work.
-// I'm going to fake out SWIG and create a variable instead.
-// ------------------------------------------------------------------------
-
-void
-MZSCHEME::constant(DOH *node)
-{
- char *name;
- SwigType *type;
- char *value;
-
- int OldStatus = ReadOnly; // Save old status flags
- char var_name[256];
- String *proc_name = NewString("");
- String *rvalue = NewString("");
- String *temp = NewString("");
- char *tm;
-
- name = GetChar(node,"name");
- type = Getattr(node,"type");
- value = GetChar(node,"value");
-
- ReadOnly = 1;
-
- // Make a static variable;
-
- sprintf (var_name, "_wrap_const_%s", name);
-
- // Build the name for scheme.
- Printv(proc_name, name,0);
- Replace(proc_name, "_", "-", DOH_REPLACE_ANY);
-
- if ((SwigType_type(type) == T_USER) && (!SwigType_ispointer(type))) {
- fprintf (stderr, "%s:%d. Unsupported constant value.\n",
- Getfile(node), Getline(node));
- return;
- }
-
- // See if there's a typemap
-
- Printv(rvalue, value,0);
- if ((SwigType_type(type) == T_CHAR) && (SwigType_ispointer(type) == 1)) {
- temp = Copy(rvalue);
- Clear(rvalue);
- Printv(rvalue, "\"", temp, "\"",0);
- }
- if ((SwigType_type(type) == T_CHAR) && (SwigType_ispointer(type) == 0)) {
- Delete(temp);
- temp = Copy(rvalue);
- Clear(rvalue);
- Printv(rvalue, "'", temp, "'",0);
- }
- if ((tm = Swig_typemap_lookup ((char*)"const", type, name,
- rvalue, name,0))) {
- // Yep. Use it instead of the default
- Printf (f_init, "%s\n", tm);
- } else {
- // Create variable and assign it a value
-
- Printf (f_header, "static %s %s = ", SwigType_str(type,0), var_name);
- if ((SwigType_type(type) == T_CHAR) && (SwigType_ispointer(type) <= 1)) {
- Printf (f_header, "\"%s\";\n", value);
} else {
- Printf (f_header, "%s;\n", value);
+ 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);
+ }
}
-
- // Now create a variable declaration
-
- Hash *nnode = Copy(node);
- Setattr(nnode,"name",var_name);
- variable (nnode);
- Delete(nnode);
- ReadOnly = OldStatus;
+
+ Delete(proc_name);
+ Delete(source);
+ Delete(target);
+ Delete(arg);
+ Delete(outarg);
+ Delete(cleanup);
+ Delete(build);
+ DelWrapper(f);
+ return SWIG_OK;
}
- Delete(proc_name);
- Delete(rvalue);
- Delete(temp);
-}
-
-// ----------------------------------------------------------------------
-// MZSCHEME::usage_var(char *iname, SwigType *t, String &usage)
-//
-// Produces a usage string for a MzScheme variable.
-// ----------------------------------------------------------------------
-
-void
-MZSCHEME::usage_var (char *iname, SwigType *t, String *usage)
-{
- // char temp[1024], *c;
-
- // usage << "(" << iname << " [value])";
- // if (!((t->type != T_USER) || (t->is_pointer))) {
- // usage << " - unsupported";
- // }
-}
-
-// ---------------------------------------------------------------------------
-// MZSCHEME::usage_func(char *iname, SwigType *t, ParmList *l, String &usage)
-//
-// Produces a usage string for a function in MzScheme
-// ---------------------------------------------------------------------------
-
-void
-MZSCHEME::usage_func (char *iname, SwigType *d, ParmList *l, DOHString *usage)
-{
- Parm *p;
-
- // Print the function name.
-
- Printv(usage,"(",iname,0);
-
- // Now go through and print parameters
- for (p = l; p != 0; p = Getnext(p)) {
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
-
- if (Getignore(p))
- continue;
-
- // Print the type. If the parameter has been named, use that as well.
-
- if (SwigType_type(pt) != T_VOID) {
-
- // Print the type.
- Printv(usage," <", Getname(pt), 0);
- if (SwigType_ispointer(pt)) {
- for (int j = 0; j < SwigType_ispointer(pt); j++) {
- Putc('*', usage);
+ /* ------------------------------------------------------------
+ * 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");
}
- Putc('>',usage);
-
- // Print the name if it exists.
- if (strlen (Char(pn)) > 0) {
- Printv(usage," ", pn, 0);
+
+ // 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(pn);
+ Delete(proc_name);
+ Delete(argnum);
+ Delete(arg);
+ Delete(tm2);
+ DelWrapper(f);
+ return SWIG_OK;
}
- Putc(')',usage);
-}
-
-
-// ---------------------------------------------------------------------------
-// MZSCHEME::usage_returns(char *iname, SwigType *t, ParmList *l, String &usage)
-//
-// Produces a usage string for a function in MzScheme
-// ---------------------------------------------------------------------------
-
-void
-MZSCHEME::usage_returns (char *iname, SwigType *d, ParmList *l, DOHString *usage)
-{
- Parm *p;
- DOHString *param;
- int have_param = 0, j;
-
- param = NewString("");
-
- Clear(usage);
- Printf(usage,"returns ");
-
- // go through and see if any are output.
-
- for (p = l; p != 0; p = Getnext(p)) {
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
-
- if (strcmp (Char(pn),"BOTH") && strcmp (Char(pn),"OUTPUT"))
- continue;
- // Print the type. If the parameter has been named, use that as well.
-
- if (SwigType_type(pt) != T_VOID) {
- ++have_param;
-
- // Print the type.
- Printv(param," $", Getname(pt), 0);
- if (SwigType_ispointer(pt)) {
- for (j = 0; j < SwigType_ispointer(pt) - 1; j++) {
- Putc('*',param);
- }
+ /* ------------------------------------------------------------
+ * 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);
}
- Printf(param,"# ");
}
- Delete(pn);
+ Delete(proc_name);
+ Delete(rvalue);
+ Delete(temp);
+ return SWIG_OK;
}
- // See if we stick on the function return type.
- if (SwigType_type(d) != T_VOID || have_param == 0) {
- ++have_param;
- if (SwigType_type(d) == T_VOID)
- Insert(param,0," unspecified");
- else {
- Insert(param,0,"# ");
- Insert(param,0,SwigType_str(d,0));
- Insert(param,0," $");
+ /* ------------------------------------------------------------
+ * validIdentifer()
+ * ------------------------------------------------------------ */
+
+ virtual int validIdentifier(String *s) {
+ char *c = Char(s);
+ /* Check whether we have an R5RS identifier.*/
+ /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */
+ /* <initial> --> <letter> | <special initial> */
+ if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~'))) {
+ /* <peculiar identifier> --> + | - | ... */
+ if ((strcmp(c, "+") == 0)
+ || strcmp(c, "-") == 0
+ || strcmp(c, "...") == 0) return 1;
+ else return 0;
}
+ /* <subsequent> --> <initial> | <digit> | <special subsequent> */
+ 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;
}
-
- // Kill extra white space.
- // Sorry. Not implemented: param.strip();
- Replace(param,"$", "<", DOH_REPLACE_ANY);
- Replace(param,"#", ">", DOH_REPLACE_ANY);
- Replace(param,"><", "> <", DOH_REPLACE_ANY);
-
- // If there are multiple return values put them in a list.
- if (have_param > 1) {
- Insert(param,0,"(");
- Append(param,")");
- }
- Printv(usage,param,0);
- Delete(param);
+};
+
+/* -----------------------------------------------------------------------------
+ * swig_mzscheme() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+extern "C" Language *
+swig_mzscheme(void) {
+ return new MZSCHEME();
}
-// ----------------------------------------------------------------------
-// MZSCHEME::usage_const(char *iname, SwigType *type, char *value, String &usage)
-//
-// Produces a usage string for a MzScheme constant
-// ----------------------------------------------------------------------
-
-void
-MZSCHEME::usage_const (char *iname, SwigType *, char *value, DOHString *usage)
-{
- Printv(usage,"(", iname, " ", value, ")", 0);
-}
diff --git a/Source/Modules1.1/mzscheme.h b/Source/Modules1.1/mzscheme.h
deleted file mode 100644
index 8aa38ebcb..000000000
--- a/Source/Modules1.1/mzscheme.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * 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.
- *******************************************************************************/
-
-/**************************************************************************
- * $Header$
- *
- * class MZSCHEME
- *
- * Mzscheme implementation
- * (Caution : This is *somewhat* experimental)
- *
- **************************************************************************/
-
-class MZSCHEME : public Language
-{
-private:
- void get_pointer(DOHString_or_char *name, int parm, SwigType *t, Wrapper *f);
- void usage_var(char *, SwigType *, DOHString *usage);
- void usage_func(char *, SwigType *, ParmList *, DOHString *usage);
- void usage_returns(char *, SwigType *, ParmList *, DOHString *usage);
- void usage_const(char *, SwigType *, char *, DOHString *usage);
-
-public :
- void parse_args (int, char *argv[]);
- void initialize(String *module);
- void function (DOH *node);
- void variable (DOH *node);
- void constant (DOH *node);
- void close (void);
- void create_command (String *, String *) { };
-};
diff --git a/Source/Modules1.1/ocaml.cxx b/Source/Modules1.1/ocaml.cxx
new file mode 100755
index 000000000..786fee5dd
--- /dev/null
+++ b/Source/Modules1.1/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 <ctype.h>
+
+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.*/
+ /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */
+ /* <initial> --> <letter> | <special initial> */
+ if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~'))) {
+ /* <peculiar identifier> --> + | - | ... */
+ if ((strcmp(c, "+") == 0)
+ || strcmp(c, "-") == 0
+ || strcmp(c, "...") == 0) return 1;
+ else return 0;
+ }
+ /* <subsequent> --> <initial> | <digit> | <special subsequent> */
+ 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/Modules1.1/overload.cxx b/Source/Modules1.1/overload.cxx
new file mode 100644
index 000000000..f62e63f93
--- /dev/null
+++ b/Source/Modules1.1/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/Modules1.1/perl5.cxx b/Source/Modules1.1/perl5.cxx
index fb04cafdd..94191080d 100644
--- a/Source/Modules1.1/perl5.cxx
+++ b/Source/Modules1.1/perl5.cxx
@@ -1,4 +1,4 @@
-/* -----------------------------------------------------------------------------
+/* ----------------------------------------------------------------------------
* perl5.cxx
*
* Generate Perl5 wrappers
@@ -7,1950 +7,1588 @@
* 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.
- * ----------------------------------------------------------------------------- */
+ * ------------------------------------------------------------------------- */
-/* DB: I had to take some features related to package naming out of this to
- get the new type system to work. These need to be put back in at some point. */
+char cvsroot_perl5_cxx[] = "$Header$";
-static char cvsroot[] = "$Header$";
+#include "swigmod.h"
-#include "swig11.h"
-#include "perl5.h"
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
-static char *usage = (char*)"\
+static const char *usage = (char*)"\
Perl5 Options (available with -perl5)\n\
- -module name - Set module name\n\
- -interface name - Set interface name\n\
- -package name - Set package prefix\n\
+ -ldflags - Print runtime libraries to link with\n\
-static - Omit code related to dynamic loading.\n\
- -shadow - Create shadow classes.\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 String *smodule = 0;
static int compat = 0;
-static int export_all = 0;
-static String *package = 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;
-static String *interface = 0;
-static String *cmodule = 0;
-static String *vinit = 0;
-static FILE *f_pm = 0;
-static String *pm; /* Package initialization code */
-static String *magic; /* Magic variable wrappers */
+
+/*
+ * 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 Hash *classes = 0; /* A hash table for storing the classes we've seen so far */
-static Hash *symbols = 0;
-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 *class_type = 0; /* Type of class "struct", "class", "union" */
-static String *real_classname = 0; /* Real name of C/C++ class */
-static String *base_class = 0; /* Base class (if using inheritance) */
-static int class_renamed = 0;
+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 *realpackage = 0; /* Name of real module */
-static String *func_stubs = 0; /* Function stubs */
-static String *var_stubs = 0; /* Variable stubs */
-static String *member_keys = 0; /* Keys for all member data */
-static String *exported = 0; /* Exported symbols */
+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()
+ * ------------------------------------------------------------ */
-/* Test to see if a type corresponds to something wrapped with a shadow class */
-static DOH *is_shadow(SwigType *t) {
- DOH *r;
- SwigType *lt = Swig_clocal_type(t);
- r = Getattr(classes,lt);
- Delete(lt);
- return r;
-}
-
-/* -----------------------------------------------------------------------------
- * PERL5::parse_args()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::parse_args(int argc, char *argv[]) {
- int i = 1;
+ virtual void main(int argc, char *argv[]) {
+ int i = 1;
- cmodule = NewString("");
- Swig_swiglib_set("perl5");
- for (i = 1; i < argc; i++) {
+ SWIG_library_directory("perl5");
+ for (i = 1; i < argc; i++) {
if (argv[i]) {
- if(strcmp(argv[i],"-package") == 0) {
- if (argv[i+1]) {
- package = NewString(argv[i+1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i+1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else 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();
- }
- } 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) {
- blessed = 1;
+ 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],"-compat") == 0) {
- compat = 1;
+ } else if (strcmp(argv[i],"-pm") == 0) {
Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-help") == 0) {
- fputs(usage,stderr);
- }
+ 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((void *) "SWIGPERL 1", 0);
- Preprocessor_define((void *) "SWIGPERL5 1", 0);
-}
+ }
-/* -----------------------------------------------------------------------------
- * PERL5::initialize()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::initialize(String *modname)
-{
- char filen[256];
-
- classes = NewHash();
- symbols = NewHash();
-
- vinit = NewString("");
- pm = NewString("");
- func_stubs = NewString("");
- var_stubs = NewString("");
- exported = NewString("");
- magic = NewString("");
- pragma_include = NewString("");
-
- Swig_banner(f_runtime);
-
- if (NoInclude) {
- Printf(f_header,"#define SWIG_NOINCLUDE\n");
+ Preprocessor_define("SWIGPERL 1", 0);
+ Preprocessor_define("SWIGPERL5 1", 0);
+ SWIG_typemap_lang("perl5");
+ SWIG_config_file("perl5.swg");
+ allow_overloading();
}
- if (Swig_insert_file("common.swg", f_runtime) == -1) {
- Printf(stderr,"SWIG : Fatal error. Unable to locate 'common.swg' in SWIG library.\n");
- Swig_exit (EXIT_FAILURE);
- }
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
- if (Swig_insert_file("perl5.swg", f_runtime) == -1) {
- Printf(stderr,"SWIG : Fatal error. Unable to locate 'perl5.swg' in SWIG library.\n");
- Swig_exit (EXIT_FAILURE);
- }
+ virtual int top(Node *n) {
- if (!module) module = NewString(modname);
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
- /* Create a C module name and put it in 'cmodule' */
- Clear(cmodule);
- Append(cmodule,module);
- Replace(cmodule,":","_",DOH_REPLACE_ANY);
+ 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");
+ }
- if (!package) {
- package = NewString(module);
- }
+ module = Copy(Getattr(n,"name"));
/* If we're in blessed mode, change the package name to "packagec" */
- if (blessed) {
- realpackage = package;
- package = interface ? interface : NewStringf("%sc",package);
- } else {
- realpackage = NewString(package);
- }
+
+ 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 */
- {
- char *m = Char(module) + Len(module);
- while (m != Char(module)) {
- if (*m == ':') {
- m++;
- break;
+ 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);
}
- m--;
+ Swig_register_filebyname("pm",f_pm);
}
- sprintf(filen,"%s%s.pm", output_dir,m);
- if ((f_pm = fopen(filen,"w")) == 0) {
- Printf(stderr,"Unable to open %s\n", filen);
- Swig_exit (EXIT_FAILURE);
+ {
+ 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);
}
- }
- if (!blessed) {
- smodule = NewString(module);
- } else if (is_static) {
- smodule = NewStringf("%sc",module);
- Append(cmodule,"c");
- Append(cmodule,"c");
- } else {
- smodule = NewString(module);
- }
- {
- String *tmp = NewString(realpackage);
- Replace(tmp,":","_", DOH_REPLACE_ANY);
- Printf(f_header,"#define SWIG_init boot_%s\n\n", tmp);
- Printf(f_header,"#define SWIG_name \"%s::boot_%s\"\n", package, tmp);
- Delete(tmp);
- }
- Printf(f_header,"#define SWIG_varinit \"%s::var_%s_init();\"\n", package, cmodule);
- Printf(f_header,"#ifdef __cplusplus\n");
- Printf(f_header,"extern \"C\"\n");
- Printf(f_header,"#endif\n");
- Printf(f_header,"#ifndef PERL_OBJECT\n");
- Printf(f_header,"SWIGEXPORT(void) SWIG_init (CV* cv);\n");
- Printf(f_header,"#else\n");
- Printf(f_header,"SWIGEXPORT(void) SWIG_init (CV *cv, CPerlObj *);\n");
- Printf(f_header,"#endif\n");
- Printf(f_init,"#ifdef __cplusplus\n");
- Printf(f_init,"extern \"C\"\n");
- Printf(f_init,"#endif\n");
- Printf(f_init,"XS(SWIG_init) {\n");
- Printf(f_init,"\t dXSARGS;\n");
- Printf(f_init,"\t int i;\n");
- Printf(f_init,"\t char *file = __FILE__;\n");
- Printv(f_init,
- "for (i = 0; swig_types_initial[i]; i++) {\n",
- "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n",
- "}\n", 0);
- Printf(f_init,"\t newXS(\"%s::var_%s_init\", _wrap_perl5_%s_var_init, file);\n",package,cmodule, cmodule);
-
- Printv(vinit,
- "XS(_wrap_perl5_", cmodule, "_var_init) {\n",
- tab4, "dXSARGS;\n",
- tab4, "SV *sv;\n",
- 0);
-
- Printf(f_pm,"# This file was automatically generated by SWIG\n");
- Printf(f_pm,"package %s;\n",realpackage);
- 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");
- }
+ Printf(f_pm,"# This file was automatically generated by SWIG\n");
+ Printf(f_pm,"package %s;\n",fullmodule);
- /* 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(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",
- 0);
-}
+ 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");
+ }
-/* -----------------------------------------------------------------------------
- * PERL5::import()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::import(String *modname) {
- if (blessed) {
- Printf(f_pm,"require %s;\n", modname);
- }
-}
+ /* 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);
-/* -----------------------------------------------------------------------------
- * PERL5::close()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::close(void) {
- String *base = NewString("");
+ 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",
- 0);
+ Printv(magic,
+ "\n\n#ifdef PERL_OBJECT\n",
+ "};\n",
+ "#endif\n",
+ NIL);
- Printf(f_header,"%s\n", magic);
+ Printf(f_header,"%s\n", magic);
- String *type_table = NewString("");
- SwigType_emit_type_table(f_runtime,type_table);
+ 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) {
- SwigType *type;
- for (type = Firstkey(classes); type; type = Nextkey(classes)) {
- String *mangle = NewStringf("\"%s\"", SwigType_manglestr(type));
- String *rep = NewStringf("\"%s\"", Getattr(classes,type));
- Replace(type_table,mangle,rep,DOH_REPLACE_ANY);
- Delete(mangle);
- Delete(rep);
+ 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(stdout,"::: Perl shadow :::\n\n%s",classes); */
- Printf(f_init,"\t ST(0) = &PL_sv_yes;\n");
- Printf(f_init,"\t XSRETURN(1);\n");
- Printf(f_init,"}\n");
+ Printf(f_wrappers,"%s",type_table);
+ Delete(type_table);
- Printv(vinit,tab4, "XSRETURN(1);\n", "}\n", 0);
- Printf(f_wrappers,"%s", vinit);
-
- Printf(f_pm,"package %s;\n", package);
-
- if (!is_static) {
- Printf(f_pm,"bootstrap %s;\n", realpackage);
- } else {
- String *tmp = NewString(realpackage);
- Replace(tmp,":","_",DOH_REPLACE_ANY);
- Printf(f_pm,"boot_%s();\n", tmp);
- Delete(tmp);
- }
- Printf(f_pm,"var_%s_init();\n", cmodule);
- Printf(f_pm,"%s",pragma_include);
- Printf(f_pm,"package %s;\n", realpackage);
- Printf(f_pm,"@EXPORT = qw(%s );\n",exported);
+ Printf(constant_tab,"{0}\n};\n");
+ Printv(f_wrappers,constant_tab,NIL);
- if (blessed) {
+ Printf(f_wrappers,"#ifdef __cplusplus\n}\n#endif\n");
- Printv(base,
- "\n# ---------- BASE METHODS -------------\n\n",
- "package ", realpackage, ";\n\n",
- 0);
+ Printf(f_init,"\t ST(0) = &PL_sv_yes;\n");
+ Printf(f_init,"\t XSRETURN(1);\n");
+ Printf(f_init,"}\n");
- /* Write out the TIE method */
+ /* Finish off tables */
+ Printf(variable_tab, "{0}\n};\n");
+ Printv(f_wrappers,variable_tab,NIL);
- Printv(base,
- "sub TIEHASH {\n",
- tab4, "my ($classname,$obj) = @_;\n",
- tab4, "return bless $obj, $classname;\n",
- "}\n\n",
- 0);
+ Printf(command_tab,"{0,0}\n};\n");
+ Printv(f_wrappers,command_tab,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");
+ Printf(f_pm,"package %s;\n", cmodule);
- /* 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",
- 0);
+ 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);
- Printf(f_pm,"%s",base);
+ if (blessed) {
- /* Emit function stubs for stand-alone functions */
+ Printv(base,
+ "\n# ---------- BASE METHODS -------------\n\n",
+ "package ", fullmodule, ";\n\n",
+ NIL);
- Printf(f_pm,"\n# ------- FUNCTION WRAPPERS --------\n\n");
- Printf(f_pm,"package %s;\n\n",realpackage);
- Printf(f_pm,"%s",func_stubs);
+ /* Write out the TIE method */
- /* Emit package code for different classes */
+ Printv(base,
+ "sub TIEHASH {\n",
+ tab4, "my ($classname,$obj) = @_;\n",
+ tab4, "return bless $obj, $classname;\n",
+ "}\n\n",
+ NIL);
- Printf(f_pm,"%s",pm);
+ /* 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. */
- /* Emit variable stubs */
+ Printf(base,"sub CLEAR { }\n\n");
- Printf(f_pm,"\n# ------- VARIABLE STUBS --------\n\n");
- Printf(f_pm,"package %s;\n\n",realpackage);
- Printf(f_pm,"%s",var_stubs);
- }
+ /* Output default firstkey/nextkey methods */
- Printf(f_pm,"1;\n");
- fclose(f_pm);
- Delete(base);
-}
+ Printf(base, "sub FIRSTKEY { }\n\n");
+ Printf(base, "sub NEXTKEY { }\n\n");
-/* -----------------------------------------------------------------------------
- * get_pointer()
- * ----------------------------------------------------------------------------- */
-static void
-get_pointer(char *iname, char *srcname, char *src, char *dest,
- SwigType *t, String *f, char *ret) {
+ /* Output a 'this' method */
- SwigType_remember(t);
- SwigType *lt = Swig_clocal_type(t);
- Printv(f, "if (SWIG_ConvertPtr(", src, ",(void **) &", dest, ",", 0);
+ Printv(base,
+ "sub this {\n",
+ tab4, "my $ptr = shift;\n",
+ tab4, "return tied(%$ptr);\n",
+ "}\n\n",
+ NIL);
- /* If we're passing a void pointer, we give the pointer conversion a NULL
- pointer, otherwise pass in the expected type. */
+ Printf(f_pm,"%s",base);
- if (Cmp(lt,"p.void") == 0) {
- Printf(f, " 0 ) < 0) {\n");
- } else {
- Printv(f, "SWIGTYPE", SwigType_manglestr(t), ") < 0) {\n",0);
- }
+ /* Emit function stubs for stand-alone functions */
- Printv(f,
- "croak(\"Type error in ", srcname, " of ", iname,". Expected %s\", SWIGTYPE",
- SwigType_manglestr(t), "->name);\n",
- ret, ";\n",
- "}\n",
- 0);
- Delete(lt);
-}
+ Printf(f_pm,"\n# ------- FUNCTION WRAPPERS --------\n\n");
+ Printf(f_pm,"package %s;\n\n",fullmodule);
+ Printf(f_pm,"%s",func_stubs);
-/* -----------------------------------------------------------------------------
- * PERL5::create_command()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::create_command(String *cname, String *iname) {
- Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package, iname, Swig_name_wrapper(cname));
- if (export_all) {
- Printf(exported,"%s ",iname);
- }
-}
+ /* Emit package code for different classes */
+ Printf(f_pm,"%s",pm);
-/* -----------------------------------------------------------------------------
- * PERL5::create_function()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::function(DOH *node)
-{
- char *name, *iname;
- SwigType *d;
- ParmList *l;
- Parm *p;
- int pcount,i,j;
- Wrapper *f;
- char source[256],target[256],temp[256], argnum[32];
- char *tm;
- String *cleanup, *outarg;
- int numopt = 0;
- int need_save, num_saved = 0;
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- d = Getattr(node,"type");
- l = Getattr(node,"parms");
-
- f = NewWrapper();
- cleanup = NewString("");
- outarg = NewString("");
-
- Printv(f, "XS(", Swig_name_wrapper(iname), ") {\n", 0);
-
- pcount = emit_args(node, f);
- numopt = check_numopt(l);
-
- Wrapper_add_local(f,"argvi","int argvi = 0");
-
- /* Check the number of arguments */
-
- Printf(f," if ((items < %d) || (items > %d)) \n", pcount-numopt, ParmList_numarg(l));
- Printf(f," croak(\"Usage: %s\");\n", usage_func(iname,d,l));
-
- /* Write code to extract parameters. */
- i = 0;
- j = 0;
- for (p = l; p; p = Getnext(p)) {
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
-
- /* Produce string representation of source and target arguments */
- sprintf(source,"ST(%d)",j);
- sprintf(target,"%s", Char(Getlname(p)));
- sprintf(argnum,"%d",j+1);
-
- /* Check to see if this argument is being ignored */
- if (!Getignore(p)) {
- /* Check for optional argument */
- if (j>= (pcount-numopt))
- Printf(f," if (items > %d) {\n", j);
-
- if ((tm = Swig_typemap_lookup((char*)"in",pt,pn,source,target,f))) {
- Printf(f,"%s\n",tm);
- Replace(f,"$argnum",argnum,DOH_REPLACE_ANY);
- Replace(f,"$arg",source,DOH_REPLACE_ANY);
- } else {
- switch(SwigType_type(pt)) {
- 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," %s = (%s)SvIV(ST(%d));\n", target, SwigType_lstr(pt,0),j);
- break;
- case T_CHAR :
-
- Printf(f," %s = (char) *SvPV(ST(%d),PL_na);\n", target, j);
- break;
-
- case T_DOUBLE :
- case T_FLOAT :
- Printf(f," %s = (%s)SvNV(ST(%d));\n", target, SwigType_lstr(pt,0), j);
- break;
-
- case T_VOID :
- break;
-
- case T_USER:
- SwigType_add_pointer(pt);
- sprintf(temp,"argument %d", i+1);
- get_pointer(iname, temp, source, target, pt, f, (char *)"XSRETURN(1)");
- SwigType_del_pointer(pt);
- break;
-
- case T_STRING:
- Printf(f," if (! SvOK((SV*) ST(%d))) { %s = 0; }\n", j, target);
- Printf(f," else { %s = (char *) SvPV(ST(%d),PL_na); }\n", target,j);
- break;
-
- case T_POINTER: case T_ARRAY: case T_REFERENCE:
- sprintf(temp,"argument %d", i+1);
- get_pointer(iname,temp,source,target, pt, f, (char*)"XSRETURN(1)");
- break;
-
- default :
- Printf(stderr,"%s:%d. Unable to use type %s as a function argument.\n",Getfile(node), Getline(node), SwigType_str(pt,0));
- break;
- }
+ 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);
}
- /* The source is going to be an array of saved values. */
- sprintf(temp,"_saved[%d]",num_saved);
- if (j>= (pcount-numopt))
- Printf(f," } \n");
- j++;
- } else {
- temp[0] = 0;
- }
- /* Check if there is any constraint code */
- if ((tm = Swig_typemap_lookup((char*)"check",pt,pn,source,target,0))) {
- Printf(f,"%s\n", tm);
- Replace(f,"$argnum",argnum, DOH_REPLACE_ANY);
- }
- need_save = 0;
+ /* Emit variable stubs */
- if ((tm = Swig_typemap_lookup((char*)"freearg",pt,pn,target,temp,0))) {
- Printf(cleanup,"%s\n", tm);
- Replace(cleanup,"$argnum",argnum,DOH_REPLACE_ANY);
- Replace(cleanup,"$arg",temp,DOH_REPLACE_ANY);
- need_save = 1;
+ Printf(f_pm,"\n# ------- VARIABLE STUBS --------\n\n");
+ Printf(f_pm,"package %s;\n\n",fullmodule);
+ Printf(f_pm,"%s",var_stubs);
}
- if ((tm = Swig_typemap_lookup((char*)"argout",pt,pn,target,(char*)"ST(argvi)",0))) {
- String *tempstr = NewString(tm);
- Replace(tempstr,"$argnum",argnum, DOH_REPLACE_ANY);
- Replace(tempstr,"$arg",temp, DOH_REPLACE_ANY);
- Printf(outarg,"%s\n", tempstr);
- Delete(tempstr);
- need_save = 1;
- }
- /* If we need a saved variable, we need to emit to emit some code for that
- This only applies if the argument actually existed (not ignore) */
- if ((need_save) && (!Getignore(p))) {
- Printv(f, tab4, temp, " = ", source, ";\n", 0);
- num_saved++;
- }
- i++;
- }
- /* 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,0);
+ 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;
}
- /* Now write code to make the function call */
-
- emit_func_call(node,f);
-
- if ((tm = Swig_typemap_lookup((char*)"out",d,iname,(char*)"result",(char*)"ST(argvi)",0))) {
- Printf(f, "%s\n", tm);
- } else {
- if (SwigType_type(d) != T_VOID) {
- Printf(f," ST(argvi) = sv_newmortal();\n");
- switch (SwigType_type(d)) {
- case T_INT: case T_BOOL: case T_UINT:
- case T_SHORT: case T_USHORT:
- case T_LONG : case T_ULONG:
- case T_SCHAR: case T_UCHAR :
- Printf(f," sv_setiv(ST(argvi++),(IV) result);\n");
- break;
- case T_DOUBLE :
- case T_FLOAT :
- Printf(f," sv_setnv(ST(argvi++), (double) result);\n");
- break;
- case T_CHAR :
- Wrapper_add_local(f,"_ctemp", "char ctemp[2]");
- Printv(f,
- tab4, "ctemp[0] = result;\n",
- tab4, "ctemp[1] = 0;\n",
- tab4, "sv_setpv((SV*)ST(argvi++),ctemp);\n",
- 0);
- break;
-
- case T_USER:
- SwigType_add_pointer(d);
- SwigType_remember(d);
- Printv(f,
- tab4, "SWIG_MakePtr(ST(argvi++), (void *) result, SWIGTYPE", SwigType_manglestr(d),");\n", 0);
- SwigType_del_pointer(d);
- break;
-
- case T_STRING:
- Printf(f," sv_setpv((SV*)ST(argvi++),(char *) result);\n");
- break;
-
- case T_POINTER: case T_ARRAY: case T_REFERENCE:
- SwigType_remember(d);
- Printv(f, tab4, "SWIG_MakePtr(ST(argvi++), (void *) result, SWIGTYPE", SwigType_manglestr(d), ");\n", 0);
- break;
-
- default :
- Printf(stderr,"%s:%d. Unable to use return type %s in function %s.\n", Getfile(node), Getline(node), SwigType_str(d,0), name);
- break;
+ /* ------------------------------------------------------------
+ * 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);
}
- /* If there were any output args, take care of them. */
-
- Printv(f,outarg,0);
-
- /* If there was any cleanup, do that. */
+ /* ------------------------------------------------------------
+ * 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;
+ }
- Printv(f,cleanup,0);
+ f = NewWrapper();
+ cleanup = NewString("");
+ outarg = NewString("");
- if (NewObject) {
- if ((tm = Swig_typemap_lookup((char*)"newfree",d,iname,(char*)"result",(char*)"",0))) {
- Printf(f,"%s\n",tm);
+ 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);
- if ((tm = Swig_typemap_lookup((char*)"ret",d,iname,(char*)"result",(char*)"",0))) {
- Printf(f,"%s\n", tm);
- }
-
- Printf(f," XSRETURN(argvi);\n}\n");
+ emit_args(d, l, f);
+ emit_attach_parmmaps(l,f);
+ Setattr(n,"wrap:parms",l);
- /* Add the dXSARGS last */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+ varargs = emit_isvarargs(l);
- Wrapper_add_local(f,"dXSARGS","dXSARGS");
+ Wrapper_add_local(f,"argvi","int argvi = 0");
- /* Substitute the cleanup code */
- Replace(f,"$cleanup",cleanup,DOH_REPLACE_ANY);
- Replace(f,"$name",iname,DOH_REPLACE_ANY);
+ /* 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");
- /* Dump the wrapper function */
+ /* 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");
+ }
- Printf(f_wrappers,"%s", f);
+ SwigType *pt = Getattr(p,"type");
+ String *ln = Getattr(p,"lname");
- /* Now register the function */
+ /* Produce string representation of source and target arguments */
+ sprintf(source,"ST(%d)",i);
+ sprintf(target,"%s", Char(ln));
- Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package, iname, Swig_name_wrapper(iname));
+ 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 (export_all) {
- Printf(exported,"%s ", iname);
- }
+ 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);
+ }
+ }
- /* --------------------------------------------------------------------
- * Create a stub for this function, provided it's not a member function
- *
- * Really we only need to create a stub if this function involves
- * complex datatypes. If it does, we'll make a small wrapper to
- * process the arguments. If it doesn't, we'll just make a symbol
- * table entry.
- * -------------------------------------------------------------------- */
-
- 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",
- 0);
-
- /* Now we have to go through and patch up the argument list. If any
- * arguments to our function correspond to other Perl objects, we
- * need to extract them from a tied-hash table object.*/
-
- Parm *p = l;
- int i = 0;
- while(p) {
- SwigType *pt = Gettype(p);
-
- if (!Getignore(p)) {
- /* Look up the datatype name here */
- char sourceNtarget[256];
- sprintf(sourceNtarget,"$args[%d]",i);
-
- if ((tm = Swig_typemap_lookup((char*)"perl5in",pt,(char*)"",sourceNtarget,sourceNtarget,0))) {
- Printf(func,"%s\n", tm);
- } else if (is_shadow(pt)) {
- /*
- if (i >= (pcount - numopt))
- Printf(func," if (scalar(@args) >= %d) {\n ", i);
- Printf(func," $args[%d] = tied(%%{$args[%d]});\n", i, i);
- if (i >= (pcount - numopt))
- Printf(func," }\n");
- need_stub = 1;
- */
+ /* 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++;
}
- i++;
+ Printv(outarg,tm,"\n",NIL);
+ p = Getattr(p,"tmap:argout:next");
+ } else {
+ p = nextSibling(p);
}
- p = Getnext(p);
}
- Printv(func, tab4, "my $result = ", package, "::", iname, "(@args);\n", 0);
+ /* 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 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. */
+ /* Now write code to make the function call */
- if ((tm = Swig_typemap_lookup((char*)"perl5out",d,(char*)"",name,(char*)"sv",0))) {
- Printv(func,
- tm, "\n",
- tab4, "return $result;\n",
- "}\n",
- 0);
- need_stub = 1;
- } else if (is_shadow(d)) {
- Printv(func, tab4, "return undef if (!defined($result));\n", 0);
-
- /* If we're returning an object by value, put it's reference
- into our local hash table */
-
- if ((!SwigType_ispointer(d)) || NewObject) {
- Printv(func, tab4, "$", is_shadow(d), "::OWNER{$result} = 1;\n", 0);
- }
+ emit_action(n,f);
- /* We're returning a Perl "object" of some kind. Turn it into a tied hash */
+ 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);
+ }
- Printv(func,
- tab4, "my %resulthash;\n",
- tab4, "tie %resulthash, ref($result), $result;\n",
- tab4, "return bless \\%resulthash, ref($result);\n",
- "}\n",
- 0);
+ /* If there were any output args, take care of them. */
- need_stub = 1;
- } else {
+ Printv(f->code,outarg,NIL);
- /* Hmmm. This doesn't appear to be anything I know about */
- Printv(func, tab4, "return $result;\n", "}\n", 0);
- }
+ /* If there was any cleanup, do that. */
- /* Now check if we needed the stub. If so, emit it, otherwise
- * Emit code to hack Perl's symbol table instead */
+ Printv(f->code,cleanup,NIL);
- if (need_stub) {
- Printf(func_stubs,"%s",func);
- } else {
- Printv(func_stubs,"*", iname, " = *", package, "::", iname, ";\n", 0);
+ 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);
+ }
}
- Delete(func);
- }
- Delete(cleanup);
- Delete(outarg);
- Delete(f);
-}
-/* -----------------------------------------------------------------------------
- * PERL5::link_variable()
- * ----------------------------------------------------------------------------- */
+ if ((tm = Swig_typemap_lookup_new("ret",n,"result", 0))) {
+ Replaceall(tm,"$source","result");
+ Printf(f->code,"%s\n", tm);
+ }
-void PERL5::variable(DOH *node) {
- char *name, *iname;
- SwigType *t;
+ 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);
- char set_name[256];
- char val_name[256];
- Wrapper *getf, *setf;
- char *tm;
- int setable = 1;
+ /* Add the dXSARGS last */
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
+ Wrapper_add_local(f,"dXSARGS","dXSARGS");
- sprintf(set_name,"_wrap_set_%s",iname);
- sprintf(val_name,"_wrap_val_%s",iname);
+ /* Substitute the cleanup code */
+ Replaceall(f->code,"$cleanup",cleanup);
+ Replaceall(f->code,"$symname",iname);
- getf = NewWrapper();
- setf = NewWrapper();
+ /* Dump the wrapper function */
- /* Create a new scalar that we will attach magic to */
+ 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;
+ }
- Printv(vinit, tab4, "sv = perl_get_sv(\"", package, "::", iname, "\",TRUE | 0x2);\n", 0);
+ /* ------------------------------------------------------------
+ * 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);
+ }
- /* Create a Perl function for setting the variable value */
+ /* Now write a function to evaluate the variable */
- if (!ReadOnly) {
- Printf(setf,"SWIGCLASS_STATIC int %s(SV* sv, MAGIC *mg) {\n", set_name);
- Printv(setf,
+ 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",
- 0);
+ NIL);
- /* Check for a few typemaps */
- if ((tm = Swig_typemap_lookup((char*)"varin",t,(char*)"",(char*)"sv",name,0))) {
- Printf(setf,"%s\n", tm);
- } else if ((tm = Swig_typemap_lookup((char*)"in",t,(char*)"",(char*)"sv",name,0))) {
- Printf(setf,"%s\n", tm);
+ 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 {
- switch(SwigType_type(t)) {
- case T_INT : case T_BOOL: case T_UINT:
- case T_SHORT : case T_USHORT:
- case T_LONG : case T_ULONG:
- case T_UCHAR: case T_SCHAR:
- Printv(setf,tab4, name, " = (", SwigType_str(t,0), ") SvIV(sv);\n", 0);
- break;
- case T_DOUBLE :
- case T_FLOAT :
- Printv(setf, tab4, name, " = (", SwigType_str(t,0), ") SvNV(sv);\n", 0);
- break;
- case T_CHAR :
- Printv(setf, tab4, name, " = (char) *SvPV(sv,PL_na);\n", 0);
- break;
-
- case T_USER:
-
- SwigType_add_pointer(t);
- Wrapper_add_local(setf,"_temp", "void *_temp");
- get_pointer(iname,(char*)"value",(char*)"sv",(char*)"_temp", t, setf, (char*)"return(1)");
- Printv(setf, tab4, name, " = *((", SwigType_str(t,0), ") _temp);\n", 0);
- SwigType_del_pointer(t);
- break;
-
- case T_STRING:
- Wrapper_add_local(setf,"_a","char *_a");
- Printf(setf," _a = (char *) SvPV(sv,PL_na);\n");
-
- if (CPlusPlus)
- Printv(setf,
- tab4, "if (", name, ") delete [] ", name, ";\n",
- tab4, name, " = new char[strlen(_a)+1];\n",
- 0);
- else
- Printv(setf,
- tab4, "if (", name, ") free((char*)", name, ");\n",
- tab4, name, " = (char *) malloc(strlen(_a)+1);\n",
- 0);
- Printv(setf,"strcpy((char*)", name, ",_a);\n", 0);
- break;
-
- case T_ARRAY:
- {
- SwigType *aop;
- SwigType *ta = Copy(t);
- aop = SwigType_pop(ta);
- if (SwigType_type(ta) == T_CHAR) {
- String *dim = SwigType_array_getdim(aop,0);
- if (dim && Len(dim)) {
- Printf(setf, "strncpy(%s,(char*) SvPV(sv,PL_na), %s);\n", name,dim);
- setable = 1;
- } else {
- setable = 0;
- }
- } else {
- setable = 0;
- }
- Delete(ta);
- Delete(aop);
- }
- break;
+ 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");
- case T_POINTER: case T_REFERENCE:
- Wrapper_add_local(setf,"_temp","void *_temp");
- get_pointer(iname,(char*)"value",(char*)"sv",(char*)"_temp", t, setf, (char*)"return(1)");
- Printv(setf,tab4, name, " = (", SwigType_str(t,0), ") _temp;\n", 0);
- break;
+ Replaceall(getf->code,"$symname",iname);
+ Wrapper_print(getf,magic);
- default :
- Printf(stderr,"%s:%d. Unable to link with datatype %s (ignored).\n", Getfile(node), Getline(node), SwigType_str(t,0));
- return;
+ 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";
}
- Printf(setf," return 1;\n}\n");
- Replace(setf,"$name",iname, DOH_REPLACE_ANY);
- Printf(magic,"%s", setf);
+ /* 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);
- }
-
- /* Now write a function to evaluate the variable */
-
- Printf(getf,"SWIGCLASS_STATIC int %s(SV *sv, MAGIC *mg) {\n", val_name);
- Printv(getf,
- tab4, "MAGIC_PPERL\n",
- tab4, "mg = mg;\n",
- 0);
-
- if ((tm = Swig_typemap_lookup((char*)"varout",t,(char*)"",name, (char*)"sv",0))) {
- Printf(getf,"%s\n", tm);
- } else if ((tm = Swig_typemap_lookup((char*)"out",t,(char*)"",name,(char*)"sv",0))) {
- Printf(getf,"%s\n", tm);
- } else {
- switch(SwigType_type(t)) {
-
- case T_INT : case T_BOOL: case T_UINT:
- case T_SHORT : case T_USHORT:
- case T_LONG : case T_ULONG:
- case T_UCHAR: case T_SCHAR:
- Printv(getf,tab4, "sv_setiv(sv, (IV) ", name, ");\n", 0);
- Printv(vinit, tab4, "sv_setiv(sv,(IV)", name, ");\n",0);
- break;
- case T_DOUBLE :
- case T_FLOAT :
- Printv(getf, tab4,"sv_setnv(sv, (double) ", name, ");\n", 0);
- Printv(vinit, tab4, "sv_setnv(sv,(double)", name, ");\n",0);
- break;
- case T_CHAR :
- Wrapper_add_local(getf,"_ptemp","char _ptemp[2]");
- Printv(getf,
- tab4, "_ptemp[0] = ", name, ";\n",
- tab4, "_ptemp[1] = 0;\n",
- tab4, "sv_setpv((SV*) sv, _ptemp);\n",
- 0);
- break;
- case T_USER:
- SwigType_add_pointer(t);
- Printv(getf,
- tab4, "rsv = SvRV(sv);\n",
- tab4, "sv_setiv(rsv,(IV) &", name, ");\n",
- 0);
-
- Wrapper_add_local(getf,"rsv","SV *rsv");
- Printv(vinit, tab4, "SWIG_MakePtr(sv, (void *) &", name, ",SWIGTYPE", SwigType_manglestr(t), ");\n",0);
- SwigType_del_pointer(t);
-
- break;
-
- case T_STRING:
- Printv(getf, tab4, "sv_setpv((SV*) sv, ", name, ");\n", 0);
- break;
-
- case T_ARRAY:
- {
- SwigType *aop;
- SwigType *ta = Copy(t);
- aop = SwigType_pop(ta);
- if (SwigType_type(ta) == T_CHAR) {
- Printv(getf, "sv_setpv((SV*)sv, ", name, ");\n", 0);
- Delete(ta);
- Delete(aop);
- break;
- }
- Delete(ta);
- Delete(aop);
- }
- /* No break here is intentional */
- case T_POINTER: case T_REFERENCE:
- Printv(getf,
- tab4, "rsv = SvRV(sv);\n",
- tab4, "sv_setiv(rsv,(IV) ", name, ");\n",
- 0);
-
- Wrapper_add_local(getf,"rsv","SV *rsv");
- Printv(vinit, tab4, "SWIG_MakePtr(sv,(void *) 1, SWIGTYPE", SwigType_manglestr(t), ");\n",0);
- break;
-
- default :
- break;
+ } else {
+ Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS ", set_name, ", MAGIC_CLASS ", val_name, ",", tt, " },\n",NIL);
}
- }
- Printf(getf," return 1;\n}\n");
- Replace(getf,"$name",iname, DOH_REPLACE_ANY);
- Printf(magic,"%s", getf);
-
- /* Now add symbol to the PERL interpreter */
- if ((ReadOnly) || (!setable)) {
- Printv(vinit, tab4, "swig_create_magic(sv,\"", package, "::", iname, "\",MAGIC_CAST MAGIC_CLASS swig_magic_readonly, MAGIC_CAST MAGIC_CLASS ", val_name, ");\n",0);
- } else {
- Printv(vinit, tab4, "swig_create_magic(sv,\"", package, "::", iname, "\", MAGIC_CAST MAGIC_CLASS ", set_name, ", MAGIC_CAST MAGIC_CLASS ", val_name, ");\n",0);
- }
-
- /* If we're blessed, try to figure out what to do with the variable
+ /* 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), "\", $",
- package, "::", iname, ";\n",
- "$", iname, "= \\%__", iname, "_hash;\n",
- "bless $", iname, ", ", is_shadow(t), ";\n",
- 0);
- } else {
- Printv(var_stubs, "*", iname, " = *", package, "::", iname, ";\n", 0);
+ 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 ", name);
+ Printf(exported,"$%s ", iname);
+
+ DelWrapper(setf);
+ DelWrapper(getf);
+ Delete(set_name);
+ Delete(val_name);
+ return SWIG_OK;
}
- Delete(setf);
- Delete(getf);
-}
-/* -----------------------------------------------------------------------------
- * PERL5::constant()
- * ----------------------------------------------------------------------------- */
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
-/* Functions used to create constants */
-
-static const char *setiv = "#ifndef PERL_OBJECT\
-\n#define swig_setiv(a,b) _swig_setiv(a,b)\
-\nstatic void _swig_setiv(char *name, long value) { \
-\n#else\
-\n#define swig_setiv(a,b) _swig_setiv(pPerl,a,b)\
-\nstatic void _swig_setiv(CPerlObj *pPerl, char *name, long value) { \
-\n#endif\
-\n SV *sv; \
-\n sv = perl_get_sv(name,TRUE | 0x2);\
-\n sv_setiv(sv, (IV) value);\
-\n SvREADONLY_on(sv);\
-\n}\n";
-
-static const char *setnv = "#ifndef PERL_OBJECT\
-\n#define swig_setnv(a,b) _swig_setnv(a,b)\
-\nstatic void _swig_setnv(char *name, double value) { \
-\n#else\
-\n#define swig_setnv(a,b) _swig_setnv(pPerl,a,b)\
-\nstatic void _swig_setnv(CPerlObj *pPerl, char *name, double value) { \
-\n#endif\
-\n SV *sv; \
-\n sv = perl_get_sv(name,TRUE | 0x2);\
-\n sv_setnv(sv, value);\
-\n SvREADONLY_on(sv);\
-\n}\n";
-
-static const char *setpv = "#ifndef PERL_OBJECT\
-\n#define swig_setpv(a,b) _swig_setpv(a,b)\
-\nstatic void _swig_setpv(char *name, char *value) { \
-\n#else\
-\n#define swig_setpv(a,b) _swig_setpv(pPerl,a,b)\
-\nstatic void _swig_setpv(CPerlObj *pPerl, char *name, char *value) { \
-\n#endif\
-\n SV *sv; \
-\n sv = perl_get_sv(name,TRUE | 0x2);\
-\n sv_setpv(sv, value);\
-\n SvREADONLY_on(sv);\
-\n}\n";
-
-static const char *setrv = "#ifndef PERL_OBJECT\
-\n#define swig_setrv(a,b,c) _swig_setrv(a,b,c)\
-\nstatic void _swig_setrv(char *name, void *value, char *type) { \
-\n#else\
-\n#define swig_setrv(a,b,c) _swig_setrv(pPerl,a,b,c)\
-\nstatic void _swig_setrv(CPerlObj *pPerl, char *name, void *value, char *type) { \
-\n#endif\
-\n SV *sv; \
-\n sv = perl_get_sv(name,TRUE | 0x2);\
-\n sv_setref_pv(sv, type, value);\
-\n SvREADONLY_on(sv);\
-\n}\n";
-
-void
-PERL5::constant(DOH *node)
- {
- char *name;
- SwigType *type;
- char *value;
- char *tm;
- static int have_int_func = 0;
- static int have_double_func = 0;
- static int have_char_func = 0;
- static int have_ref_func = 0;
-
- name = GetChar(node,"name");
- type = Getattr(node,"type");
- value = GetChar(node,"value");
-
- if ((tm = Swig_typemap_lookup((char*)"const",type,name,value,name,0))) {
- Printf(f_init,"%s\n",tm);
- } else {
- switch(SwigType_type(type)) {
- case T_INT: case T_UINT: case T_BOOL:
- case T_SHORT: case T_USHORT:
- case T_LONG: case T_ULONG:
- case T_SCHAR: case T_UCHAR:
- if (!have_int_func) {
- Printf(f_header,"%s\n",setiv);
- have_int_func = 1;
- }
- Printv(vinit, tab4, "swig_setiv(\"", package, "::", name, "\", (long) ", value, ");\n",0);
- break;
- case T_DOUBLE:
- case T_FLOAT:
- if (!have_double_func) {
- Printf(f_header,"%s\n",setnv);
- have_double_func = 1;
- }
- Printv(vinit, tab4, "swig_setnv(\"", package, "::", name, "\", (double) (", value, "));\n",0);
- break;
- case T_CHAR :
- if (!have_char_func) {
- Printf(f_header,"%s\n",setpv);
- have_char_func = 1;
- }
- Printf(vinit," swig_setpv(\"%s::%s\",\"%s\");\n", package, name, value);
+ 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;
- break;
- case T_STRING:
- if (!have_char_func) {
- Printf(f_header,"%s\n",setpv);
- have_char_func = 1;
- }
- Printf(vinit," swig_setpv(\"%s::%s\",\"%s\");\n", package, name, value);
- break;
-
- case T_POINTER: case T_ARRAY: case T_REFERENCE:
- if (!have_ref_func) {
- Printf(f_header,"%s\n",setrv);
- have_ref_func = 1;
- }
- Printv(vinit, tab4, "swig_setrv(\"", package, "::", name, "\", (void *) ", value, ", \"",
- SwigType_manglestr(type), "\");\n", 0);
- break;
+ if (!addSymbol(iname,n)) return SWIG_ERROR;
- default:
- Printf(stderr,"%s:%d. Unsupported constant value.\n", Getfile(node), Getline(node));
- break;
+ /* 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 (blessed) {
- if (is_shadow(type)) {
- Printv(var_stubs,
- "\nmy %__", name, "_hash;\n",
- "tie %__", name, "_hash,\"", is_shadow(type), "\", $",
- package, "::", name, ";\n",
- "$", name, "= \\%__", name, "_hash;\n",
- "bless $", name, ", ", is_shadow(type), ";\n",
- 0);
+ 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 {
- Printv(var_stubs, "*",name," = *", package, "::", name, ";\n", 0);
+ 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;
}
- if (export_all)
- Printf(exported,"$%s ",name);
-}
-/* -----------------------------------------------------------------------------
- * PERL5::usage_func()
- * ----------------------------------------------------------------------------- */
-char *
-PERL5::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 = Gettype(p);
- String *pn = Getname(p);
- if (!Getignore(p)) {
- /* 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));
+ /* ------------------------------------------------------------
+ * 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);
}
- i++;
- p = Getnext(p);
- if (p)
- if (!Getignore(p))
- Putc(',',temp);
- } else {
- p = Getnext(p);
- if (p)
- if ((i>0) && (!Getignore(p)))
- Putc(',',temp);
}
+ Printf(temp,");");
+ return Char(temp);
}
- Printf(temp,");");
- return Char(temp);
-}
-/* -----------------------------------------------------------------------------
- * PERL5::nativefunction()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::nativefunction(DOH *node) {
- char *name, *funcname;
- name = GetChar(node,"scriptname");
- funcname = GetChar(node,"name");
- Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package,name, funcname);
- if (export_all)
- Printf(exported,"%s ",name);
- if (blessed) {
- Printv(func_stubs,"*", name, " = *", package, "::", name, ";\n", 0);
- }
-}
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int nativeWrapper(Node *n) {
+ String *name = Getattr(n,"sym:name");
+ String *funcname = Getattr(n,"wrap:name");
-/****************************************************************************
- *** 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.
- ***
- *** 6. Object ownership is maintained by having a hash table
- *** within in each package called "this". It is unlikely
- *** that C++ program will use this so it's a somewhat
- *** safe variable name.
- ***
- ****************************************************************************/
+ if (!addSymbol(funcname,n)) return SWIG_ERROR;
-/* -----------------------------------------------------------------------------
- * PERL5::cpp_open_class()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::cpp_open_class(DOH *node) {
+ 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;
+ }
- this->Language::cpp_open_class(node);
+ /****************************************************************************
+ *** 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.
+ ***
+ ****************************************************************************/
- char *classname = GetChar(node,"name");
- char *rname = GetChar(node,"scriptname");
- char *ctype = GetChar(node,"classtype");
-
- if (blessed) {
- have_constructor = 0;
- have_destructor = 0;
- have_data_members = 0;
-
- Delete(class_name); class_name = 0;
- Delete(class_type); class_type =0;
- Delete(real_classname); real_classname = 0;
- Delete(base_class); base_class = 0;
- Delete(fullclassname); fullclassname = 0;
-
- /* If the class is being renamed to something else, use the renaming */
- if (rname) {
- class_name = NewString(rname);
- class_renamed = 1;
- } else {
- class_name = NewString(classname);
- class_renamed = 0;
+
+ 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;
}
- /* Use the fully qualified name of the Perl class */
- if (!compat) {
- fullclassname = NewStringf("%s::%s",realpackage,class_name);
+ /* Do some work on the class name */
+ actualpackage = Getattr(clsmodule,"name");
+ if ((!compat) && (!Strchr(symname,':'))) {
+ fullname = NewStringf("%s::%s",actualpackage,symname);
} else {
- fullclassname = NewString(class_name);
+ fullname = NewString(symname);
}
- real_classname = NewString(classname);
- if (base_class) Delete(base_class);
- base_class = 0;
- class_type = NewString(ctype);
- pcode = NewString("");
- blessedmembers = NewString("");
- member_keys = NewString("");
-
- /* Add some symbols to the hash tables */
- Hash *nnode = NewHash();
- Setattr(nnode,"name", classname);
- Setattr(nnode,"scriptname", fullclassname);
- Setattr(nnode,"classtype", ctype);
- cpp_class_decl(nnode);
+ Setattr(n,"perl5:proxy", fullname);
}
-}
-
-/* -----------------------------------------------------------------------------
- * PERL5::cpp_close_class()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::cpp_close_class() {
-
- if (blessed) {
- Printv(pm,
- "\n############# Class : ", fullclassname, " ##############\n",
- "\npackage ", fullclassname, ";\n",
- 0);
-
- /* If we are inheriting from a base class, set that up */
-
- if (Cmp(class_name,realpackage))
- Printv(pm, "@ISA = qw( ",realpackage, 0);
- else
- Printv(pm, "@ISA = qw( ", 0);
-
- if (base_class) {
- Printv(pm, " ", base_class, 0);
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+ virtual int classDeclaration(Node *n) {
+ /* Do some work on the class name */
+ if (blessed) {
+ setclassname(n);
+ Append(classlist,n);
}
- Printf(pm, " );\n");
+ return Language::classDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
- /* Dump out a hash table containing the pointers that we own */
+ virtual int classHandler(Node *n) {
- Printf(pm, "%%OWNER = ();\n");
- if (have_data_members) {
- Printv(pm,
- "%BLESSEDMEMBERS = (\n", blessedmembers, ");\n\n",
- 0);
- }
- if (have_data_members || have_destructor)
- Printf(pm, "%%ITERATORS = ();\n");
+ if (blessed) {
+ have_constructor = 0;
+ have_operators = 0;
+ have_destructor = 0;
+ have_data_members = 0;
+ operators = NewHash();
+ class_name = Getattr(n,"sym:name");
- /* Dump out the package methods */
+ if (!addSymbol(class_name,n)) return SWIG_ERROR;
- Printv(pm,pcode,0);
- Delete(pcode);
-
- /* Output methods for managing ownership */
+ /* 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("");
+ }
- 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",
- 0);
+ /* Emit all of the members */
+ Language::classHandler(n);
- /* Only output the following methods if a class has member data */
- if (have_data_members) {
+ /* 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);
- /* 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 = \"", package, "::", Swig_name_get(Swig_name_member(class_name,(char*)"${field}")), "\";\n",
- tab4, "my $val = &$member_func($self);\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",
- 0);
+ "\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");
- /* Output a STORE method. This is also common to all classes (might move to base class) */
+ /* Dump out the package methods */
- Printv(pm,
- "sub STORE {\n",
- tab4, "my ($self,$field,$newval) = @_;\n",
- tab4, "my $member_func = \"", package, "::", Swig_name_set(Swig_name_member(class_name,(char*)"${field}")), "\";\n",
- tab4, "if (exists $BLESSEDMEMBERS{$field}) {\n",
- tab8, "&$member_func($self,tied(%{$newval}));\n",
- tab4, "} else {\n",
- tab8, "&$member_func($self,$newval);\n",
- tab4, "}\n",
- "}\n\n",
- 0);
+ Printv(pm,pcode,NIL);
+ Delete(pcode);
- /* Output a FIRSTKEY method. This is to allow iteration over a structure's keys. */
+ /* Output methods for managing ownership */
Printv(pm,
- "sub FIRSTKEY {\n",
+ "sub DISOWN {\n",
tab4, "my $self = shift;\n",
- tab4, "$ITERATORS{$self} = [", member_keys, "];\n",
- tab4, "my $first = shift @{$ITERATORS{$self}};\n",
- tab4, "return $first;\n",
- "}\n\n",
- 0);
-
- /* Output a NEXTKEY method. This is the iterator so that each and keys works */
-
- Printv(pm,
- "sub NEXTKEY {\n",
+ tab4, "my $ptr = tied(%$self);\n",
+ tab4, "delete $OWNER{$ptr};\n",
+ tab4, "};\n\n",
+ "sub ACQUIRE {\n",
tab4, "my $self = shift;\n",
- tab4, "$nelem = scalar @{$ITERATORS{$self}};\n",
- tab4, "if ($nelem > 0) {\n",
- tab8, "my $member = shift @{$ITERATORS{$self}};\n",
- tab8, "return $member;\n",
- tab4, "} else {\n",
- tab8, "$ITERATORS{$self} = [", member_keys, "];\n",
- tab8, "return ();\n",
- tab4, "}\n",
- "}\n\n",
- 0);
- }
- }
-}
-
-/* -----------------------------------------------------------------------------
- * PERL5::cpp_member_func()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::cpp_memberfunction(DOH *node) {
- char *name, *iname;
- SwigType *t;
- ParmList *l;
- String *func;
- char *realname;
- Parm *p;
- int i;
- String *cname;
- int pcount, numopt;
- char *tm;
- int need_wrapper = 0;
-
- member_func = 1;
- this->Language::cpp_memberfunction(node);
- member_func = 0;
-
- if (!blessed) return;
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
- l = Getattr(node,"parms");
-
- func = NewString("");
- cname = NewString("perl5:");
-
- /* Now emit a Perl wrapper function around our member function, we might need
- to patch up some arguments along the way */
-
- if (!iname)
- realname = name;
- else
- realname = iname;
-
- Printf(cname,"%s::%s",class_name,realname);
- if (Getattr(symbols,cname)) {
- return; /* Forget it, we saw this already */
- }
- Setattr(symbols,cname,cname);
-
- Printv(func,
- "sub ", realname, " {\n",
- tab4, "my @args = @_;\n",
- 0);
-
- /* Now we have to go through and patch up the argument list. If any
- arguments to our function correspond to other Perl objects, we
- need to extract them from a tied-hash table object. */
-
- p = l;
- pcount = ParmList_len(l);
- numopt = check_numopt(l);
- i = 1;
- while(p) {
- SwigType *pt = Gettype(p);
- if (!Getignore(p)) {
- char sourceNtarget[512];
- sprintf(sourceNtarget, "$args[%d]", i);
-
- if ((tm = Swig_typemap_lookup((char*)"perl5in",pt,(char*)"",sourceNtarget,sourceNtarget,0))) {
- Printf(func,"%s\n",tm);
- need_wrapper = 1;
+ 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);
}
- i++;
- }
- p = Getnext(p);
- }
-
- /* Okay. We've made argument adjustments, now call into the package */
-
- Printv(func,
- tab4, "my $result = ", package, "::", Swig_name_member(class_name,realname),
- "(@args);\n",
- 0);
-
- /* 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 ((tm = Swig_typemap_lookup((char*)"perl5out",t,(char*)"",name,(char*)"sv",0))) {
- Printv(func,
- tm, "\n",
- tab4,"return $result;\n",
- "}\n",
- 0);
- need_wrapper = 1;
-
- } else if (is_shadow(t)) {
-
- Printv(func,tab4, "return undef if (!defined($result));\n", 0);
-
- /* If we're returning an object by value, put it's reference
- into our local hash table */
-
- if (!SwigType_ispointer(t) || NewObject) {
- Printv(func, tab4, "$", is_shadow(t), "::OWNER{$result} = 1; \n", 0);
+ Delete(operators); operators = 0;
}
-
- /* 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",
- 0);
-
- 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", 0);
+ return SWIG_OK;
}
- if (need_wrapper) {
- Printv(pcode,func,0);
- } else {
- Printv(pcode,"*",realname," = *", package, "::", Swig_name_member(class_name,realname), ";\n", 0);
- }
- Delete(func);
- Delete(cname);
-}
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
-/* -----------------------------------------------------------------------------
- * PERL5::cpp_variable()
- *
- * 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 memberfunctionHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
-void PERL5::cpp_variable(DOH *node) {
- char *name, *iname;
- SwigType *t;
- char *realname;
- String *cname;
+ String *func;
+ int need_wrapper = 0;
- cname = NewString("perl5:");
-
- /* Emit a pair of get/set functions for the variable */
-
- member_func = 1;
- this->Language::cpp_variable(node);
- member_func = 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);
+ }
- if (blessed) {
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
+ 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 (iname) realname = iname;
- else realname = name;
+ if (is_shadow(t)) {
+ Printv(func,tab4, "return undef if (!defined($result));\n", NIL);
- Printf(cname,"%s::%s", class_name, realname);
- if (Getattr(symbols,cname)) {
- Delete(cname);
- return;
+ /* 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);
}
- Setattr(symbols,cname,cname);
-
- /* Store name of key for future reference */
- Printf(member_keys,"'%s', ", realname);
-
- /* 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, realname, " => '", is_shadow(t), "',\n",
- 0);
-
- }
+ return SWIG_OK;
}
- have_data_members++;
- Delete(cname);
-}
-
-/* -----------------------------------------------------------------------------
- * PERL5::cpp_constructor()
- *
- * 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
- * ----------------------------------------------------------------------------- */
-void
-PERL5::cpp_constructor(DOH *node) {
- char *name, *iname;
- ParmList *l;
- Parm *p;
- int i;
- String *realname;
- String *cname;
-
- cname = NewString("perl5:constructor:");
-
- /* Emit an old-style constructor for this class */
-
- member_func = 1;
- this->Language::cpp_constructor(node);
-
- if (blessed) {
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- l = Getattr(node,"parms");
- if (iname)
- realname = iname;
- else {
- if (class_renamed) realname = class_name;
- else realname = class_name;
- }
- Printf(cname,"%s::%s", class_name, realname);
- if (Getattr(symbols,cname)) {
- Delete(cname);
- return;
- }
- Setattr(symbols,cname, cname);
- if ((Cmp(realname,class_name) == 0)) {
+ /* ------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------- */
- /* Emit a blessed constructor */
+ virtual int membervariableHandler(Node *n) {
- Printf(pcode, "sub new {\n");
+ String *symname = Getattr(n,"sym:name");
+ SwigType *t = Getattr(n,"type");
- } else {
+ /* Emit a pair of get/set functions for the variable */
- /* Constructor doesn't match classname so we'll just use the normal name */
+ member_func = 1;
+ Language::membervariableHandler(n);
+ member_func = 0;
- Printv(pcode, "sub ", Swig_name_construct(realname), " () {\n", 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);
- Printv(pcode, tab4, "my $self = shift;\n",
- tab4, "my @args = @_;\n", 0);
+ /* Now we need to generate a little Perl code for this */
- /* We are going to need to patch up arguments here if necessary
- * Now we have to go through and patch up the argument list. If any
- * arguments to our function correspond to other Perl objects, we
- * need to extract them from a tied-hash table object. */
+ if (is_shadow(t)) {
- p = l;
- i = 0;
- while(p) {
- SwigType *pt = Gettype(p);
+ /* 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);
- if (is_shadow(pt)) {
- /* Yep. This smells alot like an object, patch up the arguments */
- Printf(pcode, " $args[%d] = tied(%%{$args[%d]});\n", i, i);
}
- p = Getnext(p);
- i++;
}
-
- Printv(pcode,
- tab4, "$self = ", package, "::", Swig_name_construct(realname), "(@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,\"", fullclassname, "\";\n",
- "}\n\n",
- 0);
-
- have_constructor = 1;
-
+ have_data_members++;
+ return SWIG_OK;
}
- Delete(cname);
- member_func = 0;
-}
-/* -----------------------------------------------------------------------------
- * PERL5::cpp_destructor()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::cpp_destructor(DOH *node) {
- String *realname;
- char *name, *newname;
- member_func = 1;
- this->Language::cpp_destructor(node);
-
- if (blessed) {
- name = GetChar(node,"name");
- newname = GetChar(node,"scriptname");
-
- if (newname) realname = newname;
- else {
- if (class_renamed) realname = class_name;
- else realname = name;
- }
+ /* ------------------------------------------------------------
+ * 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
+ * ------------------------------------------------------------ */
- /* Emit a destructor for this object*/
+ virtual int constructorHandler(Node *n) {
- Printv(pcode,
- "sub DESTROY {\n",
- tab4, "return unless $_[0]->isa('HASH');\n",
- tab4, "my $self = tied(%{$_[0]});\n",
- tab4, "delete $ITERATORS{$self};\n",
- tab4, "if (exists $OWNER{$self}) {\n",
- tab8, package, "::", Swig_name_destroy(realname), "($self);\n",
- tab8, "delete $OWNER{$self};\n",
- tab4, "}\n}\n\n",
- 0);
+ String *symname = Getattr(n,"sym:name");
- have_destructor = 1;
+ member_func = 1;
+ Language::constructorHandler(n);
- }
- member_func = 0;
-}
+ 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);
+ }
-/* -----------------------------------------------------------------------------
- * PERL5::cpp_staticfunction()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::cpp_staticfunction(DOH *node) {
- char *name, *iname;
- this->Language::cpp_staticfunction(node);
- char *realname;
-
- if (blessed) {
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- if (iname) realname = name;
- else realname = iname;
-
- Printv(pcode, "*", realname, " = *", realpackage, "::", Swig_name_member(class_name,realname), ";\n", 0);
- }
-}
+ 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);
-/* -----------------------------------------------------------------------------
- * PERL5::cpp_inherit()
- * ------------------------------------------------------------------------------ */
-void
-PERL5::cpp_inherit(List *bases) {
- String *base;
- char *bc;
- int have_first = 0;
- if (!blessed) {
- this->Language::cpp_inherit(bases);
- return;
+ have_constructor = 1;
+ }
+ member_func = 0;
+ return SWIG_OK;
}
- /* Inherit variables and constants from base classes, but not
- functions (since Perl can handle that okay). */
-
- this->Language::cpp_inherit(bases);
-
- /* Now tell the Perl5 module that we're inheriting from base classes */
-
- base_class = NewString("");
- for (base = Firstitem(bases); base; base = Nextitem(bases)) {
- /* See if this is a class we know about */
- String *b = NewString(base);
- bc = Char(is_shadow(b));
- Delete(b);
- if (bc) {
- if (have_first) Putc(' ', base_class);
- Printf(base_class,bc);
- have_first = 1;
+ /* ------------------------------------------------------------
+ * 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;
}
- if (!have_first) {
- Delete(base_class);
- base_class = 0;
- }
-}
-/* -----------------------------------------------------------------------------
- * PERL5::cpp_constant()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::cpp_constant(DOH *node) {
- char *name, *iname;
- String *realname;
- int oldblessed = blessed;
- char cname[256];
-
- /* Create a normal constant */
- blessed = 0;
- this->Language::cpp_constant(node);
- blessed = oldblessed;
-
- if (blessed) {
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- if (!iname)
- realname = name;
- else
- realname = iname;
-
- sprintf(cname,"%s::%s",Char(class_name),Char(realname));
- if (Getattr(symbols, cname)) {
- return;
+ /* ------------------------------------------------------------
+ * 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);
+ }
}
- Setattr(symbols, cname,cname);
-
- /* Create a symbol table entry for it */
- Printv(pcode, "*", realname, " = *", package, "::", Swig_name_member(class_name,realname), ";\n", 0);
+ return SWIG_OK;
}
-}
-/* -----------------------------------------------------------------------------
- * PERL5::cpp_class_decl()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::cpp_class_decl(DOH *node) {
- String *name = Getname(node);
- String *rename = Getattr(node,"scriptname");
- String *ctype = Getattr(node,"classtype");
- String *stype;
- if (blessed) {
- stype = NewString(name);
- SwigType_add_pointer(stype);
- Setattr(classes,stype,rename);
- Delete(stype);
- if (Len(ctype) > 0) {
- stype = NewStringf("%s %s",ctype,name);
- SwigType_add_pointer(stype);
- Setattr(classes,stype,rename);
- Delete(stype);
+ /* ------------------------------------------------------------
+ * 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;
}
-}
-
-/* -----------------------------------------------------------------------------
- * PERL5::add_typedef()
- * ----------------------------------------------------------------------------- */
-void
-PERL5::add_typedef(SwigType *t, String *name) {
-
- if (!blessed) return;
- if (is_shadow(t)) {
- DOH *node = NewHash();
- Setattr(node,"name",name);
- Setattr(node,"scriptname", is_shadow(t));
- Setattr(node,"classtype","");
- cpp_class_decl(node);
+
+ /* ------------------------------------------------------------
+ * 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;
}
-}
-
-/* -----------------------------------------------------------------------------
- * PERL5::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
- * ----------------------------------------------------------------------------- */
-
-void PERL5::pragma(DOH *node) {
- String *name = Getattr(node,"name");
- String *value = Getattr(node,"value");
- if (Cmp(name,"code") == 0) {
- /* Dump the value string into the .pm file */
- if (value) {
- Printf(pragma_include, "%s\n", value);
- }
- } else if (Cmp(name,"include") == 0) {
- /* Include a file into the .pm file */
- if (value) {
- FILE *f = Swig_open(value);
- if (!f) {
- Printf(stderr,"%s:%d. Unable to locate file %s\n", Getfile(node), Getline(node),value);
- } else {
- char buffer[4096];
- while (fgets(buffer,4095,f)) {
- Printf(pragma_include,"%s",buffer);
+ /* ------------------------------------------------------------
+ * 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/Modules1.1/perl5.h b/Source/Modules1.1/perl5.h
deleted file mode 100644
index 90b35f8e6..000000000
--- a/Source/Modules1.1/perl5.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
- * 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.
- ****************************************************************************/
-
-/**************************************************************************
- * class PERL5
- *
- * A Perl 5 implementation
- **************************************************************************/
-
-class PERL5 : public Language {
-private:
- char *usage_func(char *, SwigType *, ParmList *);
-public :
- virtual void parse_args(int, char *argv[]);
- virtual void initialize(String *modname);
- virtual void function(DOH *node);
- virtual void variable(DOH *node);
- virtual void constant(DOH *node);
- virtual void close(void);
- virtual void nativefunction(DOH *);
- virtual void create_command(String *, String *);
-
- // Support for blessed perl thingies....
-
- virtual void cpp_open_class(DOH *);
- virtual void cpp_close_class();
- virtual void cpp_memberfunction(DOH *);
- virtual void cpp_staticfunction(DOH *);
- virtual void cpp_variable(DOH *);
- virtual void cpp_constructor(DOH *);
- virtual void cpp_destructor(DOH *);
- virtual void cpp_inherit(List *bases);
- virtual void cpp_constant(DOH *);
- virtual void cpp_class_decl(DOH *);
- virtual void add_typedef(SwigType *t, String *name);
- virtual void pragma(DOH *node);
- virtual void import(String *filename);
-};
-
-
-
diff --git a/Source/Modules1.1/php4.cxx b/Source/Modules1.1/php4.cxx
new file mode 100644
index 000000000..051e24601
--- /dev/null
+++ b/Source/Modules1.1/php4.cxx
@@ -0,0 +1,2113 @@
+/*
+ * PHP4 Support
+ *
+ * Richard Palmer
+ * richard@magicality.org
+ * Nov 2001
+ *
+ * Portions copyright Sun Microsystems (c) 2001
+ * Tim Hockin <thockin@sun.com>
+ *
+ * Portions copyright Ananova Ltd (c) 2002
+ * Sam Liddicott <sam@ananova.com>
+ *
+ */
+
+char cvsroot_php4_cxx[] = "$Header$";
+
+#include <ctype.h>
+
+#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_<mangled> 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, "<?php\n\n");
+
+ Swig_banner(f_phpcode);
+
+ Printf(f_phpcode,
+ "global $%s_LOADED__;\n"
+ "if ($%s_LOADED__) return;\n"
+ "$%s_LOADED__ = true;\n\n"
+ "/* if our extension has not been loaded, do what we can */\n"
+ "if (!extension_loaded(\"php_%s\")) {\n"
+ " if (!dl(\"php_%s\")) return;\n"
+ "}\n\n", cap_module, cap_module, cap_module, module, dlname);
+
+
+ /* sub-sections of the php file */
+ pragma_code = NewString("");
+ pragma_incl = NewString("");
+
+ /* Initialize the rest of the module */
+
+ f_php = NewWrapper();// wots this used for now?
+
+ /* start the header section */
+ Printf(s_header, php_header);
+ Printf(s_header,
+ "#define SWIG_init init%s\n\n"
+ "#define SWIG_name \"%s\"\n"
+ "#ifdef HAVE_CONFIG_H\n"
+ "#include \"config.h\"\n"
+ "#endif\n\n"
+ "#ifdef __cplusplus\n"
+ "extern \"C\" {\n"
+ "#endif\n"
+ "#include \"php.h\"\n"
+ "#include \"php_ini.h\"\n"
+ "#include \"ext/standard/info.h\"\n"
+ "#include \"php_%s.h\"\n"
+ "#ifdef __cplusplus\n"
+ "}\n"
+ "#endif\n\n",
+ module, module, module);
+
+ /* Create the .h file too */
+ filen = NewString("");
+ Printv(filen, Swig_file_dirname(outfile), "php_", module, ".h", NIL);
+ f_h = NewFile(filen, "w");
+ if (!f_h) {
+ Printf(stderr,"Unable to open %s\n", filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Swig_banner(f_h);
+ Printf(f_h, php_header);
+
+ Printf(f_h, "\n\n"
+ "#ifndef PHP_%s_H\n"
+ "#define PHP_%s_H\n\n"
+ "extern zend_module_entry %s_module_entry;\n"
+ "#define phpext_%s_ptr &%s_module_entry\n\n"
+ "#ifdef PHP_WIN32\n"
+ "# define PHP_%s_API __declspec(dllexport)\n"
+ "#else\n"
+ "# define PHP_%s_API\n"
+ "#endif\n\n"
+ "PHP_MINIT_FUNCTION(%s);\n"
+ "PHP_MSHUTDOWN_FUNCTION(%s);\n"
+ "PHP_RINIT_FUNCTION(%s);\n"
+ "PHP_RSHUTDOWN_FUNCTION(%s);\n"
+ "PHP_MINFO_FUNCTION(%s);\n\n",
+ cap_module, cap_module, module, module, module, cap_module, cap_module,
+ module, module, module, module, module);
+
+ /* start the function entry section */
+ s_entry = NewString("/* entry subsection */\n");
+ /* holds all the per-class function entry sections */
+ all_cs_entry = NewString("/* class entry subsection */\n");
+ cs_entry = NULL;
+
+ Printf(s_entry,"/* Every non-class user visible function must have an entry here */\n");
+ Printf(s_entry,"function_entry %s_functions[] = {\n", module);
+
+ /* start the init section */
+ if (gen_extra)
+ Printf(s_init,"#ifdef COMPILE_DL_%s\n", cap_module);
+ Printf(s_init,
+ "#ifdef __cplusplus\n"
+ "extern \"C\" {\n"
+ "#endif\n"
+ "ZEND_GET_MODULE(%s)\n"
+ "#ifdef __cplusplus\n"
+ "}\n"
+ "#endif\n\n",
+ module);
+ if (gen_extra)
+ Printf(s_init,"#endif\n\n");
+
+ Printf(s_init,
+ "PHP_MSHUTDOWN_FUNCTION(%s)\n{\n"
+ " return SUCCESS;\n"
+ "}\n",
+ module);
+
+ /* We have to register the constants before they are (possibly) used
+ * by the pointer typemaps. This all needs re-arranging really as
+ * things are being called in the wrong order
+ */
+
+ Printf(s_init,"PHP_MINIT_FUNCTION(%s)\n{\n", module);
+ Printf(s_init,
+ " int i;\n"
+ " for (i = 0; swig_types_initial[i]; i++) {\n"
+ " swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n"
+ " }\n");
+ /* Emit all of the code */
+ Language::top(n);
+
+ SwigPHP_emit_resource_registrations();
+// Printv(s_init,s_resourcetypes,NIL);
+ /* We need this after all classes written out by ::top */
+ Printf(s_oinit, "CG(active_class_entry) = NULL;\n");
+ Printf(s_oinit, "/* end oinit subsection */\n");
+ Printf(s_init, "%s\n", s_oinit);
+
+ /* Constants generated during top call */
+ // But save them for RINIT
+ Printf(s_cinit, "/* end cinit subsection */\n");
+
+ /* finish our init section which will have been used by class wrappers */
+ Printf(s_vinit, "/* end vinit subsection */\n");
+
+ Printf(s_init, " return SUCCESS;\n");
+ Printf(s_init,"}\n");
+
+ // Now do REQUEST init which holds cinit and vinit
+ Printf(s_init,
+ "PHP_RINIT_FUNCTION(%s)\n{\n",
+ module);
+
+ Printf(s_init, "%s\n", s_cinit);
+ Clear(s_cinit);
+
+ Printf(s_init, "%s\n", s_vinit);
+ Clear(s_vinit);
+
+ Printf(s_init,
+ " return SUCCESS;\n"
+ "}\n");
+
+ Delete(s_cinit);
+ Delete(s_vinit);
+
+ Printf(s_init,
+ "PHP_RSHUTDOWN_FUNCTION(%s)\n{\n"
+ " return SUCCESS;\n"
+ "}\n",
+ module);
+
+ Printf(s_init,
+ "PHP_MINFO_FUNCTION(%s)\n{\n"
+ "%s"
+ "}\n"
+ "/* end init section */\n",
+ module, pragma_phpinfo);
+
+ /* Complete header file */
+
+ Printf(f_h,
+ "/*If you declare any globals in php_%s.h uncomment this:\n"
+ "ZEND_BEGIN_MODULE_GLOBALS(%s)\n"
+ "ZEND_END_MODULE_GLOBALS(%s)\n"
+ "*/\n",
+ module, module, module);
+
+ Printf(f_h,
+ "#ifdef ZTS\n"
+ "#define %s_D zend_%s_globals *%s_globals\n"
+ "#define %s_DC , %s_D\n"
+ "#define %s_C %s_globals\n"
+ "#define %s_CC , %s_C\n"
+ "#define %s_SG(v) (%s_globals->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<argbase)?(&this_ptr):(args[%d-argbase]))", i, i);
+ else sprintf(source, "args[%d-argbase]", i); }
+ sprintf(target, "%s", Char(Getattr(p,"lname")));
+ sprintf(argnum, "%d", i+1);
+
+ /* Check if optional */
+
+ if(i>= (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/Modules1.1/pike.cxx b/Source/Modules1.1/pike.cxx
new file mode 100644
index 000000000..bcd51763e
--- /dev/null
+++ b/Source/Modules1.1/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/Modules1.1/python.cxx b/Source/Modules1.1/python.cxx
index c58fae78a..6651ace92 100644
--- a/Source/Modules1.1/python.cxx
+++ b/Source/Modules1.1/python.cxx
@@ -9,1562 +9,1260 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_python_cxx[] = "$Header$";
-#include "swig11.h"
-#include "python.h"
+#include "swigmod.h"
+
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+
+#include <ctype.h>
+
+#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 = 0;
-static int have_defarg = 0;
-static int have_output;
+static int shadow = 1;
static int use_kw = 0;
-static int noopt = 1;
-static FILE *f_shadow;
-static Hash *hash;
-static Hash *symbols;
-static String *classes;
-static String *func;
-static String *vars;
-static String *pragma_include = 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 char *class_name;
+static String *class_name;
+static String *shadow_indent = 0;
+static int in_class = 0;
+static int classic = 0;
-static char *usage = (char *)"\
+/* 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\
- -module name - Set module name\n\
-interface name - Set the lib name\n\
-keyword - Use keyword arguments\n\
- -noopt - No optimized shadows (pre 1.5.2)\n\
- -opt - Optimized shadow classes (1.5.2 or later)\n\
- -shadow - Generate shadow classes. \n\n";
-
-/* Test to see if a type corresponds to something wrapped with a shadow class */
-static DOH *is_shadow(SwigType *t) {
- DOH *r;
- SwigType *lt = Swig_clocal_type(t);
- r = Getattr(hash,lt);
- Delete(lt);
- return r;
-}
+ -classic - Use classic classes only\n\
+ -noexcept - No automatic exception handling.\n\
+ -noproxy - Don't generate proxy classes. \n\n";
-/* -----------------------------------------------------------------------------
- * PYTHON::parse_args()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::parse_args(int argc, char *argv[]) {
- int i;
- Swig_swiglib_set("python");
+class PYTHON : public Language {
+public:
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
- for (i = 1; i < argc; i++) {
+ SWIG_library_directory("python");
+
+ for (int i = 1; i < argc; i++) {
if (argv[i]) {
- /* Added edz@bsn.com */
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) {
- shadow = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-noopt") == 0) {
- noopt = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-opt") == 0) {
- noopt = 0;
+ if (argv[i+1]) {
+ interface = NewString(argv[i+1]);
Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-keyword") == 0) {
- use_kw = 1;
+ 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);
- } else if (strcmp(argv[i],"-help") == 0) {
- fputs(usage,stderr);
+ 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();
}
- if (!global_name) global_name = NewString("cvar");
- Preprocessor_define((void *) "SWIGPYTHON", 0);
-}
-/* -----------------------------------------------------------------------------
- * PYTHON::import()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::import(String *modname) {
- if (shadow) {
- Printf(f_shadow,"\nfrom %s import *\n", modname);
- }
-}
-/* -----------------------------------------------------------------------------
- * PYTHON::add_method()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::add_method(String *name, String *function, int kw) {
- if (!kw)
- Printf(methods,"\t { \"%s\", %s, METH_VARARGS },\n", name, function);
- else
- Printf(methods,"\t { \"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS },\n", name, function);
-}
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
-/* -----------------------------------------------------------------------------
- * PYTHON::initialize()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::initialize(String *modname) {
- char filen[256];
-
- hash = NewHash();
- symbols = NewHash();
- const_code = NewString("");
- shadow_methods = NewString("");
- classes = NewString("");
- func = NewString("");
- vars = NewString("");
- pragma_include = NewString("");
- methods = NewString("");
-
- Swig_banner(f_runtime);
-
- Printf(f_runtime,"#define SWIGPYTHON\n");
- if (NoInclude)
- Printf(f_runtime,"#define SWIG_NOINCLUDE\n");
-
- if (Swig_insert_file("common.swg", f_runtime) == -1) {
- Printf(stderr,"SWIG : Fatal error. Unable to locate common.swg. (Possible installation problem).\n");
- Swig_exit (EXIT_FAILURE);
- }
- if (Swig_insert_file("python.swg", f_runtime) == -1) {
- Printf(stderr,"SWIG : Fatal error. Unable to locate python.swg. (Possible installation problem).\n");
- Swig_exit (EXIT_FAILURE);
- }
-
- if (!module) module = NewString(modname);
-
- /* If shadow classing is enabled, we're going to change the module name to "modulec" */
- if (shadow) {
-
- sprintf(filen,"%s%s.py", output_dir, Char(module));
- // If we don't have an interface then change the module name X to Xc
- if (! interface)
- Append(module,"c");
- if ((f_shadow = fopen(filen,"w")) == 0) {
- Printf(stderr,"Unable to open %s\n", filen);
- Swig_exit (EXIT_FAILURE);
+ 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);
}
- Printf(f_shadow,"# This file was created automatically by SWIG.\n");
- Printf(f_shadow,"import %s\n", interface ? interface : module);
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
- // Include some information in the code
- Printf(f_header,"\n/*-----------------------------------------------\n @(target):= %s.so\n\
- ------------------------------------------------*/\n", interface ? interface : module);
+ /* 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);
- if (!noopt)
- Printf(f_shadow,"import new\n");
- }
+ const_code = NewString("");
+ shadow_methods = NewString("");
+ methods = NewString("");
- Printf(f_header,"#define SWIG_init init%s\n\n", module);
- Printf(f_header,"#define SWIG_name \"%s\"\n", module);
-
- /* Output the start of the init function. */
- Printf(f_init,"static PyObject *SWIG_globals;\n");
- Printf(f_init,"#ifdef __cplusplus\n");
- Printf(f_init,"extern \"C\" \n");
- Printf(f_init,"#endif\n");
- Printf(f_init,"SWIGEXPORT(void) init%s(void) {\n",module);
- Printf(f_init,"PyObject *m, *d;\n");
- Printf(f_init,"int i;\n");
- Printf(f_init,"SWIG_globals = SWIG_newvarlink();\n");
- Printf(f_init,"m = Py_InitModule(\"%s\", %sMethods);\n", module, module);
- Printf(f_init,"d = PyModule_GetDict(m);\n");
- Printv(f_init,
- "for (i = 0; swig_types_initial[i]; i++) {\n",
- "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n",
- "}\n",
- 0);
-
- 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 %sMethods[] = {\n", module);
-}
+ Swig_banner(f_runtime);
-/* -----------------------------------------------------------------------------
- * PYTHON::close()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::close(void) {
- Printf(methods,"\t { NULL, NULL }\n");
- Printf(methods,"};\n");
- Printf(f_wrappers,"%s\n",methods);
- Printf(f_wrappers,"#ifdef __cplusplus\n");
- Printf(f_wrappers,"}\n");
- Printf(f_wrappers,"#endif\n");
-
- SwigType_emit_type_table(f_runtime,f_wrappers);
-
- Printf(const_code, "{0}};\n");
- Printf(f_wrappers,"%s\n",const_code);
-
- Printv(f_init, "SWIG_InstallConstants(d,swig_const_table);\n", 0);
- Printf(f_init,"}\n");
-
- if (shadow) {
- Printv(f_shadow,
- classes,
- "\n\n#-------------- FUNCTION WRAPPERS ------------------\n\n",
- func,
- "\n\n#-------------- VARIABLE WRAPPERS ------------------\n\n",
- vars,
- 0);
-
- if (Len(pragma_include) > 0) {
- Printv(f_shadow,
- "\n\n#-------------- USER INCLUDE -----------------------\n\n",
- pragma_include,
- 0);
- }
- fclose(f_shadow);
- }
-}
+ Printf(f_runtime,"#define SWIGPYTHON\n");
+ if (NoInclude)
+ Printf(f_runtime,"#define SWIG_NOINCLUDE\n");
-/* -----------------------------------------------------------------------------
- * PYTHON::get_pointer()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::get_pointer(char *src, char *dest, SwigType *t, String *f, char *ret) {
- SwigType *lt;
- SwigType_remember(t);
- Printv(f,tab4, "if ((SWIG_ConvertPtr(", src, ",(void **) &", dest, ",", 0);
-
- lt = Swig_clocal_type(t);
- if (Cmp(lt,"p.void") == 0) {
- Printv(f, "0,1)) == -1) return ", ret, ";\n", 0);
- }
- /* if (SwigType_type(t) == T_VOID) Printv(f, "0,1)) == -1) return ", ret, ";\n", 0);*/
- else {
- Printv(f,"SWIGTYPE", SwigType_manglestr(t), ",1)) == -1) return ", ret, ";\n", 0);
- }
- Delete(lt);
-}
+ /* Set module name */
+ module = Copy(Getattr(n,"name"));
+ mainmodule = Getattr(n,"name");
-/* -----------------------------------------------------------------------------
- * PYTHON::create_command()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::create_command(String *cname, String *iname) {
- add_method(iname, Swig_name_wrapper(cname), use_kw);
-}
+ char filen[256];
-/* -----------------------------------------------------------------------------
- * PYTHON::create_function()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::function(DOH *node) {
- char *name;
- char *iname;
- SwigType *d;
- ParmList *l;
- Parm *p;
- int pcount,i,j;
- char wname[256];
- char source[64], target[64], argnum[20];
- char *usage = 0;
- Wrapper *f;
- String *parse_args;
- String *arglist;
- String *get_pointers;
- String *cleanup;
- String *outarg;
- String *check;
- String *kwargs;
- char *tm;
- int numopt = 0;
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- d = Getattr(node,"type");
- l = Getattr(node,"parms");
- f = NewWrapper();
- parse_args = NewString("");
- arglist = NewString("");
- get_pointers = NewString("");
- cleanup = NewString("");
- outarg = NewString("");
- check = NewString("");
- kwargs = NewString("");
-
- have_output = 0;
-
- strcpy(wname,Char(Swig_name_wrapper(iname)));
-
- if (!use_kw) {
- Printv(f,
- "static PyObject *", wname,
- "(PyObject *self, PyObject *args) {",
- 0);
- } else {
- Printv(f,
- "static PyObject *", wname,
- "(PyObject *self, PyObject *args, PyObject *kwargs) {",
- 0);
- }
- Wrapper_add_local(f,"resultobj", "PyObject *resultobj");
+ /* 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("");
- /* Get the function usage string for later use */
+ Swig_register_filebyname("shadow",f_shadow);
+ Swig_register_filebyname("python",f_shadow);
- usage = usage_func(iname,d,l);
+ 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);
- /* Write code to extract function parameters. */
- pcount = emit_args(node, f);
- if (!use_kw) {
- Printf(parse_args," if(!PyArg_ParseTuple(args,\"");
- } else {
- Printf(parse_args," if(!PyArg_ParseTupleAndKeywords(args,kwargs,\"");
- Printf(arglist,",kwnames");
- }
+ Printf(f_shadow,"import %s\n", module);
- i = 0;
- j = 0;
- numopt = check_numopt(l);
- if (numopt) have_defarg = 1;
- p = l;
- Printf(kwargs,"{ ");
- while (p != 0) {
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
- String *pv = Getvalue(p);
-
- sprintf(source,"obj%d",i);
- sprintf(target,Char(Getlname(p)));
- sprintf(argnum,"%d",j+1);
-
- if (!Getignore(p)) {
- Putc(',',arglist);
- if (j == pcount-numopt) Putc('|',parse_args); /* Optional argument separator */
- if (Len(pn)) {
- Printf(kwargs,"\"%s\",", pn);
- } else {
- Printf(kwargs,"\"arg%d\",", j+1);
+ // 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);
}
- if ((tm = Swig_typemap_lookup((char*)"in",pt,pn,source,target,f))) {
- Putc('O',parse_args);
- Wrapper_add_localv(f, source, "PyObject *",source, " = 0", 0);
- Printf(arglist,"&%s",source);
- if (i >= (pcount-numopt))
- Printv(get_pointers, tab4, "if (", source, ")\n", 0);
- Printv(get_pointers,tm,"\n", 0);
- Replace(get_pointers,"$argnum", argnum, DOH_REPLACE_ANY);
- Replace(get_pointers,"$arg",source, DOH_REPLACE_ANY);
- } else {
- int noarg = 0;
-
- switch(SwigType_type(pt)) {
- case T_INT : case T_UINT:
- Putc('i',parse_args);
- break;
- case T_SHORT: case T_USHORT:
- Putc('h',parse_args);
- break;
- case T_LONG : case T_ULONG:
- Putc('l',parse_args);
- break;
- case T_SCHAR : case T_UCHAR :
- Putc('b',parse_args);
- break;
- case T_CHAR:
- Putc('c',parse_args);
- break;
- case T_FLOAT :
- Putc('f',parse_args);
- break;
- case T_DOUBLE:
- Putc('d',parse_args);
- break;
-
- case T_BOOL:
- {
- char tempb[128];
- char tempval[128];
- if (pv) {
- sprintf(tempval, "(int) %s", Char(pv));
- }
- sprintf(tempb,"tempbool%d",i);
- Putc('i',parse_args);
- if (!pv)
- Wrapper_add_localv(f,tempb,"int",tempb,0);
- else
- Wrapper_add_localv(f,tempb,"int",tempb, "=",tempval,0);
- Printv(get_pointers, tab4, target, " = ( ", tempb, " != 0);\n", 0);
- Printf(arglist,"&%s",tempb);
- noarg = 1;
- }
- break;
+ // Include some information in the code
+ Printf(f_header,"\n/*-----------------------------------------------\n @(target):= %s.so\n\
+ ------------------------------------------------*/\n", module);
- case T_VOID :
- noarg = 1;
- break;
+ }
- case T_USER:
+ Printf(f_header,"#define SWIG_init init%s\n\n", module);
+ Printf(f_header,"#define SWIG_name \"%s\"\n", module);
- Putc('O',parse_args);
- sprintf(source,"argo%d", i);
- sprintf(target,Char(Getlname(p)));
+ 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");
- Wrapper_add_localv(f,source,"PyObject *",source,"=0",0);
- Printf(arglist,"&%s",source);
- SwigType_add_pointer(pt);
- get_pointer(source, target, pt, get_pointers, (char*)"NULL");
- SwigType_del_pointer(pt);
- noarg = 1;
- break;
+ /* emit code */
+ Language::top(n);
- case T_STRING:
- Putc('s',parse_args);
- Printf(arglist,"&%s", Getlname(p));
- noarg = 1;
- break;
+ /* Close language module */
+ Printf(methods,"\t { NULL, NULL }\n");
+ Printf(methods,"};\n");
+ Printf(f_wrappers,"%s\n",methods);
- case T_POINTER: case T_ARRAY: case T_REFERENCE:
+ SwigType_emit_type_table(f_runtime,f_wrappers);
- /* Have some sort of pointer variable. Create a temporary local
- variable for the string and read the pointer value into it. */
+ Printf(const_code, "{0}};\n");
+ Printf(f_wrappers,"%s\n",const_code);
+ Printf(f_init,"}\n");
- Putc('O',parse_args);
- sprintf(source,"argo%d", i);
- sprintf(target,"%s",Char(Getlname(p)));
+ Printf(f_wrappers,"#ifdef __cplusplus\n");
+ Printf(f_wrappers,"}\n");
+ Printf(f_wrappers,"#endif\n");
- Wrapper_add_localv(f,source,"PyObject *",source,"=0",0);
- Printf(arglist,"&%s",source);
- get_pointer(source, target, pt, get_pointers, (char*)"NULL");
- noarg = 1;
- break;
+ if (shadow) {
+ Printv(f_shadow, f_shadow_stubs, "\n",NIL);
+ Close(f_shadow);
+ Delete(f_shadow);
+ }
- default :
- Printf(stderr,"%s:%d. Unable to use type %s as a function argument.\n",Getfile(node), Getline(node), SwigType_str(pt,0));
- break;
- }
+ /* 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()
+ * ------------------------------------------------------------ */
- if (!noarg)
- Printf(arglist,"&%s",Getlname(p));
+ virtual int importDirective(Node *n) {
+ if (shadow) {
+ String *modname = Getattr(n,"module");
+ if (modname) {
+ Printf(f_shadow,"import %s\n", modname);
}
- j++;
- }
- /* Check if there was any constraint code */
- if ((tm = Swig_typemap_lookup((char*)"check",pt,pn,source,target,0))) {
- Printf(check,"%s\n",tm);
- Replace(check,"$argnum", argnum, DOH_REPLACE_ANY);
- }
- /* Check if there was any cleanup code */
- if ((tm = Swig_typemap_lookup((char*)"freearg",pt,pn,target,source,0))) {
- Printf(cleanup,"%s\n",tm);
- Replace(cleanup,"$argnum", argnum, DOH_REPLACE_ANY);
- Replace(cleanup,"$arg",source, DOH_REPLACE_ANY);
}
- /* Check for output arguments */
- if ((tm = Swig_typemap_lookup((char*)"argout",pt,pn,target,(char*)"resultobj",0))) {
- Printf(outarg,"%s\n", tm);
- Replace(outarg,"$argnum",argnum,DOH_REPLACE_ANY);
- Replace(outarg,"$arg",source, DOH_REPLACE_ANY);
- have_output++;
- }
- p = Getnext(p);
- i++;
+ return Language::importDirective(n);
}
- Printf(kwargs," NULL }");
- if (use_kw) {
- Wrapper_add_localv(f,"kwnames","char *kwnames[] = ", kwargs, ";\n", 0);
- /* Printv(f->locals,tab4, "char *kwnames[] = ", kwargs, ";\n", 0); */
+ /* ------------------------------------------------------------
+ * 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()
+ * ------------------------------------------------------------ */
- Printf(parse_args,":%s\"", iname);
- Printv(parse_args,
- arglist, ")) return NULL;\n",
- 0);
+ 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;
+ }
- /* Now slap the whole first part of the wrapper function together */
- Printv(f, parse_args, get_pointers, check, 0);
+ f = NewWrapper();
+ parse_args = NewString("");
+ arglist = NewString("");
+ get_pointers = NewString("");
+ cleanup = NewString("");
+ outarg = NewString("");
+ kwargs = NewString("");
+
+ Wrapper_add_local(f,"resultobj", "PyObject *resultobj");
- /* Emit the function call */
- emit_func_call(node,f);
+ /* 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));
+ }
- /* Return the function value */
- if ((tm = Swig_typemap_lookup((char*)"out",d,iname,(char*)"result",(char*)"resultobj",0))) {
- Printf(f,"%s\n", tm);
- } else {
- switch(SwigType_type(d)) {
- case T_INT: case T_UINT: case T_BOOL:
- case T_SHORT: case T_USHORT:
- case T_LONG : case T_ULONG:
- case T_SCHAR: case T_UCHAR :
- Printf(f," resultobj = PyInt_FromLong((long)result);\n");
- break;
- case T_DOUBLE :
- case T_FLOAT :
- Printf(f," resultobj = PyFloat_FromDouble(result);\n");
- break;
- case T_CHAR :
- Printf(f," resultobj = Py_BuildValue(\"c\",result);\n");
- break;
- case T_USER :
- SwigType_add_pointer(d);
- SwigType_remember(d);
- Printv(f,tab4, "resultobj = SWIG_NewPointerObj((void *)result, SWIGTYPE", SwigType_manglestr(d), ");\n",0);
- SwigType_del_pointer(d);
- break;
- case T_STRING:
- Printf(f," resultobj = Py_BuildValue(\"s\",result);\n");
- break;
- case T_POINTER: case T_ARRAY: case T_REFERENCE:
- SwigType_remember(d);
- Printv(f, tab4, "resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE", SwigType_manglestr(d), ");\n", 0);
- break;
- case T_VOID:
- Printf(f," Py_INCREF(Py_None);\n");
- Printf(f," resultobj = Py_None;\n");
- break;
- default :
- Printf(stderr,"%s:%d. Unable to use return type %s in function %s.\n", Getfile(node), Getline(node), SwigType_str(d,0), name);
- break;
+ 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");
}
- }
- /* Output argument output code */
- Printv(f,outarg,0);
+ /* Generate code for argument marshalling */
- /* Output cleanup code */
- Printv(f,cleanup,0);
+ Printf(kwargs,"{ ");
+ for (i = 0, p=l; i < num_arguments; i++) {
+
+ while (checkAttribute(p,"tmap:in:numinputs","0")) {
+ p = Getattr(p,"tmap:in:next");
+ }
- /* Look to see if there is any newfree cleanup code */
- if (NewObject) {
- if ((tm = Swig_typemap_lookup((char*)"newfree",d,iname,(char*)"result",(char*)"",0))) {
- Printf(f,"%s\n",tm);
- }
- }
+ SwigType *pt = Getattr(p,"type");
+ String *pn = Getattr(p,"name");
+ String *ln = Getattr(p,"lname");
- /* See if there is any return cleanup code */
- if ((tm = Swig_typemap_lookup((char*)"ret",d,iname,(char*)"result",(char*)"",0))) {
- Printf(f,"%s\n",tm);
- }
+ sprintf(source,"obj%d",i);
- Printf(f," return resultobj;\n}\n");
+ Putc(',',arglist);
+ if (i == num_required) Putc('|', parse_args); /* Optional argument separator */
- /* Substitute the cleanup code */
- Replace(f,"$cleanup",cleanup, DOH_REPLACE_ANY);
+ /* Keyword argument handling */
+ if (Len(pn)) {
+ Printf(kwargs,"\"%s\",", pn);
+ } else {
+ Printf(kwargs,"\"arg%d\",", i+1);
+ }
- /* Substitute the function name */
- Replace(f,"$name",iname, DOH_REPLACE_ANY);
+ /* 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");
+ }
- /* Dump the function out */
- Printf(f_wrappers,"%s",f);
+ 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);
- /* Now register the function with the interpreter. */
- add_method(iname, wname, use_kw);
+ } 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);
+ }
- /* Create a shadow for this function (if enabled and not in a member function) */
+ Printf(parse_args,":%s\"", iname);
+ Printv(parse_args,
+ arglist, ")) goto fail;\n",
+ NIL);
- if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
- int need_wrapper = 0;
- int munge_return = 0;
+ /* 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);
+ }
+ }
- /* Check return code for modification */
- if (is_shadow(d)) {
- need_wrapper = 1;
- munge_return = 1;
+ /* 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);
- /* If no modification is needed. We're just going to play some
- symbol table games instead */
+ /* This part below still needs cleanup */
- if (!need_wrapper) {
- Printv(func,iname, " = ", module, ".", iname, "\n\n", 0);
+ /* 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 {
- Printv(func,"def ", iname, "(*args, **kwargs):\n", 0);
- Printv(func, tab4, "val = apply(", module, ".", iname, ",args,kwargs)\n",0);
+ 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 (munge_return) {
- /* If the output of this object has been remapped in any way, we're
- going to return it as a bare object */
+ /* Output argument output code */
+ Printv(f->code,outarg,NIL);
- if (!Swig_typemap_search((char*)"out",d,iname)) {
+ /* Output cleanup code */
+ Printv(f->code,cleanup,NIL);
- /* If there are output arguments, we are going to return the value
- unchanged. Otherwise, emit some shadow class conversion code. */
+ /* 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);
+ }
+ }
- if (!have_output) {
- Printv(func, tab4, "if val: val = ", is_shadow(d), "Ptr(val)", 0);
- if ((!SwigType_ispointer(d)) || NewObject)
- Printf(func, "; val.thisown = 1\n");
- else
- Printf(func,"\n");
- }
+ /* 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);
}
}
- Printv(func, tab4, "return val\n\n", 0);
+ } 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;
}
- Delete(parse_args);
- Delete(arglist);
- Delete(get_pointers);
- Delete(cleanup);
- Delete(outarg);
- Delete(check);
- Delete(kwargs);
- Delete(f);
-}
-/* -----------------------------------------------------------------------------
- * PYTHON::variable()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::variable(DOH *node) {
- char *name, *iname;
- SwigType *t;
- char *wname;
+ /* ------------------------------------------------------------
+ * 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;
- char *tm;
+ String *tm;
Wrapper *getf, *setf;
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
+ 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 this is our first call, add the globals variable to the
+ Python dictionary. */
if (!have_globals) {
- Printf(f_init,"\t PyDict_SetItemString(d,\"%s\", SWIG_globals);\n",global_name);
+ Printf(f_init,"\t PyDict_SetItemString(d,(char*)\"%s\", SWIG_globals);\n",global_name);
have_globals=1;
if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
- Printv(vars, global_name, " = ", module, ".", global_name, "\n", 0);
+ Printf(f_shadow_stubs,"%s = %s.%s\n", global_name, module, global_name);
}
}
- wname = Char(Swig_name_wrapper(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,"static int %s_set(PyObject *val) {\n", wname);
- if (!ReadOnly) {
- if ((tm = Swig_typemap_lookup((char*)"varin",t,name,(char*)"val",name,0))) {
- Printf(setf,"%s\n",tm);
- Replace(setf,"$name",iname, DOH_REPLACE_ANY);
+ 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 {
- switch(SwigType_type(t)) {
-
- case T_INT: case T_SHORT: case T_LONG :
- case T_UINT: case T_USHORT: case T_ULONG:
- case T_SCHAR: case T_UCHAR: case T_BOOL:
- Wrapper_add_localv(setf,"tval",SwigType_lstr(t,0),"tval",0);
- Printv(setf,
- "tval = (", SwigType_lstr(t,0), ") PyInt_AsLong(val);\n",
- "if (PyErr_Occurred()) {\n",
- "PyErr_SetString(PyExc_TypeError,\"C variable '",
- iname, "'(", SwigType_str(t,0), ")\");\n",
- "return 1; \n",
- "}\n",
- name, " = tval;\n",
- 0);
- break;
-
- case T_FLOAT: case T_DOUBLE:
- Wrapper_add_localv(setf,"tval",SwigType_lstr(t,0), "tval",0);
- Printv(setf,
- "tval = (", SwigType_lstr(t,0), ") PyFloat_AsDouble(val);\n",
- "if (PyErr_Occurred()) {\n",
- "PyErr_SetString(PyExc_TypeError,\"C variable '",
- iname, "'(", SwigType_str(t,0), ")\");\n",
- "return 1; \n",
- "}\n",
- name, " = tval;\n",
- 0);
- break;
-
- case T_CHAR:
- Wrapper_add_local(setf,"tval","char * tval");
- Printv(setf,
- "tval = (char *) PyString_AsString(val);\n",
- "if (PyErr_Occurred()) {\n",
- "PyErr_SetString(PyExc_TypeError,\"C variable '",
- iname, "'(", SwigType_str(t,0), ")\");\n",
- "return 1; \n",
- "}\n",
- name, " = *tval;\n",
- 0);
- break;
-
- case T_USER:
- SwigType_add_pointer(t);
- Wrapper_add_localv(setf,"temp",SwigType_lstr(t,0),"temp",0);
- get_pointer((char*)"val",(char*)"temp",t,setf,(char*)"1");
- Printv(setf, name, " = *temp;\n", 0);
- SwigType_del_pointer(t);
- break;
-
- case T_STRING:
- Wrapper_add_local(setf,"tval","char * tval");
- Printv(setf,
- "tval = (char *) PyString_AsString(val);\n",
- "if (PyErr_Occurred()) {\n",
- "PyErr_SetString(PyExc_TypeError,\"C variable '",
- iname, "'(", SwigType_str(t,0), ")\");\n",
- "return 1; \n",
- "}\n",
- 0);
-
- if (CPlusPlus) {
- Printv(setf,
- "if (", name, ") delete [] ", name, ";\n",
- name, " = new char[strlen(tval)+1];\n",
- "strcpy((char *)", name, ",tval);\n",
- 0);
- } else {
- Printv(setf,
- "if (", name, ") free((char*)", name, ");\n",
- name, " = (char *) malloc(strlen(tval)+1);\n",
- "strcpy((char *)", name, ",tval);\n",
- 0);
- }
- break;
-
- case T_ARRAY:
- {
- int setable = 0;
- SwigType *aop;
- SwigType *ta = Copy(t);
- aop = SwigType_pop(ta);
- if (SwigType_type(ta) == T_CHAR) {
- String *dim = SwigType_array_getdim(aop,0);
- if (dim && Len(dim)) {
- Printf(setf, "strncpy(%s,PyString_AsString(val), %s);\n", name,dim);
- setable = 1;
- }
- }
- if (!setable) {
- Printv(setf,
- "PyErr_SetString(PyExc_TypeError,\"Variable ", iname,
- " is read-only.\");\n",
- "return 1;\n",
- 0);
- }
- Delete(ta);
- Delete(aop);
- }
- break;
-
- case T_POINTER: case T_REFERENCE:
- Wrapper_add_localv(setf,"temp", SwigType_lstr(t,0), "temp",0);
- get_pointer((char*)"val",(char*)"temp",t,setf,(char*)"1");
- Printv(setf, name, " = temp;\n", 0);
- break;
-
- default:
- Printf(stderr,"%s:%d. Unable to link with type %s.\n", Getfile(node), Getline(node), SwigType_str(t,0));
- }
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number,
+ "Unable to set variable of type %s.\n", SwigType_str(t,0));
}
- Printf(setf," return 0;\n");
+ Printf(setf->code," return 0;\n");
} else {
/* Is a readonly variable. Issue an error */
- Printv(setf,
- "PyErr_SetString(PyExc_TypeError,\"Variable ", iname,
+ Printv(setf->code,
+ tab4, "PyErr_SetString(PyExc_TypeError,\"Variable ", iname,
" is read-only.\");\n",
- "return 1;\n",
- 0);
+ tab4, "return 1;\n",
+ NIL);
}
- Printf(setf,"}\n");
- Printf(f_wrappers,"%s", setf);
+ Printf(setf->code,"}\n");
+ Wrapper_print(setf,f_wrappers);
/* Create a function for getting the value of a variable */
- Printf(getf,"static PyObject *%s_get() {\n", wname);
+ Printf(getf->def,"static PyObject *%s_get() {", wname);
Wrapper_add_local(getf,"pyobj", "PyObject *pyobj");
- if ((tm = Swig_typemap_lookup((char*)"varout",t,name,name,(char*)"pyobj",0))) {
- Printf(getf,"%s\n",tm);
- Replace(getf,"$name",iname, DOH_REPLACE_ANY);
- } else if ((tm = Swig_typemap_lookup((char*)"out",t,name,name,(char*)"pyobj",0))) {
- Printf(getf,"%s\n",tm);
- Replace(getf,"$name",iname, DOH_REPLACE_ANY);
+ 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 {
- switch(SwigType_type(t)) {
- case T_INT: case T_UINT:
- case T_SHORT: case T_USHORT:
- case T_LONG: case T_ULONG:
- case T_SCHAR: case T_UCHAR: case T_BOOL:
- Printv(getf, "pyobj = PyInt_FromLong((long) ", name, ");\n", 0);
- break;
- case T_FLOAT: case T_DOUBLE:
- Printv(getf, "pyobj = PyFloat_FromDouble((double) ", name, ");\n", 0);
- break;
- case T_CHAR:
- Wrapper_add_local(getf,"ptemp","char ptemp[2]");
- Printv(getf,
- "ptemp[0] = ", name, ";\n",
- "ptemp[1] = 0;\n",
- "pyobj = PyString_FromString(ptemp);\n",
- 0);
- break;
- case T_USER:
- SwigType_add_pointer(t);
- SwigType_remember(t);
- Printv(getf,
- "pyobj = SWIG_NewPointerObj((void *) &", name ,
- ", SWIGTYPE", SwigType_manglestr(t), ");\n",
- 0);
- SwigType_del_pointer(t);
- break;
- case T_STRING:
- Printv(getf,
- "if (", name, ")\n",
- "pyobj = PyString_FromString(", name, ");\n",
- "else pyobj = PyString_FromString(\"(NULL)\");\n",
- 0);
- break;
-
- case T_POINTER: case T_ARRAY: case T_REFERENCE:
- {
- SwigType *ta = Copy(t);
- SwigType_pop(ta);
- if (SwigType_type(ta) == T_CHAR) {
- Printv(getf,"pyobj = PyString_FromString(", name, ");\n", 0);
- } else {
- SwigType_remember(t);
- Printv(getf,
- "pyobj = SWIG_NewPointerObj((void *)", name,
- ", SWIGTYPE", SwigType_manglestr(t), ");\n",
- 0);
- }
- Delete(ta);
- }
- break;
-
- default:
- Printf(stderr,"Unable to link with type %s\n", SwigType_str(t,0));
- break;
- }
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number,
+ "Unable to link with type %s\n", SwigType_str(t,0));
}
-
- Printf(getf," return pyobj;\n}\n");
- Printf(f_wrappers,"%s", getf);
+
+ 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);
- Printf(f_init,"\t SWIG_addvarlink(SWIG_globals,\"%s\",%s_get, %s_set);\n", iname, wname, wname);
+ DelWrapper(setf);
+ DelWrapper(getf);
+ return SWIG_OK;
+ }
- /* Output a shadow variable. (If applicable and possible) */
+ /* ------------------------------------------------------------
+ * 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 (is_shadow(t)) {
- Printv(vars,
- iname, " = ", is_shadow(t), "Ptr(", module, ".", global_name,
- ".", iname, ")\n",
- 0);
+ if (!in_class) {
+ Printv(f_shadow,iname, " = ", module, ".", iname, "\n", NIL);
+ } else {
+ Printv(f_shadow_stubs,iname, " = ", module, ".", iname, "\n", NIL);
}
}
- Delete(setf);
- Delete(getf);
-}
+ return SWIG_OK;
+ }
-/* -----------------------------------------------------------------------------
- * PYTHON::constant()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::constant(DOH *node) {
- char *name;
- SwigType *type;
- char *value;
- char *tm;
-
- name = GetChar(node,"name");
- type = Getattr(node,"type");
- value = GetChar(node,"value");
-
- if ((tm = Swig_typemap_lookup((char*)"const",type,name,value,name,0))) {
- Printf(const_code,"%s\n", tm);
- } else {
- switch(SwigType_type(type)) {
- case T_INT: case T_UINT: case T_BOOL:
- case T_SHORT: case T_USHORT:
- case T_LONG: case T_ULONG:
- case T_SCHAR: case T_UCHAR:
- Printv(const_code, "{ SWIG_PY_INT, \"", name, "\", (long) ", value, ", 0, 0, 0},\n", 0);
- break;
- case T_DOUBLE:
- case T_FLOAT:
- Printv(const_code, "{ SWIG_PY_FLOAT, \"", name, "\", 0, (double) ", value, ", 0,0},\n", 0);
- break;
- case T_CHAR :
- Printf(const_code, "{ SWIG_PY_STRING, \"%s\", 0, 0, (void *) \"%s\", 0 }, \n", name, value);
- break;
- case T_STRING:
- Printf(const_code,"{ SWIG_PY_STRING, \"%s\", 0, 0, (void *) \"%s\", 0 }, \n", name, value);
- break;
- case T_POINTER: case T_ARRAY: case T_REFERENCE:
- SwigType_remember(type);
- Printv(const_code, "{ SWIG_PY_POINTER, \"", name, "\", 0, 0, (void *) ", value, ", &SWIGTYPE", SwigType_manglestr(type), "}, \n", 0);
- break;
- default:
- Printf(stderr,"%s:%d. Unsupported constant value. %s, %d\n", Getfile(node), Getline(node), name, SwigType_type(type));
- return;
- break;
+ /* ------------------------------------------------------------
+ * 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;
}
- if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
- Printv(vars,name, " = ", module, ".", name, "\n", 0);
- }
-}
-/* -----------------------------------------------------------------------------
- * PYTHON::usage_func() - Make string showing how to call a function
- * ----------------------------------------------------------------------------- */
-char *
-PYTHON::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);
-
- i = 0;
- p = l;
- while (p != 0) {
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
- if (!Getignore(p)) {
- i++;
- /* 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);
+ /* ------------------------------------------------------------
+ * 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 {
- Printf(temp,"%s", SwigType_str(pt,0));
+ importname = NewString(Getattr(n,"sym:name"));
}
- }
- p = Getnext(p);
- if (p != 0) {
- if (!Getignore(p))
- Putc(',',temp);
- }
- } else {
- p = Getnext(p);
- if (p) {
- if ((!Getignore(p)) && (i > 0))
- Putc(',',temp);
+ Setattr(n,"python:proxy",importname);
}
}
+ return Language::classDeclaration(n);
}
- Putc(')',temp);
- return Char(temp);
-}
-/* -----------------------------------------------------------------------------
- * PYTHON::nativefunctin()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::nativefunction(DOH *node) {
- char *name;
- char *funcname;
- name = GetChar(node,"scriptname");
- funcname = GetChar(node,"name");
-
- /* Figure out what kind of function this is */
- if (Swig_proto_cmp("f(p.PyObject,p.PyObject).p.PyObject",node) == 0) {
- /* Not with keyword arguments */
- add_method(name,funcname,0);
- }
- if (Swig_proto_cmp("f(p.PyObject,p.PyObject,p.PyObject).p.PyObject",node) == 0) {
- add_method(name,funcname,1);
- }
- if (shadow) {
- Printv(func, name, " = ", module, ".", name, "\n\n", 0);
- }
-}
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
-/* -----------------------------------------------------------------------------
- * PYTHON::cpp_class_decl() - Register a class definition
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::cpp_class_decl(DOH *node) {
- String *name = Getname(node);
- String *rename = Getattr(node,"scriptname");
- String *ctype = Getattr(node,"classtype");
- String *stype;
- if (shadow) {
- stype = NewString(name);
- SwigType_add_pointer(stype);
- Setattr(hash,stype,rename);
- Delete(stype);
- /* Add full name of datatype to the hash table */
- if (Len(ctype) > 0) {
- stype = NewStringf("%s %s", ctype, name);
- SwigType_add_pointer(stype);
- Setattr(hash,stype,rename);
- Delete(stype);
- }
- }
-}
+ virtual int classHandler(Node *n) {
+ int oldclassic = classic;
-/* -----------------------------------------------------------------------------
- * PYTHON::pragma()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::pragma(DOH *node) {
- String *name;
- String *value;
- name = Getattr(node,"name");
- value = Getattr(node,"value");
-
- if (Cmp(name,"code") == 0) {
if (shadow) {
- Printf(f_shadow,"%s\n",value);
- }
- } else if (Cmp(name,"include") == 0) {
- if (shadow) {
- if (value) {
- FILE *f = Swig_open(value);
- if (!f) {
- Printf(stderr,"%s:%d. Unable to locate file %s\n", Getfile(node), Getline(node),value);
- } else {
- char buffer[4096];
- while (fgets(buffer,4095,f)) {
- Printv(pragma_include,buffer,0);
+
+ /* 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);
}
- }
-}
-#ifdef OLD
-/* C++ pragmas are no longer handled as a special case. The generic %pragma
- directive may used in or outside of a class. Therefore, this functionality
- should be moved into the pragma method, not handled here. -- Dave. (12/14/00).
-*/
-
-/* -----------------------------------------------------------------------------
- * PYTHON::cpp_pragma() - Handle C++ pragmas
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::cpp_pragma(Pragma *plist) {
- PyPragma *pyp1 = 0, *pyp2 = 0;
- if (pragmas) {
- delete pragmas;
- pragmas = 0;
+ /* 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 \"<C ", class_name," instance at %s>\" % (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;
}
- while (plist) {
- if (strcmp(Char(plist->lang),(char*)"python") == 0) {
- if (strcmp(Char(plist->name),"addtomethod") == 0) {
- /* parse value, expected to be in the form "methodName:line" */
- String *temp = NewString(plist->value);
- char* txtptr = strchr(Char(temp), ':');
- if (txtptr) {
- /* add name and line to a list in current_class */
- *txtptr = 0;
- txtptr++;
- pyp1 = new PyPragma(Char(temp),txtptr);
- pyp1->next = 0;
- if (pyp2) {
- pyp2->next = pyp1;
- pyp2 = pyp1;
+
+ /* ------------------------------------------------------------
+ * 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 {
- pragmas = pyp1;
- pyp2 = pragmas;
+ Printv(f_shadow, tab4, "def ", symname, "(*args): ", NIL);
+ Printv(f_shadow, "return apply(", module, ".", Swig_name_member(class_name,symname), ",args)\n",NIL);
}
- } else {
- Printf(stderr,"%s : Line %d. Malformed addtomethod pragma. Should be \"methodName:text\"\n",
- Char(plist->filename),plist->lineno);
- }
- Delete(temp);
- } else if (strcmp(Char(plist->name), "addtoclass") == 0) {
- pyp1 = new PyPragma((char*)"__class__",Char(plist->value));
- pyp1->next = 0;
- if (pyp2) {
- pyp2->next = pyp1;
- pyp2 = pyp1;
- } else {
- pragmas = pyp1;
- pyp2 = pragmas;
}
}
}
- plist = plist->next;
+ return SWIG_OK;
}
-}
-/* -----------------------------------------------------------------------------
- * PYTHON::emitAddPragmas()
- *
- * Search the current class pragma for any text belonging to name.
- * Append the text properly spaced to the output string.
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::emitAddPragmas(String *output, char* name, char* spacing) {
- PyPragma *p = pragmas;
- while (p) {
- if (strcmp(Char(p->m_method),name) == 0) {
- Printv(output,spacing,p->m_text,"\n",0);
+ /* ------------------------------------------------------------
+ * 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);
+ }
}
- p = p->next;
+ return SWIG_OK;
}
-}
-#endif
-
-/* C++ Support + Shadow Classes */
-
-static String *setattr = 0;
-static String *getattr = 0;
-static String *csetattr = 0;
-static String *cgetattr = 0;
-static String *pyclass = 0;
-static String *imethod = 0;
-static String *construct = 0;
-static String *cinit = 0;
-static String *additional = 0;
-static int have_constructor;
-static int have_destructor;
-static int have_getattr;
-static int have_setattr;
-static int have_repr;
-static char *class_type;
-static char *real_classname;
-static String *base_class = 0;
-static int class_renamed = 0;
+ /* ------------------------------------------------------------
+ * 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. */
-/* -----------------------------------------------------------------------------
- * PYTHON::cpp_open_class()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::cpp_open_class(DOH *node) {
- this->Language::cpp_open_class(node);
+ 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;
+ }
- char *classname = GetChar(node,"name");
- char *rname = GetChar(node,"scriptname");
- char *ctype = GetChar(node,"classtype");
-
- if (shadow) {
- /* Create new strings for building up a wrapper function */
- setattr = NewString("");
- getattr = NewString("");
- csetattr = NewString("");
- cgetattr = NewString("");
- pyclass = NewString("");
- imethod = NewString("");
- construct = NewString("");
- cinit = NewString("");
- additional= NewString("");
- base_class = 0;
- have_constructor = 0;
- have_destructor = 0;
- have_getattr = 0;
- have_setattr = 0;
- have_repr = 0;
- if (rname) {
- class_name = Swig_copy_string(rname);
- class_renamed = 1;
- } else {
- class_name = Swig_copy_string(classname);
- class_renamed = 0;
+ /* ------------------------------------------------------------
+ * 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;
}
- real_classname = Swig_copy_string(classname);
- class_type = Swig_copy_string(ctype);
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
- cpp_class_decl(node);
+ virtual int membervariableHandler(Node *n) {
+ String *symname = Getattr(n,"sym:name");
- if (shadow) {
- Printv(setattr,
- tab4, "def __setattr__(self,name,value):\n",
- tab8, "if (name == \"this\") or (name == \"thisown\"): self.__dict__[name] = value; return\n",
- tab8, "method = ", class_name, ".__setmethods__.get(name,None)\n",
- tab8, "if method: return method(self,value)\n",
- 0);
+ int oldshadow = shadow;
+ if (shadow) shadow = shadow | PYSHADOW_MEMBER;
+ Language::membervariableHandler(n);
+ shadow = oldshadow;
- Printv(getattr, tab4, "def __getattr__(self,name):\n", 0);
- Printv(csetattr, tab4, "__setmethods__ = {\n", 0);
- Printv(cgetattr, tab4, "__getmethods__ = {\n", 0);
- }
-}
+ 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);
-/* -----------------------------------------------------------------------------
- * PYTHON::cpp_member_func()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::cpp_memberfunction(DOH *node) {
- char *realname;
- char *name, *iname;
- SwigType *t;
- ParmList *l;
- int oldshadow;
- char cname[1024];
-
- /* Create the default member function */
- oldshadow = shadow; /* Disable shadowing when wrapping member functions */
- if (shadow) shadow = shadow | PYSHADOW_MEMBER;
- this->Language::cpp_memberfunction(node);
- shadow = oldshadow;
- if (shadow) {
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
- l = Getattr(node,"parms");
- realname = iname ? iname : name;
-
- /* Check to see if we've already seen this */
- sprintf(cname,"python:%s::%s",class_name,realname);
- if (Getattr(symbols,cname)) return;
- Setattr(symbols,cname,cname);
-
- if (strcmp(realname,"__repr__") == 0)
- have_repr = 1;
-
- if (!is_shadow(t) && !noopt) {
- Printv(imethod,
- class_name, ".", realname, " = new.instancemethod(", module, ".", Swig_name_member(class_name,realname), ", None, ", class_name, ")\n",
- 0);
- } else {
- if (use_kw)
- Printv(pyclass,tab4, "def ", realname, "(*args, **kwargs):\n", 0);
- else
- Printv(pyclass, tab4, "def ", realname, "(*args):\n", 0);
-
- if (use_kw)
- Printv(pyclass, tab8, "val = apply(", module, ".", Swig_name_member(class_name,realname), ",args, kwargs)\n", 0);
- else
- Printv(pyclass, tab8, "val = apply(", module, ".", Swig_name_member(class_name,realname), ",args)\n",0);
-
- /* Check to see if the return type is an object */
- if (is_shadow(t)) {
- if (!Swig_typemap_search((char*)"out",t,Swig_name_member(class_name,realname))) {
- if (!have_output) {
- Printv(pyclass, tab8, "if val: val = ", is_shadow(t), "Ptr(val) ", 0);
- if ((!SwigType_ispointer(t) || NewObject)) {
- Printf(pyclass, "; val.thisown = 1\n");
- } else {
- Printf(pyclass,"\n");
- }
- }
+ 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);
}
}
- Printv(pyclass, tab8, "return val\n", 0);
}
- /* emitAddPragmas(*pyclass, realname, tab8);
- *pyclass << tab8 << "return val\n"; */
+ return SWIG_OK;
}
-}
-/* -----------------------------------------------------------------------------
- * PYTHON::cpp_constructor()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::cpp_constructor(DOH *node) {
- char *name, *iname;
- ParmList *l;
- char *realname;
- int oldshadow = shadow;
- char cname[1024];
-
- if (shadow) shadow = shadow | PYSHADOW_MEMBER;
- this->Language::cpp_constructor(node);
- shadow = oldshadow;
-
- if (shadow) {
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- l = Getattr(node,"parms");
- realname = iname ? iname : class_name;
-
- /* Check to see if we've already seen this */
- sprintf(cname,":python:constructor:%s::%s",class_name,realname);
- if (Getattr(symbols,cname)) return;
- Setattr(symbols,cname,cname);
-
- if (!have_constructor) {
- if (use_kw)
- Printv(construct, tab4, "def __init__(self,*args,**kwargs):\n", 0);
- else
- Printv(construct, tab4, "def __init__(self,*args):\n",0);
-
- if (use_kw)
- Printv(construct, tab8, "self.this = apply(", module, ".", Swig_name_construct(realname), ",args,kwargs)\n", 0);
- else
- Printv(construct, tab8, "self.this = apply(", module, ".", Swig_name_construct(realname), ",args)\n", 0);
- Printv(construct, tab8, "self.thisown = 1\n", 0);
- // emitAddPragmas(construct,(char*)"__init__",(char*)tab8);
- have_constructor = 1;
- } else {
- /* Hmmm. We seem to be creating a different constructor. We're just going to create a
- function for it. */
-
- if (use_kw)
- Printv(additional, "def ", realname, "(*args,**kwargs):\n", 0);
- else
- Printv(additional, "def ", realname, "(*args):\n", 0);
-
- Printv(additional, tab4, "val = ", class_name, "Ptr(apply(", 0);
- if (use_kw)
- Printv(additional, module, ".", Swig_name_construct(realname), ",args,kwargs))\n", 0);
- else
- Printv(additional, module, ".", Swig_name_construct(realname), ",args))\n", 0);
- Printv(additional,tab4, "val.thisown = 1\n",
- tab4, "return val\n\n", 0);
+ /* ------------------------------------------------------------
+ * 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;
-/* -----------------------------------------------------------------------------
- * PYTHON::cpp_destructor()
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::cpp_destructor(DOH *node) {
- char *name, *newname;
- char *realname;
- int oldshadow = shadow;
-
- if (shadow) shadow = shadow | PYSHADOW_MEMBER;
- this->Language::cpp_destructor(node);
- shadow = oldshadow;
- if (shadow) {
- name = GetChar(node,"name");
- newname = GetChar(node,"scriptname");
- if (newname) realname = newname;
- else realname = class_renamed ? class_name : name;
-
- Printv(pyclass, tab4, "def __del__(self,", module, "=", module, "):\n", 0);
- // emitAddPragmas(pyclass,(char*)"__del__",(char*)tab8);
- Printv(pyclass, tab8, "if self.thisown == 1 :\n",
- tab8, tab4, module, ".", Swig_name_destroy(realname), "(self)\n", 0);
-
- have_destructor = 1;
}
-}
-/* -----------------------------------------------------------------------------
- * PYTHON::cpp_close_class() - Close a class and write wrappers
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::cpp_close_class() {
- String *ptrclass;
- String *repr;
-
- ptrclass = NewString("");
- repr = NewString("");
-
- if (shadow) {
- if (!have_constructor) {
- /* Build a constructor that takes a pointer to this kind of object */
- Printv(construct,
- tab4, "def __init__(self,this):\n",
- tab8, "self.this = this\n",
- 0);
- }
- /* First, build the pointer base class */
- if (base_class) {
- Printv(ptrclass, "class ", class_name, "(", base_class, "):\n", 0);
- } else {
- Printv(ptrclass, "class ", class_name, ":\n", 0);
- }
- Printv(getattr,
- tab8, "method = ", class_name, ".__getmethods__.get(name,None)\n",
- tab8, "if method: return method(self)\n",
- tab8, "raise AttributeError,name\n",
- 0);
- Printv(setattr, tab8, "self.__dict__[name] = value\n",0);
- Printv(cgetattr, tab4, "}\n", 0);
- Printv(csetattr, tab4, "}\n", 0);
- Printv(ptrclass,cinit,construct,"\n",0);
- Printv(classes,ptrclass,pyclass,0);
-
- if (have_setattr) {
- Printv(classes, csetattr, setattr, 0);
- }
- if (have_getattr) {
- Printv(classes,cgetattr,getattr,0);
- }
- if (!have_repr) {
- /* Supply a repr method for this class */
- Printv(repr,
- tab4, "def __repr__(self):\n",
- tab8, "return \"<C ", class_name," instance at %s>\" % (self.this,)\n",
- 0);
-
- Printv(classes,repr,0);
- // emitAddPragmas(classes,(char*)"__class__",(char*)tab4);
- }
+ /* ------------------------------------------------------------
+ * memberconstantHandler()
+ * ------------------------------------------------------------ */
- /* Now build the real class with a normal constructor */
- Printv(classes,
- "class ", class_name, "Ptr(", class_name, "):\n",
- tab4, "def __init__(self,this):\n",
- tab8, "self.this = this\n",
- tab8, "self.thisown = 0\n",
- tab8, "self.__class__ = ", class_name, "\n",
- "\n", additional, "\n",
- 0);
-
- Printv(classes,imethod,"\n",0);
- Delete(pyclass);
- Delete(imethod);
- Delete(setattr);
- Delete(getattr);
- Delete(additional);
- }
- Delete(ptrclass);
- Delete(repr);
-}
+ 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;
-/* -----------------------------------------------------------------------------
- * PYTHON::cpp_inherit() - Handle inheritance
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::cpp_inherit(List *bases) {
- char *bc;
- String *base;
- int first_base = 0;
-
- if (!shadow) {
- this->Language::cpp_inherit(bases);
- return;
+ if (shadow) {
+ Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(class_name,symname), "\n", NIL);
+ }
+ return SWIG_OK;
}
- /* We'll inherit variables and constants, but not methods */
- this->Language::cpp_inherit(bases);
+ /* ------------------------------------------------------------
+ * pythoncode() - Output python code into the shadow file
+ * ------------------------------------------------------------ */
- if (!bases) return;
- base_class = NewString("");
+ String *pythoncode(String *code, const String *indent) {
+ String *out = NewString("");
+ String *temp;
+ char *t;
+ if (!indent) indent = "";
- /* Now tell the Python module that we're inheriting from a base class */
+ temp = NewString(code);
- for (base = Firstitem(bases); base; base = Nextitem(bases)) {
- String *bs = NewString(base);
- SwigType_add_pointer(bs);
- bc = GetChar(hash,bs);
- if (bc) {
- if (first_base) Putc(',',base_class);
- Printv(base_class,bc,0);
- first_base = 1;
+ t = Char(temp);
+ if (*t == '{') {
+ Delitem(temp,0);
+ Delitem(temp,DOH_END);
}
- Delete(bs);
- }
- if (!first_base) {
- Delete(base_class);
- base_class = 0;
+ /* 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;
}
-}
-/* -----------------------------------------------------------------------------
- * PYTHON::cpp_variable() - Add a member variable
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::cpp_variable(DOH *node) {
- char *name, *iname;
- SwigType *t;
- char *realname;
- int inhash = 0;
- int oldshadow = shadow;
- char cname[512];
-
- if (shadow) shadow = shadow | PYSHADOW_MEMBER;
- this->Language::cpp_variable(node);
- shadow = oldshadow;
-
- if (shadow) {
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
- have_getattr = 1;
- have_setattr = 1;
- realname = iname ? iname : name;
-
- /* Check to see if we've already seen this */
- sprintf(cname,"python:%s::%s:",class_name,realname);
- if (Getattr(symbols,cname)) return;
-
- Setattr(symbols,cname,cname);
-
- /* Figure out if we've seen this datatype before */
- if (is_shadow(t)) inhash = 1;
-
- if (ReadOnly) {
- /* *setattr << tab8 << tab4 << "raise RuntimeError, \'Member is read-only\'\n"; */
- } else {
- Printv(csetattr, tab8, "\"", realname, "\" : ", module, ".", Swig_name_set(Swig_name_member(class_name,realname)), ",\n", 0);
- }
- if (inhash) {
- Printv(cgetattr, tab8, "\"", realname, "\" : lambda x : ", is_shadow(t), "Ptr(", module, ".", Swig_name_get(Swig_name_member(class_name,realname)), "(x)),\n", 0);
+ /* ------------------------------------------------------------
+ * 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 {
- Printv(cgetattr, tab8, "\"", realname, "\" : ", module, ".", Swig_name_get(Swig_name_member(class_name,realname)),",\n", 0);
+ Language::insertDirective(n);
}
+ return SWIG_OK;
}
-}
+};
/* -----------------------------------------------------------------------------
- * PYTHON::cpp_declare_const()
+ * swig_python() - Instantiate module
* ----------------------------------------------------------------------------- */
-void
-PYTHON::cpp_constant(DOH *node) {
- char *name, *iname, *value;
- SwigType *type;
- char *realname;
- int oldshadow = shadow;
- char cname[512];
-
- if (shadow) shadow = shadow | PYSHADOW_MEMBER;
- this->Language::cpp_constant(node);
- shadow = oldshadow;
-
- if (shadow) {
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- type = Getattr(node,"type");
- value = GetChar(node,"value");
- realname = iname ? iname : name;
-
- /* Check to see if we've already seen this */
- sprintf(cname,"python:%s::%s", class_name, realname);
- if (Getattr(symbols,cname)) return;
- Setattr(symbols,cname,cname);
- Printv(cinit, tab4, realname, " = ", module, ".", Swig_name_member(class_name,realname), "\n", 0);
- }
-}
-/* -----------------------------------------------------------------------------
- * PYTHON::add_typedef() - Manage typedef's for shadow classes
- * ----------------------------------------------------------------------------- */
-void
-PYTHON::add_typedef(SwigType *t, String *name) {
- if (!shadow) return;
- if (is_shadow(t)) {
- DOH *node = NewHash();
- Setname(node,name);
- Setattr(node,"scriptname", is_shadow(t));
- Setattr(node,"classtype","");
- cpp_class_decl(node);
- }
+extern "C" Language *
+swig_python(void) {
+ return new PYTHON();
}
diff --git a/Source/Modules1.1/python.h b/Source/Modules1.1/python.h
deleted file mode 100644
index 16b0eef1e..000000000
--- a/Source/Modules1.1/python.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************************
- * 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.
- *******************************************************************************/
-
-/**************************************************************************
- * $Header$
- *
- * python.h
- *
- * Header file for Python module. Warning ; this is work in progress.
- **************************************************************************/
-
-class PYTHON : public Language {
-protected:
- void get_pointer(char *src, char *dest, SwigType *t, String *f, char *ret);
- void add_method(String *name, String *function, int kw);
- char *usage_func(char *, SwigType *, ParmList *);
-
-public :
-
- // Don't change any of this
- virtual void parse_args(int, char *argv[]);
- virtual void initialize(String *);
- virtual void function(DOH *node);
- virtual void variable(DOH *node);
- virtual void constant(DOH *node);
- virtual void nativefunction(DOH *);
- virtual void close(void);
- virtual void create_command(String *, String *);
- virtual void import(String *modname);
-
- // C++ extensions---for creating shadow classes
-
- virtual void cpp_memberfunction(DOH *);
- virtual void cpp_constructor(DOH *);
- virtual void cpp_destructor(DOH *);
- virtual void cpp_open_class(DOH *);
- virtual void cpp_close_class();
- virtual void cpp_inherit(List *bases);
- virtual void cpp_variable(DOH *);
- virtual void cpp_constant(DOH *);
- virtual void cpp_class_decl(DOH *);
- virtual void pragma(DOH *node);
- virtual void add_typedef(SwigType *t, String *name);
-};
-
-#define PYSHADOW_MEMBER 0x2
-
-
-
-
diff --git a/Source/Modules1.1/ruby.cxx b/Source/Modules1.1/ruby.cxx
index ffb64a876..f5f0a796a 100644
--- a/Source/Modules1.1/ruby.cxx
+++ b/Source/Modules1.1/ruby.cxx
@@ -10,16 +10,17 @@
*
********************************************************************/
-static char cvsroot[] = "$Header$";
+char cvsroot_ruby_cxx[] = "$Header$";
-#include "swig11.h"
-#include "ruby.h"
+#include "swigmod.h"
+
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
#include <ctype.h>
#include <string.h>
-
-/* for debug */
-#define P(obj) printf("\"%s\"\n", Char(Str(obj)))
+#include <limits.h> /* for INT_MAX */
class RClass {
private:
@@ -27,1482 +28,1413 @@ class RClass {
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;
- String *aliases;
- String *includes;
- Hash *freemethods;
- Hash *predmethods;
+ int constructor_defined;
int destructor_defined;
- RClass(void) {
- freemethods = NewHash();
- predmethods = NewHash();
- destructor_defined = 0;
+ RClass() {
+ temp = NewString("");
name = NewString("");
cname = NewString("");
+ mname = NewString("");
vname = NewString("");
type = NewString("");
prefix = NewString("");
header = NewString("");
init = NewString("");
- aliases = NewString("");
- includes = NewString("");
- temp = 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(aliases);
- Delete(includes);
- Delete(freemethods);
- Delete(predmethods);
Delete(temp);
}
- void set_name(char *cn, char *rn, char *valn) {
+ 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",name);
- Printv(prefix,(rn ? rn : cn), "_", 0);
+ Printf(vname,"c%s.klass",name);
+ Clear(prefix);
+ Printv(prefix,(rn ? rn : cn), "_", NIL);
}
- char *strip(char *s) {
- if (strncmp(s, Char(prefix), Len(prefix)) != 0)
- return s;
+ char *strip(const String_or_char *s) {
Clear(temp);
- Append(temp,s);
- Replace(temp,prefix,"",DOH_REPLACE_ANY);
+ Append(temp, s);
+ if (Strncmp(s, prefix, Len(prefix)) == 0) {
+ Replaceall(temp,prefix,"");
+ }
return Char(temp);
}
};
-static char *usage = (char*)"\
+#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\
- -module name - Set module name\n\
+ -ldflags - Print runtime libraries to link with\n\
-feature name - Set feature name (used by `require')\n";
-
-static char *module = 0;
-static char *modvar = 0;
-static char *feature = 0;
-static String *other_extern = 0;
-static String *other_init = 0;
-static char *import_file;
-
-static int current;
-
-enum {
- NO_CPP,
- MEMBER_FUNC,
- CONSTRUCTOR,
- DESTRUCTOR,
- MEMBER_VAR,
- CLASS_CONST,
- STATIC_FUNC,
- STATIC_VAR
-};
-
-static Hash *classes; /* key=cname val=RClass */
-static RClass *klass; /* Currently processing class */
-static Hash *special_methods; /* Python style special method name table */
-
+#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))
-/* ---------------------------------------------------------------------
- * RUBY::parse_args(int argc, char *argv[])
- *
- * Parse command line options and initializes variables.
- * --------------------------------------------------------------------- */
-
-void RUBY::parse_args(int argc, char *argv[]) {
- /* 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 = new char [strlen(name)+1];
- strcpy(feature, name);
+
+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);
- Swig_mark_arg(i+1);
- i++;
- } else {
- Swig_arg_error();
}
- } else if (strcmp(argv[i],"-help") == 0) {
- Printf(stderr,"%s\n", usage);
}
}
+
+ /* 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();
}
- /* Set location of SWIG library */
- Swig_swiglib_set("ruby");
- /* Add a symbol to the parser for conditional compilation */
- Preprocessor_define((void *) "SWIGRUBY", 0);
- Swig_set_config_file("ruby.i");
-}
+ /* ---------------------------------------------------------------------
+ * top()
+ * --------------------------------------------------------------------- */
+ virtual int top(Node *n) {
-static void insert_file(char *filename, File *file) {
- if (Swig_insert_file(filename, file) == -1) {
- Printf(stderr,
- "SWIG : Fatal error. "
- "Unable to locate %s. (Possible installation problem).\n",
- filename);
- Swig_exit (EXIT_FAILURE);
- }
-}
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n,"outfile");
-/* ---------------------------------------------------------------------
- * RUBY::initialize()
- *
- * Produces an initialization function. Assumes that the module
- * name has already been specified.
- * --------------------------------------------------------------------- */
-
-void RUBY::initialize(String *modname) {
- import_file = 0;
- current = NO_CPP;
- klass = 0;
- classes = NewHash();
- special_methods = NewHash();
- other_extern = NewString("");
- other_init = NewString("");
-
- /* 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?");
+ 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__", "[]=");
- /* Numeric */
- Setattr(special_methods, "__add__", "+");
- Setattr(special_methods, "__sub__", "-");
- Setattr(special_methods, "__mul__", "*");
- Setattr(special_methods, "__div__", "/");
- Setattr(special_methods, "__mod__", "%");
- Setattr(special_methods, "__divmod__", "divmod");
- Setattr(special_methods, "__pow__", "**");
- Setattr(special_methods, "__lshift__", "<<");
- Setattr(special_methods, "__rshift__", ">>");
- Setattr(special_methods, "__and__", "&");
- Setattr(special_methods, "__xor__", "^");
- Setattr(special_methods, "__or__", "|");
- Setattr(special_methods, "__neg__", "-@");
- Setattr(special_methods, "__pos__", "+@");
- Setattr(special_methods, "__abs__", "abs");
- Setattr(special_methods, "__invert__", "~");
- Setattr(special_methods, "__int__", "to_i");
- Setattr(special_methods, "__float__", "to_f");
- Setattr(special_methods, "__coerce__", "coerce");
-
- Swig_banner(f_header);
-
- Printf(f_header,"/* Implementation : RUBY */\n\n");
- Printf(f_header,"#define SWIGRUBY\n");
-
- insert_file((char*)"common.swg", f_header);
- insert_file((char*)"ruby.swg", f_header);
- if (NoInclude) {
- insert_file((char*)"rubydec.swg", f_header);
- } else {
- insert_file((char*)"rubydef.swg", f_header);
- }
+ 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_setbase(value,(char*)"void");
- SwigType_add_pointer(value);
- SwigType_typedef(value,(char*)"VALUE");
- Delete(value);
+ /* typedef void *VALUE */
+ SwigType *value = NewSwigType(T_VOID);
+ SwigType_add_pointer(value);
+ SwigType_typedef(value,(char*)"VALUE");
+ Delete(value);
- /* Old set_module code */
+ /* Set module name */
+ set_module(Char(Getattr(n,"name")));
- if (!module) {
- module = new char[Len(modname)+1];
- strcpy(module, Char(modname));
+ 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;
}
- if (!feature) {
- feature = new char[strlen(module)+1];
- strcpy(feature, module);
+
+ /* -----------------------------------------------------------------------------
+ * 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);
}
- /* module name must be a constant. */
- module[0] = toupper(module[0]);
- modvar = new char[1+strlen(module)+1];
- modvar[0] = 'm';
- strcpy(modvar+1, module);
+ /* ---------------------------------------------------------------------
+ * 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;
+ }
- /* Old init code */
+ /* ---------------------------------------------------------------------
+ * create_command(Node *n, char *iname)
+ *
+ * Creates a new command from a C function.
+ * iname = Name of function in scripting language
+ * --------------------------------------------------------------------- */
- 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);
- Printf(f_header,"\n%s\n", other_extern);
+ void create_command(Node *n, const String_or_char *iname) {
- /* 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",
- other_init,
- "\n",
- 0);
-
- Printv(f_init, tab4, modvar, " = rb_define_module(\"", module, "\");\n",
- "_mSWIG = rb_define_module_under(", modvar, ", \"SWIG\");\n",
- 0);
- 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",
- 0);
- Printf(f_init,"\n");
- klass = new RClass();
-}
+ 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);
+ }
-/* ---------------------------------------------------------------------
- * RUBY::close(void)
- *
- * Finish the initialization function. Close any additional files and
- * resources in use.
- * --------------------------------------------------------------------- */
-
-void RUBY::close(void) {
- /* Finish off our init function */
- Printf(f_init,"}\n");
- SwigType_emit_type_table(f_header,f_wrappers);
-}
+ 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");
+ }
-/* --------------------------------------------------------------------------
- * RUBY::nativefunction()
- * -------------------------------------------------------------------------- */
-void
-RUBY::nativefunction(DOH *node) {
- Printf(stderr,"%s:%d. Adding native function %s not supported (ignored).\n", Getfile(node), Getline(node), Getattr(node,"scriptname"));
-}
+ SwigType *pt = Getattr(p,"type");
+ String *pn = Getattr(p,"name");
+ String *ln = Getattr(p,"lname");
-/* ---------------------------------------------------------------------
- * RUBY::make_wrapper_name(char *cname)
- *
- * Creates a name for a wrapper function
- * iname = Name of the function in scripting language
- * --------------------------------------------------------------------- */
-
-String *RUBY::make_wrapper_name(char *iname) {
- String *wname = Swig_name_wrapper(iname);
- Replace(wname, "?", "_p", DOH_REPLACE_ANY);
- Replace(wname, "!", "_bang", DOH_REPLACE_ANY);
- return wname;
-}
+ /* 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);
-/* ---------------------------------------------------------------------
- * RUBY::create_command(char *cname, char *iname)
- *
- * Creates a new command from a C function.
- * cname = Name of the C function
- * iname = Name of function in scripting language
- * argc = Number of arguments
- * --------------------------------------------------------------------- */
-
-static int create_argc = 0;
-
-void RUBY::create_command(String *scname, String *siname) {
- char *cname, *iname;
- int argc = create_argc;
- cname = Char(scname);
- iname = Char(siname);
- String *wname = make_wrapper_name(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);
- }
+ sprintf(target,"%s", Char(ln));
- String *s = NewString("");
- String *temp = NewString("");
- char argcs[32];
- sprintf(argcs,"%d",argc);
-
- switch (current) {
- case MEMBER_FUNC:
- Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"",
- iname, "\", ", wname, ", ", argcs, ");\n", 0);
-
- break;
- case CONSTRUCTOR:
- Printv(s, tab4, "rb_define_singleton_method(", klass->vname,
- ", \"new\", ", wname, ", ", argcs, ");\n", 0);
- Replace(klass->init,"$constructor", s, DOH_REPLACE_ANY);
- break;
- case MEMBER_VAR:
- Append(temp,iname);
- Replace(temp,"_set", "=", DOH_REPLACE_ANY);
- Replace(temp,"_get", "", DOH_REPLACE_ANY);
- Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"",
- temp, "\", ", wname, ", ", argcs, ");\n", 0);
- break;
- case STATIC_FUNC:
- Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname,
- ", \"", iname, "\", ", wname, ", ", argcs, ");\n", 0);
- break;
- default:
- Printv(s, tab4, "rb_define_module_function(", modvar, ", \"",
- iname, "\", ", wname, ", ", argcs, ");\n",0);
- Printv(f_init,s,0);
- break;
- }
- Delete(s);
- Delete(temp);
-}
+ 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);
+ }
-/* ---------------------------------------------------------------------
- * RUBY::function()
- *
- * Create a function declaration and register it with the interpreter.
- * --------------------------------------------------------------------- */
-
-void RUBY::function(DOH *node) {
- char *name, *iname;
- SwigType *t;
- ParmList *l;
-
- char source[256], target[256];
- char *tm;
- String *cleanup, *outarg;
- Wrapper *f;
- int i;
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
- l = Getattr(node,"parms");
-
- /* Ruby needs no destructor wrapper */
- if (current == DESTRUCTOR) {
- Wrapper *dummy = NewWrapper();
- emit_func_call(node,dummy);
- Delete(dummy);
- return;
+ /* 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");
+ }
+ }
}
- char mname[256], inamebuf[256];
- int predicate = 0, need_result = 0;
-
- cleanup = NewString("");
- outarg = NewString("");
- f = NewWrapper();
-
- switch (current) {
- case MEMBER_FUNC:
- case MEMBER_VAR:
- case STATIC_FUNC:
- strcpy(mname, klass->strip(iname));
- if (Getattr(klass->predmethods, mname)) {
- predicate = 1;
- sprintf(inamebuf,"%s?",iname);
- iname = inamebuf;
+ /* ---------------------------------------------------------------------
+ * 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);
+ }
}
- break;
- }
- String *wname = make_wrapper_name(iname);
-
- /* Get number of arguments */
- int numarg = ParmList_numarg(l);
- int numopt = check_numopt(l);
-
- int start = 0;
- int use_self = 0;
- switch (current) {
- case MEMBER_FUNC:
- case MEMBER_VAR:
- numarg--;
- start++;
- use_self = 1;
- break;
}
- int numreq = 0;
- int numoptreal = 0;
- Parm *p = l;
- for (i = 0; i < start; i++) p = Getnext(p);
- for (i = start; p; i++, p = Getnext(p)) {
- if (!Getignore(p)) {
- if (i >= ParmList_len(l) - numopt) numoptreal++;
- else numreq++;
+ /* ---------------------------------------------------------------------
+ * 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);
+ }
}
}
- int vararg = (numoptreal != 0);
-
- /* Now write the wrapper function itself */
- Printv(f, "static VALUE\n", wname, "(", 0);
- if (vararg) {
- Printv(f, "int argc, VALUE *argv, VALUE self",0);
- } else {
- Printv(f, "VALUE self", 0);
- p = l;
- for (i = 0; i < start; i++) p = Getnext(p);
- for (i = start; p; i++, p = Getnext(p)) {
- if (!Getignore(p)) {
- Printf(f,", VALUE varg%d", i);
+
+ /* ---------------------------------------------------------------------
+ * 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);
}
}
}
- Printf(f,") {\n");
-
- /* Emit all of the local variables for holding arguments. */
- if (vararg) {
- p = l;
- for (i = 0; i < start; i++) p = Getnext(p);
- for (i = start; p; i++, p = Getnext(p)) {
- if (!Getignore(p)) {
- char s[256];
- sprintf(s,"varg%d",i);
- Wrapper_add_localv(f,s,"VALUE",s,0);
- }
+
+ /* ---------------------------------------------------------------------
+ * 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;
}
- int pcount = emit_args(node,f);
-
- /* Emit count to check the number of arguments */
- if (vararg) {
- int numscan = 0;
- for (p = l, i = 0; i < start; i++) p = Getnext(p);
- for (i = start; p; i++, p = Getnext(p)) {
- if (!Getignore(p)) numscan++;
+
+ /* ---------------------------------------------------------------------
+ * 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;
}
- Printf(f,"rb_scan_args(argc, argv, \"%d%d\"", (numarg-numoptreal), numscan - (numarg-numoptreal));
- for (p = l, i = 0; i < start; i++) p = Getnext(p);
- for (i = start; p; i++, p = Getnext(p)) {
- if (!Getignore(p)) {
- Printf(f,", &varg%d", i);
- }
+
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *kwargs = NewString("");
+ Wrapper *f = NewWrapper();
+
+ /* Rename predicate methods */
+ if (Getattr(n, "feature:predicate")) {
+ Append(symname, "?");
}
- Printf(f,");\n");
- }
- /* Now walk the function parameter list and generate code */
- /* to get arguments */
- int j = 0; /* Total number of non-optional arguments */
-
- p = l;
- for (i = 0; i < pcount ; i++, p = Getnext(p)) {
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
-
- /* Produce string representation of source and target arguments */
- int selfp = (use_self && i == 0);
- if (selfp)
- strcpy(source,"self");
- else
- sprintf(source,"varg%d",i);
-
- sprintf(target,"%s", Char(Getlname(p)));
-
- if (!Getignore(p)) {
- char *tab = (char*)tab4;
- if (j >= (pcount-numopt)) { /* Check if parsing an optional argument */
- Printf(f," if (argc > %d) {\n", j - start);
- tab = (char*)tab8;
- }
+ /* 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);
+ }
- /* Get typemap for this argument */
- tm = ruby_typemap_lookup((char*)"in",pt,pn,source,target,f);
- if (tm) {
- String *s = NewString(tm);
- Printv(f, s, 0);
- Replace(f, "$arg", source, DOH_REPLACE_ANY);
- Delete(s);
+ /* 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(stderr,"%s:%d. No typemapping for datatype %s\n",
- Getfile(node), Getline(node), SwigType_str(pt,0));
+ Printf(f->code,"if (argc < %d)\n", numreq-start);
}
- if (j >= (pcount-numopt))
- Printv(f, tab4, "} \n", 0);
- j++;
+ Printf(f->code,"rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc);\n",numreq-start);
}
- /* Check to see if there was any sort of a constaint typemap */
- tm = ruby_typemap_lookup((char*)"check",pt,pn,source,target);
- if (tm) {
- String *s = NewString(tm);
- Printv(f, s, 0);
- Replace(f, "$arg", source, DOH_REPLACE_ANY);
- Delete(s);
+ /* 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);
}
- /* Check if there was any cleanup code (save it for later) */
- tm = ruby_typemap_lookup((char*)"freearg",pt,pn,target,source);
- if (tm) {
- String *s = NewString(tm);
- Printv(cleanup,s,0);
- Replace(cleanup,"$arg",source, DOH_REPLACE_ANY);
- Delete(s);
+ /* 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);
}
- tm = ruby_typemap_lookup((char*)"argout",pt,pn,target,(char*)"vresult");
- if (tm) {
- String *s = NewString(tm);
+ 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;
- Printv(outarg, s, 0);
- Replace(outarg, "$arg", source, DOH_REPLACE_ANY);
- Delete(s);
+ 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));
+ }
+ }
}
- }
- /* Now write code to make the function call */
- emit_func_call(node,f);
+ /* 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);
- /* Return value if necessary */
- if (SwigType_type(t) != T_VOID) {
- need_result = 1;
- if (predicate) {
- Printv(f, tab4, "vresult = (result ? Qtrue : Qfalse);\n", 0);
- } else {
- tm = ruby_typemap_lookup((char*)"out",t,name,(char*)"result",(char*)"vresult");
+ /* 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) {
- String *s = NewString(tm);
- Printv(f, s, 0);
- Delete(s);
- } else {
- Printf(stderr,"%s:%d. No return typemap for datatype %s\n",
- Getfile(node), Getline(node),SwigType_str(t,0));
+ Replaceall(tm,"$source","result");
+ Printv(f->code,tm, "\n",NIL);
}
}
- }
-
- /* Dump argument output code; */
- Printv(f,outarg,0);
- /* Dump the argument cleanup code */
- Printv(f,cleanup,0);
-
- /* Look for any remaining cleanup. This processes the %new directive */
- if (NewObject) {
- tm = ruby_typemap_lookup((char*)"newfree",t,name,(char*)"result",(char*)"");
+ /* Special processing on return value. */
+ tm = Swig_typemap_lookup_new("ret",n,"result",0);
if (tm) {
- String *s = NewString(tm);
- Printv(f,s, 0);
- Delete(s);
+ Replaceall(tm,"$source","result");
+ Printv(f->code,tm, NIL);
}
- }
-
- /* free pragma */
- if (current == MEMBER_FUNC && Getattr(klass->freemethods, mname)) {
- Printv(f, tab4, "DATA_PTR(self) = 0;\n", 0);
- }
-
- /* Special processing on return value. */
- tm = ruby_typemap_lookup((char*)"ret",t,name,(char*)"result",(char*)"");
- if (tm) {
- String *s = NewString(tm);
- Printv(f,s, 0);
- }
- /* Wrap things up (in a manner of speaking) */
- if (need_result) {
- Wrapper_add_local(f,"vresult","VALUE vresult = Qnil");
- Printv(f, tab4, "return vresult;\n}\n", 0);
- } else {
- Printv(f, tab4, "return Qnil;\n}\n", 0);
- }
-
- /* Substitute the cleanup code */
- Replace(f,"$cleanup",cleanup, DOH_REPLACE_ANY);
+ /* 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);
+ }
- /* Emit the function */
- Printf(f_wrappers,"%s", f);
+ /* Substitute the cleanup code */
+ Replaceall(f->code,"$cleanup",cleanup);
- /* Now register the function with the language */
- create_argc = vararg ? -1 : numarg;
- create_command(name, iname);
- Delete(cleanup);
- Delete(outarg);
- Delete(f);
-}
+ /* Emit the function */
+ Wrapper_print(f, f_wrappers);
-/* ---------------------------------------------------------------------
- * RUBY::variable()
- *
- * Create a link to a C variable.
- * --------------------------------------------------------------------- */
-
-void RUBY::variable(DOH *node) {
- char *name, *iname;
- SwigType *t;
-
- char *tm, *source;
-
- String *getfname, *setfname;
- Wrapper *getf, *setf;
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
-
- getf = NewWrapper();
- setf = NewWrapper();
-
- /* create getter */
- getfname = NewString(Swig_name_get(name));
- Replace(getfname,"::", "_", DOH_REPLACE_ANY); /* FIXME: Swig_name_get bug? */
- Printv(getf, "static VALUE\n", getfname, "(", 0);
- Printf(getf, "VALUE self");
- Printf(getf, ") {\n");
- Wrapper_add_local(getf,"_val","VALUE _val");
-
- if (SwigType_type(t) == T_USER) {
- /* Hack this into a pointer */
- String *pname = NewString("");
- Printv(pname, "&", name, 0);
- source = Char(pname);
- } else {
- source = name;
+ /* 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;
}
- tm = ruby_typemap_lookup((char*)"varout",t,name,source,(char*)"_val");
- if (!tm)
- tm = ruby_typemap_lookup((char*)"out",t,name,source,(char*)"_val");
- if (tm) {
- String *s = NewString(tm);
- Printv(getf,s, 0);
- Delete(s);
- } else {
- Printf(stderr,"%s:%d. Unable to link with variable type %s\n",
- Getfile(node), Getline(node),SwigType_str(t,0));
- }
- Printv(getf, tab4, "return _val;\n}\n", 0);
- Printf(f_wrappers,"%s", getf);
-
- if (ReadOnly) {
- setfname = NewString("NULL");
- } else {
- /* create setter */
- char *target;
-
- setfname = NewString(Swig_name_set(name));
- Replace(setfname,"::", "_", DOH_REPLACE_ANY); /* FIXME: Swig_name_get bug? */
- Printv(setf, "static VALUE\n", setfname, "(VALUE self, ", 0);
- Printf(setf, "VALUE _val) {\n");
-
- if (SwigType_type(t) == T_USER) {
- SwigType_add_pointer(t);
- Wrapper_add_localv(setf,"temp",SwigType_lstr(t,0), "temp",0);
- SwigType_del_pointer(t);
- target = "temp";
+ /* ------------------------------------------------------------
+ * 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 {
- target = name;
+ Printf(tmp, "VALUE argv[%d]", maxargs);
}
-
- tm = ruby_typemap_lookup((char*)"varin",t,name,(char*)"_val",target);
- if (!tm)
- tm = ruby_typemap_lookup((char*)"in",t,name,(char*)"_val",target);
+ 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) {
- String *s = NewString(tm);
- Printv(setf,s,0);
- Delete(s);
+ Replaceall(tm,"$result","_val");
+ Replaceall(tm,"$target","_val");
+ Replaceall(tm,"$source",name);
+ Printv(getf->code,tm, NIL);
} else {
- Printf(stderr,"%s:%d. Unable to link with variable type %s\n",
- Getfile(node), Getline(node),SwigType_str(t,0));
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number,
+ "Unable to read variable of type %s\n", SwigType_str(t,0));
}
- if (SwigType_type(t) == T_USER) {
- Printv(setf, name, " = *temp;\n",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);
}
- Printv(setf, tab4, "return _val;\n",0);
- Printf(setf,"}\n");
- Printf(f_wrappers,"%s", setf);
- }
- /* define accessor method */
- if (CPlusPlus) {
- Insert(getfname,0,"VALUEFUNC(");
- Append(getfname,")");
- Insert(setfname,0,"VALUEFUNC(");
- Append(setfname,")");
- }
+ /* 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",
- 0);
- if (!ReadOnly) {
+ String *s = NewString("");
+ switch (current) {
+ case STATIC_VAR:
+ /* C++ class variable */
Printv(s,
tab4, "rb_define_singleton_method(", klass->vname, ", \"",
- klass->strip(iname), "=\", ", setfname, ", 1);\n",
- 0);
- }
- Printv(klass->init,s,0);
- break;
- default:
- /* C global variable */
- /* wrapped in Ruby module attribute */
- Printv(s,
- tab4, "rb_define_singleton_method(", modvar, ", \"",
- iname, "\", ", getfname, ", 0);\n",
- 0);
- if (!ReadOnly) {
+ 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, "=\", ", setfname, ", 1);\n",
- 0);
+ 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;
}
- Printv(f_init,s,0);
- Delete(s);
- break;
+ Delete(getfname);
+ Delete(setfname);
+ DelWrapper(setf);
+ DelWrapper(getf);
+ return SWIG_OK;
}
- Delete(getfname);
- Delete(setfname);
- Delete(setf);
- Delete(getf);
-}
-
-
-/* ---------------------------------------------------------------------
- * RUBY::validate_const_name(char *name)
- *
- * Validate constant name.
- * --------------------------------------------------------------------- */
-
-char *RUBY::validate_const_name(char *name) {
- if (!name || name[0] == '\0')
- return name;
-
- if (isupper(name[0]))
- return name;
- if (islower(name[0])) {
- name[0] = toupper(name[0]);
- /* Printf(stderr,"%s:%d. Wrong constant/class/module name "
- "(corrected to `%s')\n", Getfile(node), Getline(node), name); */
- Printf(stderr,"?:?. Wrong constant/class/module name (corrected to '%s')\n", name);
+ /* ---------------------------------------------------------------------
+ * 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;
}
-
- Printf(stderr,"?:?. Wrong constant/class/module name\n");
- return name;
-}
-
-/* ---------------------------------------------------------------------
- * RUBY::constant()
- *
- * Makes a constant.
- * --------------------------------------------------------------------- */
-
-void RUBY::constant(DOH *node) {
- char *tm;
- char *name, *iname;
- SwigType *type;
- char *value;
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- type = Getattr(node,"type");
- value = GetChar(node,"value");
-
- if (current == CLASS_CONST)
- iname = klass->strip(iname);
-
- tm = ruby_typemap_lookup((char*)"const",type,name,value,iname);
- if (tm) {
- String *str = NewString(tm);
- Replace(str,"$value",value, DOH_REPLACE_ANY);
+
+ /* ---------------------------------------------------------------------
+ * 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) {
- Replace(str,"$module", klass->vname, DOH_REPLACE_ANY);
- Printv(klass->init, str, 0);
- } else {
- Replace(str,"$module", modvar, DOH_REPLACE_ANY);
- Printf(f_init,"%s", str);
+ iname = klass->strip(iname);
}
- Delete(str);
- } else {
- Printf(stderr,"%s:%d. Unable to create constant %s = %s\n",
- Getfile(node), Getline(node), SwigType_str(type,0), value);
- }
-}
-
-/* ---------------------------------------------------------------------
- * RUBY::ruby_typemap_lookup(char *op, SwigType *type, char *pname, char *source, char *target, WrapperFunction *f = 0)
- *
- * Ruby specific typemap_lookup.
- * op = string code for type of mapping
- * type = the datatype
- * pname = an optional parameter name
- * source = a string with the source variable
- * target = a string containing the target value
- * f = a wrapper function object (optional)
- * --------------------------------------------------------------------- */
-
-char *RUBY::ruby_typemap_lookup(char *op, SwigType *type, String_or_char *pname, char *source, char *target, Wrapper *f) {
- static String *s = 0;
- char *tm;
- String *target_replace = NewString(target);
- target = Char(target_replace);
- int type_code, add_pointer = 0;
-
- if (SwigType_type(type) == T_USER)
- add_pointer = 1;
- if (add_pointer)
- SwigType_add_pointer(type);
- type_code = SwigType_type(type);
-
- RClass *cls = RCLASS(classes, SwigType_base(type));
-
- if (!s) s = NewString("");
- Clear(s);
-
- if ((strcmp("out", op) == 0 || strcmp("in", op) == 0)
- && Cmp(SwigType_base(type), "VALUE") == 0) {
- Printf(s,"$target = $source;\n");
- } else if (strcmp("out", op) == 0
- && (type_code == T_POINTER || type_code == T_REFERENCE)
- && cls) {
- const char *vname = (current == CONSTRUCTOR ? "self" : Char(cls->vname));
- Printv(s, "$target = Wrap_", cls->cname, "(", vname, ", $source);\n",0);
- } else if (strcmp("in", op)==0
- && (type_code == T_POINTER || type_code == T_REFERENCE)
- && cls) {
- Printv(s, "Get_", cls->cname, "($source, $target);\n", 0);
- } else {
- if (add_pointer) {
- SwigType_del_pointer(type);
- add_pointer = 0;
+ 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);
}
-
- tm = Swig_typemap_lookup(op, type, pname, source, target, f);
+ String *tm = Swig_typemap_lookup_new("constant", n, value, 0);
if (tm) {
- Delete(target_replace);
- Printv(s, tm, "\n", 0);
- } else {
- Clear(s);
- if (strcmp("in", op) == 0) {
- String *v = NewString("");
- if (from_VALUE(type, (char*)"$source", (char*)"$target", v))
- Printv(s, v, "\n", 0);
- Delete(v);
- } else if (strcmp("out", op) == 0) {
- String *v = NewString("");
- if (to_VALUE(type, (char*)"$source", v))
- Printv(s, "$target = ", v, ";\n", 0);
- Delete(v);
- } else if (strcmp("const", op) == 0) {
- String *v = NewString("");
- if (to_VALUE(type, (char*)"$value", v, 1)) {
- Printv(s, "rb_define_const($module, \"$target\", ", v, ");\n", 0);
- validate_const_name(target);
- }
- Delete(v);
+ 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;
}
- if (source && strlen(source) > 0)
- Replace(s,"$source",source, DOH_REPLACE_ANY);
- if (target && strlen(target) > 0)
- Replace(s,"$target",target, DOH_REPLACE_ANY);
- Replace(s,"$type", SwigType_str(type,0), DOH_REPLACE_ANY);
-
- if (add_pointer) {
- SwigType_del_pointer(type);
- add_pointer = 0;
- }
-
- if (Len(s) == 0)
- return NULL;
- return Char(s);
-}
-
-
-static void
-convert_pointer(char *src, SwigType *t, String *f) {
- SwigType_remember(t);
- Printv(f, "SWIG_NewPointerObj((void *)", src, ", SWIGTYPE", SwigType_manglestr(t), ")", 0);
-}
-
-/* ---------------------------------------------------------------------
- * RUBY::to_VALUE(SwigType *type, char *value, literal)
- *
- * Makes a VALUE (as a string)
- * type = Datatype of the C value
- * value = C value (as a string)
- * str = resulting code (as a string)
- * raw = value is raw string (not quoted) ?
- * --------------------------------------------------------------------- */
-
-int RUBY::to_VALUE(SwigType *type, char *value, String *str, int raw) {
- Clear(str);
- switch(SwigType_type(type)) {
- case T_INT:
- case T_SHORT:
- case T_LONG:
- case T_SCHAR:
- Printv(str, "INT2NUM(", value, ")", 0);
- break;
- case T_UINT:
- case T_USHORT:
- case T_ULONG:
- case T_UCHAR:
- Printv(str,"UINT2NUM(", value, ")", 0);
- break;
- case T_DOUBLE:
- case T_FLOAT:
- Printv(str, "rb_float_new(", value, ")", 0);
- break;
- case T_CHAR:
- Printv(str, "rb_str_new(&", value, ", 1)", 0);
- break;
- case T_BOOL:
- Printv(str, "(", value, " ? Qtrue : Qfalse)", 0);
- break;
- case T_STRING:
- if (raw)
- Printv(str, "rb_str_new2(\"", value, "\")", 0);
- else
- Printv(str, "rb_str_new2(", value, ")", 0);
- break;
- case T_ARRAY:
- {
- SwigType *aop;
- SwigType *ta = Copy(type);
- aop = SwigType_pop(ta);
- if (SwigType_type(ta) == T_CHAR) {
- Printf(str, "rb_str_new2(%s)", value);
- break;
- }
- convert_pointer(value, type, str);
- break;
+
+ /* -----------------------------------------------------------------------------
+ * 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);
}
- case T_POINTER: case T_REFERENCE:
- convert_pointer(value, type, str);
- break;
- case T_USER:
- SwigType_add_pointer(type);
- convert_pointer(value, type, str);
- SwigType_del_pointer(type);
- break;
- default:
- break;
+ Delete(namestr);
+ return Language::classDeclaration(n);
}
- if (Len(str) == 0)
- return 0;
- return 1;
-}
+ /* ----------------------------------------------------------------------
+ * classHandler()
+ * ---------------------------------------------------------------------- */
-static void
-get_pointer(char *src, char *dest, SwigType *t, String *f) {
- SwigType *lt;
+ virtual int classHandler(Node *n) {
- SwigType_remember(t);
- Printv(f, dest, " = (", SwigType_lstr(t,0), ")SWIG_ConvertPtr(", src, ", ", 0);
+ String *name = Getattr(n,"name");
+ String *symname = Getattr(n,"sym:name");
+ String *namestr = SwigType_namestr(name); // does template expansion
- lt = Swig_clocal_type(t);
- if (Cmp(lt,"p.void") == 0) {
- Printv(f, "0);", 0);
- } else {
- Printv(f, "SWIGTYPE", SwigType_manglestr(t), ");", 0);
- }
- Delete(lt);
-}
+ klass = RCLASS(classes, Char(namestr));
+ assert(klass);
+ Delete(namestr);
+ String *valid_name = NewString(symname);
+ validate_const_name(Char(valid_name), "class");
-/* ---------------------------------------------------------------------
- * RUBY::from_VALUE(SwigType *type, char *value)
- *
- * extract VALUE
- * type = Datatype of the C value
- * value = Ruby VALUE (as a string)
- * target= target C variable (as a string)
- * str = resulting code (as a string)
- * --------------------------------------------------------------------- */
-
-int RUBY::from_VALUE(SwigType *type, char *value, char *target, String *str) {
- Clear(str);
- switch(SwigType_type(type)) {
- case T_INT:
- Printv(str, target, " = NUM2INT(", value, ");", 0);
- break;
- case T_LONG:
- Printv(str, target, " = NUM2LONG(", value, ");", 0);
- break;
- case T_SHORT:
- Printv(str, target, " = NUM2SHRT(", value, ");", 0);
- break;
- case T_UINT:
- Printv(str, target, " = NUM2UINT(", value, ");", 0);
- break;
- case T_ULONG:
- Printv(str, target, " = NUM2ULONG(", value, ");", 0);
- break;
- case T_USHORT:
- Printv(str, target, " = NUM2USHRT(", value, ");", 0);
- break;
- case T_DOUBLE:
- case T_FLOAT:
- Printv(str, target, " = NUM2DBL(", value, ");", 0);
- break;
- case T_CHAR: case T_SCHAR: case T_UCHAR:
- Printv(str, target, " = NUM2CHR(", value, ");", 0);
- break;
- case T_BOOL:
- Printv(str, target, " = RTEST(", value, ");", 0);
- break;
- case T_STRING:
- Printv(str, target, " = STR2CSTR(", value, ");", 0);
- break;
- case T_ARRAY:
- {
- SwigType *aop;
- SwigType *ta = Copy(type);
- aop = SwigType_pop(ta);
- if (SwigType_type(ta) == T_CHAR) {
- String *dim = SwigType_array_getdim(aop,0);
- if (dim && Len(dim)) {
- Printf(str, "strncpy(%s, STR2CSTR(%s), %s);", target, value, dim);
+ 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);
}
- break;
}
- get_pointer(value, target, type, str);
- break;
+ Delete(modules);
}
- case T_POINTER: case T_REFERENCE:
- get_pointer(value, target, type, str);
- break;
- case T_USER:
- SwigType_add_pointer(type);
- get_pointer(value, target, type, str);
- SwigType_del_pointer(type);
- break;
- default:
- break;
- }
- if (Len(str) == 0) return 0;
- return 1;
-}
-/* ----------------------------------------------------------------------
- * void RUBY::cpp_open_class(char *classname, char *classrename, char *ctype, int strip)
- *
- * Open a new C++ class.
- *
- * INPUTS:
- * name = Real name of the C++ class
- * rename = New name of the class (if %name was used)
- * ctype = Class type (struct, class, union, etc...)
- * strip = Flag indicating whether we should strip the
- * class type off
- *
- * This function is in charge of creating a new class. The SWIG parser has
- * already processed the entire class definition prior to calling this
- * function (which should simplify things considerably).
- *
- * ---------------------------------------------------------------------- */
-
-void RUBY::cpp_open_class(DOH *node) {
- this->Language::cpp_open_class(node);
-
- char *cname = GetChar(node,"name");
- char *rename = GetChar(node,"scriptname");
- char *ctype = GetChar(node,"classtype");
- int strip = GetInt(node,"strip");
-
- klass = RCLASS(classes, cname);
-
- if (strip) {
- Clear(klass->type);
- Append(klass->type, klass->cname);
- } else {
- Clear(klass->type);
- Printv(klass->type, ctype, " ", klass->cname,0);
- }
+ 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);
+ }
+ }
- Printv(klass->header, "\nstatic VALUE ", klass->vname, ";\n", 0);
- Printv(klass->init, "\n", tab4, 0);
- Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar,
- ", \"", klass->name, "\", $super);\n", 0);
- Replace(klass->includes,"$class", klass->vname, DOH_REPLACE_ANY);
- Printv(klass->init, klass->includes,0);
- Printv(klass->init, "$constructor",0);
-
- Printv(klass->header,
- "$markproto",
- "$freeproto",
- "#define Wrap_", klass->cname, "(klass, ptr) (\\\n",
- tab4, "(ptr) ? Data_Wrap_Struct(klass",
- ", $markfunc, $freefunc, ptr) : Qnil )\n",
- "#define Get_", klass->cname, "(val, ptr) {\\\n",
- tab4, "if (NIL_P(val)) ptr = NULL;\\\n",
- tab4, "else {\\\n",
- tab8, "if (!rb_obj_is_kind_of(val, ", klass->vname, "))\\\n",
- tab8, tab4, "rb_raise(rb_eTypeError, \"wrong argument type",
- " (expected ", klass->name, ")\");\\\n",
- tab8, "Data_Get_Struct(val, ", klass->type, ", ptr);\\\n",
- tab8, "if (!ptr) rb_raise(rb_eRuntimeError, \"",
- "This ", klass->name, " already released\");\\\n",
- tab4, "}\\\n",
- "}\n",
- 0);
+ /* 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", "");
-/* ---------------------------------------------------------------------
- * void RUBY::cpp_close_class()
- *
- * Close the current class
- * --------------------------------------------------------------------- */
+ Printv(f_header, klass->header,NIL);
-void RUBY::cpp_close_class() {
- this->Language::cpp_close_class();
+ 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);
- Replace(klass->header,"$markfunc", "0", DOH_REPLACE_ANY);
- Replace(klass->header,"$markproto", "", DOH_REPLACE_ANY);
- if (!klass->destructor_defined) {
- Replace(klass->header,"$freefunc", "0", DOH_REPLACE_ANY);
- Replace(klass->header,"$freeproto", "", DOH_REPLACE_ANY);
+ Printv(f_init,klass->init,NIL);
+ klass = 0;
+ return SWIG_OK;
}
- Printv(f_header, klass->header,0);
-
- Replace(klass->aliases,"$class", klass->vname, DOH_REPLACE_ANY);
- Printv(klass->init, klass->aliases,0);
-
- String *s = NewString("");
- Printv(s, tab4, "rb_undef_method(CLASS_OF(", klass->vname,
- "), \"new\");\n", 0);
- Replace(klass->init,"$constructor", s, DOH_REPLACE_ANY);
- Replace(klass->init,"$super", "rb_cObject", DOH_REPLACE_ANY);
-
- Printv(f_init,klass->init,0);
- klass = 0;
-}
-
-/* ----------------------------------------------------------------------
- * void RUBY::cpp_inherit(char **baseclass, int mode)
- *
- * Inherit attributes from given baseclass.
- *
- * INPUT:
- * baseclass = NULL terminate list of baseclasses
- *
- * --------------------------------------------------------------------- */
+ /* ----------------------------------------------------------------------
+ * 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;
+ }
-void RUBY::cpp_inherit(List *bases) {
- if (!bases) return;
- String *base;
- for (base = Firstitem(bases); base; base = Nextitem(bases)) {
- RClass *super = RCLASS(classes, Char(base));
- if (super) {
- Replace(klass->init,"$super", super->vname, DOH_REPLACE_ANY);
- break; /* ignore multiple inheritance */
+ /* ---------------------------------------------------------------------
+ * 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;
}
-}
-
-/* ----------------------------------------------------------------------
- * void RUBY::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l)
- *
- * Method for adding C++ member function
- *
- * INPUTS:
- * name - name of the member function
- * iname - renaming (if given)
- * t - Return datatype
- * l - Parameter list
- *
- * 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.
- *
- * --------------------------------------------------------------------- */
-
-void RUBY::cpp_memberfunction(DOH *node) {
- current = MEMBER_FUNC;
- this->Language::cpp_memberfunction(node);
- current = NO_CPP;
-}
-/* ---------------------------------------------------------------------
- * void RUBY::cpp_constructor(char *name, char *iname, ParmList *l)
- *
- * Method for adding C++ member constructor
- *
- * INPUTS:
- * name - Name of the constructor (usually same as classname)
- * iname - Renamed version
- * l - parameters
- * -------------------------------------------------------------------- */
-
-void RUBY::cpp_constructor(DOH *node) {
- current = CONSTRUCTOR;
- this->Language::cpp_constructor(node);
- current = NO_CPP;
-}
-
-/* ---------------------------------------------------------------------
- * void RUBY::cpp_destructor(char *name, char *iname)
- *
- * Method for adding C++ member destructor
- *
- * INPUT:
- * name - Name of the destructor (classname)
- * iname - Renamed destructor
- *
- * -------------------------------------------------------------------- */
-
-void RUBY::cpp_destructor(DOH *node) {
- char *name, *newname;
-
- name = GetChar(node,"name");
- newname = GetChar(node,"scriptname");
- current = DESTRUCTOR;
- this->Language::cpp_destructor(node);
-
- String *freefunc = NewString("");
- String *freeproto = NewString("");
- String *freebody = NewString("");
-
- Printv(freefunc, "free_", klass->cname, 0);
- Printv(freeproto, "static void ", freefunc, "(", klass->type, " *);\n", 0);
- Printv(freebody, "static void\n",
- freefunc, "(", klass->type, " *", Swig_cparm_name(0,0), ") {\n",
- tab4, 0);
- if (AddMethods) {
- Printv(freebody, Swig_name_destroy(name), "(", Swig_cparm_name(0,0), ")", 0);
- } else {
- /* When no addmethods mode, swig emits no destroy function. */
- if (CPlusPlus)
- Printv(freebody, Swig_cppdestructor_call(), 0);
- else
- Printv(freebody, Swig_cdestructor_call(), 0);
- }
- Printv(freebody, ";\n}\n", 0);
- if (CPlusPlus) {
- Insert(freefunc,0,"VOIDFUNC(");
- Append(freefunc,")");
+ /* ---------------------------------------------------------------------
+ * 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;
}
- Replace(klass->header,"$freefunc", freefunc, DOH_REPLACE_ANY);
- Replace(klass->header,"$freeproto", freeproto, DOH_REPLACE_ANY);
- Printv(f_wrappers, freebody, 0);
-
- klass->destructor_defined = 1;
- current = NO_CPP;
- Delete(freefunc);
- Delete(freeproto);
- Delete(freebody);
-}
-
-/* ---------------------------------------------------------------------
- * void RUBY::cpp_variable(char *name, char *iname, SwigType *t)
- *
- * Wrap a C++ data member
- *
- * INPUTS :
- * name = Name of the C++ member
- * iname = Name as used in the interpreter
- * t = Datatype
- *
- * This creates a pair of functions to set/get the variable of a member.
- * -------------------------------------------------------------------- */
-
-void RUBY::cpp_variable(DOH *node) {
- current = MEMBER_VAR;
- this->Language::cpp_variable(node);
- current = NO_CPP;
-}
-
-/* -----------------------------------------------------------------------
- * void RUBY::cpp_static_func(char *name, char *iname, SwigType *t, ParmList *l)
- *
- * Wrap a static C++ function
- *
- * INPUTS:
- * name = Real name of the function
- * iname = New name in interpreter
- * t = Return datatype
- * l = Parameters
- * ---------------------------------------------------------------------- */
-
-void RUBY::cpp_staticfunction(DOH *node) {
- current = STATIC_FUNC;
- this->Language::cpp_staticfunction(node);
- current = NO_CPP;
-}
-
-/* ----------------------------------------------------------------------
- * void RUBY::cpp_declare_const(char *name, char *iname, SwigType *t, char *value)
- *
- * Create a C++ constant
- *
- * INPUTS :
- * name = Real name of the constant
- * iname = new name
- * t = Datatype
- * value = value as a string
- *
- * --------------------------------------------------------------------- */
-
-
-void RUBY::cpp_constant(DOH *node) {
- current = CLASS_CONST;
- this->Language::cpp_constant(node);
- current = NO_CPP;
-}
-
-/* ---------------------------------------------------------------------
- * void RUBY::cpp_static_var(char *name, char *iname, SwigType *t)
- *
- * Wrap a static C++ variable
- *
- * INPUT :
- * name = name of the variable
- * iname = interpreter name
- * t = Datatype
- *
- * --------------------------------------------------------------------- */
-
-void RUBY::cpp_staticvariable(DOH *node) {
- current = STATIC_VAR;
- this->Language::cpp_staticvariable(node);
- current = NO_CPP;
-}
-
-/* -----------------------------------------------------------------------
- * RUBY::cpp_class_decl(char *name, char *rename, char *type)
- *
- * A forward class declaration
- * ----------------------------------------------------------------------- */
-
-void RUBY::cpp_class_decl(DOH *node) {
- String *cname = Getattr(node,"name");
- String *rename = Getattr(node,"scriptname");
- String *ctype = Getattr(node,"classtype");
- String *valid_name = NewString((rename ? rename : cname));
- validate_const_name(Char(valid_name));
- klass->set_name(Char(cname), Char(rename), Char(valid_name));
- SET_RCLASS(classes, Char(cname), klass);
- if (ctype && Len(ctype) > 0) {
- char temp[256];
- sprintf(temp,"%s %s", Char(ctype), Char(cname));
- SET_RCLASS(classes, temp, klass);
+ /* -----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ *
+ * Wrap a static C++ function
+ * ---------------------------------------------------------------------- */
+
+ virtual int
+ staticmemberfunctionHandler(Node *n) {
+ current = STATIC_FUNC;
+ Language::staticmemberfunctionHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
}
- /*
- char s[256];
- sprintf(s,"extern VALUE %s;\n", Char(klass->vname));
- Printf(f_header, s);
- */
- klass = new RClass();
- Delete(valid_name);
-}
-
-/* --------------------------------------------------------------------
- * void RUBY::pragma(char *target, char *var, char *value)
- *
- * A pragma declaration
- * -------------------------------------------------------------------- */
-
-void RUBY::pragma(DOH *node) {
- String *cmd = Getattr(node,"name");
- String *value = Getattr(node,"value");
- if (Cmp(cmd, "free") == 0) {
- char name[64];
- if (sscanf(Char(value), " %s ", name) != 1) {
- Printf(stderr, "%s:%d. Invalid free pragma.\n",
- Getfile(node), Getline(node));
- return;
- }
- Setattr(klass->freemethods, name, name);
- } else if (Cmp(cmd, "include") == 0) {
- char name[64];
- if (sscanf(Char(value), " %s ", name) != 1) {
- Printf(stderr, "%s:%d. Invalid include pragma.\n",
- Getfile(node), Getline(node));
- return;
- }
- Printv(klass->includes,tab4, "rb_include_module($class, ",
- "rb_eval_string(\"", name, "\"));\n", 0);
- } else if (Cmp(cmd, "alias") == 0) {
- char alias[64], name[64];
- if (sscanf(Char(value), " %s %s ", alias, name) != 2) {
- Printf(stderr, "%s:%d. Invalid alias pragma.\n",
- Getfile(node), Getline(node));
- return;
- }
- Printv(klass->aliases, tab4, "rb_define_alias($class, ",
- "\"", alias, "\", \"", name, "\");\n", 0);
- } else if (Cmp(cmd, "pred") == 0) {
- char *tok;
- tok = strtok(Char(value), " \t");
- while (tok) {
- Setattr(klass->predmethods, tok, tok);
- tok = strtok(0, " \t");
- }
- } else if (Cmp(cmd, "debug") == 0) {
- Printf(f_header, "/* %s */\n", value);
- Printf(f_wrappers, "/* %s */\n", value);
- Printf(f_init, "/* %s */\n", value);
- Printf(stderr, "%s\n", value);
+
+ /* ----------------------------------------------------------------------
+ * 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;
}
-}
-
-/* ---------------------------------------------------------------------
- * RUBY::import(char *filename)
- *
- * Imports a SWIG module as a separate file.
- *---------------------------------------------------------------------- */
+}; /* class RUBY */
+
+/* -----------------------------------------------------------------------------
+ * swig_ruby() - Instantiate module
+ * ----------------------------------------------------------------------------- */
-void RUBY::import(String *modname) {
- Printf(f_init, "rb_f_require(Qnil, rb_str_new2(\"%s\"));\n", modname);
+extern "C" Language *
+swig_ruby(void) {
+ return new RUBY();
}
+
/*
* Local Variables:
* c-basic-offset: 2
* End:
*/
-
-
-
-
diff --git a/Source/Modules1.1/ruby.h b/Source/Modules1.1/ruby.h
deleted file mode 100644
index 8844945ea..000000000
--- a/Source/Modules1.1/ruby.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/********************************************************************
- * Ruby module for SWIG
- *
- * $Header$
- *
- * Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
- * Copyright (C) 2000 Information-technology Promotion Agency, Japan
- *
- * Masaki Fukushima
- *
- ********************************************************************/
-
-class RUBY : public Language {
- protected:
- virtual String *make_wrapper_name(char *cname);
- virtual char *validate_const_name(char *name);
- virtual char *ruby_typemap_lookup(char *, SwigType *, String_or_char *, char *, char *, Wrapper * = 0);
- virtual int to_VALUE(SwigType *, char *, DOHString *, int = 0);
- virtual int from_VALUE(SwigType *, char *, char *, DOHString *);
- public:
- /* Virtual functions required by the SWIG parser */
- virtual void parse_args(int, char *argv[]);
- virtual void initialize(String *module);
- virtual void function(DOH *node);
- virtual void variable(DOH *node);
- virtual void constant(DOH *node);
- virtual void close(void);
- virtual void nativefunction(DOH *);
- virtual void create_command(String *, String *);
- virtual void import(String *);
-
- /* C++ language extensions. */
- virtual void cpp_memberfunction(DOH *);
- virtual void cpp_constructor(DOH *);
- virtual void cpp_destructor(DOH *);
- virtual void cpp_open_class(DOH *);
- virtual void cpp_close_class();
- virtual void cpp_inherit(List *bases);
- virtual void cpp_variable(DOH *);
- virtual void cpp_staticfunction(DOH *);
- virtual void cpp_constant(DOH *);
- virtual void cpp_staticvariable(DOH *);
-
- /* Declaration of a class, but not a full definition */
- virtual void cpp_class_decl(DOH *);
-
- /* Pragma directive */
- virtual void pragma(DOH *node);
-};
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * End:
- */
diff --git a/Source/Modules1.1/s-exp.cxx b/Source/Modules1.1/s-exp.cxx
new file mode 100644
index 000000000..2a9f2dcc1
--- /dev/null
+++ b/Source/Modules1.1/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<hanging_parens; i++)
+ Printf(out, ")");
+ hanging_parens = 0;
+ need_newline = true;
+ need_whitespace = true;
+ }
+ if (need_newline) {
+ Printf(out, "\n");
+ print_indent();
+ need_newline = false;
+ need_whitespace = false;
+ }
+ else if (need_whitespace) {
+ Printf(out, " ");
+ need_whitespace = false;
+ }
+ }
+
+ void print_lazy_whitespace()
+ {
+ need_whitespace = 1;
+ }
+
+ void print_lazy_newline()
+ {
+ need_newline = 1;
+ }
+
+ bool internal_key_p(DOH *key)
+ {
+ return ((Cmp(key,"nodeType") == 0)
+ || (Cmp(key,"firstChild") == 0)
+ || (Cmp(key,"lastChild") == 0)
+ || (Cmp(key,"parentNode") == 0)
+ || (Cmp(key,"nextSibling") == 0)
+ || (Cmp(key,"previousSibling") == 0)
+ || (Cmp(key,"csym:nextSibling") == 0)
+ || (Cmp(key,"csym:previousSibling") == 0)
+ || (Cmp(key,"typepass:visit") == 0)
+ || (Cmp(key,"allocate:visit") == 0)
+ || (*(Char(key)) == '$'));
+ }
+
+ bool boolean_key_p(DOH *key)
+ {
+ return ((Cmp(key,"allocate:default_constructor") == 0)
+ || (Cmp(key,"allocate:default_destructor") == 0)
+ || (Cmp(key,"allows_typedef") == 0)
+ || (Cmp(key,"feature:immutable") == 0));
+ }
+
+ bool list_key_p(DOH *key)
+ {
+ return ((Cmp(key, "parms") == 0)
+ || (Cmp(key, "baselist") == 0));
+ }
+
+ bool plist_key_p(DOH *key)
+ // true if KEY is the name of data that is a mapping from keys to
+ // values, which should be printed as a plist.
+ {
+ return ((Cmp(key, "typescope") == 0));
+ }
+
+ bool maybe_plist_key_p(DOH *key)
+ {
+ return (Strncmp(key, "tmap:", 5) == 0);
+ }
+
+ bool print_circle(DOH *obj, bool list_p)
+ // We have a complex object, which might be referenced several
+ // times, or even recursively. Use Lisp's reader notation for
+ // circular structures (#n#, #n=).
+ //
+ // An object can be printed in list-mode or object-mode; LIST_P toggles.
+ // return TRUE if OBJ still needs to be printed
+ {
+ flush_parens();
+ // Following is a silly hack. It works around the limitation of
+ // DOH's hash tables that only work with string keys!
+ char address[16];
+ sprintf(address, "%x%c", (unsigned int)obj, list_p ? 'L' : 'O');
+ DOH *placeholder = Getattr(print_circle_hash, address);
+ if (placeholder) {
+ Printv(out, placeholder, NIL);
+ return false;
+ }
+ else {
+ String *placeholder = NewStringf("#%d#", ++print_circle_count);
+ Setattr(print_circle_hash, address, placeholder);
+ Printf(out, "#%d=", print_circle_count);
+ return true;
+ }
+ }
+
+ void Sexp_print_value_of_key(DOH *value, DOH *key)
+ {
+ if ((Cmp(key, "parms") == 0) || (Cmp(key, "wrap:parms") == 0)
+ || (Cmp(key, "kwargs") == 0) || (Cmp(key, "pattern") == 0))
+ Sexp_print_parms(value);
+ else if (plist_key_p(key))
+ Sexp_print_plist(value);
+ else if (maybe_plist_key_p(key)) {
+ if (DohIsMapping(value))
+ Sexp_print_plist(value);
+ else
+ Sexp_print_doh(value);
+ }
+ else if (list_key_p(key))
+ Sexp_print_list(value);
+ else if (boolean_key_p(key))
+ Sexp_print_boolean(value);
+ else
+ Sexp_print_doh(value);
+ }
+
+ void Sexp_print_boolean(DOH *obj)
+ {
+ flush_parens();
+ /* See DOH/Doh/base.c, DohGetInt() */
+ if (DohIsString(obj)) {
+ if (atoi(Char(obj)) != 0)
+ Printf(out, "t");
+ else Printf(out, "nil");
+ }
+ else Printf(out, "nil");
+ }
+
+ void Sexp_print_list(DOH *obj)
+ {
+ if (print_circle(obj, true)) {
+ open_paren(NIL);
+ for (; obj; obj = nextSibling(obj)) {
+ Sexp_print_doh(obj);
+ print_lazy_whitespace();
+ }
+ close_paren(true);
+ }
+ }
+
+ void Sexp_print_parms(DOH *obj)
+ // print it as a list of plists
+ {
+ if (print_circle(obj, true)) {
+ open_paren(NIL);
+ for (; obj; obj = nextSibling(obj)) {
+ if (DohIsMapping(obj)) {
+ DOH *k;
+ open_paren(NIL);
+ for (k = Firstkey(obj); k; k = Nextkey(obj)) {
+ if (!internal_key_p(k)) {
+ DOH *value = Getattr(obj, k);
+ Sexp_print_as_keyword(k);
+ Sexp_print_value_of_key(value, k);
+ print_lazy_whitespace();
+ }
+ }
+ close_paren(true);
+ }
+ else Sexp_print_doh(obj);
+ print_lazy_whitespace();
+ }
+ close_paren(true);
+ }
+ }
+
+ void Sexp_print_doh(DOH *obj)
+ {
+ flush_parens();
+ if (DohIsString(obj)) {
+ String *o = Str(obj);
+ Replaceall( o, "\\", "\\\\" );
+ Replaceall( o, "\"", "\\\"" );
+ Printf(out,"\"%s\"", o);
+ Delete(o);
+ }
+ else {
+ if (print_circle(obj, false)) {
+ // Dispatch type
+ if (nodeType(obj)) {
+ Sexp_print_node(obj);
+ }
+
+ else if (DohIsMapping(obj)) {
+ DOH *k;
+ open_paren(NIL);
+ for (k = Firstkey(obj); k; k = Nextkey(obj)) {
+ if (!internal_key_p(k)) {
+ DOH *value = Getattr(obj, k);
+ flush_parens();
+ open_paren(NIL);
+ Sexp_print_doh(k);
+ Printf(out, " . ");
+ Sexp_print_value_of_key(value, k);
+ close_paren();
+ }
+ }
+ close_paren();
+ }
+ else {
+ // What is it?
+ Printf(out,"#<DOH %x>", 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/Modules1.1/swig11.h b/Source/Modules1.1/swig11.h
deleted file mode 100644
index cfc222861..000000000
--- a/Source/Modules1.1/swig11.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -----------------------------------------------------------------------------
- * swig11.h
- *
- * Main header file for the SWIG1.1 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.
- *
- * $Header$
- * ----------------------------------------------------------------------------- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "swigver.h"
-
-extern "C" {
-#include "swig.h"
-}
-
-/* Global variables. */
-
-extern FILE *f_runtime; // Runtime code
-extern DOH *f_header; // Headers
-extern DOH *f_wrappers; // Wrappers
-extern DOH *f_init; // Initialization code
-extern FILE *f_input;
-extern int CPlusPlus; // C++ mode
-extern int AddMethods; // AddMethods mode
-extern int NewObject; // NewObject mode
-extern int NoInclude; // NoInclude flag
-extern char output_dir[512]; // Output directory
-extern int Verbose;
-extern int ReadOnly; // Read only mode
-extern int Native; // Native mode
-
-/* Miscellaneous stuff */
-
-#define tab4 " "
-#define tab8 " "
-
-// Modes for different types of inheritance
-
-#define INHERIT_FUNC 0x1
-#define INHERIT_VAR 0x2
-#define INHERIT_CONST 0x4
-#define INHERIT_ALL (INHERIT_FUNC | INHERIT_VAR | INHERIT_CONST)
-
-/* Language Class */
-class Language {
-public:
- virtual void parse_args(int argc, char *argv[]) = 0;
- virtual void initialize(String *modname) = 0;
- virtual void close(void) = 0;
- virtual void import(String *modname);
-
- /* Basic function, variable, constant API (required) */
- virtual void function(DOH *node) = 0;
- virtual void variable(DOH *node) = 0;
- virtual void constant(DOH *node) = 0;
- virtual void nativefunction(DOH *node);
- virtual void create_command(String *cname, String *iname);
-
- /* Optional C++ handling */
- virtual void cpp_open_class(DOH *node);
- virtual void cpp_memberfunction(DOH *node);
- virtual void cpp_constructor(DOH *node);
- virtual void cpp_destructor(DOH *node);
- virtual void cpp_variable(DOH *node);
- virtual void cpp_staticfunction(DOH *node);
- virtual void cpp_constant(DOH *node);
- virtual void cpp_staticvariable(DOH *node);
- virtual void cpp_close_class();
-
- virtual void cpp_class_decl(DOH *node);
- virtual void cpp_inherit(List *bases);
-
- /* Miscellaneous features */
-
- virtual void add_typedef(SwigType *t, String *name);
- virtual void pragma(DOH *node);
-
-};
-
-/* Emit functions */
-
-extern void new_create_function(char *, char *, SwigType *, ParmList *);
-extern void emit_set_get(DOH *node);
-extern void emit_set_action(DOHString_or_char *decl);
-
-/* These are in the new core */
-extern "C" void *Preprocessor_define(void *, int);
-
-// Misc
-
-extern int emit_args(DOH *node, Wrapper *f);
-extern void emit_func_call(DOH *node, Wrapper *f);
-extern int check_numopt(ParmList *);
-extern void SWIG_config_file(const String_or_char *);
-
-/* C++ utility functions */
-extern int cplus_check_abstract(DOH *node);
-extern void cplus_walk_inherit(DOH *cls, void (*action)(DOH *base, void *clientdata), void *clientdata);
-
-extern Language *lang;
-
-/* swig11.h ends here */
-
-
-
-
-
-
-
-
diff --git a/Source/Modules1.1/swigmod.h b/Source/Modules1.1/swigmod.h
new file mode 100644
index 000000000..2668b0cb5
--- /dev/null
+++ b/Source/Modules1.1/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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#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/Modules1.1/tcl8.cxx b/Source/Modules1.1/tcl8.cxx
index 7f2913082..0f9738715 100644
--- a/Source/Modules1.1/tcl8.cxx
+++ b/Source/Modules1.1/tcl8.cxx
@@ -9,1112 +9,824 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_tcl8_cxx[] = "$Header$";
-#include "swig11.h"
-#include "tcl8.h"
-#include <ctype.h>
+#include "swigmod.h"
-static char *usage = (char*)"\
-Tcl 8.0 Options (available with -tcl)\n\
- -module name - Set name of module\n\
+#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\
- -noobject - Omit code for object oriented interface.\n\n";
-
-static String *mod_init = 0;
-static String *cmd_info = 0;
-static String *var_info = 0;
-static String *methods = 0;
-static String *attributes = 0;
+ -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 int shadow = 1;
-static String *init_name = 0;
-static String *ns_name = 0;
-static int have_constructor;
-static int have_destructor;
-
-static String *class_name = 0;
-static String *class_type = 0;
-static String *real_classname = 0;
-static Hash *class_methods = 0;
-static Hash *class_attributes = 0;
-static Hash *repeatcmd = 0;
-
-
-/* -----------------------------------------------------------------------------
- * TCL8::parse_args()
- * ----------------------------------------------------------------------------- */
-
-void
-TCL8::parse_args(int argc, char *argv[]) {
- int i;
- Swig_swiglib_set("tcl");
+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[]) {
- for (i = 1; i < argc; i++) {
+ 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],"-namespace") == 0) {
- nspace = 1;
+ if (strcmp(argv[i],"-prefix") == 0) {
+ if (argv[i+1]) {
+ prefix = NewString(argv[i+1]);
Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-noobject") == 0) {
- shadow = 0;
+ 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);
- } else if (strcmp(argv[i],"-help") == 0) {
- fputs(usage,stderr);
+ 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();
}
- if ((nspace) && module) {
- ns_name = Copy(module);
- } else if (prefix) {
- ns_name = Copy(prefix);
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
- }
- if (prefix)
- Append(prefix,"_");
-
- Preprocessor_define((void *) "SWIGTCL 1",0);
- Preprocessor_define((void *) "SWIGTCL8 1", 0);
- Swig_set_config_file("tcl8.swg");
-}
+ virtual int top(Node *n) {
-/* -----------------------------------------------------------------------------
- * TCL8::initialize()
- * ----------------------------------------------------------------------------- */
-
-void
-TCL8::initialize(String *modname) {
-
- mod_init = NewString("");
- cmd_info = NewString("");
- var_info = NewString("");
- repeatcmd = NewHash();
- class_methods = NewHash();
- class_attributes = NewHash();
-
- Swig_banner(f_runtime);
-
- /* Include a Tcl configuration file */
- if (NoInclude) {
- Printf(f_runtime,"#define SWIG_NOINCLUDE\n");
- }
- if (Swig_insert_file("common.swg",f_runtime) == -1) {
- Printf(stderr,"SWIG : Fatal error. Unable to locate 'common.swg' in SWIG library.\n");
- Swig_exit (EXIT_FAILURE);
- }
- if (Swig_insert_file("swigtcl8.swg",f_runtime) == -1) {
- Printf(stderr,"SWIG : Fatal error. Unable to locate 'swigtcl8.swg' in SWIG library.\n");
- Swig_exit (EXIT_FAILURE);
- }
- if (!module) module = NewString(modname);
-
- /* Fix capitalization for Tcl */
- char *c = Char(module);
- while (c && *c) {
- *c = (char) tolower(*c);
- c++;
- }
- /* Now create an initialization function */
- init_name = NewStringf("%s_Init",module);
- c = Char(init_name);
- *c = toupper(*c);
-
- if (!ns_name) ns_name = Copy(module);
-
- /* If namespaces have been specified, set the prefix to the module name */
- if ((nspace) && (!prefix)) {
- prefix = NewStringf("%s_",module);
- } else {
- prefix = NewString("");
- }
-
- Printf(f_header,"#define SWIG_init %s\n", init_name);
- if (!module) module = NewString("swig");
- 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_namespace \"\"\n\n");
- }
- Printf(f_header,"#ifdef __cplusplus\n");
- Printf(f_header,"extern \"C\" {\n");
- Printf(f_header,"#endif\n");
- Printf(f_header,"#ifdef MAC_TCL\n");
- Printf(f_header,"#pragma export on\n");
- Printf(f_header,"#endif\n");
- Printf(f_header,"SWIGEXPORT(int) %s(Tcl_Interp *);\n", init_name);
- Printf(f_header,"#ifdef MAC_TCL\n");
- Printf(f_header,"#pragma export off\n");
- Printf(f_header,"#endif\n");
- Printf(f_header,"#ifdef __cplusplus\n");
- Printf(f_header,"}\n");
- Printf(f_header,"#endif\n");
-
- Printf(f_init,"SWIGEXPORT(int) %s(Tcl_Interp *interp) {\n", init_name);
- Printf(f_init,"int i;\n");
- Printf(f_init,"if (interp == 0) return TCL_ERROR;\n");
-
- /* Check to see if we're adding support for Tcl8 nspaces */
- if (nspace) {
- Printf(f_init,"Tcl_Eval(interp,\"namespace eval %s { }\");\n", ns_name);
+ /* 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);
- Printf(cmd_info, "\nstatic swig_command_info swig_commands[] = {\n");
- Printf(var_info, "\nstatic swig_var_info swig_variables[] = {\n");
- Printv(f_init,
- "for (i = 0; swig_types_initial[i]; i++) {\n",
- "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n",
- "}\n", 0);
-}
-
-/* -----------------------------------------------------------------------------
- * TCL8::close()
- * ----------------------------------------------------------------------------- */
-
-void
-TCL8::close(void) {
-
- Printv(cmd_info, tab4, "{0, 0, 0}\n", "};\n",0);
- Printv(var_info, tab4, "{0,0,0,0}\n", "};\n",0);
-
- Printf(f_wrappers,"%s", cmd_info);
- Printf(f_wrappers,"%s", var_info);
-
- Printf(f_init,"for (i = 0; swig_commands[i].name; i++) {\n");
- Printf(f_init,"Tcl_CreateObjCommand(interp, (char *) swig_commands[i].name, swig_commands[i].wrapper, swig_commands[i].clientdata, NULL);\n");
- Printf(f_init,"}\n");
-
- Printf(f_init,"for (i = 0; swig_variables[i].name; i++) {\n");
- Printf(f_init,"Tcl_SetVar(interp, (char *) swig_variables[i].name, \"\", TCL_GLOBAL_ONLY);\n");
- Printf(f_init,"Tcl_TraceVar(interp, (char *) swig_variables[i].name, TCL_TRACE_READS | TCL_GLOBAL_ONLY, swig_variables[i].get, (ClientData) swig_variables[i].addr);\n");
- Printf(f_init,"Tcl_TraceVar(interp, (char *) swig_variables[i].name, TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, swig_variables[i].set, (ClientData) swig_variables[i].addr);\n");
- Printf(f_init,"}\n");
-
- /* Dump the pointer equivalency table */
- SwigType_emit_type_table(f_runtime, f_wrappers);
-
- /* Close the init function and quit */
- Printf(f_init,"return TCL_OK;\n");
- Printf(f_init,"}\n");
-}
-
-/* -----------------------------------------------------------------------------
- * TCL8::create_command()
- * ----------------------------------------------------------------------------- */
-
-void
-TCL8::create_command(String *cname, String *iname) {
-
- String *wname = Swig_name_wrapper(cname);
- Printv(cmd_info, tab4, "{ SWIG_prefix \"", iname, "\", ", wname, ", NULL},\n", 0);
-
- /* Add interpreter name to repeatcmd hash table. This hash is used in C++ code
- generation to try and find repeated wrapper functions. */
-
- Setattr(repeatcmd,iname,wname);
-}
-
-/* -----------------------------------------------------------------------------
- * TCL8::create_function()
- * ----------------------------------------------------------------------------- */
+ 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");
+ }
-void
-TCL8::function(DOH *node) {
- char *name, *iname;
- SwigType *d;
- ParmList *l;
- Parm *p;
- int pcount,i,j;
- char *tm;
- Wrapper *f;
- String *incode, *cleanup, *outarg, *argstr, *args;
- int numopt= 0;
-
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- d = Getattr(node,"type");
- l = Getattr(node,"parms");
-
- incode = NewString("");
- cleanup = NewString("");
- outarg = NewString("");
- argstr = NewString("\"");
- args = NewString("");
-
- f = NewWrapper();
- Printv(f,
- "static int\n ", Swig_name_wrapper(iname), "(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {\n",
- 0);
-
- /* Print out variables for storing arguments. */
- pcount = emit_args(node, f);
- numopt = check_numopt(l);
-
- /* Extract parameters. */
- i = 0;
- j = 0;
- p = l;
- while (p != 0) {
- char source[64];
- char target[64];
- char argnum[64];
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
-
- /* Produce string representations of the source and target arguments */
- sprintf(source,"objv[%d]",j+1);
- sprintf(target,"%s", Char(Getlname(p)));
- sprintf(argnum,"%d",j+1);
-
- /* See if this argument is being ignored */
- if (!Getignore(p)) {
- if (j == (pcount-numopt)) Putc('|',argstr);
- if ((tm = Swig_typemap_lookup((char*)"in",pt,pn,source,target,f))) {
- Putc('o',argstr);
- Printf(args,",0");
- Printf(incode,"%s\n", tm);
- Replace(incode,"$argnum",argnum, DOH_REPLACE_ANY);
- Replace(incode,"$arg",source, DOH_REPLACE_ANY);
- } else {
- switch(SwigType_type(pt)) {
- case T_INT:
- case T_UINT:
- Putc('i', argstr);
- Printf(args,",&%s",target);
- break;
-
- case T_BOOL:
- Putc('i',argstr);
- {
- char tb[32];
- sprintf(tb,"tempb%d",i);
- Wrapper_add_localv(f,tb,"int",tb,0);
- Printf(args,",&%s",tb);
- Printv(incode, target, " = (bool) ", tb, ";\n", 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");
}
- break;
-
- case T_SHORT:
- case T_USHORT:
- Putc('h',argstr);
- Printf(args,",&%s",target);
- break;
-
- case T_LONG:
- case T_ULONG:
- Putc('l',argstr);
- Printf(args,",&%s",target);
- break;
-
- case T_SCHAR:
- case T_UCHAR:
- Putc('b',argstr);
- Printf(args,",&%s", target);
- break;
-
- case T_FLOAT:
- Putc('f',argstr);
- Printf(args,",&%s", target);
- break;
-
- case T_DOUBLE:
- Putc('d',argstr);
- Printf(args,",&%s", target);
- break;
-
- case T_CHAR :
- Putc('c',argstr);
- Printf(args,",&%s",target);
- break;
-
- case T_VOID :
- break;
-
- case T_USER:
- SwigType_add_pointer(pt);
- SwigType_remember(pt);
- Putc('p',argstr);
- Printv(args, ",&", target, ", SWIGTYPE", SwigType_manglestr(pt), 0);
- SwigType_del_pointer(pt);
- break;
-
- case T_STRING:
- Putc('s',argstr);
- Printf(args,",&%s",target);
- break;
-
- case T_POINTER: case T_ARRAY: case T_REFERENCE:
- {
- SwigType *lt;
+ } else {
+ Printf(argstr,"%s",parse);
+ Printf(args,",&%s",ln);
+ if (Strcmp(parse,"p") == 0) {
+ SwigType *lt = SwigType_ltype(pt);
SwigType_remember(pt);
- Putc('p',argstr);
- lt = Swig_clocal_type(pt);
if (Cmp(lt,"p.void") == 0) {
- Printv(args, ",&", target, ", 0", 0);
+ Printf(args,",0");
} else {
- Printv(args, ",&", target, ", SWIGTYPE", SwigType_manglestr(pt), 0);
+ Printf(args,",SWIGTYPE%s", SwigType_manglestr(pt));
}
Delete(lt);
- break;
}
- default :
- Printf(stderr,"%s:%d: Unable to use type %s as a function argument.\n",
- Getfile(node), Getline(node), SwigType_str(pt,0));
- break;
}
+ 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);
}
- j++;
}
- /* Check to see if there was any sort of a constaint typemap */
- if ((tm = Swig_typemap_lookup((char*)"check",pt,pn,source,target,0))) {
- Printf(incode,"%s\n", tm);
- Replace(incode,"$argnum",argnum, DOH_REPLACE_ANY);
- Replace(incode,"$arg",source, DOH_REPLACE_ANY);
+
+ /* 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);
+ }
}
- /* Check if there was any cleanup code (save it for later) */
- if ((tm = Swig_typemap_lookup((char*)"freearg",pt,pn,target,(char*)"tcl_result",0))) {
- Printf(cleanup,"%s\n", tm);
- Replace(cleanup,"$argnum",argnum, DOH_REPLACE_ANY);
- Replace(cleanup,"$arg",source,DOH_REPLACE_ANY);
+
+ /* 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);
}
- /* Look for output arguments */
- if ((tm = Swig_typemap_lookup((char*)"argout",pt,pn,target,(char*)"tcl_result",0))) {
- Printf(outarg,"%s\n", tm);
- Replace(outarg,"$argnum",argnum, DOH_REPLACE_ANY);
- Replace(outarg,"$arg",source, DOH_REPLACE_ANY);
+
+ /* 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);
}
- i++;
- p = Getnext(p);
+ 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;
}
- Printf(argstr,":%s\"",usage_string(iname,d,l));
- Printv(f,
- "if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) return TCL_ERROR;\n",
- 0);
-
- Printv(f,incode,0);
-
- /* Now write code to make the function call */
- emit_func_call(node,f);
-
- /* Return value if necessary */
- if ((tm = Swig_typemap_lookup((char*)"out",d,name,(char*)"result",(char*)"tcl_result",0))) {
- Printf(f,"%s\n", tm);
- } else {
- 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:
- Printv(f, "Tcl_SetObjResult(interp,Tcl_NewIntObj((long) result));\n",0);
- break;
-
- /* Is a single character. We return it as a string */
- case T_CHAR :
- Printv(f, "Tcl_SetObjResult(interp,Tcl_NewStringObj(&result,1));\n",0);
- break;
-
- case T_DOUBLE :
- case T_FLOAT :
- Printv(f, "Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) result));\n",0);
- break;
-
- case T_USER :
-
- /* Okay. We're returning malloced memory at this point.
- Probably dangerous, but safe programming is for wimps. */
- SwigType_add_pointer(d);
- SwigType_remember(d);
- Printv(f, "Tcl_SetObjResult(interp,SWIG_NewPointerObj((void *) result,SWIGTYPE",
- SwigType_manglestr(d), "));\n", 0);
-
- SwigType_del_pointer(d);
- break;
-
- case T_STRING:
- Printv(f, "Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1));\n",0);
- break;
- case T_POINTER: case T_REFERENCE: case T_ARRAY:
- SwigType_remember(d);
- Printv(f, "Tcl_SetObjResult(interp,SWIG_NewPointerObj((void *) result,SWIGTYPE",
- SwigType_manglestr(d), "));\n",
- 0);
- break;
-
- case T_VOID:
- break;
-
- default :
- Printf(stderr,"%s:%d. Unable to use return type %s in function %s.\n",
- Getfile(node), Getline(node), SwigType_str(d,0), name);
- break;
+ /* ------------------------------------------------------------
+ * 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;
}
- /* Dump output argument code */
- Printv(f,outarg,0);
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
- /* Dump the argument cleanup code */
- Printv(f,cleanup,0);
+ 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;
- /* Look for any remaining cleanup */
- if (NewObject) {
- if ((tm = Swig_typemap_lookup((char*)"newfree",d,iname,(char*)"result",(char*)"",0))) {
- Printf(f,"%s\n", 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;
}
- if ((tm = Swig_typemap_lookup((char*)"ret",d,name,(char*)"result",(char*)"",0))) {
- Printf(f,"%s\n", tm);
- }
- Printv(f, "return TCL_OK;\n}\n", 0);
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
- /* Substitute the cleanup code */
- Replace(f,"$cleanup",cleanup,DOH_REPLACE_ANY);
- Replace(f,"$name", iname, DOH_REPLACE_ANY);
+ virtual int nativeWrapper(Node *n) {
+ String *name = Getattr(n,"sym:name");
+ String *funcname = Getattr(n,"wrap:name");
+ if (!addSymbol(funcname,n)) return SWIG_ERROR;
- /* Dump out the function */
- Printf(f_wrappers,"%s",f);
+ 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;
+ }
- /* Register the function with Tcl */
- Printv(cmd_info, tab4, "{ SWIG_prefix \"", iname, "\", ", Swig_name_wrapper(iname), ", NULL},\n", 0);
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
- Delete(incode);
- Delete(cleanup);
- Delete(outarg);
- Delete(argstr);
- Delete(args);
- Delete(f);
-}
+ virtual int classHandler(Node *n) {
+
+ String *mangled_classname = 0;
+ String *real_classname = 0;
-/* -----------------------------------------------------------------------------
- * TCL8::variable()
- * ----------------------------------------------------------------------------- */
+ have_constructor = 0;
+ have_destructor = 0;
+ destructor_action = 0;
-static Hash *setf = 0;
-static Hash *getf = 0;
+ class_name = Getattr(n,"sym:name");
+ if (!addSymbol(class_name,n)) return SWIG_ERROR;
-void
-TCL8::variable(DOH *node) {
- char *name, *iname;
- SwigType *t;
+ real_classname = Getattr(n,"name");
+ mangled_classname = Swig_name_mangle(real_classname);
- String *setname;
- String *getname;
+ 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);
- int isarray = 0;
- int readonly = 0;
- int setable = 1;
- int tc;
+ /* Generate normal wrappers */
+ Language::classHandler(n);
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- t = Getattr(node,"type");
+ 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);
- if (!setf) setf = NewHash();
- if (!getf) getf = NewHash();
+ // t = Copy(Getattr(n,"classtype"));
+ // SwigType_add_pointer(t);
- /* See if there were any typemaps */
- if (Swig_typemap_search((char *)"varin",t,name) || (Swig_typemap_search((char*)"varout",t,name))) {
- Printf(stderr,"%s:%d. Warning. varin/varout typemap methods not supported.",
- Getfile(node), Getline(node));
- }
+ String *rt = Copy(Getattr(n,"classtype"));
+ SwigType_add_pointer(rt);
- if (ReadOnly) readonly = 1;
- isarray = SwigType_isarray(t);
- tc = SwigType_type(t);
- setname = Getattr(setf,t);
- getname = Getattr(getf,t);
-
- /* Dump a collection of set/get functions suitable for variable tracing */
- if (!getname) {
- Wrapper *get, *set;
-
- setname = NewStringf("swig_%s_set", Swig_string_mangle(t));
- getname = NewStringf("swig_%s_get", Swig_string_mangle(t));
- get = NewWrapper();
- set = NewWrapper();
- Printv(set, "static char *", setname, "(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {\n",0);
- Printv(get, "static char *", getname, "(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {\n",0);
-
- SwigType *lt = Swig_clocal_type(t);
- if ((tc != T_USER) && (!isarray))
- SwigType_add_pointer(lt);
- Wrapper_add_localv(get,"addr",SwigType_lstr(lt,"addr"),0);
- Wrapper_add_localv(set,"addr",SwigType_lstr(lt,"addr"),0);
- Printv(set, "addr = (", SwigType_lstr(lt,0), ") clientData;\n", 0);
- Printv(get, "addr = (", SwigType_lstr(lt,0), ") clientData;\n", 0);
- if ((tc != T_USER) && (!isarray))
- SwigType_del_pointer(lt);
- Delete(lt);
- Wrapper_add_local(set, "value", "char *value");
- Wrapper_add_local(get, "value", "Tcl_Obj *value");
-
- Printv(set, "value = Tcl_GetVar2(interp, name1, name2, flags);\n",
- "if (!value) return NULL;\n", 0);
-
- switch(tc) {
- case T_INT:
- case T_SHORT:
- case T_USHORT:
- case T_LONG:
- case T_UCHAR:
- case T_SCHAR:
- case T_BOOL:
- Printv(set, "*(addr) = (", SwigType_str(t,0), ") atol(value);\n", 0);
- Wrapper_add_local(get,"value","Tcl_Obj *value");
- Printv(get,
- "value = Tcl_NewIntObj((int) *addr);\n",
- "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
- "Tcl_DecrRefCount(value);\n",
- 0);
- break;
-
- case T_UINT:
- case T_ULONG:
- Printv(set, "*(addr) = (", SwigType_str(t,0), ") strtoul(value,0,0);\n",0);
- Wrapper_add_local(get,"value","Tcl_Obj *value");
- Printv(get,
- "value = Tcl_NewIntObj((int) *addr);\n",
- "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
- "Tcl_DecrRefCount(value);\n",
- 0);
- break;
-
- case T_FLOAT:
- case T_DOUBLE:
- Printv(set, "*(addr) = (", SwigType_str(t,0), ") atof(value);\n",0);
- Wrapper_add_local(get,"value","Tcl_Obj *value");
- Printv(get,
- "value = Tcl_NewDoubleObj((double) *addr);\n",
- "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
- "Tcl_DecrRefCount(value);\n",
- 0);
- break;
-
- case T_CHAR:
- Printv(set, "*(addr) = *value;\n",0);
- Wrapper_add_local(get,"temp", "char temp[2]");
- Printv(get, "temp[0] = *addr; temp[1] = 0;\n",
- "Tcl_SetVar2(interp,name1,name2,temp,flags);\n",
- 0);
- break;
-
- case T_USER:
- /* User defined type. We return it as a pointer */
- SwigType_add_pointer(t);
- SwigType_remember(t);
- Printv(set, "{\n",
- "void *ptr;\n",
- "if (SWIG_ConvertPtrFromString(interp,value,&ptr,SWIGTYPE", SwigType_manglestr(t), ") != TCL_OK) {\n",
- "return \"Type Error\";\n",
- "}\n",
- "*(addr) = *((", SwigType_lstr(t,0), ") ptr);\n",
- "}\n",
- 0);
-
- SwigType_del_pointer(t);
- Wrapper_add_local(get,"value", "Tcl_Obj *value");
- SwigType_add_pointer(t);
- SwigType_remember(t);
- Printv(get, "value = SWIG_NewPointerObj(addr, SWIGTYPE", SwigType_manglestr(t), ");\n",
- "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
- "Tcl_DecrRefCount(value);\n",0);
- SwigType_del_pointer(t);
-
- break;
-
- case T_STRING:
- Printv(set, "if (*addr) free(*addr);\n",
- "*addr = (char *) malloc(strlen(value)+1);\n",
- "strcpy(*addr,value);\n",
- 0);
- Printv(get, "Tcl_SetVar2(interp,name1,name2,*addr, flags);\n",0);
- break;
-
- case T_ARRAY:
- {
- SwigType *aop;
- SwigType *ta = Copy(t);
- aop = SwigType_pop(ta);
- /* Printf(stdout,"'%s' '%s'\n", ta, aop);*/
- setable = 0;
- readonly = 1;
- if (SwigType_type(ta) == T_CHAR) {
- String *dim = SwigType_array_getdim(aop,0);
- if (dim && Len(dim)) {
- Printf(set, "strncpy(addr,value,%s);\n", dim);
- setable = 1;
- readonly = ReadOnly;
- }
- Printv(get, "Tcl_SetVar2(interp,name1,name2,addr, flags);\n",0);
+ // 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 {
- Printf(stderr,"%s:%d: Array variable '%s' will be read-only.\n", Getfile(node), Getline(node), name);
- Wrapper_add_local(get,"value","Tcl_Obj *value");
- SwigType_remember(t);
- Printv(get,
- "value = SWIG_NewPointerObj(addr, SWIGTYPE", SwigType_manglestr(t), ");\n",
- "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
- "Tcl_DecrRefCount(value);\n",
- 0);
+ Printv(f_wrappers," free((char *) obj);\n",NIL);
}
- Delete(ta);
- Delete(aop);
}
- break;
-
- case T_POINTER: case T_REFERENCE:
- SwigType_remember(t);
- Printv(set, "{\n",
- "void *ptr;\n",
- "if (SWIG_ConvertPtrFromString(interp,value,&ptr,SWIGTYPE", SwigType_manglestr(t), ") != TCL_OK) {\n",
- "return \"Type Error\";\n",
- "}\n",
- "*(addr) = (", SwigType_lstr(t,0), ") ptr;\n",
- "}\n",
- 0);
-
- Wrapper_add_local(get,"value","Tcl_Obj *value");
- Printv(get,
- "value = SWIG_NewPointerObj(*addr, SWIGTYPE", SwigType_manglestr(t), ");\n",
- "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
- "Tcl_DecrRefCount(value);\n",
- 0);
-
- break;
- case T_VOID:
- break;
-
- default:
- Printf(stderr,"TCL8::link_variable. Unknown type %s!\n", SwigType_str(t,0));
- break;
+ Printf(f_wrappers,"}\n");
}
- Printv(set, "return NULL;\n", "}\n",0);
- Printv(get, "return NULL;\n", "}\n",0);
- Printf(f_wrappers,"%s",get);
- Setattr(getf,Copy(t),getname);
- if (setable) {
- Printf(f_wrappers,"%s",set);
- Setattr(setf,Copy(t),setname);
- }
- Delete(get);
- Delete(set);
- }
- Printv(var_info, tab4,"{ SWIG_prefix \"", iname, "\", (void *) ", isarray ? "" : "&", name, ",", getname, ",", 0);
-
- if (readonly) {
- static int readonlywrap = 0;
- if (!readonlywrap) {
- Wrapper *ro = NewWrapper();
- Printf(ro, "static char *swig_readonly(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {\n");
- Printv(ro, "return \"Variable is read-only\";\n", "}\n", 0);
- Printf(f_wrappers,"%s",ro);
- readonlywrap = 1;
- Delete(ro);
+
+ 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);
+ }
}
- Printf(var_info, "swig_readonly},\n");
- } else {
- Printv(var_info, setname, "},\n",0);
- }
-}
-/* -----------------------------------------------------------------------------
- * TCL8::constant()
- * ----------------------------------------------------------------------------- */
+ Printv(f_wrappers,"static swig_class *swig_",mangled_classname,"_bases[] = {", base_class,"0};\n", NIL);
+ Delete(base_class);
-void
-TCL8::constant(DOH *node) {
- char *name;
- SwigType *type;
- char *value;
- int OldStatus = ReadOnly;
- SwigType *t;
- char var_name[256];
- char *tm;
- String *rvalue;
- ReadOnly = 1;
- DOH *nnode;
-
- name = GetChar(node,"name");
- type = Getattr(node,"type");
- value = GetChar(node,"value");
- nnode = Copy(node);
-
- /* Make a static variable */
- sprintf(var_name,"_wrap_const_%s",name);
-
- if (SwigType_type(type) == T_STRING) {
- rvalue = NewStringf("\"%s\"",value);
- } else if (SwigType_type(type) == T_CHAR) {
- rvalue = NewStringf("\'%s\'",value);
- } else {
- rvalue = NewString(value);
- }
- if ((tm = Swig_typemap_lookup((char*)"const",type,name,Char(rvalue),name,0))) {
- Printf(f_init,"%s\n",tm);
- } else {
- /* Create variable and assign it a value */
- switch(SwigType_type(type)) {
- case T_BOOL: case T_INT: case T_DOUBLE:
- Printf(f_header,"static %s %s = %s;\n", SwigType_str(type,0), var_name, value);
- Setattr(nnode,"name",var_name);
- variable(nnode);
- break;
-
- case T_SHORT:
- case T_LONG:
- case T_SCHAR:
- Printf(f_header,"static %s %s = %s;\n", SwigType_str(type,0), var_name, value);
- Printf(f_header,"static char *%s_char;\n", var_name);
- if (CPlusPlus)
- Printf(f_init,"\t %s_char = new char[32];\n",var_name);
- else
- Printf(f_init,"\t %s_char = (char *) malloc(32);\n",var_name);
-
- Printf(f_init,"\t sprintf(%s_char,\"%%ld\", (long) %s);\n", var_name, var_name);
- sprintf(var_name,"%s_char",var_name);
- t = NewString("char");
- SwigType_add_pointer(t);
- Setattr(nnode,"name",var_name);
- Setattr(nnode,"type",t);
- variable(nnode);
- Delete(t);
- break;
-
- case T_UINT:
- case T_USHORT:
- case T_ULONG:
- case T_UCHAR:
- Printf(f_header,"static %s %s = %s;\n", SwigType_str(type,0), var_name, value);
- Printf(f_header,"static char *%s_char;\n", var_name);
- if (CPlusPlus)
- Printf(f_init,"\t %s_char = new char[32];\n",var_name);
- else
- Printf(f_init,"\t %s_char = (char *) malloc(32);\n",var_name);
-
- Printf(f_init,"\t sprintf(%s_char,\"%%lu\", (unsigned long) %s);\n", var_name, var_name);
- sprintf(var_name,"%s_char",var_name);
- t = NewSwigType(T_CHAR);
- SwigType_add_pointer(t);
- Setattr(nnode,"name",var_name);
- Setattr(nnode,"type",t);
- variable(nnode);
- Delete(t);
- break;
-
- case T_FLOAT:
- Printf(f_header,"static %s %s = (%s) (%s);\n", SwigType_lstr(type,0), var_name, SwigType_lstr(type,0), value);
- Setattr(nnode,"name",var_name);
- variable(nnode);
- break;
-
- case T_CHAR:
- SwigType_add_pointer(type);
- Printf(f_header,"static %s %s = \"%s\";\n", SwigType_lstr(type,0), var_name, value);
- Setattr(nnode,"name",var_name);
- Setattr(nnode,"type",type);
- variable(nnode);
- SwigType_del_pointer(type);
- break;
-
- case T_STRING:
- Printf(f_header,"static %s %s = \"%s\";\n", SwigType_lstr(type,0), var_name, value);
- Setattr(nnode,"name",var_name);
- variable(nnode);
- break;
-
- case T_POINTER: case T_ARRAY: case T_REFERENCE:
- Printf(f_header,"static %s = %s;\n", SwigType_lstr(type,var_name), value);
- Printf(f_header,"static char *%s_char;\n", var_name);
- if (CPlusPlus)
- Printf(f_init,"\t %s_char = new char[%d];\n",var_name,(int) Len(SwigType_manglestr(type))+ 20);
- else
- Printf(f_init,"\t %s_char = (char *) malloc(%d);\n",var_name, (int) Len(SwigType_manglestr(type))+ 20);
-
- t = NewSwigType(T_CHAR);
- SwigType_add_pointer(t);
- SwigType_remember(type);
- Printf(f_init,"\t SWIG_MakePtr(%s_char, (void *) %s, SWIGTYPE%s);\n",
- var_name, var_name, SwigType_manglestr(type));
- sprintf(var_name,"%s_char",var_name);
- Setattr(nnode,"type",t);
- Setattr(nnode,"name",var_name);
- variable(nnode);
- Delete(t);
- break;
-
- default:
- Printf(stderr,"%s:%d. Unsupported constant value.\n", Getfile(node), Getline(node));
- break;
+ 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");
}
- }
- Delete(rvalue);
- Delete(nnode);
- ReadOnly = OldStatus;
-}
-
-/* -----------------------------------------------------------------------------
- * TCL8::usage_string()
- * ----------------------------------------------------------------------------- */
-
-char *
-TCL8::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 = check_numopt(l);
- for (p = l; p; p = Getnext(p)) {
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
-
- /* Only print an argument if not ignored */
- if (!Swig_typemap_search((char*)"ignore",pt,pn)) {
- if (i >= (pcount-numopt))
- Putc('?',temp);
- /* 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));
- }
- }
- if (i >= (pcount-numopt)) Putc('?',temp);
- Putc(' ',temp);
- i++;
+ 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;
}
- return Char(temp);
-}
-/* -----------------------------------------------------------------------------
- * TCL8::nativefunction();
- * ----------------------------------------------------------------------------- */
-void
-TCL8::nativefunction(DOH *node) {
- char *name;
- char *funcname;
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
- name = GetChar(node,"scriptname");
- funcname = GetChar(node,"name");
+ virtual int memberfunctionHandler(Node *n) {
+ String *name = Getattr(n,"name");
+ String *iname = GetChar(n,"sym:name");
- if ((Swig_proto_cmp("f(ClientData,p.Tcl_Interp,int,p.p.Tcl_Obj).int", node) == 0) ||
- (Swig_proto_cmp("f(ClientData,p.Tcl_Interp,int,a().p.Tcl_Obj).int", node) == 0)) {
- Printf(f_init,"\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",name, funcname);
- }
+ String *realname, *rname;
- if ((Swig_proto_cmp("f(ClientData,p.Tcl_Interp,int,p.p.char).int", node) == 0) ||
- (Swig_proto_cmp("f(ClientData,p.Tcl_Interp,int,a().p.char).int", node) == 0)) {
- Printf(f_init,"\t Tcl_CreateCommand(interp, SWIG_prefix \"%s\", %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",name, funcname);
- }
-
-}
+ Language::memberfunctionHandler(n);
-/* -----------------------------------------------------------------------------
- * C++ Handling
- * ----------------------------------------------------------------------------- */
+ 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;
+ }
-void
-TCL8::cpp_open_class(DOH *node) {
- this->Language::cpp_open_class(node);
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
- char *classname = GetChar(node,"name");
- char *rename = GetChar(node,"scriptname");
- char *ctype = GetChar(node,"classtype");
- int strip = GetInt(node,"strip");
-
- if (shadow) {
- static int included_object = 0;
- if (!included_object) {
- if (Swig_insert_file("object.swg",f_header) == -1) {
- Printf(stderr,"SWIG : Fatal error. Unable to locate 'object.swg' in SWIG library.\n");
- Swig_exit (EXIT_FAILURE);
- }
- included_object = 1;
+ 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;
+ }
- attributes = NewString("");
- /* Printf(attributes, "static swig_attribute swig_");
- Printv(attributes, classname, "_attributes[] = {\n", 0); */
-
- methods = NewString("");
- /* Printf(methods,"static swig_method swig_");
- Printv(methods, classname, "_methods[] = {\n", 0); */
+ /* ------------------------------------------------------------
+ * constructorHandler()
+ * ------------------------------------------------------------ */
- have_constructor = 0;
- have_destructor = 0;
+ virtual int constructorHandler(Node *n) {
+ Language::constructorHandler(n);
+ have_constructor = 1;
+ return SWIG_OK;
+ }
- Delete(class_name);
- Delete(class_type);
- Delete(real_classname);
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
- class_name = rename ? NewString(rename) : NewString(classname);
- class_type = strip ? NewString("") : NewStringf("%s ",ctype);
- real_classname = NewString(classname);
+ virtual int destructorHandler(Node *n) {
+ Language::destructorHandler(n);
+ have_destructor = 1;
+ destructor_action = Getattr(n,"wrap:action");
+ return SWIG_OK;
}
-}
-void
-TCL8::cpp_close_class() {
- SwigType *t;
- String *code = NewString("");
+ /* ------------------------------------------------------------
+ * validIdentifier()
+ * ------------------------------------------------------------ */
- this->Language::cpp_close_class();
- if (shadow) {
- t = NewStringf("%s%s", class_type, real_classname);
- SwigType_add_pointer(t);
+ virtual int validIdentifier(String *s) {
+ if (Strchr(s,' ')) return 0;
+ return 1;
+ }
- if (have_destructor) {
- Printv(code, "static void swig_delete_", class_name, "(void *obj) {\n", 0);
- if (CPlusPlus) {
- Printv(code," delete (", SwigType_str(t,0), ") obj;\n",0);
- } else {
- Printv(code," free((char *) obj);\n",0);
- }
- Printf(code,"}\n");
- }
+ /* ------------------------------------------------------------
+ * usage_string()
+ * ------------------------------------------------------------ */
- Printf(code,"static swig_method swig_");
- Printv(code, real_classname, "_methods[] = {\n", 0);
- Printv(code,methods,0);
- Printf(code, " {0,0}\n};\n");
- Setattr(class_methods,real_classname,methods);
-
- Printf(code, "static swig_attribute swig_");
- Printv(code, real_classname, "_attributes[] = {\n", 0);
- Printv(code,attributes,0);
- Printf(code, " {0,0,0}\n};\n");
- Setattr(class_attributes,real_classname,attributes);
+ char *
+ usage_string(char *iname, SwigType *, ParmList *l) {
+ static String *temp = 0;
+ Parm *p;
+ int i, numopt,pcount;
- Printv(code, "static swig_class _wrap_class_", class_name, " = { \"", class_name,
- "\", &SWIGTYPE", SwigType_manglestr(t), ",",0);
-
- if (have_constructor) {
- Printf(code, "%s", Swig_name_wrapper(Swig_name_construct(class_name)));
+ if (!temp) temp = NewString("");
+ Clear(temp);
+ if (nspace) {
+ Printf(temp,"%s::%s", ns_name,iname);
} else {
- Printf(code,"0");
+ Printf(temp,"%s ", iname);
}
- if (have_destructor) {
- Printv(code, ", swig_delete_", class_name,0);
- } else {
- Printf(code,",0");
+ /* 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++;
+ }
}
- Printv(code, ", swig_", real_classname, "_methods, swig_", real_classname, "_attributes };\n", 0);
- Printf(f_wrappers,"%s",code);
-
- Printv(cmd_info, tab4, "{ SWIG_prefix \"", class_name, "\", SwigObjectCmd, &_wrap_class_", class_name, "},\n", 0);
+ return Char(temp);
}
- Delete(code);
-}
-
-void TCL8::cpp_memberfunction(DOH *node) {
- char *name, *iname;
- char *realname;
- char temp[1024];
- String *rname;
-
- this->Language::cpp_memberfunction(node);
- if (shadow) {
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- realname = iname ? iname : name;
- /* Add stubs for this member to our class handler function */
+};
- strcpy(temp, Char(Swig_name_member(class_name,realname)));
- rname = Getattr(repeatcmd,temp);
- if (!rname) rname = Swig_name_wrapper(temp);
+/* ----------------------------------------------------------------------
+ * swig_tcl() - Instantiate module
+ * ---------------------------------------------------------------------- */
- Printv(methods, tab4, "{\"", realname, "\", ", rname, "}, \n", 0);
- }
+extern "C" Language *
+swig_tcl(void) {
+ return new TCL8();
}
-void TCL8::cpp_variable(DOH *node) {
- char *name, *iname;
- char *realname;
- char temp[1024];
- String *rname;
- this->Language::cpp_variable(node);
- if (shadow) {
- name = GetChar(node,"name");
- iname = GetChar(node,"scriptname");
- realname = iname ? iname : name;
- Printv(attributes, tab4, "{ \"-", realname, "\",", 0);
-
- /* Try to figure out if there is a wrapper for this function */
- strcpy(temp, Char(Swig_name_get(Swig_name_member(class_name,realname))));
- rname = Getattr(repeatcmd,temp);
- if (!rname) rname = Swig_name_wrapper(temp);
- Printv(attributes, rname, ", ", 0);
-
- if (!ReadOnly) {
- strcpy(temp, Char(Swig_name_set(Swig_name_member(class_name,realname))));
- rname = Getattr(repeatcmd,temp);
- if (!rname) rname = Swig_name_wrapper(temp);
- Printv(attributes, rname, "},\n",0);
- } else {
- Printf(attributes, "0 },\n");
- }
- }
-}
-void
-TCL8::cpp_constructor(DOH *node) {
- this->Language::cpp_constructor(node);
- have_constructor = 1;
-}
-
-void
-TCL8::cpp_destructor(DOH *node) {
- this->Language::cpp_destructor(node);
- have_destructor = 1;
-}
-
-void
-TCL8::cpp_inherit(List *bases) {
- String *b;
- Printf(stdout,"bases = %s\n", bases);
- for (b = Firstitem(bases); b; b = Nextitem(bases)) {
- Printf(stdout,"base: %s\n", b);
- String *s = Getattr(class_methods,b);
- if (s) {
- Append(methods,s);
- }
- s = Getattr(class_attributes,b);
- if (s) {
- Append(attributes,s);
- }
- }
-}
diff --git a/Source/Modules1.1/tcl8.h b/Source/Modules1.1/tcl8.h
deleted file mode 100644
index 4bafbab6e..000000000
--- a/Source/Modules1.1/tcl8.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- * 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.
- *******************************************************************************/
-
-/**************************************************************************
- * class TCL8
- *
- * A TCL implementation for Tcl 8.0. Basically the same as the other
- * Tcl module, but with different code generation.
- **************************************************************************/
-
-class TCL8 : public Language {
-private:
- char *usage_string(char *, SwigType *, ParmList *);
-
-public :
- virtual void parse_args(int, char *argv[]);
- virtual void initialize(String *);
- virtual void function(DOH *node);
- virtual void variable(DOH *node);
- virtual void constant(DOH *node);
- virtual void close(void);
- virtual void nativefunction(DOH *);
- virtual void create_command(String *, String *);
-
- // Stubs for processing C++ classes in Tcl
-
- virtual void cpp_open_class(DOH *node);
- virtual void cpp_close_class();
- virtual void cpp_memberfunction(DOH *);
- virtual void cpp_variable(DOH *);
- virtual void cpp_constructor(DOH *);
- virtual void cpp_destructor(DOH *);
- virtual void cpp_inherit(List *bases);
-
-};
-
-
-
-
-
-
diff --git a/Source/Modules1.1/typepass.cxx b/Source/Modules1.1/typepass.cxx
new file mode 100644
index 000000000..3e4f74338
--- /dev/null
+++ b/Source/Modules1.1/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/Modules1.1/xml.cxx b/Source/Modules1.1/xml.cxx
index e3891b1c6..261f3e348 100644
--- a/Source/Modules1.1/xml.cxx
+++ b/Source/Modules1.1/xml.cxx
@@ -1,304 +1,318 @@
-/* -----------------------------------------------------------------------------
- * xml.cxx
+/* -----------------------------------------------------------------------------
+ * Xml.cxx
*
- * Generate XML representation
+ * 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)
*
- * Author(s) : SWIG core: David Beazley (beazley@cs.uchicago.edu)
- * XML module: Klaus Wiederaenders (kwconsulting@compuserve.com)
- * Copyright (C) 1999-2001. The University of Chicago
- * See the file LICENSE for information on usage and redistribution.
+ * Copyright (C) 2002. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-/* DB: I had to take some features related to package naming out of this to
- get the new type system to work. These need to be put back in at some
- point. */
-
-static char cvsroot[] = "$Header$";
+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 <time.h>
-#include "swig11.h"
-#include "xml.h"
-#include "dohobj.h"
+#include "swigmod.h"
-static char *usage = (char*)"\
-XML Options (available with -xml)\n\
- -o filename - Output file\n\
- -dtd filename - Stylsheet file\n\n";
-
-static String *dtdfile = 0;
-static String *xmlfile = 0;
-static int indent = 0;
-static const int indentsize = 2;
-static const char * indentchar = " ";
-FILE *f_xml = 0;
-extern "C"
+//static Node *view_top = 0;
+static File *out = 0;
+
+class XML
+: public Language
{
-static String * emit_indent( int indent )
-{
- String *out;
- out = NewString("");
- for(int iX = 0; iX < indent; iX ++ )
- Append( out, indentchar );
- return Swig_temp_result(out);
-}
-void xml(DOH *node)
-{
- if (ObjGetMark(node))
- {
- Printf( f_xml, "%s<swigxml:node ident=\"ID%0X\" />\n",
- emit_indent( indent ), node);
- return;
- }
- indent += indentsize;
- ObjSetMark(node, 1);
- while (node)
- {
- DohBase * base = (DohBase *) node;
- if( !base )
- return;
- switch( base->type )
- {
- case 1:
- Replace( node, "<", "&lt;", DOH_REPLACE_ANY );
- Replace( node, "&", "&amp;", DOH_REPLACE_ANY );
- Printf( f_xml, "%s", node );
- break;
- case 2:
- {
- indent += indentsize;
- DOH *item;
-
- item = Firstitem(node);
- while (item)
- {
- DohBase * itembase = (DohBase *) item;
- if( itembase && itembase->type == DOHTYPE_STRING )
- {
- Printf( f_xml,
- "%s<swigxml:item name=\"%s\" ident=\"ID%0X\" />\n",
- emit_indent( indent ), Char( item ), item );
- }
- else
- {
- Printf( f_xml, "%s<swigxml:item ident=\"ID%0X\">\n",
- emit_indent( indent ), item );
- xml( item );
- Printf( f_xml, "%s</swigxml:item>\n",
- emit_indent( indent ) );
-
- }
- item = Nextitem(node);
- }
- indent -= indentsize;
- break;
- }
- case 3:
- {
- String * none = NewString("swigxml:none");
- DOH * tag = Getattr( node, "tag" );
- if( !tag )
- {
- /*
- ObjSetMark(node, 0);
- Printf( f_xml, "------- %s\n", Char( Str( node )));
- ObjSetMark(node, 1);
- */
- tag = none;
- }
- DOH * name = Getattr( node, "name" );
- char * ttt = Char( tag );
-
- if( tag && ::strchr( Char(tag), ':' ) == 0 )
- Insert( tag, 0, "swigxml:" );
- // check for simple node
- int length = Len( node );
- if( Getattr( node, "tag" ) )
- --length;
- if( Getattr( node, "prev" ) )
- --length;
- if( Getattr( node, "next" ) )
- --length;
- if( Getattr( node, "parent" ) )
- --length;
- if( Getattr( node, "last" ) )
- --length;
- if( length == 1 && name )
- { // Yes, it's simple
- if( Len( name) )
- Printf( f_xml, "%s<%s name=\"%s\" ident=\"ID%0X\" />\n",
- emit_indent( indent ), Char( tag ), Char( name ),
- node );
- else
- Printf( f_xml, "%s<%s ident=\"ID%0X\" />\n",
- emit_indent( indent ), Char( tag ), node );
- Delete( none );
- break;
- }
- if( Len( name) )
- Printf( f_xml, "%s<%s name=\"%s\" ident=\"ID%0X\">\n",
- emit_indent( indent ), Char( tag ), Char( name ), node );
- else
- Printf( f_xml, "%s<%s ident=\"ID%0X\">\n",
- emit_indent( indent ), Char( tag ), node );
- indent += indentsize;
-
- DOH * key = Firstkey(node);
- while (key)
- {
- char * kkkk = Char( key );
- DOH * attr = Getattr( node, key );
- char * aaaa = Char( Getattr( node, key ) );
- DohBase * attrbase = (DohBase *) attr;
- if( ::strcmp( Char( key ), "tag")
- && ::strcmp( Char( key ), "code")
- && ::strcmp( Char( key ), "name")
- && attrbase && attrbase->type == DOHTYPE_STRING)
- {
- Replace( attr, "\"", "&quot;", DOH_REPLACE_ANY );
- Printf( f_xml,
- "%s<swigxml:%s string=\"%s\" ident=\"ID%0X\" />\n",
- emit_indent( indent ), Char( key ), Char( attr ),
- attr );
- }
- else
- {
- if( ::strcmp( Char( key ), "prev" )
- && ::strcmp( Char( key ), "next" )
- && ::strcmp( Char( key ), "parent" )
- && ::strcmp( Char( key ), "tag" )
- && ::strcmp( Char( key ), "name" )
- && ::strcmp( Char( key ), "last" ) )
- {
- Printf( f_xml, "%s<swigxml:%s ident=\"ID%0X\">\n",
- emit_indent( indent ), Char( key ), key );
- xml( attr );
- Printf( f_xml, "%s</swigxml:%s>\n",
- emit_indent( indent ), Char( key ) );
- }
-
- }
- key = Nextkey(node);
- }
- indent -= indentsize;
- Printf( f_xml, "%s</%s>\n", emit_indent( indent ), Char( tag ) );
- Delete( none );
- break;
- }
- case 4:
- Printf( f_xml, "%s ", "DOHTYPE_VOID" );
- break;
- case 5:
- Printf( f_xml, "%s ", "DOHTYPE_FILE" );
- break;
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- Printf( f_xml, "%d ", base->type );
- ;
- }
- ObjSetMark(node, 0);
- node = Swig_next(node);
- }
- indent -= indentsize;
-}
+public:
-int xml_init(int argc, char *argv[])
-{
- int i;
- int help = 0;
-
- // Get options
- for (i = 1; i < argc; i++)
- {
- if (argv[i])
- {
- if(strcmp(argv[i],"-xml") == 0)
- {
- if (argv[i+1])
- {
- xmlfile = NewString(argv[i+1]);
- // don't do this: Swig_mark_arg(i);
- Swig_mark_arg(i+1);
- i++;
- }
- else
- {
- Swig_arg_error();
- }
- continue;
- }
- if(strcmp(argv[i],"-dtd") == 0)
- {
- if (argv[i+1])
- {
- dtdfile = NewString(argv[i+1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i+1);
- i++;
- }
- else
- {
- Swig_arg_error();
- }
- continue;
- }
- if (strcmp(argv[i],"-help") == 0)
- {
- fputs(usage,stderr);
- Swig_mark_arg(i);
- help = 1;
- }
- }
- }
-
- if (help) return 0;
- Preprocessor_define((void *) "SWIGXML 1", 0);
- if( ! Swig_swiglib_get() )
- Swig_swiglib_set("xml");
-
- return 0;
-}
+ int indent_level;
+ long id;
+ XML()
+ : indent_level( 0 )
+ , id( 0 )
+ {
+ }
-DOH *xml_run(DOH *node)
-{
- time_t now;
- time( &now );
- char buffer[32];
- ::strcpy( buffer, ctime(&now));
- buffer[24] = '\0';
- char * filename = Char(xmlfile);
- if ((f_xml = fopen( filename,"w")) == 0) {
- fprintf(stderr,"Unable to open %s\n", filename);
- Swig_exit(1);
- }
- Printf( f_xml, "<!-- Generated by Swig XML at %s -->\n", buffer );
-
- if( dtdfile )
- {
- Printf( f_xml, "<!DOCTYPE swigxml:swig SYSTEM \"%s\">\n", dtdfile);
- }
-
- Printf( f_xml, "<swigxml:swig"
- " name=\"namespaces\""
- " xmlns:swigxml=\"http://jniplusplus.sourceforge.net\""
- " xmlns:swig=\"http://swig.sourceforge.net\""
- " xmlns:c=\"http://www.ansi.org\""
- " ident=\"ID000000\">\n" );
- xml(node);
- Printf( f_xml, "</swigxml:swig>\n" );
-
- fclose(f_xml);
- return node;
-}
+ 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, "<?xml version=\"1.0\" ?> \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, "<attributelist id=\"%ld\" addr=\"%x\" >\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, "<", "&lt;" );
+ Replaceall( o, "&", "&amp;" );
+ Replaceall( o, "\"", "&quot;" );
+ Replaceall( o, "\\", "\\\\" );
+ Printf(out,"<attribute name=\"%s\" value=\"%s\" id=\"%ld\" addr=\"%x\" />\n", k, o, ++id, o );
+ Delete(o);
+ }
+ else
+ {
+ o = Getattr(obj,k);
+ Replaceall( k, ":", "_" );
+ Printf(out,"<attribute name=\"%s\" value=\"%x\" id=\"%ld\" addr=\"%x\" />\n", k, o, ++id, o );
+ }
+ }
+ k = Nextkey(obj);
+ }
+ indent_level -= 4;
+ print_indent(0);
+ Printf( out, "</attributelist >\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, "<parmlist id=\"%ld\" addr=\"%x\" >\n", ++id, p );
+ indent_level += 4;
+ while(p)
+ {
+ print_indent(0);
+ Printf( out, "<parm id=\"%ld\">\n", ++id );
+ Xml_print_attributes( p );
+ print_indent(0);
+ Printf( out, "</parm >\n" );
+ p = nextSibling(p);
+ }
+ indent_level -= 4;
+ print_indent(0);
+ Printf( out, "</parmlist >\n" );
+ }
+
+ void Xml_print_baselist(List *p)
+ {
+
+ print_indent(0);
+ Printf( out, "<baselist id=\"%ld\" addr=\"%x\" >\n", ++id, p );
+ indent_level += 4;
+ String *s;
+ for (s = Firstitem(p); s; s = Nextitem(p))
+ {
+ print_indent(0);
+ Printf( out, "<base name=\"%s\" id=\"%ld\" addr=\"%x\" />\n", s, ++id, s );
+ }
+ indent_level -= 4;
+ print_indent(0);
+ Printf( out, "</baselist >\n" );
+ }
+
+ void Xml_print_module(Node *p)
+ {
+
+ print_indent(0);
+ Printf( out, "<attribute name=\"module\" value=\"%s\" id=\"%ld\" addr=\"%x\" />\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();
+ }
}
diff --git a/Source/Modules1.1/xml.dtd b/Source/Modules1.1/xml.dtd
deleted file mode 100644
index 68e40e33e..000000000
--- a/Source/Modules1.1/xml.dtd
+++ /dev/null
@@ -1,119 +0,0 @@
-<!ELEMENT swig:top (swigxml:child)>
-<!ATTLIST swig:top name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swig:pragma (swigxml:value,swigxml:lang?)>
-<!ATTLIST swig:pragma name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swig:file ((swigxml:type|swigxml:child)+)>
-<!ATTLIST swig:file name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swig:module EMPTY>
-<!ATTLIST swig:module name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swig:insert (swigxml:code,swigxml:section?,swigxml:method?,swigxml:type?)>
-<!ATTLIST swig:insert name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swig:types (swigxml:parms)>
-<!ATTLIST swig:types name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swig:typemap (swigxml:parms?,(swigxml:srctype|swigxml:code),swigxml:method,swigxml:type,swigxml:lang?,swigxml:srcname?)>
-<!ATTLIST swig:typemap name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swig:constant (swigxml:value,swigxml:type?)>
-<!ATTLIST swig:constant name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swig:apply (swigxml:parms?,swigxml:type)>
-<!ATTLIST swig:apply name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swig:addmethods (swigxml:child)>
-<!ATTLIST swig:addmethods name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT c:class ((swigxml:child|swigxml:classtype|swigxml:namespace|swigxml:bases|swigxml:scriptname|swigxml:symbols|swigxml:altname)+)>
-<!ATTLIST c:class name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT c:destructor (swigxml:code?,swigxml:storage?)>
-<!ATTLIST c:destructor name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT c:function (swigxml:abstract?,swigxml:parms?,swigxml:code?,swigxml:storage?,swigxml:type)>
-<!ATTLIST c:function name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT c:variable (swigxml:storage?,swigxml:value?,swigxml:type)>
-<!ATTLIST c:variable name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT c:access EMPTY>
-<!ATTLIST c:access name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT c:typedef (swigxml:type)>
-<!ATTLIST c:typedef name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT c:enum (swigxml:child)>
-<!ATTLIST c:enum name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT c:enumvalue (swigxml:value?)>
-<!ATTLIST c:enumvalue name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:child ((swig:addmethods|swig:apply|swig:constant|swig:types|swig:insert|swig:file|swig:module|swig:typemap|swig:pragma|c:class|c:destructor|c:function|c:access|c:variable|c:typedef|c:enum|c:enumvalue)+)>
-<!ATTLIST swigxml:child name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:swig (swig:top)>
-<!ATTLIST swigxml:swig name CDATA #REQUIRED xmlns:swigxml CDATA #REQUIRED xmlns:swig CDATA #REQUIRED xmlns:c CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:type EMPTY>
-<!ATTLIST swigxml:type name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:code (#PCDATA)>
-<!ATTLIST swigxml:code name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:method EMPTY>
-<!ATTLIST swigxml:method name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:value EMPTY>
-<!ATTLIST swigxml:value name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:lang EMPTY>
-<!ATTLIST swigxml:lang name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:parms (swigxml:parm+|swigxml:none+)>
-<!ATTLIST swigxml:parms name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:parm (swigxml:value?,swigxml:type)>
-<!ATTLIST swigxml:parm name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:storage EMPTY>
-<!ATTLIST swigxml:storage name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:classtype EMPTY>
-<!ATTLIST swigxml:classtype name CDATA #IMPLIED string (struct|class|union) #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:namespace EMPTY>
-<!ATTLIST swigxml:namespace name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:bases (swigxml:item+)>
-<!ATTLIST swigxml:bases name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:item EMPTY>
-<!ATTLIST swigxml:item name CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:node EMPTY>
-<!ATTLIST swigxml:node ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:scriptname EMPTY>
-<!ATTLIST swigxml:scriptname name CDATA #REQUIRED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:abstract EMPTY>
-<!ATTLIST swigxml:abstract name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:section EMPTY>
-<!ATTLIST swigxml:section name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:srctype EMPTY>
-<!ATTLIST swigxml:srctype name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:srcname EMPTY>
-<!ATTLIST swigxml:srcname name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:none (swigxml:type)>
-<!ATTLIST swigxml:none name CDATA #IMPLIED ident CDATA #REQUIRED>
-
-<!ELEMENT swigxml:altname EMPTY>
-<!ATTLIST swigxml:altname name CDATA #IMPLIED string CDATA #REQUIRED ident CDATA #REQUIRED>
diff --git a/Source/Modules1.1/xml.h b/Source/Modules1.1/xml.h
deleted file mode 100644
index 79532957c..000000000
--- a/Source/Modules1.1/xml.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/****************************************************************************
- * 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.
- ****************************************************************************/
-
-extern "C" DOH *xml_run(DOH *node);
-extern "C" int xml_init(int argc, char *argv[]);
-
diff --git a/Source/Preprocessor/Makefile.in b/Source/Preprocessor/Makefile.in
index 24320f5e9..ac1bed800 100644
--- a/Source/Preprocessor/Makefile.in
+++ b/Source/Preprocessor/Makefile.in
@@ -6,7 +6,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
SRCS = expr.c cpp.c
-OBJS = expr.o cpp.o
+OBJS = expr.@OBJEXT@ cpp.@OBJEXT@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -15,11 +15,11 @@ CC = @CC@
AR = @AR@
RANLIB = @RANLIB@
CFLAGS = @CFLAGS@
-INCLUDE = -I$(srcdir)/. -I$(srcdir)/../Swig -I$(srcdir)/../DOH/Include
+INCLUDES = -I$(srcdir)/. -I$(srcdir)/../Swig -I$(srcdir)/../DOH/Include -I$(srcdir)/../Include
TARGET = libcpp.a
-.c.o:
- $(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $<
+.c.@OBJEXT@:
+ $(CC) $(CFLAGS) $(INCLUDES) -c -o $*.@OBJEXT@ $<
all: $(TARGET)
@@ -28,4 +28,4 @@ $(TARGET): $(OBJS)
$(RANLIB) $(TARGET)
clean:
- rm -f *.o *~ core *.so *.a *_wrap.*
+ rm -f *.@OBJEXT@ *~ core *.so *.a *_wrap.*
diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c
index f0f11b67c..9fa55a0e6 100644
--- a/Source/Preprocessor/cpp.c
+++ b/Source/Preprocessor/cpp.c
@@ -15,49 +15,36 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_cpp_c[] = "$Header$";
#include "preprocessor.h"
#include <ctype.h>
-static DOHHash *cpp = 0; /* C preprocessor data */
+static Hash *cpp = 0; /* C preprocessor data */
static int include_all = 0; /* Follow all includes */
+static int ignore_missing = 0;
+static int import_all = 0; /* Follow all includes, but as %import statements */
static int single_include = 1; /* Only include each file once */
-static int silent_errors = 0;
-static DOHHash *included_files = 0;
-
-/* Handle an error */
-
-static void cpp_error(DOHString *file, int line, char *fmt, ...) {
- va_list ap;
- if (silent_errors) return;
- va_start(ap,fmt);
- if (line > 0) {
- Printf(stderr,"%s:%d ", file, line);
- } else {
- Printf(stderr,"%s:EOF ",file);
- }
- vPrintf(stderr,fmt,ap);
- va_end(ap);
-}
+static Hash *included_files = 0;
+static List *dependencies = 0;
/* Test a character to see if it starts an identifier */
static int
-isidentifier(char c) {
+isidentifier(int c) {
if ((isalpha(c)) || (c == '_') || (c == '$')) return 1;
else return 0;
}
/* Test a character to see if it valid in an identifier (after the first letter) */
static int
-isidchar(char c) {
+isidchar(int c) {
if ((isalnum(c)) || (c == '_') || (c == '$')) return 1;
else return 0;
}
/* Skip whitespace */
static void
-skip_whitespace(DOH *s, DOH *out) {
+skip_whitespace(File *s, File *out) {
int c;
while ((c = Getc(s)) != EOF) {
if (!isspace(c)) {
@@ -69,7 +56,7 @@ skip_whitespace(DOH *s, DOH *out) {
/* Skip to a specified character taking line breaks into account */
static int
-skip_tochar(DOHFile *s, int ch, DOHFile *out) {
+skip_tochar(File *s, int ch, File *out) {
int c;
while ((c = Getc(s)) != EOF) {
if (out) Putc(c,out);
@@ -89,8 +76,8 @@ copy_location(DOH *s1, DOH *s2) {
Setline(s2,Getline(s1));
}
-static DOHString *cpp_include(DOHString_or_char *fn) {
- DOHString *s;
+static String *cpp_include(String_or_char *fn) {
+ String *s;
if (single_include) {
if (Getattr(included_files,fn)) return 0;
Setattr(included_files,fn,fn);
@@ -98,18 +85,31 @@ static DOHString *cpp_include(DOHString_or_char *fn) {
s = Swig_include(fn);
if (!s) {
Seek(fn,0,SEEK_SET);
- cpp_error(Getfile(fn),Getline(fn),"Unable to find '%s'\n", fn);
+ if (ignore_missing) {
+ Swig_warning(WARN_PP_MISSING_FILE,Getfile(fn),Getline(fn),"Unable to find '%s'\n", fn);
+ } else {
+ Swig_error(Getfile(fn),Getline(fn),"Unable to find '%s'\n", fn);
+ }
} else {
Seek(s,0,SEEK_SET);
+ if (!dependencies) {
+ dependencies = NewList();
+ }
+ Append(dependencies, Copy(Swig_last_file()));
}
return s;
}
+List *Preprocessor_depend(void) {
+ return dependencies;
+}
+
/* -----------------------------------------------------------------------------
* void Preprocessor_cpp_init() - Initialize the preprocessor
* ----------------------------------------------------------------------------- */
void Preprocessor_init() {
- DOHHash *s;
+ extern void Preprocessor_expr_init(void);
+ Hash *s;
cpp = NewHash();
s = NewHash();
Setattr(cpp,"symbols",s);
@@ -123,6 +123,15 @@ void Preprocessor_include_all(int a) {
include_all = a;
}
+void Preprocessor_import_all(int a) {
+ import_all = a;
+}
+
+void Preprocessor_ignore_missing(int a) {
+ ignore_missing = a;
+}
+
+
/* -----------------------------------------------------------------------------
* Preprocessor_define()
*
@@ -130,30 +139,30 @@ void Preprocessor_include_all(int a) {
* SWIG macro semantics.
* ----------------------------------------------------------------------------- */
-DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro)
+Hash *Preprocessor_define(const String_or_char *_str, int swigmacro)
{
- DOHString *macroname = 0, *argstr = 0, *macrovalue = 0, *file = 0, *s = 0;
- DOHHash *macro = 0, *symbols = 0, *m1;
- DOHList *arglist = 0;
+ String *macroname = 0, *argstr = 0, *macrovalue = 0, *file = 0, *s = 0;
+ Hash *macro = 0, *symbols = 0, *m1;
+ List *arglist = 0;
int c, line;
+ int varargs = 0;
+ String_or_char *str = (String_or_char *) _str;
assert(cpp);
assert(str);
/* First make sure that string is actually a string */
if (DohCheck(str)) {
- s = Copy(str);
+ s = NewString(str);
copy_location(str,s);
str = s;
} else {
str = NewString((char *) str);
- Seek(str,0,SEEK_SET);
}
+ Seek(str,0,SEEK_SET);
line = Getline(str);
file = Getfile(str);
- /* Printf(stdout,"%s:%d '%s'\n", file,line,str); */
-
/* Skip over any leading whitespace */
skip_whitespace(str,0);
@@ -169,7 +178,7 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro)
else Putc(c,argstr);
}
if (c != ')') {
- cpp_error(Getfile(str),Getline(str), "Missing \')\' in macro parameters\n");
+ Swig_error(Getfile(str),Getline(str), "Missing \')\' in macro parameters\n");
goto macro_error;
}
break;
@@ -178,7 +187,7 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro)
} else if (isspace(c)) {
break;
} else {
- cpp_error(Getfile(str),Getline(str),"Illegal character in macro name\n");
+ Swig_error(Getfile(str),Getline(str),"Illegal character in macro name\n");
goto macro_error;
}
}
@@ -197,18 +206,38 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro)
argname = NewString("");
while ((c = Getc(argstr)) != EOF) {
if (c == ',') {
- Append(arglist,argname);
+ /* Check for varargs */
+ if (Strstr(argname,".")) {
+ if (Strcmp(argname,"...") != 0) {
+ Swig_error(Getfile(str),Getline(str),"Illegal macro argument name '%s'\n", argname);
+ } else {
+ Append(arglist,"__VA_ARGS__");
+ varargs = 1;
+ }
+ } else {
+ Append(arglist,argname);
+ }
Delete(argname);
argname = NewString("");
- } else if (isidchar(c)) {
+ } else if (isidchar(c) || (c == '.')) {
Putc(c,argname);
- } else if (!isspace(c)) {
- cpp_error(Getfile(str),Getline(str),"Illegal character in macro name\n");
+ } else if (!(isspace(c) || (c == '\\'))) {
+ Swig_error(Getfile(str),Getline(str),"Illegal character in macro argument name\n");
goto macro_error;
}
}
if (Len(argname)) {
- Append(arglist,argname);
+ /* Check for varargs */
+ if (Strstr(argname,".")) {
+ if (Strcmp(argname,"...") != 0) {
+ Swig_error(Getfile(str),Getline(str),"Illegal macro argument name '%s'\n", argname);
+ } else {
+ Append(arglist,"__VA_ARGS__");
+ varargs = 1;
+ }
+ } else {
+ Append(arglist,argname);
+ }
Delete(argname);
}
}
@@ -216,16 +245,70 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro)
if (!swigmacro) {
Replace(macrovalue,"\\\n"," ", DOH_REPLACE_NOQUOTE);
}
+
+ /* Look for special # substitutions. We only consider # that appears
+ outside of quotes and comments */
+
+ {
+ int state = 0;
+ char *cc = Char(macrovalue);
+ while (*cc) {
+ switch(state) {
+ case 0:
+ if (*cc == '#') *cc = '\001';
+ else if (*cc == '/') state = 10;
+ else if (*cc == '\'') state = 20;
+ else if (*cc == '\"') state = 30;
+ break;
+ case 10:
+ if (*cc == '*') state = 11;
+ else if (*cc == '/') state = 15;
+ else {
+ state = 0;
+ cc--;
+ }
+ break;
+ case 11:
+ if (*cc == '*') state = 12;
+ break;
+ case 12:
+ if (*cc == '/') state = 0;
+ else if (*cc != '*') state = 11;
+ break;
+ case 15:
+ if (*cc == '\n') state = 0;
+ break;
+ case 20:
+ if (*cc == '\'') state = 0;
+ if (*cc == '\\') state = 21;
+ break;
+ case 21:
+ state = 20;
+ break;
+ case 30:
+ if (*cc == '\"') state = 0;
+ if (*cc == '\\') state = 31;
+ break;
+ case 31:
+ state = 30;
+ break;
+ default:
+ break;
+ }
+ cc++;
+ }
+ }
+
/* Get rid of whitespace surrounding # */
- Replace(macrovalue,"#","\001",DOH_REPLACE_NOQUOTE);
+ /* Replace(macrovalue,"#","\001",DOH_REPLACE_NOQUOTE); */
while(strstr(Char(macrovalue),"\001 ")) {
- Replace(macrovalue,"\001 ","\001", DOH_REPLACE_NOQUOTE);
+ Replace(macrovalue,"\001 ","\001", DOH_REPLACE_ANY);
}
while(strstr(Char(macrovalue)," \001")) {
- Replace(macrovalue," \001","\001", DOH_REPLACE_NOQUOTE);
+ Replace(macrovalue," \001","\001", DOH_REPLACE_ANY);
}
/* Replace '##' with a special token */
- Replace(macrovalue,"\001\001","\002", DOH_REPLACE_NOQUOTE);
+ Replace(macrovalue,"\001\001","\002", DOH_REPLACE_ANY);
/* Go create the macro */
macro = NewHash();
@@ -234,6 +317,9 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro)
if (arglist) {
Setattr(macro,"args",arglist);
Delete(arglist);
+ if (varargs) {
+ Setattr(macro,"varargs","1");
+ }
}
Setattr(macro,"value",macrovalue);
Delete(macrovalue);
@@ -245,7 +331,7 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro)
symbols = Getattr(cpp,"symbols");
if ((m1 = Getattr(symbols,macroname))) {
if (Cmp(Getattr(m1,"value"),macrovalue))
- cpp_error(Getfile(str),Getline(str),"Macro '%s' redefined. Previous definition in \'%s\', Line %d\n", macroname, Getfile(m1), Getline(m1));
+ Swig_error(Getfile(str),Getline(str),"Macro '%s' redefined. Previous definition in \'%s\', Line %d\n", macroname, Getfile(m1), Getline(m1));
}
Setattr(symbols,macroname,macro);
Delete(str);
@@ -263,9 +349,9 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro)
*
* Undefines a macro.
* ----------------------------------------------------------------------------- */
-void Preprocessor_undef(DOHString_or_char *str)
+void Preprocessor_undef(String_or_char *str)
{
- DOH *symbols;
+ Hash *symbols;
assert(cpp);
symbols = Getattr(cpp,"symbols");
Delattr(symbols,str);
@@ -277,11 +363,11 @@ void Preprocessor_undef(DOHString_or_char *str)
* Isolates macro arguments and returns them in a list. For each argument,
* leading and trailing whitespace is stripped (ala K&R, pg. 230).
* ----------------------------------------------------------------------------- */
-static DOHList *
-find_args(DOHString *s)
+static List *
+find_args(String *s)
{
- DOHList *args;
- DOHString *str;
+ List *args;
+ String *str;
int c, level;
long pos;
@@ -344,7 +430,7 @@ find_args(DOHString *s)
c = Getc(s);
}
unterm:
- cpp_error(Getfile(args),Getline(args),"Unterminated macro call.\n");
+ Swig_error(Getfile(args),Getline(args),"Unterminated macro call.\n");
return args;
}
@@ -355,9 +441,9 @@ find_args(DOHString *s)
* or bare.
* ----------------------------------------------------------------------------- */
-static DOHString *
-get_filename(DOHString *str) {
- DOHString *fn;
+static String *
+get_filename(String *str) {
+ String *fn;
int c;
skip_whitespace(str,0);
@@ -377,6 +463,31 @@ get_filename(DOHString *str) {
return fn;
}
+static String *
+get_options(String *str) {
+
+ int c;
+ skip_whitespace(str,0);
+ c = Getc(str);
+ if (c == '(') {
+ String *opt;
+ int level = 1;
+ opt = NewString("(");
+ while (((c = Getc(str)) != EOF)) {
+ Putc(c,opt);
+ if (c == ')') {
+ level--;
+ if (!level) return opt;
+ }
+ if (c == '(') level++;
+ }
+ Delete(opt);
+ return 0;
+ } else {
+ Ungetc(c,str);
+ return 0;
+ }
+}
/* -----------------------------------------------------------------------------
* expand_macro()
*
@@ -386,12 +497,13 @@ get_filename(DOHString *str) {
DOH *expanded_value = 0;
-static DOHString *
-expand_macro(DOHString_or_char *name, DOHList *args)
+static String *
+expand_macro(String_or_char *name, List *args)
{
DOH *symbols, *ns, *macro, *margs, *mvalue, *temp, *tempa, *e;
DOH *Preprocessor_replace(DOH *);
int i, l;
+ int isvarargs = 0;
symbols = Getattr(cpp,"symbols");
if (!symbols) return 0;
@@ -420,14 +532,37 @@ expand_macro(DOHString_or_char *name, DOHList *args)
assert(mvalue);
margs = Getattr(macro,"args");
+ if (Getattr(macro,"varargs")) {
+ isvarargs = 1;
+ /* Variable length argument macro. We need to collect all of the extra arguments into a single argument */
+ if (Len(args) >= (Len(margs)-1)) {
+ int i;
+ int vi, na;
+ String *vararg = NewString("");
+ vi = Len(margs)-1;
+ na = Len(args);
+ for (i = vi; i < na; i++) {
+ Append(vararg,Getitem(args,i));
+ if ((i+1) < na) {
+ Append(vararg,",");
+ }
+ }
+ /* Remove arguments */
+ for (i = vi; i < na; i++) {
+ Delitem(args,vi);
+ }
+ Append(args,vararg);
+ Delete(vararg);
+ }
+ }
/* If there are arguments, see if they match what we were given */
if ((margs) && (Len(margs) != Len(args))) {
- if (Len(margs) > 1)
- cpp_error(Getfile(args),Getline(args),"Macro '%s' expects %d arguments\n", name, Len(margs));
- else if (Len(margs) == 1)
- cpp_error(Getfile(args),Getline(args),"Macro '%s' expects 1 argument\n", name);
+ if (Len(margs) > (1+isvarargs))
+ Swig_error(Getfile(args),Getline(args),"Macro '%s' expects %d arguments\n", name, Len(margs)-isvarargs);
+ else if (Len(margs) == (1+isvarargs))
+ Swig_error(Getfile(args),Getline(args),"Macro '%s' expects 1 argument\n", name);
else
- cpp_error(Getfile(args),Getline(args),"Macro '%s' expects no arguments\n", name);
+ Swig_error(Getfile(args),Getline(args),"Macro '%s' expects no arguments\n", name);
return 0;
}
@@ -480,27 +615,49 @@ expand_macro(DOHString_or_char *name, DOHList *args)
}
Replace(ns,temp,rep, DOH_REPLACE_ANY);
}
+ if (isvarargs) {
+ if ((Strcmp(aname,"__VA_ARGS__") == 0) && (Len(arg) == 0)) {
+ /* Zero length __VA_ARGS__ macro argument. We search for commas that might appear before and nuke them */
+ char *a, *s, *t;
+ s = Char(ns);
+ a = strstr(s,"__VA_ARGS__");
+ while (a) {
+ t = a-1;
+ if (*t == '\002') {
+ t--;
+ while (t >= s) {
+ if (isspace((int) *t)) t--;
+ else if (*t == ',') {
+ *t = ' ';
+ } else break;
+ }
+ }
+ a = strstr(a+11,"__VA_ARGS__");
+ }
+ }
+ }
Replace(ns, aname, arg, DOH_REPLACE_ID);
}
}
Replace(ns,"\002","",DOH_REPLACE_ANY); /* Get rid of concatenation tokens */
Replace(ns,"\001","#",DOH_REPLACE_ANY); /* Put # back (non-standard C) */
-
/* Expand this macro even further */
e = Preprocessor_replace(ns);
Delete(ns);
Delattr(macro,"*expanded*");
if (Getattr(macro,"swigmacro")) {
- DOHString *g;
- DOHString *f = NewString("");
- Printf(f,"%%macro %s, \"%s\", %d {\n", name, Getfile(macro), Getline(macro));
+ String *g;
+ String *f = NewString("");
Seek(e,0,SEEK_SET);
copy_location(macro,e);
g = Preprocessor_parse(e);
- Printf(f,"%s\n", g);
- Printf(f,"}\n");
+
+ /* Drop the macro in place, but with a marker around it */
+ Printf(f,"/*@%s,%d,%s@*/%s/*@@*/", Getfile(macro), Getline(macro), name, g);
+
+ /* Printf(f," }\n"); */
Delete(g);
Delete(e);
e = f;
@@ -511,6 +668,24 @@ expand_macro(DOHString_or_char *name, DOHList *args)
}
/* -----------------------------------------------------------------------------
+ * evaluate_args()
+ *
+ * Evaluate the arguments of a macro
+ * ----------------------------------------------------------------------------- */
+
+List *evaluate_args(List *x) {
+ String *a;
+ String *Preprocessor_replace(String *);
+
+ List *nl = NewList();
+
+ for (a = Firstitem(x); a; a = Nextitem(x)) {
+ Append(nl,Preprocessor_replace(a));
+ }
+ return nl;
+}
+
+/* -----------------------------------------------------------------------------
* DOH *Preprocessor_replace(DOH *s)
*
* Performs a macro substitution on a string s. Returns a new string with
@@ -575,6 +750,7 @@ Preprocessor_replace(DOH *s)
DOH *arg = 0;
args = NewList();
arg = NewString("");
+ if (isidchar(c)) Putc(c,arg);
while ((c = Getc(s)) != EOF) {
if (!isidchar(c)) {
Seek(s,-1,SEEK_CUR);
@@ -585,8 +761,8 @@ Preprocessor_replace(DOH *s)
Append(args,arg);
Delete(arg);
}
- if (!args) {
- cpp_error(Getfile(id),Getline(id),"No arguments given to defined()\n");
+ if ((!args) || (!Len(args))) {
+ Swig_error(Getfile(id),Getline(id),"No arguments given to defined()\n");
state = 0;
break;
}
@@ -608,7 +784,10 @@ Preprocessor_replace(DOH *s)
break;
}
if (Cmp(id,"__FILE__") == 0) {
- Printf(ns,"\"%s\"",Getfile(s));
+ String *fn = Copy(Getfile(s));
+ Replaceall(fn,"\\","\\\\");
+ Printf(ns,"\"%s\"",fn);
+ Delete(fn);
state = 0;
break;
}
@@ -623,6 +802,12 @@ Preprocessor_replace(DOH *s)
} else {
args = 0;
}
+ if (args) {
+ List *nargs = evaluate_args(args);
+ Delete(args);
+ args = nargs;
+ }
+
e = expand_macro(id,args);
if (e) {
Printf(ns,"%s",e);
@@ -668,13 +853,13 @@ Preprocessor_replace(DOH *s)
if (state == 1) {
/* See if this is the special "defined" macro */
if (Cmp(id,"defined") == 0) {
- cpp_error(Getfile(id),Getline(id),"No arguments given to defined()\n");
+ Swig_error(Getfile(id),Getline(id),"No arguments given to defined()\n");
} else if ((m = Getattr(symbols,id))) {
DOH *e;
/* Yes. There is a macro here */
/* See if the macro expects arguments */
if (Getattr(m,"args")) {
- cpp_error(Getfile(id),Getline(id),"Macro arguments expected.\n");
+ Swig_error(Getfile(id),Getline(id),"Macro arguments expected.\n");
}
e = expand_macro(id,0);
Printf(ns,"%s",e);
@@ -698,52 +883,24 @@ Preprocessor_replace(DOH *s)
static int
check_id(DOH *s)
{
- int c, state = 0;
- int hasvalue = 0;
+ static SwigScanner *scan = 0;
+ int c;
+
Seek(s,0,SEEK_SET);
- while ((c = Getc(s)) != EOF) {
- switch(state) {
- case 0:
- if (isdigit(c)) {
- hasvalue =1;
- state = 1;
- }
- else if (isidentifier(c)) return 1;
- else if (c == '\"') {
- skip_tochar(s,'\"',0);
- hasvalue = 1;
- } else if (c == '\'') {
- skip_tochar(s,'\'',0);
- hasvalue = 1;
- } else if (c == '/') state = 3;
- break;
- case 1:
- if (isspace(c)) state = 0;
- hasvalue = 1;
- break;
- case 3:
- if (c == '*') state = 10;
- else if (c == '/') state = 20;
- else {
- Ungetc(c,s);
- state = 0;
- }
- break;
- case 10:
- if (c == '*') state = 11;
- break;
- case 11:
- if (c == '/') state = 0;
- else if (c != '*') state = 10;
- break;
- case 20:
- if (c == '\n') state = 0;
- break;
- }
+ if (!scan) {
+ scan = NewSwigScanner();
+ }
+
+ SwigScanner_clear(scan);
+ s = Copy(s);
+ Seek(s,SEEK_SET,0);
+ SwigScanner_push(scan,s);
+ while ((c = SwigScanner_token(scan))) {
+ if ((c == SWIG_TOKEN_ID) || (c == SWIG_TOKEN_LBRACE) || (c == SWIG_TOKEN_RBRACE)) return 1;
}
- if (!hasvalue) return 1;
return 0;
+
}
/* addline(). Utility function for adding lines to a chunk */
@@ -775,7 +932,7 @@ static void add_chunk(DOH *ns, DOH *chunk, int allow) {
}
/* -----------------------------------------------------------------------------
- * DOH *Preprocessor_parse(DOH *s)
+ * Preprocessor_parse()
*
* Parses the string s. Returns a new string containing the preprocessed version.
*
@@ -787,12 +944,13 @@ static void add_chunk(DOH *ns, DOH *chunk, int allow) {
* included inline (with all preprocessor directives included).
* ----------------------------------------------------------------------------- */
-DOH *
-Preprocessor_parse(DOH *s)
+String *
+Preprocessor_parse(String *s)
{
- DOH *ns; /* New string containing the preprocessed text */
- DOH *chunk, *symbols, *sval, *decl;
- DOH *id = 0, *value = 0, *comment = 0;
+ String *ns; /* New string containing the preprocessed text */
+ String *chunk, *sval, *decl;
+ Hash *symbols;
+ String *id = 0, *value = 0, *comment = 0;
int i, state, val, e, c;
int start_line = 0;
int allow = 1;
@@ -802,6 +960,9 @@ Preprocessor_parse(DOH *s)
int cpp_lines = 0;
int cond_lines[256];
+ /* Blow away all carriage returns */
+ Replace(s,"\015","",DOH_REPLACE_ANY);
+
ns = NewString(""); /* Return result */
decl = NewString("");
@@ -842,12 +1003,12 @@ Preprocessor_parse(DOH *s)
else if (c == '\"') {
start_line = Getline(s);
if (skip_tochar(s,'\"',chunk) < 0) {
- cpp_error(Getfile(s),-1,"Unterminated string constant starting at line %d\n",start_line);
+ Swig_error(Getfile(s),-1,"Unterminated string constant starting at line %d\n",start_line);
}
} else if (c == '\'') {
start_line = Getline(s);
if (skip_tochar(s,'\'',chunk) < 0) {
- cpp_error(Getfile(s),-1,"Unterminated character constant starting at line %d\n",start_line);
+ Swig_error(Getfile(s),-1,"Unterminated character constant starting at line %d\n",start_line);
}
}
else if (c == '/') state = 30; /* Comment */
@@ -896,8 +1057,13 @@ Preprocessor_parse(DOH *s)
if (c == '\n') {
Ungetc(c,s);
state = 50;
+ } else {
+ state = 42;
+ if (!isspace(c)) {
+ Ungetc(c,s);
+ }
}
- else state = 42;
+
copy_location(s,value);
break;
}
@@ -922,6 +1088,12 @@ Preprocessor_parse(DOH *s)
state = 50;
} else if (c == '/') {
state = 45;
+ } else if (c == '\"') {
+ Putc(c,value);
+ skip_tochar(s,'\"',value);
+ } else if (c == '\'') {
+ Putc(c,value);
+ skip_tochar(s,'\'',value);
} else {
Putc(c,value);
if (c == '\\') state = 44;
@@ -982,9 +1154,9 @@ Preprocessor_parse(DOH *s)
if ((m) && !(Getattr(m,"args"))) {
v = Copy(Getattr(m,"value"));
if (Len(v)) {
- silent_errors = 1;
+ Swig_error_silent(1);
v1 = Preprocessor_replace(v);
- silent_errors = 0;
+ Swig_error_silent(0);
/* Printf(stdout,"checking '%s'\n", v1); */
if (!check_id(v1)) {
if (Len(comment) == 0)
@@ -1021,20 +1193,20 @@ Preprocessor_parse(DOH *s)
}
} else if (Cmp(id,"else") == 0) {
if (level <= 0) {
- cpp_error(Getfile(s),Getline(id),"Misplaced #else.\n");
+ Swig_error(Getfile(s),Getline(id),"Misplaced #else.\n");
} else {
cond_lines[level-1] = Getline(id);
if (allow) {
allow = 0;
mask = 0;
} else if (level == start_level) {
- allow = 1;
+ allow = 1*mask;
}
}
} else if (Cmp(id,"endif") == 0) {
level--;
if (level < 0) {
- cpp_error(Getfile(id),Getline(id),"Extraneous #endif ignored.\n");
+ Swig_error(Getfile(id),Getline(id),"Extraneous #endif.\n");
level = 0;
} else {
if (level < start_level) {
@@ -1053,7 +1225,7 @@ Preprocessor_parse(DOH *s)
val = Preprocessor_expr(sval,&e);
if (e) {
Seek(value,0,SEEK_SET);
- /* cpp_error(Getfile(value),Getline(value),"Could not evaluate '%s'\n", value); */
+ Swig_warning(WARN_PP_EVALUATION,Getfile(value),Getline(value),"Could not evaluate '%s'\n", value);
allow = 0;
} else {
if (val == 0)
@@ -1063,7 +1235,7 @@ Preprocessor_parse(DOH *s)
}
} else if (Cmp(id,"elif") == 0) {
if (level == 0) {
- cpp_error(Getfile(s),Getline(id),"Misplaced #elif.\n");
+ Swig_error(Getfile(s),Getline(id),"Misplaced #elif.\n");
} else {
cond_lines[level-1] = Getline(id);
if (allow) {
@@ -1075,7 +1247,7 @@ Preprocessor_parse(DOH *s)
val = Preprocessor_expr(sval,&e);
if (e) {
Seek(value,0,SEEK_SET);
- /* cpp_error(Getfile(value),Getline(value),"Could not evaluate '%s'\n", value); */
+ Swig_warning(WARN_PP_EVALUATION,Getfile(value),Getline(value),"Could not evaluate '%s'\n", value);
allow = 0;
} else {
if (val)
@@ -1087,24 +1259,36 @@ Preprocessor_parse(DOH *s)
}
} else if (Cmp(id,"line") == 0) {
} else if (Cmp(id,"include") == 0) {
- if ((include_all) && (allow)) {
+ if (((include_all) || (import_all)) && (allow)) {
DOH *s1, *s2, *fn;
Seek(value,0,SEEK_SET);
fn = get_filename(value);
s1 = cpp_include(fn);
if (s1) {
- Printf(ns,"%%file(\"include\") \"%s\" {\n", Swig_last_file());
+ if (include_all)
+ Printf(ns,"%%includefile \"%s\" [\n", Swig_last_file());
+ else if (import_all)
+ Printf(ns,"%%importfile \"%s\" [\n", Swig_last_file());
s2 = Preprocessor_parse(s1);
addline(ns,s2,allow);
- Printf(ns,"\n}\n");
+ Printf(ns,"\n]\n");
Delete(s2);
}
Delete(s1);
Delete(fn);
}
} else if (Cmp(id,"pragma") == 0) {
+ if (Strncmp(value,"SWIG ",5) == 0) {
+ char *c = Char(value)+5;
+ while (*c && (isspace((int)*c))) c++;
+ if (*c) {
+ if (Strncmp(c,"nowarn=",7) == 0) {
+ Swig_warnfilter(c+7,1);
+ }
+ }
+ }
} else if (Cmp(id,"level") == 0) {
- cpp_error(Getfile(s),Getline(id),"cpp debug: level = %d, startlevel = %d\n", level, start_level);
+ Swig_error(Getfile(s),Getline(id),"cpp debug: level = %d, startlevel = %d\n", level, start_level);
}
for (i = 0; i < cpp_lines; i++)
Putc('\n',ns);
@@ -1124,8 +1308,9 @@ Preprocessor_parse(DOH *s)
}
/* %#cpp - an embedded C preprocessor directive (we strip off the %) */
else if (c == '#') {
+ add_chunk(ns,chunk,allow);
Putc(c,chunk);
- state = 0;
+ state = 107;
} else if (isidentifier(c)) {
Clear(decl);
Putc('%',decl);
@@ -1155,6 +1340,22 @@ Preprocessor_parse(DOH *s)
state = 105;
}
break;
+
+ case 107:
+ Putc(c,chunk);
+ if (c == '\n') {
+ addline(ns,chunk,allow);
+ Clear(chunk);
+ state = 0;
+ } else if (c == '\\') {
+ state = 108;
+ }
+ break;
+
+ case 108:
+ Putc(c,chunk);
+ state = 107;
+ break;
case 110:
if (!isidchar(c)) {
@@ -1163,22 +1364,31 @@ Preprocessor_parse(DOH *s)
if ((Cmp(decl,"%include") == 0) || (Cmp(decl,"%import") == 0) || (Cmp(decl,"%extern") == 0)) {
/* Got some kind of file inclusion directive */
if (allow) {
- DOH *s1, *s2, *fn;
+ DOH *s1, *s2, *fn, *opt;
+
+ if (Cmp(decl,"%extern") == 0) {
+ Swig_warning(WARN_DEPRECATED_EXTERN, Getfile(s),Getline(s),"%%extern is deprecated. Use %%import instead.\n");
+ Clear(decl);
+ Printf(decl,"%%import");
+ }
+ opt = get_options(s);
fn = get_filename(s);
s1 = cpp_include(fn);
if (s1) {
add_chunk(ns,chunk,allow);
copy_location(s,chunk);
- Printf(ns,"%%file(\"%s\") \"%s\" {\n", Char(decl)+1, Swig_last_file());
+ Printf(ns,"%sfile%s \"%s\" [\n", decl, opt, Swig_last_file());
if ((Cmp(decl,"%import") == 0) || (Cmp(decl,"%extern") == 0)) {
Preprocessor_define("WRAPEXTERN 1", 0);
+ Preprocessor_define("SWIGIMPORT 1", 0);
}
s2 = Preprocessor_parse(s1);
if ((Cmp(decl,"%import") == 0) || (Cmp(decl,"%extern") == 0)) {
+ Preprocessor_undef("SWIGIMPORT");
Preprocessor_undef("WRAPEXTERN");
}
addline(ns,s2,allow);
- Printf(ns,"\n}\n");
+ Printf(ns,"\n]\n");
Delete(s2);
Delete(s1);
}
@@ -1209,15 +1419,17 @@ Preprocessor_parse(DOH *s)
Putc(c,value);
if (c == '%') {
int i = 0;
- char *d = "enddef\n";
- for (i = 0; i < 7; i++) {
+ char *d = "enddef";
+ for (i = 0; i < 6; i++) {
c = Getc(s);
Putc(c,value);
if (c != d[i]) break;
}
- if (i == 7) {
+ c = Getc(s);
+ Ungetc(c,s);
+ if ((i == 6) && (isspace(c))) {
/* Got the macro */
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 7; i++) {
Delitem(value,DOH_END);
}
if (allow) {
@@ -1237,18 +1449,18 @@ Preprocessor_parse(DOH *s)
}
}
while (level > 0) {
- cpp_error(Getfile(s),-1,"Missing #endif for conditional starting on line %d\n", cond_lines[level-1]);
+ Swig_error(Getfile(s),-1,"Missing #endif for conditional starting on line %d\n", cond_lines[level-1]);
level--;
}
if (state == 150) {
Seek(value,0,SEEK_SET);
- cpp_error(Getfile(s),-1,"Missing %%enddef for macro starting on line %d\n",Getline(value));
+ Swig_error(Getfile(s),-1,"Missing %%enddef for macro starting on line %d\n",Getline(value));
}
if ((state >= 105) && (state < 107)) {
- cpp_error(Getfile(s),-1,"Unterminated %%{ ... %%} block starting on line %d\n", start_line);
+ Swig_error(Getfile(s),-1,"Unterminated %%{ ... %%} block starting on line %d\n", start_line);
}
if ((state >= 30) && (state < 40)) {
- cpp_error(Getfile(s),-1,"Unterminated comment starting on line %d\n", start_line);
+ Swig_error(Getfile(s),-1,"Unterminated comment starting on line %d\n", start_line);
}
add_chunk(ns,chunk,allow);
copy_location(s,chunk);
diff --git a/Source/Preprocessor/expr.c b/Source/Preprocessor/expr.c
index 13ca42d96..39a54149c 100644
--- a/Source/Preprocessor/expr.c
+++ b/Source/Preprocessor/expr.c
@@ -10,7 +10,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_expr_c[] = "$Header$";
#include "preprocessor.h"
@@ -19,6 +19,7 @@ static SwigScanner *scan = 0;
typedef struct {
int op;
long value;
+ String *svalue;
} exprval;
#define EXPR_TOP 1
@@ -66,95 +67,122 @@ static void reduce_op() {
sp = 0;
return;
}
- switch(stack[sp-1].value) {
- case SWIG_TOKEN_STAR:
- stack[sp-2].value = stack[sp-2].value * stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_EQUALTO:
- stack[sp-2].value = stack[sp-2].value == stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_NOTEQUAL:
- stack[sp-2].value = stack[sp-2].value != stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_PLUS:
- stack[sp-2].value = stack[sp-2].value + stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_MINUS:
- stack[sp-2].value = stack[sp-2].value - stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_AND:
- stack[sp-2].value = stack[sp-2].value & stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_LAND:
- stack[sp-2].value = stack[sp-2].value && stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_OR:
- stack[sp-2].value = stack[sp-2].value | stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_LOR:
- stack[sp-2].value = stack[sp-2].value || stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_XOR:
- stack[sp-2].value = stack[sp-2].value ^ stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_LESSTHAN:
- stack[sp-2].value = stack[sp-2].value < stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_GREATERTHAN:
- stack[sp-2].value = stack[sp-2].value > stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_LTEQUAL:
- stack[sp-2].value = stack[sp-2].value <= stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_GTEQUAL:
- stack[sp-2].value = stack[sp-2].value >= stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_NOT:
- stack[sp-1].value = ~stack[sp].value;
- sp--;
- break;
- case SWIG_TOKEN_LNOT:
- stack[sp-1].value = !stack[sp].value;
- sp--;
- break;
- case EXPR_UMINUS:
- stack[sp-1].value = -stack[sp].value;
- sp--;
- break;
- case SWIG_TOKEN_SLASH:
- stack[sp-2].value = stack[sp-2].value / stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_PERCENT:
- stack[sp-2].value = stack[sp-2].value % stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_LSHIFT:
- stack[sp-2].value = stack[sp-2].value << stack[sp].value;
- sp -= 2;
- break;
- case SWIG_TOKEN_RSHIFT:
- stack[sp-2].value = stack[sp-2].value >> stack[sp].value;
- sp -= 2;
- break;
- default:
- errmsg = "Syntax error";
- sp = 0;
- break;
+ if (stack[sp-2].svalue || stack[sp].svalue) {
+ /* A string expression */
+ if (!(stack[sp-2].svalue && stack[sp].svalue)) {
+ errmsg = "Can't mix strings and integers in expression";
+ sp = 0;
+ return;
+ }
+ switch(stack[sp-1].value) {
+ case SWIG_TOKEN_EQUALTO:
+ stack[sp-2].value = (Strcmp(stack[sp-2].svalue,stack[sp].svalue) == 0);
+ Delete(stack[sp-2].svalue);
+ Delete(stack[sp].svalue);
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_NOTEQUAL:
+ stack[sp-2].value = (Strcmp(stack[sp-2].svalue,stack[sp].svalue) != 0);
+ Delete(stack[sp-2].svalue);
+ Delete(stack[sp].svalue);
+ sp -= 2;
+ break;
+ default:
+ errmsg = "Syntax error";
+ sp = 0;
+ break;
+ }
+ } else {
+ switch(stack[sp-1].value) {
+ case SWIG_TOKEN_STAR:
+ stack[sp-2].value = stack[sp-2].value * stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_EQUALTO:
+ stack[sp-2].value = stack[sp-2].value == stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_NOTEQUAL:
+ stack[sp-2].value = stack[sp-2].value != stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_PLUS:
+ stack[sp-2].value = stack[sp-2].value + stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_MINUS:
+ stack[sp-2].value = stack[sp-2].value - stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_AND:
+ stack[sp-2].value = stack[sp-2].value & stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_LAND:
+ stack[sp-2].value = stack[sp-2].value && stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_OR:
+ stack[sp-2].value = stack[sp-2].value | stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_LOR:
+ stack[sp-2].value = stack[sp-2].value || stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_XOR:
+ stack[sp-2].value = stack[sp-2].value ^ stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_LESSTHAN:
+ stack[sp-2].value = stack[sp-2].value < stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_GREATERTHAN:
+ stack[sp-2].value = stack[sp-2].value > stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_LTEQUAL:
+ stack[sp-2].value = stack[sp-2].value <= stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_GTEQUAL:
+ stack[sp-2].value = stack[sp-2].value >= stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_NOT:
+ stack[sp-1].value = ~stack[sp].value;
+ sp--;
+ break;
+ case SWIG_TOKEN_LNOT:
+ stack[sp-1].value = !stack[sp].value;
+ sp--;
+ break;
+ case EXPR_UMINUS:
+ stack[sp-1].value = -stack[sp].value;
+ sp--;
+ break;
+ case SWIG_TOKEN_SLASH:
+ stack[sp-2].value = stack[sp-2].value / stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_PERCENT:
+ stack[sp-2].value = stack[sp-2].value % stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_LSHIFT:
+ stack[sp-2].value = stack[sp-2].value << stack[sp].value;
+ sp -= 2;
+ break;
+ case SWIG_TOKEN_RSHIFT:
+ stack[sp-2].value = stack[sp-2].value >> stack[sp].value;
+ sp -= 2;
+ break;
+ default:
+ errmsg = "Syntax error";
+ sp = 0;
+ break;
+ }
}
stack[sp].op = EXPR_VALUE;
}
@@ -187,6 +215,7 @@ Preprocessor_expr(DOH *s, int *error) {
assert(scan);
Seek(s,0,SEEK_SET);
+ /* Printf(stdout,"evaluating : '%s'\n", s); */
*error = 0;
SwigScanner_clear(scan);
SwigScanner_push(scan,s);
@@ -208,7 +237,10 @@ Preprocessor_expr(DOH *s, int *error) {
}
if ((token == SWIG_TOKEN_INT) || (token == SWIG_TOKEN_UINT) || (token == SWIG_TOKEN_LONG) || (token == SWIG_TOKEN_ULONG)) {
/* A number. Reduce EXPR_TOP to an EXPR_VALUE */
- stack[sp].value = (long) atol(Char(SwigScanner_text(scan)));
+ char *c = Char(SwigScanner_text(scan));
+ stack[sp].value = (long) strtol(c,0,0);
+ stack[sp].svalue = 0;
+ /* stack[sp].value = (long) atol(Char(SwigScanner_text(scan))); */
stack[sp].op = EXPR_VALUE;
} else if (token == SWIG_TOKEN_PLUS) { }
else if ((token == SWIG_TOKEN_MINUS) || (token == SWIG_TOKEN_LNOT) || (token==SWIG_TOKEN_NOT)) {
@@ -216,12 +248,21 @@ Preprocessor_expr(DOH *s, int *error) {
stack[sp].value = token;
stack[sp++].op = EXPR_OP;
stack[sp].op = EXPR_TOP;
+ stack[sp].svalue = 0;
} else if ((token == SWIG_TOKEN_LPAREN)) {
stack[sp++].op = EXPR_GROUP;
stack[sp].op = EXPR_TOP;
stack[sp].value = 0;
- } else if (token == SWIG_TOKEN_ENDLINE) { }
- else goto syntax_error;
+ stack[sp].svalue = 0;
+ } else if (token == SWIG_TOKEN_ENDLINE) {
+ } else if ((token == SWIG_TOKEN_STRING)) {
+ stack[sp].svalue = NewString(SwigScanner_text(scan));
+ stack[sp].op = EXPR_VALUE;
+ } else if ((token == SWIG_TOKEN_ID)) {
+ stack[sp].value = 0;
+ stack[sp].svalue = 0;
+ stack[sp].op = EXPR_VALUE;
+ } else goto syntax_error;
break;
case EXPR_VALUE:
/* A value is on the stack. We may reduce or evaluate depending on what the next token is */
@@ -302,6 +343,7 @@ Preprocessor_expr(DOH *s, int *error) {
break;
}
break;
+
default:
fprintf(stderr,"Internal error in expression evaluator.\n");
abort();
diff --git a/Source/Preprocessor/preprocessor.h b/Source/Preprocessor/preprocessor.h
index a32501164..eb4f8feda 100644
--- a/Source/Preprocessor/preprocessor.h
+++ b/Source/Preprocessor/preprocessor.h
@@ -15,19 +15,21 @@
#define _PREPROCESSOR_H
#include "swig.h"
+#include "swigwarn.h"
#ifdef __cplusplus
extern "C" {
#endif
-
-extern void Preprocessor_expr_init(void);
-extern int Preprocessor_expr(DOHString *s, int *error);
-extern char *Preprocessor_expr_error(void);
-extern DOH *Preprocessor_define(DOHString_or_char *str, int swigmacro);
-extern void Preprocessor_undef(DOHString_or_char *name);
-extern void Preprocessor_init();
-extern DOH *Preprocessor_parse(DOH *s);
-extern void Preprocessor_include_all(int);
+extern int Preprocessor_expr(String *s, int *error);
+extern char *Preprocessor_expr_error(void);
+extern Hash *Preprocessor_define(const String_or_char *str, int swigmacro);
+extern void Preprocessor_undef(String_or_char *name);
+extern void Preprocessor_init();
+extern String *Preprocessor_parse(String *s);
+extern void Preprocessor_include_all(int);
+extern void Preprocessor_import_all(int);
+extern void Preprocessor_ignore_missing(int);
+extern List *Preprocessor_depend(void);
#ifdef __cplusplus
}
diff --git a/Source/README b/Source/README
new file mode 100644
index 000000000..db46fd03d
--- /dev/null
+++ b/Source/README
@@ -0,0 +1,32 @@
+SWIG Source directory
+
+This directory currently contains a mix of legacy SWIG1.1 code and
+recent development work. As a result, it's still a little messy.
+Here is a rough breakdown of the directories:
+
+ Source/DOH - A core set of basic datatypes including
+ strings, lists, hashes, and files. Used
+ extensively by the rest of SWIG.
+
+ Source/Swig - Swig core. Type-system, utility functions.
+
+ Source/Preprocessor - SWIG C Preprocessor
+
+ Source/CParse - SWIG C Parser (still messy)
+
+ Source/Modules1.1 - Old SWIG1.1 derived language modules.
+ Remaining legacy code.
+
+
+The following directories may be in CVS, but are largely deprecated:
+
+ Source/Modules - Some experimental module work. New
+ modules may be added here eventually.
+
+ Source/LParse - Experimental parser. Officially dead
+ as CParse is more capable.
+
+ Source/SWIG1.1 - Old SWIG1.1 core. Completely empty now.
+
+
+
diff --git a/Source/Swig/Makefile.in b/Source/Swig/Makefile.in
index 9503e0ab2..1186c6887 100644
--- a/Source/Swig/Makefile.in
+++ b/Source/Swig/Makefile.in
@@ -5,10 +5,10 @@
srcdir = @srcdir@
VPATH = @srcdir@
-SRCS = map.c wrapfunc.c naming.c tree.c stype.c scanner.c include.c getopt.c misc.c \
- parms.c cwrap.c typemap.c module.c main.c
-OBJS = map.o wrapfunc.o naming.o tree.o stype.o scanner.o include.o getopt.o misc.o \
- parms.o cwrap.o typemap.o module.o main.o
+SRCS = wrapfunc.c naming.c tree.c stype.c typesys.c scanner.c include.c getopt.c misc.c \
+ parms.c cwrap.c typemap.c warn.c symbol.c error.c fragment.c
+OBJS = wrapfunc.@OBJEXT@ naming.@OBJEXT@ tree.@OBJEXT@ stype.@OBJEXT@ typesys.@OBJEXT@ scanner.@OBJEXT@ include.@OBJEXT@ getopt.@OBJEXT@ misc.@OBJEXT@ \
+ parms.@OBJEXT@ cwrap.@OBJEXT@ typemap.@OBJEXT@ warn.@OBJEXT@ symbol.@OBJEXT@ error.@OBJEXT@ fragment.@OBJEXT@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -17,11 +17,11 @@ CC = @CC@
AR = @AR@
RANLIB = @RANLIB@
CFLAGS = @CFLAGS@
-INCLUDE = -I$(srcdir)/. -I$(srcdir)/../DOH/Include -I$(srcdir)/../Include
+INCLUDES = -I$(srcdir)/. -I$(srcdir)/../DOH/Include -I$(srcdir)/../Include
TARGET = libswig.a
-.c.o:
- $(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $<
+.c.@OBJEXT@:
+ $(CC) $(CFLAGS) $(INCLUDES) -c -o $*.@OBJEXT@ $<
all: $(TARGET)
@@ -30,4 +30,4 @@ $(TARGET): $(OBJS)
$(RANLIB) $(TARGET)
clean:
- rm -f *.o *~ core *.so *.a *_wrap.*
+ rm -f *.@OBJEXT@ *~ core *.so *.a *_wrap.*
diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c
index a5fd6d9ba..5abcab2ab 100644
--- a/Source/Swig/cwrap.c
+++ b/Source/Swig/cwrap.c
@@ -13,10 +13,18 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_cwrap_c[] = "$Header$";
#include "swig.h"
+static Parm *nonvoid_parms(Parm *p) {
+ if (p) {
+ SwigType *t = Getattr(p,"type");
+ if (SwigType_type(t) == T_VOID) return 0;
+ }
+ return p;
+}
+
/* -----------------------------------------------------------------------------
* Swig_parm_name()
*
@@ -25,11 +33,11 @@ static char cvsroot[] = "$Header$";
String *
Swig_cparm_name(Parm *p, int i) {
- String *name = NewStringf("arg%d",i);
+ String *name = NewStringf("arg%d",i+1);
if (p) {
- Setlname(p,name);
+ Setattr(p,"lname",name);
}
- return Swig_temp_result(name);
+ return name;
}
/* -----------------------------------------------------------------------------
@@ -41,99 +49,67 @@ Swig_cparm_name(Parm *p, int i) {
String *
Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value) {
- String *decl = 0;
+ String *decl;
- /* *((char *) decl) = 'x';*/
decl = NewString("");
+
switch(SwigType_type(t)) {
- case T_USER:
- SwigType_add_pointer(t);
- if (value)
- Printf(decl,"%s = (%s) &%s", SwigType_lstr(t,name), SwigType_lstr(t,0), value);
- else
- Printf(decl,"%s", SwigType_lstr(t,name));
- SwigType_del_pointer(t);
- break;
case T_REFERENCE:
- if (value)
- Printf(decl,"%s = (%s) &%s", SwigType_lstr(t,name), SwigType_lstr(t,0), value);
- else
- Printf(decl,"%s", SwigType_lstr(t,name));
+ if (value) {
+ Printf(decl,"%s = (%s) &%s_defvalue", SwigType_lstr(t,name), SwigType_lstr(t,0), name);
+ } else {
+ Printf(decl,"%s = 0", SwigType_lstr(t,name));
+ }
break;
case T_VOID:
break;
+ case T_VARARGS:
+ Printf(decl,"void *%s = 0", name);
+ break;
+
default:
- if (value)
- Printf(decl,"%s = %s", SwigType_lstr(t,name), value);
- else
+ if (value) {
+ Printf(decl,"%s = (%s) %s", SwigType_lstr(t,name), SwigType_lstr(t,0), SwigType_lcaststr(t,value));
+ } else {
Printf(decl,"%s", SwigType_lstr(t,name));
+ }
}
- return Swig_temp_result(decl);
+ return decl;
}
/* -----------------------------------------------------------------------------
- * Swig_clocal_type()
+ * Swig_wrapped_var_convert()
*
- * Creates a string that declares a C local variable type. Converts references
- * and user defined types to pointers.
+ * Converts a member variable for use in the get and set wrapper methods.
+ * This function only converts user defined types to pointers.
* ----------------------------------------------------------------------------- */
-SwigType *
-Swig_clocal_type(SwigType *t) {
+String *
+Swig_wrapped_var_type(SwigType *t) {
SwigType *ty;
- switch(SwigType_type(t)) {
- case T_USER:
- SwigType_add_pointer(t);
- ty = SwigType_ltype(t);
- SwigType_del_pointer(t);
- break;
- default:
- ty = SwigType_ltype(t);
- break;
+ ty = Copy(t);
+
+ if (SwigType_isclass(t)) {
+ SwigType_add_pointer(ty);
}
return ty;
}
-/* -----------------------------------------------------------------------------
- * Swig_clocal_deref()
- *
- * Creates a string that can be used to deref a local variable wrapped with
- * the Swig_clocal() function.
- * ----------------------------------------------------------------------------- */
-
String *
-Swig_clocal_deref(SwigType *t, String_or_char *name) {
- switch(SwigType_type(t)) {
- case T_USER:
- return Swig_temp_result(NewStringf("*%s",name));
- break;
- case T_VOID:
- return Swig_temp_result(NewString(""));
- break;
- default:
+Swig_wrapped_var_deref(SwigType *t, String_or_char *name) {
+ if (SwigType_isclass(t)) {
+ return NewStringf("*%s",name);
+ } else {
return SwigType_rcaststr(t,name);
- break;
}
}
-/* -----------------------------------------------------------------------------
- * Swig_clocal_assign()
- *
- * Assigns a value to a local
- * ----------------------------------------------------------------------------- */
-
String *
-Swig_clocal_assign(SwigType *t, String_or_char *name) {
- switch(SwigType_type(t)) {
- case T_VOID:
- return Swig_temp_result(NewString(""));
- break;
- case T_USER:
- return Swig_temp_result(NewStringf("&%s", name));
- break;
- default:
+Swig_wrapped_var_assign(SwigType *t, String_or_char *name) {
+ if (SwigType_isclass(t)) {
+ return NewStringf("&%s",name);
+ } else {
return SwigType_lcaststr(t,name);
- break;
}
}
@@ -151,17 +127,41 @@ int Swig_cargs(Wrapper *w, ParmList *p) {
String *pname;
String *local;
String *lname;
+ SwigType *altty;
+ String *type;
+ int tycode;
i = 0;
while (p != 0) {
lname = Swig_cparm_name(p,i);
- pt = Gettype(p);
- pname = Getname(p);
- pvalue = Getvalue(p);
- local = Swig_clocal(pt,lname,pvalue);
- Wrapper_add_localv(w,lname,local,0);
- i++;
- p = Getnext(p);
+ pt = Getattr(p,"type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ pname = Getattr(p,"name");
+ pvalue = Getattr(p,"value");
+ altty = Getattr(p,"alttype");
+ type = Getattr(p,"type");
+ tycode = SwigType_type(type);
+ if (tycode == T_REFERENCE) {
+ if (pvalue) {
+ String *defname, *defvalue;
+ defname = NewStringf("%s_defvalue", lname);
+ defvalue = NewStringf("%s = %s", SwigType_str(type,defname), pvalue);
+ Wrapper_add_localv(w,defname, defvalue, NIL);
+ Delete(defname);
+ Delete(defvalue);
+ }
+ } else if (!pvalue && (tycode == T_POINTER)) {
+ pvalue = (String *) "0";
+ }
+ if (!altty) {
+ local = Swig_clocal(pt,lname,pvalue);
+ } else {
+ local = Swig_clocal(altty,lname, pvalue);
+ }
+ Wrapper_add_localv(w,lname,local,NIL);
+ i++;
+ }
+ p = nextSibling(p);
}
return(i);
}
@@ -173,27 +173,21 @@ int Swig_cargs(Wrapper *w, ParmList *p) {
* function call.
* ----------------------------------------------------------------------------- */
-void Swig_cresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char *decl) {
+String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_char *decl) {
String *fcall;
fcall = NewString("");
-
- if (SwigType_type(t) != T_VOID)
- Wrapper_add_localv(w,name, Swig_clocal(t,name,0), 0);
-
switch(SwigType_type(t)) {
case T_VOID:
break;
- case T_USER:
- SwigType_add_pointer(t);
- Printf(fcall,"%s = (%s) malloc(sizeof(", name, SwigType_lstr(t,0));
- SwigType_del_pointer(t);
- Printf(fcall, "%s));\n", SwigType_str(t,0));
- Printf(fcall, "*(%s) = ", name);
- break;
case T_REFERENCE:
+ Printf(fcall,"{\n");
Printf(fcall,"%s = ", SwigType_str(t,"_result_ref"));
break;
+ case T_USER:
+ Printf(fcall,"%s = ", name);
+ break;
+
default:
/* Normal return value */
Printf(fcall,"%s = (%s)", name, SwigType_lstr(t,0));
@@ -201,7 +195,7 @@ void Swig_cresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char
}
/* Now print out function call */
- Printv(fcall,decl,0);
+ Printv(fcall,decl,NIL);
/* A sick hack */
{
@@ -213,75 +207,9 @@ void Swig_cresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char
if (SwigType_type(t) == T_REFERENCE) {
Printf(fcall,"%s = (%s) &_result_ref;\n", name, SwigType_lstr(t,0));
+ Printf(fcall,"}\n");
}
-
- if (Replace(w,"$function",fcall, DOH_REPLACE_ANY) == 0) {
- Printv(w, fcall, 0);
- }
- Delete(fcall);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_cppresult()
- *
- * This function generates the C++ code needed to set the result. This uses
- * the C++ default copy constructor for user defined objects.
- * ----------------------------------------------------------------------------- */
-
-void Swig_cppresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char *decl) {
- String *fcall;
-
- fcall = NewString("");
- if (SwigType_type(t) != T_VOID)
- Wrapper_add_localv(w,name, Swig_clocal(t,name,0), 0);
-
- switch(SwigType_type(t)) {
- case T_VOID:
- break;
- case T_USER:
- {
- SwigType *temp = Copy(t);
- while (SwigType_isconst(temp)) {
- SwigType_pop(temp);
- }
- Printf(fcall, "%s = new %s(", name, SwigType_str(temp,0));
- Delete(temp);
- }
- break;
- case T_REFERENCE:
- Printf(fcall, "%s = ", SwigType_str(t,"_result_ref"));
- break;
- default:
- Printf(fcall,"%s = (%s)", name, SwigType_lstr(t,0));
- break;
- }
-
- /* Now print out function call */
- Printv(fcall, decl, 0);
-
- switch(SwigType_type(t)) {
- case T_USER:
- Printf(fcall,");\n");
- break;
- case T_REFERENCE:
- Printf(fcall,";\n");
- Printf(fcall, "%s = (%s) &_result_ref;\n", name, SwigType_lstr(t,0));
- break;
- default:
- /* A sick hack */
- {
- char *c = Char(decl) + Len(decl) - 1;
- if (!((*c == ';') || (*c == '}')))
- Printf(fcall, ";");
- }
- Printf(fcall,"\n");
- break;
- }
-
- if (Replace(w,"$function",fcall, DOH_REPLACE_ANY) == 0) {
- Printv(w, fcall, 0);
- }
- Delete(fcall);
+ return fcall;
}
/* -----------------------------------------------------------------------------
@@ -296,25 +224,31 @@ void Swig_cppresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_cha
String *
Swig_cfunction_call(String_or_char *name, ParmList *parms) {
- DOH *func;
+ String *func;
int i = 0;
+ int comma = 0;
Parm *p = parms;
SwigType *pt;
+ String *nname;
func = NewString("");
- Printf(func,"%s(", name);
+ nname = SwigType_namestr(name);
+ Printf(func,"%s(", nname);
while (p) {
String *pname;
- pt = Gettype(p);
- pname = Swig_cparm_name(p,i);
- Printf(func,"%s", Swig_clocal_deref(pt, pname));
- i++;
- p = Getnext(p);
- if (p)
- Printf(func,",");
+ pt = Getattr(p,"type");
+
+ if ((SwigType_type(pt) != T_VOID)) {
+ if (comma) Printf(func,",");
+ pname = Swig_cparm_name(p,i);
+ Printf(func,"%s", SwigType_rcaststr(pt, pname));
+ comma = 1;
+ i++;
+ }
+ p = nextSibling(p);
}
Printf(func,")");
- return Swig_temp_result(func);
+ return func;
}
/* -----------------------------------------------------------------------------
@@ -324,32 +258,58 @@ Swig_cfunction_call(String_or_char *name, ParmList *parms) {
*
* arg0->name(arg1, arg2, arg3, ..., argn)
*
+ * self is an argument that defines how to handle the first argument. Normally,
+ * it should be set to "this->". With C++ proxy classes enabled, it could be
+ * set to "(*this)->" or some similar sequence.
* ----------------------------------------------------------------------------- */
String *
-Swig_cmethod_call(String_or_char *name, ParmList *parms) {
- DOH *func;
+Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self) {
+ String *func, *nname;
int i = 0;
Parm *p = parms;
SwigType *pt;
+ int comma = 0;
+
+ if (!self) self = (char *) "(this)->";
func = NewString("");
- if (!p) return Swig_temp_result(func);
- Printf(func,"%s->%s(", Swig_cparm_name(p,0), name);
+ nname = SwigType_namestr(name);
+ if (!p) return func;
+ Append(func,self);
+ pt = Getattr(p,"type");
+
+ /* If the method is invoked through a dereferenced pointer, we don't add any casts
+ (needed for smart pointers). Otherwise, we cast to the appropriate type */
+
+ if (Strstr(func,"*this")) {
+ Replaceall(func,"this", Swig_cparm_name(p,0));
+ } else {
+ Replaceall(func,"this", SwigType_rcaststr(pt, Swig_cparm_name(p,0)));
+ }
+
+ if (SwigType_istemplate(name)) {
+ Printf(func,"template %s(", nname);
+ } else {
+ Printf(func,"%s(", nname);
+ }
i++;
- p = Getnext(p);
+ p = nextSibling(p);
while (p) {
String *pname;
- pt = Gettype(p);
- pname = Swig_cparm_name(p,i);
- Printf(func,"%s", Swig_clocal_deref(pt, pname));
- i++;
- p = Getnext(p);
- if (p)
- Printf(func,",");
+ pt = Getattr(p,"type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ if (comma) Printf(func,",");
+ pname = Swig_cparm_name(p,i);
+ Printf(func,"%s", SwigType_rcaststr(pt, pname));
+ comma = 1;
+ i++;
+ }
+ p = nextSibling(p);
}
Printf(func,")");
- return Swig_temp_result(func);
+ Delete(nname);
+ return func;
}
/* -----------------------------------------------------------------------------
@@ -366,7 +326,7 @@ Swig_cconstructor_call(String_or_char *name) {
func = NewString("");
Printf(func,"(%s *) calloc(1, sizeof(%s))", name, name);
- return Swig_temp_result(func);
+ return func;
}
@@ -382,24 +342,30 @@ Swig_cconstructor_call(String_or_char *name) {
String *
Swig_cppconstructor_call(String_or_char *name, ParmList *parms) {
- DOH *func;
+ String *func;
+ String *nname;
int i = 0;
+ int comma = 0;
Parm *p = parms;
SwigType *pt;
+ nname = SwigType_namestr(name);
func = NewString("");
- Printf(func,"new %s(", name);
+ Printf(func,"new %s(", nname);
while (p) {
String *pname;
- pt = Gettype(p);
- pname = Swig_cparm_name(p,i);
- Printf(func,"%s", Swig_clocal_deref(pt, pname));
- i++;
- p = Getnext(p);
- if (p)
- Printf(func,",");
+ pt = Getattr(p,"type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ if (comma) Printf(func,",");
+ pname = Swig_cparm_name(p,i);
+ Printf(func,"%s", SwigType_rcaststr(pt, pname));
+ comma = 1;
+ i++;
+ }
+ p = nextSibling(p);
}
Printf(func,")");
- return Swig_temp_result(func);
+ Delete(nname);
+ return func;
}
@@ -413,12 +379,10 @@ Swig_cppconstructor_call(String_or_char *name, ParmList *parms) {
String *
Swig_cdestructor_call() {
- DOH *func;
-
+ String *func;
func = NewString("");
-
Printf(func,"free((char *) %s)", Swig_cparm_name(0,0));
- return Swig_temp_result(func);
+ return func;
}
@@ -432,11 +396,11 @@ Swig_cdestructor_call() {
String *
Swig_cppdestructor_call() {
- DOH *func;
+ String *func;
func = NewString("");
Printf(func,"delete %s", Swig_cparm_name(0,0));
- return Swig_temp_result(func);
+ return func;
}
/* -----------------------------------------------------------------------------
@@ -449,22 +413,17 @@ Swig_cppdestructor_call() {
* ----------------------------------------------------------------------------- */
String *
-Swig_cmemberset_call(String_or_char *name, SwigType *type) {
- DOH *func;
+Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self) {
+ String *func;
func = NewString("");
-
- /*
- if (SwigType_type(type) == T_USER) {
- Printf(func,"%s %s->%s; ", Swig_clocal_assign(type,""), Swig_cparm_name(0,0), name);
- } else {
- Printf(func,"%s ", Swig_clocal_assign(type,""));
+ if (!self) self = NewString("(this)->");
+ else self = NewString(self);
+ Replaceall(self,"this",Swig_cparm_name(0,0));
+ if (SwigType_type(type) != T_ARRAY) {
+ Printf(func,"if (%s) %s%s = %s",Swig_cparm_name(0,0), self,name, Swig_wrapped_var_deref(type, Swig_cparm_name(0,1)));
}
- */
- /* Printf(func,"(%s->%s = ", Swig_cparm_name(0,0), name);
- Printf(func,"%s)", Swig_clocal_deref(type, (pname = Swig_cparm_name(0,1))));
- */
- Printf(func,"%s->%s = %s",Swig_cparm_name(0,0),name, Swig_clocal_deref(type, Swig_cparm_name(0,1)));
- return Swig_temp_result(func);
+ Delete(self);
+ return(func);
}
@@ -478,499 +437,358 @@ Swig_cmemberset_call(String_or_char *name, SwigType *type) {
* ----------------------------------------------------------------------------- */
String *
-Swig_cmemberget_call(String_or_char *name, SwigType *t) {
- DOH *func;
-
+Swig_cmemberget_call(String_or_char *name, SwigType *t, String_or_char *self) {
+ String *func;
+ if (!self) self = NewString("(this)->");
+ else self = NewString(self);
+ Replaceall(self,"this",Swig_cparm_name(0,0));
func = NewString("");
- Printf(func,"%s (%s->%s)", Swig_clocal_assign(t,""),Swig_cparm_name(0,0), name);
- return Swig_temp_result(func);
-}
-
-
-static void fix_parm_names(ParmList *p) {
- int i = 0;
- while (p) {
- if (!Getname(p)) {
- char temp[64];
- sprintf(temp,"arg%d",i);
- Setname(p,temp);
- }
- i++;
- p = Getnext(p);
- }
+ Printf(func,"%s (%s%s)", Swig_wrapped_var_assign(t,""),self, name);
+ Delete(self);
+ return func;
}
/* -----------------------------------------------------------------------------
- * Swig_cfunction_wrapper()
+ * Swig_MethodToFunction(Node *n)
*
- * This function creates a C wrapper around a C++ method. Returns a Wrapper
- * object containing the code, parameters, and so forth.
+ * Converts a C++ method node to a function accessor function.
* ----------------------------------------------------------------------------- */
-Wrapper *
-Swig_cfunction_wrapper(String_or_char *funcname,
- SwigType *rtype,
- ParmList *parms,
- String_or_char *code)
-{
- Wrapper *w;
- ParmList *l;
+int
+Swig_MethodToFunction(Node *n, String *classname, int flags) {
+ String *name, *qualifier;
+ ParmList *parms;
+ SwigType *type;
+ Parm *p;
+ String *self = 0;
- w = NewWrapper();
+ /* If smart pointer, change self derefencing */
+ if (flags & CWRAP_SMART_POINTER) {
+ self = NewString("(*this)->");
+ }
+ /* If node is a member template expansion, we don't allow added code */
- /* Set the name of the function */
- Setname(w,funcname);
+ if (Getattr(n,"templatetype")) flags &= ~(CWRAP_EXTEND);
- l = CopyParmList(parms);
- fix_parm_names(l);
- Printf(w,"%s %s(%s) {\n", SwigType_str(rtype,0), funcname, ParmList_str(l));
- if (code) {
- Printv(w, code, "\n", 0);
+ name = Getattr(n,"name");
+ qualifier = Getattr(n,"qualifier");
+ parms = CopyParmList(nonvoid_parms(Getattr(n,"parms")));
+
+ type = NewString(classname);
+ if (qualifier) {
+ SwigType_push(type,qualifier);
}
-
- Printf(w,"}\n");
- Setattr(w,"type",rtype);
- Setattr(w,"parms",l);
- Delete(l);
- return w;
-}
+ SwigType_add_pointer(type);
+ p = NewParm(type,"self");
+ Setattr(p,"hidden","1");
+ set_nextSibling(p,parms);
+ Delete(type);
-/* -----------------------------------------------------------------------------
- * Swig_cmethod_wrapper()
- *
- * This function creates a C wrapper around a C++ method. Returns a Wrapper
- * object containing the code, parameters, and so forth.
- * ----------------------------------------------------------------------------- */
-
-Wrapper *
-Swig_cmethod_wrapper(String_or_char *classname,
- String_or_char *methodname,
- SwigType *rtype,
- ParmList *parms,
- String_or_char *code)
-{
- Wrapper *w;
- ParmList *l;
- Parm *p;
- SwigType *t;
+ /* Generate action code for the access */
+ if (!(flags & CWRAP_EXTEND)) {
+ Setattr(n,"wrap:action", Swig_cresult(Getattr(n,"type"),"result", Swig_cmethod_call(name,p,self)));
+ } else {
+ String *code;
+ String *mangled;
+ String *membername = Swig_name_member(classname, name);
+ mangled = Swig_name_mangle(membername);
- w = NewWrapper();
+ code = Getattr(n,"code");
+ type = Getattr(n,"type");
- /* Set the name of the function */
- Setname(w,Swig_name_member(classname, methodname));
+ /* Check if the method is overloaded. If so, and it has code attached, we append an extra suffix
+ to avoid a name-clash in the generated wrappers. This allows overloaded methods to be defined
+ in C. */
- l = CopyParmList(parms);
- t = NewString(classname);
- SwigType_add_pointer(t);
- p = NewParm(t,"self");
- Setnext(p,l);
- Delete(t);
-
- l = p;
- fix_parm_names(l);
+ if (Getattr(n,"sym:overloaded") && code) {
+ Append(mangled,Getattr(n,"sym:overname"));
+ }
- Printf(w,"%s %s(%s) {\n", SwigType_str(rtype,0), Swig_name_member(classname, methodname), ParmList_str(l));
+ Setattr(n,"wrap:action", Swig_cresult(Getattr(n,"type"),"result", Swig_cfunction_call(mangled,p)));
- if (!code) {
- /* No code supplied. Write a function manually */
- if (SwigType_type(rtype) != T_VOID) {
- Printf(w,"return ");
- }
-
- Printf(w,"self->%s(", methodname);
- p = Getnext(l);
- while (p) {
- Printf(w,"%s", Getname(p));
- p = Getnext(p);
- if (p)
- Printf(w,",");
+ /* See if there is any code that we need to emit */
+ if (code) {
+ String *body;
+ String *tmp = NewStringf("%s(%s)", mangled, ParmList_str(p));
+ body = SwigType_str(type,tmp);
+ Delete(tmp);
+ Printv(body,code,"\n",NIL);
+ Setattr(n,"wrap:code",body);
}
- Printf(w,");\n");
- Printf(w,"}\n");
- } else {
- Printv(w, code, "\n", 0);
- Printf(w,"}\n");
+ Delete(membername);
+ Delete(mangled);
}
- Setattr(w,"type",rtype);
- Setattr(w,"parms",l);
- Delete(l);
- return w;
+ Setattr(n,"parms",p);
+ Delete(p);
+ Delete(self);
+ return SWIG_OK;
}
-
/* -----------------------------------------------------------------------------
- * Swig_cconstructor_wrapper()
+ * Swig_ConstructorToFunction()
*
* This function creates a C wrapper for a C constructor function.
* ----------------------------------------------------------------------------- */
-Wrapper *
-Swig_cconstructor_wrapper(String_or_char *classname,
- ParmList *parms,
- String_or_char *code)
+int
+Swig_ConstructorToFunction(Node *n, String *classname, int cplus, int flags)
{
- Wrapper *w;
- ParmList *l;
- SwigType *t;
-
- w = NewWrapper();
-
- /* Set the name of the function */
- Setname(w,Swig_name_construct(classname));
-
- l = CopyParmList(parms);
- t = NewString(classname);
- SwigType_add_pointer(t);
-
- /* Patch up the argument names */
- fix_parm_names(l);
-
- Printf(w,"%s %s(%s) {\n", SwigType_str(t,0), Swig_name_construct(classname), ParmList_str(l));
-
- if (!code) {
- /* No code supplied. Write a function manually */
- Printf(w,"return (%s) calloc(1,sizeof(%s));\n", SwigType_str(t,0), classname);
+ ParmList *parms;
+ SwigType *type;
+ String *membername;
+ String *mangled;
+ membername = Swig_name_construct(classname);
+ mangled = Swig_name_mangle(membername);
+
+ parms = CopyParmList(nonvoid_parms(Getattr(n,"parms")));
+ type = NewString(classname);
+ SwigType_add_pointer(type);
+
+ if (flags & CWRAP_EXTEND) {
+ String *code = Getattr(n,"code");
+ if (code) {
+ String *wrap;
+ String *s = NewStringf("%s(%s)", mangled, ParmList_str(parms));
+ wrap = SwigType_str(type,s);
+ Delete(s);
+ Printv(wrap,code,"\n",NIL);
+ Setattr(n,"wrap:code",wrap);
+ Delete(wrap);
+ }
+ Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(mangled,parms)));
} else {
- Printv(w, code, "\n", 0);
+ if (cplus) {
+ Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cppconstructor_call(classname,parms)));
+ } else {
+ Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cconstructor_call(classname)));
+ }
}
- Printf(w,"}\n");
- Setattr(w,"type",t);
- Setattr(w,"parms",l);
- Delete(l);
- Delete(t);
- return w;
+ Setattr(n,"type",type);
+ Setattr(n,"parms", parms);
+ Delete(type);
+ Delete(parms);
+ Delete(mangled);
+ Delete(membername);
+ return SWIG_OK;
}
/* -----------------------------------------------------------------------------
- * Swig_cppconstructor_wrapper()
+ * Swig_DestructorToFunction()
*
- * This function creates a C wrapper for a C++ constructor function.
+ * This function creates a C wrapper for a destructor function.
* ----------------------------------------------------------------------------- */
-Wrapper *
-Swig_cppconstructor_wrapper(String_or_char *classname,
- ParmList *parms,
- String_or_char *code)
+int
+Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags)
{
- Wrapper *w;
- ParmList *l;
- SwigType *t;
+ SwigType *type;
Parm *p;
- w = NewWrapper();
-
- /* Set the name of the function */
- Setname(w,Swig_name_construct(classname));
-
- l = CopyParmList(parms);
- t = NewString(classname);
- SwigType_add_pointer(t);
-
- /* Patch up the argument names */
- fix_parm_names(l);
-
- Printf(w,"%s %s(%s) {\n", SwigType_str(t,0), Swig_name_construct(classname), ParmList_str(l));
-
- if (!code) {
- /* No code supplied. Write a function manually */
- Printf(w,"return new %s", SwigType_str(t,0));
- p = l;
- if (p) {
- Printf(w,"(");
- while (p) {
- Printf(w,"%s", Getname(p));
- p = Getnext(p);
- if (p)
- Printf(w,",");
- }
- Printf(w,")");
+ type = NewString(classname);
+ SwigType_add_pointer(type);
+ p = NewParm(type,"self");
+ Delete(type);
+ type = NewString("void");
+
+ if (flags & CWRAP_EXTEND) {
+ String *membername, *mangled, *code;
+ membername = Swig_name_destroy(classname);
+ mangled = Swig_name_mangle(membername);
+ code = Getattr(n,"code");
+ if (code) {
+ String *s = NewStringf("void %s(%s)", mangled, ParmList_str(p));
+ Printv(s,code,"\n",NIL);
+ Setattr(n,"wrap:code",s);
+ Delete(s);
}
- Printf(w,";\n");
+ Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cfunction_call(mangled,p)));
+ Delete(membername);
+ Delete(mangled);
} else {
- Printv(w, code, "\n", 0);
+ if (cplus) {
+ Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cppdestructor_call()));
+ } else {
+ Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cdestructor_call()));
+ }
}
- Printf(w,"}\n");
- Setattr(w,"type",t);
- Setattr(w,"parms",l);
- Delete(l);
- Delete(t);
- return w;
+ Setattr(n,"type",type);
+ Setattr(n,"parms", p);
+ Delete(type);
+ Delete(p);
+ return SWIG_OK;
}
-
/* -----------------------------------------------------------------------------
- * Swig_cdestructor_wrapper()
+ * Swig_MembersetToFunction()
*
- * This function creates a C wrapper for a C destructor.
+ * This function creates a C wrapper for setting a structure member.
* ----------------------------------------------------------------------------- */
-Wrapper *
-Swig_cdestructor_wrapper(String_or_char *classname,
- String_or_char *code)
-{
- Wrapper *w;
- ParmList *l;
- SwigType *t;
+int
+Swig_MembersetToFunction(Node *n, String *classname, int flags) {
+ String *name;
+ ParmList *parms;
Parm *p;
+ SwigType *t;
+ SwigType *ty;
+ SwigType *type;
+ String *membername;
+ String *mangled;
+ String *self= 0;
- w = NewWrapper();
-
- /* Set the name of the function */
- Setname(w, Swig_name_destroy(classname));
-
- t = NewString(classname);
- SwigType_add_pointer(t);
- p = NewParm(t,"self");
- l = p;
- Delete(t);
-
- t = NewString("void");
-
- Printf(w,"%s %s(%s) {\n", SwigType_str(t,0), Swig_name_destroy(classname), ParmList_str(l));
-
- if (!code) {
- /* No code supplied. Write a function manually */
- Printf(w,"free((char *) self);\n");
- } else {
- Printv(w, code, "\n", 0);
+ if (flags & CWRAP_SMART_POINTER) {
+ self = NewString("(*this)->");
}
- Printf(w,"}\n");
- Setattr(w,"type",t);
- Setattr(w,"parms",l);
- Delete(l);
- Delete(t);
- return w;
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_cppdestructor_wrapper()
- *
- * This function creates a C wrapper for a C++ destructor.
- * ----------------------------------------------------------------------------- */
-
-Wrapper *
-Swig_cppdestructor_wrapper(String_or_char *classname,
- String_or_char *code)
-{
- Wrapper *w;
- ParmList *l;
- SwigType *t;
- Parm *p;
- w = NewWrapper();
+ name = Getattr(n,"name");
+ type = Getattr(n,"type");
- /* Set the name of the function */
- Setname(w, Swig_name_destroy(classname));
+ membername = Swig_name_member(classname, Swig_name_set(name));
+ mangled = Swig_name_mangle(membername);
t = NewString(classname);
SwigType_add_pointer(t);
- p = NewParm(t,"self");
-
- l = p;
+ parms = NewParm(t,"self");
Delete(t);
- t = NewString("void");
-
- Printf(w,"%s %s(%s) {\n", SwigType_str(t,0), Swig_name_destroy(classname), ParmList_str(l));
+ ty = Swig_wrapped_var_type(type);
+ p = NewParm(ty,name);
+ set_nextSibling(parms,p);
- if (!code) {
- /* No code supplied. Write a function manually */
- Printf(w,"delete self;\n");
+ /* If the type is a pointer or reference. We mark it with a special wrap:disown attribute */
+ if (SwigType_check_decl(type,"p.")) {
+ Setattr(p,"wrap:disown","1");
+ }
+ Delete(p);
+
+ if (flags & CWRAP_EXTEND) {
+ String *code = Getattr(n,"code");
+ if (code) {
+ String *s = NewStringf("void %s(%s)", mangled, ParmList_str(parms));
+ Printv(s,code,"\n",NIL);
+ Setattr(n,"wrap:code",s);
+ Delete(s);
+ }
+ Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cfunction_call(mangled,parms)));
} else {
- Printv(w, code, "\n", 0);
+ Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cmemberset_call(name,type,self)));
}
- Printf(w,"}\n");
- Setattr(w,"type",t);
- Setattr(w,"parms",l);
- Delete(l);
- Delete(t);
- return w;
+ Setattr(n,"type","void");
+ Setattr(n,"parms", parms);
+ Delete(parms);
+ Delete(ty);
+ Delete(membername);
+ Delete(mangled);
+ Delete(self);
+ return SWIG_OK;
}
/* -----------------------------------------------------------------------------
- * Swig_cmemberset_wrapper()
+ * Swig_MembergetToFunction()
*
- * This function creates a C wrapper for setting a C++ structure member.
+ * This function creates a C wrapper for setting a structure member.
* ----------------------------------------------------------------------------- */
-Wrapper *
-Swig_cmemberset_wrapper(String_or_char *classname,
- String_or_char *membername,
- SwigType *type,
- String_or_char *code)
-{
- Wrapper *w;
- ParmList *l;
- Parm *p;
+int
+Swig_MembergetToFunction(Node *n, String *classname, int flags) {
+ String *name;
+ ParmList *parms;
SwigType *t;
- SwigType *lt;
-
- w = NewWrapper();
-
- /* Set the name of the function */
- Setname(w, Swig_name_member(classname, Swig_name_set(membername)));
-
- t = NewString(classname);
- SwigType_add_pointer(t);
- p = NewParm(t,"self");
- l = p;
- Delete(t);
-
- lt = Swig_clocal_type(type);
- p = NewParm(lt,"value");
- Setnext(l,p);
-
- Printf(w,"void %s(%s) {\n", Getname(w), ParmList_str(l));
+ SwigType *ty;
+ SwigType *type;
+ String *membername;
+ String *mangled;
+ String *self = 0;
- if (!code) {
- /* No code supplied. Write a function manually */
- Printf(w,"self->%s = %s;\n", membername, Swig_clocal_deref(lt,"value"));
- Printf(w,"return %s self->%s;\n", Swig_clocal_assign(lt,""), membername);
- } else {
- Printv(w, code, "\n", 0);
+ if (flags & CWRAP_SMART_POINTER) {
+ self = NewString("(*this)->");
}
- Printf(w,"}\n");
- /* Wrapper_Settype(w,lt); */
- Setattr(w,"type","void");
- Setattr(w,"parms", l);
- Delete(l);
- Delete(lt);
- return w;
-}
+ name = Getattr(n,"name");
+ type = Getattr(n,"type");
-/* -----------------------------------------------------------------------------
- * Swig_cmemberget_wrapper()
- *
- * This function creates a C wrapper for getting a structure member
- * ----------------------------------------------------------------------------- */
-
-Wrapper *
-Swig_cmemberget_wrapper(String_or_char *classname,
- String_or_char *membername,
- SwigType *type,
- String_or_char *code)
-{
- Wrapper *w;
- ParmList *l;
- Parm *p;
- SwigType *t;
- SwigType *lt;
-
- w = NewWrapper();
-
- /* Set the name of the function */
- Setname(w,Swig_name_member(classname, Swig_name_get(membername)));
+ membername = Swig_name_member(classname, Swig_name_get(name));
+ mangled = Swig_name_mangle(membername);
t = NewString(classname);
SwigType_add_pointer(t);
- p = NewParm(t,"self");
- l = p;
+ parms = NewParm(t,"self");
Delete(t);
- lt = Swig_clocal_type(type);
- Printf(w,"%s %s(%s) {\n", SwigType_str(lt,0), Getname(w), ParmList_str(l));
-
- if (!code) {
- /* No code supplied. Write a function manually */
- Printf(w,"return %s self->%s;", Swig_clocal_assign(lt,""), membername);
+ ty = Swig_wrapped_var_type(type);
+ if (flags & CWRAP_EXTEND) {
+ String *code = Getattr(n,"code");
+ if (code) {
+ String *tmp = NewStringf("%s(%s)", mangled, ParmList_str(parms));
+ String *s = SwigType_str(ty,tmp);
+ Delete(tmp);
+ Printv(s,code,"\n",NIL);
+ Setattr(n,"wrap:code",s);
+ Delete(s);
+ }
+ Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_cfunction_call(mangled,parms)));
} else {
- Printv(w, code, "\n", 0);
+ Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_cmemberget_call(name,type,self)));
}
- Printf(w,"}\n");
- Setattr(w,"type",lt);
- Setattr(w,"parms",l);
- Delete(l);
- Delete(lt);
- return w;
+ Setattr(n,"type",ty);
+ Setattr(n,"parms", parms);
+ Delete(parms);
+ Delete(ty);
+ Delete(membername);
+ Delete(mangled);
+ return SWIG_OK;
}
/* -----------------------------------------------------------------------------
- * Swig_cvarset_wrapper()
+ * Swig_VarsetToFunction()
*
* This function creates a C wrapper for setting a global variable.
* ----------------------------------------------------------------------------- */
-Wrapper *
-Swig_cvarset_wrapper(String_or_char *varname,
- SwigType *type,
- String_or_char *code)
-{
- Wrapper *w;
- ParmList *l;
- Parm *p;
- SwigType *lt;
+int
+Swig_VarsetToFunction(Node *n) {
+ String *name,*nname;
+ ParmList *parms;
+ SwigType *type, *ty;
- w = NewWrapper();
+ name = Getattr(n,"name");
+ type = Getattr(n,"type");
- /* Set the name of the function */
- Setname(w,Swig_name_set(varname));
+ nname = SwigType_namestr(name);
- lt = Swig_clocal_type(type);
- p = NewParm(lt,"value");
- l = p;
+ ty = Swig_wrapped_var_type(type);
+ parms = NewParm(ty,"value");
+ Delete(ty);
- Printf(w,"%s %s(%s) {\n", SwigType_str(lt,0), Getname(w), ParmList_str(l));
-
- if (!code) {
- /* No code supplied. Write a function manually */
- Printf(w,"%s = %s;\n", varname, Swig_clocal_deref(lt,"value"));
- Printf(w,"return %s;\n", Swig_clocal_assign(lt,varname));
- } else {
- Printv(w, code, "\n", 0);
- Replace(w,"$target",varname, DOH_REPLACE_ANY);
- Replace(w,"$source","value", DOH_REPLACE_ANY);
- Replace(w,"$ltype", SwigType_str(lt,""), DOH_REPLACE_ANY);
- Replace(w,"$rtype", SwigType_str(type,""), DOH_REPLACE_ANY);
- }
- Printf(w,"}\n");
- Setattr(w,"type",lt);
- Setattr(w,"parms",l);
- Delete(l);
- Delete(lt);
- return w;
+ Setattr(n,"wrap:action", NewStringf("%s = %s;\n", nname, Swig_wrapped_var_deref(type,Swig_cparm_name(0,0))));
+ Setattr(n,"type","void");
+ Setattr(n,"parms",parms);
+ Delete(parms);
+ Delete(nname);
+ return SWIG_OK;
}
/* -----------------------------------------------------------------------------
- * Swig_cvarget_wrapper()
+ * Swig_VargetToFunction()
*
- * This function creates a C wrapper for getting a structure member
+ * This function creates a C wrapper for getting a global variable.
* ----------------------------------------------------------------------------- */
-Wrapper *
-Swig_cvarget_wrapper(String_or_char *varname,
- SwigType *type,
- String_or_char *code)
-{
- Wrapper *w;
- ParmList *l = 0;
- SwigType *lt;
-
- w = NewWrapper();
-
- /* Set the name of the function */
- Setname(w,Swig_name_get(varname));
+int
+Swig_VargetToFunction(Node *n) {
+ String *name, *nname;
+ SwigType *type, *ty;
- lt = Swig_clocal_type(type);
+ name = Getattr(n,"name");
+ type = Getattr(n,"type");
- Printf(w,"%s %s(%s) {\n", SwigType_str(lt,0), Getname(w), ParmList_str(l));
+ nname = SwigType_namestr(name);
+ ty = Swig_wrapped_var_type(type);
- if (!code) {
- /* No code supplied. Write a function manually */
- Printf(w,"return %s;", Swig_clocal_assign(type,varname));
- } else {
- Printv(w, code, "\n", 0);
- }
- Printf(w,"}\n");
- Setattr(w,"type",lt);
- Setattr(w,"parms",l);
- Delete(l);
- Delete(lt);
- return w;
+ Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_wrapped_var_assign(type,nname)));
+ Setattr(n,"type",ty);
+ Delattr(n,"parms");
+ Delete(nname);
+ Delete(ty);
+ return SWIG_OK;
}
-
-
-
-
-
diff --git a/Source/Swig/error.c b/Source/Swig/error.c
new file mode 100644
index 000000000..a728510eb
--- /dev/null
+++ b/Source/Swig/error.c
@@ -0,0 +1,198 @@
+/* -----------------------------------------------------------------------------
+ * error.c
+ *
+ * Error handling functions. These are used to issue warnings and
+ * error messages.
+ *
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+#include "swig.h"
+#include <stdarg.h>
+#include <ctype.h>
+
+char cvsroot_error_c[] = "$Header$";
+
+/* -----------------------------------------------------------------------------
+ * Commentary on the warning filter.
+ *
+ * The warning filter is a string of numbers prefaced by (-) or (+) to
+ * indicate whether or not a warning message is displayed. For example:
+ *
+ * "-304-201-140+210+201"
+ *
+ * The filter string is scanned left to right and the first occurrence
+ * of a warning number is used to determine printing behavior.
+ *
+ * The same number may appear more than once in the string. For example, in the
+ * above string, "201" appears twice. This simply means that warning 201
+ * was disabled after it was previously enabled. This may only be temporary
+ * setting--the first number may be removed later in which case the warning
+ * is reenabled.
+ * ----------------------------------------------------------------------------- */
+
+static int silence = 0; /* Silent operation */
+static String *filter = 0; /* Warning filter */
+static int warnall = 0;
+static int nwarning = 0;
+
+/* -----------------------------------------------------------------------------
+ * Swig_warning()
+ *
+ * Issue a warning message
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_warning(int wnum, const String_or_char *filename, int line, const char *fmt, ...) {
+ String *out;
+ char *msg;
+ int wrn = 1;
+ va_list ap;
+ if (silence) return;
+
+ va_start(ap,fmt);
+
+ out = NewString("");
+ vPrintf(out,fmt,ap);
+ {
+ char temp[64], *t;
+ t = temp;
+ msg = Char(out);
+ while (isdigit(*msg)) {
+ *(t++) = *(msg++);
+ }
+ if (t != temp) {
+ msg++;
+ wnum = atoi(temp);
+ }
+ }
+
+ /* Check in the warning filter */
+ if (filter) {
+ char temp[32];
+ char *c;
+ sprintf(temp,"%d",wnum);
+ c = Strstr(filter,temp);
+ if (c) {
+ if (*(c-1) == '-') wrn = 0; /* Warning disabled */
+ if (*(c-1) == '+') wrn = 1; /* Warning enabled */
+ }
+ }
+ if (warnall || wrn) {
+ if (wnum) {
+ Printf(stderr,"%s:%d: Warning(%d): ", filename, line, wnum);
+ } else {
+ Printf(stderr,"%s:%d: Warning: ", filename, line, wnum);
+ }
+ Printf(stderr,"%s",msg);
+ nwarning++;
+ }
+ Delete(out);
+ va_end(ap);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_error()
+ *
+ * Issue an error message
+ * ----------------------------------------------------------------------------- */
+
+static int nerrors = 0;
+
+void
+Swig_error(const String_or_char *filename, int line, const char *fmt, ...) {
+ va_list ap;
+
+ if (silence) return;
+
+ va_start(ap,fmt);
+ if (line > 0) {
+ Printf(stderr,"%s:%d: ", filename, line);
+ } else {
+ Printf(stderr,"%s:EOF: ", filename);
+ }
+ vPrintf(stderr,fmt,ap);
+ va_end(ap);
+ nerrors++;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_error_count()
+ *
+ * Returns number of errors received.
+ * ----------------------------------------------------------------------------- */
+
+int
+Swig_error_count(void) {
+ return nerrors;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_error_silent()
+ *
+ * Set silent flag
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_error_silent(int s) {
+ silence = s;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_warnfilter()
+ *
+ * Takes a comma separate list of warning numbers and puts in the filter.
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_warnfilter(const String_or_char *wlist, int add) {
+ char *c;
+ String *s;
+
+ if (!filter) filter = NewString("");
+ s = NewString(wlist);
+ c = Char(s);
+ c = strtok(c,", ");
+ while (c) {
+ if (isdigit(*c) || (*c == '+') || (*c == '-')) {
+ if (add) {
+ Insert(filter,0,c);
+ if (isdigit(*c)) {
+ Insert(filter,0,"-");
+ }
+ } else {
+ char temp[32];
+ if (isdigit(*c)) {
+ sprintf(temp,"-%s",c);
+ } else {
+ strcpy(temp,c);
+ }
+ Replace(filter,temp,"", DOH_REPLACE_FIRST);
+ }
+ }
+ c = strtok(NULL,", ");
+ }
+ Delete(s);
+}
+
+void
+Swig_warnall(void) {
+ warnall = 1;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_warn_count()
+ *
+ * Return the number of warnings
+ * ----------------------------------------------------------------------------- */
+
+int
+Swig_warn_count(void) {
+ return nwarning;
+}
+
diff --git a/Source/Swig/fragment.c b/Source/Swig/fragment.c
new file mode 100644
index 000000000..b039759a3
--- /dev/null
+++ b/Source/Swig/fragment.c
@@ -0,0 +1,64 @@
+/* -----------------------------------------------------------------------------
+ * fragment.c
+ *
+ * This file manages named code fragments. Code fragments are typically
+ * used to hold helper-code that may or may not be included in the wrapper
+ * file (depending on what features are actually used in the interface).
+ *
+ * By using fragments, it's possible to greatly reduce the amount of
+ * wrapper code and to generate cleaner wrapper files.
+ *
+ * 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_fragment_c[] = "$Header$";
+
+#include "swig.h"
+
+static Hash *fragments = 0;
+
+/* -----------------------------------------------------------------------------
+ * Swig_fragment_register()
+ *
+ * Add a fragment.
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_fragment_register(String *name, String *section, String *code) {
+ String *ccode;
+ if (!fragments) {
+ fragments = NewHash();
+ }
+ ccode = Copy(code);
+ Setmeta(ccode,"section",Copy(section));
+ Setattr(fragments,Copy(name),ccode);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_fragment_emit()
+ *
+ * Emit a fragment
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_fragment_emit(String *name) {
+ String *code;
+ if (!fragments) return;
+
+ code = Getattr(fragments,name);
+ if (code) {
+ String *section = Getmeta(code,"section");
+ if (section) {
+ File *f = Swig_filebyname(section);
+ if (!f) {
+ Swig_error(Getfile(code),Getline(code),"Bad section '%s' for code fragment '%s'\n", section,name);
+ } else {
+ Printf(f,"%s\n",code);
+ }
+ }
+ Delattr(fragments,name);
+ }
+}
diff --git a/Source/Swig/getopt.c b/Source/Swig/getopt.c
index 7c71bee8b..77f53cf9b 100644
--- a/Source/Swig/getopt.c
+++ b/Source/Swig/getopt.c
@@ -18,7 +18,7 @@
* Should have cleaner error handling in general.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_getopt_c[] = "$Header$";
#include "swig.h"
diff --git a/Source/Swig/include.c b/Source/Swig/include.c
index 9d0bc24cd..288bd662d 100644
--- a/Source/Swig/include.c
+++ b/Source/Swig/include.c
@@ -11,7 +11,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_include_c[] = "$Header$";
#include "swig.h"
@@ -19,7 +19,6 @@ static char cvsroot[] = "$Header$";
static List *directories = 0; /* List of include directories */
static String *lastpath = 0; /* Last file that was included */
-static int bytes_read = 0; /* Bytes read */
static String *swiglib = 0; /* Location of SWIG library */
static String *lang_config = 0; /* Language configuration file */
@@ -178,7 +177,6 @@ Swig_read_file(FILE *f) {
* Opens a file and returns it as a string.
* ----------------------------------------------------------------------------- */
-static int readbytes = 0;
String *
Swig_include(const String_or_char *name) {
FILE *f;
@@ -187,20 +185,13 @@ Swig_include(const String_or_char *name) {
f = Swig_open(name);
if (!f) return 0;
str = Swig_read_file(f);
- bytes_read = bytes_read + Len(str);
fclose(f);
Seek(str,0,SEEK_SET);
Setfile(str,lastpath);
Setline(str,1);
- readbytes += Len(str);
return str;
}
-int
-Swig_bytes_read() {
- return readbytes;
-}
-
/* -----------------------------------------------------------------------------
* Swig_insert_file()
*
@@ -249,4 +240,82 @@ Swig_filebyname(const String_or_char *filename) {
return Getattr(named_files,filename);
}
+/* -----------------------------------------------------------------------------
+ * Swig_file_suffix()
+ *
+ * Returns the suffix of a file
+ * ----------------------------------------------------------------------------- */
+
+char *
+Swig_file_suffix(const String_or_char *filename) {
+ char *d;
+ char *c = Char(filename);
+ if (strlen(c)) {
+ d = c + Len(filename) - 1;
+ while (d != c) {
+ if (*d == '.') return d;
+ d--;
+ }
+ return c+Len(filename);
+ }
+ return c;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_file_basename()
+ *
+ * Returns the filename with no suffix attached.
+ * ----------------------------------------------------------------------------- */
+char *
+Swig_file_basename(const String_or_char *filename)
+{
+ static char tmp[1024];
+ char *c;
+ strcpy(tmp,Char(filename));
+ c = Swig_file_suffix(tmp);
+ *c = 0;
+ return tmp;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_file_filename()
+ *
+ * Return the file with any leading path stripped off
+ * ----------------------------------------------------------------------------- */
+char *
+Swig_file_filename(const String_or_char *filename)
+{
+ static char tmp[1024];
+ const char *delim = SWIG_FILE_DELIMETER;
+ char *c;
+
+ strcpy(tmp,Char(filename));
+ if ((c=strrchr(tmp,*delim))) return c+1;
+ else return tmp;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_file_dirname()
+ *
+ * Return the name of the directory associated with a file
+ * ----------------------------------------------------------------------------- */
+char *
+Swig_file_dirname(const String_or_char *filename)
+{
+ static char tmp[1024];
+ const char *delim = SWIG_FILE_DELIMETER;
+ char *c;
+ strcpy(tmp,Char(filename));
+ if (!strstr(tmp,delim)) {
+ return "";
+ }
+ c = tmp + strlen(tmp) -1;
+ while (*c != *delim) c--;
+ *(++c) = 0;
+ return tmp;
+}
+
+
+
+
diff --git a/Source/Swig/main.c b/Source/Swig/main.c
deleted file mode 100644
index 623d1a442..000000000
--- a/Source/Swig/main.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -----------------------------------------------------------------------------
- * main.c
- *
- * SWIG main program.
- *
- * 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.
- * ----------------------------------------------------------------------------- */
-
-#include "swigconfig.h"
-#include "swigver.h"
-#include "swig.h"
-
-static char *usage = (char*)"\
-\nGeneral Options\n\
- -version - Print SWIG version number\n\
- -help - This output.\n\n";
-
-/* -----------------------------------------------------------------------------
- * Swig_main()
- *
- * Entry point to SWIG. This should only be called after all of the available
- * modules have been registered (presumably by the real main function).
- * ----------------------------------------------------------------------------- */
-
-int Swig_main(int argc, char **argv, char **modules) {
- int i;
- int help = 0;
- int freeze = 0;
- Hash *top = 0;
-
- /* Initialize the SWIG core */
- Swig_init();
- Swig_init_args(argc,argv);
-
- /* Look for command line options */
- for (i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i],"-freeze") == 0) {
- freeze= 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i],"-version") == 0) {
- fprintf(stderr,"\nSWIG Version %s %s\n",
- SWIG_VERSION, SWIG_SPIN);
- fprintf(stderr,"Copyright (c) 1995-1998, University of Utah and the Regents of the University of California\n");
- fprintf(stderr,"Copyright (c) 1998-2000, University of Chicago\n");
- Swig_exit (EXIT_SUCCESS);
- } else if (strcmp(argv[i],"-help") == 0) {
- Printf(stderr,"%s",usage);
- Swig_mark_arg(i);
- help = 1;
- } else {
- if (!Swig_check_marked(i)) {
- Module *m;
- m = Swig_load_module(argv[i]+1);
- if (m) {
- Swig_mark_arg(i);
- Swig_init_module(m, argc, argv);
- }
- }
- }
- }
- }
-
- /* Load the default modules (always enabled) */
- if (modules) {
- int i = 0;
- while (modules[i]) {
- Module *m;
- m = Swig_load_module(modules[i]);
- if (m) {
- Swig_init_module(m,argc,argv);
- } else {
- Printf(stderr,"Swig: default module '%s' not found!\n", modules[i]);
- }
- i++;
- }
- }
-
- if (help) Swig_exit(EXIT_SUCCESS);
- /* Check the arguments */
- Swig_check_options();
-
- /* Get the input file name and create a starting node */
- top = NewHash();
- Settag(top,"swig:initial");
- Setname(top,argv[argc-1]);
-
- /* Run the modules */
- Swig_run_modules(top);
-
- while(freeze);
- return 0;
-}
-
-void Swig_exit(int n) {
- exit(n);
-}
-
-
-
diff --git a/Source/Swig/map.c b/Source/Swig/map.c
deleted file mode 100644
index f1384ba8a..000000000
--- a/Source/Swig/map.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/* -----------------------------------------------------------------------------
- * map.c
- *
- * This file provides support for defining %map rules that match lists of
- * parameters to objects defining code generation rules.
- *
- * 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.
- * ----------------------------------------------------------------------------- */
-
-static char cvsroot[] = "$Header$";
-
-#include "swig.h"
-
-/* -----------------------------------------------------------------------------
- * Synopsis
- *
- * One of the problems in creating wrappers is that of defining rules for
- * managing various datatypes and function parameters. In SWIG1.1,
- * this sort of customization was managed using a mechanism known as
- * "typemaps". This module generalizes the idea even further and provides
- * generic set of functions that can be used to define and match rules
- * that are associated with lists of datatypes.
- *
- * The functions in this file are intended to be rather generic. They are only
- * responsible for the storage and matching of rules. Other parts of the
- * code can use these to implement typemaps, argmaps, or anything else.
- * ----------------------------------------------------------------------------- */
-
-/* -----------------------------------------------------------------------------
- * Swig_map_add_parmrule()
- *
- * Adds a new mapping rule for a list of parameters. The parms input to this
- * function should be a properly constructed parameter list with associated
- * attributes (type and name). The 'obj' attribute can be any DOH object.
- *
- * The structure of how data might be stored is as follows:
- *
- * ruleset (hash)
- * --------------
- * parm1 ---------> rule (hash)
- * -------------
- * parm2 -----------> rule (hash)
- * *obj* --> obj ------------
- * parm3
- * *obj* -->obj
- *
- * For multiple arguments, we end up building a large tree of hash tables.
- * The object will be stored in the *obj* attribute of the last hash table.
- * ----------------------------------------------------------------------------- */
-
-void
-Swig_map_add_parmrule(Hash *ruleset, Hash *parms, DOH *obj)
-{
- Hash *p, *n;
-
- /* Walk down the parms list and create a series of hash tables */
- p = parms;
- n = ruleset;
-
- while (p) {
- String *ty, *name, *key;
- Hash *nn;
- ty = Getattr(p,"type");
- name = Getattr(p,"name");
-
- /* Create a hash table key */
-
- key = NewStringf("*map:%s-%s",name,ty);
-
- /* See if there is already a entry with this type in the table */
- nn = Getattr(n,key);
- if (!nn) {
- /* No. Go ahead and create it */
- nn = NewHash();
- Setattr(n,key,nn);
- }
- Delete(key);
- n = nn;
- p = Swig_next(p);
- }
-
- /* No more parameters. At this point, n points to the very last hash table in our search.
- We'll stick our object there */
-
- Setattr(n,"*obj*",obj);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_map_add_typerule()
- *
- * Adds a rule for a single type and name.
- * ----------------------------------------------------------------------------- */
-
-void
-Swig_map_add_typerule(Hash *ruleset, DOH *type, String_or_char *name, DOH *obj) {
- Hash *p;
-
- p = NewHash();
- Setattr(p,"type",type);
- if (name)
- Setattr(p,"name", name);
-
- Swig_map_add_parmrule(ruleset,p,obj);
- Delete(p);
-}
-
-typedef struct MatchObject {
- Hash *ruleset; /* Hash table of rules */
- Hash *p; /* Parameter on which checking starts */
- int depth; /* Depth of the match */
- struct MatchObject *next; /* Next match object */
-} MatchObject;
-
-
-static MatchObject *matchstack = 0;
-
-/* -----------------------------------------------------------------------------
- * Swig_map_match_parms()
- *
- * Perform a longest map match for a list of parameters and a set of mapping rules.
- * Returns the corresponding rule object and the number of parameters that were
- * matched.
- *
- * Note: If the ruleset has a 'parent' attribute, this function will walk its
- * way up and try to find a match. This can be used to implement scoped
- * mappings.
- * ----------------------------------------------------------------------------- */
-
-DOH *
-Swig_map_match_parms(Hash *ruleset, Hash *parms, int *nmatch)
-{
- MatchObject *mo;
-
- DOH *bestobj = 0;
- int bestdepth = -1;
-
- *nmatch = 0;
-
- mo = (MatchObject *) malloc(sizeof(MatchObject));
- mo->ruleset = ruleset;
- mo->depth = 0;
- mo->p = parms;
- mo->next = 0;
-
- matchstack = mo;
-
- /* Loop over all candidates until we find the best one */
-
- while (matchstack) {
- Hash *rs;
- Hash *p;
- int depth = 0;
- DOH *obj;
- String *key;
- String *ty;
- String *name;
- String *nm;
- int matched = 0;
-
- mo = matchstack;
- /* See if there is a match at this level */
- rs = mo->ruleset;
- obj = Getattr(rs,"*obj*");
- if (obj) {
- if (mo->depth > bestdepth) {
- bestdepth = mo->depth;
- bestobj = obj;
- }
- }
- p = mo->p;
-
- /* No more parameters. Oh well */
- if (!p) {
- matchstack = mo->next;
- free(mo);
- continue;
- }
-
- /* Generate some keys for checking the next parameter */
-
- depth = mo->depth;
- name = Getattr(p,"name");
- ty = Getattr(p,"type");
-
-
- if (!SwigType_isarray(ty)) {
- key = NewStringf("*map:-%s",ty);
- /* See if there is a generic name match for this type */
- nm = Getattr(rs,key);
- if (nm) {
- /* Yes! Add to our stack. Just reuse mo for this */
- mo->ruleset = nm;
- mo->p = Swig_next(p);
- mo->depth++;
- mo = 0;
- matched++;
- }
-
- /* See if there is a specific name match for this type */
- Clear(key);
- Printf(key,"*map:%s-%s",name,ty);
- nm = Getattr(rs,key);
- if (nm) {
- if (!mo) {
- mo = (MatchObject *) malloc(sizeof(MatchObject));
- mo->next = matchstack;
- matchstack = mo;
- }
- mo->ruleset = nm;
- mo->p = Swig_next(p);
- mo->depth = depth+1;
- matched++;
- }
- Delete(key);
- } else {
- /* The next parameter is an array. This is pretty nasty because we have to do a bunch of checks
- related to array indices */
-
- int ndim;
- int i, j, n;
- int ncheck;
- String *ntype;
-
- key = NewString("");
-
- /* Drop the mo record. This is too complicated */
- matchstack = mo->next;
- free(mo);
- mo = 0;
-
- /* Get the number of array dimensions */
- ndim = SwigType_array_ndim(ty);
-
- /* First, we test all of the generic-unnamed parameters */
- ncheck = 1 << ndim;
-
- j = ncheck-1;
- for (i = 0; i < ncheck; i++, j--) {
- int k = j;
- ntype = Copy(ty);
- for (n = 0; n < ndim; n++, k = k >> 1) {
- if (k & 1) {
- SwigType_array_setdim(ntype,n,"");
- }
- }
- Clear(key);
- Printf(key,"*map:-%s",ntype);
- Printf(stdout,"matcharray : %s\n", key);
- nm = Getattr(rs,key);
- if (nm) {
- mo = (MatchObject *) malloc(sizeof(MatchObject));
- mo->ruleset = nm;
- mo->p = Swig_next(p);
- mo->depth = depth+1;
- mo->next = matchstack;
- matchstack = mo;
- matched++;
- mo = 0;
- }
- Delete(ntype);
- }
-
- /* Next check all of the named parameters */
- ncheck = 1 << ndim;
-
- j = ncheck-1;
- for (i = 0; i < ncheck; i++, j--) {
- int k = j;
- ntype = Copy(ty);
- for (n = 0; n < ndim; n++, k = k >> 1) {
- if (k & 1) {
- SwigType_array_setdim(ntype,n,"");
- }
- }
- Clear(key);
- Printf(key,"*map:%s-%s",name,ntype);
- Printf(stdout,"matcharray : %s\n", key);
- nm = Getattr(rs,key);
- if (nm) {
- mo = (MatchObject *) malloc(sizeof(MatchObject));
- mo->ruleset = nm;
- mo->p = Swig_next(p);
- mo->depth = depth+1;
- mo->next = matchstack;
- matchstack = mo;
- matched++;
- mo = 0;
- }
- Delete(ntype);
- }
- Delete(key);
- }
- if ((!matched) && mo) {
- matchstack = mo->next;
- free(mo);
- }
- }
- if (bestobj) {
- *nmatch = bestdepth;
- } else {
- /* If there is no match at all. I guess we can check for a default type */
- DOH *rs;
- String *key;
- String *dty = SwigType_default(Getattr(parms,"type"));
- key = NewStringf("*map:-%s",dty);
-
- rs = Getattr(ruleset,key);
- if (rs) {
- bestobj = Getattr(rs,"*obj*");
- if (bestobj) *nmatch = 1;
- }
- Delete(key);
- Delete(dty);
- }
- if (!bestobj) {
- DOH *prules = Getattr(ruleset,"parent");
- if (prules) {
- bestobj = Swig_map_match_parms(prules,parms,nmatch);
- }
- }
- return bestobj;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_map_match_type()
- *
- * Match a rule for a single type
- * ----------------------------------------------------------------------------- */
-
-DOH *
-Swig_map_match_type(Hash *ruleset, DOH *type, String_or_char *name) {
- Hash *p;
- DOH *obj;
- int nmatch;
-
- p = NewHash();
- Setattr(p,"type",type);
- if (name)
- Setattr(p,"name",name);
-
- obj = Swig_map_match_parms(ruleset,p,&nmatch);
- Delete(p);
- return obj;
-}
-
-
-
-
-
diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c
index 7899e4e37..e1217d513 100644
--- a/Source/Swig/misc.c
+++ b/Source/Swig/misc.c
@@ -9,7 +9,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_misc_c[] = "$Header$";
#include "swig.h"
#include "swigver.h"
@@ -42,73 +42,17 @@ Swig_banner(File *f) {
Printf(f,
"/* ----------------------------------------------------------------------------\n\
* This file was automatically generated by SWIG (http://www.swig.org).\n\
- * Version %s %s\n\
+ * Version %s\n\
* \n\
* This file is not intended to be easily readable and contains a number of \n\
* coding conventions designed to improve portability and efficiency. Do not make\n\
* changes to this file unless you know what you are doing--modify the SWIG \n\
* interface file instead. \n\
- * ----------------------------------------------------------------------------- */\n\n", SWIG_VERSION, SWIG_SPIN);
+ * ----------------------------------------------------------------------------- */\n\n", SWIG_VERSION);
}
/* -----------------------------------------------------------------------------
- * Swig_section()
- *
- * Print a comment denoting a section of wrapper code
- * ----------------------------------------------------------------------------- */
-
-void Swig_section(File *f, const String_or_char *name) {
- Printf(f,"/* -----------------------------------------------------------------------------\n");
- Printf(f," * %s\n", name);
- Printf(f," * ----------------------------------------------------------------------------- */\n");
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_temp_result()
- *
- * This function is used to return a "temporary" result--a result that is only
- * guaranteed to exist for a short period of time. Typically this is used by
- * functions that return strings and other intermediate results that are
- * used in print statements.
- *
- * Note: this is really a bit of a kludge to make it easier to work with
- * temporary variables (so that the caller doesn't have to worry about
- * memory management). In theory, it is possible to break this if an
- * operation produces so many temporaries that it overflows the internal
- * array before they are used. However, in practice, this would only
- * occur for very deep levels of recursion or functions taking lots of
- * parameters---neither of which occur very often in SWIG (if at all).
- * Also, a user can prevent destruction of a temporary object by increasing
- * it's reference count using DohIncref().
- *
- * It is an error to place two identical results onto this list. It is also
- * an error for a caller to free anything returned by this function.
- *
- * Note: SWIG1.1 did something similar to this in a less-organized manner.
- * ----------------------------------------------------------------------------- */
-
-#define MAX_RESULT 512
-
-static DOH *results[MAX_RESULT];
-static int results_index = 0;
-static int results_init = 0;
-
-DOH *Swig_temp_result(DOH *x) {
- int i;
- if (!results_init) {
- for (i = 0; i < MAX_RESULT; i++) results[i] = 0;
- results_init = 1;
- }
- /* Printf(stdout,"results_index = %d, %x, '%s'\n", results_index, x, x); */
- if (results[results_index]) Delete(results[results_index]);
- results[results_index] = x;
- results_index = (results_index + 1) % MAX_RESULT;
- return x;
-}
-
-
-/* -----------------------------------------------------------------------------
* Swig_string_escape()
*
* Takes a string object and produces a string with escape codes added to it.
@@ -142,7 +86,108 @@ String *Swig_string_escape(String *s) {
}
return ns;
}
-
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_upper()
+ *
+ * Takes a string object and convets it to all caps.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_upper(String *s) {
+ String *ns;
+ int c;
+ ns = NewString("");
+
+ while ((c = Getc(s)) != EOF) {
+ Putc(toupper(c),ns);
+ }
+ return ns;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_lower()
+ *
+ * Takes a string object and convets it to all lower.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_lower(String *s) {
+ String *ns;
+ int c;
+ ns = NewString("");
+
+ while ((c = Getc(s)) != EOF) {
+ Putc(tolower(c),ns);
+ }
+ return ns;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_title()
+ *
+ * Takes a string object and convets it to all lower.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_title(String *s) {
+ String *ns;
+ int first = 1;
+ int c;
+ ns = NewString("");
+
+ while ((c = Getc(s)) != EOF) {
+ Putc(first ? toupper(c) : tolower(c),ns);
+ first = 0;
+ }
+ return ns;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_typecode()
+ *
+ * Takes a string with possible type-escapes in it and replaces them with
+ * real C datatypes.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_typecode(String *s) {
+ String *ns;
+ int c;
+ String *tc;
+ ns = NewString("");
+ while ((c = Getc(s)) != EOF) {
+ if (c == '`') {
+ tc = NewString("");
+ while ((c = Getc(s)) != EOF) {
+ if (c == '`') break;
+ Putc(c,tc);
+ }
+ Printf(ns,"%s",SwigType_str(tc,0));
+ } else {
+ Putc(c,ns);
+ if (c == '\'') {
+ while ((c = Getc(s)) != EOF) {
+ Putc(c,ns);
+ if (c == '\'') break;
+ if (c == '\\') {
+ c = Getc(s);
+ Putc(c,ns);
+ }
+ }
+ } else if (c == '\"') {
+ while ((c = Getc(s)) != EOF) {
+ Putc(c,ns);
+ if (c == '\"') break;
+ if (c == '\\') {
+ c = Getc(s);
+ Putc(c,ns);
+ }
+ }
+ }
+ }
+ }
+ return ns;
+}
+
/* -----------------------------------------------------------------------------
* Swig_string_mangle()
*
@@ -160,28 +205,188 @@ String *Swig_string_mangle(String *s) {
}
/* -----------------------------------------------------------------------------
- * Swig_proto_cmp()
+ * Swig_scopename_prefix()
*
- * Compares a function prototype against an expected type-string.
- * For example, Swig_proto_cmp("f(p.void,p.Tcl_Interp,int,p.p.char).int", node)
+ * Take a qualified name like "A::B::C" and return the scope name.
+ * In this case, "A::B". Returns NULL if there is no base.
* ----------------------------------------------------------------------------- */
-int
-Swig_proto_cmp(const String_or_char *pat, DOH *node) {
- SwigType *ty;
- SwigType *ct;
- ParmList *p;
- int r;
-
- ty = Gettype(node);
- p = Getparms(node);
- if (!ty || !p) return -1;
- ct = Copy(ty);
- SwigType_add_function(ct,p);
- SwigType_strip_qualifiers(ct);
- r = Cmp(pat,ct);
- Delete(ct);
- return r;
+String *
+Swig_scopename_prefix(String *s) {
+ char tmp[1024];
+ char *c, *cc;
+ if (!Strstr(s,"::")) return 0;
+ strcpy(tmp,Char(s));
+ c = tmp;
+ cc = c;
+ while (*c) {
+ if (strncmp(c,"::",2) == 0) {
+ cc = c;
+ c += 2;
+ } else {
+ if (*c == '<') {
+ int level = 1;
+ c++;
+ while (*c && level) {
+ if (*c == '<') level++;
+ if (*c == '>') level--;
+ c++;
+ }
+ } else {
+ c++;
+ }
+ }
+ }
+
+ *cc = 0;
+ if (cc != tmp) {
+ return NewString(tmp);
+ } else {
+ return 0;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_scopename_last()
+ *
+ * Take a qualified name like "A::B::C" and returns the last. In this
+ * case, "C".
+ * ----------------------------------------------------------------------------- */
+
+String *
+Swig_scopename_last(String *s) {
+ char tmp[1024];
+ char *c, *cc;
+ if (!Strstr(s,"::")) return NewString(s);
+ strcpy(tmp,Char(s));
+ c = tmp;
+ cc = c;
+
+ while (*c) {
+ if (strncmp(c,"::",2) == 0) {
+ cc = c;
+ c += 2;
+ } else {
+ if (*c == '<') {
+ int level = 1;
+ c++;
+ while (*c && level) {
+ if (*c == '<') level++;
+ if (*c == '>') level--;
+ c++;
+ }
+ } else {
+ c++;
+ }
+ }
+ }
+ return NewString(cc+2);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_scopename_first()
+ *
+ * Take a qualified name like "A::B::C" and returns the first scope name.
+ * In this case, "A". Returns NULL if there is no base.
+ * ----------------------------------------------------------------------------- */
+
+String *
+Swig_scopename_first(String *s) {
+ char tmp[1024];
+ char *c;
+ if (!Strstr(s,"::")) return 0;
+ strcpy(tmp,Char(s));
+ c = tmp;
+ while (*c) {
+ if (strncmp(c,"::",2) == 0) {
+ break;
+ } else {
+ if (*c == '<') {
+ int level = 1;
+ c++;
+ while (*c && level) {
+ if (*c == '<') level++;
+ if (*c == '>') level--;
+ c++;
+ }
+ } else {
+ c++;
+ }
+ }
+ }
+ if (*c && (c != tmp)) {
+ *c = 0;
+ return NewString(tmp);
+ } else {
+ return 0;
+ }
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_scopename_suffix()
+ *
+ * Take a qualified name like "A::B::C" and returns the suffix.
+ * In this case, "B::C". Returns NULL if there is no suffix.
+ * ----------------------------------------------------------------------------- */
+
+String *
+Swig_scopename_suffix(String *s) {
+ char tmp[1024];
+ char *c;
+ if (!Strstr(s,"::")) return 0;
+ strcpy(tmp,Char(s));
+ c = tmp;
+ while (*c) {
+ if (strncmp(c,"::",2) == 0) {
+ break;
+ } else {
+ if (*c == '<') {
+ int level = 1;
+ c++;
+ while (*c && level) {
+ if (*c == '<') level++;
+ if (*c == '>') level--;
+ c++;
+ }
+ } else {
+ c++;
+ }
+ }
+ }
+ if (*c && (c != tmp)) {
+ return NewString(c+2);
+ } else {
+ return 0;
+ }
+}
+/* -----------------------------------------------------------------------------
+ * Swig_scopename_check()
+ *
+ * Checks to see if a name is qualified with a scope name
+ * ----------------------------------------------------------------------------- */
+
+int Swig_scopename_check(String *s) {
+ char *c = Char(s);
+ if (!Strstr(s,"::")) return 0;
+ while (*c) {
+ if (strncmp(c,"::",2) == 0) {
+ return 1;
+ } else {
+ if (*c == '<') {
+ int level = 1;
+ c++;
+ while (*c && level) {
+ if (*c == '<') level++;
+ if (*c == '>') level--;
+ c++;
+ }
+ } else {
+ c++;
+ }
+ }
+ }
+ return 0;
}
@@ -193,7 +398,20 @@ Swig_proto_cmp(const String_or_char *pat, DOH *node) {
void
Swig_init() {
+ /* Set some useful string encoding methods */
DohEncoding("escape", Swig_string_escape);
+ DohEncoding("upper", Swig_string_upper);
+ DohEncoding("lower", Swig_string_lower);
+ DohEncoding("title", Swig_string_title);
+ DohEncoding("typecode",Swig_string_typecode);
+
+ /* Initialize typemaps */
Swig_typemap_init();
+ /* Initialize symbol table */
+ Swig_symbol_init();
+
+ /* Initialize type system */
+ SwigType_typesystem_init();
+
}
diff --git a/Source/Swig/module.c b/Source/Swig/module.c
deleted file mode 100644
index 3c5916858..000000000
--- a/Source/Swig/module.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/* -----------------------------------------------------------------------------
- * module.c
- *
- * This file implements the SWIG module system. Modules are simply
- * pieces of code that manipulate tree objects. Each module is defined
- * by 4 quantities:
- *
- * - Module name (used to select the module on the command line)
- * - init function (called with the SWIG command line options).
- * - start function (called to launch the module)
- * - start tag (starting tag expected by the module)
- *
- * Currently modules must be statically linked with SWIG. However, it
- * is anticipated that the module system may eventually support
- * dynamic loading.
- *
- * 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.
- * ----------------------------------------------------------------------------- */
-
-#include "swig.h"
-
-#ifdef DYNAMIC_MODULES
-#include <dlfcn.h>
-#endif
-
-static char cvsroot[] = "$Header$";
-
-struct Module {
- String *modname;
- int (*initfunc)(int argc, char **argv);
- DOH *(*startfunc)(DOH *);
- String *starttag;
- struct Module *next;
-};
-
-static Module *Modules = 0;
-static Hash *LoadedModules = 0;
-
-/* -----------------------------------------------------------------------------
- * Swig_register_module()
- *
- * Register a new module with the system
- * ----------------------------------------------------------------------------- */
-
-void
-Swig_register_module(const String_or_char *modname, const String_or_char *starttag,
- int (*initfunc)(int argc, char **argv),
- DOH *(*startfunc)(DOH *))
-{
- Module *m;
- m = (Module *) malloc(sizeof(Module));
- m->modname = NewString(modname);
- m->starttag = NewString(starttag);
- m->initfunc = initfunc;
- m->startfunc = startfunc;
- m->next = Modules;
- Modules = m;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_load_module()
- *
- * Load a module. Returns the module object.
- * ----------------------------------------------------------------------------- */
-
-Module *
-Swig_load_module(const String_or_char *modname) {
- Module *m;
- static int dlcheck = 0;
- m = Modules;
-
- while (m) {
- if (Cmp(m->modname, modname) == 0) {
- /* Create a new entry in the loaded modules table */
- List *ml;
- if (!LoadedModules) LoadedModules = NewHash();
- ml = Getattr(LoadedModules,m->starttag);
- if (!ml) {
- ml = NewList();
- Setattr(LoadedModules,m->starttag,ml);
- }
- Append(ml,NewVoid(m,0));
- return m;
- }
- m = m->next;
- }
- /* Module is not a built-in module. See if we can dynamically load it */
-
-#ifdef DYNAMIC_MODULES
- if (dlcheck) return 0;
- {
- DOH *filename;
- void *handle;
- void (*init)(void) = 0;
- char initfunc[256];
- FILE *f;
- filename = NewStringf("./swig%s.so", modname);
- f = Swig_open(filename);
- if (!f) return 0;
- fclose(f);
-
- Clear(filename);
- Append(filename,Swig_last_file());
-
- sprintf(initfunc,"%smodule",Char(modname));
- handle = dlopen(Char(filename), RTLD_NOW | RTLD_GLOBAL);
- if (!handle) {
- Printf(stdout,"%s\n", dlerror());
- return 0;
- }
-
- init = (void (*)(void)) dlsym(handle,initfunc);
- if (!init) {
- Printf(stdout,"Dynamic module %s doesn't define %s()\n", initfunc);
- return 0;
- }
- (*init)(); /* Register function */
- dlcheck = 1;
- m = Swig_load_module(modname);
- dlcheck = 0;
- return m;
- }
-#else
- return 0;
-#endif
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_init_module()
- *
- * Initialize a module
- * ----------------------------------------------------------------------------- */
-
-int Swig_init_module(Module *m, int argc, char **argv) {
- return (*m->initfunc)(argc,argv);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_start_module()
- *
- * Start a module
- * ----------------------------------------------------------------------------- */
-
-DOH *
-Swig_start_module(Module *m, DOH *obj) {
- return (*m->startfunc)(obj);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_run_modules()
- *
- * Given a tree node. This function tries to run it through all of the loaded
- * modules. This works by looking at the "tag" attribute of the node and
- * searching for a loaded module that can handle that tag. If no module can be
- * found, processing stops and an error is generated.
- *
- * If more than one module can work on a given tag, those modules will be
- * executed one after the other. Caveat: if one of those modules outputs
- * a different type of tree, processing immediately stops.
- * ----------------------------------------------------------------------------- */
-
-DOH *Swig_run_modules(DOH *node) {
- String *tag;
- List *ml;
- DOH *newnode;
- String *newtag;
- int i;
-
- tag = Getattr(node,"tag");
- if (!tag) {
- Printf(stderr,"Whoa. No tag attribute on node passed to Swig_module_run.\n");
- exit(EXIT_FAILURE);
- }
- /* Get the set of modules that can respond to this node */
- while (node) {
- if (!LoadedModules) {
- Printf(stderr,"No modules loaded.\n");
- return 0;
- }
- ml = Getattr(LoadedModules,tag);
- if ((!ml) || (Len(ml) == 0)) {
- Printf(stderr,"Internal error. No module defined for handling '%s'\n", tag);
- return 0;
- }
- newnode = 0;
- newtag = 0;
- for (i = 0; i < Len(ml); i++) {
- Module *m;
- m = (Module *) Data(Getitem(ml,i));
- assert(m);
- newnode = (*m->startfunc)(node);
- if (!newnode) return node; /* Done */
- newtag = Getattr(newnode,"tag");
- if (!newtag) {
- Printf(stderr,"Fatal error. Module '%s' returns untagged object.\n", m->modname);
- exit(EXIT_FAILURE);
- }
- if (Cmp(newtag,tag)) break; /* Tag is different. Oh well */
- }
- if (Cmp(newtag,tag) == 0) break; /* Hmmm. The tag is the same but we already did everything */
- node = newnode;
- tag = newtag;
- }
- return 0;
-}
-
-
diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c
index 5b82276c3..2aa92db58 100644
--- a/Source/Swig/naming.c
+++ b/Source/Swig/naming.c
@@ -9,7 +9,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_naming_c[] = "$Header$";
#include "swig.h"
#include <ctype.h>
@@ -25,11 +25,99 @@ static Hash *naming_hash = 0;
* ----------------------------------------------------------------------------- */
void
-Swig_name_register(String_or_char *method, String_or_char *format) {
+Swig_name_register(const String_or_char *method, const String_or_char *format) {
if (!naming_hash) naming_hash = NewHash();
Setattr(naming_hash,method,format);
}
+void
+Swig_name_unregister(const String_or_char *method) {
+ if (naming_hash) {
+ Delattr(naming_hash,method);
+ }
+}
+
+static int name_mangle(String *r) {
+ char *c;
+ int special;
+ special = 0;
+ Replaceall(r,"::","_");
+ c = Char(r);
+ while (*c) {
+ if (!isalnum(*c) && (*c != '_')) {
+ special = 1;
+ switch(*c) {
+ case '+':
+ *c = 'a';
+ break;
+ case '-':
+ *c = 's';
+ break;
+ case '*':
+ *c = 'm';
+ break;
+ case '/':
+ *c = 'd';
+ break;
+ case '<':
+ *c = 'l';
+ break;
+ case '>':
+ *c = 'g';
+ break;
+ case '=':
+ *c = 'e';
+ break;
+ case ',':
+ *c = 'c';
+ break;
+ case '(':
+ *c = 'p';
+ break;
+ case ')':
+ *c = 'P';
+ break;
+ case '[':
+ *c = 'b';
+ break;
+ case ']':
+ *c = 'B';
+ break;
+ case '^':
+ *c = 'x';
+ break;
+ case '&':
+ *c = 'A';
+ break;
+ case '|':
+ *c = 'o';
+ break;
+ case '~':
+ *c = 'n';
+ break;
+ case '!':
+ *c = 'N';
+ break;
+ case '%':
+ *c = 'M';
+ break;
+ case '.':
+ *c = 'f';
+ break;
+ case '?':
+ *c = 'q';
+ break;
+ default:
+ *c = '_';
+ break;
+ }
+ }
+ c++;
+ }
+ if (special) Append(r,"___");
+ return special;
+}
+
/* -----------------------------------------------------------------------------
* Swig_name_mangle()
*
@@ -37,16 +125,10 @@ Swig_name_register(String_or_char *method, String_or_char *format) {
* ----------------------------------------------------------------------------- */
String *
-Swig_name_mangle(String_or_char *s) {
- String *r = NewString("");
- char *c;
- Append(r,s);
- c = Char(r);
- while (*c) {
- if (!isalnum(*c)) *c = '_';
- c++;
- }
- return Swig_temp_result(r);
+Swig_name_mangle(const String_or_char *s) {
+ String *r = NewString(s);
+ name_mangle(r);
+ return r;
}
/* -----------------------------------------------------------------------------
@@ -56,7 +138,7 @@ Swig_name_mangle(String_or_char *s) {
* ----------------------------------------------------------------------------- */
String *
-Swig_name_wrapper(String_or_char *fname) {
+Swig_name_wrapper(const String_or_char *fname) {
String *r;
String *f;
@@ -69,8 +151,8 @@ Swig_name_wrapper(String_or_char *fname) {
Append(r,f);
}
Replace(r,"%f",fname, DOH_REPLACE_ANY);
- Replace(r,":","_", DOH_REPLACE_ANY);
- return Swig_temp_result(r);
+ name_mangle(r);
+ return r;
}
@@ -81,11 +163,13 @@ Swig_name_wrapper(String_or_char *fname) {
* ----------------------------------------------------------------------------- */
String *
-Swig_name_member(String_or_char *classname, String_or_char *mname) {
+Swig_name_member(const String_or_char *classname, const String_or_char *mname) {
String *r;
String *f;
- char *cname, *c;
+ String *rclassname;
+ char *cname;
+ rclassname = SwigType_namestr(classname);
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"member");
@@ -94,12 +178,17 @@ Swig_name_member(String_or_char *classname, String_or_char *mname) {
} else {
Append(r,f);
}
- cname = Char(classname);
- c = strchr(cname, ' ');
- if (c) cname = c+1;
+ cname = Char(rclassname);
+ if ((strncmp(cname,"struct ", 7) == 0) ||
+ ((strncmp(cname,"class ", 6) == 0)) ||
+ ((strncmp(cname,"union ", 6) == 0))) {
+ cname = strchr(cname, ' ')+1;
+ }
Replace(r,"%c",cname, DOH_REPLACE_ANY);
Replace(r,"%m",mname, DOH_REPLACE_ANY);
- return Swig_temp_result(r);
+ /* name_mangle(r);*/
+ Delete(rclassname);
+ return r;
}
/* -----------------------------------------------------------------------------
@@ -109,7 +198,7 @@ Swig_name_member(String_or_char *classname, String_or_char *mname) {
* ----------------------------------------------------------------------------- */
String *
-Swig_name_get(String_or_char *vname) {
+Swig_name_get(const String_or_char *vname) {
String *r;
String *f;
@@ -122,7 +211,8 @@ Swig_name_get(String_or_char *vname) {
Append(r,f);
}
Replace(r,"%v",vname, DOH_REPLACE_ANY);
- return Swig_temp_result(r);
+ Replace(r,"::","_", DOH_REPLACE_ANY);
+ return r;
}
/* -----------------------------------------------------------------------------
@@ -132,7 +222,7 @@ Swig_name_get(String_or_char *vname) {
* ----------------------------------------------------------------------------- */
String *
-Swig_name_set(String_or_char *vname) {
+Swig_name_set(const String_or_char *vname) {
String *r;
String *f;
@@ -145,7 +235,8 @@ Swig_name_set(String_or_char *vname) {
Append(r,f);
}
Replace(r,"%v",vname, DOH_REPLACE_ANY);
- return Swig_temp_result(r);
+ Replace(r,"::","_", DOH_REPLACE_ANY);
+ return r;
}
/* -----------------------------------------------------------------------------
@@ -155,10 +246,13 @@ Swig_name_set(String_or_char *vname) {
* ----------------------------------------------------------------------------- */
String *
-Swig_name_construct(String_or_char *classname) {
+Swig_name_construct(const String_or_char *classname) {
String *r;
String *f;
- char *cname, *c;
+ String *rclassname;
+ char *cname;
+
+ rclassname = SwigType_namestr(classname);
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"construct");
@@ -168,14 +262,52 @@ Swig_name_construct(String_or_char *classname) {
Append(r,f);
}
- cname = Char(classname);
- c = strchr(cname, ' ');
- if (c) cname = c+1;
+ cname = Char(rclassname);
+ if ((strncmp(cname,"struct ", 7) == 0) ||
+ ((strncmp(cname,"class ", 6) == 0)) ||
+ ((strncmp(cname,"union ", 6) == 0))) {
+ cname = strchr(cname, ' ')+1;
+ }
+ Replace(r,"%c",cname, DOH_REPLACE_ANY);
+ Delete(rclassname);
+ return r;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_copyconstructor()
+ *
+ * Returns the name of the accessor function used to copy an object.
+ * ----------------------------------------------------------------------------- */
+
+String *
+Swig_name_copyconstructor(const String_or_char *classname) {
+ String *r;
+ String *f;
+ String *rclassname;
+ char *cname;
+
+ rclassname = SwigType_namestr(classname);
+ r = NewString("");
+ if (!naming_hash) naming_hash = NewHash();
+ f = Getattr(naming_hash,"construct");
+ if (!f) {
+ Append(r,"copy_%c");
+ } else {
+ Append(r,f);
+ }
+
+ cname = Char(rclassname);
+ if ((strncmp(cname,"struct ", 7) == 0) ||
+ ((strncmp(cname,"class ", 6) == 0)) ||
+ ((strncmp(cname,"union ", 6) == 0))) {
+ cname = strchr(cname, ' ')+1;
+ }
Replace(r,"%c",cname, DOH_REPLACE_ANY);
- return Swig_temp_result(r);
+ Delete(rclassname);
+ return r;
}
-
/* -----------------------------------------------------------------------------
* Swig_name_destroy()
@@ -183,10 +315,12 @@ Swig_name_construct(String_or_char *classname) {
* Returns the name of the accessor function used to destroy an object.
* ----------------------------------------------------------------------------- */
-String *Swig_name_destroy(String_or_char *classname) {
+String *Swig_name_destroy(const String_or_char *classname) {
String *r;
String *f;
- char *cname, *c;
+ String *rclassname;
+ char *cname;
+ rclassname = SwigType_namestr(classname);
r = NewString("");
if (!naming_hash) naming_hash = NewHash();
f = Getattr(naming_hash,"destroy");
@@ -196,14 +330,297 @@ String *Swig_name_destroy(String_or_char *classname) {
Append(r,f);
}
- cname = Char(classname);
- c = strchr(cname, ' ');
- if (c) cname = c+1;
-
+ cname = Char(rclassname);
+ if ((strncmp(cname,"struct ", 7) == 0) ||
+ ((strncmp(cname,"class ", 6) == 0)) ||
+ ((strncmp(cname,"union ", 6) == 0))) {
+ cname = strchr(cname, ' ')+1;
+ }
Replace(r,"%c",cname, DOH_REPLACE_ANY);
- return Swig_temp_result(r);
+ Delete(rclassname);
+ return r;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_object_set()
+ *
+ * Sets an object associated with a name and optional declarators.
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object) {
+ DOH *n;
+
+ /* Printf(stdout,"name: '%s', '%s'\n", name, decl);*/
+ n = Getattr(namehash,name);
+ if (!n) {
+ n = NewHash();
+ Setattr(namehash,name,n);
+ }
+ /* Add an object based on the declarator value */
+ if (!decl) {
+ Setattr(n,NewString("*"),object);
+ } else {
+ Setattr(n,Copy(decl),object);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_object_get()
+ *
+ * Return an object associated with an optional class prefix, name, and
+ * declarator. This function operates according to name matching rules
+ * described for the %rename directive in the SWIG manual.
+ * ----------------------------------------------------------------------------- */
+
+static DOH *get_object(Hash *n, String *decl) {
+ DOH *rn = 0;
+ if (!n) return 0;
+ if (decl) {
+ rn = Getattr(n,decl);
+ } else {
+ rn = Getattr(n,"*");
+ }
+ return rn;
+}
+
+DOH *
+Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl) {
+ String *tname;
+ DOH *rn = 0;
+ Hash *n;
+ char *ncdecl = 0;
+
+ if (!namehash) return 0;
+
+ /* DB: This removed to more tightly control feature/name matching */
+ /* if ((decl) && (SwigType_isqualifier(decl))) {
+ ncdecl = strchr(Char(decl),'.');
+ ncdecl++;
+ }
+ */
+
+ /* Perform a class-based lookup (if class prefix supplied) */
+ if (prefix) {
+ if (Len(prefix)) {
+ tname = NewStringf("%s::%s",prefix,name);
+ n = Getattr(namehash,tname);
+ rn = get_object(n,decl);
+ if ((!rn) && ncdecl) rn = get_object(n,ncdecl);
+ if (!rn) rn = get_object(n,0);
+ Delete(tname);
+ }
+ /* A wildcard-based class lookup */
+ if (!rn) {
+ tname = NewStringf("*::%s",name);
+ n = Getattr(namehash,tname);
+ rn = get_object(n,decl);
+ if ((!rn) && ncdecl) rn = get_object(n,ncdecl);
+ if (!rn) rn = get_object(n,0);
+ Delete(tname);
+ }
+ } else {
+ /* Lookup in the global namespace only */
+ tname = NewStringf("::%s",name);
+ n = Getattr(namehash,tname);
+ rn = get_object(n,decl);
+ if ((!rn) && ncdecl) rn = get_object(n,ncdecl);
+ if (!rn) rn = get_object(n,0);
+ Delete(tname);
+ }
+ /* Catch-all */
+ if (!rn) {
+ n = Getattr(namehash,name);
+ rn = get_object(n,decl);
+ if ((!rn) && ncdecl) rn = get_object(n,ncdecl);
+ if (!rn) rn = get_object(n,0);
+ }
+ return rn;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_object_inherit()
+ *
+ * Implements name-based inheritance scheme.
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_name_object_inherit(Hash *namehash, String *base, String *derived) {
+ String *key;
+ String *bprefix;
+ String *dprefix;
+ char *cbprefix;
+ int plen;
+
+ if (!namehash) return;
+
+ bprefix = NewStringf("%s::",base);
+ dprefix = NewStringf("%s::",derived);
+ cbprefix = Char(bprefix);
+ plen = strlen(cbprefix);
+ for (key = Firstkey(namehash); key; key = Nextkey(namehash)) {
+ char *k = Char(key);
+ if (strncmp(k,cbprefix,plen) == 0) {
+ Hash *n, *newh;
+ String *nkey, *okey;
+
+ nkey = NewStringf("%s%s",dprefix,k+plen);
+ n = Getattr(namehash,key);
+ newh = Getattr(namehash,nkey);
+ if (!newh) {
+ newh = NewHash();
+ Setattr(namehash,nkey,newh);
+ }
+ for (okey = Firstkey(n); okey; okey = Nextkey(n)) {
+ String *ovalue = Getattr(n,okey);
+ if (!Getattr(newh,okey)) {
+ Setattr(newh,okey,Copy(ovalue));
+ }
+ }
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_features_get()
+ *
+ * Given a node, this function merges features.
+ * ----------------------------------------------------------------------------- */
+
+static void merge_features(Hash *features, Node *n) {
+ String *key;
+ if (!features) return;
+ for (key = Firstkey(features); key; key = Nextkey(features)) {
+ if (Getattr(n,key)) {
+ continue;
+ }
+ Setattr(n,key,Copy(Getattr(features,key)));
+ }
+}
+
+void
+Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) {
+ String *tname;
+ DOH *rn = 0;
+ Hash *n;
+ char *ncdecl = 0;
+
+ if (!features) return;
+
+ if ((decl) && (SwigType_isqualifier(decl))) {
+ ncdecl = strchr(Char(decl),'.');
+ ncdecl++;
+ }
+
+ if (name) {
+ /* Perform a class-based lookup (if class prefix supplied) */
+ if (prefix) {
+ if (Len(prefix)) {
+ tname = NewStringf("%s::%s",prefix,name);
+ n = Getattr(features,tname);
+ rn = get_object(n,decl);
+ merge_features(rn,node);
+ if (ncdecl) {
+ rn = get_object(n,ncdecl);
+ merge_features(rn,node);
+ }
+ rn = get_object(n,0);
+ merge_features(rn,node);
+ Delete(tname);
+ }
+ /* A wildcard-based class lookup */
+ tname = NewStringf("*::%s",name);
+ n = Getattr(features,tname);
+ rn = get_object(n,decl);
+ merge_features(rn,node);
+ if (ncdecl) {
+ rn = get_object(n,ncdecl);
+ merge_features(rn,node);
+ }
+ rn = get_object(n,0);
+ merge_features(rn,node);
+ Delete(tname);
+
+ /* A class-generic feature */
+ if (Len(prefix)) {
+ tname = NewStringf("%s::",prefix);
+ n = Getattr(features,tname);
+ rn = get_object(n,0);
+ merge_features(rn,node);
+ Delete(tname);
+ }
+
+ } else {
+ /* Lookup in the global namespace only */
+ tname = NewStringf("::%s",name);
+ n = Getattr(features,tname);
+ rn = get_object(n,decl);
+ merge_features(rn,node);
+ if (ncdecl) {
+ rn = get_object(n,ncdecl);
+ merge_features(rn,node);
+ }
+ rn = get_object(n,0);
+ merge_features(rn,node);
+ Delete(tname);
+ }
+ /* Catch-all */
+ n = Getattr(features,name);
+ rn = get_object(n,decl);
+ merge_features(rn,node);
+ if (ncdecl) {
+ rn = get_object(n,ncdecl);
+ merge_features(rn,node);
+ }
+ rn = get_object(n,0);
+ merge_features(rn,node);
+ }
+ /* Global features */
+ n = Getattr(features,"");
+ rn = get_object(n,0);
+ merge_features(rn,node);
+
}
+/* -----------------------------------------------------------------------------
+ * Swig_feature_set()
+ *
+ * Sets a feature name and value.
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_feature_set(Hash *features, String *name, SwigType *decl, String *featurename, DOH *value) {
+ Hash *n;
+ Hash *fhash;
+ /* Printf(stdout,"feature: %s %s %s %s\n", name, decl, featurename, value);*/
+
+ n = Getattr(features,name);
+ if (!n) {
+ n = NewHash();
+ Setattr(features,name,n);
+ }
+ if (!decl) {
+ fhash = Getattr(n,"*");
+ if (!fhash) {
+ fhash = NewHash();
+ Setattr(n,"*",fhash);
+ }
+ } else {
+ fhash = Getattr(n,decl);
+ if (!fhash) {
+ fhash = NewHash();
+ Setattr(n,Copy(decl),fhash);
+ }
+ }
+ if (value) {
+ Setattr(fhash,featurename,value);
+ } else {
+ Delattr(fhash,featurename);
+ }
+}
+
+
+
diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c
index db6de504e..2dd8d5fbc 100644
--- a/Source/Swig/parms.c
+++ b/Source/Swig/parms.c
@@ -14,7 +14,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_parms_c[] = "$Header$";
#include "swig.h"
@@ -42,27 +42,36 @@ Parm *NewParm(SwigType *type, String_or_char *n) {
Parm *CopyParm(Parm *p) {
SwigType *t;
- char *name;
- char *lname;
- char *value;
- int ignore;
+ String *name;
+ String *lname;
+ String *value;
+ String *ignore;
+ String *alttype;
Parm *np = NewHash();
t = Getattr(p,"type");
- name = GetChar(p,"name");
- lname = GetChar(p,"lname");
- value = GetChar(p,"value");
- ignore = GetInt(p,"ignore");
-
- Setattr(np,"type",Copy(t));
+ name = Getattr(p,"name");
+ lname = Getattr(p,"lname");
+ value = Getattr(p,"value");
+ ignore = Getattr(p,"ignore");
+ alttype = Getattr(p,"alttype");
+
+ if (t)
+ Setattr(np,"type",Copy(t));
if (name)
- Setattr(np,"name",name);
+ Setattr(np,"name",Copy(name));
if (lname)
- Setattr(np,"lname", lname);
+ Setattr(np,"lname", Copy(lname));
if (value)
- Setattr(np,"value", value);
+ Setattr(np,"value", Copy(value));
if (ignore)
- SetInt(np,"ignore", ignore);
+ Setattr(np,"ignore", Copy(ignore));
+ if (alttype)
+ Setattr(np,"alttype", Copy(alttype));
+
+ Setfile(np,Getfile(p));
+ Setline(np,Getline(p));
+
return np;
}
@@ -81,12 +90,12 @@ CopyParmList(ParmList *p) {
while (p) {
np = CopyParm(p);
if (pp) {
- Setnext(pp,np);
+ set_nextSibling(pp,np);
} else {
fp = np;
}
pp = np;
- p = Getnext(p);
+ p = nextSibling(p);
}
return fp;
}
@@ -98,13 +107,30 @@ CopyParmList(ParmList *p) {
int ParmList_numarg(ParmList *p) {
int n = 0;
while (p) {
- if (!Getignore(p)) n++;
- p = Getnext(p);
+ if (!Getattr(p,"ignore")) n++;
+ p = nextSibling(p);
}
return n;
}
/* -----------------------------------------------------------------------------
+ * int ParmList_numrequired(). Return number of required arguments
+ * ----------------------------------------------------------------------------- */
+
+int ParmList_numrequired(ParmList *p) {
+ int i = 0;
+ while (p) {
+ SwigType *t = Getattr(p,"type");
+ String *value = Getattr(p,"value");
+ if (value) return i;
+ if (!(SwigType_type(t) == T_VOID)) i++;
+ else break;
+ p = nextSibling(p);
+ }
+ return i;
+}
+
+/* -----------------------------------------------------------------------------
* int ParmList_len()
* ----------------------------------------------------------------------------- */
@@ -112,7 +138,7 @@ int ParmList_len(ParmList *p) {
int i = 0;
while (p) {
i++;
- p = Getnext(p);
+ p = nextSibling(p);
}
return i;
}
@@ -129,13 +155,13 @@ String *ParmList_str(ParmList *p) {
out = NewString("");
while(p) {
- t = Gettype(p);
- Printf(out,"%s", SwigType_str(t,Getname(p)));
- p = Getnext(p);
+ t = Getattr(p,"type");
+ Printf(out,"%s", SwigType_str(t,Getattr(p,"name")));
+ p = nextSibling(p);
if (p)
Printf(out,",");
}
- return Swig_temp_result(out);
+ return out;
}
/* ---------------------------------------------------------------------
@@ -150,13 +176,17 @@ String *ParmList_protostr(ParmList *p) {
out = NewString("");
while(p) {
- t = Gettype(p);
+ if (Getattr(p,"hidden")) {
+ p = nextSibling(p);
+ continue;
+ }
+ t = Getattr(p,"type");
Printf(out,"%s", SwigType_str(t,0));
- p = Getnext(p);
+ p = nextSibling(p);
if (p)
Printf(out,",");
}
- return Swig_temp_result(out);
+ return out;
}
diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c
index 680db572d..8fc2d0ac4 100644
--- a/Source/Swig/scanner.c
+++ b/Source/Swig/scanner.c
@@ -12,7 +12,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_scanner_c[] = "$Header$";
#include "swig.h"
#include <ctype.h>
@@ -598,22 +598,46 @@ look(SwigScanner *s) {
if ((c = nextchar(s)) == 0) return SWIG_TOKEN_LONG;
if ((c == 'u') || (c == 'U')) {
return SWIG_TOKEN_ULONG;
+ } else if ((c == 'l') || (c == 'L')) {
+ state = 870;
} else {
retract(s,1);
return SWIG_TOKEN_LONG;
}
+ break;
+
+ /* A long long integer */
+
+ case 870:
+ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_LONGLONG;
+ if ((c == 'u') || (c == 'U')) {
+ return SWIG_TOKEN_ULONGLONG;
+ } else {
+ retract(s,1);
+ return SWIG_TOKEN_LONGLONG;
+ }
/* An unsigned number */
case 88:
if ((c = nextchar(s)) == 0) return SWIG_TOKEN_UINT;
if ((c == 'l') || (c == 'L')) {
- return SWIG_TOKEN_ULONG;
+ state = 880;
} else {
- retract(s,1);
- return SWIG_TOKEN_UINT;
+ retract(s,1);
+ return SWIG_TOKEN_UINT;
}
+ break;
+ /* Possibly an unsigned long long or unsigned long */
+ case 880:
+ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_ULONG;
+ if ((c == 'l') || (c == 'L')) return SWIG_TOKEN_ULONGLONG;
+ else {
+ retract(s,1);
+ return SWIG_TOKEN_ULONG;
+ }
+
/* A character constant */
case 9:
if ((c = nextchar(s)) == 0) {
diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c
index 64ff0ceab..40bac71c8 100644
--- a/Source/Swig/stype.c
+++ b/Source/Swig/stype.c
@@ -10,7 +10,7 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_stype_c[] = "$Header$";
#include "swig.h"
#include <ctype.h>
@@ -38,12 +38,12 @@ static char cvsroot[] = "$Header$";
*
* All type constructors are denoted by a trailing '.':
*
- * 'p.' = Pointer
- * 'r.' = Reference
- * 'a(n).' = Array of size n
- * 'f(..,..).' = Function with arguments
- * 'q(str).' = Qualifier (such as const or volatile)
- * 't(...).' = Template specifier???
+ * 'p.' = Pointer (*)
+ * 'r.' = Reference (&)
+ * 'a(n).' = Array of size n [n]
+ * 'f(..,..).' = Function with arguments (args)
+ * 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
+ * 'm(qual).' = Pointer to member (qual::*)
*
* The encoding follows the order that you might describe a type in words.
* For example "p.a(200).int" is "A pointer to array of int's" and
@@ -124,6 +124,18 @@ SwigType *NewSwigType(int t) {
case T_UCHAR:
return NewString("unsigned char");
break;
+ case T_STRING: {
+ SwigType *t = NewString("char");
+ SwigType_add_pointer(t);
+ return t;
+ break;
+ }
+ case T_LONGLONG:
+ return NewString("long long");
+ break;
+ case T_ULONGLONG:
+ return NewString("unsigned long long");
+ break;
case T_VOID:
return NewString("void");
break;
@@ -147,6 +159,10 @@ SwigType_add_pointer(SwigType *t) {
void
SwigType_del_pointer(SwigType *t) {
char *c = Char(t);
+ if (strncmp(c,"q(",2) == 0) {
+ Delete(SwigType_pop(t));
+ c = Char(t);
+ }
if (strncmp(c,"p.",2)) {
printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n");
abort();
@@ -155,6 +171,19 @@ SwigType_del_pointer(SwigType *t) {
}
/* -----------------------------------------------------------------------------
+ * SwigType_add_memberpointer()
+ *
+ * Add a pointer to a member to a type
+ * ----------------------------------------------------------------------------- */
+
+void
+SwigType_add_memberpointer(SwigType *t, String_or_char *name) {
+ String *temp = NewStringf("m(%s).", name);
+ Insert(t,0,temp);
+ Delete(temp);
+}
+
+/* -----------------------------------------------------------------------------
* SwigType_add_array()
*
* Adds an array constructor to a type
@@ -168,6 +197,25 @@ SwigType_add_array(SwigType *t, String *size) {
}
/* -----------------------------------------------------------------------------
+ * SwigType_pop_arrays()
+ *
+ * Pop all arrays off as a single item
+ * ----------------------------------------------------------------------------- */
+
+SwigType *
+SwigType_pop_arrays(SwigType *t) {
+ String *ta;
+ if (!SwigType_isarray(t)) return 0;
+ ta = NewString("");
+ while (SwigType_isarray(t)) {
+ SwigType *td = SwigType_pop(t);
+ Append(ta,td);
+ Delete(td);
+ }
+ return ta;
+}
+
+/* -----------------------------------------------------------------------------
* SwigType_add_reference()
*
* Adds a reference constructor to a type.
@@ -187,8 +235,57 @@ SwigType_add_reference(SwigType *t) {
void
SwigType_add_qualifier(SwigType *t, String *qual) {
char temp[256];
- sprintf(temp,"q(%s).",Char(qual));
- Insert(t,0,temp);
+ if (!SwigType_isqualifier(t)) {
+ sprintf(temp,"q(%s).",Char(qual));
+ Insert(t,0,temp);
+ } else {
+ /* Already has a qualifier on it. We are going to generate a
+ canonical qualifier string */
+ String *qt;
+ char *c, *qc;
+ String *newq;
+
+ qt = SwigType_pop(t); /* Rip off the old qualifier */
+ /* See if the added qualifier is already there */
+ if (strstr(Char(qt),Char(qual))) {
+ /* Already added this qualifier */
+ SwigType_push(t,qt);
+ Delete(qt);
+ return;
+ }
+ /* We need to add the qualifier to the qualifier list */
+ /* To do this, we keep the qualifiers in alphabetical order */
+ newq = NewString("q(");
+ qc = Char(qual);
+ c = Char(qt)+2;
+ c = strtok(c," ).");
+ while (c) {
+ if (!strlen(c)) {
+ c = strtok(NULL," ).");
+ continue;
+ }
+ if (qc) {
+ if (strcmp(c,qc) < 0) {
+ Printf(newq,"%s",c);
+ } else {
+ Printf(newq,"%s %s", qc,c);
+ qc = 0;
+ }
+ } else {
+ Printf(newq,"%s",c);
+ }
+ c = strtok(NULL," ).");
+ if (c) Putc(' ',newq);
+ }
+ if (qc) {
+ Printf(newq," %s",qc);
+ }
+ Putc(')',newq);
+ Putc('.',newq);
+ SwigType_push(t,newq);
+ Delete(newq);
+ Delete(qt);
+ }
}
/* -----------------------------------------------------------------------------
@@ -201,20 +298,84 @@ SwigType_add_qualifier(SwigType *t, String *qual) {
void
SwigType_add_function(SwigType *t, ParmList *parms) {
String *pstr;
+ Parm *p;
Insert(t,0,").");
pstr = NewString("f(");
-
- while (parms) {
- Printf(pstr,"%s",Gettype(parms));
- parms = Getnext(parms);
- if (parms)
- Putc(',',pstr);
+ p = parms;
+ for (p = parms; p; p = nextSibling(p)) {
+ if (p != parms) Putc(',',pstr);
+ Printf(pstr,"%s", Getattr(p,"type"));
}
Insert(t,0,pstr);
Delete(pstr);
}
+SwigType *
+SwigType_pop_function(SwigType *t) {
+ SwigType *f = 0;
+ SwigType *g = 0;
+ char *c = Char(t);
+ if (strncmp(c,"q(",2) == 0) {
+ f = SwigType_pop(t);
+ c = Char(t);
+ }
+ if (strncmp(c,"f(",2)) {
+ printf("Fatal error. SwigType_pop_function applied to non-function.\n");
+ abort();
+ }
+ g = SwigType_pop(t);
+ if (f) SwigType_push(g,f);
+ Delete(f);
+ return g;
+}
+
+ParmList *
+SwigType_function_parms(SwigType *t) {
+ List *l = SwigType_parmlist(t);
+ Hash *p, *pp = 0, *firstp = 0;
+ DOH *obj;
+ for (obj = Firstitem(l); obj; obj = Nextitem(l)) {
+ p = NewParm(obj,0);
+ if (!firstp) firstp = p;
+ if (pp) {
+ set_nextSibling(pp,p);
+ }
+ pp = p;
+ }
+ Delete(l);
+ return firstp;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_add_template()
+ *
+ * Adds a template to a type. This template is encoded in the SWIG type
+ * mechanism and produces a string like this:
+ *
+ * vector<int *> ----> "vector<(p.int)>"
+ * ----------------------------------------------------------------------------- */
+
+void
+SwigType_add_template(SwigType *t, ParmList *parms) {
+ Parm *p;
+
+ Append(t,"<(");
+ p = parms;
+ for (p = parms; p; p = nextSibling(p)) {
+ String *v;
+ if (Getattr(p,"default")) continue;
+ if (p != parms) Append(t,",");
+ v = Getattr(p,"value");
+ if (v) {
+ Append(t,v);
+ } else {
+ Append(t,Getattr(p,"type"));
+ }
+ }
+ Append(t,")>");
+}
+
/* -----------------------------------------------------------------------------
* static isolate_element()
*
@@ -228,8 +389,7 @@ isolate_element(char *c) {
if (*c == '.') {
Putc(*c,result);
return result;
- }
- else if (*c == '(') {
+ } else if (*c == '(') {
int nparen = 1;
Putc(*c,result);
c++;
@@ -263,6 +423,7 @@ List *SwigType_split(SwigType *t) {
int len;
c = Char(t);
+
list = NewList();
while (*c) {
item = isolate_element(c);
@@ -312,6 +473,7 @@ void SwigType_push(SwigType *t, String *cons)
{
if (!cons) return;
if (!Len(cons)) return;
+
if (Len(t)) {
char *c = Char(cons);
if (c[strlen(c)-1] != '.')
@@ -326,7 +488,7 @@ void SwigType_push(SwigType *t, String *cons)
* Splits a comma separated list of components into strings.
* ----------------------------------------------------------------------------- */
-List *SwigType_parmlist(String *p) {
+List *SwigType_parmlist(const String *p) {
DOH *item;
List *list;
char *c;
@@ -404,20 +566,37 @@ String *SwigType_parm(SwigType *t) {
* SwigType_isfunction()
* SwigType_isqualifier()
*
- * Testing functions for querying a datatype
+ * Testing functions for querying a raw datatype
* ----------------------------------------------------------------------------- */
int SwigType_ispointer(SwigType *t) {
char *c;
+ if (!t) return 0;
c = Char(t);
+ if (strncmp(c,"q(",2) == 0) {
+ c = strchr(c,'.');
+ if (!c) return 0;
+ c++;
+ }
if (strncmp(c,"p.",2) == 0) {
return 1;
}
return 0;
}
+int SwigType_ismemberpointer(SwigType *t) {
+ char *c;
+ if (!t) return 0;
+ c = Char(t);
+ if (strncmp(c,"m(",2) == 0) {
+ return 1;
+ }
+ return 0;
+}
+
int SwigType_isreference(SwigType *t) {
char *c;
+ if (!t) return 0;
c = Char(t);
if (strncmp(c,"r.",2) == 0) {
return 1;
@@ -427,6 +606,7 @@ int SwigType_isreference(SwigType *t) {
int SwigType_isarray(SwigType *t) {
char *c;
+ if (!t) return 0;
c = Char(t);
if (strncmp(c,"a(",2) == 0) {
return 1;
@@ -436,8 +616,16 @@ int SwigType_isarray(SwigType *t) {
int SwigType_isfunction(SwigType *t) {
char *c;
-
+ if (!t) {
+ return 0;
+ }
c = Char(t);
+ if (strncmp(c,"q(",2) == 0) {
+ /* Might be a 'const' function. Try to skip over the 'const' */
+ c = strchr(c,'.');
+ if (c) c++;
+ else return 0;
+ }
if (strncmp(c,"f(",2) == 0) {
return 1;
}
@@ -446,6 +634,7 @@ int SwigType_isfunction(SwigType *t) {
int SwigType_isqualifier(SwigType *t) {
char *c;
+ if (!t) return 0;
c = Char(t);
if (strncmp(c,"q(",2) == 0) {
return 1;
@@ -455,21 +644,79 @@ int SwigType_isqualifier(SwigType *t) {
int SwigType_isconst(SwigType *t) {
char *c;
+ if (!t) return 0;
c = Char(t);
- if (strncmp(c,"q(const)",8) == 0) {
- return 1;
+ if (strncmp(c,"q(",2) == 0) {
+ String *q = SwigType_parm(t);
+ if (strstr(Char(q),"const")) {
+ Delete(q);
+ return 1;
+ }
+ Delete(q);
+ }
+ /* Hmmm. Might be const through a typedef */
+ if (SwigType_issimple(t)) {
+ int ret;
+ SwigType *td = SwigType_typedef_resolve(t);
+ if (td) {
+ ret = SwigType_isconst(td);
+ Delete(td);
+ return ret;
+ }
}
return 0;
}
+int SwigType_ismutable(SwigType *t) {
+ int r;
+ SwigType *qt = SwigType_typedef_resolve_all(t);
+ if (SwigType_isreference(qt)) {
+ Delete(SwigType_pop(qt));
+ }
+ r = SwigType_isconst(qt);
+ Delete(qt);
+ return r ? 0 : 1;
+}
+
int SwigType_isenum(SwigType *t) {
char *c = Char(t);
+ if (!t) return 0;
if (strncmp(c,"enum ",5) == 0) {
return 1;
}
return 0;
}
+int SwigType_issimple(SwigType *t) {
+ char *c = Char(t);
+ if (!t) return 0;
+ while (*c) {
+ if (*c == '<') {
+ int nest = 1;
+ c++;
+ while (*c && nest) {
+ if (*c == '<') nest++;
+ if (*c == '>') nest--;
+ c++;
+ }
+ c--;
+ }
+ if (*c == '.') return 0;
+ c++;
+ }
+ return 1;
+}
+
+int SwigType_isvarargs(const SwigType *t) {
+ if (Strcmp(t,"v(...)") == 0) return 1;
+ return 0;
+}
+
+int SwigType_istemplate(const SwigType *t) {
+ if (Strstr(t,"<(")) return 1;
+ return 0;
+}
+
/* -----------------------------------------------------------------------------
* SwigType_base()
*
@@ -481,20 +728,35 @@ SwigType *SwigType_base(SwigType *t) {
c = Char(t);
d = c + strlen(c);
+
+ /* Check for a type constructor */
+ if ((d > c) && (*(d-1) == '.')) d--;
+
while (d > c) {
d--;
- if (*d == '.') return Swig_temp_result(NewString(d+1));
+ if (*d == '>') {
+ /* Skip over template--that's part of the base name */
+ int ntemp = 1;
+ d--;
+ while ((d > c) && (ntemp > 0)) {
+ if (*d == '>') ntemp++;
+ if (*d == '<') ntemp--;
+ d--;
+ }
+ }
+ if (*d == ')') {
+ /* Skip over params */
+ int nparen = 1;
+ d--;
+ while ((d > c) && (nparen > 0)) {
+ if (*d == ')') nparen++;
+ if (*d == '(') nparen--;
+ d--;
+ }
+ }
+ if (*d == '.') return NewString(d+1);
}
- return Swig_temp_result(NewString(c));
-}
-
-void SwigType_setbase(SwigType *t, String_or_char *n) {
- SwigType *p;
- p = SwigType_prefix(t);
- Clear(t);
- Append(t,p);
- Append(t,n);
- Delete(p);
+ return NewString(c);
}
/* -----------------------------------------------------------------------------
@@ -509,8 +771,32 @@ String *SwigType_prefix(SwigType *t) {
c = Char(t);
d = c + strlen(c);
+
+ /* Check for a type constructor */
+ if ((d > c) && (*(d-1) == '.')) d--;
+
while (d > c) {
d--;
+ if (*d == '>') {
+ int nest = 1;
+ d--;
+ while ((d > c) && (nest)) {
+ if (*d == '>') nest++;
+ if (*d == '<') nest--;
+ d--;
+ }
+ }
+ if (*d == ')') {
+ /* Skip over params */
+ int nparen = 1;
+ d--;
+ while ((d > c) && (nparen)) {
+ if (*d == ')') nparen++;
+ if (*d == '(') nparen--;
+ d--;
+ }
+ }
+
if (*d == '.') {
char t = *(d+1);
*(d+1) = 0;
@@ -522,6 +808,125 @@ String *SwigType_prefix(SwigType *t) {
return NewString("");
}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_templateprefix()
+ *
+ * Returns the prefix before the first template definition.
+ * For example:
+ *
+ * Foo<(p.int)>::bar
+ *
+ * Results in "Foo"
+ * ----------------------------------------------------------------------------- */
+
+String *
+SwigType_templateprefix(SwigType *t) {
+ char *c;
+ String *r;
+ String *s = NewString(t);
+ c = Char(s);
+ while (*c) {
+ if (*c == '<') {
+ *c = 0;
+ r = NewString(Char(s));
+ Delete(s);
+ return r;
+ }
+ c++;
+ }
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_templatesuffix()
+ *
+ * Returns text after a template substitution. Used to handle scope names
+ * for example:
+ *
+ * Foo<(p.int)>::bar
+ *
+ * returns "::bar"
+ * ----------------------------------------------------------------------------- */
+
+String *
+SwigType_templatesuffix(const SwigType *t) {
+ char *c;
+ c = Char(t);
+ while (*c) {
+ if ((*c == '<') && (*(c+1) == '(')) {
+ int nest = 1;
+ c++;
+ while (*c && nest) {
+ if (*c == '<') nest++;
+ if (*c == '>') nest--;
+ c++;
+ }
+ return NewString(c);
+ }
+ c++;
+ }
+ return NewString("");
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_templateargs()
+ *
+ * Returns the template part
+ * ----------------------------------------------------------------------------- */
+
+String *
+SwigType_templateargs(SwigType *t) {
+ String *result = NewString("");
+ char *c;
+ c = Char(t);
+ while (*c) {
+ if ((*c == '<') && (*(c+1) == '(')) {
+ int nest = 1;
+ Putc(*c,result);
+ c++;
+ while (*c && nest) {
+ Putc(*c,result);
+ if (*c == '<') nest++;
+ if (*c == '>') nest--;
+ c++;
+ }
+ return result;
+ }
+ c++;
+ }
+ Delete(result);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_strip_qualifiers()
+ *
+ * Strip all qualifiers from a type and return a new type
+ * ----------------------------------------------------------------------------- */
+
+static Hash *memoize_stripped = 0;
+
+SwigType *
+SwigType_strip_qualifiers(SwigType *t) {
+ SwigType *r;
+ List *l;
+ SwigType *e;
+ if (!memoize_stripped) memoize_stripped = NewHash();
+ r = Getattr(memoize_stripped,t);
+ if (r) return Copy(r);
+
+ l = SwigType_split(t);
+ r = NewString("");
+ for (e = Firstitem(l); e; e = Nextitem(l)) {
+ if (SwigType_isqualifier(e)) continue;
+ Append(r,e);
+ }
+ Setattr(memoize_stripped,Copy(t),Copy(r));
+ return r;
+}
+
/* -----------------------------------------------------------------------------
* SwigType_array_ndim()
*
@@ -553,7 +958,7 @@ String *SwigType_array_getdim(SwigType *t, int n) {
c++;
n--;
}
- if (n == 0) return Swig_temp_result(SwigType_parm(c));
+ if (n == 0) return SwigType_parm(c);
return 0;
}
@@ -592,17 +997,34 @@ void SwigType_array_setdim(SwigType *t, int n, String_or_char *rep) {
}
/* -----------------------------------------------------------------------------
+ * SwigType_array_type()
+ *
+ * Return the base type of an array
+ * ----------------------------------------------------------------------------- */
+
+SwigType *
+SwigType_array_type(SwigType *ty) {
+ SwigType *t;
+ t = Copy(ty);
+ while (SwigType_isarray(t)) {
+ Delete(SwigType_pop(t));
+ }
+ return t;
+}
+
+/* -----------------------------------------------------------------------------
* SwigType_default()
*
* Create the default string for this datatype. This takes a type and strips it
* down to its most primitive form--resolving all typedefs and removing operators.
*
* Rules:
- * Pointers: p.SWIGPOINTER
- * References: r.SWIGREFERENCE
- * Arrays: a().SWIGARRAY
+ * Pointers: p.SWIGTYPE
+ * References: r.SWIGTYPE
+ * Arrays: a().SWIGTYPE
* Types: SWIGTYPE
- *
+ * MemberPointer: m(CLASS).SWIGTYPE
+ * Enums: enum SWIGENUM
* ----------------------------------------------------------------------------- */
static Hash *default_cache = 0;
@@ -621,12 +1043,24 @@ SwigType *SwigType_default(SwigType *t) {
if (r != t) Delete(r);
r = r1;
}
+ if (SwigType_isqualifier(r)) {
+ if (r == t) r = Copy(t);
+ do {
+ Delete(SwigType_pop(r));
+ } while (SwigType_isqualifier(r));
+ }
if (SwigType_ispointer(r)) {
- def = NewString("p.SWIGPOINTER");
+ def = NewString("p.SWIGTYPE");
} else if (SwigType_isreference(r)) {
- def = NewString("r.SWIGREFERENCE");
+ def = NewString("r.SWIGTYPE");
} else if (SwigType_isarray(r)) {
- def = NewString("a().SWIGARRAY");
+ def = NewString("a().SWIGTYPE");
+ } else if (SwigType_ismemberpointer(r)) {
+ def = NewString("m(CLASS).SWIGTYPE");
+ } else if (SwigType_isenum(r)) {
+ def = NewString("enum SWIGTYPE");
+ } else if (SwigType_isvarargs(r)) {
+ def = NewString("v(...)");
} else {
def = NewString("SWIGTYPE");
}
@@ -636,7 +1070,56 @@ SwigType *SwigType_default(SwigType *t) {
}
/* -----------------------------------------------------------------------------
- * SwigType_str(DOH *s, DOH *id)
+ * SwigType_namestr()
+ *
+ * Returns a string of the base type. Takes care of template expansions
+ * ----------------------------------------------------------------------------- */
+
+String *
+SwigType_namestr(const SwigType *t) {
+ String *r;
+ String *suffix;
+ List *p;
+ char tmp[256];
+ char *c, *d, *e;
+ int i, sz;
+
+ if (!SwigType_istemplate(t)) return NewString(t);
+
+ c = Strstr(t,"<(");
+
+ d = Char(t);
+ e = tmp;
+ while (d != c) {
+ *(e++) = *(d++);
+ }
+ *e = 0;
+ r = NewString(tmp);
+ Putc('<',r);
+
+ p = SwigType_parmlist(t);
+ sz = Len(p);
+ for (i = 0; i < sz; i++) {
+ Append(r,SwigType_str(Getitem(p,i),0));
+ if ((i+1) < sz) Putc(',',r);
+ }
+ Putc(' ',r);
+ Putc('>',r);
+ suffix = SwigType_templatesuffix(t);
+ Append(r,suffix);
+ Delete(suffix);
+#if 0
+ if (SwigType_istemplate(r)) {
+ SwigType *rr = SwigType_namestr(r);
+ Delete(r);
+ return rr;
+ }
+#endif
+ return r;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_str()
*
* Create a C string representation of a datatype.
* ----------------------------------------------------------------------------- */
@@ -668,15 +1151,32 @@ SwigType_str(SwigType *s, const String_or_char *id)
} else {
nextelement = 0;
}
- if (SwigType_ispointer(element)) {
+ if (SwigType_isqualifier(element)) {
+ DOH *q = 0;
+ q = SwigType_parm(element);
+ Insert(result,0," ");
+ Insert(result,0,q);
+ Delete(q);
+ } else if (SwigType_ispointer(element)) {
Insert(result,0,"*");
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
Insert(result,0,"(");
Append(result,")");
}
+ } else if (SwigType_ismemberpointer(element)) {
+ String *q;
+ q = SwigType_parm(element);
+ Insert(result,0,"::*");
+ Insert(result,0,q);
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result,0,"(");
+ Append(result,")");
+ }
+ Delete(q);
}
- else if (SwigType_isreference(element)) Insert(result,0,"&");
- else if (SwigType_isarray(element)) {
+ else if (SwigType_isreference(element)) {
+ Insert(result,0,"&");
+ } else if (SwigType_isarray(element)) {
DOH *size;
Append(result,"[");
size = SwigType_parm(element);
@@ -696,199 +1196,109 @@ SwigType_str(SwigType *s, const String_or_char *id)
}
Append(result,")");
Delete(parms);
- } else if (SwigType_isqualifier(element)) {
- DOH *q = 0;
- q = SwigType_parm(element);
- Insert(result,0," ");
- Insert(result,0,q);
- Delete(q);
} else {
- Insert(result,0," ");
- Insert(result,0,element);
- }
- element = nextelement;
- }
- Delete(elements);
- return Swig_temp_result(result);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_lstr(DOH *s, DOH *id)
- *
- * Produces a type-string that is suitable as a lvalue in an expression.
- * That is, a type that can be freely assigned a value without violating
- * any C assignment rules.
- *
- * - Qualifiers such as 'const' and 'volatile' are stripped.
- * - Arrays are converted into a *single* pointer (i.e.,
- * double [][] becomes double *).
- * - References are converted into a pointer.
- * - Typedef names that refer to read-only types will be replaced
- * with an equivalent assignable version.
- * -------------------------------------------------------------------- */
-
-String *
-SwigType_lstr(SwigType *s, const String_or_char *id)
-{
- String *result;
- String *element = 0, *nextelement;
- List *elements;
- int nelements, i;
- int firstarray = 1;
- SwigType *td, *rs, *tc = 0;
- if (id) {
- result = NewString(Char(id));
- } else {
- result = NewString("");
- }
- if (SwigType_isconst(s)) {
- tc = Copy(s);
- Delete(SwigType_pop(tc));
- rs = tc;
- } else {
- rs = s;
- }
- td = SwigType_typedef_resolve(rs);
- if ((td) && (SwigType_isconst(td) || SwigType_isarray(td))) {
- elements = SwigType_split(td);
- } else if (td && SwigType_isenum(td)) {
- elements = SwigType_split("int");
- } else {
- elements = SwigType_split(rs);
- }
- if (td) Delete(td);
- nelements = Len(elements);
-
- if (nelements > 0) {
- element = Getitem(elements,0);
- }
- /* Now, walk the type list and start emitting */
- for (i = 0; i < nelements; i++) {
- if (i < (nelements - 1)) {
- nextelement = Getitem(elements,i+1);
- } else {
- nextelement = 0;
- }
- if (SwigType_ispointer(element)) {
- Insert(result,0,"*");
- if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
- Insert(result,0,"(");
- Append(result,")");
- }
- firstarray = 0;
- } else if (SwigType_isreference(element)) {
- Insert(result,0,"*");
- } else if (SwigType_isarray(element)) {
- if (firstarray) {
- Insert(result,0,"*");
- while (nextelement && (SwigType_isarray(nextelement))) {
- i++;
- nextelement = Getitem(elements,i+1);
- }
- if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
- Insert(result,0,"(");
- Append(result,")");
- }
- firstarray = 0;
+ if (Strcmp(element,"v(...)") == 0) {
+ Insert(result,0,"...");
} else {
- DOH *size;
- Append(result,"[");
- size = SwigType_parm(element);
- Append(result,size);
- Append(result,"]");
- Delete(size);
- }
- } else if (SwigType_isfunction(element)) {
- DOH *parms, *p;
- int j, plen;
- Append(result,"(");
- parms = SwigType_parmlist(element);
- plen = Len(parms);
- for (j = 0; j < plen; j++) {
- p = SwigType_str(Getitem(parms,j),0);
- Append(result,p);
- if (j < (plen-1)) Append(result,",");
+ String *bs = SwigType_namestr(element);
+ Insert(result,0," ");
+ Insert(result,0,bs);
+ Delete(bs);
}
- Append(result,")");
- Delete(parms);
- } else if (SwigType_isqualifier(element)) {
- } else {
- Insert(result,0," ");
- Insert(result,0,element);
}
element = nextelement;
}
Delete(elements);
- if (tc) Delete(tc);
- return Swig_temp_result(result);
+ Chop(result);
+ return result;
}
-
/* -----------------------------------------------------------------------------
* SwigType_ltype(SwigType *ty)
*
- * Returns a type object corresponding to the string created by lstr
+ * Create a locally assignable type
* ----------------------------------------------------------------------------- */
SwigType *
SwigType_ltype(SwigType *s) {
String *result;
- String *element, *nextelement;
- SwigType *td, *rs, *tc = 0;
+ String *element;
+ SwigType *td, *tc = 0;
List *elements;
int nelements, i;
int firstarray = 1;
result = NewString("");
-
- if (SwigType_isconst(s)) {
- tc = Copy(s);
+ tc = Copy(s);
+ /* Nuke all leading qualifiers */
+ while (SwigType_isqualifier(tc)) {
Delete(SwigType_pop(tc));
- rs = tc;
- } else {
- rs = s;
}
-
- td = SwigType_typedef_resolve(rs);
- if ((td) && (SwigType_isconst(td) || SwigType_isarray(td))) {
- elements = SwigType_split(td);
- } else if (td && SwigType_isenum(td)) {
- elements = SwigType_split("int");
- } else {
- elements = SwigType_split(rs);
+ if (SwigType_issimple(tc)) {
+ /* Resolve any typedef definitions */
+ td = SwigType_typedef_resolve(tc);
+ if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isenum(td) || SwigType_isreference(td))) {
+ /* We need to use the typedef type */
+ Delete(tc);
+ tc = td;
+ } else if (td) {
+ Delete(td);
+ }
}
- if (td) Delete(td);
+ elements = SwigType_split(tc);
nelements = Len(elements);
/* Now, walk the type list and start emitting */
for (i = 0; i < nelements; i++) {
element = Getitem(elements,i);
- if (SwigType_ispointer(element)) {
+ if (SwigType_isqualifier(element)) {
+ /* Do nothing. Ignore */
+ } else if (SwigType_ispointer(element)) {
+ Append(result,element);
+ firstarray = 0;
+ } else if (SwigType_ismemberpointer(element)) {
Append(result,element);
firstarray = 0;
} else if (SwigType_isreference(element)) {
Append(result,"p.");
- } else if (SwigType_isarray(element)) {
- if (firstarray) {
- Append(result,"p.");
- while (i < (nelements - 1)) {
- element = Getitem(elements,i+1);
- if (!SwigType_isarray(element)) break;
- i++;
- }
- firstarray = 0;
- } else {
- Append(result,element);
- }
- } else if (SwigType_isfunction(element)) {
- Append(result,element);
- } else if (SwigType_isqualifier(element)) {
+ firstarray = 0;
+ } else if (SwigType_isarray(element) && firstarray) {
+ Append(result,"p.");
+ firstarray = 0;
+ } else if (SwigType_isenum(element)) {
+ Append(result,"int");
} else {
Append(result,element);
}
- element = nextelement;
}
Delete(elements);
- if (tc) Delete(tc);
+ Delete(tc);
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_lstr(DOH *s, DOH *id)
+ *
+ * Produces a type-string that is suitable as a lvalue in an expression.
+ * That is, a type that can be freely assigned a value without violating
+ * any C assignment rules.
+ *
+ * - Qualifiers such as 'const' and 'volatile' are stripped.
+ * - Arrays are converted into a *single* pointer (i.e.,
+ * double [][] becomes double *).
+ * - References are converted into a pointer.
+ * - Typedef names that refer to read-only types will be replaced
+ * with an equivalent assignable version.
+ * -------------------------------------------------------------------- */
+
+String *
+SwigType_lstr(SwigType *s, const String_or_char *id)
+{
+ String *result;
+ SwigType *tc;
+
+ tc = SwigType_ltype(s);
+ result = SwigType_str(tc,id);
+ Delete(tc);
return result;
}
@@ -907,6 +1317,7 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) {
int nelements, i;
int clear = 1;
int firstarray = 1;
+ int isreference = 0;
result = NewString("");
@@ -918,18 +1329,21 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) {
rs = s;
}
- td = SwigType_typedef_resolve(rs);
- if ((td) && (SwigType_isconst(td) || SwigType_isarray(td))) {
- elements = SwigType_split(td);
- } else if (td && SwigType_isenum(td)) {
- elements = SwigType_split(rs);
- clear = 0;
+ if (SwigType_issimple(rs)) {
+ td = SwigType_typedef_resolve(rs);
+ if ((td) && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
+ elements = SwigType_split(td);
+ } else if (td && SwigType_isenum(td)) {
+ elements = SwigType_split(rs);
+ clear = 0;
+ } else {
+ elements = SwigType_split(rs);
+ }
+ if (td) Delete(td);
} else {
elements = SwigType_split(rs);
}
- if (td) Delete(td);
nelements = Len(elements);
-
if (nelements > 0) {
element = Getitem(elements,0);
}
@@ -940,15 +1354,34 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) {
} else {
nextelement = 0;
}
- if (SwigType_ispointer(element)) {
+ if (SwigType_isqualifier(element)) {
+ DOH *q = 0;
+ q = SwigType_parm(element);
+ Insert(result,0," ");
+ Insert(result,0,q);
+ Delete(q);
+ clear = 0;
+ } else if (SwigType_ispointer(element)) {
Insert(result,0,"*");
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
Insert(result,0,"(");
Append(result,")");
}
firstarray = 0;
+ } else if (SwigType_ismemberpointer(element)) {
+ String *q;
+ Insert(result,0,"::*");
+ q = SwigType_parm(element);
+ Insert(result,0,q);
+ Delete(q);
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result,0,"(");
+ Append(result,")");
+ }
+ firstarray = 0;
} else if (SwigType_isreference(element)) {
Insert(result,0,"&");
+ isreference = 1;
} else if (SwigType_isarray(element)) {
DOH *size;
if (firstarray) {
@@ -975,16 +1408,16 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) {
}
Append(result,")");
Delete(parms);
- } else if (SwigType_isqualifier(element)) {
- DOH *q = 0;
- q = SwigType_parm(element);
- Insert(result,0," ");
- Insert(result,0,q);
- Delete(q);
+ } else if (SwigType_isenum(element)) {
+ String *bs = SwigType_namestr(element);
+ Insert(result,0,bs);
+ Delete(bs);
clear = 0;
} else {
+ String *bs = SwigType_namestr(element);
Insert(result,0," ");
- Insert(result,0,element);
+ Insert(result,0,bs);
+ Delete(bs);
}
element = nextelement;
}
@@ -995,14 +1428,14 @@ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) {
cast = NewStringf("(%s)",result);
}
if (name) {
- if (SwigType_isreference(s)) {
+ if (isreference) {
Append(cast,"*");
}
Append(cast,name);
}
Delete(result);
Delete(tc);
- return Swig_temp_result(cast);
+ return cast;
}
@@ -1020,659 +1453,156 @@ String *SwigType_lcaststr(SwigType *s, const String_or_char *name) {
if (SwigType_isarray(s)) {
Printf(result,"(%s)%s", SwigType_lstr(s,0),name);
} else if (SwigType_isreference(s)) {
- Printf(result,"(%s)", SwigType_lstr(s,0));
+ Printf(result,"(%s)", SwigType_str(s,0));
if (name)
- Printf(result,"&%s", name);
+ Printf(result,"%s", name);
} else if (SwigType_isqualifier(s)) {
Printf(result,"(%s)%s", SwigType_lstr(s,0),name);
} else {
if (name)
Append(result,name);
}
- return Swig_temp_result(result);
+ return result;
}
String *SwigType_manglestr_default(SwigType *s) {
char *c;
- String *result;
+ String *result,*base;
+ SwigType *lt;
+ SwigType *ss = 0;
+
+ if (SwigType_istemplate(s)) {
+ ss = SwigType_typedef_resolve_all(s);
+ s = ss;
+ }
+ lt = SwigType_ltype(s);
+ result = SwigType_prefix(lt);
+ base = SwigType_base(lt);
- if (SwigType_istypedef(s))
- result = Copy(s);
- else
- result = SwigType_ltype(s);
- Replace(result,"struct ","", DOH_REPLACE_ANY);
- Replace(result,"class ","", DOH_REPLACE_ANY);
- Replace(result,"union ","", DOH_REPLACE_ANY);
c = Char(result);
while (*c) {
- if (!isalnum(*c)) *c = '_';
+ if (!isalnum((int)*c)) *c = '_';
c++;
}
- Insert(result,0,"_");
- return Swig_temp_result(result);
-}
-
-String *SwigType_manglestr(SwigType *s) {
- return SwigType_manglestr_default(s);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_strip_qualifiers()
- *
- * Rips all qualifiers out of a type.
- * ----------------------------------------------------------------------------- */
-
-void SwigType_strip_qualifiers(SwigType *ty) {
- /* Sick hack alert */
- Replace(ty,"q(const).","", DOH_REPLACE_ANY);
- Replace(ty,"q(volatile).", "", DOH_REPLACE_ANY);
-}
-
-/* -----------------------------------------------------------------------------
- * Scope handling
- *
- * These functions are used to manipulate typedefs and scopes.
- * ----------------------------------------------------------------------------- */
-
-#define MAX_SCOPE 8
-
-static Hash *type_scopes = 0; /* Hash table of scope names */
-static Hash *scopes[MAX_SCOPE]; /* List representing the current scope */
-static String *scopenames[MAX_SCOPE]; /* Names of the various scopes */
-static int scope_level = 0;
-
-static void init_scopes() {
- if (type_scopes) return;
- type_scopes = NewHash();
- scopes[scope_level] = NewHash();
- scopenames[scope_level] = NewString("::");
- Setattr(type_scopes,"::",scopes[scope_level]);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_typedef()
- *
- * Defines a new typedef. Returns -1 if the type name is already defined.
- * ----------------------------------------------------------------------------- */
-
-int SwigType_typedef(SwigType *type, String_or_char *name) {
- int i;
- String *qname;
- init_scopes();
- if (Getattr(scopes[scope_level],name)) return -1;
- if (Cmp(type,name) == 0) {
- return 0;
- }
- i = scope_level;
- qname = NewString(name);
- while (i >= 0) {
- String *sname;
- /* Printf(stdout,"Adding typedef [%d] : '%s' -> '%s'\n", i, qname, type); */
- Setattr(scopes[i],qname,type);
- if (i > 0) {
- sname = scopenames[i];
- if (sname) {
- qname = NewStringf("%s::%s",sname,qname);
- }
- }
- i--;
- }
-
- /* Setattr(scopes[scope_level],name,type); */
- /* Need to modify this to include all scopes */
-
- if (default_cache)
- Delattr(default_cache,type);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_new_scope()
- *
- * Creates a new scope
- * ----------------------------------------------------------------------------- */
-
-void SwigType_new_scope() {
- init_scopes();
- scope_level++;
- scopes[scope_level] = NewHash();
- scopenames[scope_level] = NewString("");
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_reset_scopes()
- *
- * Reset the scope system
- * ----------------------------------------------------------------------------- */
-
-void SwigType_reset_scopes() {
- Delete(type_scopes);
- type_scopes = 0;
- init_scopes();
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_set_scope_name()
- *
- * Set the name of the current scope. Note: this will create an entry in the
- * type_scopes hash.
- * ----------------------------------------------------------------------------- */
-
-void SwigType_set_scope_name(String_or_char *name) {
- String *key;
- int i;
- init_scopes();
- scopenames[scope_level] = NewString(Char(name));
- key = NewString("");
- for (i = 1; i <= scope_level; i++) {
- Append(key,scopenames[scope_level]);
- if (i < scope_level) Append(key,"::");
- }
- Setattr(type_scopes,key,scopes[scope_level]);
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_merge_scope()
- *
- * Merges the contents of one scope into the current scope.
- * ----------------------------------------------------------------------------- */
-
-void SwigType_merge_scope(Hash *scope, String *prefix) {
- String *name;
- String *key;
- String *type;
-
- init_scopes();
- key = Firstkey(scope);
- while (key) {
- type = Getattr(scope,key);
- if (prefix) {
- name = NewStringf("%s::%s",prefix,key);
- } else {
- name = NewString(key);
- }
- SwigType_typedef(type,name);
- key = Nextkey(scope);
- }
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_pop_scope()
- *
- * Pop off the last scope. Returns the hash table for the scope that was popped off.
- * ----------------------------------------------------------------------------- */
-
-Hash *SwigType_pop_scope() {
- Hash *s;
- String *prefix;
- init_scopes();
- if (scope_level == 0) return 0;
- prefix = scopenames[scope_level];
- s = scopes[scope_level--];
- if (Len(s)) return s;
- Delete(s);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_typedef_resolve()
- *
- * Resolves a typedef and returns a new type string. Returns 0 if there is no
- * typedef mapping.
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_typedef_resolve(SwigType *t) {
- String *base;
- String *type;
- String *r;
- int level;
-
- init_scopes();
- base = SwigType_base(t);
- level = scope_level;
- while (level >= 0) {
- /* See if we know about this type */
- type = Getattr(scopes[level],base);
- if (type) break;
- level--;
- }
- if (level < 0) {
- return 0;
+ if (SwigType_istemplate(base)) {
+ String *b = SwigType_namestr(base);
+ Delete(base);
+ base = b;
}
- r = SwigType_prefix(t);
- Append(r,type);
- return r;
-}
-/* -----------------------------------------------------------------------------
- * SwigType_typedef_resolve_all()
- *
- * Fully resolve a type down to its most basic datatype
- * ----------------------------------------------------------------------------- */
-
-SwigType *SwigType_typedef_resolve_all(SwigType *t) {
- SwigType *n;
- SwigType *r = Copy(t);
-
- while ((n = SwigType_typedef_resolve(r))) {
- Delete(r);
- r = n;
- }
- return r;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_istypedef()
- *
- * Checks a typename to see if it is a typedef.
- * ----------------------------------------------------------------------------- */
+ Replace(base,"struct ","", DOH_REPLACE_ANY); /* This might be problematic */
+ Replace(base,"class ","", DOH_REPLACE_ANY);
+ Replace(base,"union ","", DOH_REPLACE_ANY);
-int SwigType_istypedef(SwigType *t) {
- String *base, *type;
- int level;
-
- init_scopes();
- base = SwigType_base(t);
- level = scope_level;
- while (level >= 0) {
- /* See if we know about this type */
- type = Getattr(scopes[level],base);
- if (type) {
- return 1;
- }
- level--;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_cmp()
- *
- * Compares two type-strings using all available typedef information. Returns 0
- * if equal, 1 if not.
- * ----------------------------------------------------------------------------- */
-
-int SwigType_cmp(SwigType *tpat, SwigType *type) {
- String *r, *s;
- char *p, *t;
-
- p = Char(tpat);
- t = Char(type);
-
- if (strcmp(p,t) == 0) return 0;
-
- r = SwigType_typedef_resolve(type);
- while (r) {
- t = Char(r);
- if (strcmp(p,t) == 0) {
- Delete(r);
- return 0;
- }
- s = SwigType_typedef_resolve(r);
- Delete(r);
- r = s;
- }
- return 1;
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_type()
- *
- * Returns an integer code describing the datatype. This is only used for
- * compatibility with SWIG1.1 language modules and is likely to go away once
- * everything is based on typemaps.
- * ----------------------------------------------------------------------------- */
-
-int SwigType_type(SwigType *t)
-{
- char *c;
- /* Check for the obvious stuff */
- c = Char(t);
-
- if (strncmp(c,"p.",2) == 0) {
- if (SwigType_type(c+2) == T_CHAR) return T_STRING;
- else return T_POINTER;
- }
- if (strncmp(c,"a(",2) == 0) return T_ARRAY;
- if (strncmp(c,"r.",2) == 0) return T_REFERENCE;
-
- if (strncmp(c,"q(",2) == 0) {
- while(*c && (*c != '.')) c++;
- if (*c) return SwigType_type(c+1);
- return T_ERROR;
+ c = Char(base);
+ while (*c) {
+ if (*c == '<') *c = 'T';
+ else if (*c == '>') *c = 't';
+ else if (*c == '*') *c = 'p';
+ else if (*c == '[') *c = 'a';
+ else if (*c == ']') *c = 'A';
+ else if (*c == '&') *c = 'R';
+ else if (*c == '(') *c = 'f';
+ else if (*c == ')') *c = 'F';
+ else if (!isalnum((int)*c)) *c = '_';
+ c++;
}
- if (strncmp(c,"f(",2) == 0) return T_FUNCTION;
-
- /* Look for basic types */
- if (strcmp(c,"int") == 0) return T_INT;
- if (strcmp(c,"long") == 0) return T_LONG;
- if (strcmp(c,"short") == 0) return T_SHORT;
- if (strcmp(c,"unsigned") == 0) return T_UINT;
- if (strcmp(c,"unsigned short") == 0) return T_USHORT;
- if (strcmp(c,"unsigned long") == 0) return T_ULONG;
- if (strcmp(c,"unsigned int") == 0) return T_UINT;
- if (strcmp(c,"char") == 0) return T_CHAR;
- if (strcmp(c,"signed char") == 0) return T_SCHAR;
- if (strcmp(c,"unsigned char") == 0) return T_UCHAR;
- if (strcmp(c,"float") == 0) return T_FLOAT;
- if (strcmp(c,"double") == 0) return T_DOUBLE;
- if (strcmp(c,"void") == 0) return T_VOID;
- if (strcmp(c,"bool") == 0) return T_BOOL;
- if (strncmp(c,"enum ",5) == 0) return T_INT;
- /* Hmmm. Unknown type */
- if (SwigType_istypedef(t)) {
- int r;
- SwigType *nt = SwigType_typedef_resolve(t);
- r = SwigType_type(nt);
- Delete(nt);
- return r;
- }
- return T_USER;
+ Append(result,base);
+ Insert(result,0,"_");
+ Delete(lt);
+ Delete(base);
+ if (ss) Delete(ss);
+ return result;
}
-/* -----------------------------------------------------------------------------
- * SwigType_remember()
- *
- * This function "remembers" a datatype that was used during wrapper code generation
- * so that a type-checking table can be generated later on. It is up to the language
- * modules to actually call this function--it is not done automatically.
- *
- * Type tracking is managed through two separate hash tables. The hash 'r_mangled'
- * is mapping between mangled type names (used in the target language) and
- * fully-resolved C datatypes used in the source input. The second hash 'r_resolved'
- * is the inverse mapping that maps fully-resolved C datatypes to all of the mangled
- * names in the scripting languages. For example, consider the following set of
- * typedef declarations:
- *
- * typedef double Real;
- * typedef double Float;
- * typedef double Point[3];
- *
- * Now, suppose that the types 'double *', 'Real *', 'Float *', 'double[3]', and
- * 'Point' were used in an interface file and "remembered" using this function.
- * The hash tables would look like this:
- *
- * r_mangled {
- * _p_double : [ p.double, a(3).double ]
- * _p_Real : [ p.double ]
- * _p_Float : [ p.double ]
- * _Point : [ a(3).double ]
- *
- * r_resolved {
- * p.double : [ _p_double, _p_Real, _p_Float ]
- * a(3).double : [ _p_double, _Point ]
- * }
- *
- * Together these two hash tables can be used to determine type-equivalency between
- * mangled typenames. To do this, we view the two hash tables as a large graph and
- * compute the transitive closure.
- * ----------------------------------------------------------------------------- */
-
-static Hash *r_mangled = 0; /* Hash mapping mangled types to fully resolved types */
-static Hash *r_resolved = 0; /* Hash mapping resolved types to mangled types */
-static Hash *r_ltype = 0; /* Hash mapping mangled names to their local c type */
-
-void SwigType_remember(SwigType *t) {
- String *mt;
- SwigType *lt;
- Hash *h;
- SwigType *fr;
-
- if (!r_mangled) {
- r_mangled = NewHash();
- r_resolved = NewHash();
- r_ltype = NewHash();
- }
-
- mt = SwigType_manglestr(t); /* Create mangled string */
- if (SwigType_istypedef(t))
- lt = Copy(t);
- else
- lt = SwigType_ltype(t);
- Setattr(r_ltype, mt, lt);
- fr = SwigType_typedef_resolve_all(t); /* Create fully resolved type */
- h = Getattr(r_mangled,mt);
- if (!h) {
- h = NewHash();
- Setattr(r_mangled,mt,h);
- Delete(h);
- }
- Setattr(h,fr,mt);
-
- h = Getattr(r_resolved, fr);
- if (!h) {
- h = NewHash();
- Setattr(r_resolved,fr,h);
- Delete(h);
- }
- Setattr(h,mt,fr);
+String *SwigType_manglestr(SwigType *s) {
+ return SwigType_manglestr_default(s);
}
/* -----------------------------------------------------------------------------
- * SwigType_equivalent_mangle()
+ * SwigType_typename_replace()
*
- * Return a list of all of the mangled typenames that are equivalent to another
- * mangled name. This works as follows: For each fully qualified C datatype
- * in the r_mangled hash entry, we collect all of the mangled names from the
- * r_resolved hash and combine them together in a list (removing duplicate entries).
+ * Replaces a typename in a type with something else. Needed for templates.
* ----------------------------------------------------------------------------- */
-List *SwigType_equivalent_mangle(String *ms, Hash *checked, Hash *found) {
- List *l;
- Hash *h;
- Hash *ch;
- Hash *mh;
-
- if (found) {
- h = found;
- } else {
- h = NewHash();
- }
- if (checked) {
- ch = checked;
- } else {
- ch = NewHash();
- }
- if (Getattr(ch,ms)) goto check_exit; /* Already checked this type */
- Setattr(h,ms,"1");
- Setattr(ch, ms, "1");
- mh = Getattr(r_mangled,ms);
- if (mh) {
- String *key;
- key = Firstkey(mh);
- while (key) {
- Hash *rh;
- if (Getattr(ch,key)) {
- key = Nextkey(mh);
- continue;
- }
- Setattr(ch,key,"1");
- rh = Getattr(r_resolved,key);
- if (rh) {
- String *rkey;
- rkey = Firstkey(rh);
- while (rkey) {
- Setattr(h,rkey,"1");
- SwigType_equivalent_mangle(rkey,ch,h);
- rkey = Nextkey(rh);
+void
+SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
+ String *nt;
+ int i;
+ List *elem;
+
+ if (!Strstr(t,pat)) return;
+
+ if (Strcmp(t,pat) == 0) {
+ Replace(t,pat,rep,DOH_REPLACE_ANY);
+ return;
+ }
+ nt = NewString("");
+ elem = SwigType_split(t);
+ for (i = 0; i < Len(elem); i++) {
+ String *e = Getitem(elem,i);
+ if (SwigType_issimple(e)) {
+ if (Strcmp(e,pat) == 0) {
+ /* Replaces a type of the form 'pat' with 'rep<args>' */
+ Replace(e,pat,rep,DOH_REPLACE_ANY);
+ } else if (SwigType_istemplate(e)) {
+ /* Replaces a type of the form 'pat<args>' with 'rep' */
+ if (Strncmp(e,pat,Len(pat)) == 0) {
+ String *repbase = SwigType_templateprefix(rep);
+ Replace(e,pat,repbase,DOH_REPLACE_ID | DOH_REPLACE_FIRST);
+ Delete(repbase);
+ }
+ {
+ List *tparms = SwigType_parmlist(e);
+ int j;
+ String *nt = SwigType_templateprefix(e);
+ Printf(nt,"<(");
+ for (j = 0; j < Len(tparms); j++) {
+ SwigType_typename_replace(Getitem(tparms,j), pat, rep);
+ Printf(nt,"%s",Getitem(tparms,j));
+ if (j < (Len(tparms)-1)) Printf(nt,",");
+ }
+ Printf(nt,")>%s", SwigType_templatesuffix(e));
+ Clear(e);
+ Append(e,nt);
+ Delete(nt);
}
}
- key = Nextkey(mh);
- }
- }
- check_exit:
- if (!found) {
- l = Hash_keys(h);
- Delete(h);
- Delete(ch);
- return l;
- } else {
- return 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_inherit()
- *
- * Record information about inheritance. We keep a hash table that keeps
- * a mapping between base classes and all of the classes that are derived
- * from them.
- *
- * subclass is a hash that maps base-classes to all of the classes derived from them.
- * ----------------------------------------------------------------------------- */
-
-static Hash *subclass = 0;
-static Hash *conversions = 0;
-
-void
-SwigType_inherit(String *derived, String *base) {
- Hash *h;
- if (!subclass) subclass = NewHash();
-
- h = Getattr(subclass,base);
- if (!h) {
- h = NewHash();
- Setattr(subclass,base,h);
- }
- Setattr(h,derived,"1");
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_inherit_equiv()
- *
- * Modify the type table to handle C++ inheritance
- * ----------------------------------------------------------------------------- */
-
-void SwigType_inherit_equiv(File *out) {
- String *rkey, *bkey, *ckey;
- String *prefix, *base;
-
- Hash *sub;
- Hash *rh;
-
- if (!conversions) conversions = NewHash();
- if (!subclass) subclass = NewHash();
-
- rkey = Firstkey(r_resolved);
- while (rkey) {
- /* rkey is actually a fully qualified type */
-
- base = SwigType_base(rkey);
- sub = Getattr(subclass,base);
- if (!sub) {
- rkey = Nextkey(r_resolved);
- continue;
- }
-
- rh = Getattr(r_resolved, rkey);
-
- /* Hmmm. We actually got a base-class match. We're going to try and patch things up */
- bkey = Firstkey(sub);
- while (bkey) {
- prefix= SwigType_prefix(rkey);
- Append(prefix,bkey);
- Setattr(rh,SwigType_manglestr(prefix),prefix);
-
- ckey = NewStringf("%s+%s",SwigType_manglestr(prefix), SwigType_manglestr(rkey));
- if (!Getattr(conversions,ckey)) {
- Printf(out,"static void *%sTo%s(void *x) {\n", SwigType_manglestr(prefix), SwigType_manglestr(rkey));
- Printf(out," return (void *)((%s) ((%s) x));\n", SwigType_lstr(rkey,0), SwigType_lstr(prefix,0));
- Printf(out,"}\n");
- SetInt(conversions,ckey,1);
+ } else if (SwigType_isfunction(e)) {
+ int j;
+ List *fparms = SwigType_parmlist(e);
+ Clear(e);
+ Printf(e,"f(");
+ for (j = 0; j < Len(fparms); j++) {
+ SwigType_typename_replace(Getitem(fparms,j), pat, rep);
+ Printf(e,"%s",Getitem(fparms,j));
+ if (j < (Len(fparms)-1)) Printf(e,",");
}
- Delete(ckey);
- Delete(prefix);
- bkey = Nextkey(sub);
+ Printf(e,").");
}
- rkey = Nextkey(r_resolved);
+ Append(nt,e);
}
+ Clear(t);
+ Append(t,nt);
}
/* -----------------------------------------------------------------------------
- * SwigType_type_table()
+ * SwigType_check_decl()
*
- * Generate the type-table for the type-checker.
+ * Checks type declarators for a match
* ----------------------------------------------------------------------------- */
-void
-SwigType_emit_type_table(File *f_forward, File *f_table) {
- DOH *key;
- String *types, *table;
- int i = 0;
-
- if (!r_mangled) {
- r_mangled = NewHash();
- r_resolved = NewHash();
- }
-
- Printf(f_table,"\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */\n\n");
-
- SwigType_inherit_equiv(f_table);
-
-#ifdef DEBUG
- Printf(stdout,"---r_mangled---\n");
- Printf(stdout,"%s\n", r_mangled);
-
- Printf(stdout,"---r_resolved---\n");
- Printf(stdout,"%s\n", r_resolved);
-
- Printf(stdout,"---r_ltype---\n");
- Printf(stdout,"%s\n", r_ltype);
-
- Printf(stdout,"---subclass---\n");
- Printf(stdout,"%s\n", subclass);
-
- Printf(stdout,"---scopes[0]---\n");
- Printf(stdout,"%s\n", scopes[0]);
-
-#endif
- table = NewString("");
- types = NewString("");
- Printf(table,"static swig_type_info *swig_types_initial[] = {\n");
- key = Firstkey(r_mangled);
- Printf(f_forward,"\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n");
- while (key) {
- List *el;
- String *en;
- Printf(f_forward,"#define SWIGTYPE%s swig_types[%d] \n", key, i);
- Printv(types,"static swig_type_info _swigt_", key, "[] = {", 0);
- Printv(types,"{\"", key, "\", 0, \"", SwigType_str(Getattr(r_ltype,key),0),"\"},", 0);
- el = SwigType_equivalent_mangle(key,0,0);
- for (en = Firstitem(el); en; en = Nextitem(el)) {
- String *ckey;
- ckey = NewStringf("%s+%s", en, key);
- if (Getattr(conversions,ckey)) {
- Printf(types,"{\"%s\", %sTo%s},", en, en, key);
- } else {
- Printf(types,"{\"%s\"},", en);
- }
- Delete(ckey);
- }
- Delete(el);
- Printf(types,"{0}};\n");
- Printv(table, "_swigt_", key, ", \n", 0);
- key = Nextkey(r_mangled);
- i++;
- }
-
- Printf(table, "0\n};\n");
- Printf(f_forward,"static swig_type_info *swig_types[%d];\n", i+1);
- Printf(f_forward,"\n/* -------- TYPES TABLE (END) -------- */\n\n");
- Printf(f_table,"%s\n", types);
- Printf(f_table,"%s\n", table);
- Printf(f_table,"\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */\n\n");
- Delete(types);
- Delete(table);
+int
+SwigType_check_decl(SwigType *ty, const SwigType *decl) {
+ SwigType *t,*t1,*t2;
+ int r;
+ t = SwigType_typedef_resolve_all(ty);
+ t1 = SwigType_strip_qualifiers(t);
+ t2 = SwigType_prefix(t1);
+ r = Cmp(t2,decl);
+ Delete(t);
+ Delete(t1);
+ Delete(t2);
+ if (r == 0) return 1;
+ return 0;
}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
index 3012d2cc4..604c62a9d 100644
--- a/Source/Swig/swig.h
+++ b/Source/Swig/swig.h
@@ -22,6 +22,12 @@
#include "doh.h"
+/* Status codes */
+
+#define SWIG_OK 1
+#define SWIG_ERROR 0
+#define SWIG_NOWRAP 0
+
/* Short names for common data types */
typedef DOH String;
@@ -32,30 +38,46 @@ typedef DOH File;
typedef DOH Parm;
typedef DOH ParmList;
typedef DOH Node;
+typedef DOH Symtab;
+typedef DOH Typetab;
+typedef DOH SwigType;
/* --- Legacy DataType interface. These type codes are provided solely
- for backwards compatibility with older modules --- */
+ for backwards compatibility with older modules --- */
+
+/* --- The ordering of type values is used to determine type-promotion
+ in the parser. Do not change */
-#define T_INT 1
-#define T_SHORT 2
-#define T_LONG 3
-#define T_UINT 4
+/* Numeric types */
+
+#define T_BOOL 1
+#define T_SCHAR 2
+#define T_UCHAR 3
+#define T_SHORT 4
#define T_USHORT 5
-#define T_ULONG 6
-#define T_UCHAR 7
-#define T_SCHAR 8
-#define T_BOOL 9
-#define T_DOUBLE 10
-#define T_FLOAT 11
-#define T_CHAR 12
-#define T_USER 13
-#define T_VOID 14
-#define T_ENUM 15
-#define T_STRING 20
-#define T_POINTER 21
-#define T_REFERENCE 22
-#define T_ARRAY 23
-#define T_FUNCTION 24
+#define T_ENUM 6
+#define T_INT 7
+#define T_UINT 8
+#define T_LONG 9
+#define T_ULONG 10
+#define T_LONGLONG 11
+#define T_ULONGLONG 12
+#define T_FLOAT 20
+#define T_DOUBLE 21
+#define T_NUMERIC 22
+
+/* non-numeric */
+
+#define T_CHAR 30
+#define T_USER 31
+#define T_VOID 32
+#define T_STRING 33
+#define T_POINTER 34
+#define T_REFERENCE 35
+#define T_ARRAY 36
+#define T_FUNCTION 37
+#define T_MPOINTER 38
+#define T_VARARGS 39
#define T_SYMBOL 98
#define T_ERROR 99
@@ -68,20 +90,21 @@ extern FILE *Swig_open(const String_or_char *name);
extern String *Swig_read_file(FILE *f);
extern String *Swig_include(const String_or_char *name);
extern int Swig_insert_file(const String_or_char *name, File *outfile);
-extern int Swig_bytes_read();
-extern void Swig_register_filebyname(const String_or_char *name, File *outfile);
-extern File *Swig_filebyname(const String_or_char *name);
-extern void Swig_swiglib_set(const String_or_char *name);
+extern void Swig_set_config_file(const String_or_char *filename);
+extern String *Swig_get_config_file(void);
+extern void Swig_swiglib_set(const String_or_char *);
extern String *Swig_swiglib_get();
-extern void Swig_set_config_file(const String_or_char *name);
-extern String *Swig_get_config_file();
-
-#define OUTFILE(x) Swig_filebyname(x)
+extern void Swig_register_filebyname(const String_or_char *filename, File *outfile);
+extern File *Swig_filebyname(const String_or_char *filename);
+extern char *Swig_file_suffix(const String_or_char *filename);
+extern char *Swig_file_basename(const String_or_char *filename);
+extern char *Swig_file_filename(const String_or_char *filename);
+extern char *Swig_file_dirname(const String_or_char *filename);
#ifdef MACSWIG
-#define SWIG_FILE_DELIMETER ":"
+# define SWIG_FILE_DELIMETER ":"
#else
-#define SWIG_FILE_DELIMETER "/"
+# define SWIG_FILE_DELIMETER "/"
#endif
/* --- Command line parsing --- */
@@ -159,23 +182,29 @@ extern void SwigScanner_idstart(SwigScanner *, char *idchar);
#define SWIG_TOKEN_DOLLAR 46
#define SWIG_TOKEN_CODEBLOCK 47
#define SWIG_TOKEN_RSTRING 48
+#define SWIG_TOKEN_LONGLONG 49
+#define SWIG_TOKEN_ULONGLONG 50
#define SWIG_TOKEN_ILLEGAL 98
#define SWIG_TOKEN_LAST 99
/* --- Functions for manipulating the string-based type encoding --- */
-typedef DOH SwigType;
extern SwigType *NewSwigType(int typecode);
extern void SwigType_add_pointer(SwigType *t);
+extern void SwigType_add_memberpointer(SwigType *t, String_or_char *qual);
extern void SwigType_del_pointer(SwigType *t);
extern void SwigType_add_array(SwigType *t, String_or_char *size);
+extern SwigType *SwigType_pop_arrays(SwigType *t);
extern void SwigType_add_reference(SwigType *t);
extern void SwigType_add_qualifier(SwigType *t, String_or_char *qual);
extern void SwigType_add_function(SwigType *t, ParmList *parms);
+extern void SwigType_add_template(SwigType *t, ParmList *parms);
+extern SwigType *SwigType_pop_function(SwigType *t);
+extern ParmList *SwigType_function_parms(SwigType *t);
extern List *SwigType_split(SwigType *t);
extern String *SwigType_pop(SwigType *t);
extern void SwigType_push(SwigType *t, SwigType *s);
-extern List *SwigType_parmlist(SwigType *p);
+extern List *SwigType_parmlist(const SwigType *p);
extern String *SwigType_parm(String *p);
extern String *SwigType_str(SwigType *s, const String_or_char *id);
extern String *SwigType_lstr(SwigType *s, const String_or_char *id);
@@ -184,35 +213,84 @@ extern String *SwigType_lcaststr(SwigType *s, const String_or_char *id);
extern String *SwigType_manglestr(SwigType *t);
extern SwigType *SwigType_ltype(SwigType *t);
extern int SwigType_ispointer(SwigType *t);
+extern int SwigType_ismemberpointer(SwigType *t);
extern int SwigType_isreference(SwigType *t);
extern int SwigType_isarray(SwigType *t);
extern int SwigType_isfunction(SwigType *t);
extern int SwigType_isqualifier(SwigType *t);
extern int SwigType_isconst(SwigType *t);
-
+extern int SwigType_issimple(SwigType *t);
+extern int SwigType_ismutable(SwigType *t);
+extern int SwigType_isvarargs(const SwigType *t);
+extern int SwigType_istemplate(const SwigType *t);
+extern int SwigType_isenum(SwigType *t);
+extern int SwigType_check_decl(SwigType *t, const String_or_char *decl);
+extern SwigType *SwigType_strip_qualifiers(SwigType *t);
extern String *SwigType_base(SwigType *t);
+extern String *SwigType_namestr(const SwigType *t);
+extern String *SwigType_templateprefix(SwigType *t);
+extern String *SwigType_templatesuffix(const SwigType *t);
+extern String *SwigType_templateargs(SwigType *t);
extern String *SwigType_prefix(SwigType *t);
-extern void SwigType_setbase(SwigType *t, String_or_char *name);
+extern int SwigType_array_ndim(SwigType *t);
+extern String *SwigType_array_getdim(SwigType *t, int n);
+extern void SwigType_array_setdim(SwigType *t, int n, String_or_char *rep);
+extern SwigType *SwigType_array_type(SwigType *t);
+extern String *SwigType_default(SwigType *t);
+extern void SwigType_typename_replace(SwigType *t, String *pat, String *rep);
+/* --- Type-system managment --- */
+extern void SwigType_typesystem_init();
extern int SwigType_typedef(SwigType *type, String_or_char *name);
-extern void SwigType_inherit(String *subclass, String *baseclass);
-extern void SwigType_new_scope();
+extern int SwigType_typedef_class(String_or_char *name);
+extern int SwigType_typedef_using(String_or_char *qname);
+extern void SwigType_inherit(String *subclass, String *baseclass, String *cast);
+extern int SwigType_issubtype(SwigType *subtype, SwigType *basetype);
+extern void SwigType_scope_alias(String *aliasname, Typetab *t);
+extern void SwigType_using_scope(Typetab *t);
+extern void SwigType_new_scope(String_or_char *name);
extern void SwigType_reset_scopes();
extern void SwigType_set_scope_name(String_or_char *name);
-extern void SwigType_merge_scope(Hash *scope, String *prefix);
-extern Hash *SwigType_pop_scope();
+extern void SwigType_inherit_scope(Typetab *scope);
+extern Typetab *SwigType_pop_scope();
+extern Typetab *SwigType_set_scope(Typetab *h);
+extern void SwigType_print_scope(Typetab *t);
extern SwigType *SwigType_typedef_resolve(SwigType *t);
extern SwigType *SwigType_typedef_resolve_all(SwigType *t);
+extern SwigType *SwigType_typedef_qualified(SwigType *t);
extern int SwigType_istypedef(SwigType *t);
-extern int SwigType_cmp(String_or_char *pat, SwigType *t);
-extern int SwigType_array_ndim(SwigType *t);
-extern String *SwigType_array_getdim(SwigType *t, int n);
-extern void SwigType_array_setdim(SwigType *t, int n, String_or_char *rep);
-extern String *SwigType_default(SwigType *t);
-extern int SwigType_type(SwigType *t);
+extern int SwigType_isclass(SwigType *t);
+extern void SwigType_attach_symtab(Symtab *syms);
extern void SwigType_remember(SwigType *t);
+extern void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata);
+extern void (*SwigType_remember_trace(void (*tf)(SwigType *, String *, String *)))(SwigType *, String *, String *);
extern void SwigType_emit_type_table(File *f_headers, File *f_table);
-extern void SwigType_strip_qualifiers(SwigType *t);
+extern int SwigType_type(SwigType *t);
+
+/* --- Symbol table module --- */
+
+extern void Swig_symbol_init();
+extern void Swig_symbol_setscopename(const String_or_char *name);
+extern String *Swig_symbol_getscopename();
+extern String *Swig_symbol_qualifiedscopename(Symtab *symtab);
+extern Symtab *Swig_symbol_newscope();
+extern Symtab *Swig_symbol_setscope(Symtab *);
+extern Symtab *Swig_symbol_getscope(const String_or_char *symname);
+extern Symtab *Swig_symbol_current();
+extern Symtab *Swig_symbol_popscope();
+extern Node *Swig_symbol_add(String_or_char *symname, Node *node);
+extern void Swig_symbol_cadd(String_or_char *symname, Node *node);
+extern Node *Swig_symbol_clookup(String_or_char *symname, Symtab *tab);
+extern Symtab *Swig_symbol_cscope(String_or_char *symname, Symtab *tab);
+extern Node *Swig_symbol_clookup_local(String_or_char *symname, Symtab *tab);
+extern String *Swig_symbol_qualified(Node *node);
+extern Node *Swig_symbol_isoverloaded(Node *node);
+extern void Swig_symbol_remove(Node *node);
+extern void Swig_symbol_alias(String_or_char *aliasname, Symtab *tab);
+extern void Swig_symbol_inherit(Symtab *tab);
+extern SwigType *Swig_symbol_type_qualify(SwigType *ty, Symtab *tab);
+extern String *Swig_symbol_string_qualify(String *s, Symtab *tab);
+extern SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab);
/* --- Parameters and Parameter Lists --- */
@@ -221,58 +299,63 @@ extern void SwigType_strip_qualifiers(SwigType *t);
extern Parm *NewParm(SwigType *type, String_or_char *n);
extern Parm *CopyParm(Parm *p);
-
-
-
extern ParmList *CopyParmList(ParmList *);
extern int ParmList_len(ParmList *);
extern int ParmList_numarg(ParmList *);
+extern int ParmList_numrequired(ParmList *);
extern String *ParmList_str(ParmList *);
extern String *ParmList_protostr(ParmList *);
/* --- Parse tree support --- */
-typedef struct {
- const char *name;
- int (*action)(DOH *obj, void *clientdata);
-} SwigRule;
-
-
-#define SWIG_OK 1
-#define SWIG_NORULE 0
-#define SWIG_ERROR -1
-
-extern void Swig_add_rule(const String_or_char *, int (*action)(DOH *, void *));
-extern void Swig_add_rules(SwigRule ruleset[]);
-extern void Swig_clear_rules();
-extern int Swig_tag_check(DOH *obj, const String_or_char *tagname);
-extern int Swig_emit(DOH *obj, void *clientdata);
-extern int Swig_emit_all(DOH *obj, void *clientdata);
-extern void Swig_set_callback(DOH *obj, void (*cb)(void *clientdata), void *clientdata);
-extern void (*Swig_set_trace(DOH *obj, void (*cb)(DOH *, DOH *), DOH *arg))(DOH *, DOH *);
-extern void Swig_remove_trace(DOH *obj);
-extern void Swig_node_cut(DOH *obj);
-extern void Swig_node_insert(DOH *node, DOH *newnode);
-extern void Swig_node_temporary(DOH *node);
-extern void Swig_node_ignore(DOH *node);
-extern void Swig_node_append_child(DOH *node, DOH *cld);
-extern int Swig_count_nodes(DOH *node);
-
-extern DOH *Swig_next(DOH *obj);
-extern DOH *Swig_prev(DOH *obj);
+/* DOM-like node access */
+
+#define nodeType(x) Getattr(x,"nodeType")
+#define parentNode(x) Getattr(x,"parentNode")
+#define previousSibling(x) Getattr(x,"previousSibling")
+#define nextSibling(x) Getattr(x,"nextSibling")
+#define firstChild(x) Getattr(x,"firstChild")
+#define lastChild(x) Getattr(x,"lastChild")
+extern int checkAttribute(Node *obj, const String_or_char *name, const String_or_char *value);
+
+/* Macros to set up the DOM tree (mostly used by the parser) */
+
+#define set_nodeType(x,v) Setattr(x,"nodeType",v)
+#define set_parentNode(x,v) Setattr(x,"parentNode",v)
+#define set_previousSibling(x,v) Setattr(x,"previousSibling",v)
+#define set_nextSibling(x,v) Setattr(x,"nextSibling",v)
+#define set_firstChild(x,v) Setattr(x,"firstChild",v)
+#define set_lastChild(x,v) Setattr(x,"lastChild",v)
+
+extern void appendChild(Node *node, Node *child);
+extern void deleteNode(Node *node);
+extern Node *copyNode(Node *node);
+
+extern void Swig_tag_nodes(Node *node, const String_or_char *attrname, DOH *value);
+
+extern int Swig_require(Node **node, ...);
+extern int Swig_save(Node **node,...);
+extern void Swig_restore(Node **node);
/* Debugging of parse trees */
extern void Swig_debug_emit(int);
-extern void Swig_dump_tags(DOH *obj, DOH *root);
-extern void Swig_dump_tree(DOH *obj);
-extern void Swig_dump_rules();
+extern void Swig_print_tags(File *obj, Node *root);
+extern void Swig_print_tree(Node *obj);
+extern void Swig_print_node(Node *obj);
/* -- Wrapper function Object */
-typedef DOH Wrapper;
+typedef struct {
+ Hash *localh;
+ String *def;
+ String *locals;
+ String *code;
+} Wrapper;
extern Wrapper *NewWrapper();
+extern void DelWrapper(Wrapper *w);
extern void Wrapper_pretty_print(String *str, File *f);
+extern void Wrapper_print(Wrapper *w, File *f);
extern int Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl);
extern int Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...);
extern int Wrapper_check_local(Wrapper *w, const String_or_char *name);
@@ -281,160 +364,115 @@ extern char *Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...)
/* --- Naming functions --- */
-extern void Swig_name_register(String_or_char *method, String_or_char *format);
-extern String *Swig_name_mangle(String_or_char *s);
-extern String *Swig_name_wrapper(String_or_char *fname);
-extern String *Swig_name_member(String_or_char *classname, String_or_char *mname);
-extern String *Swig_name_get(String_or_char *vname);
-extern String *Swig_name_set(String_or_char *vname);
-extern String *Swig_name_construct(String_or_char *classname);
-extern String *Swig_name_destroy(String_or_char *classname);
-
-/* --- Mapping interface --- */
-
-extern void Swig_map_add(Hash *ruleset, Hash *parms, DOH *obj);
-extern DOH *Swig_map_match(Hash *ruleset, Hash *parms, int *nmatch);
+extern void Swig_name_register(const String_or_char *method, const String_or_char *format);
+extern void Swig_name_unregister(const String_or_char *method);
+extern String *Swig_name_mangle(const String_or_char *s);
+extern String *Swig_name_wrapper(const String_or_char *fname);
+extern String *Swig_name_member(const String_or_char *classname, const String_or_char *mname);
+extern String *Swig_name_get(const String_or_char *vname);
+extern String *Swig_name_set(const String_or_char *vname);
+extern String *Swig_name_construct(const String_or_char *classname);
+extern String *Swig_name_copyconstructor(const String_or_char *classname);
+extern String *Swig_name_destroy(const String_or_char *classname);
+
+/* --- parameterized rename functions --- */
+
+extern void Swig_name_object_set(Hash *namehash, String_or_char *name, SwigType *decl, DOH *object);
+extern DOH *Swig_name_object_get(Hash *namehash, String_or_char *prefix, String_or_char *name, SwigType *decl);
+extern void Swig_name_object_inherit(Hash *namehash, String *base, String *derived);
+extern void Swig_features_get(Hash *features, String_or_char *prefix, String_or_char *name, SwigType *decl, Node *n);
+extern void Swig_feature_set(Hash *features, String_or_char *name, SwigType *decl, String_or_char *fname, String *value);
/* --- Misc --- */
extern char *Swig_copy_string(const char *c);
extern void Swig_banner(File *f);
-extern void Swig_section(File *f, const String_or_char *s);
-extern DOH *Swig_temp_result(DOH *x);
extern String *Swig_string_escape(String *s);
extern String *Swig_string_mangle(String *s);
+extern String *Swig_scopename_prefix(String *s);
+extern String *Swig_scopename_last(String *s);
+extern String *Swig_scopename_first(String *s);
+extern String *Swig_scopename_suffix(String *s);
+extern int Swig_scopename_check(String *s);
+
extern void Swig_init();
+extern void Swig_warn(const char *filename, int line, const char *msg);
+
+
+#define WARNING(msg) Swig_warn(__FILE__,__LINE__,msg)
-extern int Swig_proto_cmp(const String_or_char *pat, DOH *node);
+extern void Swig_warning(int num, const String_or_char *filename, int line, const char *fmt, ...);
+extern void Swig_error(const String_or_char *filename, int line, const char *fmt, ...);
+extern int Swig_error_count(void);
+extern void Swig_error_silent(int s);
+extern void Swig_warnfilter(const String_or_char *wlist, int val);
+extern void Swig_warnall(void);
+extern int Swig_warn_count(void);
/* --- C Wrappers --- */
-extern String *Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value);
-extern SwigType *Swig_clocal_type(SwigType *t);
-extern String *Swig_clocal_deref(SwigType *t, String_or_char *name);
-extern String *Swig_clocal_assign(SwigType *t, String_or_char *name);
extern String *Swig_cparm_name(Parm *p, int i);
+extern String *Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value);
+extern String *Swig_wrapped_var_type(SwigType *t);
+extern String *Swig_wrapped_var_deref(SwigType *t, String_or_char *name);
+extern String *Swig_wrapped_var_assign(SwigType *t, String_or_char *name);
extern int Swig_cargs(Wrapper *w, ParmList *l);
-extern void Swig_cresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char *decl);
-extern void Swig_cppresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_char *decl);
+extern String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_char *decl);
+
extern String *Swig_cfunction_call(String_or_char *name, ParmList *parms);
-extern String *Swig_cmethod_call(String_or_char *name, ParmList *parms);
+extern String *Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self);
extern String *Swig_cconstructor_call(String_or_char *name);
extern String *Swig_cppconstructor_call(String_or_char *name, ParmList *parms);
extern String *Swig_cdestructor_call();
extern String *Swig_cppdestructor_call();
-extern String *Swig_cmemberset_call(String_or_char *name, SwigType *t);
-extern String *Swig_cmemberget_call(String_or_char *name, SwigType *t);
-
-extern Wrapper *Swig_cfunction_wrapper(String_or_char *funcname,
- SwigType *rtype,
- ParmList *parms,
- String_or_char *code);
-
-extern Wrapper *Swig_cmethod_wrapper(String_or_char *classname,
- String_or_char *methodname,
- SwigType *rtype,
- ParmList *parms,
- String_or_char *code);
-
-extern Wrapper *Swig_cdestructor_wrapper(String_or_char *classname,
- String_or_char *code);
-
-extern Wrapper *Swig_cppdestructor_wrapper(String_or_char *classname,
- String_or_char *code);
-
-extern Wrapper *Swig_cconstructor_wrapper(String_or_char *classname,
- ParmList *parms,
- String_or_char *code);
-
-extern Wrapper *Swig_cppconstructor_wrapper(String_or_char *classname,
- ParmList *parms,
- String_or_char *code);
-
-
-extern Wrapper *Swig_cmemberset_wrapper(String_or_char *classname,
- String_or_char *membername,
- SwigType *type,
- String_or_char *code);
-
-extern Wrapper *Swig_cmemberget_wrapper(String_or_char *classname,
- String_or_char *membername,
- SwigType *type,
- String_or_char *code);
-
-extern Wrapper *Swig_cvarset_wrapper(String_or_char *varname,
- SwigType *type,
- String_or_char *code);
-
-extern Wrapper *Swig_cvarget_wrapper(String_or_char *varname,
- SwigType *type,
- String_or_char *code);
-
-
-/* --- Module loader and handler --- */
-
-typedef struct Module Module;
-extern void Swig_register_module(const String_or_char *modname, const String_or_char *starttag,
- int (*initfunc)(int, char **),
- DOH *(*startfunc)(DOH *));
-
-extern Module *Swig_load_module(const String_or_char *modname);
-extern int Swig_init_module(Module *m, int argc, char **argv);
-extern DOH *Swig_start_module(Module *m, DOH *obj);
-extern DOH *Swig_run_modules(DOH *node);
-
-/* --- Legacy Typemap API (somewhat simplified) --- */
-
-extern void Swig_typemap_init();
-extern void Swig_typemap_register(const String_or_char *op, SwigType *type, String_or_char *name, String_or_char *code, ParmList *locals);
-extern void Swig_typemap_copy(const String_or_char *op, SwigType *stype, String_or_char *sname,
- SwigType *ttype, String_or_char *tname);
-extern void Swig_typemap_clear(const String_or_char *op, SwigType *type, String_or_char *name);
-extern void Swig_typemap_apply(SwigType *tm_type, String_or_char *tmname, SwigType *type, String_or_char *pname);
-extern void Swig_typemap_clear_apply(SwigType *type, String_or_char *pname);
-extern void Swig_typemap_debug();
-extern Hash *Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *pname);
-extern char *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname, String_or_char *source, String_or_char *target, Wrapper *f);
-extern void Swig_typemap_new_scope(Hash *);
+extern String *Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self);
+extern String *Swig_cmemberget_call(String_or_char *name, SwigType *t, String_or_char *self);
+
+/* --- Transformations --- */
+
+extern int Swig_MethodToFunction(Node *n, String *classname, int flags);
+extern int Swig_ConstructorToFunction(Node *n, String *classname, int cplus, int flags);
+extern int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags);
+extern int Swig_MembersetToFunction(Node *n, String *classname, int flags);
+extern int Swig_MembergetToFunction(Node *n, String *classname, int flags);
+extern int Swig_VargetToFunction(Node *n);
+extern int Swig_VarsetToFunction(Node *n);
+
+#define CWRAP_EXTEND 0x01
+#define CWRAP_SMART_POINTER 0x02
+
+/* --- Legacy Typemap API (somewhat simplified, ha!) --- */
+
+extern void Swig_typemap_init();
+extern void Swig_typemap_register(const String_or_char *op, ParmList *pattern, String_or_char *code, ParmList *locals, ParmList *kwargs);
+extern int Swig_typemap_copy(const String_or_char *op, ParmList *srcpattern, ParmList *pattern);
+extern void Swig_typemap_clear(const String_or_char *op, ParmList *pattern);
+extern int Swig_typemap_apply(ParmList *srcpat, ParmList *destpat);
+extern void Swig_typemap_clear_apply(ParmList *pattern);
+extern void Swig_typemap_debug();
+
+extern Hash *Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *pname, SwigType **matchtype);
+extern Hash *Swig_typemap_search_multi(const String_or_char *op, ParmList *parms, int *nmatch);
+extern String *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname, String_or_char *lname,
+ String_or_char *source, String_or_char *target, Wrapper *f);
+
+extern String *Swig_typemap_lookup_new(const String_or_char *op, Node *n, const String_or_char *lname, Wrapper *f);
+
+extern String *Swig_typemap_lookup_multi(const String_or_char *op, ParmList *parms, String_or_char *source, Wrapper *f, int *nmatch);
+extern void Swig_typemap_new_scope();
extern Hash *Swig_typemap_pop_scope();
-/* --- Legacy %except directive API --- */
-extern void Swig_except_register(String_or_char *code);
-extern char *Swig_except_lookup();
-extern void Swig_except_clear();
-
-/* --- Attribute access macros --- */
-
-#define Gettype(x) Getattr(x,"type")
-#define Getname(x) Getattr(x,"name")
-#define Getvalue(x) Getattr(x,"value")
-#define Getlname(x) Getattr(x,"lname")
-#define Getignore(x) GetInt(x,"ignore")
-#define Getparms(x) Getattr(x,"parms")
-#define Gettag(x) Getattr(x,"tag")
-#define Getparent(x) Getattr(x,"parent")
-
-#define Settype(x,v) Setattr(x,"type",v)
-#define Setname(x,v) Setattr(x,"name",v)
-#define Setlname(x,v) Setattr(x,"lname",v)
-#define Setvalue(x,v) Setattr(x,"value", v)
-#define Setignore(x,v) SetInt(x,"ignore",v)
-#define Settag(x,v) Setattr(x,"tag",v)
-#define Setparms(x,v) Setattr(x,"parms", v)
-#define Setparent(x,p) Setattr(x,"parent",p)
-
-#define Getnext(x) Getattr(x,"next")
-#define Setnext(x,n) Setattr(x,"next",n)
-#define Getprev(x) Getattr(x,"prev")
-#define Setprev(x,n) Setattr(x,"prev",n)
-
-#define Getchild(x) Getattr(x,"child")
-#define Setchild(x,c) Setattr(x,"child",c)
-
-extern int Swig_main(int argc, char **argv, char **modules);
-extern void Swig_exit(int n);
+extern void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f);
+
+/* --- Code fragment support --- */
+extern void Swig_fragment_register(String *name, String *section, String *code);
+extern void Swig_fragment_emit(String *name);
+
#endif
+
+
+
diff --git a/Source/Swig/swig.i b/Source/Swig/swig.i
index d90df029b..33d174ddf 100644
--- a/Source/Swig/swig.i
+++ b/Source/Swig/swig.i
@@ -717,11 +717,7 @@ extern FILE *Swig_open(DOH *name);
extern DOH *Swig_read_file(FILE *file);
extern DOH *Swig_include(DOH *name);
-#ifdef MACSWIG
-#define SWIG_FILE_DELIMETER ":"
-#else
#define SWIG_FILE_DELIMETER "/"
-#endif
%section "Command Line Parsing"
diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
new file mode 100644
index 000000000..31a6016c3
--- /dev/null
+++ b/Source/Swig/symbol.c
@@ -0,0 +1,1124 @@
+/* -----------------------------------------------------------------------------
+ * symbol.c
+ *
+ * This file implements the SWIG symbol table. See details below.
+ *
+ * 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_symbol_c[] = "$Header$";
+
+#include "swig.h"
+#include "swigwarn.h"
+#include <ctype.h>
+
+/* -----------------------------------------------------------------------------
+ * Synopsis
+ *
+ * This module provides symbol table management for all of SWIG. In previous
+ * releases, the management of symbols was rather haphazard. This module tries
+ * to correct that.
+ *
+ * All symbols are associated with simple identifiers. For example, here are some
+ * declarations that generate symbol table entries:
+ *
+ * decl symbol
+ * -------------- ------------
+ * void foo(int); foo
+ * int x; x
+ * typedef int *blah; blah
+ *
+ * Associated with each symbol is a Hash table that can contain any set of
+ * attributes that make sense for that object. For example:
+ *
+ * typedef int *blah; ----> "name" : 'blah'
+ * "type" : 'int'
+ * "decl" : 'p.'
+ * "storage" : 'typedef'
+ *
+ * In some cases, the symbol table needs to manage overloaded entries. For instance,
+ * overloaded functions. In this case, a linked list is built. The "sym:nextSibling"
+ * attribute is reserved to hold a link to the next entry. For example:
+ *
+ * int foo(int); --> "name" : "foo" "name" : "foo"
+ * int foo(int,double); "type" : "int" "type" : "int"
+ * "decl" : "f(int)." "decl" : "f(int,double)."
+ * ... ...
+ * "sym:nextSibling" : --------> "sym:nextSibling": --------> ...
+ *
+ * When more than one symbol has the same name, the symbol declarator is
+ * used to detect duplicates. For example, in the above case, foo(int) and
+ * foo(int,double) are different because their "decl" attribute is different.
+ * However, if a third declaration "foo(int)" was made, it would generate a
+ * conflict (due to having a declarator that matches a previous entry).
+ *
+ * Structures and classes:
+ *
+ * C/C++ symbol tables are normally managed in a few different spaces. The
+ * most visible namespace is reserved for functions, variables, typedef, enum values
+ * and such. In C, a separate tag-space is reserved for 'struct name', 'class name',
+ * and 'union name' declarations. In SWIG, a single namespace is used for everything
+ * this means that certain incompatibilities will arise with some C programs. For instance:
+ *
+ * struct Foo {
+ * ...
+ * }
+ *
+ * int Foo(); // Error. Name clash. Works in C though
+ *
+ * Due to the unified namespace for structures, special handling is performed for
+ * the following:
+ *
+ * typedef struct Foo {
+ *
+ * } Foo;
+ *
+ * In this case, the symbol table contains an entry for the structure itself. The
+ * typedef is left out of the symbol table.
+ *
+ * Target language vs C:
+ *
+ * The symbol tables are normally managed *in the namespace of the target language*.
+ * This means that name-collisions can be resolved using %rename and related
+ * directives. A quirk of this is that sometimes the symbol tables need to
+ * be used for C type resolution as well. To handle this, each symbol table
+ * also has a C-symbol table lurking behind the scenes. This is used to locate
+ * symbols in the C namespace. However, this symbol table is not used for error
+ * reporting nor is it used for anything else during code generation.
+ *
+ * Symbol table structure:
+ *
+ * Symbol tables themselves are a special kind of node that is organized just like
+ * a normal parse tree node. Symbol tables are organized in a tree that can be
+ * traversed using the SWIG-DOM API. The following attributes names are reserved.
+ *
+ * name -- Name of the scope defined by the symbol table (if any)
+ * This name is the C-scope name and is not affected by
+ * %renaming operations
+ * symtab -- Hash table mapping identifiers to nodes.
+ * csymtab -- Hash table mapping C identifiers to nodes.
+ *
+ * Reserved attributes on symbol objects:
+ *
+ * When a symbol is placed in the symbol table, the following attributes
+ * are set:
+ *
+ * sym:name -- Symbol name
+ * sym:nextSibling -- Next symbol (if overloaded)
+ * sym:previousSibling -- Previous symbol (if overloaded)
+ * sym:symtab -- Symbol table object holding the symbol
+ * sym:overloaded -- Set to the first symbol if overloaded
+ *
+ * These names are modeled after XML namespaces. In particular, every attribute
+ * pertaining to symbol table management is prefaced by the "sym:" prefix.
+ * ----------------------------------------------------------------------------- */
+
+static Hash *current = 0; /* The current symbol table hash */
+static Hash *ccurrent = 0; /* The current c symbol table hash */
+static Hash *current_symtab = 0; /* Current symbol table node */
+static Hash *symtabs = 0; /* Hash of all symbol tables by fully-qualified name */
+static Hash *global_scope = 0; /* Global scope */
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_new()
+ *
+ * Create a new symbol table object
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_symbol_init() {
+ current = NewHash();
+ current_symtab = NewHash();
+ ccurrent = NewHash();
+ set_nodeType(current_symtab,"symboltable");
+ Setattr(current_symtab,"symtab",current);
+ Setattr(current_symtab,"csymtab", ccurrent);
+
+ /* Set the global scope */
+ symtabs = NewHash();
+ Setattr(symtabs,"",current_symtab);
+ global_scope = current_symtab;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_setscopename()
+ *
+ * Set the C scopename of the current symbol table.
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_symbol_setscopename(const String_or_char *name) {
+ String *qname;
+ assert(!Getattr(current_symtab,"name"));
+ Setattr(current_symtab,"name",name);
+
+ /* Set nested scope in parent */
+
+ qname = Swig_symbol_qualifiedscopename(current_symtab);
+
+ /* Save a reference to this scope */
+ Setattr(symtabs,qname,current_symtab);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_getscopename()
+ *
+ * Get the C scopename of the current symbol table
+ * ----------------------------------------------------------------------------- */
+
+String *
+Swig_symbol_getscopename() {
+ return Getattr(current_symtab,"name");
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_getscope()
+ *
+ * Given a fully qualified C scopename, this function returns a symbol table
+ * ----------------------------------------------------------------------------- */
+
+Symtab *
+Swig_symbol_getscope(const String_or_char *name) {
+ if (!symtabs) return 0;
+ if (Strcmp(name,"::") == 0) name = "";
+ return Getattr(symtabs,name);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_qualifiedscopename()
+ *
+ * Get the fully qualified C scopename of a symbol table. Note, this only pertains
+ * to the C/C++ scope name. It is not affected by renaming.
+ * ----------------------------------------------------------------------------- */
+
+String *
+Swig_symbol_qualifiedscopename(Symtab *symtab) {
+ String *result = 0;
+ Hash *parent;
+ String *name;
+ if (!symtab) symtab = current_symtab;
+ parent = parentNode(symtab);
+ if (parent) {
+ result = Swig_symbol_qualifiedscopename(parent);
+ }
+ name = Getattr(symtab,"name");
+ if (name) {
+ if (!result) {
+ result = NewString("");
+ }
+ if (Len(result)) {
+ Printf(result,"::%s",name);
+ } else {
+ Printf(result,"%s",name);
+ }
+ }
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_newscope()
+ *
+ * Create a new scope. Returns the newly created scope.
+ * ----------------------------------------------------------------------------- */
+
+Symtab *
+Swig_symbol_newscope()
+{
+ Hash *n;
+ Hash *hsyms, *h;
+
+ hsyms = NewHash();
+ h = NewHash();
+
+ set_nodeType(h,"symboltable");
+ Setattr(h,"symtab",hsyms);
+ set_parentNode(h,current_symtab);
+
+ n = lastChild(current_symtab);
+ if (!n) {
+ set_firstChild(current_symtab,h);
+ } else {
+ set_nextSibling(n,h);
+ }
+ set_lastChild(current_symtab,h);
+ current = hsyms;
+ ccurrent = NewHash();
+ Setattr(h,"csymtab",ccurrent);
+ current_symtab = h;
+ return current_symtab;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_setscope()
+ *
+ * Set the current scope. Returns the previous current scope.
+ * ----------------------------------------------------------------------------- */
+
+Symtab *
+Swig_symbol_setscope(Symtab *sym) {
+ Symtab *ret = current_symtab;
+ current_symtab = sym;
+ current = Getattr(sym,"symtab");
+ assert(current);
+ ccurrent = Getattr(sym,"csymtab");
+ assert(ccurrent);
+ return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_popscope()
+ *
+ * Pop out of the current scope. Returns the popped scope and sets the
+ * scope to the parent scope.
+ * ----------------------------------------------------------------------------- */
+
+Symtab *
+Swig_symbol_popscope() {
+ Hash *h = current_symtab;
+ current_symtab = parentNode(current_symtab);
+ assert(current_symtab);
+ current = Getattr(current_symtab,"symtab");
+ assert(current);
+ ccurrent = Getattr(current_symtab,"csymtab");
+ assert(ccurrent);
+ return h;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_current()
+ *
+ * Return the current symbol table.
+ * ----------------------------------------------------------------------------- */
+
+Symtab *
+Swig_symbol_current() {
+ return current_symtab;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_alias()
+ *
+ * Makes an alias for a symbol in the global symbol table.
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_symbol_alias(String_or_char *aliasname, Symtab *s) {
+ String *qname;
+ qname = Swig_symbol_qualifiedscopename(current_symtab);
+ if (qname) {
+ Printf(qname,"::%s", aliasname);
+ } else {
+ qname = NewString(aliasname);
+ }
+ if (!Getattr(symtabs,qname)) {
+ Setattr(symtabs,qname,s);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_inherit()
+ *
+ * Inherit symbols from another scope.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_symbol_inherit(Symtab *s) {
+ int i;
+ List *inherit = Getattr(current_symtab,"inherit");
+ if (!inherit) {
+ inherit = NewList();
+ Setattr(current_symtab,"inherit", inherit);
+ }
+ assert(s != current_symtab);
+ for (i = 0; i < Len(inherit); i++) {
+ Node *n = Getitem(inherit,i);
+ if (n == s) return; /* Already inherited */
+ }
+ Append(inherit,s);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_cadd()
+ *
+ * Adds a node to the C symbol table only.
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_symbol_cadd(String_or_char *name, Node *n) {
+ Node *append = 0;
+
+ Node *cn;
+ /* There are a few options for weak symbols. A "weak" symbol
+ is any symbol that can be replaced by another symbol in the C symbol
+ table. An example would be a forward class declaration. A forward
+ class sits in the symbol table until a real class declaration comes along.
+
+ Certain symbols are marked as "sym:typename". These are important
+ symbols related to the C++ type-system and take precedence in the C
+ symbol table. An example might be code like this:
+
+ template<class T> T foo(T x);
+ int foo(int);
+
+ In this case, the template is marked with "sym:typename" so that it
+ stays in the C symbol table (so that it can be expanded using %template).
+ */
+
+ if (!name) return;
+ cn = Getattr(ccurrent,name);
+
+ if (cn && (Getattr(cn,"sym:typename"))) {
+ /* The node in the C symbol table is a typename. Do nothing */
+ /* We might append the symbol at the end */
+ append = n;
+ } else if (cn && (Getattr(cn,"sym:weak"))) {
+ /* The node in the symbol table is weak. Replace it */
+ Setattr(ccurrent,name, n);
+ } else if (cn && (Getattr(n,"sym:weak"))) {
+ /* The node being added is weak. Don't worry about it */
+ } else if (cn && (Getattr(n,"sym:typename"))) {
+ /* The node being added is a typename. We definitely add it */
+ Setattr(ccurrent,name,n);
+ append = cn;
+ } else if (cn && (Strcmp(nodeType(cn),"templateparm") == 0)) {
+ Swig_error(Getfile(n),Getline(n),"Error. Declaration of '%s' shadows template parameter at %s:%d\n",
+ name,Getfile(cn),Getline(cn));
+ return;
+ } else if (cn) {
+ append = n;
+ } else if (!cn) {
+ /* No conflict. Add the symbol */
+ Setattr(ccurrent,name,n);
+ }
+
+ /* Multiple entries in the C symbol table. We append to to the symbol table */
+ if (append) {
+ Node *fn, *pn = 0;
+ cn = Getattr(ccurrent,name);
+ fn = cn;
+ while (fn) {
+ pn = fn;
+ if (fn == append) {
+ /* already added. Bail */
+ return;
+ }
+ fn = Getattr(fn,"csym:nextSibling");
+ }
+ if (pn) {
+ Setattr(pn,"csym:nextSibling",append);
+ }
+ }
+
+ /* Special typedef handling. When a typedef node is added to the symbol table, we
+ might have to add a type alias. This would occur if the typedef mapped to another
+ scope in the system. For example:
+
+ class Foo {
+ };
+
+ typedef Foo OtherFoo;
+
+ In this case, OtherFoo becomes an alias for Foo. */
+
+ {
+ Node *td = n;
+ while (td && (Strcmp(nodeType(td),"cdecl") == 0) && (checkAttribute(td,"storage","typedef"))) {
+ SwigType *type;
+ Node *td1;
+ type = Copy(Getattr(td,"type"));
+ SwigType_push(type,Getattr(td,"decl"));
+ td1 = Swig_symbol_clookup(type,0);
+ Delete(type);
+ if (td1 == td) break;
+ td = td1;
+ if (td) {
+ Symtab *st = Getattr(td,"symtab");
+ if (st) {
+ Swig_symbol_alias(Getattr(n,"name"),st);
+ break;
+ }
+ }
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_add()
+ *
+ * Adds a node to the symbol table. Returns the node itself if successfully
+ * added. Otherwise, it returns the symbol table entry of the conflicting node.
+ *
+ * Also places the symbol in a behind-the-scenes C symbol table. This is needed
+ * for namespace support, type resolution, and other issues.
+ * ----------------------------------------------------------------------------- */
+
+Node *
+Swig_symbol_add(String_or_char *symname, Node *n) {
+ Hash *c, *cn, *cl = 0;
+ SwigType *decl, *ndecl;
+ String *cstorage, *nstorage;
+ int nt = 0, ct = 0;
+ int pn = 0;
+ int u1 = 0, u2 = 0;
+ String *name;
+
+ /* See if the node has a name. If so, we place in the C symbol table for this
+ scope. We don't worry about overloading here---the primary purpose of this
+ is to record information for type/name resolution for later. Conflicts
+ in C namespaces are errors, but these will be caught by the C++ compiler
+ when compiling the wrapper code */
+
+
+ /* There are a few options for weak symbols. A "weak" symbol
+ is any symbol that can be replaced by another symbol in the C symbol
+ table. An example would be a forward class declaration. A forward
+ class sits in the symbol table until a real class declaration comes along.
+
+ Certain symbols are marked as "sym:typename". These are important
+ symbols related to the C++ type-system and take precedence in the C
+ symbol table. An example might be code like this:
+
+ template<class T> T foo(T x);
+ int foo(int);
+
+ In this case, the template is marked with "sym:typename" so that it
+ stays in the C symbol table (so that it can be expanded using %template).
+ */
+
+ name = Getattr(n,"name");
+ if (name) {
+ Swig_symbol_cadd(name,n);
+ }
+
+ /* No symbol name defined. We return. */
+ if (!symname) {
+ Setattr(n,"sym:symtab",current_symtab);
+ return n;
+ }
+
+ /* If node is ignored. We don't proceed any further */
+ if (Getattr(n,"feature:ignore")) return n;
+
+ /* See if the symbol already exists in the table */
+ c = Getattr(current,symname);
+
+ /* Check for a weak symbol. A weak symbol is allowed to be in the
+ symbol table, but is silently overwritten by other symbols. An example
+ would be a forward class declaration. For instance:
+
+ class Foo;
+
+ In this case, "Foo" sits in the symbol table. However, the
+ definition of Foo would replace the entry if it appeared later. */
+
+ if (c && Getattr(c,"sym:weak")) {
+ c = 0;
+ }
+ if (c) {
+ /* There is a symbol table conflict. There are a few cases to consider here:
+ (1) A conflict between a class/enum and a typedef declaration is okay.
+ In this case, the symbol table entry is set to the class/enum declaration
+ itself, not the typedef.
+
+ (2) A conflict between namespaces is okay--namespaces are open
+
+ (3) Otherwise, overloading is only allowed for functions
+ */
+
+ /* Check for namespaces */
+ if ((Strcmp(nodeType(n),nodeType(c)) == 0) && ((Strcmp(nodeType(n),"namespace") == 0))) {
+ Node *cl, *pcl = 0;
+ cl = c;
+ while (cl) {
+ pcl = cl;
+ cl = Getattr(cl,"sym:nextSibling");
+ }
+ Setattr(pcl,"sym:nextSibling",n);
+ Setattr(n,"sym:symtab", current_symtab);
+ Setattr(n,"sym:name", symname);
+ Setattr(n,"sym:previousSibling", pcl);
+ return n;
+ }
+ if (Getattr(n,"allows_typedef")) nt = 1;
+ if (Getattr(c,"allows_typedef")) ct = 1;
+ if (nt || ct) {
+ Node *td, *other;
+ String *s;
+ /* At least one of the nodes allows typedef overloading. Make sure that
+ both don't--this would be a conflict */
+
+ if (nt && ct) return c;
+
+ /* Figure out which node allows the typedef */
+ if (nt) {
+ td = n;
+ other = c;
+ } else {
+ td = c;
+ other = n;
+ }
+ /* Make sure the other node is a typedef */
+ s = Getattr(other,"storage");
+ if (!s || (Strcmp(s,"typedef"))) return c; /* No. This is a conflict */
+
+ /* Hmmm. This appears to be okay. Make sure the symbol table refers to the allow_type node */
+
+ if (td != c) {
+ Setattr(current,symname, td);
+ Setattr(td,"sym:symtab", current_symtab);
+ Setattr(td,"sym:name", symname);
+ }
+ return n;
+ }
+
+ decl = Getattr(c,"decl");
+ ndecl = Getattr(n,"decl");
+
+ {
+ String *nt1, *nt2;
+ nt1 = nodeType(n);
+ if (Strcmp(nt1,"template") == 0) nt1 = Getattr(n,"templatetype");
+ nt2 = nodeType(c);
+ if (Strcmp(nt2,"template") == 0) nt2 = Getattr(c,"templatetype");
+ if (Strcmp(nt1,"using") == 0) u1 = 1;
+ if (Strcmp(nt2,"using") == 0) u2 = 1;
+
+ if ((Strcmp(nt1,nt2) != 0) && !(u1 || u2)) return c;
+ }
+ if (!(u1 || u2)) {
+ if ((!SwigType_isfunction(decl)) || (!SwigType_isfunction(ndecl))) {
+ /* Symbol table conflict */
+ return c;
+ }
+ }
+
+ /* Hmmm. Declarator seems to indicate that this is a function */
+ /* Look at storage class to see if compatible */
+ cstorage = Getattr(c,"storage");
+ nstorage = Getattr(n,"storage");
+
+ /* If either one is declared as typedef, forget it. We're hosed */
+ if (Cmp(cstorage,"typedef") == 0) {
+ return c;
+ }
+ if (Cmp(nstorage,"typedef") == 0) {
+ return c;
+ }
+ /* Okay. Walk down the list of symbols and see if we get a declarator match */
+ cn = c;
+ pn = 0;
+ while (cn) {
+ decl = Getattr(cn,"decl");
+ if (!(u1 || u2)) {
+ if (Cmp(ndecl,decl) == 0) {
+ /* Declarator conflict */
+ return cn;
+ }
+ }
+ cl = cn;
+ cn = Getattr(cn,"sym:nextSibling");
+ pn++;
+ }
+ /* Well, we made it this far. Guess we can drop the symbol in place */
+ Setattr(n,"sym:symtab",current_symtab);
+ Setattr(n,"sym:name",symname);
+ Setattr(n,"sym:overname", NewStringf("__SWIG_%d", pn));
+ Setattr(cl,"sym:nextSibling",n);
+ Setattr(n,"sym:previousSibling",cl);
+ Setattr(cl,"sym:overloaded",c);
+ Setattr(n,"sym:overloaded",c);
+ return n;
+ }
+
+ /* No conflict. Just add it */
+ Setattr(n,"sym:symtab",current_symtab);
+ Setattr(n,"sym:name",symname);
+ Setattr(n,"sym:overname", NewStringf("__SWIG_%d", pn));
+ Setattr(current,symname,n);
+ return n;
+}
+
+/* -----------------------------------------------------------------------------
+ * symbol_lookup_qualified()
+ *
+ * Internal function to handle fully qualified symbol table lookups. This
+ * works from the symbol table supplied in symtab and unwinds its way out
+ * towards the global scope.
+ *
+ * This function operates in the C namespace, not the target namespace.
+ * ----------------------------------------------------------------------------- */
+
+static Node *
+symbol_lookup(String_or_char *name, Symtab *symtab) {
+ Node *n;
+ List *inherit;
+ Hash *sym = Getattr(symtab,"csymtab");
+
+ if (Getmark(symtab)) return 0;
+ Setmark(symtab,1);
+
+ n = Getattr(sym,name);
+ if (n) {
+ Setmark(symtab,0);
+ return n;
+ }
+ inherit = Getattr(symtab,"inherit");
+ if (inherit) {
+ int i,len;
+ len = Len(inherit);
+ for (i = 0; i < len; i++) {
+ n = symbol_lookup(name, Getitem(inherit,i));
+ if (n) {
+ Setmark(symtab,0);
+ return n;
+ }
+ }
+ }
+ Setmark(symtab,0);
+ return 0;
+}
+
+static Node *
+symbol_lookup_qualified(String_or_char *name, Symtab *symtab, String *prefix, int local) {
+ /* This is a little funky, we search by fully qualified names */
+
+ if (!symtab) return 0;
+ if (!prefix) {
+ Node *n;
+ String *bname;
+ String *prefix;
+ bname = Swig_scopename_last(name);
+ prefix = Swig_scopename_prefix(name);
+ n = symbol_lookup_qualified(bname,symtab,prefix,local);
+ Delete(bname);
+ Delete(prefix);
+ return n;
+ } else {
+ String *qname;
+ Symtab *st;
+ Node *n = 0;
+ /* Make qualified name of current scope */
+ qname = Swig_symbol_qualifiedscopename(symtab);
+ if (qname && Len(qname)) {
+ if (Len(prefix)) {
+ Append(qname,"::");
+ Append(qname,prefix);
+ }
+ } else {
+ qname = NewString(prefix);
+ }
+ st = Getattr(symtabs,qname);
+ /* Found a scope match */
+ if (st) {
+ if (!name) return st;
+ n = symbol_lookup(name, st);
+ }
+ Delete(qname);
+ if (!n) {
+ if (!local) {
+ Node *pn = parentNode(symtab);
+ if (pn) n = symbol_lookup_qualified(name,pn, prefix, local);
+ } else {
+ n = 0;
+ }
+ }
+ return n;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_clookup()
+ *
+ * Look up a symbol in the symbol table. This uses the C name, not scripting
+ * names. Note: If we come across a using a directive, we follow it to
+ * to get the real node.
+ * ----------------------------------------------------------------------------- */
+
+Node *
+Swig_symbol_clookup(String_or_char *name, Symtab *n) {
+ Hash *hsym;
+ Node *s = 0;
+
+ if (!n) {
+ hsym = current_symtab;
+ } else {
+ if (Strcmp(nodeType(n),"symboltable")) {
+ n = Getattr(n,"sym:symtab");
+ }
+ assert(n);
+ if (n) {
+ hsym = n;
+ }
+ }
+
+ if (Swig_scopename_check(name)) {
+ if (Strncmp(name,"::",2) == 0) {
+ String *nname = NewString(Char(name)+2);
+ if (Swig_scopename_check(nname)) {
+ s = symbol_lookup_qualified(nname,global_scope,0,0);
+ }
+ } else {
+ String *prefix = Swig_scopename_prefix(name);
+ if (prefix) {
+ s = symbol_lookup_qualified(name,hsym,0,0);
+ Delete(prefix);
+ if (!s) {
+ return 0;
+ }
+ }
+ }
+ }
+ if (!s) {
+ while (hsym) {
+ s = symbol_lookup(name,hsym);
+ if (s) break;
+ hsym = parentNode(hsym);
+ if (!hsym) break;
+ }
+ }
+ if (!s) {
+ return 0;
+ }
+ /* Check if s is a 'using' node */
+ while (s && Strcmp(nodeType(s),"using") == 0) {
+ Node *ss;
+ ss = Swig_symbol_clookup(Getattr(s,"uname"), Getattr(s,"sym:symtab"));
+ if (!ss) {
+ Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s,"uname"));
+ }
+ s = ss;
+ }
+ return s;
+}
+
+Node *
+Swig_symbol_clookup_local(String_or_char *name, Symtab *n) {
+ Hash *h, *hsym;
+ Node *s = 0;
+
+ if (!n) {
+ hsym = current_symtab;
+ h = ccurrent;
+ } else {
+ if (Strcmp(nodeType(n),"symboltable")) {
+ n = Getattr(n,"sym:symtab");
+ }
+ assert(n);
+ hsym = n;
+ h = Getattr(n,"csymtab");
+ }
+
+ if (Swig_scopename_check(name)) {
+ if (Strncmp(name,"::",2) == 0) {
+ s = symbol_lookup_qualified(Char(name)+2,global_scope,0,0);
+ } else {
+ s = symbol_lookup_qualified(name,hsym,0,0);
+ }
+ }
+ if (!s) {
+ s = symbol_lookup(name,hsym);
+ }
+ if (!s) return 0;
+ /* Check if s is a 'using' node */
+ while (s && Strcmp(nodeType(s),"using") == 0) {
+ Node *ss = Swig_symbol_clookup_local(Getattr(s,"uname"), Getattr(s,"sym:symtab"));
+ if (!ss) {
+ Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s,"uname"));
+ }
+ s = ss;
+ }
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_cscope()
+ *
+ * Look up a scope name.
+ * ----------------------------------------------------------------------------- */
+
+Symtab *
+Swig_symbol_cscope(String_or_char *name, Symtab *symtab) {
+ if (Strncmp(name,"::",2) == 0) return symbol_lookup_qualified(0, global_scope, name, 0);
+ return symbol_lookup_qualified(0,symtab,name,0);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_remove()
+ *
+ * Remove a symbol
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_symbol_remove(Node *n) {
+ Symtab *symtab;
+ String *symname;
+ Node *symprev;
+ Node *symnext;
+ symtab = Getattr(n,"sym:symtab"); /* Get symbol table object */
+ symtab = Getattr(symtab,"symtab"); /* Get actual hash table of symbols */
+ symname = Getattr(n,"sym:name");
+ symprev = Getattr(n,"sym:previousSibling");
+ symnext = Getattr(n,"sym:nextSibling");
+
+ /* If previous symbol, just fix the links */
+ if (symprev) {
+ if (symnext) {
+ Setattr(symprev,"sym:nextSibling",symnext);
+ } else {
+ Delattr(symprev,"sym:nextSibling");
+ }
+ } else {
+ /* If no previous symbol, see if there is a next symbol */
+ if (symnext) {
+ Setattr(symtab,symname,symnext);
+ } else {
+ Delattr(symtab,symname);
+ }
+ }
+ Delattr(n,"sym:symtab");
+ Delattr(n,"sym:previousSibling");
+ Delattr(n,"sym:nextSibling");
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_qualified()
+ *
+ * Return the qualified name of a symbol
+ * ----------------------------------------------------------------------------- */
+
+String *
+Swig_symbol_qualified(Node *n) {
+ Hash *symtab;
+ if (Strcmp(nodeType(n),"symboltable") == 0) {
+ symtab = n;
+ } else {
+ symtab = Getattr(n,"sym:symtab");
+ }
+ if (!symtab) return NewString("");
+ return Swig_symbol_qualifiedscopename(symtab);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_isoverloaded()
+ *
+ * Check if a symbol is overloaded. Returns the first symbol if so.
+ * ----------------------------------------------------------------------------- */
+
+Node *
+Swig_symbol_isoverloaded(Node *n) {
+ return Getattr(n,"sym:overloaded");
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_type_qualify()
+ *
+ * Create a fully qualified type name
+ * ----------------------------------------------------------------------------- */
+
+SwigType *
+Swig_symbol_type_qualify(SwigType *t, Symtab *st) {
+ List *elements;
+ String *result;
+ int i,len;
+
+ result = NewString("");
+ elements = SwigType_split(t);
+
+ len = Len(elements);
+ for (i = 0; i < len; i++) {
+ String *e = Getitem(elements,i);
+ if (SwigType_issimple(e)) {
+ Node *n = Swig_symbol_clookup(e,st);
+ if (n) {
+ String *name = Getattr(n,"name");
+ Clear(e);
+ Append(e,name);
+ if (!Swig_scopename_check(name)) {
+ String *qname = Swig_symbol_qualified(n);
+ if (Len(qname)) {
+ Insert(e,0,"::");
+ Insert(e,0,qname);
+ }
+ Delete(qname);
+ }
+ } else if (SwigType_istemplate(e)) {
+ String *tprefix, *tsuffix;
+ SwigType *qprefix;
+ List *targs;
+ String *tparm;
+ tprefix = SwigType_templateprefix(e);
+ tsuffix = SwigType_templatesuffix(e);
+ qprefix = Swig_symbol_type_qualify(tprefix,st);
+ targs = SwigType_parmlist(e);
+ Printf(qprefix,"<(");
+ for (tparm = Firstitem(targs); tparm;) {
+ String *qparm = Swig_symbol_type_qualify(tparm,st);
+ /* Printf(stdout,"qparm = '%s', tparm = '%s'\n", qparm, tparm);*/
+ while (1) {
+ /* It is possible for an integer to show up here. If so, we need to evaluate it */
+ {
+ Node *nn = Swig_symbol_clookup(qparm,st);
+ if ((nn) && (Strcmp(nodeType(nn),"cdecl") == 0)) {
+ String *nv = Getattr(nn,"value");
+ if (nv) {
+ Clear(qparm);
+ Append(qparm,nv);
+ } else {
+ break;
+ }
+ } else if ((nn) && (Strcmp(nodeType(nn),"enumitem") == 0)) {
+ String *qn = Swig_symbol_qualified(nn);
+ if (Len(qn)) {
+ Append(qn,"::");
+ Append(qn,Getattr(nn,"name"));
+ Clear(qparm);
+ Append(qparm,qn);
+ }
+ Delete(qn);
+ break;
+ } else {
+ break;
+ }
+ }
+ }
+ Append(qprefix,qparm);
+ tparm = Nextitem(targs);
+ if (tparm) {
+ Putc(',',qprefix);
+ }
+ Delete(qparm);
+ }
+ Append(qprefix,")>");
+ Append(qprefix,tsuffix);
+ Clear(e);
+ Append(e,qprefix);
+ Delete(tprefix);
+ Delete(tsuffix);
+ Delete(qprefix);
+ }
+ if (Strncmp(e,"::",2) == 0) {
+ Delitem(e,0);
+ Delitem(e,0);
+ }
+ Append(result,e);
+ } else if (SwigType_isfunction(e)) {
+ List *parms = SwigType_parmlist(e);
+ String *s = NewString("f(");
+ String *p;
+ p = Firstitem(parms);
+ while (p) {
+ Append(s,Swig_symbol_type_qualify(p,st));
+ p = Nextitem(parms);
+ if (p) {
+ Append(s,",");
+ }
+ }
+ Append(s,").");
+ Append(result,s);
+ Delete(s);
+ } else {
+ Append(result,e);
+ }
+ }
+ Delete(elements);
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_typedef_reduce()
+ *
+ * Chase a typedef through symbol tables looking for a match.
+ * ----------------------------------------------------------------------------- */
+
+SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab) {
+ SwigType *prefix, *base;
+ Node *n;
+
+ base = SwigType_base(ty);
+ prefix = SwigType_prefix(ty);
+
+ n = Swig_symbol_clookup(base,tab);
+ if (!n) {
+ Delete(base);
+ Delete(prefix);
+ return Copy(ty);
+ }
+ if (Strcmp(nodeType(n),"using") == 0) {
+ String *uname = Getattr(n,"uname");
+ if (uname) {
+ n = Swig_symbol_clookup(base,Getattr(n,"sym:symtab"));
+ if (!n) {
+ Delete(base);
+ Delete(prefix);
+ return Copy(ty);
+ }
+ }
+ }
+ if (Strcmp(nodeType(n),"cdecl") == 0) {
+ String *storage = Getattr(n,"storage");
+ if (Strcmp(storage,"typedef") == 0) {
+ SwigType *decl;
+ SwigType *rt;
+ SwigType *nt = Copy(Getattr(n,"type"));
+ decl = Getattr(n,"decl");
+ if (decl) {
+ SwigType_push(nt,decl);
+ }
+ SwigType_push(nt,prefix);
+ Delete(base);
+ Delete(prefix);
+ rt = Swig_symbol_typedef_reduce(nt, Getattr(n,"sym:symtab"));
+ Delete(nt);
+ return rt;
+ }
+ }
+ Delete(base);
+ Delete(prefix);
+ return Copy(ty);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_string_qualify()
+ *
+ * This function takes a string and looks for identifiers. Identifiers are
+ * then qualified according to scope rules. This function is used in a number
+ * of settings including expression evaluation, scoping of conversion operators,
+ * and so forth.
+ * ----------------------------------------------------------------------------- */
+
+String *
+Swig_symbol_string_qualify(String *s, Symtab *st) {
+ char *c;
+ String *id, *r;
+ int have_id = 0;
+
+ id = NewString("");
+ r = NewString("");
+ c = Char(s);
+ while (*c) {
+ if (isalpha(*c) || (*c == '_') || (*c == ':')) {
+ Putc(*c,id);
+ have_id = 1;
+ } else {
+ if (have_id) {
+ String *qid = Swig_symbol_type_qualify(id,st);
+ Append(r,qid);
+ Clear(id);
+ Delete(qid);
+ have_id = 0;
+ }
+ Putc(*c,r);
+ }
+ c++;
+ }
+ if (have_id) {
+ String *qid = Swig_symbol_type_qualify(id,st);
+ Append(r,qid);
+ Delete(qid);
+ }
+ Delete(id);
+ return r;
+}
+
diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c
index 81566d21e..7df80420c 100644
--- a/Source/Swig/tree.c
+++ b/Source/Swig/tree.c
@@ -11,40 +11,19 @@
* ----------------------------------------------------------------------------- */
#include "swig.h"
+#include <stdarg.h>
+#include <assert.h>
-static char cvsroot[] = "$Header$";
-
-/* Hash table mapping tag names to handler functions */
-static Hash *rules = 0;
-static int debug_emit = 0;
-
-/* -----------------------------------------------------------------------------
- * Swig_next()
- * Swig_prev()
- *
- * Return next/prev node in a parse tree
- * ----------------------------------------------------------------------------- */
-
-DOH *Swig_next(DOH *obj) {
- return Getnext(obj);
-}
-
-DOH *Swig_prev(DOH *obj) {
- return Getprev(obj);
-}
-
-void Swig_debug_emit(int n) {
- debug_emit = n;
-}
+char cvsroot_tree_c[] = "$Header$";
/* -----------------------------------------------------------------------------
- * Swig_dump_tags()
+ * Swig_print_tags()
*
* Dump the tag structure of a parse tree to standard output
* ----------------------------------------------------------------------------- */
void
-Swig_dump_tags(DOH *obj, DOH *root) {
+Swig_print_tags(DOH *obj, DOH *root) {
DOH *croot, *newroot;
DOH *cobj;
@@ -52,22 +31,21 @@ Swig_dump_tags(DOH *obj, DOH *root) {
else croot = root;
while (obj) {
- Printf(stdout,"%s . %s (%s:%d)\n", croot, Getattr(obj,"tag"), Getfile(obj), Getline(obj));
- cobj = Getattr(obj,"child");
+ Printf(stdout,"%s . %s (%s:%d)\n", croot, nodeType(obj), Getfile(obj), Getline(obj));
+ cobj = firstChild(obj);
if (cobj) {
- newroot = NewStringf("%s . %s",croot,Getattr(obj,"tag"));
- Swig_dump_tags(cobj,newroot);
+ newroot = NewStringf("%s . %s",croot,nodeType(obj));
+ Swig_print_tags(cobj,newroot);
Delete(newroot);
}
- obj = Swig_next(obj);
+ obj = nextSibling(obj);
}
if (!root)
Delete(croot);
}
-
/* -----------------------------------------------------------------------------
- * Swig_dump_tree()
+ * Swig_print_tree()
*
* Dump the tree structure of a parse tree to standard output
* ----------------------------------------------------------------------------- */
@@ -85,429 +63,339 @@ static void print_indent(int l) {
}
}
-void
-Swig_dump_tree(DOH *obj) {
- DOH *k;
- DOH *cobj;
- while (obj) {
- print_indent(0);
- Printf(stdout,"+++ %s ----------------------------------------\n", Getattr(obj,"tag"));
-
- k = Firstkey(obj);
- while (k) {
- if ((Cmp(k,"tag") == 0) || (Cmp(k,"child") == 0) ||
- (Cmp(k,"parent") == 0) || (Cmp(k,"next") == 0) ||
- (Cmp(k,"prev") == 0)) {
- /* Do nothing */
- } else if (Cmp(k,"parms") == 0) {
- print_indent(2);
- Printf(stdout,"%-12s - %s\n", k, ParmList_protostr(Getattr(obj,k)));
- } else {
- DOH *o;
- char *trunc = "";
- print_indent(2);
+/* -----------------------------------------------------------------------------
+ * Swig_dump_node(Node *n)
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_print_node(Node *obj) {
+ String *k;
+ Node *cobj;
+
+ print_indent(0);
+ Printf(stdout,"+++ %s ----------------------------------------\n", nodeType(obj));
+ 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) {
+ print_indent(2);
+ Printf(stdout,"%-12s - %s\n", k, ParmList_protostr(Getattr(obj,k)));
+ } else {
+ DOH *o;
+ char *trunc = "";
+ print_indent(2);
+ if (DohIsString(Getattr(obj,k))) {
o = Str(Getattr(obj,k));
if (Len(o) > 40) {
trunc = "...";
}
Printf(stdout,"%-12s - \"%(escape)-0.40s%s\"\n", k, o, trunc);
Delete(o);
+ } else {
+ Printf(stdout,"%-12s - 0x%x\n", k, Getattr(obj,k));
}
- k = Nextkey(obj);
- }
- cobj = Getattr(obj,"child");
- if (cobj) {
- indent_level += 6;
- Printf(stdout,"\n");
- Swig_dump_tree(cobj);
- indent_level -= 6;
- } else {
- print_indent(1);
- Printf(stdout,"\n");
}
- obj = Swig_next(obj);
+ k = Nextkey(obj);
}
-}
-
-
-/* -----------------------------------------------------------------------------
- * Swig_add_rule()
- *
- * Adds a new rule to the tree walking code.
- * ----------------------------------------------------------------------------- */
-
-void
-Swig_add_rule(const String_or_char *name, int (*action)(DOH *node, void *clientdata))
-{
- if (!rules) rules = NewHash();
- if (action)
- Setattr(rules,name,NewVoid((void *) action,0));
- else
- Delattr(rules,name);
-
- if (debug_emit) {
- Printf(stderr,"Swig_add_rule : '%s' -> %x\n", name, action);
+ cobj = firstChild(obj);
+ if (cobj) {
+ indent_level += 6;
+ Printf(stdout,"\n");
+ Swig_print_tree(cobj);
+ indent_level -= 6;
+ } else {
+ print_indent(1);
+ Printf(stdout,"\n");
}
}
-/* -----------------------------------------------------------------------------
- * Swig_add_rules()
- *
- * Add a complete set of rules to the rule system
- * ----------------------------------------------------------------------------- */
-
-void
-Swig_add_rules(SwigRule ruleset[]) {
- int i = 0;
- while (ruleset[i].name) {
- Swig_add_rule(ruleset[i].name, ruleset[i].action);
- i++;
+void
+Swig_print_tree(DOH *obj) {
+ while (obj) {
+ Swig_print_node(obj);
+ obj = nextSibling(obj);
}
}
/* -----------------------------------------------------------------------------
- * Swig_clear_rules()
+ * appendChild()
*
- * Clears all of the existing rules
+ * Appends a new child to a node
* ----------------------------------------------------------------------------- */
void
-Swig_clear_rules()
-{
- if (rules) Delete(rules);
- rules = NewHash();
- if (debug_emit) {
- Printf(stderr,"Swig_clear_rules :\n");
- }
+appendChild(Node *node, Node *chd) {
+ Node *lc;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_dump_rules()
- *
- * Print out debugging information for the rules
- * ----------------------------------------------------------------------------- */
+ if (!chd) return;
-void
-Swig_dump_rules() {
- String *key;
- Printf(stdout,"SWIG emit rules:::\n");
- if (!rules) {
- Printf(stdout," No rules defined.\n");
- return;
+ lc = lastChild(node);
+ if (!lc) {
+ set_firstChild(node,chd);
+ } else {
+ set_nextSibling(lc,chd);
+ set_previousSibling(chd,lc);
}
- key = Firstkey(rules);
- while (key) {
- Printf(stdout," '%-15s' -> %x\n", key, GetVoid(rules,key));
- key = Nextkey(rules);
+ while (chd) {
+ lc = chd;
+ set_parentNode(chd,node);
+ chd = nextSibling(chd);
}
+ set_lastChild(node,lc);
}
/* -----------------------------------------------------------------------------
- * Swig_tag_check()
+ * deleteNode()
*
- * Checks the tag name of an object taking into account namespace issues.
- * For example, a check of "function" will match any object with a tag
- * of the form "xxx:function" whereas a check of "c:function" will check
- * for a more exact match. Returns 1 if a match is found, 0 otherwise
+ * Deletes a node.
* ----------------------------------------------------------------------------- */
-int
-Swig_tag_check(DOH *obj, const String_or_char *tagname) {
- String *tag;
- char *tc;
- char *tnc;
- tag = Getattr(obj,"tag");
- assert(tag);
-
- tnc = Char(tag);
- tc = Char(tagname);
-
- while (tnc) {
- if (strcmp(tc,tnc) == 0) return 1;
- tnc = strchr(tnc,':');
- if (tnc) tnc++;
- }
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_set_callback()
- *
- * Sets a parser callback function for a node.
- * ----------------------------------------------------------------------------- */
void
-Swig_set_callback(DOH *obj, void (*cb)(void *clientdata), void *clientdata) {
- SetVoid(obj,"-callback-",(void *)cb);
- if (clientdata)
- SetVoid(obj,"-callbackarg-", clientdata);
+deleteNode(Node *n) {
+ Node *parent;
+ Node *prev;
+ Node *next;
+
+ parent = parentNode(n);
+ prev = previousSibling(n);
+ next = nextSibling(n);
+ if (prev) {
+ set_nextSibling(prev,next);
+ } else {
+ if (parent) {
+ set_firstChild(parent,next);
+ }
+ }
+ if (next) {
+ set_previousSibling(next,prev);
+ } else {
+ if (parent) {
+ set_lastChild(parent,prev);
+ }
+ }
}
/* -----------------------------------------------------------------------------
- * Swig_set_trace()
+ * copyNode()
*
- * Sets a tracing function on a parse tree node. Returns the old tracing
- * function (if any).
+ * Copies a node, but only copies simple attributes (no lists, hashes).
* ----------------------------------------------------------------------------- */
-void (*Swig_set_trace(DOH *obj, void (*cb)(DOH *, DOH *), DOH *arg))(DOH *, DOH *) {
- void (*old)(DOH *,DOH *);
- old = (void (*)(DOH *, DOH *)) GetVoid(obj,"-trace-");
- SetVoid(obj,"-trace-", (void *) cb);
- if (arg)
- Setattr(obj,"-tracearg-", arg);
- return old;
+Node *
+copyNode(Node *n) {
+ String *key;
+ DOH *v;
+ Node *c = NewHash();
+ for (key = Firstkey(n); key; key = Nextkey(n)) {
+ v = Getattr(n,key);
+ if (DohIsString(v)) {
+ Setattr(c,key,Copy(v));
+ }
+ }
+ Setfile(c,Getfile(n));
+ Setline(c,Getline(n));
+ return c;
}
/* -----------------------------------------------------------------------------
- * Swig_remove_trace()
+ * Swig_tag_nodes()
*
- * Removes the tracing function from a parse tree node
+ * Tags a collection of nodes with an attribute. Used by the parser to mark
+ * subtypes with extra information.
* ----------------------------------------------------------------------------- */
void
-Swig_remove_trace(DOH *obj) {
- Delattr(obj,"-trace-");
- Delattr(obj,"-tracearg-");
+Swig_tag_nodes(Node *n, const String_or_char *attrname, DOH *value) {
+ while (n) {
+ Setattr(n,attrname,value);
+ Swig_tag_nodes(firstChild(n),attrname, value);
+ n = nextSibling(n);
+ }
}
-
-/* -----------------------------------------------------------------------------
- * Swig_node_temporary()
- *
- * Sets a node as being temporary (deleted immediately after it is emitted)
- * ----------------------------------------------------------------------------- */
-
-void Swig_node_temporary(DOH *obj) {
- SetInt(obj,"-temp-",1);
+int
+checkAttribute(Node *n, const String_or_char *name, const String_or_char *value) {
+ String *v;
+ v = Getattr(n,name);
+ if (!v) return 0;
+ if (Cmp(v,value) == 0) return 1;
+ return 0;
}
/* -----------------------------------------------------------------------------
- * Swig_node_ignore()
- *
- * Causes a node to be ignored
+ * Swig_require()
* ----------------------------------------------------------------------------- */
-void Swig_node_ignore(DOH *obj) {
- SetInt(obj,"-ignore-",1);
+#define MAX_SWIG_STACK 256
+static Hash *attr_stack[MAX_SWIG_STACK];
+static Node **nodeptr_stack[MAX_SWIG_STACK];
+static Node *node_stack[MAX_SWIG_STACK];
+static int stackp = 0;
+static int stack_direction = 0;
+
+static void set_direction(int n, int *x) {
+ if (n == 1) {
+ set_direction(0,&n);
+ } else {
+ if (&n < x) {
+ stack_direction = -1; /* Stack grows down */
+ } else {
+ stack_direction = 1; /* Stack grows up */
+ }
+ }
}
-/* -----------------------------------------------------------------------------
- * int Swig_emit()
- *
- * This function calls the handler function (if any) for an object.
- * ----------------------------------------------------------------------------- */
-
-int
-Swig_emit(DOH *obj, void *clientdata) {
- DOH *tag;
- DOH *actionobj;
- char *tc;
- int (*action)(DOH *obj, void *clientdata);
- void (*callback)(void *clientdata);
- void (*tracefunc)(DOH *obj, DOH *arg);
- int ret;
-
- assert(obj);
-
- if (!rules) {
- Printf(stderr,"No rules defined in Swig_emit()!\n");
- return SWIG_ERROR;
- }
- if (obj) {
- if (Getattr(obj,"-ignore-")) return SWIG_OK;
- tag = Getattr(obj,"tag");
- assert(tag);
- tc = Char(tag);
- while(tc) {
- actionobj = Getattr(rules,tc);
- if (actionobj) {
- if (debug_emit) {
- Printf(stderr,"Swig_emit : Matched tag '%s' -> rule '%s'\n", tag, tc);
- }
- /* Check for user tracing -- traces occur before any handlers are called */
- tracefunc = (void (*)(DOH *, DOH *)) GetVoid(obj,"-trace-");
- if (tracefunc) {
- DOH *tobj = Getattr(obj,"-tracearg-");
- (*tracefunc)(obj,tobj);
- }
- action = (int (*)(DOH *, void *)) Data(actionobj);
- ret = (*action)(obj,clientdata);
- /* Check for a parser callback */
- callback = (void (*)(void *clientdata)) GetVoid(obj,"-callback-");
- if (callback) {
- void *cbarg;
- cbarg = GetVoid(obj,"-callbackarg-");
- (*callback)(cbarg);
- Delattr(obj,"-callback-");
- Delattr(obj,"-callbackarg-");
- }
- return ret;
- } else {
- tc = strchr(tc,':');
- if (tc) tc++;
- }
+int
+Swig_require(Node **nptr, ...) {
+ va_list ap;
+ char *name;
+ DOH *obj;
+ DOH *frame = 0;
+ Node *n = *nptr;
+ va_start(ap, nptr);
+ name = va_arg(ap, char *);
+ while (name) {
+ int newref = 0;
+ int opt = 0;
+ if (*name == '*') {
+ newref = 1;
+ name++;
+ } else if (*name == '?') {
+ newref = 1;
+ opt = 1;
+ name++;
}
- actionobj = Getattr(rules,"*");
- if (actionobj) {
- if (debug_emit) {
- Printf(stderr,"Swig_emit : Matched tag '%s' -> rule '*'\n", tag);
+ obj = Getattr(n,name);
+ if (!opt && !obj) {
+ Printf(stderr,"%s:%d. Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n",
+ Getfile(n), Getline(n), name, nodeType(n));
+ assert(obj);
+ }
+ if (!obj) obj = DohNone;
+ if (newref) {
+ if (!attr_stack[stackp]) {
+ attr_stack[stackp]= NewHash();
}
- /* Check for user tracing -- traces occur before any handlers are called */
- tracefunc = (void (*)(DOH *, DOH *)) GetVoid(obj,"-trace-");
- if (tracefunc) {
- DOH *tobj = Getattr(obj,"-tracearg-");
- (*tracefunc)(obj,tobj);
+ frame = attr_stack[stackp];
+ if (Setattr(frame,name,obj)) {
+ Printf(stderr,"Swig_require('%s'): Warning, attribute '%s' was already saved.\n", nodeType(n), name);
}
- action = (int (*)(DOH *, void *)) Data(actionobj);
- ret = (*action)(obj,clientdata);
- /* Check for a parser callback */
- callback = (void (*)(void *clientdata)) GetVoid(obj,"-callback-");
- if (callback) {
- void *cbarg;
- cbarg = GetVoid(obj,"-callbackarg-");
- (*callback)(cbarg);
- Delattr(obj,"-callback-");
- Delattr(obj,"-callbackarg-");
+ }
+ name = va_arg(ap, char *);
+ }
+ va_end(ap);
+ if (frame) {
+ /* This is a sanity check to make sure no one is saving data, but not restoring it */
+ if (stackp > 0) {
+ int e = 0;
+ if (!stack_direction) set_direction(1,0);
+
+ if (stack_direction < 0) {
+ if ((((char *) nptr) >= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
+ } else {
+ if ((((char *) nptr) <= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
+ }
+ if (e) {
+ Printf(stderr,
+"Swig_require('%s'): Fatal memory management error. If you are seeing this\n\
+message. It means that the target language module is not managing its memory\n\
+correctly. A handler for '%s' probably forgot to call Swig_restore().\n\
+Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1]));
+ assert(0);
}
- return ret;
- }
- if (debug_emit) {
- Printf(stderr,"Swig_emit : No rule defined for tag '%s'\n", tag);
}
+ nodeptr_stack[stackp] = nptr;
+ node_stack[stackp] = n;
+ stackp++;
}
- return SWIG_NORULE;
+ return 1;
}
-/* -----------------------------------------------------------------------------
- * Swig_emit_all()
- *
- * Emit all of the nodes at this level.
- * ----------------------------------------------------------------------------- */
int
-Swig_emit_all(DOH *obj, void *clientdata) {
- int ret;
- while (obj) {
- ret = Swig_emit(obj,clientdata);
- if (ret < 0) return ret;
- obj = Swig_next(obj);
- }
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_node_cut()
- *
- * This function cuts an object out of a parse tree. To do this, the object
- * MUST be properly initialized with "next", "prev", and "parent" attributes.
- * ----------------------------------------------------------------------------- */
-
-void Swig_node_cut(DOH *obj) {
- DOH *parent;
- DOH *next;
- DOH *prev;
-
- parent = Getattr(obj,"parent");
- assert(parent);
- next = Getattr(obj,"next");
- prev = Getattr(obj,"prev");
-
- DohIncref(obj); /* Make sure object doesn't go away */
- Delattr(obj,"parent"); /* Disassociate from my parent */
-
- if (!next && !prev) {
- /* Well, this is a single child. Guess we'll just tell the parent that their child is gone */
- Delattr(parent,"child");
- return;
- }
-
- /* If no next node, then this must be at the end of a list */
- if (!next) {
- Delattr(prev,"next"); /* Break the 'next' link in the previous node */
- Delattr(obj,"prev"); /* Break my link back to the previous object */
- return;
- }
-
- /* No previous node. This must be the beginning of a list */
- if (!prev) {
- Delattr(next,"prev"); /* Break the 'prev' link of the next node */
- Setattr(parent,"child",next); /* Update parent to point at next node */
- Delattr(obj,"next"); /* Break my link to the next object */
- return;
+Swig_save(Node **nptr, ...) {
+ va_list ap;
+ char *name;
+ DOH *obj;
+ DOH *frame;
+ Node *n = *nptr;
+
+ if ((stackp > 0) && (nodeptr_stack[stackp-1] == nptr)) {
+ frame = attr_stack[stackp-1];
+ } else {
+ if (stackp > 0) {
+ int e = 0;
+ if (!stack_direction) set_direction(1,0);
+ if (stack_direction < 0) {
+ if ((((char *) nptr) >= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
+ } else {
+ if ((((char *) nptr) <= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
+ }
+ if (e) {
+ Printf(stderr,
+"Swig_save('%s'): Fatal memory management error. If you are seeing this\n\
+message. It means that the target language module is not managing its memory\n\
+correctly. A handler for '%s' probably forgot to call Swig_restore().\n\
+Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1]));
+ assert(0);
+ }
+ }
+ attr_stack[stackp] = NewHash();
+ nodeptr_stack[stackp] = nptr;
+ node_stack[stackp] = n;
+ frame = attr_stack[stackp];
+ stackp++;
}
-
- /* In the middle of a list someplace */
- Setattr(prev,"next",next); /* Update previous node to my next node */
- Setattr(next,"prev",prev); /* Update next node to my previous node */
- Delattr(obj,"next");
- Delattr(obj,"prev");
- return;
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_node_insert()
- *
- * Inserts a node after a given node. The node to be inserted should be
- * isolated (no parent, no siblings, etc...).
- * ----------------------------------------------------------------------------- */
-
-void
-Swig_node_insert(DOH *node, DOH *newnode) {
- DOH *next;
- next = Getattr(node,"next");
-
- if (next) {
- Setattr(newnode,"next", next);
- Setattr(next,"prev", newnode);
+ va_start(ap, nptr);
+ name = va_arg(ap, char *);
+ while (name) {
+ if (*name == '*') {
+ name++;
+ } else if (*name == '?') {
+ name++;
+ }
+ obj = Getattr(n,name);
+ if (!obj) {
+ obj = DohNone;
+ }
+ if (Setattr(frame,name,obj)) {
+ Printf(stderr,"Swig_save('%s'): Warning, attribute '%s' was already saved.\n", nodeType(n), name);
+ }
+ name = va_arg(ap, char *);
}
- Setattr(node,"next",newnode);
- Setattr(newnode,"prev", node);
- Setattr(newnode,"parent", Getattr(node,"parent"));
+ va_end(ap);
+ return 1;
}
-/* -----------------------------------------------------------------------------
- * Swig_node_append_child()
- *
- * Appends a new child to a node
- * ----------------------------------------------------------------------------- */
-
-void
-Swig_node_append_child(DOH *node, DOH *chd) {
- DOH *c;
- DOH *pc;
- c = Getattr(node,"child");
- if (!c) {
- Setattr(node,"child",chd);
- Setattr(chd,"parent",node);
- return;
- }
- while (c) {
- pc = c;
- c = Getnext(c);
+void
+Swig_restore(Node **nptr) {
+ String *key;
+ Hash *frame;
+ Node *n = *nptr;
+ assert(stackp > 0);
+ if (!(nptr==nodeptr_stack[stackp-1])) {
+ Printf(stderr,
+"Swig_restore('%s'): Fatal memory management error. If you are seeing this\n\
+message. It means that the target language module is not managing its memory\n\
+correctly. A handler for '%s' probably forgot to call Swig_restore().\n\
+Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1]));
+ assert(0);
}
- Setattr(pc,"next",chd);
- Setattr(chd,"prev",pc);
- Setattr(chd,"parent",node);
-}
-
-/* -----------------------------------------------------------------------------
- * Swig_count_nodes()
- *
- * Count number of nodes at this level
- * ----------------------------------------------------------------------------- */
-
-int Swig_count_nodes(DOH *node) {
- int n = 0;
- while (node) {
- n++;
- node = Getnext(node);
+ stackp--;
+ frame = attr_stack[stackp];
+ nodeptr_stack[stackp] = 0;
+ node_stack[stackp] = 0;
+ for (key = Firstkey(frame); key; key = Nextkey(frame)) {
+ DOH *obj = Getattr(frame,key);
+ if (obj != DohNone) {
+ Setattr(n,key,obj);
+ } else {
+ Delattr(n,key);
+ }
+ Delattr(frame,key);
}
- return n;
}
-
-
-
-
-
diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c
index 3d68dd4fd..fbb5dddbd 100644
--- a/Source/Swig/typemap.c
+++ b/Source/Swig/typemap.c
@@ -9,10 +9,33 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_typemap_c[] = "$Header$";
#include "swig.h"
+/* -----------------------------------------------------------------------------
+ * Typemaps are stored in a collection of nested hash tables. Something like
+ * this:
+ *
+ * [ type ]
+ * +-------- [ name ]
+ * +-------- [ name ]
+ *
+ * Each hash table [ type ] or [ name ] then contains references to the
+ * different typemap methods. These are referenced by names such as
+ * "tmap:in", "tmap:out", "tmap:argout", and so forth.
+ *
+ * The object corresponding to a specific method has the following
+ * attributes:
+ *
+ * "type" - Typemap type
+ * "pname" - Parameter name
+ * "code" - Typemap code
+ * "typemap" - Descriptive text describing the actual map
+ * "locals" - Local variables (if any)
+ *
+ * ----------------------------------------------------------------------------- */
+
#define MAX_SCOPE 32
static Hash *typemaps[MAX_SCOPE];
@@ -33,10 +56,15 @@ void Swig_typemap_init() {
tm_scope = 0;
}
-static char *parm_key(String_or_char *pname) {
- static char temp[512] = "-";
- strcpy(temp+1,Char(pname));
- return temp;
+static String *tmop_name(const String_or_char *op) {
+ static Hash *names = 0;
+ String *s;
+ if (!names) names = NewHash();
+ s = Getattr(names,op);
+ if (s) return s;
+ s = NewStringf("tmap:%s",op);
+ Setattr(names,op,s);
+ return s;
}
/* -----------------------------------------------------------------------------
@@ -45,14 +73,9 @@ static char *parm_key(String_or_char *pname) {
* Create a new typemap scope
* ----------------------------------------------------------------------------- */
-void Swig_typemap_new_scope(Hash *oldscope) {
+void Swig_typemap_new_scope() {
tm_scope++;
- if (!oldscope) {
- typemaps[tm_scope] = NewHash();
- } else {
- typemaps[tm_scope] = oldscope;
- DohIncref(oldscope);
- }
+ typemaps[tm_scope] = NewHash();
}
/* -----------------------------------------------------------------------------
@@ -64,12 +87,7 @@ void Swig_typemap_new_scope(Hash *oldscope) {
Hash *
Swig_typemap_pop_scope() {
if (tm_scope > 0) {
- if (Len(typemaps[tm_scope])) {
- return typemaps[tm_scope--];
- } else {
- Delete(typemaps[tm_scope--]);
- return 0;
- }
+ return typemaps[tm_scope--];
}
return 0;
}
@@ -77,56 +95,96 @@ Swig_typemap_pop_scope() {
/* -----------------------------------------------------------------------------
* Swig_typemap_register()
*
- * Add a new typemap
+ * Add a new multi-valued typemap
* ----------------------------------------------------------------------------- */
void
-Swig_typemap_register(const String_or_char *op, SwigType *type, String_or_char *pname, String_or_char *code, ParmList *locals) {
- char *key;
+Swig_typemap_register(const String_or_char *op, ParmList *parms, String_or_char *code, ParmList *locals, ParmList *kwargs) {
Hash *tm;
Hash *tm1;
Hash *tm2;
+ Parm *np;
+ String *tmop;
+ SwigType *type;
+ String *pname;
+
+ if (!parms) return;
+ tmop = tmop_name(op);
+
+ /* Register the first type in the parameter list */
+
+ type = Getattr(parms,"type");
+ pname = Getattr(parms,"name");
/* See if this type has been seen before */
tm = Getattr(typemaps[tm_scope],type);
if (!tm) {
tm = NewHash();
- Setattr(typemaps[tm_scope],Char(type),tm);
+ Setattr(typemaps[tm_scope],Copy(type),tm);
Delete(tm);
}
- if ((pname) && Len(pname)) {
+ if (pname) {
/* See if parameter has been seen before */
- key = parm_key(pname);
- tm1 = Getattr(tm,key);
+ tm1 = Getattr(tm,pname);
if (!tm1) {
tm1 = NewHash();
- Setattr(tm,key,tm1);
+ Setattr(tm,NewString(pname),tm1);
Delete(tm1);
}
tm = tm1;
}
- tm2 = Getattr(tm,op);
- if (tm2) {
- SwigType *tm_type;
- String *tm_pname;
- tm_type = Getattr(tm2,"type");
- tm_pname = Getattr(tm2,"pname");
- if (Cmp(tm_type,type) || Cmp(tm_pname,pname)) {
- tm2 = 0;
- }
- }
+
+ /* Now see if this typemap op has been seen before */
+ tm2 = Getattr(tm,tmop);
if (!tm2) {
tm2 = NewHash();
- Setattr(tm,op,tm2);
+ Setattr(tm,tmop,tm2);
Delete(tm2);
}
- Setattr(tm2,"code",NewString(code));
- Setattr(tm2,"type",NewString(type));
- Setattr(tm2,"typemap",NewStringf("typemap(%s) %s", op, SwigType_str(type,pname)));
- if (pname) {
- Setattr(tm2,"pname", NewString(pname));
+
+ /* For a multi-valued typemap, the typemap code and information
+ is really only stored in the last argument. However, to
+ make this work, we perform a really neat trick using
+ the typemap operator name.
+
+ For example, consider this typemap
+
+ %typemap(in) (int foo, int *bar, char *blah[]) {
+ ...
+ }
+
+ To store it, we look at typemaps for the following:
+
+ operator type-name
+ ----------------------------------------------
+ "in" int foo
+ "in-int+foo:" int *bar
+ "in-int+foo:-p.int+bar: char *blah[]
+
+ Notice how the operator expands to encode information about
+ previous arguments.
+
+ */
+
+ np = nextSibling(parms);
+ if (np) {
+ /* Make an entirely new operator key */
+ String *newop = NewStringf("%s-%s+%s:",op,type,pname);
+ /* Now reregister on the remaining arguments */
+ Swig_typemap_register(newop,np,code,locals,kwargs);
+
+ /* Setattr(tm2,newop,newop); */
+ Delete(newop);
+ } else {
+ Setattr(tm2,"code",NewString(code));
+ Setattr(tm2,"type",Copy(type));
+ Setattr(tm2,"typemap",NewStringf("typemap(%s) %s", op, SwigType_str(type,pname)));
+ if (pname) {
+ Setattr(tm2,"pname", NewString(pname));
+ }
+ Setattr(tm2,"locals", CopyParmList(locals));
+ Setattr(tm2,"kwargs", CopyParmList(kwargs));
}
- Setattr(tm2,"locals", CopyParmList(locals));
}
/* -----------------------------------------------------------------------------
@@ -145,7 +203,7 @@ Swig_typemap_get(SwigType *type, String_or_char *name, int scope) {
return 0;
}
if ((name) && Len(name)) {
- tm1 = Getattr(tm, parm_key(name));
+ tm1 = Getattr(tm, name);
return tm1;
}
return tm;
@@ -157,108 +215,264 @@ Swig_typemap_get(SwigType *type, String_or_char *name, int scope) {
* Copy a typemap
* ----------------------------------------------------------------------------- */
-void
-Swig_typemap_copy(const String_or_char *op, SwigType *stype, String_or_char *sname,
- SwigType *ttype, String_or_char *tname) {
-
- Hash *tm=0, *tm1;
+int
+Swig_typemap_copy(const String_or_char *op, ParmList *srcparms, ParmList *parms) {
+ Hash *tm = 0;
+ String *tmop;
+ Parm *p;
+ String *pname;
+ SwigType *ptype;
int ts = tm_scope;
+ String *tmops, *newop;
+ if (ParmList_len(parms) != ParmList_len(srcparms)) return -1;
+
+ tmop = tmop_name(op);
while (ts >= 0) {
- tm = Swig_typemap_get(stype,sname,ts);
- if (tm) break;
- tm = Swig_typemap_get(stype,0,ts);
- if (tm) break;
+ p = srcparms;
+ tmops = NewString(tmop);
+ while (p) {
+ ptype = Getattr(p,"type");
+ pname = Getattr(p,"name");
+
+ /* Lookup the type */
+ tm = Swig_typemap_get(ptype,pname,ts);
+ if (!tm) break;
+
+ tm = Getattr(tm,tmops);
+ if (!tm) break;
+
+ /* Got a match. Look for next typemap */
+ newop = NewStringf("%s-%s+%s:",tmops,ptype,pname);
+ Delete(tmops);
+ tmops = newop;
+ p = nextSibling(p);
+ }
+ Delete(tmops);
+
+ if (!p && tm) {
+
+ /* Got some kind of match */
+ Swig_typemap_register(op,parms, Getattr(tm,"code"), Getattr(tm,"locals"),Getattr(tm,"kwargs"));
+ return 0;
+ }
ts--;
}
- if (!tm) return;
- tm1 = Getattr(tm,op);
- if (!tm1) return;
- Swig_typemap_register(op,ttype,tname, Getattr(tm1,"code"), Getattr(tm1,"locals"));
+ /* Not found */
+ return -1;
+
}
/* -----------------------------------------------------------------------------
* Swig_typemap_clear()
*
- * Delete a typemap
+ * Delete a multi-valued typemap
* ----------------------------------------------------------------------------- */
void
-Swig_typemap_clear(const String_or_char *op, SwigType *type, String_or_char *name) {
- Hash *tm;
+Swig_typemap_clear(const String_or_char *op, ParmList *parms) {
+ SwigType *type;
+ String *name;
+ Parm *p;
+ String *newop;
+ Hash *tm = 0;
- tm = Swig_typemap_get(type,name,tm_scope);
- if (tm)
- Delattr(tm,op);
+ /* This might not work */
+ newop = NewString(op);
+ p = parms;
+ while (p) {
+ type = Getattr(p,"type");
+ name = Getattr(p,"name");
+ tm = Swig_typemap_get(type,name,tm_scope);
+ if (!tm) return;
+ p = nextSibling(p);
+ if (p)
+ Printf(newop,"-%s+%s:", type,name);
+ }
+ if (tm) {
+ tm = Getattr(tm, tmop_name(newop));
+ if (tm) {
+ Delattr(tm,"code");
+ Delattr(tm,"locals");
+ Delattr(tm,"kwargs");
+ }
+ }
+ Delete(newop);
}
/* -----------------------------------------------------------------------------
* Swig_typemap_apply()
*
- * %apply directive. This function is nothing more than a glorified typemap
- * copy. Note: this is *very* different than SWIG1.1 although the end result
- * is very "similar."
+ * Multi-argument %apply directive. This is pretty horrible so I sure hope
+ * it works.
* ----------------------------------------------------------------------------- */
-static void merge_attributes(Hash *target, Hash *source) {
- String *key;
- for (key = Firstkey(source); key; key = Nextkey(source)) {
- /* if (Getattr(target,key)) continue; */
- Setattr(target,key,Getattr(source,key));
+static
+int count_args(String *s) {
+ /* Count up number of arguments */
+ int na = 0;
+ char *c = Char(s);
+ while (*c) {
+ if (*c == '+') na++;
+ c++;
}
+ return na;
}
-void
-Swig_typemap_apply(SwigType *tm_type, String_or_char *tmname, SwigType *type, String_or_char *pname) {
- Hash *tm, *tm1, *am;
- int ts = tm_scope;
- char *key;
+int
+Swig_typemap_apply(ParmList *src, ParmList *dest) {
+ String *ssig, *dsig;
+ Parm *p, *np, *lastp, *dp, *lastdp = 0;
+ int narg = 0;
+ int ts = tm_scope;
+ SwigType *type = 0, *name;
+ Hash *tm, *sm;
+ int match = 0;
- tm = Swig_typemap_get(type,pname,tm_scope);
- if (!tm) {
- tm = Getattr(typemaps[tm_scope],type);
- if (!tm) {
- tm = NewHash();
- Setattr(typemaps[tm_scope], Char(type), tm);
- Delete(tm);
+ /* Printf(stdout,"apply : %s --> %s\n", ParmList_str(src), ParmList_str(dest)); */
+
+ /* Create type signature of source */
+ ssig = NewString("");
+ dsig = NewString("");
+ p = src;
+ dp = dest;
+ lastp = 0;
+ while (p) {
+ lastp = p;
+ lastdp = dp;
+ np = nextSibling(p);
+ if (np) {
+ Printf(ssig,"-%s+%s:", Getattr(p,"type"), Getattr(p,"name"));
+ Printf(dsig,"-%s+%s:", Getattr(dp,"type"), Getattr(dp,"name"));
+ narg++;
}
- if ((pname) && Len(pname)) {
- key = parm_key(pname);
+ p = np;
+ dp = nextSibling(dp);
+ }
+
+ /* make sure a typemap node exists for the last destination node */
+ tm = Getattr(typemaps[tm_scope],Getattr(lastdp,"type"));
+ if (!tm) {
+ tm = NewHash();
+ Setattr(typemaps[tm_scope],Getattr(lastdp,"type"),tm);
+ Delete(tm);
+ }
+ name = Getattr(lastdp,"name");
+ if (name) {
+ Hash *tm1 = Getattr(tm,name);
+ if (!tm1) {
tm1 = NewHash();
- Setattr(tm,key,tm1);
+ Setattr(tm,NewString(name),tm1);
Delete(tm1);
- tm = tm1;
}
+ tm = tm1;
}
- /* tm contains the typemap table into which we are going to be copying */
+
+ /* This is a little nasty. We need to go searching for all possible typemaps in the
+ source and apply them to the target */
+
+ type = Getattr(lastp,"type");
+ name = Getattr(lastp,"name");
+
while (ts >= 0) {
- am = Swig_typemap_get(tm_type, tmname,ts);
- if (am) {
- merge_attributes(tm,am);
+
+ /* See if there is a matching typemap in this scope */
+ sm = Swig_typemap_get(type,name,ts);
+
+ if (sm) {
+ /* Got a typemap. Need to only merge attributes for methods that match our signature */
+ String *key;
+
+ match = 1;
+ for (key = Firstkey(sm); key; key = Nextkey(sm)) {
+ /* Check for a signature match with the source signature */
+ if ((count_args(key) == narg) && (Strstr(key,ssig))) {
+ String *oldm;
+ /* A typemap we have to copy */
+ String *nkey = Copy(key);
+ Replace(nkey,ssig,dsig,DOH_REPLACE_ANY);
+
+ /* Make sure the typemap doesn't already exist in the target map */
+
+ oldm = Getattr(tm,nkey);
+ if (!oldm || (!Getattr(tm,"code"))) {
+ String *code;
+ ParmList *locals;
+ ParmList *kwargs;
+ Hash *sm1 = Getattr(sm,key);
+
+ code = Getattr(sm1,"code");
+ locals = Getattr(sm1,"locals");
+ kwargs = Getattr(sm1,"kwargs");
+ if (code) {
+ Replace(nkey,dsig,"", DOH_REPLACE_ANY);
+ Replace(nkey,"tmap:","", DOH_REPLACE_ANY);
+ Swig_typemap_register(nkey,dest,code,locals,kwargs);
+ }
+ }
+ Delete(nkey);
+ }
+ }
}
ts--;
}
+ return match;
}
/* -----------------------------------------------------------------------------
* Swig_typemap_clear_apply()
*
- * %clear directive. Clears all typemaps for a type.
+ * %clear directive. Clears all typemaps for a type (in the current scope only).
* ----------------------------------------------------------------------------- */
+/* Multi-argument %clear directive */
void
-Swig_typemap_clear_apply(SwigType *type, String_or_char *name) {
- Hash *tm;
-
- tm = Getattr(typemaps[tm_scope],type);
- if (!tm) return;
- if ((name) && (Len(name))) {
- Delattr(tm,parm_key(name));
- } else {
- Delattr(typemaps[tm_scope],type);
+Swig_typemap_clear_apply(Parm *parms) {
+ String *tsig;
+ Parm *p, *np, *lastp;
+ int narg = 0;
+ Hash *tm;
+ String *name;
+
+ /* Create a type signature of the parameters */
+ tsig = NewString("");
+ p = parms;
+ lastp = 0;
+ while (p) {
+ lastp = p;
+ np = nextSibling(p);
+ if (np) {
+ Printf(tsig,"-%s+%s:", Getattr(p,"type"), Getattr(p,"name"));
+ narg++;
+ }
+ p = np;
+ }
+ tm = Getattr(typemaps[tm_scope],Getattr(lastp,"type"));
+ if (!tm) {
+ Delete(tsig);
+ return;
}
+ name = Getattr(lastp,"name");
+ if (name) {
+ tm = Getattr(tm,name);
+ }
+ if (tm) {
+ /* Clear typemaps that match our signature */
+ String *key, *key2;
+ for (key = Firstkey(tm); key; key = Nextkey(tm)) {
+ if (Strncmp(key,"tmap:",5) == 0) {
+ int na = count_args(key);
+ if ((na == narg) && Strstr(key,tsig)) {
+ Hash *h = Getattr(tm,key);
+ for (key2 = Firstkey(h); key2; key2 = Nextkey(h)) {
+ Delattr(h,key2);
+ }
+ }
+ }
+ }
+ }
+ Delete(tsig);
}
-
/* Internal function to strip array dimensions. */
static SwigType *strip_arrays(SwigType *type) {
SwigType *t;
@@ -272,25 +486,30 @@ static SwigType *strip_arrays(SwigType *type) {
return t;
}
+
/* -----------------------------------------------------------------------------
- * Swig_typemap_search_op()
+ * Swig_typemap_search()
*
- * Search for a typemap match.
+ * Search for a typemap match. Tries to find the most specific typemap
+ * that includes a 'code' attribute.
* ----------------------------------------------------------------------------- */
Hash *
-Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *name) {
+Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *name, SwigType **matchtype) {
Hash *result = 0, *tm, *tm1, *tma;
+ Hash *backup = 0;
SwigType *noarrays = 0;
SwigType *primitive = 0;
SwigType *ctype = 0;
int ts;
int isarray;
- char *cname = 0;
+ String *cname = 0;
+ SwigType *unstripped = 0;
+ String *tmop = tmop_name(op);
- if ((name) && Len(name)) cname = parm_key(name);
- isarray = SwigType_isarray(type);
+ if ((name) && Len(name)) cname = name;
ts = tm_scope;
+
while (ts >= 0) {
ctype = type;
while (ctype) {
@@ -299,61 +518,455 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na
if (tm && cname) {
tm1 = Getattr(tm,cname);
if (tm1) {
- result = Getattr(tm1,op); /* See if there is a type-name match */
- if (result) goto ret_result;
+ result = Getattr(tm1,tmop); /* See if there is a type-name match */
+ if (result && Getattr(result,"code")) goto ret_result;
+ if (result) backup = result;
}
}
if (tm) {
- result = Getattr(tm,op); /* See if there is simply a type match */
- if (result) goto ret_result;
+ result = Getattr(tm,tmop); /* See if there is simply a type match */
+ if (result && Getattr(result,"code")) goto ret_result;
+ if (result) backup = result;
}
-
+ isarray = SwigType_isarray(ctype);
if (isarray) {
- /* If working with arrays, strip away all of the dimensions and replace with ANY.
+ /* If working with arrays, strip away all of the dimensions and replace with "ANY".
See if that generates a match */
if (!noarrays) noarrays = strip_arrays(ctype);
tma = Getattr(typemaps[ts],noarrays);
if (tma && cname) {
tm1 = Getattr(tma,cname);
if (tm1) {
- result = Getattr(tm1,op); /* type-name match */
- if (result) goto ret_result;
+ result = Getattr(tm1,tmop); /* type-name match */
+ if (result && Getattr(result,"code")) goto ret_result;
+ if (result) backup = result;
}
}
if (tma) {
- result = Getattr(tma,op); /* type match */
- if (result) goto ret_result;
+ result = Getattr(tma,tmop); /* type match */
+ if (result && Getattr(result,"code")) goto ret_result;
+ if (result) backup = result;
}
+ Delete(noarrays);
+ noarrays = 0;
}
- /* No match so far. If this type had a typedef declaration, maybe there are
- some typemaps for that */
+ /* No match so far. If the type is unstripped, we'll strip its
+ qualifiers and check. Otherwise, we'll try to resolve a typedef */
+
+ if (!unstripped) {
+ unstripped = ctype;
+ ctype = SwigType_strip_qualifiers(ctype);
+ if (Strcmp(ctype,unstripped) != 0) continue; /* Types are different */
+ Delete(ctype);
+ ctype = unstripped;
+ unstripped = 0;
+ }
{
- SwigType *nt = SwigType_typedef_resolve(ctype);
- if (ctype != type) Delete(ctype);
- ctype = nt;
+ String *octype;
+ if (unstripped) {
+ if (unstripped != type) {
+ Delete(ctype);
+ }
+ ctype = unstripped;
+ unstripped = 0;
+ }
+ octype = ctype;
+ ctype = SwigType_typedef_resolve(ctype);
+ if (octype != type) Delete(octype);
}
}
-
+#ifdef NEW
+ /* No match seems to be found at all. Try a SWIGTYPE substitution */
+ if (!primitive) {
+ SwigType *base = SwigType_base(type);
+ primitive = SwigType_prefix(type);
+ if (Strstr(base,"enum ")) {
+ Append(primitive,"enum SWIGTYPE");
+ } else {
+ Append(primitive,"SWIGTYPE");
+ }
+ tm = Getattr(typemaps[ts],primitive);
+ if (tm && cname) {
+ tm1 = Getattr(tm, cname);
+ if (tm1) {
+ result = Getattr(tm1,tmop);
+ if (result) goto ret_result;
+ }
+ }
+ if (tm) {
+ result = Getattr(tm,tmop);
+ if (result) goto ret_result;
+ }
+ Delete(primitive);
+ primitive = 0;
+ }
+#endif
+
/* Hmmm. Well, no match seems to be found at all. See if there is some kind of default mapping */
if (!primitive)
primitive = SwigType_default(type);
tm = Getattr(typemaps[ts],primitive);
- if (tm) {
- result = Getattr(tm,op);
+ if (tm && cname) {
+ tm1 = Getattr(tm,cname);
+ if (tm1) {
+ result = Getattr(tm1,tmop); /* See if there is a type-name match */
+ if (result) goto ret_result;
+ }
+ }
+ if (tm) { /* See if there is simply a type match */
+ result = Getattr(tm,tmop);
if (result) goto ret_result;
}
if (ctype != type) Delete(ctype);
ts--; /* Hmmm. Nothing found in this scope. Guess we'll go try another scope */
}
-
+ result = backup;
+
ret_result:
if (noarrays) Delete(noarrays);
if (primitive) Delete(primitive);
+ if ((unstripped) && (unstripped != type)) Delete(unstripped);
+ if (matchtype) {
+ *matchtype = Copy(ctype);
+ }
if (type != ctype) Delete(ctype);
return result;
}
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_search_multi()
+ *
+ * Search for a multi-valued typemap.
+ * ----------------------------------------------------------------------------- */
+
+Hash *
+Swig_typemap_search_multi(const String_or_char *op, ParmList *parms, int *nmatch) {
+ SwigType *type;
+ SwigType *mtype = 0;
+ String *name;
+ String *newop;
+ Hash *tm, *tm1;
+
+ if (!parms) {
+ *nmatch = 0;
+ return 0;
+ }
+ type = Getattr(parms,"type");
+ name = Getattr(parms,"name");
+
+ /* Try to find a match on the first type */
+ tm = Swig_typemap_search(op, type, name, &mtype);
+ if (tm) {
+ if (mtype && SwigType_isarray(mtype)) {
+ Setattr(parms,"tmap:match", mtype);
+ }
+ Delete(mtype);
+ newop = NewStringf("%s-%s+%s:", op, type,name);
+ tm1 = Swig_typemap_search_multi(newop, nextSibling(parms), nmatch);
+ if (tm1) tm = tm1;
+ if (Getattr(tm,"code")) {
+ *(nmatch) = *nmatch + 1;
+ } else {
+ tm = 0;
+ }
+ Delete(newop);
+ }
+ return tm;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * typemap_replace_vars()
+ *
+ * Replaces typemap variables on a string. index is the $n variable.
+ * type and pname are the type and parameter name.
+ * ----------------------------------------------------------------------------- */
+
+static
+void replace_local_types(ParmList *p, String *name, String *rep) {
+ SwigType *t;
+ while (p) {
+ t = Getattr(p,"type");
+ Replace(t,name,rep,DOH_REPLACE_ANY);
+ p = nextSibling(p);
+ }
+}
+
+static
+void typemap_replace_vars(String *s, ParmList *locals, SwigType *type, String *pname, String *lname, int index)
+{
+ char var[512];
+ char *varname;
+ SwigType *ftype;
+
+ ftype = SwigType_typedef_resolve_all(type);
+
+ if (!pname) pname = lname;
+ {
+ Parm *p;
+ int rep = 0;
+ p = locals;
+ while (p) {
+ if (Strchr(Getattr(p,"type"),'$')) rep = 1;
+ p = nextSibling(p);
+ }
+ if (!rep) locals = 0;
+ }
+
+ sprintf(var,"$%d_",index);
+ varname = &var[strlen(var)];
+
+ /* If the original datatype was an array. We're going to go through and substitute
+ it's array dimensions */
+
+ if (SwigType_isarray(type)) {
+ String *size;
+ int ndim = SwigType_array_ndim(type);
+ int i;
+ size = NewString("");
+ for (i = 0; i < ndim; i++) {
+ String *dim = SwigType_array_getdim(type,i);
+ if (index == 1) {
+ char t[32];
+ sprintf(t,"$dim%d",i);
+ Replace(s,t,dim,DOH_REPLACE_ANY);
+ replace_local_types(locals,t,dim);
+ }
+ sprintf(varname,"dim%d",i);
+ Replace(s,var,dim,DOH_REPLACE_ANY);
+ replace_local_types(locals,var,dim);
+ if (Len(size)) Putc('*',size);
+ Append(size,dim);
+ Delete(dim);
+ }
+ sprintf(varname,"size");
+ Replace(s,var,size,DOH_REPLACE_ANY);
+ replace_local_types(locals,var,size);
+ Delete(size);
+ }
+
+ /* Parameter name substitution */
+ if (index == 1) {
+ Replace(s,"$parmname",pname, DOH_REPLACE_ANY);
+ }
+ strcpy(varname,"name");
+ Replace(s,var,pname,DOH_REPLACE_ANY);
+
+ /* Type-related stuff */
+ {
+ SwigType *star_type, *amp_type, *base_type;
+ SwigType *ltype, *star_ltype, *amp_ltype;
+ String *mangle, *star_mangle, *amp_mangle, *base_mangle;
+ String *descriptor, *star_descriptor, *amp_descriptor;
+ String *ts;
+ char *sc;
+
+ sc = Char(s);
+
+ if (strstr(sc,"type")) {
+ /* Given type : $type */
+ ts = SwigType_str(type,0);
+ if (index == 1) {
+ Replace(s, "$type", ts, DOH_REPLACE_ANY);
+ replace_local_types(locals,"$type",type);
+ }
+ strcpy(varname,"type");
+ Replace(s,var,ts,DOH_REPLACE_ANY);
+ replace_local_types(locals,var,type);
+ Delete(ts);
+ sc = Char(s);
+ }
+ if (strstr(sc,"ltype")) {
+ /* Local type: $ltype */
+ ltype = SwigType_ltype(type);
+ ts = SwigType_str(ltype,0);
+ if (index == 1) {
+ Replace(s, "$ltype", ts, DOH_REPLACE_ANY);
+ replace_local_types(locals,"$ltype",ltype);
+ }
+ strcpy(varname,"ltype");
+ Replace(s,var,ts,DOH_REPLACE_ANY);
+ replace_local_types(locals,var,ltype);
+ Delete(ts);
+ Delete(ltype);
+ sc = Char(s);
+ }
+ if (strstr(sc,"mangle") || strstr(sc,"descriptor")) {
+ /* Mangled type */
+
+ mangle = SwigType_manglestr(type);
+ if (index == 1)
+ Replace(s, "$mangle", mangle, DOH_REPLACE_ANY);
+ strcpy(varname,"mangle");
+ Replace(s,var,mangle,DOH_REPLACE_ANY);
+
+ descriptor = NewStringf("SWIGTYPE%s", mangle);
+
+ if (index == 1)
+ if (Replace(s, "$descriptor", descriptor, DOH_REPLACE_ANY))
+ SwigType_remember(type);
+
+ strcpy(varname,"descriptor");
+ if (Replace(s,var,descriptor,DOH_REPLACE_ANY))
+ SwigType_remember(type);
+
+ Delete(descriptor);
+ Delete(mangle);
+ }
+
+ /* One pointer level removed */
+ /* This creates variables of the form
+ $*n_type
+ $*n_ltype
+ */
+
+ if (SwigType_ispointer(ftype) || (SwigType_isarray(ftype)) || (SwigType_isreference(ftype))) {
+ if (!(SwigType_isarray(type) || SwigType_ispointer(type) || SwigType_isreference(type))) {
+ star_type = Copy(ftype);
+ } else {
+ star_type = Copy(type);
+ }
+ if (!SwigType_isreference(star_type)) {
+ if (SwigType_isarray(star_type)) {
+ Delete(SwigType_pop(star_type));
+ } else {
+ SwigType_del_pointer(star_type);
+ }
+ ts = SwigType_str(star_type,0);
+ if (index == 1) {
+ Replace(s, "$*type", ts, DOH_REPLACE_ANY);
+ replace_local_types(locals,"$*type",star_type);
+ }
+ sprintf(varname,"$*%d_type",index);
+ Replace(s,varname,ts,DOH_REPLACE_ANY);
+ replace_local_types(locals,varname,star_type);
+ Delete(ts);
+ } else {
+ Delete(SwigType_pop(star_type));;
+ }
+ star_ltype = SwigType_ltype(star_type);
+ ts = SwigType_str(star_ltype,0);
+ if (index == 1) {
+ Replace(s, "$*ltype", ts, DOH_REPLACE_ANY);
+ replace_local_types(locals,"$*ltype",star_ltype);
+ }
+ sprintf(varname,"$*%d_ltype",index);
+ Replace(s,varname,ts,DOH_REPLACE_ANY);
+ replace_local_types(locals,varname,star_ltype);
+ Delete(ts);
+ Delete(star_ltype);
+
+ star_mangle = SwigType_manglestr(star_type);
+ if (index == 1)
+ Replace(s, "$*mangle", star_mangle, DOH_REPLACE_ANY);
+
+ sprintf(varname,"$*%d_mangle",index);
+ Replace(s,varname,star_mangle,DOH_REPLACE_ANY);
+
+ star_descriptor = NewStringf("SWIGTYPE%s", star_mangle);
+ if (index == 1)
+ if (Replace(s, "$*descriptor",
+ star_descriptor, DOH_REPLACE_ANY))
+ SwigType_remember(star_type);
+ sprintf(varname,"$*%d_descriptor",index);
+ if (Replace(s,varname,star_descriptor,DOH_REPLACE_ANY))
+ SwigType_remember(star_type);
+
+ Delete(star_descriptor);
+ Delete(star_mangle);
+ Delete(star_type);
+ }
+ else {
+ /* TODO: Signal error if one of the $* substitutions is
+ requested */
+ }
+ /* One pointer level added */
+ amp_type = Copy(type);
+ SwigType_add_pointer(amp_type);
+ ts = SwigType_str(amp_type,0);
+ if (index == 1) {
+ Replace(s, "$&type", ts, DOH_REPLACE_ANY);
+ replace_local_types(locals,"$&type",amp_type);
+ }
+ sprintf(varname,"$&%d_type",index);
+ Replace(s,varname,ts,DOH_REPLACE_ANY);
+ replace_local_types(locals,varname,amp_type);
+ Delete(ts);
+
+ amp_ltype = SwigType_ltype(type);
+ SwigType_add_pointer(amp_ltype);
+ ts = SwigType_str(amp_ltype,0);
+
+ if (index == 1) {
+ Replace(s, "$&ltype", ts, DOH_REPLACE_ANY);
+ replace_local_types(locals, "$&ltype", amp_ltype);
+ }
+ sprintf(varname,"$&%d_ltype",index);
+ Replace(s,varname,ts,DOH_REPLACE_ANY);
+ replace_local_types(locals,varname,amp_ltype);
+ Delete(ts);
+ Delete(amp_ltype);
+
+ amp_mangle = SwigType_manglestr(amp_type);
+ if (index == 1)
+ Replace(s, "$&mangle", amp_mangle, DOH_REPLACE_ANY);
+ sprintf(varname,"$&%d_mangle",index);
+ Replace(s,varname,amp_mangle,DOH_REPLACE_ANY);
+
+ amp_descriptor = NewStringf("SWIGTYPE%s", amp_mangle);
+ if (index == 1)
+ if (Replace(s, "$&descriptor",
+ amp_descriptor, DOH_REPLACE_ANY))
+ SwigType_remember(amp_type);
+ sprintf(varname,"$&%d_descriptor",index);
+ if (Replace(s,varname,amp_descriptor,DOH_REPLACE_ANY))
+ SwigType_remember(amp_type);
+
+ Delete(amp_descriptor);
+ Delete(amp_mangle);
+ Delete(amp_type);
+
+ /* Base type */
+ if (SwigType_isarray(type)) {
+ SwigType *bt = Copy(type);
+ Delete(SwigType_pop_arrays(bt));
+ base_type = SwigType_str(bt,0);
+ Delete(bt);
+ } else {
+ base_type = SwigType_base(type);
+ }
+
+ if (index == 1) {
+ Replace(s,"$basetype", base_type, DOH_REPLACE_ANY);
+ replace_local_types(locals,"$basetype", base_type);
+ }
+ strcpy(varname,"basetype");
+ Replace(s,var,base_type,DOH_REPLACE_ANY);
+ replace_local_types(locals,var,base_type);
+
+ base_mangle = SwigType_manglestr(base_type);
+ if (index == 1)
+ Replace(s,"$basemangle", base_mangle, DOH_REPLACE_ANY);
+ strcpy(varname,"basemangle");
+ Replace(s,var,base_mangle,DOH_REPLACE_ANY);
+ Delete(base_mangle);
+ Delete(base_type);
+ }
+
+ /* Replace any $n. with (&n)-> */
+ {
+ char temp[64];
+ sprintf(var,"$%d.",index);
+ sprintf(temp,"(&$%d)->", index);
+ Replace(s,var,temp,DOH_REPLACE_ANY);
+ }
+
+ /* Replace the bare $n variable */
+ sprintf(var,"$%d",index);
+ Replace(s,var,lname,DOH_REPLACE_ANY);
+ Delete(ftype);
+}
/* ------------------------------------------------------------------------
* static typemap_locals()
@@ -362,42 +975,50 @@ Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *na
* creates the local variables.
* ------------------------------------------------------------------------ */
-static void typemap_locals(SwigType *t, String_or_char *pname, DOHString *s, ParmList *l, Wrapper *f) {
+static void typemap_locals(DOHString *s, ParmList *l, Wrapper *f, int argnum) {
Parm *p;
char *new_name;
-
+
p = l;
while (p) {
- SwigType *pt = Gettype(p);
- String *pn = Getname(p);
+ SwigType *pt = Getattr(p,"type");
+ String *pn = Getattr(p,"name");
+ String *value = Getattr(p,"value");
if (pn) {
if (Len(pn) > 0) {
- DOHString *str;
- SwigType *tt;
+ String *str;
+ int isglobal = 0;
str = NewString("");
+
+ if (Strncmp(pn,"_global_",8) == 0) {
+ isglobal = 1;
+ }
+
/* If the user gave us $type as the name of the local variable, we'll use
the passed datatype instead */
- if (Cmp(SwigType_base(pt),"$type")==0 || Cmp(SwigType_base(pt),"$basetype")==0) {
- tt = t;
+ if ((argnum >= 0) && (!isglobal)) {
+ Printf(str,"%s%d",pn,argnum);
} else {
- tt = pt;
+ Printf(str,"%s",pn);
}
- Printf(str,"%s",pn);
- /* Substitute parameter names */
- Replace(str,"$arg",pname, DOH_REPLACE_ANY);
- if (Cmp(SwigType_base(pt),"$basetype")==0) {
- /* use $basetype */
- new_name = Wrapper_new_localv(f,str,SwigType_base(tt),str,0);
- } else {
- new_name = Wrapper_new_localv(f,str, SwigType_str(tt,str), 0);
+ if (isglobal && Wrapper_check_local(f,str)) {
+ p = nextSibling(p);
+ continue;
+ }
+ if (value) {
+ new_name = Wrapper_new_localv(f,str, SwigType_str(pt,str), "=", value, NIL);
+ } else {
+ new_name = Wrapper_new_localv(f,str, SwigType_str(pt,str), NIL);
+ }
+ if (!isglobal) {
+ /* Substitute */
+ Replace(s,pn,new_name,DOH_REPLACE_ID);
}
- /* Substitute */
- Replace(s,pn,new_name,DOH_REPLACE_ID);
}
}
- p = Getnext(p);
+ p = nextSibling(p);
}
}
@@ -407,43 +1028,39 @@ static void typemap_locals(SwigType *t, String_or_char *pname, DOHString *s, Par
* Perform a typemap lookup (ala SWIG1.1)
* ----------------------------------------------------------------------------- */
-char *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname, String_or_char *source,
+String *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname,
+ String_or_char *lname, String_or_char *source,
String_or_char *target, Wrapper *f)
{
Hash *tm;
- String *s;
+ String *s = 0;
+ SwigType *mtype = 0;
ParmList *locals;
-
- tm = Swig_typemap_search(op,type,pname);
+ tm = Swig_typemap_search(op,type,pname,&mtype);
if (!tm) return 0;
s = Getattr(tm,"code");
if (!s) return 0;
+
+ /* Blocked */
+ if (Cmp(s,"pass") == 0) return 0;
+
s = Copy(s); /* Make a local copy of the typemap code */
locals = Getattr(tm,"locals");
+ if (locals) locals = CopyParmList(locals);
- /* Replace array dimensions */
- if (locals && f) {
- typemap_locals(type,pname,s,locals,f);
+ /* This is wrong. It replaces locals in place. Need to fix this */
+ if (mtype && SwigType_isarray(mtype)) {
+ typemap_replace_vars(s,locals,mtype,pname,lname,1);
+ } else {
+ typemap_replace_vars(s,locals,type,pname,lname,1);
}
- /* If the original datatype was an array. We're going to go through and substitute
- it's array dimensions */
-
- if (SwigType_isarray(type)) {
- char temp[10];
- int ndim = SwigType_array_ndim(type);
- int i;
- for (i = 0; i < ndim; i++) {
- DOHString *dim = SwigType_array_getdim(type,i);
- sprintf(temp,"$dim%d",i);
- if (f)
- Replace(Getattr(f,"locals"),temp,dim, DOH_REPLACE_ANY);
- Replace(s,temp,dim,DOH_REPLACE_ANY);
- }
+ if (locals && f) {
+ typemap_locals(s,locals,f,-1);
}
-
+
/* Now perform character replacements */
Replace(s,"$source",source,DOH_REPLACE_ANY);
Replace(s,"$target",target,DOH_REPLACE_ANY);
@@ -451,20 +1068,256 @@ char *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_ch
String *tmname = Getattr(tm,"typemap");
if (tmname) Replace(s,"$typemap",tmname, DOH_REPLACE_ANY);
}
- Replace(s,"$type",SwigType_str(type,0),DOH_REPLACE_ANY);
+ Replace(s,"$parmname",pname, DOH_REPLACE_ANY);
+ /* Replace(s,"$name",pname,DOH_REPLACE_ANY); */
+ Delete(locals);
+ Delete(mtype);
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_lookup_new()
+ *
+ * Attach one or more typemaps to a node
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f)
+{
+ SwigType *type;
+ SwigType *mtype = 0;
+ String *pname;
+ Hash *tm;
+ String *s = 0;
+ ParmList *locals;
+ ParmList *kw;
+ char temp[256];
+ String *symname;
+ String *cname = 0;
+ String *clname = 0;
+
+ type = Getattr(node,"type");
+ if (!type) return 0;
+
+ pname = Getattr(node,"name");
+ tm = Swig_typemap_search(op,type,pname,&mtype);
+ if (!tm) return 0;
+
+ s = Getattr(tm,"code");
+ if (!s) return 0;
+
+ /* Empty typemap. No match */
+ if (Cmp(s,"pass") == 0) return 0;
+
+ s = Copy(s); /* Make a local copy of the typemap code */
+
+ locals = Getattr(tm,"locals");
+ if (locals) locals = CopyParmList(locals);
+
+ if (pname) {
+ if (SwigType_istemplate(pname)) {
+ cname = SwigType_namestr(pname);
+ pname = cname;
+ }
+ }
+ if (SwigType_istemplate((char*)lname)) {
+ clname = SwigType_namestr((char *)lname);
+ lname = clname;
+ }
+ if (mtype && SwigType_isarray(mtype)) {
+ typemap_replace_vars(s,locals,mtype,pname,(char *) lname,1);
+ } else {
+ typemap_replace_vars(s,locals,type,pname,(char *) lname,1);
+ }
+ if (locals && f) {
+ typemap_locals(s,locals,f,-1);
+ }
+ {
+ String *tmname = Getattr(tm,"typemap");
+ if (tmname) Replace(s,"$typemap",tmname, DOH_REPLACE_ANY);
+ }
+ Replace(s,"$name",pname,DOH_REPLACE_ANY);
+
+ symname = Getattr(node,"sym:name");
+ if (symname) {
+ Replace(s,"$symname",symname, DOH_REPLACE_ANY);
+ }
+
+ Setattr(node,tmop_name(op),s);
+ if (locals) {
+ sprintf(temp,"%s:locals", Char(op));
+ Setattr(node,tmop_name(temp), locals);
+ Delete(locals);
+ }
+
+ if (checkAttribute(tm,"type","SWIGTYPE")) {
+ sprintf(temp,"%s:SWIGTYPE", Char(op));
+ Setattr(node,tmop_name(temp),"1");
+ }
+
+ /* Attach kwargs */
+ kw = Getattr(tm,"kwargs");
+ while (kw) {
+ sprintf(temp,"%s:%s",Char(op),Char(Getattr(kw,"name")));
+ Setattr(node,tmop_name(temp), Copy(Getattr(kw,"value")));
+ kw = nextSibling(kw);
+ }
+
+ /* Look for warnings */
{
- SwigType *ltype = Swig_clocal_type(type);
- Replace(s,"$ltype",SwigType_str(ltype,0), DOH_REPLACE_ANY);
- Delete(ltype);
+ String *w;
+ sprintf(temp,"%s:warning", Char(op));
+ w = Getattr(node,tmop_name(temp));
+ if (w) {
+ Swig_warning(0,Getfile(node),Getline(node),"%s\n", w);
+ }
}
- Replace(s,"$parmname",pname, DOH_REPLACE_ANY);
- /* Print base type (without any pointers) */
- Replace(s,"$basetype",SwigType_base(type), DOH_REPLACE_ANY);
- Replace(s,"$basemangle",SwigType_manglestr(SwigType_base(type)), DOH_REPLACE_ANY);
- Replace(s,"$mangle",SwigType_manglestr(type), DOH_REPLACE_ANY);
- Swig_temp_result(s);
- return Char(s);
+ /* Look for code fragments */
+ {
+ String *f;
+ sprintf(temp,"%s:fragment", Char(op));
+ f = Getattr(node,tmop_name(temp));
+ 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);
+ }
+ }
+
+ if (cname) Delete(cname);
+ if (clname) Delete(clname);
+ if (mtype) Delete(mtype);
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_attach_parms()
+ *
+ * Given a parmeter list, this function attaches all of the typemaps for a
+ * given typemap type
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f) {
+ Parm *p, *firstp;
+ Hash *tm;
+ int nmatch = 0;
+ int i;
+ String *s;
+ ParmList *locals;
+ int argnum = 0;
+ char temp[256];
+ Parm *kw;
+
+ p = parms;
+ while (p) {
+ argnum++;
+ nmatch = 0;
+ tm = Swig_typemap_search_multi(op,p,&nmatch);
+ if (!tm) {
+ p = nextSibling(p);
+ continue;
+ }
+ s = Getattr(tm,"code");
+ if (!s) {
+ p = nextSibling(p);
+ continue;
+ }
+
+ /* Empty typemap. No match */
+ if (Cmp(s,"pass") == 0) {
+ p = nextSibling(p);
+ continue;
+ }
+
+ s = Copy(s);
+ locals = Getattr(tm,"locals");
+ if (locals) locals = CopyParmList(locals);
+ firstp = p;
+ for (i = 0; i < nmatch; i++) {
+ SwigType *type;
+ String *pname;
+ String *lname;
+ SwigType *mtype;
+
+ type = Getattr(p,"type");
+ pname = Getattr(p,"name");
+ lname = Getattr(p,"lname");
+ mtype = Getattr(p,"tmap:match");
+
+ if (mtype) {
+ typemap_replace_vars(s,locals, mtype,pname,lname,i+1);
+ Delattr(p,"tmap:match");
+ } else {
+ typemap_replace_vars(s,locals, type,pname,lname,i+1);
+ }
+ if (checkAttribute(tm,"type","SWIGTYPE")) {
+ sprintf(temp,"%s:SWIGTYPE", Char(op));
+ Setattr(p,tmop_name(temp),"1");
+ }
+ p = nextSibling(p);
+ }
+
+ if (locals && f) {
+ typemap_locals(s,locals,f,argnum);
+ }
+
+ /* Replace the argument number */
+ sprintf(temp,"%d",argnum);
+ Replace(s,"$argnum",temp, DOH_REPLACE_ANY);
+
+ /* Attach attributes to object */
+ Setattr(firstp,tmop_name(op),s); /* Code object */
+
+ if (locals) {
+ sprintf(temp,"%s:locals", Char(op));
+ Setattr(firstp,tmop_name(temp), locals);
+ Delete(locals);
+ }
+
+ /* Attach a link to the next parameter. Needed for multimaps */
+ sprintf(temp,"%s:next",Char(op));
+ Setattr(firstp,tmop_name(temp),p);
+
+ /* Attach kwargs */
+ kw = Getattr(tm,"kwargs");
+ while (kw) {
+ sprintf(temp,"%s:%s",Char(op),Char(Getattr(kw,"name")));
+ Setattr(firstp,tmop_name(temp), Copy(Getattr(kw,"value")));
+ kw = nextSibling(kw);
+ }
+ {
+ String *w;
+ sprintf(temp,"%s:warning", Char(op));
+ w = Getattr(firstp,tmop_name(temp));
+ if (w) {
+ Swig_warning(0,Getfile(firstp), Getline(firstp), "%s\n", w);
+ }
+ }
+ /* Look for code fragments */
+ {
+ String *f;
+ sprintf(temp,"%s:fragment", Char(op));
+ f = Getattr(firstp,tmop_name(temp));
+ 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);
+ }
+ }
+ }
}
/* -----------------------------------------------------------------------------
@@ -483,37 +1336,4 @@ void Swig_typemap_debug() {
}
Printf(stdout,"-----------------------------------------------------------------------------\n");
}
-
-
-/* -----------------------------------------------------------------------------
- * %except directive support.
- *
- * These functions technically don't really have anything to do with typemaps
- * except that they have the same scoping rules. Therefore, it's easy enough to
- * just use the hash table structure of the typemap code.
- * ----------------------------------------------------------------------------- */
-
-void Swig_except_register(String_or_char *code) {
- String *s = NewString(code);
- Setattr(typemaps[tm_scope],"*except*",s);
- Delete(s);
-}
-char *Swig_except_lookup() {
- String *s;
- int ts = tm_scope;
- while (ts >= 0) {
- s = Getattr(typemaps[tm_scope],"*except*");
- if (s) {
- s = Copy(s);
- Swig_temp_result(s);
- return Char(s);
- }
- ts--;
- }
- return 0;
-}
-
-void Swig_except_clear() {
- Delattr(typemaps[tm_scope],"*except*");
-}
diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c
new file mode 100644
index 000000000..65df2f882
--- /dev/null
+++ b/Source/Swig/typesys.c
@@ -0,0 +1,1609 @@
+/* -----------------------------------------------------------------------------
+ * typesys.c
+ *
+ * SWIG type system management. These functions are used to manage
+ * the C++ type system including typenames, typedef, type scopes,
+ * inheritance, and namespaces. Generation of support code for the
+ * run-time type checker is also handled here.
+ *
+ * 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_typesys_c[] = "$Header$";
+
+#include "swig.h"
+
+/* -----------------------------------------------------------------------------
+ * Synopsis
+ *
+ * The purpose of this module is to manage type names and scoping issues related
+ * to the C++ type system. The primary use is tracking typenames through typedef
+ * and inheritance.
+ *
+ * New typenames are introduced by typedef, class, and enum declarations.
+ * Each type is declared in a scope. This is either the global scope, a
+ * class, or a namespace. For example:
+ *
+ * typedef int A; // Typename A, in global scope
+ * namespace Foo {
+ * typedef int A; // Typename A, in scope Foo::
+ * }
+ * class Bar { // Typename Bar, in global scope
+ * typedef int A; // Typename A, in scope Bar::
+ * }
+ *
+ * To manage scopes, the type system is constructed as a tree of hash tables. Each
+ * hash table contains the following attributes:
+ *
+ * "name" - Scope name
+ * "qname" - Fully qualified typename
+ * "typetab" - Type table containing typenames and typedef information
+ * "symtab" - Hash table of symbols defined in a scope
+ * "inherit" - List of inherited scopes
+ * "parent" - Parent scope
+ *
+ * Typedef information is stored in the "typetab" hash table. For example,
+ * if you have these declarations:
+ *
+ * typedef int A;
+ * typedef A B;
+ * typedef B *C;
+ *
+ * typetab is built as follows:
+ *
+ * "A" : "int"
+ * "B" : "A"
+ * "C" : "p.B"
+ *
+ * To resolve a type back to its root type, one repeatedly expands on the type base.
+ * For example:
+ *
+ * C *[40] ---> a(40).p.C (string type representation, see stype.c)
+ * ---> a(40).p.p.B (C --> p.B)
+ * ---> a(40).p.p.A (B --> A)
+ * ---> a(40).p.p.int (A --> int)
+ *
+ * For inheritance, SWIG tries to resolve types back to the base class. For instance, if
+ * you have this:
+ *
+ * class Foo {
+ * public:
+ * typedef int Integer;
+ * };
+ *
+ * class Bar : public Foo {
+ * void blah(Integer x);
+ * }
+ *
+ * The argument type of Bar::blah will be set to Foo::Integer.
+ *
+ * The scope-inheritance mechanism is used to manage C++ namespace aliases.
+ * For example, if you have this:
+ *
+ * namespace Foo {
+ * typedef int Integer;
+ * }
+ *
+ * namespace F = Foo;
+ *
+ * In this case, "F::" is defined as a scope that "inherits" from Foo. Internally,
+ * "F::" will merely be an empty scope that refers to Foo. SWIG will never
+ * place new type information into a namespace alias---attempts to do so
+ * will generate a warning message (in the parser) and will place information into
+ * Foo instead.
+ *
+ *----------------------------------------------------------------------------- */
+
+static Typetab *current_scope = 0; /* Current type scope */
+static Hash *current_typetab = 0; /* Current type table */
+static Hash *current_symtab = 0; /* Current symbol table */
+static Typetab *global_scope = 0; /* The global scope */
+static Hash *scopes = 0; /* Hash table containing fully qualified scopes */
+
+/* Performance optimization */
+static Hash *typedef_resolve_cache = 0;
+static Hash *typedef_all_cache = 0;
+static Hash *typedef_qualified_cache = 0;
+
+static void flush_cache() {
+ typedef_resolve_cache = 0;
+ typedef_all_cache = 0;
+ typedef_qualified_cache = 0;
+}
+
+/* Initialize the scoping system */
+
+void SwigType_typesystem_init() {
+ if (global_scope) Delete(global_scope);
+ if (scopes) Delete(scopes);
+
+ current_scope = NewHash();
+ global_scope = current_scope;
+
+ Setattr(current_scope,"name",""); /* No name for global scope */
+ current_typetab = NewHash();
+ Setattr(current_scope,"typetab", current_typetab);
+
+ current_symtab = 0;
+ scopes = NewHash();
+ Setattr(scopes,"",current_scope);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_typedef()
+ *
+ * Defines a new typedef in the current scope. Returns -1 if the type name is
+ * already defined.
+ * ----------------------------------------------------------------------------- */
+
+int SwigType_typedef(SwigType *type, String_or_char *name) {
+ Typetab *SwigType_find_scope(Typetab *, String *s);
+ if (Getattr(current_typetab, name)) return -1; /* Already defined */
+ if (Strcmp(type,name) == 0) { /* Can't typedef a name to itself */
+ return 0;
+ }
+
+ /* Check if 'type' is already a scope. If so, we create an alias in the type
+ system for it. This is needed to make strange nested scoping problems work
+ correctly. */
+ {
+ Typetab *t = SwigType_find_scope(current_scope,type);
+ if (t) {
+ SwigType_new_scope(name);
+ SwigType_inherit_scope(t);
+ SwigType_pop_scope();
+ }
+ }
+ Setattr(current_typetab,name,type);
+ flush_cache();
+ return 0;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_typedef_class()
+ *
+ * Defines a class in the current scope.
+ * ----------------------------------------------------------------------------- */
+
+int SwigType_typedef_class(String_or_char *name) {
+ String *cname;
+ /* Printf(stdout,"class : '%s'\n", name); */
+ if (Getattr(current_typetab, name)) return -1; /* Already defined */
+ cname = NewString(name);
+ Setmeta(cname,"class","1");
+ Setattr(current_typetab,cname,cname);
+ flush_cache();
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_scope_name()
+ *
+ * Returns the qualified scope name of a type table
+ * ----------------------------------------------------------------------------- */
+
+String *
+SwigType_scope_name(Typetab *ttab) {
+ String *qname = NewString(Getattr(ttab,"name"));
+ ttab = Getattr(ttab,"parent");
+ while (ttab) {
+ String *pname = Getattr(ttab,"name");
+ if (Len(pname)) {
+ Insert(qname,0,"::");
+ Insert(qname,0,pname);
+ }
+ ttab = Getattr(ttab,"parent");
+ }
+ return qname;
+}
+/* -----------------------------------------------------------------------------
+ * SwigType_new_scope()
+ *
+ * Creates a new scope
+ * ----------------------------------------------------------------------------- */
+
+void SwigType_new_scope(String_or_char *name) {
+ Typetab *s;
+ Hash *ttab;
+ String *qname;
+
+ if (!name) {
+ name = "<unnamed>";
+ }
+ s = NewHash();
+ Setattr(s,"name", name);
+ Setattr(s,"parent", current_scope);
+ ttab = NewHash();
+ Setattr(s,"typetab", ttab);
+
+ /* Build fully qualified name and */
+ qname = SwigType_scope_name(s);
+ Setattr(scopes,qname,s);
+ Setattr(s,"qname",qname);
+ Delete(qname);
+
+ current_scope = s;
+ current_typetab = ttab;
+ current_symtab = 0;
+ flush_cache();
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_inherit_scope()
+ *
+ * Makes the current scope inherit from another scope. This is used for both
+ * C++ class inheritance, namespaces, and namespace aliases.
+ * ----------------------------------------------------------------------------- */
+
+void
+SwigType_inherit_scope(Typetab *scope) {
+ List *inherits;
+ int i, len;
+ inherits = Getattr(current_scope,"inherit");
+ if (!inherits) {
+ inherits = NewList();
+ Setattr(current_scope,"inherit", inherits);
+ }
+ assert(scope != current_scope);
+
+ len = Len(inherits);
+ for (i = 0; i < len; i++) {
+ Node *n = Getitem(inherits,i);
+ if (n == scope) return;
+ }
+ Append(inherits,scope);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_scope_alias()
+ *
+ * Creates a scope-alias.
+ * ----------------------------------------------------------------------------- */
+
+void
+SwigType_scope_alias(String *aliasname, Typetab *ttab) {
+ String *q;
+ /* Printf(stdout,"alias: '%s' '%x'\n", aliasname, ttab);*/
+ q = SwigType_scope_name(current_scope);
+ if (Len(q)) {
+ Append(q,"::");
+ }
+ Append(q,aliasname);
+ Setattr(scopes,q,ttab);
+ flush_cache();
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_using_scope()
+ *
+ * Import another scope into this scope.
+ * ----------------------------------------------------------------------------- */
+
+void
+SwigType_using_scope(Typetab *scope) {
+ SwigType_inherit_scope(scope);
+ {
+ List *ulist;
+ int i, len;
+ ulist = Getattr(current_scope,"using");
+ if (!ulist) {
+ ulist = NewList();
+ Setattr(current_scope,"using", ulist);
+ }
+ assert(scope != current_scope);
+ len = Len(ulist);
+ for (i = 0; i < len; i++) {
+ Typetab *n = Getitem(ulist,i);
+ if (n == scope) return;
+ }
+ Append(ulist,scope);
+ }
+ flush_cache();
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_pop_scope()
+ *
+ * Pop off the last scope and perform a merge operation. Returns the hash
+ * table for the scope that was popped off.
+ * ----------------------------------------------------------------------------- */
+
+Typetab *SwigType_pop_scope() {
+ Typetab *s, *s1;
+ s = Getattr(current_scope,"parent");
+ if (!s) {
+ current_scope = 0;
+ current_typetab = 0;
+ current_symtab = 0;
+ return 0;
+ }
+ s1 = current_scope;
+ current_scope = s;
+ current_typetab = Getattr(s,"typetab");
+ current_symtab = Getattr(s,"symtab");
+ flush_cache();
+ return s1;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_set_scope()
+ *
+ * Set the scope. Returns the old scope.
+ * ----------------------------------------------------------------------------- */
+
+Typetab *
+SwigType_set_scope(Typetab *t) {
+ Typetab *old = current_scope;
+ if (!t) t = global_scope;
+ current_scope = t;
+ current_typetab = Getattr(t,"typetab");
+ current_symtab = Getattr(t,"symtab");
+ flush_cache();
+ return old;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_attach_symtab()
+ *
+ * Attaches a symbol table to a type scope
+ * ----------------------------------------------------------------------------- */
+
+void
+SwigType_attach_symtab(Symtab *sym) {
+ Setattr(current_scope,"symtab",sym);
+ current_symtab = sym;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_print_scope()
+ *
+ * Debugging function for printing out current scope
+ * ----------------------------------------------------------------------------- */
+
+void SwigType_print_scope(Typetab *t) {
+ String *key;
+ Hash *ttab;
+ String *tkey;
+
+ for (tkey = Firstkey(scopes); tkey; tkey = Nextkey(scopes)) {
+ t = Getattr(scopes,tkey);
+ ttab = Getattr(t,"typetab");
+
+ Printf(stdout,"Type scope '%s' (%x)\n", tkey, t);
+ {
+ List *inherit = Getattr(t,"inherit");
+ if (inherit) {
+ Typetab *it;
+ for (it = Firstitem(inherit); it; it = Nextitem(inherit)) {
+ Printf(stdout," Inherits from '%s' (%x)\n", Getattr(it,"qname"), it);
+ }
+ }
+ }
+ Printf(stdout,"-------------------------------------------------------------\n");
+ for (key = Firstkey(ttab); key; key = Nextkey(ttab)) {
+ Printf(stdout,"%40s -> %s\n", key, Getattr(ttab,key));
+ }
+ }
+}
+
+Typetab *
+SwigType_find_scope(Typetab *s, String *nameprefix) {
+ Typetab *ss;
+ String *nnameprefix = 0;
+ static int check_parent = 1;
+
+ /* Printf(stdout,"find_scope: %x(%s) '%s'\n", s, Getattr(s,"name"), nameprefix); */
+
+ if (SwigType_istemplate(nameprefix)) {
+ nnameprefix = SwigType_typedef_resolve_all(nameprefix);
+ nameprefix = nnameprefix;
+ }
+
+ ss = s;
+ while (ss) {
+ String *full;
+ String *qname = Getattr(ss,"qname");
+ if (qname) {
+ full = NewStringf("%s::%s", qname, nameprefix);
+ } else {
+ full = NewString(nameprefix);
+ }
+ if (Getattr(scopes,full)) {
+ s = Getattr(scopes,full);
+ } else {
+ s = 0;
+ }
+ Delete(full);
+ if (s) {
+ if (nnameprefix) Delete(nnameprefix);
+ return s;
+ }
+ if (!s) {
+ /* Check inheritance */
+ List *inherit;
+ inherit = Getattr(ss,"using");
+ if (inherit) {
+ Typetab *ttab;
+ int i, len;
+ len = Len(inherit);
+ for (i = 0; i < len; i++) {
+ int oldcp = check_parent;
+ ttab = Getitem(inherit,i);
+ check_parent = 0;
+ s = SwigType_find_scope(ttab,nameprefix);
+ check_parent = oldcp;
+ if (s) {
+ if (nnameprefix) Delete(nnameprefix);
+ return s;
+ }
+ }
+ }
+ }
+ if (!check_parent) break;
+ ss = Getattr(ss,"parent");
+ }
+ if (nnameprefix) Delete(nnameprefix);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_typedef_resolve()
+ *
+ * Resolves a typedef and returns a new type string. Returns 0 if there is no
+ * typedef mapping. base is a name without qualification.
+ * ----------------------------------------------------------------------------- */
+
+static Typetab *resolved_scope = 0;
+
+/* Internal function */
+static SwigType *
+typedef_resolve(Typetab *s, String *base) {
+ Hash *ttab;
+ SwigType *type;
+ List *inherit;
+
+ if (!s) return 0;
+ /* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */
+
+ if (Getmark(s)) return 0;
+ Setmark(s,1);
+
+ ttab = Getattr(s,"typetab");
+ type = Getattr(ttab,base);
+ if (type) {
+ resolved_scope = s;
+ Setmark(s,0);
+ return type;
+ }
+ /* Hmmm. Not found in my scope. It could be in an inherited scope */
+ inherit = Getattr(s,"inherit");
+ if (inherit) {
+ int i,len;
+ len = Len(inherit);
+ for (i = 0; i < len; i++) {
+ type = typedef_resolve(Getitem(inherit,i), base);
+ if (type) {
+ Setmark(s,0);
+ return type;
+ }
+ }
+ }
+ type = typedef_resolve(Getattr(s,"parent"), base);
+ Setmark(s,0);
+ return type;
+}
+
+SwigType *SwigType_typedef_resolve(SwigType *t) {
+ String *base;
+ String *type = 0;
+ String *r = 0;
+ Typetab *s;
+ Hash *ttab;
+ String *namebase = 0;
+ String *nameprefix = 0;
+ int newtype = 0;
+
+ resolved_scope = 0;
+
+ if (!typedef_resolve_cache) {
+ typedef_resolve_cache = NewHash();
+ }
+ /*
+ r = Getattr(typedef_resolve_cache,t);
+ if (r) {
+ if (r != DohNone) {
+ resolved_scope = Getmeta(r,"scope");
+ return Copy(r);
+ } else {
+ return 0;
+ }
+ }
+*/
+
+ base = SwigType_base(t);
+
+ /* Printf(stdout,"base = '%s'\n", base); */
+
+ if (SwigType_issimple(base)) {
+ s = current_scope;
+ ttab = current_typetab;
+ if (Strncmp(base,"::",2) == 0) {
+ s = global_scope;
+ ttab = Getattr(s,"typetab");
+ Delitem(base,0);
+ Delitem(base,0);
+ }
+ /* Do a quick check in the local scope */
+ type = Getattr(ttab,base);
+ if (type) {
+ resolved_scope = s;
+ }
+ if (!type) {
+ /* Didn't find in this scope. We need to do a little more searching */
+ if (Swig_scopename_check(base)) {
+ /* A qualified name. */
+ nameprefix = Swig_scopename_prefix(base);
+ /* Printf(stdout,"nameprefix = '%s'\n", nameprefix);*/
+ if (nameprefix) {
+ /* Name had a prefix on it. See if we can locate the proper scope for it */
+ s = SwigType_find_scope(s,nameprefix);
+ /* Couldn't locate a scope for the type. */
+ if (!s) {
+ Delete(base);
+ Delete(nameprefix);
+ r = 0;
+ goto return_result;
+ }
+ /* Try to locate the name starting in the scope */
+ namebase = Swig_scopename_last(base);
+ /* Printf(stdout,"namebase = '%s'\n", namebase); */
+ type = typedef_resolve(s,namebase);
+ /* Printf(stdout,"%s type = '%s'\n", Getattr(s,"name"), type); */
+ if ((type) && (!Swig_scopename_check(type))) {
+ Typetab *rtab = resolved_scope;
+ String *qname = Getattr(resolved_scope,"qname");
+ /* If qualified *and* the typename is defined from the resolved scope, we qualify */
+ if ((qname) && typedef_resolve(resolved_scope,type)) {
+ type = Copy(type);
+ Insert(type,0,"::");
+ Insert(type,0,qname);
+ newtype = 1;
+ }
+ resolved_scope = rtab;
+ }
+ } else {
+ /* Name is unqualified. */
+ type = typedef_resolve(s,base);
+ }
+ } else {
+ /* Name is unqualified. */
+ type = typedef_resolve(s,base);
+ }
+ }
+
+ if (type && (Strcmp(base,type) == 0)) {
+ Delete(base);
+ r = 0;
+ goto return_result;
+ }
+
+ /* If the type is a template, and no typedef was found, we need to check the
+ template arguments one by one to see if they can be resolved. */
+
+ if (!type && SwigType_istemplate(base)) {
+ List *tparms;
+ String *suffix;
+ int i,sz;
+ int rep = 0;
+ type = SwigType_templateprefix(base);
+ suffix = SwigType_templatesuffix(base);
+ Append(type,"<(");
+ tparms = SwigType_parmlist(base);
+ sz = Len(tparms);
+ for (i = 0; i < sz; i++) {
+ SwigType *tpr;
+ SwigType *tp = Getitem(tparms, i);
+ if (!rep) {
+ tpr = SwigType_typedef_resolve(tp);
+ } else {
+ tpr = 0;
+ }
+ if (tpr) {
+ Append(type,tpr);
+ rep = 1;
+ } else {
+ Append(type,tp);
+ }
+ if ((i+1) < sz) Append(type,",");
+ }
+ Append(type,")>");
+ Append(type,suffix);
+ Delete(suffix);
+ Delete(tparms);
+ if (!rep) {
+ Delete(type);
+ type = 0;
+ }
+ }
+ if (namebase) Delete(namebase);
+ if (nameprefix) Delete(nameprefix);
+ } else {
+ if (SwigType_isfunction(base)) {
+ List *parms;
+ int i,sz;
+ int rep = 0;
+ type = NewString("f(");
+ parms = SwigType_parmlist(base);
+ sz = Len(parms);
+ for (i = 0; i < sz; i++) {
+ SwigType *tpr;
+ SwigType *tp = Getitem(parms, i);
+ if (!rep) {
+ tpr = SwigType_typedef_resolve(tp);
+ } else {
+ tpr = 0;
+ }
+ if (tpr) {
+ Append(type,tpr);
+ rep = 1;
+ } else {
+ Append(type,tp);
+ }
+ if ((i+1) < sz) Append(type,",");
+ }
+ Append(type,").");
+ Delete(parms);
+ if (!rep) {
+ Delete(type);
+ type = 0;
+ }
+ } else if (SwigType_ismemberpointer(base)) {
+ String *rt;
+ String *mtype = SwigType_parm(base);
+ rt = SwigType_typedef_resolve(mtype);
+ if (rt) {
+ type = NewStringf("m(%s).", rt);
+ Delete(rt);
+ }
+ Delete(mtype);
+ } else {
+ type = 0;
+ }
+ }
+ r = SwigType_prefix(t);
+ if (!type) {
+ if (r && Len(r)) {
+ if ((Strstr(r,"f(") || (Strstr(r,"m(")))) {
+ SwigType *rt = SwigType_typedef_resolve(r);
+ if (rt) {
+ Delete(r);
+ Append(rt,base);
+ Delete(base);
+ r = rt;
+ goto return_result;
+ }
+ }
+ }
+ Delete(r);
+ Delete(base);
+ r = 0;
+ goto return_result;
+ }
+ Delete(base);
+ Append(r,type);
+ if (newtype) {
+ Delete(type);
+ }
+
+ return_result:
+ if (!r) {
+ Setattr(typedef_resolve_cache,NewString(t),DohNone);
+ } else {
+ Setattr(typedef_resolve_cache,NewString(t),r);
+ Setmeta(r,"scope",resolved_scope);
+ r = Copy(r);
+ }
+ return r;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_typedef_resolve_all()
+ *
+ * Fully resolve a type down to its most basic datatype
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_typedef_resolve_all(SwigType *t) {
+ SwigType *n;
+ SwigType *r;
+
+ if (!typedef_all_cache) {
+ typedef_all_cache = NewHash();
+ }
+ r = Getattr(typedef_all_cache,t);
+ if (r) {
+ return Copy(r);
+ }
+ r = NewString(t);
+ while ((n = SwigType_typedef_resolve(r))) {
+ Delete(r);
+ r = n;
+ }
+ {
+ SwigType *rr = Copy(r);
+ Setattr(typedef_all_cache,NewString(t),rr);
+ }
+ return r;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_typedef_qualified()
+ *
+ * Given a type declaration, this function tries to fully qualify it according to
+ * typedef scope rules.
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_typedef_qualified(SwigType *t)
+{
+ List *elements;
+ String *result;
+ int i,len;
+
+ if (!typedef_qualified_cache) typedef_qualified_cache = NewHash();
+ result = Getattr(typedef_qualified_cache,t);
+ if (result) {
+ String *rc = Copy(result);
+ return rc;
+ }
+ result = NewString("");
+ elements = SwigType_split(t);
+ len = Len(elements);
+ for (i = 0; i < len; i++) {
+ String *e = Getitem(elements,i);
+ if (SwigType_issimple(e)) {
+ if (!SwigType_istemplate(e)) {
+ String *isenum = 0;
+ if (SwigType_isenum(e)) {
+ isenum = e;
+ e = NewString(Char(e)+5);
+ }
+ resolved_scope = 0;
+ if (typedef_resolve(current_scope,e)) {
+ /* resolved_scope contains the scope that actually resolved the symbol */
+ String *qname = Getattr(resolved_scope,"qname");
+ if (qname) {
+ Insert(e,0,"::");
+ Insert(e,0,qname);
+ if (isenum) {
+ Clear(isenum);
+ Printf(isenum, "enum %s", e);
+ Delete(e);
+ }
+ }
+ } else {
+
+ if (Swig_scopename_check(e)) {
+ String *tqname;
+ String *qlast;
+ String *qname = Swig_scopename_prefix(e);
+ if (qname) {
+ qlast = Swig_scopename_last(e);
+ tqname = SwigType_typedef_qualified(qname);
+ Clear(e);
+ Printf(e,"%s::%s", tqname, qlast);
+ Delete(qname);
+ Delete(qlast);
+ Delete(tqname);
+ }
+ /* Automatic template instantiation might go here??? */
+
+ }
+ }
+ if (isenum) e = isenum;
+
+ } else {
+ /* Template. We need to qualify template parameters as well as the template itself */
+ String *tprefix, *qprefix;
+ String *tsuffix;
+ Parm *p;
+ List *parms = SwigType_parmlist(e);
+ tprefix = SwigType_templateprefix(e);
+ tsuffix = SwigType_templatesuffix(e);
+ qprefix = SwigType_typedef_qualified(tprefix);
+ Printf(qprefix,"<(");
+ p = Firstitem(parms);
+ while (p) {
+ String *qt = SwigType_typedef_qualified(p);
+ if ((Strcmp(qt,p) == 0)) { /* && (!Swig_scopename_check(qt))) { */
+ /* No change in value. It is entirely possible that the parameter is an integer value.
+ If there is a symbol table associated with this scope, we're going to check for this */
+
+ if (current_symtab) {
+ Node *lastnode = 0;
+ String *value = Copy(p);
+ while (1) {
+ Node *n = Swig_symbol_clookup(value,current_symtab);
+ if (n == lastnode) break;
+ lastnode = n;
+ if (n) {
+ if (Strcmp(nodeType(n),"enumitem") == 0) {
+ /* An enum item. Generate a fully qualified name */
+ String *qn = Swig_symbol_qualified(n);
+ if (Len(qn)) {
+ Append(qn,"::");
+ Append(qn,Getattr(n,"name"));
+ Delete(value);
+ value = qn;
+ continue;
+ } else {
+ break;
+ }
+ } else if ((Strcmp(nodeType(n),"cdecl") == 0) && (Getattr(n,"value"))) {
+ Delete(value);
+ value = Copy(Getattr(n,"value"));
+ continue;
+ }
+ }
+ break;
+ }
+ Append(qprefix,value);
+ } else {
+ Append(qprefix,p);
+ }
+ } else {
+ Append(qprefix,qt);
+ }
+ Delete(qt);
+ p= Nextitem(parms);
+ if (p) {
+ Append(qprefix,",");
+ }
+ }
+ Append(qprefix,")>");
+ Append(qprefix,tsuffix);
+ Delete(tsuffix);
+ Clear(e);
+ Append(e,qprefix);
+ Delete(tprefix);
+ Delete(qprefix);
+ }
+ if (Strncmp(e,"::",2) == 0) {
+ Delitem(e,0);
+ Delitem(e,0);
+ }
+ Append(result,e);
+ } else if (SwigType_isfunction(e)) {
+ List *parms = SwigType_parmlist(e);
+ String *s = NewString("f(");
+ String *p;
+ p = Firstitem(parms);
+ while (p) {
+ Append(s,SwigType_typedef_qualified(p));
+ p = Nextitem(parms);
+ if (p) {
+ Append(s,",");
+ }
+ }
+ Append(s,").");
+ Append(result,s);
+ Delete(s);
+ } else if (SwigType_isarray(e)) {
+ String *ndim;
+ String *dim = SwigType_parm(e);
+ ndim = Swig_symbol_string_qualify(dim,0);
+ Printf(result,"a(%s).",ndim);
+ Delete(dim);
+ Delete(ndim);
+ } else {
+ Append(result,e);
+ }
+ }
+ Delete(elements);
+ Setattr(typedef_qualified_cache,NewString(t),NewString(result));
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_istypedef()
+ *
+ * Checks a typename to see if it is a typedef.
+ * ----------------------------------------------------------------------------- */
+
+int SwigType_istypedef(SwigType *t) {
+ String *type;
+
+ type = SwigType_typedef_resolve(t);
+ if (type) {
+ Delete(type);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_typedef_using()
+ *
+ * Processes a 'using' declaration to import types from one scope into another.
+ * Name is a qualified name like A::B.
+ * ----------------------------------------------------------------------------- */
+
+int SwigType_typedef_using(String_or_char *name) {
+ String *base;
+ String *td;
+ String *prefix;
+ Typetab *s;
+ Typetab *tt = 0;
+
+ String *defined_name = 0;
+
+ /* Printf(stdout,"using %s\n", name);*/
+
+ if (!Swig_scopename_check(name)) return -1; /* Not properly qualified */
+ base = Swig_scopename_last(name);
+
+ /* See if the base is already defined in this scope */
+ if (Getattr(current_typetab,base)) {
+ Delete(base);
+ return -1;
+ }
+
+ /* See if the using name is a scope */
+ /* tt = SwigType_find_scope(current_scope,name);
+ Printf(stdout,"tt = %x, name = '%s'\n", tt, name); */
+
+ /* We set up a typedef B --> A::B */
+ Setattr(current_typetab,base,name);
+
+ /* Find the scope name where the symbol is defined */
+ td = SwigType_typedef_resolve(name);
+ /* Printf(stdout,"td = '%s' %x\n", td, resolved_scope); */
+ if (resolved_scope) {
+ defined_name = Getattr(resolved_scope,"qname");
+ if (defined_name) {
+ defined_name = Copy(defined_name);
+ Append(defined_name,"::");
+ Append(defined_name,base);
+ }
+ }
+ if (td) Delete(td);
+
+ /* Printf(stdout,"defined_name = '%s'\n", defined_name);*/
+ tt = SwigType_find_scope(current_scope,defined_name);
+
+ /* Figure out the scope the using directive refers to */
+ {
+ prefix = Swig_scopename_prefix(name);
+ s = SwigType_find_scope(current_scope,prefix);
+ if (s) {
+ Hash *ttab = Getattr(s,"typetab");
+ if (!Getattr(ttab,base) && defined_name) {
+ Setattr(ttab,base, defined_name);
+ }
+ }
+ }
+
+ if (tt) {
+ /* Using directive had it's own scope. We need to do create a new scope for it */
+ SwigType_new_scope(base);
+ SwigType_inherit_scope(tt);
+ SwigType_pop_scope();
+ }
+
+ if (defined_name) Delete(defined_name);
+ Delete(prefix);
+ Delete(base);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_isclass()
+ *
+ * Determines if a type defines a class or not. A class is defined by
+ * its type-table entry maps to itself. Note: a pointer to a class is not
+ * a class.
+ * ----------------------------------------------------------------------------- */
+
+int
+SwigType_isclass(SwigType *t) {
+ SwigType *qty, *qtys;
+ int isclass = 0;
+
+ qty = SwigType_typedef_resolve_all(t);
+ qtys = SwigType_strip_qualifiers(qty);
+ if (SwigType_issimple(qtys)) {
+ String *td = SwigType_typedef_resolve(qtys);
+ if (td) {
+ Delete(td);
+ }
+ if (resolved_scope) {
+ isclass = 1;
+ }
+ /* Hmmm. Not a class. If a template, it might be uninstantiated */
+ if (SwigType_istemplate(qtys)) {
+ String *tp = SwigType_templateprefix(qtys);
+ isclass = SwigType_isclass(tp);
+ Delete(tp);
+ }
+ }
+ Delete(qty);
+ Delete(qtys);
+ return isclass;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_type()
+ *
+ * Returns an integer code describing the datatype. This is only used for
+ * compatibility with SWIG1.1 language modules and is likely to go away once
+ * everything is based on typemaps.
+ * ----------------------------------------------------------------------------- */
+
+int SwigType_type(SwigType *t)
+{
+ char *c;
+ /* Check for the obvious stuff */
+ c = Char(t);
+
+ if (strncmp(c,"p.",2) == 0) {
+ if (SwigType_type(c+2) == T_CHAR) return T_STRING;
+ else return T_POINTER;
+ }
+ if (strncmp(c,"a(",2) == 0) return T_ARRAY;
+ if (strncmp(c,"r.",2) == 0) return T_REFERENCE;
+ if (strncmp(c,"m(",2) == 0) return T_MPOINTER;
+ if (strncmp(c,"q(",2) == 0) {
+ while(*c && (*c != '.')) c++;
+ if (*c) return SwigType_type(c+1);
+ return T_ERROR;
+ }
+ if (strncmp(c,"f(",2) == 0) return T_FUNCTION;
+
+ /* Look for basic types */
+ if (strcmp(c,"int") == 0) return T_INT;
+ if (strcmp(c,"long") == 0) return T_LONG;
+ if (strcmp(c,"short") == 0) return T_SHORT;
+ if (strcmp(c,"unsigned") == 0) return T_UINT;
+ if (strcmp(c,"unsigned short") == 0) return T_USHORT;
+ if (strcmp(c,"unsigned long") == 0) return T_ULONG;
+ if (strcmp(c,"unsigned int") == 0) return T_UINT;
+ if (strcmp(c,"char") == 0) return T_CHAR;
+ if (strcmp(c,"signed char") == 0) return T_SCHAR;
+ if (strcmp(c,"unsigned char") == 0) return T_UCHAR;
+ if (strcmp(c,"float") == 0) return T_FLOAT;
+ if (strcmp(c,"double") == 0) return T_DOUBLE;
+ if (strcmp(c,"void") == 0) return T_VOID;
+ if (strcmp(c,"bool") == 0) return T_BOOL;
+ if (strcmp(c,"long long") == 0) return T_LONGLONG;
+ if (strcmp(c,"unsigned long long") == 0) return T_ULONGLONG;
+ if (strncmp(c,"enum ",5) == 0) return T_INT;
+
+ if (strcmp(c,"v(...)") == 0) return T_VARARGS;
+ /* Hmmm. Unknown type */
+ if (SwigType_istypedef(t)) {
+ int r;
+ SwigType *nt = SwigType_typedef_resolve(t);
+ r = SwigType_type(nt);
+ Delete(nt);
+ return r;
+ }
+ return T_USER;
+}
+
+/******************************************************************************
+ *** * * * WARNING * * * ***
+ *** ***
+ *** Don't even think about modifying anything below this line unless you ***
+ *** are completely on top of *EVERY* subtle aspect of the C++ type system ***
+ *** and you are prepared to suffer endless hours of agony trying to ***
+ *** debug the SWIG run-time type checker after you break it. ***
+ ******************************************************************************/
+
+/* -----------------------------------------------------------------------------
+ * SwigType_remember()
+ *
+ * This function "remembers" a datatype that was used during wrapper code generation
+ * so that a type-checking table can be generated later on. It is up to the language
+ * modules to actually call this function--it is not done automatically.
+ *
+ * Type tracking is managed through two separate hash tables. The hash 'r_mangled'
+ * is mapping between mangled type names (used in the target language) and
+ * fully-resolved C datatypes used in the source input. The second hash 'r_resolved'
+ * is the inverse mapping that maps fully-resolved C datatypes to all of the mangled
+ * names in the scripting languages. For example, consider the following set of
+ * typedef declarations:
+ *
+ * typedef double Real;
+ * typedef double Float;
+ * typedef double Point[3];
+ *
+ * Now, suppose that the types 'double *', 'Real *', 'Float *', 'double[3]', and
+ * 'Point' were used in an interface file and "remembered" using this function.
+ * The hash tables would look like this:
+ *
+ * r_mangled {
+ * _p_double : [ p.double, a(3).double ]
+ * _p_Real : [ p.double ]
+ * _p_Float : [ p.double ]
+ * _Point : [ a(3).double ]
+ *
+ * r_resolved {
+ * p.double : [ _p_double, _p_Real, _p_Float ]
+ * a(3).double : [ _p_double, _Point ]
+ * }
+ *
+ * Together these two hash tables can be used to determine type-equivalency between
+ * mangled typenames. To do this, we view the two hash tables as a large graph and
+ * compute the transitive closure.
+ * ----------------------------------------------------------------------------- */
+
+static Hash *r_mangled = 0; /* Hash mapping mangled types to fully resolved types */
+static Hash *r_resolved = 0; /* Hash mapping resolved types to mangled types */
+static Hash *r_ltype = 0; /* Hash mapping mangled names to their local c type */
+static Hash *r_clientdata = 0; /* Hash mapping resolved types to client data */
+static Hash *r_remembered = 0; /* Hash of types we remembered already */
+
+static void (*r_tracefunc)(SwigType *t, String *mangled, String *clientdata) = 0;
+
+void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata) {
+ String *mt;
+ SwigType *lt;
+ Hash *h;
+ SwigType *fr;
+ SwigType *qr;
+
+ if (!r_mangled) {
+ r_mangled = NewHash();
+ r_resolved = NewHash();
+ r_ltype = NewHash();
+ r_clientdata = NewHash();
+ r_remembered = NewHash();
+ }
+
+ {
+ String *last;
+ last = Getattr(r_remembered,t);
+ if (last && (Cmp(last,clientdata) == 0)) return;
+ }
+
+ Setattr(r_remembered, Copy(t), clientdata ? NewString(clientdata) : (void *) "");
+
+ mt = SwigType_manglestr(t); /* Create mangled string */
+
+ if (r_tracefunc) {
+ (*r_tracefunc)(t,mt, (String *) clientdata);
+ }
+
+ if (SwigType_istypedef(t))
+ lt = Copy(t);
+ else
+ lt = SwigType_ltype(t);
+ Setattr(r_ltype, mt, lt);
+ fr = SwigType_typedef_resolve_all(t); /* Create fully resolved type */
+ qr = SwigType_typedef_qualified(fr);
+ Delete(fr);
+
+ /* Added to deal with possible table bug */
+ fr = SwigType_strip_qualifiers(qr);
+ Delete(qr);
+
+ /*Printf(stdout,"t = '%s'\n", t);
+ Printf(stdout,"fr= '%s'\n\n", fr); */
+
+ if (Strstr(t,"<") && !(Strstr(t,"<("))) {
+ Printf(stdout,"Bad template type passed to SwigType_remember: %s\n", t);
+ assert(0);
+ }
+
+ h = Getattr(r_mangled,mt);
+ if (!h) {
+ h = NewHash();
+ Setattr(r_mangled,mt,h);
+ Delete(h);
+ }
+ Setattr(h,fr,mt);
+
+ h = Getattr(r_resolved, fr);
+ if (!h) {
+ h = NewHash();
+ Setattr(r_resolved,fr,h);
+ Delete(h);
+ }
+ Setattr(h,mt,fr);
+
+ if (clientdata) {
+ String *cd = Getattr(r_clientdata,fr);
+ if (cd) {
+ if (Strcmp(clientdata,cd) != 0) {
+ Printf(stderr,"*** Internal error. Inconsistent clientdata for type '%s'\n", SwigType_str(fr,0));
+ Printf(stderr,"*** '%s' != '%s'\n", clientdata, cd);
+ assert(0);
+ }
+ } else {
+ Setattr(r_clientdata, fr, NewString(clientdata));
+ }
+ }
+}
+
+void
+SwigType_remember(SwigType *ty) {
+ SwigType_remember_clientdata(ty,0);
+}
+
+void (*SwigType_remember_trace(void (*tf)(SwigType *, String *, String *)))(SwigType *, String *, String *) {
+ void (*o)(SwigType *, String *, String *) = r_tracefunc;
+ r_tracefunc = tf;
+ return o;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_equivalent_mangle()
+ *
+ * Return a list of all of the mangled typenames that are equivalent to another
+ * mangled name. This works as follows: For each fully qualified C datatype
+ * in the r_mangled hash entry, we collect all of the mangled names from the
+ * r_resolved hash and combine them together in a list (removing duplicate entries).
+ * ----------------------------------------------------------------------------- */
+
+List *SwigType_equivalent_mangle(String *ms, Hash *checked, Hash *found) {
+ List *l;
+ Hash *h;
+ Hash *ch;
+ Hash *mh;
+
+ if (found) {
+ h = found;
+ } else {
+ h = NewHash();
+ }
+ if (checked) {
+ ch = checked;
+ } else {
+ ch = NewHash();
+ }
+ if (Getattr(ch,ms)) goto check_exit; /* Already checked this type */
+ Setattr(h,ms,"1");
+ Setattr(ch, ms, "1");
+ mh = Getattr(r_mangled,ms);
+ if (mh) {
+ String *key;
+ key = Firstkey(mh);
+ while (key) {
+ Hash *rh;
+ if (Getattr(ch,key)) {
+ key = Nextkey(mh);
+ continue;
+ }
+ Setattr(ch,key,"1");
+ rh = Getattr(r_resolved,key);
+ if (rh) {
+ String *rkey;
+ rkey = Firstkey(rh);
+ while (rkey) {
+ Setattr(h,rkey,"1");
+ SwigType_equivalent_mangle(rkey,ch,h);
+ rkey = Nextkey(rh);
+ }
+ }
+ key = Nextkey(mh);
+ }
+ }
+ check_exit:
+ if (!found) {
+ l = Keys(h);
+ Delete(h);
+ Delete(ch);
+ return l;
+ } else {
+ return 0;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_clientdata_collect()
+ *
+ * Returns the clientdata field for a mangled type-string.
+ * ----------------------------------------------------------------------------- */
+
+static
+String *SwigType_clientdata_collect(String *ms, Hash *checked) {
+ Hash *ch;
+ Hash *mh;
+ String *clientdata = 0;
+
+ if (checked) {
+ ch = checked;
+ } else {
+ ch = NewHash();
+ }
+ if (Getattr(ch,ms)) goto check_exit; /* Already checked this type */
+ Setattr(ch, ms, "1");
+ mh = Getattr(r_mangled,ms);
+ if (mh) {
+ String *key;
+ key = Firstkey(mh);
+ while (key) {
+ Hash *rh;
+ Setattr(ch,key,"1");
+ clientdata = Getattr(r_clientdata,key);
+ if (clientdata) goto check_exit;
+ rh = Getattr(r_resolved,key);
+ if (rh) {
+ String *rkey;
+ rkey = Firstkey(rh);
+ while (rkey) {
+ clientdata = SwigType_clientdata_collect(rkey,ch);
+ if (clientdata) goto check_exit;
+ rkey = Nextkey(rh);
+ }
+ }
+ key = Nextkey(mh);
+ }
+ }
+ check_exit:
+ if (!checked) {
+ Delete(ch);
+ }
+ return clientdata;
+}
+
+
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_inherit()
+ *
+ * Record information about inheritance. We keep a hash table that keeps
+ * a mapping between base classes and all of the classes that are derived
+ * from them.
+ *
+ * subclass is a hash that maps base-classes to all of the classes derived from them.
+ * ----------------------------------------------------------------------------- */
+
+static Hash *subclass = 0;
+static Hash *conversions = 0;
+
+void
+SwigType_inherit(String *derived, String *base, String *cast) {
+ Hash *h;
+ if (!subclass) subclass = NewHash();
+
+ /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */
+
+ if (SwigType_istemplate(derived)) {
+ derived = SwigType_typedef_qualified(SwigType_typedef_resolve_all(derived));
+ }
+ if (SwigType_istemplate(base)) {
+ base = SwigType_typedef_qualified(SwigType_typedef_resolve_all(base));
+ }
+
+ /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast);*/
+
+ h = Getattr(subclass,base);
+ if (!h) {
+ h = NewHash();
+ Setattr(subclass,base,h);
+ }
+ if (!Getattr(h,derived)) {
+ Setattr(h,derived, cast ? cast : (void *) "");
+ }
+
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_issubtype()
+ *
+ * Determines if a t1 is a subtype of t2
+ * ----------------------------------------------------------------------------- */
+
+int
+SwigType_issubtype(SwigType *t1, SwigType *t2) {
+ SwigType *ft1, *ft2;
+ String *b1, *b2;
+ Hash *h;
+ int r = 0;
+
+ if (!subclass) return 0;
+
+ ft1 = SwigType_typedef_resolve_all(t1);
+ ft2 = SwigType_typedef_resolve_all(t2);
+ b1 = SwigType_base(ft1);
+ b2 = SwigType_base(ft2);
+
+ h = Getattr(subclass,b2);
+ if (h) {
+ if (Getattr(h,b1)) {
+ r = 1;
+ }
+ }
+ Delete(ft1);
+ Delete(ft2);
+ Delete(b1);
+ Delete(b2);
+ /* Printf(stdout, "issubtype(%s,%s) --> %d\n", t1, t2, r); */
+ return r;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_inherit_equiv()
+ *
+ * Modify the type table to handle C++ inheritance
+ * ----------------------------------------------------------------------------- */
+
+void SwigType_inherit_equiv(File *out) {
+ String *rkey, *bkey, *ckey;
+ String *prefix, *base;
+ Hash *sub;
+ Hash *rh;
+ List *rlist;
+
+ if (!conversions) conversions = NewHash();
+ if (!subclass) subclass = NewHash();
+
+ rkey = Firstkey(r_resolved);
+ while (rkey) {
+ /* rkey is a fully qualified type. We strip all of the type constructors off of it just to get the base */
+ base = SwigType_base(rkey);
+ /* Check to see whether the base is recorded in the subclass table */
+ sub = Getattr(subclass,base);
+ Delete(base);
+ if (!sub) {
+ rkey = Nextkey(r_resolved);
+ continue;
+ }
+
+ /* This type has subclasses. We now need to walk through these subtypes and generate pointer converion functions */
+
+ rh = Getattr(r_resolved, rkey);
+ rlist = NewList();
+ for (ckey = Firstkey(rh); ckey; ckey = Nextkey(rh)) {
+ Append(rlist,ckey);
+ }
+ /* Printf(stdout,"rkey = '%s'\n", rkey);
+ Printf(stdout,"rh = %x '%s'\n", rh,rh); */
+
+ bkey = Firstkey(sub);
+ while (bkey) {
+ prefix= SwigType_prefix(rkey);
+ Append(prefix,bkey);
+ /* Printf(stdout,"set %x = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */
+ Setattr(rh,SwigType_manglestr(prefix),prefix);
+ ckey = NewStringf("%s+%s",SwigType_manglestr(prefix), SwigType_manglestr(rkey));
+ if (!Getattr(conversions,ckey)) {
+ String *convname = NewStringf("%sTo%s", SwigType_manglestr(prefix), SwigType_manglestr(rkey));
+ Printf(out,"static void *%s(void *x) {\n", convname);
+ Printf(out," return (void *)((%s) %s ((%s) x));\n", SwigType_lstr(rkey,0), Getattr(sub,bkey), SwigType_lstr(prefix,0));
+ Printf(out,"}\n");
+ Setattr(conversions,ckey,convname);
+ Delete(ckey);
+
+ /* This inserts conversions for typedefs */
+ {
+ Hash *r = Getattr(r_resolved, prefix);
+ if (r) {
+ String *rrkey = Firstkey(r);
+ while (rrkey) {
+ String *rlkey;
+ String *rkeymangle;
+
+ /* Make sure this name equivalence is not due to inheritance */
+ if (Cmp(prefix, Getattr(r,rrkey)) == 0) {
+ rkeymangle = SwigType_manglestr(rkey);
+ ckey = NewStringf("%s+%s", rrkey, rkeymangle);
+ if (!Getattr(conversions, ckey)) {
+ Setattr(conversions, ckey, convname);
+ }
+ Delete(ckey);
+ for (rlkey = Firstitem(rlist); rlkey; rlkey = Nextitem(rlist)) {
+ ckey = NewStringf("%s+%s", rrkey, rlkey);
+ Setattr(conversions, ckey, convname);
+ Delete(ckey);
+ }
+ Delete(rkeymangle);
+ /* This is needed to pick up other alternative names for the same type.
+ Needed to make templates work */
+ Setattr(rh,rrkey,Getattr(r,rrkey));
+ }
+ rrkey = Nextkey(r);
+ }
+ }
+ }
+ Delete(convname);
+ }
+ Delete(prefix);
+ bkey = Nextkey(sub);
+ }
+ rkey = Nextkey(r_resolved);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_type_table()
+ *
+ * Generate the type-table for the type-checker.
+ * ----------------------------------------------------------------------------- */
+
+void
+SwigType_emit_type_table(File *f_forward, File *f_table) {
+ DOH *key;
+ String *types, *table;
+ int i = 0;
+
+ if (!r_mangled) {
+ r_mangled = NewHash();
+ r_resolved = NewHash();
+ }
+
+ Printf(f_table,"\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */\n\n");
+
+ SwigType_inherit_equiv(f_table);
+
+ /* #define DEBUG 1 */
+#ifdef DEBUG
+ Printf(stdout,"---r_mangled---\n");
+ Printf(stdout,"%s\n", r_mangled);
+
+ Printf(stdout,"---r_resolved---\n");
+ Printf(stdout,"%s\n", r_resolved);
+
+ Printf(stdout,"---r_ltype---\n");
+ Printf(stdout,"%s\n", r_ltype);
+
+ Printf(stdout,"---subclass---\n");
+ Printf(stdout,"%s\n", subclass);
+
+ Printf(stdout,"---conversions---\n");
+ Printf(stdout,"%s\n", conversions);
+
+#endif
+ table = NewString("");
+ types = NewString("");
+ Printf(table,"static swig_type_info *swig_types_initial[] = {\n");
+ key = Firstkey(r_mangled);
+ Printf(f_forward,"\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n");
+ while (key) {
+ List *el;
+ String *en;
+ String *cd;
+
+ Printf(f_forward,"#define SWIGTYPE%s swig_types[%d] \n", key, i);
+ Printv(types,"static swig_type_info _swigt_", key, "[] = {", NIL);
+
+ cd = SwigType_clientdata_collect(key,0);
+ if (!cd) cd = "0";
+ Printv(types,"{\"", key, "\", 0, \"", SwigType_str(Getattr(r_ltype,key),0),"\", ", cd, "},", NIL);
+ el = SwigType_equivalent_mangle(key,0,0);
+ for (en = Firstitem(el); en; en = Nextitem(el)) {
+ String *ckey;
+ String *conv;
+ ckey = NewStringf("%s+%s", en, key);
+ conv = Getattr(conversions,ckey);
+ if (conv) {
+ Printf(types,"{\"%s\", %s},", en, conv);
+ } else {
+ Printf(types,"{\"%s\"},", en);
+ }
+ Delete(ckey);
+ }
+ Delete(el);
+ Printf(types,"{0}};\n");
+ Printv(table, "_swigt_", key, ", \n", NIL);
+ key = Nextkey(r_mangled);
+ i++;
+ }
+
+ Printf(table, "0\n};\n");
+ Printf(f_forward,"static swig_type_info *swig_types[%d];\n", i+1);
+ Printf(f_forward,"\n/* -------- TYPES TABLE (END) -------- */\n\n");
+ Printf(f_table,"%s\n", types);
+ Printf(f_table,"%s\n", table);
+ Printf(f_table,"\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */\n\n");
+ Delete(types);
+ Delete(table);
+}
diff --git a/Source/Swig/warn.c b/Source/Swig/warn.c
new file mode 100644
index 000000000..805f0a4dd
--- /dev/null
+++ b/Source/Swig/warn.c
@@ -0,0 +1,42 @@
+/* -----------------------------------------------------------------------------
+ * warn.c
+ *
+ * SWIG warning framework. This was added to warn developers about
+ * deprecated APIs and other features.
+ *
+ * Author(s) : David Beazley (beazley@cs.uchicago.edu)
+ *
+ * Copyright (C) 1999-2001. The University of Chicago
+ * See the file LICENSE for information on usage and redistribution.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_warn_c[] = "$Header$";
+
+#include "swig.h"
+
+static Hash *warnings = 0;
+
+/* -----------------------------------------------------------------------------
+ * Swig_warn()
+ *
+ * Issue a warning
+ * ----------------------------------------------------------------------------- */
+
+void
+Swig_warn(const char *filename, int line, const char *msg) {
+ String *key;
+ if (!warnings) {
+ warnings = NewHash();
+ }
+ key = NewStringf("%s:%d", filename,line);
+ if (!Getattr(warnings,key)) {
+ Printf(stderr,"swig-dev warning:%s:%d:%s\n", filename, line, msg);
+ Setattr(warnings,key,key);
+ }
+ Delete(key);
+}
+
+
+
+
+
diff --git a/Source/Swig/wrapfunc.c b/Source/Swig/wrapfunc.c
index f716fba39..182e3f2af 100644
--- a/Source/Swig/wrapfunc.c
+++ b/Source/Swig/wrapfunc.c
@@ -14,30 +14,41 @@
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
-static char cvsroot[] = "$Header$";
+char cvsroot_wrapfunc_c[] = "$Header$";
#include "swig.h"
#include <ctype.h>
-#include "dohobj.h"
+/* -----------------------------------------------------------------------------
+ * NewWrapper()
+ *
+ * Create a new wrapper function object.
+ * ----------------------------------------------------------------------------- */
-typedef struct {
- Hash *attr; /* Attributes */
- Hash *localh; /* Hash of local variable names */
- String *code; /* Code string */
-} WrapObj;
+Wrapper *
+NewWrapper() {
+ Wrapper *w;
+ w = (Wrapper *) malloc(sizeof(Wrapper));
+ w->localh = NewHash();
+ w->locals = NewString("");
+ w->code = NewString("");
+ w->def = NewString("");
+ return w;
+}
/* -----------------------------------------------------------------------------
* DelWrapper()
+ *
+ * Delete a wrapper function object.
* ----------------------------------------------------------------------------- */
-static void
-DelWrapper(DOH *wo) {
- WrapObj *w = (WrapObj *) ObjData(wo);
+void
+DelWrapper(Wrapper *w) {
Delete(w->localh);
+ Delete(w->locals);
Delete(w->code);
- Delete(w->attr);
- DohFree(w);
+ Delete(w->def);
+ free(w);
}
/* -----------------------------------------------------------------------------
@@ -108,6 +119,35 @@ Wrapper_pretty_print(String *str, File *f) {
Printf(f,"%s",ts);
Clear(ts);
empty = 1;
+ } else if (c == '/') {
+ Putc(c,ts);
+ c = Getc(str);
+ if (c != EOF) {
+ Putc(c,ts);
+ if (c == '/') { /* C++ comment */
+ while ((c = Getc(str)) != EOF) {
+ if (c == '\n') {
+ Ungetc(c,str);
+ break;
+ }
+ Putc(c,ts);
+ }
+ } else if (c == '*') { /* C comment */
+ int endstar = 0;
+ while ((c = Getc(str)) != EOF) {
+ if (endstar && c == '/') { /* end of C comment */
+ Putc(c,ts);
+ break;
+ }
+ endstar = (c == '*');
+ Putc(c,ts);
+ if (c == '\n') { /* multi-line C comment. Could be improved slightly. */
+ for (i = 0; i < level; i++)
+ Putc(' ',ts);
+ }
+ }
+ }
+ }
} else {
if (!empty || !isspace(c)) {
Putc(c,ts);
@@ -122,39 +162,20 @@ Wrapper_pretty_print(String *str, File *f) {
/* -----------------------------------------------------------------------------
- * Wrapper_str()
+ * Wrapper_print()
*
- * Create a string representation of the wrapper function.
- * ----------------------------------------------------------------------------- */
-
-static String *
-Wrapper_str(DOH *wo) {
- String *s, *s1;
- WrapObj *w = (WrapObj *) ObjData(wo);
- s = NewString(w->code);
- s1 = NewString("");
-
- /* Replace the first '{' with a brace followed by local variable definitions */
- Replace(s,"{", Getattr(w->attr,"locals"), DOH_REPLACE_FIRST);
- Wrapper_pretty_print(s,s1);
- Delete(s);
- return s1;
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_dump()
- *
- * Serialize on out
+ * Print out a wrapper function. Does pretty printing as well.
* ----------------------------------------------------------------------------- */
-static int
-Wrapper_dump(DOH *wo, DOH *out) {
- String *s;
- int len;
- s = Wrapper_str(wo);
- len = Dump(s,out);
- Delete(s);
- return len;
+void
+Wrapper_print(Wrapper *w, File *f) {
+ String *str;
+
+ str = NewString("");
+ Printf(str,"%s\n", w->def);
+ Printf(str,"%s\n", w->locals);
+ Printf(str,"%s\n", w->code);
+ Wrapper_pretty_print(str,f);
}
/* -----------------------------------------------------------------------------
@@ -165,14 +186,13 @@ Wrapper_dump(DOH *wo, DOH *out) {
* ----------------------------------------------------------------------------- */
int
-Wrapper_add_local(Wrapper *wo, const String_or_char *name, const String_or_char *decl) {
- WrapObj *w = (WrapObj *) ObjData(wo);
+Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) {
/* See if the local has already been declared */
if (Getattr(w->localh,name)) {
return -1;
}
Setattr(w->localh,name,decl);
- Printf(Getattr(w->attr,"locals"),"%s;\n", decl);
+ Printf(w->locals,"%s;\n", decl);
return 0;
}
@@ -185,24 +205,23 @@ Wrapper_add_local(Wrapper *wo, const String_or_char *name, const String_or_char
* ----------------------------------------------------------------------------- */
int
-Wrapper_add_localv(Wrapper *wo, const String_or_char *name, ...) {
+Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...) {
va_list ap;
int ret;
String *decl;
DOH *obj;
- WrapObj *w = (WrapObj *) ObjData(wo);
decl = NewString("");
va_start(ap,name);
obj = va_arg(ap,void *);
while (obj) {
- Printv(decl,obj,0);
+ Printv(decl,obj,NIL);
Putc(' ', decl);
obj = va_arg(ap, void *);
}
va_end(ap);
- ret = Wrapper_add_local(wo,name,decl);
+ ret = Wrapper_add_local(w,name,decl);
Delete(decl);
return ret;
}
@@ -214,8 +233,7 @@ Wrapper_add_localv(Wrapper *wo, const String_or_char *name, ...) {
* ----------------------------------------------------------------------------- */
int
-Wrapper_check_local(Wrapper *wo, const String_or_char *name) {
- WrapObj *w = (WrapObj *) ObjData(wo);
+Wrapper_check_local(Wrapper *w, const String_or_char *name) {
if (Getattr(w->localh,name)) {
return 1;
}
@@ -230,22 +248,22 @@ Wrapper_check_local(Wrapper *wo, const String_or_char *name) {
* ----------------------------------------------------------------------------- */
char *
-Wrapper_new_local(Wrapper *wo, const String_or_char *name, const String_or_char *decl) {
+Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) {
int i;
- char *ret;
String *nname = NewString(name);
String *ndecl = NewString(decl);
- WrapObj *w = (WrapObj *) ObjData(wo);
+ char *ret;
+
i = 0;
- while (Wrapper_check_local(wo,nname)) {
+ while (Wrapper_check_local(w,nname)) {
Clear(nname);
Printf(nname,"%s%d",name,i);
i++;
}
Replace(ndecl, name, nname, DOH_REPLACE_ID);
Setattr(w->localh,nname,ndecl);
- Printf(Getattr(w->attr,"locals"),"%s;\n", ndecl);
+ Printf(w->locals,"%s;\n", ndecl);
ret = Char(nname);
Delete(nname);
Delete(ndecl);
@@ -262,205 +280,29 @@ Wrapper_new_local(Wrapper *wo, const String_or_char *name, const String_or_char
* ----------------------------------------------------------------------------- */
char *
-Wrapper_new_localv(Wrapper *wo, const String_or_char *name, ...) {
+Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...) {
va_list ap;
char *ret;
String *decl;
DOH *obj;
- WrapObj *w = (WrapObj *) ObjData(wo);
decl = NewString("");
va_start(ap,name);
obj = va_arg(ap,void *);
while (obj) {
- Printv(decl,obj,0);
+ Printv(decl,obj,NIL);
Putc(' ',decl);
obj = va_arg(ap, void *);
}
va_end(ap);
- ret = Wrapper_new_local(wo,name,decl);
+ ret = Wrapper_new_local(w,name,decl);
Delete(decl);
return ret;
}
-/* -----------------------------------------------------------------------------
- * Wrapper_Getattr()
- * ----------------------------------------------------------------------------- */
-static DOH *
-Wrapper_getattr(Wrapper *wo, DOH *k) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Getattr(w->attr,k);
-}
-/* -----------------------------------------------------------------------------
- * Wrapper_Delattr()
- * ----------------------------------------------------------------------------- */
-
-static int
-Wrapper_delattr(Wrapper *wo, DOH *k) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- Delattr(w->attr,k);
- return 0;
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_Setattr()
- * ----------------------------------------------------------------------------- */
-
-static int
-Wrapper_setattr(Wrapper *wo, DOH *k, DOH *obj) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Setattr(w->attr,k,obj);
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_firstkey()
- * ----------------------------------------------------------------------------- */
-
-static DOH *
-Wrapper_firstkey(Wrapper *wo) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Firstkey(w->attr);
-}
-
-/* -----------------------------------------------------------------------------
- * Wrapper_firstkey()
- * ----------------------------------------------------------------------------- */
-
-static DOH *
-Wrapper_nextkey(Wrapper *wo) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Nextkey(w->attr);
-}
-
-/* File methods. These simply operate on the code string */
-
-static int
-Wrapper_read(Wrapper *wo, void *buffer, int nbytes) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Read(w->code,buffer,nbytes);
-}
-
-static int
-Wrapper_write(Wrapper *wo, void *buffer, int nbytes) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Write(w->code,buffer,nbytes);
-}
-
-static int
-Wrapper_putc(Wrapper *wo, int ch) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Putc(ch, w->code);
-}
-
-static int
-Wrapper_getc(Wrapper *wo) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Getc(w->code);
-}
-
-static int
-Wrapper_ungetc(Wrapper *wo, int ch) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Ungetc(ch, w->code);
-}
-
-static int
-Wrapper_seek(Wrapper *wo, long offset, int whence) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Seek(w->code, offset, whence);
-}
-
-static long
-Wrapper_tell(Wrapper *wo) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Tell(w->code);
-}
-
-/* String method */
-
-static int Wrapper_replace(DOH *wo, DOH *tok, DOH *rep, int flags) {
- WrapObj *w = (WrapObj *) ObjData(wo);
- return Replace(w->code, tok, rep, flags);
-}
-
-/* -----------------------------------------------------------------------------
- * type information
- * ----------------------------------------------------------------------------- */
-
-static DohHashMethods WrapperHashMethods = {
- Wrapper_getattr,
- Wrapper_setattr,
- Wrapper_delattr,
- Wrapper_firstkey,
- Wrapper_nextkey,
-};
-
-static DohFileMethods WrapperFileMethods = {
- Wrapper_read,
- Wrapper_write,
- Wrapper_putc,
- Wrapper_getc,
- Wrapper_ungetc,
- Wrapper_seek,
- Wrapper_tell,
- 0, /* close */
-};
-
-static DohStringMethods WrapperStringMethods = {
- Wrapper_replace,
- 0,
-};
-
-static DohObjInfo WrapperType = {
- "Wrapper", /* objname */
- DelWrapper, /* doh_del */
- 0, /* doh_copy */
- 0, /* doh_clear */
- Wrapper_str, /* doh_str */
- 0, /* doh_data */
- 0, /* doh_dump */
- 0, /* doh_len */
- 0, /* doh_hash */
- 0, /* doh_cmp */
- 0, /* doh_setfile */
- 0, /* doh_getfile */
- 0, /* doh_setline */
- 0, /* doh_getline */
- &WrapperHashMethods, /* doh_mapping */
- 0, /* doh_sequence */
- &WrapperFileMethods, /* doh_file */
- &WrapperStringMethods, /* doh_string */
- 0, /* doh_positional */
- 0,
-};
-
-/* -----------------------------------------------------------------------------
- * NewWrapper()
- *
- * Create a new wrapper function object.
- * ----------------------------------------------------------------------------- */
-
-#define DOHTYPE_WRAPPER 0xa
-
-Wrapper *
-NewWrapper() {
- WrapObj *w;
- static int init = 0;
- if (!init) {
- DohRegisterType(DOHTYPE_WRAPPER, &WrapperType);
- init = 1;
- }
- w = (WrapObj *) DohMalloc(sizeof(WrapObj));
- w->localh = NewHash();
- w->code = NewString("");
- w->attr= NewHash();
- Setattr(w->attr,"locals","{\n");
- Setattr(w->attr,"wrapcode", w->code);
- return DohObjMalloc(DOHTYPE_WRAPPER, w);
-}