summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2009-08-18 20:56:02 +0000
committerLorry <lorry@roadtrain.codethink.co.uk>2012-09-25 16:59:08 +0000
commit9f8a09ed743cedd9547bf0661d518647966ab114 (patch)
tree9c7803d3b27a8ec22e91792ac7f7932efa128b20 /Source
downloadswig-tarball-9f8a09ed743cedd9547bf0661d518647966ab114.tar.gz
Imported from /srv/lorry/lorry-area/swig-tarball/swig-1.3.40.tar.gz.HEADswig-1.3.40master
Diffstat (limited to 'Source')
-rw-r--r--Source/CParse/cparse.h74
-rw-r--r--Source/CParse/cscanner.c930
-rw-r--r--Source/CParse/parser.c10438
-rw-r--r--Source/CParse/parser.h351
-rw-r--r--Source/CParse/parser.y6066
-rw-r--r--Source/CParse/templ.c675
-rw-r--r--Source/CParse/util.c88
-rw-r--r--Source/DOH/README118
-rw-r--r--Source/DOH/base.c943
-rw-r--r--Source/DOH/doh.h442
-rw-r--r--Source/DOH/dohint.h133
-rw-r--r--Source/DOH/file.c299
-rw-r--r--Source/DOH/fio.c589
-rw-r--r--Source/DOH/hash.c551
-rw-r--r--Source/DOH/list.c377
-rw-r--r--Source/DOH/memory.c220
-rw-r--r--Source/DOH/string.c1158
-rw-r--r--Source/DOH/void.c96
-rw-r--r--Source/Include/swigconfig.h.in93
-rw-r--r--Source/Include/swigwarn.h261
-rw-r--r--Source/Makefile.am144
-rw-r--r--Source/Makefile.in1072
-rw-r--r--Source/Modules/README9
-rw-r--r--Source/Modules/allegrocl.cxx3222
-rw-r--r--Source/Modules/allocate.cxx955
-rw-r--r--Source/Modules/browser.cxx413
-rw-r--r--Source/Modules/cffi.cxx1081
-rw-r--r--Source/Modules/chicken.cxx1552
-rw-r--r--Source/Modules/clisp.cxx509
-rw-r--r--Source/Modules/contract.cxx354
-rw-r--r--Source/Modules/csharp.cxx3960
-rw-r--r--Source/Modules/directors.cxx288
-rw-r--r--Source/Modules/emit.cxx512
-rw-r--r--Source/Modules/guile.cxx1759
-rw-r--r--Source/Modules/java.cxx4166
-rw-r--r--Source/Modules/lang.cxx3431
-rw-r--r--Source/Modules/lua.cxx1226
-rw-r--r--Source/Modules/main.cxx1251
-rw-r--r--Source/Modules/modula3.cxx3987
-rw-r--r--Source/Modules/module.cxx57
-rw-r--r--Source/Modules/mzscheme.cxx834
-rw-r--r--Source/Modules/ocaml.cxx1866
-rw-r--r--Source/Modules/octave.cxx1425
-rw-r--r--Source/Modules/overload.cxx792
-rw-r--r--Source/Modules/perl5.cxx1768
-rw-r--r--Source/Modules/php.cxx2739
-rw-r--r--Source/Modules/pike.cxx903
-rw-r--r--Source/Modules/python.cxx4067
-rw-r--r--Source/Modules/r.cxx2745
-rw-r--r--Source/Modules/ruby.cxx3427
-rw-r--r--Source/Modules/s-exp.cxx394
-rw-r--r--Source/Modules/swigmain.cxx202
-rw-r--r--Source/Modules/swigmod.h391
-rw-r--r--Source/Modules/tcl8.cxx1306
-rw-r--r--Source/Modules/typepass.cxx1164
-rw-r--r--Source/Modules/uffi.cxx398
-rw-r--r--Source/Modules/utils.cxx98
-rw-r--r--Source/Modules/xml.cxx320
-rw-r--r--Source/Preprocessor/cpp.c1854
-rw-r--r--Source/Preprocessor/expr.c436
-rw-r--r--Source/Preprocessor/preprocessor.h38
-rw-r--r--Source/README25
-rw-r--r--Source/Swig/cwrap.c1462
-rw-r--r--Source/Swig/deprecate.c105
-rw-r--r--Source/Swig/error.c277
-rw-r--r--Source/Swig/fragment.c181
-rw-r--r--Source/Swig/getopt.c107
-rw-r--r--Source/Swig/include.c383
-rw-r--r--Source/Swig/misc.c1156
-rw-r--r--Source/Swig/naming.c1652
-rw-r--r--Source/Swig/parms.c196
-rw-r--r--Source/Swig/scanner.c1227
-rw-r--r--Source/Swig/stype.c1105
-rw-r--r--Source/Swig/swig.h403
-rw-r--r--Source/Swig/swigfile.h40
-rw-r--r--Source/Swig/swigopt.h16
-rw-r--r--Source/Swig/swigparm.h29
-rw-r--r--Source/Swig/swigscan.h108
-rw-r--r--Source/Swig/swigtree.h50
-rw-r--r--Source/Swig/swigwrap.h29
-rw-r--r--Source/Swig/symbol.c1916
-rw-r--r--Source/Swig/tree.c376
-rw-r--r--Source/Swig/typemap.c1936
-rw-r--r--Source/Swig/typeobj.c1095
-rw-r--r--Source/Swig/typesys.c2074
-rw-r--r--Source/Swig/warn.c34
-rw-r--r--Source/Swig/wrapfunc.c518
87 files changed, 97517 insertions, 0 deletions
diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h
new file mode 100644
index 0000000..5679771
--- /dev/null
+++ b/Source/CParse/cparse.h
@@ -0,0 +1,74 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * cparse.h
+ *
+ * SWIG parser module.
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: cparse.h 11097 2009-01-30 10:27:37Z bhy $ */
+
+#ifndef SWIG_CPARSE_H_
+#define SWIG_CPARSE_H_
+
+#include "swig.h"
+#include "swigwarn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* cscanner.c */
+ extern String *cparse_file;
+ extern int cparse_line;
+ extern int cparse_cplusplus;
+ extern int cparse_start_line;
+
+ extern void Swig_cparse_cplusplus(int);
+ extern void scanner_file(File *);
+ extern void scanner_next_token(int);
+ 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 scanner_set_location(String *file, int line);
+ extern void scanner_set_main_input_file(String *file);
+ extern String *scanner_get_main_input_file();
+ extern void Swig_cparse_follow_locators(int);
+ extern void start_inline(char *, int);
+ extern String *scanner_ccode;
+ extern int yylex(void);
+
+/* parser.y */
+ extern SwigType *Swig_cparse_type(String *);
+ extern Node *Swig_cparse(File *);
+ extern Hash *Swig_cparse_features(void);
+ extern void SWIG_cparse_set_compact_default_args(int defargs);
+ extern int SWIG_cparse_template_reduce(int treduce);
+
+/* util.c */
+ extern void Swig_cparse_replace_descriptor(String *s);
+ extern void cparse_normalize_void(Node *);
+ extern Parm *Swig_cparse_parm(String *s);
+ extern ParmList *Swig_cparse_parms(String *s);
+
+
+/* templ.c */
+ extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope);
+ extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms, Symtab *tscope);
+ extern void Swig_cparse_debug_templates(int);
+
+#ifdef __cplusplus
+}
+#endif
+#define SWIG_WARN_NODE_BEGIN(Node) \
+ { \
+ String *wrnfilter = Node ? Getattr(Node,"feature:warnfilter") : 0; \
+ if (wrnfilter) Swig_warnfilter(wrnfilter,1)
+#define SWIG_WARN_NODE_END(Node) \
+ if (wrnfilter) Swig_warnfilter(wrnfilter,0); \
+ }
+#endif
diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c
new file mode 100644
index 0000000..9128a2b
--- /dev/null
+++ b/Source/CParse/cscanner.c
@@ -0,0 +1,930 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * scanner.c
+ *
+ * SWIG tokenizer. This file is a wrapper around the generic C scanner
+ * found in Swig/scanner.c. Extra logic is added both to accomodate the
+ * bison-based grammar and certain peculiarities of C++ parsing (e.g.,
+ * operator overloading, typedef resolution, etc.). This code also splits
+ * C identifiers up into keywords and SWIG directives.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_cscanner_c[] = "$Id: cscanner.c 11123 2009-02-08 22:30:10Z wsfulton $";
+
+#include "cparse.h"
+#include "parser.h"
+#include <string.h>
+#include <ctype.h>
+
+/* Scanner object */
+static Scanner *scan = 0;
+
+/* Global string containing C code. Used by the parser to grab code blocks */
+String *scanner_ccode = 0;
+
+/* The main file being parsed */
+static String *main_input_file = 0;
+
+/* Error reporting/location information */
+int cparse_line = 1;
+String *cparse_file = 0;
+int cparse_start_line = 0;
+
+/* C++ mode */
+int cparse_cplusplus = 0;
+
+/* Private vars */
+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;
+static int expanding_macro = 0;
+static int follow_locators = 0;
+
+/* -----------------------------------------------------------------------------
+ * Swig_cparse_cplusplus()
+ * ----------------------------------------------------------------------------- */
+
+void Swig_cparse_cplusplus(int v) {
+ cparse_cplusplus = v;
+}
+
+/* ----------------------------------------------------------------------
+ * locator()
+ *
+ * Support for locator strings. These are strings of the form
+ * @SWIG:filename,line,id@ emitted by the SWIG preprocessor. They
+ * are primarily used for macro line number reporting
+ * ---------------------------------------------------------------------- */
+
+typedef struct Locator {
+ String *filename;
+ int line_number;
+ struct Locator *next;
+} Locator;
+
+static Locator *locs = 0;
+
+/* we just use the locator to mark when active/deactive the linecounting */
+
+static void scanner_locator(String *loc) {
+ if (!follow_locators) {
+ if (Equal(loc, "/*@SWIG@*/")) {
+ /* End locator. */
+ if (expanding_macro)
+ --expanding_macro;
+ } else {
+ /* Begin locator. */
+ ++expanding_macro;
+ }
+ /* Freeze line number processing in Scanner */
+ Scanner_freeze_line(scan,expanding_macro);
+ } else {
+ int c;
+ Locator *l;
+ Seek(loc, 7, SEEK_SET);
+ c = Getc(loc);
+ if (c == '@') {
+ /* Empty locator. We pop the last location off */
+ if (locs) {
+ Scanner_set_location(scan,locs->filename,locs->line_number);
+ cparse_file = locs->filename;
+ cparse_line = locs->line_number;
+ l = locs->next;
+ free(locs);
+ locs = l;
+ }
+ 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 = NewStringEmpty();
+ /* 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); */
+ Scanner_set_location(scan,cparse_file,cparse_line);
+ Delete(fn);
+ }
+ }
+}
+
+void Swig_cparse_follow_locators(int v) {
+ follow_locators = v;
+}
+
+
+/* ----------------------------------------------------------------------------
+ * scanner_init()
+ *
+ * Initialize buffers
+ * ------------------------------------------------------------------------- */
+
+void scanner_init() {
+ scan = NewScanner();
+ Scanner_idstart(scan,"%");
+ scan_init = 1;
+ scanner_ccode = NewStringEmpty();
+}
+
+/* ----------------------------------------------------------------------------
+ * scanner_file(DOHFile *f)
+ *
+ * Start reading from new file
+ * ------------------------------------------------------------------------- */
+void scanner_file(DOHFile * f) {
+ if (!scan_init) scanner_init();
+ Scanner_clear(scan);
+ Scanner_push(scan,f);
+}
+
+/* ----------------------------------------------------------------------------
+ * start_inline(char *text, int line)
+ *
+ * Take a chunk of text and recursively feed it back into the scanner. Used
+ * by the %inline directive.
+ * ------------------------------------------------------------------------- */
+
+void start_inline(char *text, int line) {
+ String *stext = NewString(text);
+
+ Seek(stext,0,SEEK_SET);
+ Setfile(stext,cparse_file);
+ Setline(stext,line);
+ Scanner_push(scan,stext);
+ Delete(stext);
+}
+
+/* -----------------------------------------------------------------------------
+ * 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) {
+ Clear(scanner_ccode);
+
+ if (Scanner_skip_balanced(scan,startchar,endchar) < 0) {
+ Swig_error(Scanner_file(scan),Scanner_errline(scan), "Missing '%c'. Reached end of input.\n", endchar);
+ return;
+ }
+
+ cparse_line = Scanner_line(scan);
+ cparse_file = Scanner_file(scan);
+
+ Append(scanner_ccode, Scanner_text(scan));
+ 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) {
+ int tok;
+ int done = 0;
+ int start_line = Scanner_line(scan);
+
+ while (!done) {
+ tok = Scanner_token(scan);
+ if (tok == 0) {
+ if (!Swig_error_count()) {
+ Swig_error(cparse_file, start_line, "Missing semicolon. Reached end of input.\n");
+ }
+ return;
+ }
+ if (tok == SWIG_TOKEN_LBRACE) {
+ if (Scanner_skip_balanced(scan,'{','}') < 0) {
+ Swig_error(cparse_file, start_line, "Missing '}'. Reached end of input.\n");
+ }
+ break;
+ }
+ if (tok == SWIG_TOKEN_SEMI) {
+ done = 1;
+ }
+ }
+ cparse_file = Scanner_file(scan);
+ cparse_line = Scanner_line(scan);
+}
+
+/* ----------------------------------------------------------------------------
+ * int yylook()
+ *
+ * Lexical scanner.
+ * ------------------------------------------------------------------------- */
+
+int yylook(void) {
+
+ int tok = 0;
+
+ while (1) {
+ if ((tok = Scanner_token(scan)) == 0)
+ return 0;
+ if (tok == SWIG_TOKEN_ERROR)
+ return 0;
+ cparse_start_line = Scanner_start_line(scan);
+ cparse_line = Scanner_line(scan);
+ cparse_file = Scanner_file(scan);
+
+ switch(tok) {
+ case SWIG_TOKEN_ID:
+ return ID;
+ case SWIG_TOKEN_LPAREN:
+ return LPAREN;
+ case SWIG_TOKEN_RPAREN:
+ return RPAREN;
+ case SWIG_TOKEN_SEMI:
+ return SEMI;
+ case SWIG_TOKEN_COMMA:
+ return COMMA;
+ case SWIG_TOKEN_STAR:
+ return STAR;
+ case SWIG_TOKEN_RBRACE:
+ num_brace--;
+ if (num_brace < 0) {
+ Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '}'\n");
+ num_brace = 0;
+ } else {
+ return RBRACE;
+ }
+ break;
+ case SWIG_TOKEN_LBRACE:
+ last_brace = num_brace;
+ num_brace++;
+ return LBRACE;
+ case SWIG_TOKEN_EQUAL:
+ return EQUAL;
+ case SWIG_TOKEN_EQUALTO:
+ return EQUALTO;
+ case SWIG_TOKEN_PLUS:
+ return PLUS;
+ case SWIG_TOKEN_MINUS:
+ return MINUS;
+ case SWIG_TOKEN_SLASH:
+ return SLASH;
+ case SWIG_TOKEN_AND:
+ return AND;
+ case SWIG_TOKEN_LAND:
+ return LAND;
+ case SWIG_TOKEN_OR:
+ return OR;
+ case SWIG_TOKEN_LOR:
+ return LOR;
+ case SWIG_TOKEN_XOR:
+ return XOR;
+ case SWIG_TOKEN_NOT:
+ return NOT;
+ case SWIG_TOKEN_LNOT:
+ return LNOT;
+ case SWIG_TOKEN_NOTEQUAL:
+ return NOTEQUALTO;
+ case SWIG_TOKEN_LBRACKET:
+ return LBRACKET;
+ case SWIG_TOKEN_RBRACKET:
+ return RBRACKET;
+ case SWIG_TOKEN_QUESTION:
+ return QUESTIONMARK;
+ case SWIG_TOKEN_LESSTHAN:
+ return LESSTHAN;
+ case SWIG_TOKEN_LTEQUAL:
+ return LESSTHANOREQUALTO;
+ case SWIG_TOKEN_LSHIFT:
+ return LSHIFT;
+ case SWIG_TOKEN_GREATERTHAN:
+ return GREATERTHAN;
+ case SWIG_TOKEN_GTEQUAL:
+ return GREATERTHANOREQUALTO;
+ case SWIG_TOKEN_RSHIFT:
+ return RSHIFT;
+ case SWIG_TOKEN_PERIOD:
+ return PERIOD;
+ case SWIG_TOKEN_MODULO:
+ return MODULO;
+ case SWIG_TOKEN_COLON:
+ return COLON;
+ case SWIG_TOKEN_DCOLONSTAR:
+ return DSTAR;
+
+ case SWIG_TOKEN_DCOLON:
+ {
+ int nexttok = Scanner_token(scan);
+ if (nexttok == SWIG_TOKEN_STAR) {
+ return DSTAR;
+ } else if (nexttok == SWIG_TOKEN_NOT) {
+ return DCNOT;
+ } else {
+ Scanner_pushtoken(scan,nexttok,Scanner_text(scan));
+ if (!last_id) {
+ scanner_next_token(DCOLON);
+ return NONID;
+ } else {
+ return DCOLON;
+ }
+ }
+ }
+ break;
+
+ /* Look for multi-character sequences */
+
+ case SWIG_TOKEN_RSTRING:
+ yylval.type = NewString(Scanner_text(scan));
+ return TYPE_RAW;
+
+ case SWIG_TOKEN_STRING:
+ yylval.id = Swig_copy_string(Char(Scanner_text(scan)));
+ return STRING;
+
+ case SWIG_TOKEN_CHAR:
+ yylval.str = NewString(Scanner_text(scan));
+ if (Len(yylval.str) == 0) {
+ Swig_error(cparse_file, cparse_line, "Empty character constant\n");
+ Printf(stdout,"%d\n", Len(Scanner_text(scan)));
+ }
+ return CHARCONST;
+
+ /* Numbers */
+
+ case SWIG_TOKEN_INT:
+ return NUM_INT;
+
+ case SWIG_TOKEN_UINT:
+ return NUM_UNSIGNED;
+
+ case SWIG_TOKEN_LONG:
+ return NUM_LONG;
+
+ case SWIG_TOKEN_ULONG:
+ return NUM_ULONG;
+
+ case SWIG_TOKEN_LONGLONG:
+ return NUM_LONGLONG;
+
+ case SWIG_TOKEN_ULONGLONG:
+ return NUM_ULONGLONG;
+
+ case SWIG_TOKEN_DOUBLE:
+ case SWIG_TOKEN_FLOAT:
+ return NUM_FLOAT;
+
+ case SWIG_TOKEN_POUND:
+ Scanner_skip_line(scan);
+ yylval.id = Swig_copy_string(Char(Scanner_text(scan)));
+ return POUND;
+ break;
+
+ case SWIG_TOKEN_CODEBLOCK:
+ yylval.str = NewString(Scanner_text(scan));
+ return HBLOCK;
+
+ case SWIG_TOKEN_COMMENT:
+ {
+ String *cmt = Scanner_text(scan);
+ char *loc = Char(cmt);
+ if ((strncmp(loc,"/*@SWIG",7) == 0) && (loc[Len(cmt)-3] == '@')) {
+ scanner_locator(cmt);
+ }
+ }
+ break;
+ case SWIG_TOKEN_ENDLINE:
+ break;
+ case SWIG_TOKEN_BACKSLASH:
+ break;
+ default:
+ Swig_error(cparse_file, cparse_line, "Illegal token '%s'.\n", Scanner_text(scan));
+ return (ILLEGAL);
+ }
+ }
+}
+
+static int check_typedef = 0;
+
+void scanner_set_location(String *file, int line) {
+ Scanner_set_location(scan,file,line-1);
+}
+
+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;
+}
+
+/* Used to push a ficticious token into the scanner */
+static int next_token = 0;
+void scanner_next_token(int tok) {
+ next_token = tok;
+}
+
+void scanner_set_main_input_file(String *file) {
+ main_input_file = file;
+}
+
+String *scanner_get_main_input_file() {
+ return main_input_file;
+}
+
+/* ----------------------------------------------------------------------------
+ * int yylex()
+ *
+ * Gets the lexene and returns tokens.
+ * ------------------------------------------------------------------------- */
+
+int yylex(void) {
+
+ int l;
+ char *yytext;
+
+ if (!scan_init) {
+ scanner_init();
+ }
+
+ if (next_token) {
+ l = next_token;
+ next_token = 0;
+ return l;
+ }
+
+ l = yylook();
+
+ /* Printf(stdout, "%s:%d:::%d: '%s'\n", cparse_file, cparse_line, l, Scanner_text(scan)); */
+
+ 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 */
+
+ 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(Scanner_text(scan));
+ yylval.dtype.bitfield = 0;
+ yylval.dtype.throws = 0;
+ return (l);
+
+ case ID:
+ yytext = Char(Scanner_text(scan));
+ 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, "wchar_t") == 0) {
+ yylval.type = NewSwigType(T_WCHAR);
+ return (TYPE_WCHAR);
+ }
+ 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);
+ }
+
+ /* Non ISO (Windows) C extensions */
+ if (strcmp(yytext, "__int8") == 0) {
+ yylval.type = NewString(yytext);
+ return (TYPE_NON_ISO_INT8);
+ }
+ if (strcmp(yytext, "__int16") == 0) {
+ yylval.type = NewString(yytext);
+ return (TYPE_NON_ISO_INT16);
+ }
+ if (strcmp(yytext, "__int32") == 0) {
+ yylval.type = NewString(yytext);
+ return (TYPE_NON_ISO_INT32);
+ }
+ if (strcmp(yytext, "__int64") == 0) {
+ yylval.type = NewString(yytext);
+ return (TYPE_NON_ISO_INT64);
+ }
+
+ /* C++ keywords */
+ if (cparse_cplusplus) {
+ if (strcmp(yytext, "and") == 0)
+ return (LAND);
+ if (strcmp(yytext, "or") == 0)
+ return (LOR);
+ if (strcmp(yytext, "not") == 0)
+ return (LNOT);
+ 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) {
+ int nexttok;
+ String *s = NewString("operator ");
+
+ /* If we have an operator, we have to collect the operator symbol and attach it to
+ the operator identifier. To do this, we need to scan ahead by several tokens.
+ Cases include:
+
+ (1) If the next token is an operator as determined by Scanner_isoperator(),
+ it means that the operator applies to one of the standard C++ mathematical,
+ assignment, or logical operator symbols (e.g., '+','<=','==','&', etc.)
+ In this case, we merely append the symbol text to the operator string above.
+
+ (2) If the next token is (, we look for ). This is operator ().
+ (3) If the next token is [, we look for ]. This is operator [].
+ (4) If the next token is an identifier. The operator is possibly a conversion operator.
+ (a) Must check for special case new[] and delete[]
+
+ Error handling is somewhat tricky here. We'll try to back out gracefully if we can.
+
+ */
+
+ nexttok = Scanner_token(scan);
+ if (Scanner_isoperator(nexttok)) {
+ /* One of the standard C/C++ symbolic operators */
+ Append(s,Scanner_text(scan));
+ yylval.str = s;
+ return OPERATOR;
+ } else if (nexttok == SWIG_TOKEN_LPAREN) {
+ /* Function call operator. The next token MUST be a RPAREN */
+ nexttok = Scanner_token(scan);
+ if (nexttok != SWIG_TOKEN_RPAREN) {
+ Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n");
+ } else {
+ Append(s,"()");
+ yylval.str = s;
+ return OPERATOR;
+ }
+ } else if (nexttok == SWIG_TOKEN_LBRACKET) {
+ /* Array access operator. The next token MUST be a RBRACKET */
+ nexttok = Scanner_token(scan);
+ if (nexttok != SWIG_TOKEN_RBRACKET) {
+ Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n");
+ } else {
+ Append(s,"[]");
+ yylval.str = s;
+ return OPERATOR;
+ }
+ } else if (nexttok == SWIG_TOKEN_ID) {
+ /* We have an identifier. This could be any number of things. It could be a named version of
+ an operator (e.g., 'and_eq') or it could be a conversion operator. To deal with this, we're
+ going to read tokens until we encounter a ( or ;. Some care is needed for formatting. */
+ int needspace = 1;
+ int termtoken = 0;
+ const char *termvalue = 0;
+
+ Append(s,Scanner_text(scan));
+ while (1) {
+
+ nexttok = Scanner_token(scan);
+ if (nexttok <= 0) {
+ Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n");
+ }
+ if (nexttok == SWIG_TOKEN_LPAREN) {
+ termtoken = SWIG_TOKEN_LPAREN;
+ termvalue = "(";
+ break;
+ } else if (nexttok == SWIG_TOKEN_CODEBLOCK) {
+ termtoken = SWIG_TOKEN_CODEBLOCK;
+ termvalue = Char(Scanner_text(scan));
+ break;
+ } else if (nexttok == SWIG_TOKEN_LBRACE) {
+ termtoken = SWIG_TOKEN_LBRACE;
+ termvalue = "{";
+ break;
+ } else if (nexttok == SWIG_TOKEN_SEMI) {
+ termtoken = SWIG_TOKEN_SEMI;
+ termvalue = ";";
+ break;
+ } else if (nexttok == SWIG_TOKEN_STRING) {
+ termtoken = SWIG_TOKEN_STRING;
+ termvalue = Swig_copy_string(Char(Scanner_text(scan)));
+ break;
+ } else if (nexttok == SWIG_TOKEN_ID) {
+ if (needspace) {
+ Append(s," ");
+ }
+ Append(s,Scanner_text(scan));
+ } else {
+ Append(s,Scanner_text(scan));
+ needspace = 0;
+ }
+ }
+ yylval.str = s;
+ if (!rename_active) {
+ String *cs;
+ char *t = Char(s) + 9;
+ if (!((strcmp(t, "new") == 0)
+ || (strcmp(t, "delete") == 0)
+ || (strcmp(t, "new[]") == 0)
+ || (strcmp(t, "delete[]") == 0)
+ || (strcmp(t, "and") == 0)
+ || (strcmp(t, "and_eq") == 0)
+ || (strcmp(t, "bitand") == 0)
+ || (strcmp(t, "bitor") == 0)
+ || (strcmp(t, "compl") == 0)
+ || (strcmp(t, "not") == 0)
+ || (strcmp(t, "not_eq") == 0)
+ || (strcmp(t, "or") == 0)
+ || (strcmp(t, "or_eq") == 0)
+ || (strcmp(t, "xor") == 0)
+ || (strcmp(t, "xor_eq") == 0)
+ )) {
+ /* retract(strlen(t)); */
+
+ /* The operator is a conversion operator. In order to deal with this, we need to feed the
+ type information back into the parser. For now this is a hack. Needs to be cleaned up later. */
+ cs = NewString(t);
+ if (termtoken) Append(cs,termvalue);
+ Seek(cs,0,SEEK_SET);
+ Setline(cs,cparse_line);
+ Setfile(cs,cparse_file);
+ Scanner_push(scan,cs);
+ Delete(cs);
+ return COPERATOR;
+ }
+ }
+ if (termtoken)
+ Scanner_pushtoken(scan, termtoken, termvalue);
+ 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 (EXPLICIT);
+ 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_KW);
+ }
+ 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");
+ }
+ if (strcmp(yytext, "complex") == 0) {
+ yylval.type = NewSwigType(T_COMPLEX);
+ return (TYPE_COMPLEX);
+ }
+ if (strcmp(yytext, "restrict") == 0)
+ return (yylex());
+ }
+
+ /* Misc keywords */
+
+ if (strcmp(yytext, "extern") == 0)
+ return (EXTERN);
+ if (strcmp(yytext, "const") == 0)
+ return (CONST_QUAL);
+ 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);
+ if (strcmp(yytext, "register") == 0)
+ return (REGISTER);
+ if (strcmp(yytext, "inline") == 0)
+ return (yylex());
+
+ /* 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) {
+ /* The rename_active indicates we don't need the information of the
+ * following function's return type. This applied for %rename, so do
+ * %feature.
+ */
+ rename_active = 1;
+ 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.c b/Source/CParse/parser.c
new file mode 100644
index 0000000..e8c8111
--- /dev/null
+++ b/Source/CParse/parser.c
@@ -0,0 +1,10438 @@
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ID = 258,
+ HBLOCK = 259,
+ POUND = 260,
+ STRING = 261,
+ INCLUDE = 262,
+ IMPORT = 263,
+ INSERT = 264,
+ CHARCONST = 265,
+ NUM_INT = 266,
+ NUM_FLOAT = 267,
+ NUM_UNSIGNED = 268,
+ NUM_LONG = 269,
+ NUM_ULONG = 270,
+ NUM_LONGLONG = 271,
+ NUM_ULONGLONG = 272,
+ TYPEDEF = 273,
+ TYPE_INT = 274,
+ TYPE_UNSIGNED = 275,
+ TYPE_SHORT = 276,
+ TYPE_LONG = 277,
+ TYPE_FLOAT = 278,
+ TYPE_DOUBLE = 279,
+ TYPE_CHAR = 280,
+ TYPE_WCHAR = 281,
+ TYPE_VOID = 282,
+ TYPE_SIGNED = 283,
+ TYPE_BOOL = 284,
+ TYPE_COMPLEX = 285,
+ TYPE_TYPEDEF = 286,
+ TYPE_RAW = 287,
+ TYPE_NON_ISO_INT8 = 288,
+ TYPE_NON_ISO_INT16 = 289,
+ TYPE_NON_ISO_INT32 = 290,
+ TYPE_NON_ISO_INT64 = 291,
+ LPAREN = 292,
+ RPAREN = 293,
+ COMMA = 294,
+ SEMI = 295,
+ EXTERN = 296,
+ INIT = 297,
+ LBRACE = 298,
+ RBRACE = 299,
+ PERIOD = 300,
+ CONST_QUAL = 301,
+ VOLATILE = 302,
+ REGISTER = 303,
+ STRUCT = 304,
+ UNION = 305,
+ EQUAL = 306,
+ SIZEOF = 307,
+ MODULE = 308,
+ LBRACKET = 309,
+ RBRACKET = 310,
+ ILLEGAL = 311,
+ CONSTANT = 312,
+ NAME = 313,
+ RENAME = 314,
+ NAMEWARN = 315,
+ EXTEND = 316,
+ PRAGMA = 317,
+ FEATURE = 318,
+ VARARGS = 319,
+ ENUM = 320,
+ CLASS = 321,
+ TYPENAME = 322,
+ PRIVATE = 323,
+ PUBLIC = 324,
+ PROTECTED = 325,
+ COLON = 326,
+ STATIC = 327,
+ VIRTUAL = 328,
+ FRIEND = 329,
+ THROW = 330,
+ CATCH = 331,
+ EXPLICIT = 332,
+ USING = 333,
+ NAMESPACE = 334,
+ NATIVE = 335,
+ INLINE = 336,
+ TYPEMAP = 337,
+ EXCEPT = 338,
+ ECHO = 339,
+ APPLY = 340,
+ CLEAR = 341,
+ SWIGTEMPLATE = 342,
+ FRAGMENT = 343,
+ WARN = 344,
+ LESSTHAN = 345,
+ GREATERTHAN = 346,
+ MODULO = 347,
+ DELETE_KW = 348,
+ LESSTHANOREQUALTO = 349,
+ GREATERTHANOREQUALTO = 350,
+ EQUALTO = 351,
+ NOTEQUALTO = 352,
+ QUESTIONMARK = 353,
+ TYPES = 354,
+ PARMS = 355,
+ NONID = 356,
+ DSTAR = 357,
+ DCNOT = 358,
+ TEMPLATE = 359,
+ OPERATOR = 360,
+ COPERATOR = 361,
+ PARSETYPE = 362,
+ PARSEPARM = 363,
+ PARSEPARMS = 364,
+ CAST = 365,
+ LOR = 366,
+ LAND = 367,
+ OR = 368,
+ XOR = 369,
+ AND = 370,
+ RSHIFT = 371,
+ LSHIFT = 372,
+ MINUS = 373,
+ PLUS = 374,
+ MODULUS = 375,
+ SLASH = 376,
+ STAR = 377,
+ LNOT = 378,
+ NOT = 379,
+ UMINUS = 380,
+ DCOLON = 381
+ };
+#endif
+/* Tokens. */
+#define ID 258
+#define HBLOCK 259
+#define POUND 260
+#define STRING 261
+#define INCLUDE 262
+#define IMPORT 263
+#define INSERT 264
+#define CHARCONST 265
+#define NUM_INT 266
+#define NUM_FLOAT 267
+#define NUM_UNSIGNED 268
+#define NUM_LONG 269
+#define NUM_ULONG 270
+#define NUM_LONGLONG 271
+#define NUM_ULONGLONG 272
+#define TYPEDEF 273
+#define TYPE_INT 274
+#define TYPE_UNSIGNED 275
+#define TYPE_SHORT 276
+#define TYPE_LONG 277
+#define TYPE_FLOAT 278
+#define TYPE_DOUBLE 279
+#define TYPE_CHAR 280
+#define TYPE_WCHAR 281
+#define TYPE_VOID 282
+#define TYPE_SIGNED 283
+#define TYPE_BOOL 284
+#define TYPE_COMPLEX 285
+#define TYPE_TYPEDEF 286
+#define TYPE_RAW 287
+#define TYPE_NON_ISO_INT8 288
+#define TYPE_NON_ISO_INT16 289
+#define TYPE_NON_ISO_INT32 290
+#define TYPE_NON_ISO_INT64 291
+#define LPAREN 292
+#define RPAREN 293
+#define COMMA 294
+#define SEMI 295
+#define EXTERN 296
+#define INIT 297
+#define LBRACE 298
+#define RBRACE 299
+#define PERIOD 300
+#define CONST_QUAL 301
+#define VOLATILE 302
+#define REGISTER 303
+#define STRUCT 304
+#define UNION 305
+#define EQUAL 306
+#define SIZEOF 307
+#define MODULE 308
+#define LBRACKET 309
+#define RBRACKET 310
+#define ILLEGAL 311
+#define CONSTANT 312
+#define NAME 313
+#define RENAME 314
+#define NAMEWARN 315
+#define EXTEND 316
+#define PRAGMA 317
+#define FEATURE 318
+#define VARARGS 319
+#define ENUM 320
+#define CLASS 321
+#define TYPENAME 322
+#define PRIVATE 323
+#define PUBLIC 324
+#define PROTECTED 325
+#define COLON 326
+#define STATIC 327
+#define VIRTUAL 328
+#define FRIEND 329
+#define THROW 330
+#define CATCH 331
+#define EXPLICIT 332
+#define USING 333
+#define NAMESPACE 334
+#define NATIVE 335
+#define INLINE 336
+#define TYPEMAP 337
+#define EXCEPT 338
+#define ECHO 339
+#define APPLY 340
+#define CLEAR 341
+#define SWIGTEMPLATE 342
+#define FRAGMENT 343
+#define WARN 344
+#define LESSTHAN 345
+#define GREATERTHAN 346
+#define MODULO 347
+#define DELETE_KW 348
+#define LESSTHANOREQUALTO 349
+#define GREATERTHANOREQUALTO 350
+#define EQUALTO 351
+#define NOTEQUALTO 352
+#define QUESTIONMARK 353
+#define TYPES 354
+#define PARMS 355
+#define NONID 356
+#define DSTAR 357
+#define DCNOT 358
+#define TEMPLATE 359
+#define OPERATOR 360
+#define COPERATOR 361
+#define PARSETYPE 362
+#define PARSEPARM 363
+#define PARSEPARMS 364
+#define CAST 365
+#define LOR 366
+#define LAND 367
+#define OR 368
+#define XOR 369
+#define AND 370
+#define RSHIFT 371
+#define LSHIFT 372
+#define MINUS 373
+#define PLUS 374
+#define MODULUS 375
+#define SLASH 376
+#define STAR 377
+#define LNOT 378
+#define NOT 379
+#define UMINUS 380
+#define DCOLON 381
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 12 "parser.y"
+
+
+#define yylex yylex
+
+char cvsroot_parser_y[] = "$Id: parser.y 11582 2009-08-15 10:40:19Z wsfulton $";
+
+#include "swig.h"
+#include "cparse.h"
+#include "preprocessor.h"
+#include <ctype.h>
+
+/* We do this for portability */
+#undef alloca
+#define alloca malloc
+
+/* -----------------------------------------------------------------------------
+ * Externals
+ * ----------------------------------------------------------------------------- */
+
+int yyparse();
+
+/* NEW Variables */
+
+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;
+static int extendmode = 0;
+static int compact_default_args = 0;
+static int template_reduce = 0;
+static int cparse_externc = 0;
+
+static int max_class_levels = 0;
+static int class_level = 0;
+static Node **class_decl = NULL;
+
+/* -----------------------------------------------------------------------------
+ * Assist Functions
+ * ----------------------------------------------------------------------------- */
+
+
+
+/* Called by the parser (yyparse) when an error is found.*/
+static void yyerror (const char *e) {
+ (void)e;
+}
+
+static Node *new_node(const_String_or_char_ptr 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;
+ Iterator k;
+ nn = NewHash();
+ Setfile(nn,Getfile(n));
+ Setline(nn,Getline(n));
+ for (k = First(n); k.key; k = Next(k)) {
+ String *ci;
+ String *key = k.key;
+ char *ckey = Char(key);
+ if ((strcmp(ckey,"nextSibling") == 0) ||
+ (strcmp(ckey,"previousSibling") == 0) ||
+ (strcmp(ckey,"parentNode") == 0) ||
+ (strcmp(ckey,"lastChild") == 0)) {
+ continue;
+ }
+ if (Strncmp(key,"csym:",5) == 0) continue;
+ /* We do copy sym:name. For templates */
+ if ((strcmp(ckey,"sym:name") == 0) ||
+ (strcmp(ckey,"sym:weak") == 0) ||
+ (strcmp(ckey,"sym:typename") == 0)) {
+ String *ci = Copy(k.item);
+ Setattr(nn,key, ci);
+ Delete(ci);
+ continue;
+ }
+ if (strcmp(ckey,"sym:symtab") == 0) {
+ Setattr(nn,"sym:needs_symtab", "1");
+ }
+ /* We don't copy any other symbol table attributes */
+ if (strncmp(ckey,"sym:",4) == 0) {
+ continue;
+ }
+ /* If children. We copy them recursively using this function */
+ if (strcmp(ckey,"firstChild") == 0) {
+ /* Copy children */
+ Node *cn = k.item;
+ while (cn) {
+ Node *copy = copy_node(cn);
+ appendChild(nn,copy);
+ Delete(copy);
+ 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(ckey,"symtab") == 0) {
+ /* Node defined a symbol table. */
+ Setattr(nn,"requires_symtab","1");
+ continue;
+ }
+ /* Can't copy nodes */
+ if (strcmp(ckey,"node") == 0) {
+ continue;
+ }
+ if ((strcmp(ckey,"parms") == 0) || (strcmp(ckey,"pattern") == 0) || (strcmp(ckey,"throws") == 0)
+ || (strcmp(ckey,"kwargs") == 0)) {
+ ParmList *pl = CopyParmList(k.item);
+ Setattr(nn,key,pl);
+ Delete(pl);
+ continue;
+ }
+ /* Looks okay. Just copy the data using Copy */
+ ci = Copy(k.item);
+ Setattr(nn, key, ci);
+ Delete(ci);
+ }
+ return nn;
+}
+
+/* -----------------------------------------------------------------------------
+ * Variables
+ * ----------------------------------------------------------------------------- */
+
+static 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
+
+/* include types */
+static int import_mode = 0;
+
+void SWIG_typemap_lang(const char *tm_lang) {
+ typemap_lang = Swig_copy_string(tm_lang);
+}
+
+void SWIG_cparse_set_compact_default_args(int defargs) {
+ compact_default_args = defargs;
+}
+
+int SWIG_cparse_template_reduce(int treduce) {
+ template_reduce = treduce;
+ return treduce;
+}
+
+/* -----------------------------------------------------------------------------
+ * Assist functions
+ * ----------------------------------------------------------------------------- */
+
+static int promote_type(int t) {
+ if (t <= T_UCHAR || t == T_CHAR) return T_INT;
+ return t;
+}
+
+/* Perform type-promotion for binary operators */
+static int promote(int t1, int t2) {
+ t1 = promote_type(t1);
+ t2 = promote_type(t2);
+ return t1 > t2 ? t1 : t2;
+}
+
+static String *yyrename = 0;
+
+/* Forward renaming operator */
+
+static String *resolve_node_scope(String *cname);
+
+
+Hash *Swig_cparse_features(void) {
+ static Hash *features_hash = 0;
+ if (!features_hash) features_hash = NewHash();
+ return features_hash;
+}
+
+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);
+ }
+}
+
+/* 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(Node *n, String *name,SwigType *decl) {
+ int destructor = name && (*(Char(name)) == '~');
+
+ if (yyrename) {
+ String *s = NewString(yyrename);
+ Delete(yyrename);
+ yyrename = 0;
+ if (destructor && (*(Char(s)) != '~')) {
+ Insert(s,0,"~");
+ }
+ return s;
+ }
+
+ if (!name) return 0;
+ return Swig_name_make(n,Namespaceprefix,name,decl,add_oldname);
+}
+
+/* Generate an unnamed identifier */
+static String *make_unnamed() {
+ unnamed++;
+ return NewStringf("$unnamed%d$",unnamed);
+}
+
+/* Return if the node is a friend declaration */
+static int is_friend(Node *n) {
+ return Cmp(Getattr(n,"storage"),"friend") == 0;
+}
+
+static int is_operator(String *name) {
+ return Strncmp(name,"operator ", 9) == 0;
+}
+
+
+/* Add declaration list to symbol table */
+static int add_only_one = 0;
+
+static void add_symbols(Node *n) {
+ String *decl;
+ String *wrn = 0;
+ if (inclass && n) {
+ cparse_normalize_void(n);
+ }
+ while (n) {
+ String *symname = 0;
+ /* for friends, we need to pop the scope once */
+ String *old_prefix = 0;
+ Symtab *old_scope = 0;
+ int isfriend = inclass && is_friend(n);
+ int iscdecl = Cmp(nodeType(n),"cdecl") == 0;
+ int only_csymbol = 0;
+ if (extendmode) {
+ Setattr(n,"isextension","1");
+ }
+
+ if (inclass) {
+ String *name = Getattr(n, "name");
+ if (isfriend) {
+ /* for friends, we need to add the scopename if needed */
+ String *prefix = name ? Swig_scopename_prefix(name) : 0;
+ old_prefix = Namespaceprefix;
+ old_scope = Swig_symbol_popscope();
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ if (!prefix) {
+ if (name && !is_operator(name) && Namespaceprefix) {
+ String *nname = NewStringf("%s::%s", Namespaceprefix, name);
+ Setattr(n,"name",nname);
+ Delete(nname);
+ }
+ } else {
+ Symtab *st = Swig_symbol_getscope(prefix);
+ String *ns = st ? Getattr(st,"name") : prefix;
+ String *base = Swig_scopename_last(name);
+ String *nname = NewStringf("%s::%s", ns, base);
+ Setattr(n,"name",nname);
+ Delete(nname);
+ Delete(base);
+ Delete(prefix);
+ }
+ Namespaceprefix = 0;
+ } else {
+ /* for member functions, we need to remove the redundant
+ class scope if provided, as in
+
+ struct Foo {
+ int Foo::method(int a);
+ };
+
+ */
+ String *prefix = name ? Swig_scopename_prefix(name) : 0;
+ if (prefix) {
+ if (Classprefix && (Equal(prefix,Classprefix))) {
+ String *base = Swig_scopename_last(name);
+ Setattr(n,"name",base);
+ Delete(base);
+ }
+ Delete(prefix);
+ }
+
+ /*
+ if (!Getattr(n,"parentNode") && class_level) set_parentNode(n,class_decl[class_level - 1]);
+ */
+ Setattr(n,"ismember","1");
+ }
+ }
+ if (!isfriend && inclass) {
+ if ((cplus_mode != CPLUS_PUBLIC)) {
+ only_csymbol = 1;
+ if (cplus_mode == CPLUS_PROTECTED) {
+ Setattr(n,"access", "protected");
+ only_csymbol = !Swig_need_protected(n);
+ } else {
+ Setattr(n,"access", "private");
+ /* private are needed only when they are pure virtuals - why? */
+ if ((Cmp(Getattr(n,"storage"),"virtual") == 0) && (Cmp(Getattr(n,"value"),"0") == 0)) {
+ only_csymbol = 0;
+ }
+ }
+ } else {
+ Setattr(n,"access", "public");
+ }
+ }
+ if (Getattr(n,"sym:name")) {
+ n = nextSibling(n);
+ continue;
+ }
+ decl = Getattr(n,"decl");
+ if (!SwigType_isfunction(decl)) {
+ String *name = Getattr(n,"name");
+ String *makename = Getattr(n,"parser:makename");
+ if (iscdecl) {
+ String *storage = Getattr(n, "storage");
+ if (Cmp(storage,"typedef") == 0) {
+ Setattr(n,"kind","typedef");
+ } else {
+ SwigType *type = Getattr(n,"type");
+ String *value = Getattr(n,"value");
+ Setattr(n,"kind","variable");
+ if (value && Len(value)) {
+ Setattr(n,"hasvalue","1");
+ }
+ if (type) {
+ SwigType *ty;
+ SwigType *tmp = 0;
+ if (decl) {
+ ty = tmp = Copy(type);
+ SwigType_push(ty,decl);
+ } else {
+ ty = type;
+ }
+ if (!SwigType_ismutable(ty)) {
+ SetFlag(n,"hasconsttype");
+ SetFlag(n,"feature:immutable");
+ }
+ if (tmp) Delete(tmp);
+ }
+ if (!type) {
+ Printf(stderr,"notype name %s\n", name);
+ }
+ }
+ }
+ Swig_features_get(Swig_cparse_features(), Namespaceprefix, name, 0, n);
+ if (makename) {
+ symname = make_name(n, makename,0);
+ Delattr(n,"parser:makename"); /* temporary information, don't leave it hanging around */
+ } else {
+ makename = name;
+ symname = make_name(n, makename,0);
+ }
+
+ if (!symname) {
+ symname = Copy(Getattr(n,"unnamed"));
+ }
+ if (symname) {
+ wrn = Swig_name_warning(n, Namespaceprefix, symname,0);
+ }
+ } else {
+ String *name = Getattr(n,"name");
+ SwigType *fdecl = Copy(decl);
+ SwigType *fun = SwigType_pop_function(fdecl);
+ if (iscdecl) {
+ Setattr(n,"kind","function");
+ }
+
+ Swig_features_get(Swig_cparse_features(),Namespaceprefix,name,fun,n);
+
+ symname = make_name(n, name,fun);
+ wrn = Swig_name_warning(n, Namespaceprefix,symname,fun);
+
+ Delete(fdecl);
+ Delete(fun);
+
+ }
+ if (!symname) {
+ n = nextSibling(n);
+ continue;
+ }
+ if (only_csymbol || GetFlag(n,"feature:ignore")) {
+ /* Only add to C symbol table and continue */
+ Swig_symbol_add(0, n);
+ } else if (strncmp(Char(symname),"$ignore",7) == 0) {
+ char *c = Char(symname)+7;
+ SetFlag(n,"feature:ignore");
+ if (strlen(c)) {
+ SWIG_WARN_NODE_BEGIN(n);
+ Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1);
+ SWIG_WARN_NODE_END(n);
+ }
+ Swig_symbol_add(0, n);
+ } else {
+ Node *c;
+ if ((wrn) && (Len(wrn))) {
+ String *metaname = symname;
+ if (!Getmeta(metaname,"already_warned")) {
+ SWIG_WARN_NODE_BEGIN(n);
+ Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn);
+ SWIG_WARN_NODE_END(n);
+ Setmeta(metaname,"already_warned","1");
+ }
+ }
+ c = Swig_symbol_add(symname,n);
+
+ if (c != n) {
+ /* symbol conflict attempting to add in the new symbol */
+ if (Getattr(n,"sym:weak")) {
+ Setattr(n,"sym:name",symname);
+ } else {
+ String *e = NewStringEmpty();
+ String *en = NewStringEmpty();
+ String *ec = NewStringEmpty();
+ int redefined = Swig_need_redefined_warn(n,c,inclass);
+ if (redefined) {
+ Printf(en,"Identifier '%s' redefined (ignored)",symname);
+ Printf(ec,"previous definition of '%s'",symname);
+ } else {
+ Printf(en,"Redundant redeclaration of '%s'",symname);
+ Printf(ec,"previous declaration of '%s'",symname);
+ }
+ if (Cmp(symname,Getattr(n,"name"))) {
+ Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name")));
+ }
+ Printf(en,",");
+ if (Cmp(symname,Getattr(c,"name"))) {
+ Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name")));
+ }
+ Printf(ec,".");
+ SWIG_WARN_NODE_BEGIN(n);
+ if (redefined) {
+ Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
+ Swig_warning(WARN_PARSE_REDEFINED,Getfile(c),Getline(c),"%s\n",ec);
+ } else if (!is_friend(n) && !is_friend(c)) {
+ Swig_warning(WARN_PARSE_REDUNDANT,Getfile(n),Getline(n),"%s\n",en);
+ Swig_warning(WARN_PARSE_REDUNDANT,Getfile(c),Getline(c),"%s\n",ec);
+ }
+ SWIG_WARN_NODE_END(n);
+ Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(n),Getline(n),en,
+ Getfile(c),Getline(c),ec);
+ Setattr(n,"error",e);
+ Delete(e);
+ Delete(en);
+ Delete(ec);
+ }
+ }
+ }
+ /* restore the class scope if needed */
+ if (isfriend) {
+ Swig_symbol_setscope(old_scope);
+ if (old_prefix) {
+ Delete(Namespaceprefix);
+ Namespaceprefix = old_prefix;
+ }
+ }
+ Delete(symname);
+
+ if (add_only_one) return;
+ n = nextSibling(n);
+ }
+}
+
+
+/* add symbols a parse tree node copy */
+
+static void add_symbols_copy(Node *n) {
+ String *name;
+ int emode = 0;
+ while (n) {
+ char *cnodeType = Char(nodeType(n));
+
+ if (strcmp(cnodeType,"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);
+ /* Disable this, it prevents %rename to work with templates */
+ /* If already renamed, we used that name */
+ /*
+ if (Strcmp(add_oldname, Getattr(n,"name")) != 0) {
+ Delete(yyrename);
+ yyrename = Copy(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);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+ if (strcmp(cnodeType,"class") == 0) {
+ inclass = 1;
+ current_class = n;
+ if (Strcmp(Getattr(n,"kind"),"class") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else {
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ }
+ if (strcmp(cnodeType,"extend") == 0) {
+ emode = cplus_mode;
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ add_symbols_copy(firstChild(n));
+ if (strcmp(cnodeType,"extend") == 0) {
+ cplus_mode = emode;
+ }
+ if (Getattr(n,"requires_symtab")) {
+ Setattr(n,"symtab", Swig_symbol_popscope());
+ Delattr(n,"requires_symtab");
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+ if (add_oldname) {
+ Delete(add_oldname);
+ add_oldname = 0;
+ }
+ if (strcmp(cnodeType,"class") == 0) {
+ inclass = 0;
+ current_class = 0;
+ }
+ } else {
+ if (strcmp(cnodeType,"extend") == 0) {
+ emode = cplus_mode;
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ add_symbols_copy(firstChild(n));
+ if (strcmp(cnodeType,"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 *cls, Node *am) {
+ Node *n;
+ Node *csym;
+
+ n = firstChild(am);
+ while (n) {
+ String *symname;
+ if (Strcmp(nodeType(n),"constructor") == 0) {
+ symname = Getattr(n,"sym:name");
+ if (symname) {
+ if (Strcmp(symname,Getattr(n,"name")) == 0) {
+ /* If the name and the sym:name of a constructor are the same,
+ then it hasn't been renamed. However---the name of the class
+ itself might have been renamed so we need to do a consistency
+ check here */
+ if (Getattr(cls,"sym:name")) {
+ Setattr(n,"sym:name", Getattr(cls,"sym:name"));
+ }
+ }
+ }
+ }
+
+ 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 = NewStringEmpty();
+ String *en = NewStringEmpty();
+ String *ec = NewStringEmpty();
+ Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
+ Printf(en,"%%extend definition of '%s'.",symname);
+ SWIG_WARN_NODE_BEGIN(n);
+ Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
+ Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
+ SWIG_WARN_NODE_END(n);
+ Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec,
+ Getfile(n),Getline(n),en);
+ Setattr(csym,"error",e);
+ Delete(e);
+ Delete(en);
+ Delete(ec);
+ Swig_symbol_remove(csym); /* Remove class definition */
+ Swig_symbol_add(symname,n); /* Insert extend definition */
+ }
+ }
+ n = nextSibling(n);
+ }
+}
+
+static void append_previous_extension(Node *cls, Node *am) {
+ Node *n, *ne;
+ Node *pe = 0;
+ Node *ae = 0;
+
+ if (!am) return;
+
+ n = firstChild(am);
+ while (n) {
+ ne = nextSibling(n);
+ set_nextSibling(n,0);
+ /* typemaps and fragments need to be prepended */
+ if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
+ if (!pe) pe = new_node("extend");
+ appendChild(pe, n);
+ } else {
+ if (!ae) ae = new_node("extend");
+ appendChild(ae, n);
+ }
+ n = ne;
+ }
+ if (pe) prependChild(cls,pe);
+ if (ae) appendChild(cls,ae);
+}
+
+
+/* Check for unused %extend. Special case, don't report unused
+ extensions for templates */
+
+static void check_extensions() {
+ Iterator ki;
+
+ if (!extendhash) return;
+ for (ki = First(extendhash); ki.key; ki = Next(ki)) {
+ if (!Strchr(ki.key,'<')) {
+ SWIG_WARN_NODE_BEGIN(ki.item);
+ Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", ki.key);
+ SWIG_WARN_NODE_END(ki.item);
+ }
+ }
+}
+
+/* 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);
+ Delete(args);
+ Delete(qargs);
+ nname = prefix;
+ }
+ return nname;
+}
+
+static List *make_inherit_list(String *clsname, List *names) {
+ int i, ilen;
+ String *derived;
+ List *bases = NewList();
+
+ if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname);
+ else derived = NewString(clsname);
+
+ ilen = Len(names);
+ for (i = 0; i < ilen; 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"));
+ Delete(q);
+ } else {
+ base = NewString(Getattr(s,"name"));
+ }
+ } else {
+ base = NewString(n);
+ }
+ } else {
+ base = NewString(n);
+ }
+ if (base) {
+ Swig_name_inherit(base,derived);
+ Delete(base);
+ }
+ }
+ return bases;
+}
+
+/* If the class name is qualified. We need to create or lookup namespace entries */
+
+static Symtab *get_global_scope() {
+ Symtab *symtab = Swig_symbol_current();
+ Node *pn = parentNode(symtab);
+ while (pn) {
+ symtab = pn;
+ pn = parentNode(symtab);
+ if (!pn) break;
+ }
+ Swig_symbol_setscope(symtab);
+ return symtab;
+}
+
+/* Remove the block braces, { and }, if the 'noblock' attribute is set.
+ * Node *kw can be either a Hash or Parmlist. */
+static String *remove_block(Node *kw, const String *inputcode) {
+ String *modified_code = 0;
+ while (kw) {
+ String *name = Getattr(kw,"name");
+ if (name && (Cmp(name,"noblock") == 0)) {
+ char *cstr = Char(inputcode);
+ size_t len = Len(inputcode);
+ if (len && cstr[0] == '{') {
+ --len; ++cstr;
+ if (len && cstr[len - 1] == '}') { --len; }
+ /* we now remove the extra spaces */
+ while (len && isspace((int)cstr[0])) { --len; ++cstr; }
+ while (len && isspace((int)cstr[len - 1])) { --len; }
+ modified_code = NewStringWithSize(cstr, len);
+ break;
+ }
+ }
+ kw = nextSibling(kw);
+ }
+ return modified_code;
+}
+
+
+static Node *nscope = 0;
+static Node *nscope_inner = 0;
+static String *resolve_node_scope(String *cname) {
+ Symtab *gscope = 0;
+ nscope = 0;
+ nscope_inner = 0;
+ if (Swig_scopename_check(cname)) {
+ Node *ns;
+ String *prefix = Swig_scopename_prefix(cname);
+ String *base = Swig_scopename_last(cname);
+ if (prefix && (Strncmp(prefix,"::",2) == 0)) {
+ /* Use the global scope */
+ String *nprefix = NewString(Char(prefix)+2);
+ Delete(prefix);
+ prefix= nprefix;
+ gscope = get_global_scope();
+ }
+ if (!prefix || (Len(prefix) == 0)) {
+ /* Use the global scope, but we need to add a 'global' namespace. */
+ if (!gscope) gscope = get_global_scope();
+ /* note that this namespace is not the "unnamed" one,
+ and we don't use Setattr(nscope,"name", ""),
+ because the unnamed namespace is private */
+ nscope = new_node("namespace");
+ Setattr(nscope,"symtab", gscope);;
+ nscope_inner = nscope;
+ return base;
+ }
+ /* 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 {
+ Symtab *nstab = Getattr(ns,"symtab");
+ if (!nstab) {
+ Swig_error(cparse_file,cparse_line,
+ "'%s' is not defined as a valid scope.\n", prefix);
+ ns = 0;
+ } else {
+ /* Check if the node scope is the current scope */
+ String *tname = Swig_symbol_qualifiedscopename(0);
+ String *nname = Swig_symbol_qualifiedscopename(nstab);
+ if (tname && (Strcmp(tname,nname) == 0)) {
+ ns = 0;
+ cname = base;
+ }
+ Delete(tname);
+ Delete(nname);
+ }
+ if (ns) {
+ /* we will try to create a new node using the namespaces we
+ can find in the scope name */
+ List *scopes;
+ String *sname;
+ Iterator si;
+ String *name = NewString(prefix);
+ scopes = NewList();
+ while (name) {
+ String *base = Swig_scopename_last(name);
+ String *tprefix = Swig_scopename_prefix(name);
+ Insert(scopes,0,base);
+ Delete(base);
+ Delete(name);
+ name = tprefix;
+ }
+ for (si = First(scopes); si.item; si = Next(si)) {
+ Node *ns1,*ns2;
+ sname = si.item;
+ ns1 = Swig_symbol_clookup(sname,0);
+ assert(ns1);
+ if (Strcmp(nodeType(ns1),"namespace") == 0) {
+ if (Getattr(ns1,"alias")) {
+ ns1 = Getattr(ns1,"namespace");
+ }
+ } else {
+ /* now this last part is a class */
+ si = Next(si);
+ ns1 = Swig_symbol_clookup(sname,0);
+ /* or a nested class tree, which is unrolled here */
+ for (; si.item; si = Next(si)) {
+ if (si.item) {
+ Printf(sname,"::%s",si.item);
+ }
+ }
+ /* we get the 'inner' class */
+ nscope_inner = Swig_symbol_clookup(sname,0);
+ /* set the scope to the inner class */
+ Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
+ /* save the last namespace prefix */
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ /* and return the node name, including the inner class prefix */
+ break;
+ }
+ /* here we just populate the namespace tree as usual */
+ ns2 = new_node("namespace");
+ Setattr(ns2,"name",sname);
+ Setattr(ns2,"symtab", Getattr(ns1,"symtab"));
+ add_symbols(ns2);
+ Swig_symbol_setscope(Getattr(ns1,"symtab"));
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ if (nscope_inner) {
+ if (Getattr(nscope_inner,"symtab") != Getattr(ns2,"symtab")) {
+ appendChild(nscope_inner,ns2);
+ Delete(ns2);
+ }
+ }
+ nscope_inner = ns2;
+ if (!nscope) nscope = ns2;
+ }
+ cname = base;
+ Delete(scopes);
+ }
+ }
+ Delete(prefix);
+ }
+ return cname;
+}
+
+
+
+
+
+/* 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 */
+ int unnamed; /* unnamed 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;
+ }
+}
+
+/* Strips C-style and C++-style comments from string in-place. */
+static void strip_comments(char *string) {
+ int state = 0; /*
+ * 0 - not in comment
+ * 1 - in c-style comment
+ * 2 - in c++-style comment
+ * 3 - in string
+ * 4 - after reading / not in comments
+ * 5 - after reading * in c-style comments
+ * 6 - after reading \ in strings
+ */
+ char * c = string;
+ while (*c) {
+ switch (state) {
+ case 0:
+ if (*c == '\"')
+ state = 3;
+ else if (*c == '/')
+ state = 4;
+ break;
+ case 1:
+ if (*c == '*')
+ state = 5;
+ *c = ' ';
+ break;
+ case 2:
+ if (*c == '\n')
+ state = 0;
+ else
+ *c = ' ';
+ break;
+ case 3:
+ if (*c == '\"')
+ state = 0;
+ else if (*c == '\\')
+ state = 6;
+ break;
+ case 4:
+ if (*c == '/') {
+ *(c-1) = ' ';
+ *c = ' ';
+ state = 2;
+ } else if (*c == '*') {
+ *(c-1) = ' ';
+ *c = ' ';
+ state = 1;
+ } else
+ state = 0;
+ break;
+ case 5:
+ if (*c == '/')
+ state = 0;
+ else
+ state = 1;
+ *c = ' ';
+ break;
+ case 6:
+ state = 3;
+ break;
+ }
+ ++c;
+ }
+}
+
+/* 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(const char *parent) {
+ Nested *n,*n1;
+ Node *ret = 0;
+ n = nested_list;
+ if (!parent) {
+ nested_list = 0;
+ return 0;
+ }
+ while (n) {
+ Node *retx;
+ SwigType *nt;
+ /* 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) */
+ 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);
+ nt = Copy(n->type);
+ Setattr(retx,"type",nt);
+ Delete(nt);
+ Setattr(retx,"nested",parent);
+ if (n->unnamed) {
+ Setattr(retx,"unnamed","1");
+ }
+
+ add_symbols(retx);
+ if (ret) {
+ set_nextSibling(retx,ret);
+ Delete(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;
+ */
+
+ /* Strip comments - further code may break in presence of comments. */
+ strip_comments(Char(n->code));
+
+ /* 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 opening brace */
+
+ code_ptr = strstr(code_ptr, types_array[i]);
+ if (code_ptr) {
+ char *open_bracket_pos;
+ code_ptr += strlen(types_array[i]);
+ open_bracket_pos = strchr(code_ptr, '{');
+ if (open_bracket_pos) {
+ /* Make sure we don't have something like struct A a; */
+ char* semi_colon_pos = strchr(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 = strchr(code_ptr, ';');
+ if (directive_end_pos) {
+ while (code_ptr <= directive_end_pos)
+ *code_ptr++ = ' ';
+ }
+ }
+ }
+ }
+ {
+ Node *head = new_node("insert");
+ String *code = NewStringf("\n%s\n",n->code);
+ Setattr(head,"code", code);
+ Delete(code);
+ set_nextSibling(head,ret);
+ Delete(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) {
+ scanner_file(f);
+ top = 0;
+ yyparse();
+ return top;
+}
+
+static void single_new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
+ String *fname;
+ String *name;
+ String *fixname;
+ SwigType *t = Copy(type);
+
+ /* Printf(stdout, "single_new_feature: [%s] [%s] [%s] [%s] [%s] [%s]\n", featurename, val, declaratorid, t, ParmList_str_defaultargs(declaratorparms), qualifier); */
+
+ fname = NewStringf("feature:%s",featurename);
+ if (declaratorid) {
+ fixname = feature_identifier_fix(declaratorid);
+ } else {
+ fixname = NewStringEmpty();
+ }
+ if (Namespaceprefix) {
+ name = NewStringf("%s::%s",Namespaceprefix, fixname);
+ } else {
+ name = fixname;
+ }
+
+ if (declaratorparms) Setmeta(val,"parms",declaratorparms);
+ if (!Len(t)) t = 0;
+ if (t) {
+ if (qualifier) SwigType_push(t,qualifier);
+ if (SwigType_isfunction(t)) {
+ SwigType *decl = SwigType_pop_function(t);
+ if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(Swig_cparse_features(), nname, decl, fname, val, featureattribs);
+ Delete(nname);
+ } else {
+ Swig_feature_set(Swig_cparse_features(), name, decl, fname, val, featureattribs);
+ }
+ Delete(decl);
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(Swig_cparse_features(),nname,0,fname,val, featureattribs);
+ Delete(nname);
+ }
+ } else {
+ /* Global feature, that is, feature not associated with any particular symbol */
+ Swig_feature_set(Swig_cparse_features(),name,0,fname,val, featureattribs);
+ }
+ Delete(fname);
+ Delete(name);
+}
+
+/* Add a new feature to the Hash. Additional features are added if the feature has a parameter list (declaratorparms)
+ * and one or more of the parameters have a default argument. An extra feature is added for each defaulted parameter,
+ * simulating the equivalent overloaded method. */
+static void new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
+
+ ParmList *declparms = declaratorparms;
+
+ /* remove the { and } braces if the noblock attribute is set */
+ String *newval = remove_block(featureattribs, val);
+ val = newval ? newval : val;
+
+ /* Add the feature */
+ single_new_feature(featurename, val, featureattribs, declaratorid, type, declaratorparms, qualifier);
+
+ /* Add extra features if there are default parameters in the parameter list */
+ if (type) {
+ while (declparms) {
+ if (ParmList_has_defaultargs(declparms)) {
+
+ /* Create a parameter list for the new feature by copying all
+ but the last (defaulted) parameter */
+ ParmList* newparms = CopyParmListMax(declparms, ParmList_len(declparms)-1);
+
+ /* Create new declaration - with the last parameter removed */
+ SwigType *newtype = Copy(type);
+ Delete(SwigType_pop_function(newtype)); /* remove the old parameter list from newtype */
+ SwigType_add_function(newtype,newparms);
+
+ single_new_feature(featurename, Copy(val), featureattribs, declaratorid, newtype, newparms, qualifier);
+ declparms = newparms;
+ } else {
+ declparms = 0;
+ }
+ }
+ }
+}
+
+/* check if a function declaration is a plain C object */
+static int is_cfunction(Node *n) {
+ if (!cparse_cplusplus || cparse_externc) return 1;
+ if (Cmp(Getattr(n,"storage"),"externc") == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/* If the Node is a function with parameters, check to see if any of the parameters
+ * have default arguments. If so create a new function for each defaulted argument.
+ * The additional functions form a linked list of nodes with the head being the original Node n. */
+static void default_arguments(Node *n) {
+ Node *function = n;
+
+ if (function) {
+ ParmList *varargs = Getattr(function,"feature:varargs");
+ if (varargs) {
+ /* Handles the %varargs directive by looking for "feature:varargs" and
+ * substituting ... with an alternative set of arguments. */
+ Parm *p = Getattr(function,"parms");
+ Parm *pp = 0;
+ while (p) {
+ SwigType *t = Getattr(p,"type");
+ if (Strcmp(t,"v(...)") == 0) {
+ if (pp) {
+ ParmList *cv = Copy(varargs);
+ set_nextSibling(pp,cv);
+ Delete(cv);
+ } else {
+ ParmList *cv = Copy(varargs);
+ Setattr(function,"parms", cv);
+ Delete(cv);
+ }
+ break;
+ }
+ pp = p;
+ p = nextSibling(p);
+ }
+ }
+
+ /* Do not add in functions if kwargs is being used or if user wants old default argument wrapping
+ (one wrapped method per function irrespective of number of default arguments) */
+ if (compact_default_args
+ || is_cfunction(function)
+ || GetFlag(function,"feature:compactdefaultargs")
+ || GetFlag(function,"feature:kwargs")) {
+ ParmList *p = Getattr(function,"parms");
+ if (p)
+ Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */
+ function = 0; /* don't add in extra methods */
+ }
+ }
+
+ while (function) {
+ ParmList *parms = Getattr(function,"parms");
+ if (ParmList_has_defaultargs(parms)) {
+
+ /* Create a parameter list for the new function by copying all
+ but the last (defaulted) parameter */
+ ParmList* newparms = CopyParmListMax(parms,ParmList_len(parms)-1);
+
+ /* Create new function and add to symbol table */
+ {
+ SwigType *ntype = Copy(nodeType(function));
+ char *cntype = Char(ntype);
+ Node *new_function = new_node(ntype);
+ SwigType *decl = Copy(Getattr(function,"decl"));
+ int constqualifier = SwigType_isconst(decl);
+ String *ccode = Copy(Getattr(function,"code"));
+ String *cstorage = Copy(Getattr(function,"storage"));
+ String *cvalue = Copy(Getattr(function,"value"));
+ SwigType *ctype = Copy(Getattr(function,"type"));
+ String *cthrow = Copy(Getattr(function,"throw"));
+
+ Delete(SwigType_pop_function(decl)); /* remove the old parameter list from decl */
+ SwigType_add_function(decl,newparms);
+ if (constqualifier)
+ SwigType_add_qualifier(decl,"const");
+
+ Setattr(new_function,"name", Getattr(function,"name"));
+ Setattr(new_function,"code", ccode);
+ Setattr(new_function,"decl", decl);
+ Setattr(new_function,"parms", newparms);
+ Setattr(new_function,"storage", cstorage);
+ Setattr(new_function,"value", cvalue);
+ Setattr(new_function,"type", ctype);
+ Setattr(new_function,"throw", cthrow);
+
+ Delete(ccode);
+ Delete(cstorage);
+ Delete(cvalue);
+ Delete(ctype);
+ Delete(cthrow);
+ Delete(decl);
+
+ {
+ Node *throws = Getattr(function,"throws");
+ ParmList *pl = CopyParmList(throws);
+ if (throws) Setattr(new_function,"throws",pl);
+ Delete(pl);
+ }
+
+ /* copy specific attributes for global (or in a namespace) template functions - these are not templated class methods */
+ if (strcmp(cntype,"template") == 0) {
+ Node *templatetype = Getattr(function,"templatetype");
+ Node *symtypename = Getattr(function,"sym:typename");
+ Parm *templateparms = Getattr(function,"templateparms");
+ if (templatetype) {
+ Node *tmp = Copy(templatetype);
+ Setattr(new_function,"templatetype",tmp);
+ Delete(tmp);
+ }
+ if (symtypename) {
+ Node *tmp = Copy(symtypename);
+ Setattr(new_function,"sym:typename",tmp);
+ Delete(tmp);
+ }
+ if (templateparms) {
+ Parm *tmp = CopyParmList(templateparms);
+ Setattr(new_function,"templateparms",tmp);
+ Delete(tmp);
+ }
+ } else if (strcmp(cntype,"constructor") == 0) {
+ /* only copied for constructors as this is not a user defined feature - it is hard coded in the parser */
+ if (GetFlag(function,"feature:new")) SetFlag(new_function,"feature:new");
+ }
+
+ add_symbols(new_function);
+ /* mark added functions as ones with overloaded parameters and point to the parsed method */
+ Setattr(new_function,"defaultargs", n);
+
+ /* Point to the new function, extending the linked list */
+ set_nextSibling(function, new_function);
+ Delete(new_function);
+ function = new_function;
+
+ Delete(ntype);
+ }
+ } else {
+ function = 0;
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * tag_nodes()
+ *
+ * Used by the parser to mark subtypes with extra information.
+ * ----------------------------------------------------------------------------- */
+
+static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
+ while (n) {
+ Setattr(n, attrname, value);
+ tag_nodes(firstChild(n), attrname, value);
+ n = nextSibling(n);
+ }
+}
+
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 1440 "parser.y"
+{
+ char *id;
+ List *bases;
+ struct Define {
+ String *val;
+ String *rawval;
+ int type;
+ String *qualifier;
+ String *bitfield;
+ Parm *throws;
+ String *throwf;
+ } dtype;
+ struct {
+ char *type;
+ String *filename;
+ int line;
+ } loc;
+ struct {
+ char *id;
+ SwigType *type;
+ String *defarg;
+ ParmList *parms;
+ short have_parms;
+ ParmList *throws;
+ String *throwf;
+ } decl;
+ Parm *tparms;
+ struct {
+ String *method;
+ Hash *kwargs;
+ } tmap;
+ struct {
+ String *type;
+ String *us;
+ } ptype;
+ SwigType *type;
+ String *str;
+ Parm *p;
+ ParmList *pl;
+ int ivalue;
+ Node *node;
+}
+/* Line 187 of yacc.c. */
+#line 1819 "y.tab.c"
+ YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 216 of yacc.c. */
+#line 1832 "y.tab.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+ int i;
+#endif
+{
+ return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 55
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 3902
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 127
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 148
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 467
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 904
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 381
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 5, 9, 12, 16, 19, 25, 29,
+ 32, 34, 36, 38, 40, 42, 44, 46, 49, 51,
+ 53, 55, 57, 59, 61, 63, 65, 67, 69, 71,
+ 73, 75, 77, 79, 81, 83, 85, 87, 89, 91,
+ 92, 100, 106, 110, 116, 122, 126, 129, 132, 138,
+ 141, 147, 150, 155, 157, 159, 167, 175, 181, 182,
+ 190, 192, 194, 197, 200, 202, 208, 214, 220, 224,
+ 229, 233, 241, 250, 256, 260, 262, 264, 268, 270,
+ 275, 283, 290, 292, 294, 302, 312, 321, 332, 338,
+ 346, 353, 362, 364, 366, 372, 377, 383, 391, 393,
+ 397, 404, 411, 420, 422, 425, 429, 431, 434, 438,
+ 445, 451, 461, 464, 466, 468, 470, 471, 478, 484,
+ 486, 491, 493, 495, 498, 504, 511, 516, 524, 533,
+ 540, 542, 544, 546, 548, 550, 552, 553, 563, 564,
+ 573, 575, 578, 583, 584, 591, 595, 597, 599, 601,
+ 603, 605, 607, 609, 612, 614, 616, 618, 622, 624,
+ 628, 633, 634, 641, 642, 648, 654, 657, 658, 665,
+ 667, 669, 670, 674, 676, 678, 680, 682, 684, 686,
+ 688, 690, 694, 696, 698, 700, 702, 704, 706, 708,
+ 710, 712, 719, 726, 734, 743, 752, 760, 766, 769,
+ 772, 775, 776, 784, 785, 792, 793, 802, 804, 806,
+ 808, 810, 812, 814, 816, 818, 820, 822, 824, 826,
+ 828, 831, 834, 837, 842, 845, 851, 853, 856, 858,
+ 860, 862, 864, 866, 868, 870, 873, 875, 879, 881,
+ 884, 892, 896, 898, 901, 903, 907, 909, 911, 913,
+ 916, 922, 925, 928, 930, 933, 936, 938, 940, 942,
+ 944, 947, 951, 953, 956, 960, 965, 971, 976, 978,
+ 981, 985, 990, 996, 1000, 1005, 1010, 1012, 1015, 1020,
+ 1025, 1031, 1035, 1040, 1045, 1047, 1050, 1053, 1057, 1059,
+ 1062, 1064, 1067, 1071, 1076, 1080, 1085, 1088, 1092, 1096,
+ 1101, 1105, 1109, 1112, 1115, 1117, 1119, 1122, 1124, 1126,
+ 1128, 1130, 1133, 1135, 1138, 1142, 1144, 1146, 1148, 1151,
+ 1154, 1156, 1158, 1161, 1163, 1165, 1168, 1170, 1172, 1174,
+ 1176, 1178, 1180, 1182, 1184, 1186, 1188, 1190, 1192, 1194,
+ 1196, 1197, 1200, 1202, 1204, 1208, 1210, 1212, 1216, 1218,
+ 1220, 1222, 1224, 1226, 1228, 1234, 1236, 1238, 1242, 1247,
+ 1253, 1259, 1266, 1269, 1272, 1274, 1276, 1278, 1280, 1282,
+ 1284, 1286, 1290, 1294, 1298, 1302, 1306, 1310, 1314, 1318,
+ 1322, 1326, 1330, 1334, 1338, 1342, 1346, 1350, 1356, 1359,
+ 1362, 1365, 1368, 1371, 1373, 1374, 1378, 1380, 1382, 1386,
+ 1389, 1394, 1396, 1398, 1400, 1402, 1404, 1406, 1408, 1410,
+ 1412, 1414, 1416, 1421, 1427, 1429, 1433, 1437, 1442, 1447,
+ 1451, 1454, 1456, 1458, 1462, 1465, 1469, 1471, 1473, 1475,
+ 1477, 1479, 1482, 1487, 1489, 1493, 1495, 1499, 1503, 1506,
+ 1509, 1512, 1515, 1518, 1523, 1525, 1529, 1531, 1535, 1539,
+ 1542, 1545, 1548, 1551, 1553, 1555, 1557, 1559, 1563, 1565,
+ 1569, 1575, 1577, 1581, 1585, 1591, 1593, 1595
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 128, 0, -1, 129, -1, 107, 215, 40, -1, 107,
+ 1, -1, 108, 215, 40, -1, 108, 1, -1, 109,
+ 37, 212, 38, 40, -1, 109, 1, 40, -1, 129,
+ 130, -1, 274, -1, 131, -1, 168, -1, 176, -1,
+ 40, -1, 1, -1, 175, -1, 1, 106, -1, 132,
+ -1, 134, -1, 135, -1, 136, -1, 137, -1, 138,
+ -1, 141, -1, 142, -1, 145, -1, 146, -1, 147,
+ -1, 148, -1, 149, -1, 150, -1, 153, -1, 155,
+ -1, 158, -1, 160, -1, 165, -1, 166, -1, 167,
+ -1, -1, 61, 271, 264, 43, 133, 193, 44, -1,
+ 85, 164, 43, 162, 44, -1, 86, 162, 40, -1,
+ 57, 3, 51, 237, 40, -1, 57, 231, 223, 220,
+ 40, -1, 57, 1, 40, -1, 84, 4, -1, 84,
+ 269, -1, 83, 37, 3, 38, 43, -1, 83, 43,
+ -1, 83, 37, 3, 38, 40, -1, 83, 40, -1,
+ 269, 43, 215, 44, -1, 269, -1, 139, -1, 88,
+ 37, 140, 39, 272, 38, 4, -1, 88, 37, 140,
+ 39, 272, 38, 43, -1, 88, 37, 140, 38, 40,
+ -1, -1, 144, 271, 269, 54, 143, 129, 55, -1,
+ 7, -1, 8, -1, 81, 4, -1, 81, 43, -1,
+ 4, -1, 9, 37, 262, 38, 269, -1, 9, 37,
+ 262, 38, 4, -1, 9, 37, 262, 38, 43, -1,
+ 53, 271, 262, -1, 58, 37, 262, 38, -1, 58,
+ 37, 38, -1, 80, 37, 3, 38, 211, 3, 40,
+ -1, 80, 37, 3, 38, 211, 231, 223, 40, -1,
+ 62, 152, 3, 51, 151, -1, 62, 152, 3, -1,
+ 269, -1, 4, -1, 37, 3, 38, -1, 274, -1,
+ 154, 223, 262, 40, -1, 154, 37, 272, 38, 223,
+ 256, 40, -1, 154, 37, 272, 38, 269, 40, -1,
+ 59, -1, 60, -1, 63, 37, 262, 38, 223, 256,
+ 156, -1, 63, 37, 262, 39, 273, 38, 223, 256,
+ 40, -1, 63, 37, 262, 157, 38, 223, 256, 156,
+ -1, 63, 37, 262, 39, 273, 157, 38, 223, 256,
+ 40, -1, 63, 37, 262, 38, 156, -1, 63, 37,
+ 262, 39, 273, 38, 40, -1, 63, 37, 262, 157,
+ 38, 156, -1, 63, 37, 262, 39, 273, 157, 38,
+ 40, -1, 270, -1, 40, -1, 100, 37, 212, 38,
+ 40, -1, 39, 262, 51, 273, -1, 39, 262, 51,
+ 273, 157, -1, 64, 37, 159, 38, 223, 256, 40,
+ -1, 212, -1, 11, 39, 215, -1, 82, 37, 161,
+ 38, 162, 270, -1, 82, 37, 161, 38, 162, 40,
+ -1, 82, 37, 161, 38, 162, 51, 164, 40, -1,
+ 272, -1, 164, 163, -1, 39, 164, 163, -1, 274,
+ -1, 231, 222, -1, 37, 212, 38, -1, 37, 212,
+ 38, 37, 212, 38, -1, 99, 37, 212, 38, 156,
+ -1, 87, 37, 263, 38, 267, 90, 216, 91, 40,
+ -1, 89, 269, -1, 170, -1, 174, -1, 173, -1,
+ -1, 41, 269, 43, 169, 129, 44, -1, 211, 231,
+ 223, 172, 171, -1, 40, -1, 39, 223, 172, 171,
+ -1, 43, -1, 220, -1, 229, 220, -1, 75, 37,
+ 212, 38, 220, -1, 229, 75, 37, 212, 38, 220,
+ -1, 211, 65, 3, 40, -1, 211, 65, 239, 43,
+ 240, 44, 40, -1, 211, 65, 239, 43, 240, 44,
+ 223, 171, -1, 211, 231, 37, 212, 38, 257, -1,
+ 177, -1, 181, -1, 182, -1, 189, -1, 190, -1,
+ 200, -1, -1, 211, 254, 264, 247, 43, 178, 193,
+ 44, 180, -1, -1, 211, 254, 43, 179, 193, 44,
+ 223, 171, -1, 40, -1, 223, 171, -1, 211, 254,
+ 264, 40, -1, -1, 104, 90, 185, 91, 183, 184,
+ -1, 104, 254, 264, -1, 170, -1, 177, -1, 197,
+ -1, 182, -1, 181, -1, 199, -1, 186, -1, 187,
+ 188, -1, 274, -1, 253, -1, 215, -1, 39, 187,
+ 188, -1, 274, -1, 78, 264, 40, -1, 78, 79,
+ 264, 40, -1, -1, 79, 264, 43, 191, 129, 44,
+ -1, -1, 79, 43, 192, 129, 44, -1, 79, 3,
+ 51, 264, 40, -1, 196, 193, -1, -1, 61, 43,
+ 194, 193, 44, 193, -1, 142, -1, 274, -1, -1,
+ 1, 195, 193, -1, 168, -1, 197, -1, 198, -1,
+ 201, -1, 207, -1, 199, -1, 181, -1, 202, -1,
+ 211, 264, 40, -1, 189, -1, 182, -1, 200, -1,
+ 166, -1, 167, -1, 210, -1, 141, -1, 165, -1,
+ 40, -1, 211, 231, 37, 212, 38, 257, -1, 124,
+ 266, 37, 212, 38, 208, -1, 73, 124, 266, 37,
+ 212, 38, 209, -1, 211, 106, 231, 228, 37, 212,
+ 38, 209, -1, 211, 106, 231, 115, 37, 212, 38,
+ 209, -1, 211, 106, 231, 37, 212, 38, 209, -1,
+ 76, 37, 212, 38, 43, -1, 69, 71, -1, 68,
+ 71, -1, 70, 71, -1, -1, 211, 254, 3, 43,
+ 203, 206, 40, -1, -1, 211, 254, 43, 204, 206,
+ 40, -1, -1, 211, 254, 264, 71, 250, 43, 205,
+ 40, -1, 223, -1, 274, -1, 150, -1, 136, -1,
+ 148, -1, 153, -1, 155, -1, 158, -1, 146, -1,
+ 160, -1, 134, -1, 135, -1, 137, -1, 256, 40,
+ -1, 256, 43, -1, 256, 40, -1, 256, 51, 237,
+ 40, -1, 256, 43, -1, 211, 231, 71, 243, 40,
+ -1, 41, -1, 41, 269, -1, 72, -1, 18, -1,
+ 73, -1, 74, -1, 77, -1, 274, -1, 213, -1,
+ 215, 214, -1, 274, -1, 39, 215, 214, -1, 274,
+ -1, 232, 221, -1, 104, 90, 254, 91, 254, 264,
+ 220, -1, 45, 45, 45, -1, 217, -1, 219, 218,
+ -1, 274, -1, 39, 219, 218, -1, 274, -1, 215,
+ -1, 244, -1, 51, 237, -1, 51, 237, 54, 243,
+ 55, -1, 51, 43, -1, 71, 243, -1, 274, -1,
+ 223, 220, -1, 226, 220, -1, 220, -1, 223, -1,
+ 226, -1, 274, -1, 228, 224, -1, 228, 115, 224,
+ -1, 225, -1, 115, 224, -1, 264, 102, 224, -1,
+ 228, 264, 102, 224, -1, 228, 264, 102, 115, 224,
+ -1, 264, 102, 115, 224, -1, 264, -1, 124, 264,
+ -1, 37, 264, 38, -1, 37, 228, 224, 38, -1,
+ 37, 264, 102, 224, 38, -1, 224, 54, 55, -1,
+ 224, 54, 243, 55, -1, 224, 37, 212, 38, -1,
+ 264, -1, 124, 264, -1, 37, 228, 225, 38, -1,
+ 37, 115, 225, 38, -1, 37, 264, 102, 225, 38,
+ -1, 225, 54, 55, -1, 225, 54, 243, 55, -1,
+ 225, 37, 212, 38, -1, 228, -1, 228, 227, -1,
+ 228, 115, -1, 228, 115, 227, -1, 227, -1, 115,
+ 227, -1, 115, -1, 264, 102, -1, 228, 264, 102,
+ -1, 228, 264, 102, 227, -1, 227, 54, 55, -1,
+ 227, 54, 243, 55, -1, 54, 55, -1, 54, 243,
+ 55, -1, 37, 226, 38, -1, 227, 37, 212, 38,
+ -1, 37, 212, 38, -1, 122, 229, 228, -1, 122,
+ 228, -1, 122, 229, -1, 122, -1, 230, -1, 230,
+ 229, -1, 46, -1, 47, -1, 48, -1, 232, -1,
+ 229, 233, -1, 233, -1, 233, 229, -1, 229, 233,
+ 229, -1, 234, -1, 29, -1, 27, -1, 31, 261,
+ -1, 65, 264, -1, 32, -1, 264, -1, 254, 264,
+ -1, 235, -1, 236, -1, 236, 235, -1, 19, -1,
+ 21, -1, 22, -1, 25, -1, 26, -1, 23, -1,
+ 24, -1, 28, -1, 20, -1, 30, -1, 33, -1,
+ 34, -1, 35, -1, 36, -1, -1, 238, 243, -1,
+ 3, -1, 274, -1, 240, 39, 241, -1, 241, -1,
+ 3, -1, 3, 51, 242, -1, 274, -1, 243, -1,
+ 244, -1, 231, -1, 245, -1, 269, -1, 52, 37,
+ 231, 221, 38, -1, 246, -1, 10, -1, 37, 243,
+ 38, -1, 37, 243, 38, 243, -1, 37, 243, 228,
+ 38, 243, -1, 37, 243, 115, 38, 243, -1, 37,
+ 243, 228, 115, 38, 243, -1, 115, 243, -1, 122,
+ 243, -1, 11, -1, 12, -1, 13, -1, 14, -1,
+ 15, -1, 16, -1, 17, -1, 243, 119, 243, -1,
+ 243, 118, 243, -1, 243, 122, 243, -1, 243, 121,
+ 243, -1, 243, 120, 243, -1, 243, 115, 243, -1,
+ 243, 113, 243, -1, 243, 114, 243, -1, 243, 117,
+ 243, -1, 243, 116, 243, -1, 243, 112, 243, -1,
+ 243, 111, 243, -1, 243, 96, 243, -1, 243, 97,
+ 243, -1, 243, 95, 243, -1, 243, 94, 243, -1,
+ 243, 98, 243, 71, 243, -1, 118, 243, -1, 119,
+ 243, -1, 124, 243, -1, 123, 243, -1, 231, 37,
+ -1, 248, -1, -1, 71, 249, 250, -1, 274, -1,
+ 251, -1, 250, 39, 251, -1, 255, 264, -1, 255,
+ 252, 255, 264, -1, 69, -1, 68, -1, 70, -1,
+ 66, -1, 67, -1, 253, -1, 49, -1, 50, -1,
+ 73, -1, 274, -1, 229, -1, 75, 37, 212, 38,
+ -1, 229, 75, 37, 212, 38, -1, 274, -1, 256,
+ 258, 40, -1, 256, 258, 43, -1, 37, 212, 38,
+ 40, -1, 37, 212, 38, 43, -1, 51, 237, 40,
+ -1, 71, 259, -1, 274, -1, 260, -1, 259, 39,
+ 260, -1, 264, 37, -1, 90, 216, 91, -1, 274,
+ -1, 3, -1, 269, -1, 262, -1, 274, -1, 266,
+ 265, -1, 101, 126, 266, 265, -1, 266, -1, 101,
+ 126, 266, -1, 105, -1, 101, 126, 105, -1, 126,
+ 266, 265, -1, 126, 266, -1, 126, 105, -1, 103,
+ 266, -1, 3, 261, -1, 3, 268, -1, 101, 126,
+ 3, 268, -1, 3, -1, 101, 126, 3, -1, 105,
+ -1, 101, 126, 105, -1, 126, 3, 268, -1, 126,
+ 3, -1, 126, 105, -1, 103, 3, -1, 269, 6,
+ -1, 6, -1, 269, -1, 43, -1, 4, -1, 37,
+ 272, 38, -1, 274, -1, 262, 51, 273, -1, 262,
+ 51, 273, 39, 272, -1, 262, -1, 262, 39, 272,
+ -1, 262, 51, 139, -1, 262, 51, 139, 39, 272,
+ -1, 269, -1, 245, -1, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 1593, 1593, 1606, 1610, 1613, 1616, 1619, 1622, 1627,
+ 1632, 1637, 1638, 1639, 1640, 1641, 1647, 1663, 1673, 1674,
+ 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684,
+ 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1700,
+ 1700, 1772, 1782, 1793, 1814, 1836, 1847, 1856, 1875, 1881,
+ 1887, 1892, 1899, 1906, 1910, 1923, 1932, 1947, 1960, 1960,
+ 2015, 2016, 2023, 2043, 2074, 2078, 2088, 2093, 2111, 2151,
+ 2157, 2170, 2176, 2202, 2208, 2215, 2216, 2219, 2220, 2228,
+ 2274, 2320, 2331, 2334, 2361, 2367, 2373, 2379, 2387, 2393,
+ 2399, 2405, 2413, 2414, 2415, 2418, 2423, 2433, 2469, 2470,
+ 2500, 2517, 2525, 2538, 2563, 2569, 2573, 2576, 2587, 2592,
+ 2605, 2617, 2890, 2900, 2907, 2908, 2912, 2912, 2943, 3004,
+ 3008, 3030, 3036, 3042, 3048, 3054, 3067, 3082, 3092, 3170,
+ 3221, 3222, 3223, 3224, 3225, 3226, 3232, 3232, 3464, 3464,
+ 3586, 3587, 3599, 3619, 3619, 3854, 3860, 3863, 3866, 3869,
+ 3872, 3875, 3880, 3910, 3914, 3917, 3920, 3925, 3929, 3934,
+ 3944, 3975, 3975, 4004, 4004, 4026, 4053, 4068, 4068, 4078,
+ 4079, 4080, 4080, 4096, 4097, 4114, 4115, 4116, 4117, 4118,
+ 4119, 4120, 4121, 4122, 4123, 4124, 4125, 4126, 4127, 4128,
+ 4129, 4138, 4163, 4187, 4228, 4243, 4261, 4280, 4287, 4294,
+ 4302, 4325, 4325, 4360, 4360, 4391, 4391, 4409, 4410, 4416,
+ 4419, 4423, 4426, 4427, 4428, 4429, 4430, 4431, 4432, 4433,
+ 4436, 4441, 4448, 4456, 4464, 4475, 4481, 4482, 4490, 4491,
+ 4492, 4493, 4494, 4495, 4502, 4513, 4517, 4520, 4524, 4528,
+ 4538, 4546, 4554, 4567, 4571, 4574, 4578, 4582, 4610, 4618,
+ 4629, 4643, 4652, 4660, 4670, 4674, 4678, 4685, 4702, 4719,
+ 4727, 4735, 4744, 4748, 4757, 4768, 4780, 4790, 4803, 4810,
+ 4818, 4834, 4842, 4853, 4864, 4875, 4894, 4902, 4919, 4927,
+ 4934, 4945, 4956, 4967, 4986, 4992, 4998, 5005, 5014, 5017,
+ 5026, 5033, 5040, 5050, 5061, 5072, 5083, 5090, 5097, 5100,
+ 5117, 5127, 5134, 5140, 5145, 5151, 5155, 5161, 5162, 5163,
+ 5169, 5175, 5179, 5180, 5184, 5191, 5194, 5195, 5196, 5197,
+ 5198, 5200, 5203, 5208, 5233, 5236, 5290, 5294, 5298, 5302,
+ 5306, 5310, 5314, 5318, 5322, 5326, 5330, 5334, 5338, 5342,
+ 5348, 5348, 5374, 5375, 5378, 5391, 5399, 5407, 5424, 5427,
+ 5442, 5443, 5462, 5463, 5467, 5472, 5473, 5487, 5494, 5511,
+ 5518, 5525, 5533, 5537, 5543, 5544, 5545, 5546, 5547, 5548,
+ 5549, 5552, 5556, 5560, 5564, 5568, 5572, 5576, 5580, 5584,
+ 5588, 5592, 5596, 5600, 5604, 5618, 5625, 5629, 5635, 5639,
+ 5643, 5647, 5651, 5667, 5672, 5672, 5673, 5676, 5693, 5702,
+ 5715, 5728, 5729, 5730, 5734, 5738, 5744, 5747, 5751, 5757,
+ 5758, 5761, 5766, 5771, 5776, 5783, 5790, 5797, 5805, 5813,
+ 5821, 5822, 5825, 5826, 5829, 5835, 5841, 5844, 5845, 5848,
+ 5849, 5852, 5857, 5861, 5864, 5867, 5870, 5875, 5879, 5882,
+ 5889, 5895, 5904, 5909, 5913, 5916, 5919, 5922, 5927, 5931,
+ 5934, 5937, 5943, 5948, 5951, 5954, 5958, 5963, 5976, 5980,
+ 5985, 5991, 5995, 6000, 6004, 6011, 6014, 6019
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "ID", "HBLOCK", "POUND", "STRING",
+ "INCLUDE", "IMPORT", "INSERT", "CHARCONST", "NUM_INT", "NUM_FLOAT",
+ "NUM_UNSIGNED", "NUM_LONG", "NUM_ULONG", "NUM_LONGLONG", "NUM_ULONGLONG",
+ "TYPEDEF", "TYPE_INT", "TYPE_UNSIGNED", "TYPE_SHORT", "TYPE_LONG",
+ "TYPE_FLOAT", "TYPE_DOUBLE", "TYPE_CHAR", "TYPE_WCHAR", "TYPE_VOID",
+ "TYPE_SIGNED", "TYPE_BOOL", "TYPE_COMPLEX", "TYPE_TYPEDEF", "TYPE_RAW",
+ "TYPE_NON_ISO_INT8", "TYPE_NON_ISO_INT16", "TYPE_NON_ISO_INT32",
+ "TYPE_NON_ISO_INT64", "LPAREN", "RPAREN", "COMMA", "SEMI", "EXTERN",
+ "INIT", "LBRACE", "RBRACE", "PERIOD", "CONST_QUAL", "VOLATILE",
+ "REGISTER", "STRUCT", "UNION", "EQUAL", "SIZEOF", "MODULE", "LBRACKET",
+ "RBRACKET", "ILLEGAL", "CONSTANT", "NAME", "RENAME", "NAMEWARN",
+ "EXTEND", "PRAGMA", "FEATURE", "VARARGS", "ENUM", "CLASS", "TYPENAME",
+ "PRIVATE", "PUBLIC", "PROTECTED", "COLON", "STATIC", "VIRTUAL", "FRIEND",
+ "THROW", "CATCH", "EXPLICIT", "USING", "NAMESPACE", "NATIVE", "INLINE",
+ "TYPEMAP", "EXCEPT", "ECHO", "APPLY", "CLEAR", "SWIGTEMPLATE",
+ "FRAGMENT", "WARN", "LESSTHAN", "GREATERTHAN", "MODULO", "DELETE_KW",
+ "LESSTHANOREQUALTO", "GREATERTHANOREQUALTO", "EQUALTO", "NOTEQUALTO",
+ "QUESTIONMARK", "TYPES", "PARMS", "NONID", "DSTAR", "DCNOT", "TEMPLATE",
+ "OPERATOR", "COPERATOR", "PARSETYPE", "PARSEPARM", "PARSEPARMS", "CAST",
+ "LOR", "LAND", "OR", "XOR", "AND", "RSHIFT", "LSHIFT", "MINUS", "PLUS",
+ "MODULUS", "SLASH", "STAR", "LNOT", "NOT", "UMINUS", "DCOLON", "$accept",
+ "program", "interface", "declaration", "swig_directive",
+ "extend_directive", "@1", "apply_directive", "clear_directive",
+ "constant_directive", "echo_directive", "except_directive", "stringtype",
+ "fname", "fragment_directive", "include_directive", "@2", "includetype",
+ "inline_directive", "insert_directive", "module_directive",
+ "name_directive", "native_directive", "pragma_directive", "pragma_arg",
+ "pragma_lang", "rename_directive", "rename_namewarn",
+ "feature_directive", "stringbracesemi", "featattr", "varargs_directive",
+ "varargs_parms", "typemap_directive", "typemap_type", "tm_list",
+ "tm_tail", "typemap_parm", "types_directive", "template_directive",
+ "warn_directive", "c_declaration", "@3", "c_decl", "c_decl_tail",
+ "initializer", "c_enum_forward_decl", "c_enum_decl",
+ "c_constructor_decl", "cpp_declaration", "cpp_class_decl", "@4", "@5",
+ "cpp_opt_declarators", "cpp_forward_class_decl", "cpp_template_decl",
+ "@6", "cpp_temp_possible", "template_parms", "templateparameters",
+ "templateparameter", "templateparameterstail", "cpp_using_decl",
+ "cpp_namespace_decl", "@7", "@8", "cpp_members", "@9", "@10",
+ "cpp_member", "cpp_constructor_decl", "cpp_destructor_decl",
+ "cpp_conversion_operator", "cpp_catch_decl", "cpp_protection_decl",
+ "cpp_nested", "@11", "@12", "@13", "nested_decl", "cpp_swig_directive",
+ "cpp_end", "cpp_vend", "anonymous_bitfield", "storage_class", "parms",
+ "rawparms", "ptail", "parm", "valparms", "rawvalparms", "valptail",
+ "valparm", "def_args", "parameter_declarator",
+ "typemap_parameter_declarator", "declarator", "notso_direct_declarator",
+ "direct_declarator", "abstract_declarator", "direct_abstract_declarator",
+ "pointer", "type_qualifier", "type_qualifier_raw", "type", "rawtype",
+ "type_right", "primitive_type", "primitive_type_list", "type_specifier",
+ "definetype", "@14", "ename", "enumlist", "edecl", "etype", "expr",
+ "valexpr", "exprnum", "exprcompound", "inherit", "raw_inherit", "@15",
+ "base_list", "base_specifier", "access_specifier", "templcpptype",
+ "cpptype", "opt_virtual", "cpp_const", "ctor_end", "ctor_initializer",
+ "mem_initializer_list", "mem_initializer", "template_decl", "idstring",
+ "idstringopt", "idcolon", "idcolontail", "idtemplate", "idcolonnt",
+ "idcolontailnt", "string", "stringbrace", "options", "kwargs",
+ "stringnum", "empty", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
+ 375, 376, 377, 378, 379, 380, 381
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint16 yyr1[] =
+{
+ 0, 127, 128, 128, 128, 128, 128, 128, 128, 129,
+ 129, 130, 130, 130, 130, 130, 130, 130, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
+ 131, 131, 131, 131, 131, 131, 131, 131, 131, 133,
+ 132, 134, 135, 136, 136, 136, 137, 137, 138, 138,
+ 138, 138, 139, 140, 140, 141, 141, 141, 143, 142,
+ 144, 144, 145, 145, 146, 146, 146, 146, 147, 148,
+ 148, 149, 149, 150, 150, 151, 151, 152, 152, 153,
+ 153, 153, 154, 154, 155, 155, 155, 155, 155, 155,
+ 155, 155, 156, 156, 156, 157, 157, 158, 159, 159,
+ 160, 160, 160, 161, 162, 163, 163, 164, 164, 164,
+ 165, 166, 167, 168, 168, 168, 169, 168, 170, 171,
+ 171, 171, 172, 172, 172, 172, 173, 174, 174, 175,
+ 176, 176, 176, 176, 176, 176, 178, 177, 179, 177,
+ 180, 180, 181, 183, 182, 182, 184, 184, 184, 184,
+ 184, 184, 185, 186, 186, 187, 187, 188, 188, 189,
+ 189, 191, 190, 192, 190, 190, 193, 194, 193, 193,
+ 193, 195, 193, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 197, 198, 198, 199, 199, 199, 200, 201, 201,
+ 201, 203, 202, 204, 202, 205, 202, 206, 206, 207,
+ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207,
+ 208, 208, 209, 209, 209, 210, 211, 211, 211, 211,
+ 211, 211, 211, 211, 212, 213, 213, 214, 214, 215,
+ 215, 215, 216, 217, 217, 218, 218, 219, 219, 220,
+ 220, 220, 220, 220, 221, 221, 221, 222, 222, 222,
+ 223, 223, 223, 223, 223, 223, 223, 223, 224, 224,
+ 224, 224, 224, 224, 224, 224, 225, 225, 225, 225,
+ 225, 225, 225, 225, 226, 226, 226, 226, 226, 226,
+ 226, 226, 226, 226, 227, 227, 227, 227, 227, 227,
+ 227, 228, 228, 228, 228, 229, 229, 230, 230, 230,
+ 231, 232, 232, 232, 232, 233, 233, 233, 233, 233,
+ 233, 233, 233, 234, 235, 235, 236, 236, 236, 236,
+ 236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
+ 238, 237, 239, 239, 240, 240, 241, 241, 241, 242,
+ 243, 243, 244, 244, 244, 244, 244, 244, 244, 244,
+ 244, 244, 244, 244, 245, 245, 245, 245, 245, 245,
+ 245, 246, 246, 246, 246, 246, 246, 246, 246, 246,
+ 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
+ 246, 246, 246, 247, 249, 248, 248, 250, 250, 251,
+ 251, 252, 252, 252, 253, 253, 254, 254, 254, 255,
+ 255, 256, 256, 256, 256, 257, 257, 257, 257, 257,
+ 258, 258, 259, 259, 260, 261, 261, 262, 262, 263,
+ 263, 264, 264, 264, 264, 264, 264, 265, 265, 265,
+ 265, 266, 267, 267, 267, 267, 267, 267, 268, 268,
+ 268, 268, 269, 269, 270, 270, 270, 271, 271, 272,
+ 272, 272, 272, 272, 272, 273, 273, 274
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 3, 2, 3, 2, 5, 3, 2,
+ 1, 1, 1, 1, 1, 1, 1, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 7, 5, 3, 5, 5, 3, 2, 2, 5, 2,
+ 5, 2, 4, 1, 1, 7, 7, 5, 0, 7,
+ 1, 1, 2, 2, 1, 5, 5, 5, 3, 4,
+ 3, 7, 8, 5, 3, 1, 1, 3, 1, 4,
+ 7, 6, 1, 1, 7, 9, 8, 10, 5, 7,
+ 6, 8, 1, 1, 5, 4, 5, 7, 1, 3,
+ 6, 6, 8, 1, 2, 3, 1, 2, 3, 6,
+ 5, 9, 2, 1, 1, 1, 0, 6, 5, 1,
+ 4, 1, 1, 2, 5, 6, 4, 7, 8, 6,
+ 1, 1, 1, 1, 1, 1, 0, 9, 0, 8,
+ 1, 2, 4, 0, 6, 3, 1, 1, 1, 1,
+ 1, 1, 1, 2, 1, 1, 1, 3, 1, 3,
+ 4, 0, 6, 0, 5, 5, 2, 0, 6, 1,
+ 1, 0, 3, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 6, 6, 7, 8, 8, 7, 5, 2, 2,
+ 2, 0, 7, 0, 6, 0, 8, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 4, 2, 5, 1, 2, 1, 1,
+ 1, 1, 1, 1, 1, 2, 1, 3, 1, 2,
+ 7, 3, 1, 2, 1, 3, 1, 1, 1, 2,
+ 5, 2, 2, 1, 2, 2, 1, 1, 1, 1,
+ 2, 3, 1, 2, 3, 4, 5, 4, 1, 2,
+ 3, 4, 5, 3, 4, 4, 1, 2, 4, 4,
+ 5, 3, 4, 4, 1, 2, 2, 3, 1, 2,
+ 1, 2, 3, 4, 3, 4, 2, 3, 3, 4,
+ 3, 3, 2, 2, 1, 1, 2, 1, 1, 1,
+ 1, 2, 1, 2, 3, 1, 1, 1, 2, 2,
+ 1, 1, 2, 1, 1, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 2, 1, 1, 3, 1, 1, 3, 1, 1,
+ 1, 1, 1, 1, 5, 1, 1, 3, 4, 5,
+ 5, 6, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 5, 2, 2,
+ 2, 2, 2, 1, 0, 3, 1, 1, 3, 2,
+ 4, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 4, 5, 1, 3, 3, 4, 4, 3,
+ 2, 1, 1, 3, 2, 3, 1, 1, 1, 1,
+ 1, 2, 4, 1, 3, 1, 3, 3, 2, 2,
+ 2, 2, 2, 4, 1, 3, 1, 3, 3, 2,
+ 2, 2, 2, 1, 1, 1, 1, 3, 1, 3,
+ 5, 1, 3, 3, 5, 1, 1, 0
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint16 yydefact[] =
+{
+ 467, 0, 0, 0, 0, 0, 10, 4, 467, 326,
+ 334, 327, 328, 331, 332, 329, 330, 317, 333, 316,
+ 335, 467, 320, 336, 337, 338, 339, 0, 307, 308,
+ 309, 407, 408, 0, 404, 405, 0, 0, 435, 0,
+ 0, 305, 467, 312, 315, 323, 324, 406, 0, 321,
+ 433, 6, 0, 0, 467, 1, 15, 64, 60, 61,
+ 0, 229, 14, 226, 467, 0, 0, 82, 83, 467,
+ 467, 0, 0, 228, 230, 231, 0, 232, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 9, 11, 18, 19, 20, 21, 22, 23,
+ 24, 25, 467, 26, 27, 28, 29, 30, 31, 32,
+ 0, 33, 34, 35, 36, 37, 38, 12, 113, 115,
+ 114, 16, 13, 130, 131, 132, 133, 134, 135, 0,
+ 233, 467, 441, 426, 318, 0, 319, 0, 0, 3,
+ 311, 306, 467, 340, 0, 0, 290, 304, 0, 256,
+ 239, 467, 262, 467, 288, 284, 276, 253, 313, 325,
+ 322, 0, 0, 431, 5, 8, 0, 234, 467, 236,
+ 17, 0, 453, 227, 0, 0, 458, 0, 467, 0,
+ 310, 0, 0, 0, 0, 78, 0, 467, 467, 0,
+ 0, 467, 163, 0, 0, 62, 63, 0, 0, 51,
+ 49, 46, 47, 467, 0, 467, 0, 467, 467, 0,
+ 112, 467, 467, 0, 0, 0, 0, 0, 0, 276,
+ 467, 0, 0, 356, 364, 365, 366, 367, 368, 369,
+ 370, 0, 0, 0, 0, 0, 0, 0, 0, 247,
+ 0, 242, 467, 351, 310, 0, 350, 352, 355, 353,
+ 244, 241, 436, 434, 0, 314, 467, 290, 0, 0,
+ 284, 321, 251, 249, 0, 296, 0, 350, 252, 467,
+ 0, 263, 289, 268, 302, 303, 277, 254, 467, 0,
+ 255, 467, 0, 286, 260, 285, 268, 291, 440, 439,
+ 438, 0, 0, 235, 238, 427, 0, 428, 452, 116,
+ 461, 0, 68, 45, 340, 0, 467, 70, 0, 0,
+ 0, 74, 0, 0, 0, 98, 0, 0, 159, 0,
+ 467, 161, 0, 0, 103, 0, 0, 0, 107, 257,
+ 258, 259, 42, 0, 104, 106, 429, 0, 430, 54,
+ 0, 53, 0, 0, 152, 467, 156, 406, 154, 145,
+ 0, 427, 0, 0, 0, 0, 0, 0, 0, 268,
+ 0, 467, 0, 343, 467, 467, 138, 322, 0, 0,
+ 362, 388, 389, 363, 391, 390, 425, 0, 243, 246,
+ 392, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 432, 0,
+ 290, 284, 321, 0, 276, 300, 298, 286, 0, 276,
+ 291, 0, 341, 297, 284, 321, 269, 467, 0, 301,
+ 0, 281, 0, 0, 294, 0, 261, 287, 292, 0,
+ 264, 437, 7, 467, 0, 467, 0, 0, 457, 0,
+ 0, 69, 39, 77, 0, 0, 0, 0, 0, 0,
+ 0, 160, 0, 0, 467, 467, 0, 0, 108, 0,
+ 467, 0, 0, 0, 0, 0, 143, 0, 153, 158,
+ 58, 0, 0, 0, 0, 79, 0, 126, 467, 0,
+ 321, 0, 0, 122, 467, 0, 142, 394, 0, 393,
+ 396, 357, 0, 304, 0, 467, 467, 386, 385, 383,
+ 384, 0, 382, 381, 377, 378, 376, 380, 379, 372,
+ 371, 375, 374, 373, 0, 0, 291, 279, 278, 292,
+ 0, 0, 0, 268, 270, 291, 0, 273, 0, 283,
+ 282, 299, 295, 0, 265, 293, 267, 237, 66, 67,
+ 65, 0, 462, 463, 466, 465, 459, 43, 44, 0,
+ 76, 73, 75, 456, 93, 455, 0, 88, 467, 454,
+ 92, 0, 465, 0, 0, 99, 467, 197, 165, 164,
+ 0, 226, 0, 0, 50, 48, 467, 41, 105, 444,
+ 0, 446, 0, 57, 0, 0, 110, 467, 467, 467,
+ 467, 0, 0, 346, 0, 345, 348, 467, 467, 0,
+ 119, 121, 118, 0, 123, 171, 190, 0, 0, 0,
+ 0, 230, 0, 217, 218, 210, 219, 188, 169, 215,
+ 211, 209, 212, 213, 214, 216, 189, 185, 186, 173,
+ 179, 183, 182, 0, 0, 174, 175, 178, 184, 176,
+ 180, 177, 187, 0, 233, 467, 136, 358, 0, 304,
+ 303, 0, 0, 0, 245, 0, 467, 280, 250, 271,
+ 0, 275, 274, 266, 117, 0, 0, 0, 467, 0,
+ 411, 0, 414, 0, 0, 0, 0, 90, 467, 0,
+ 162, 227, 467, 0, 101, 0, 100, 0, 0, 0,
+ 442, 0, 467, 0, 52, 146, 147, 150, 149, 144,
+ 148, 151, 0, 157, 0, 0, 81, 0, 467, 0,
+ 467, 340, 467, 129, 0, 467, 467, 0, 167, 199,
+ 198, 200, 0, 0, 0, 166, 0, 0, 0, 321,
+ 409, 395, 397, 0, 410, 0, 360, 359, 0, 354,
+ 387, 240, 272, 464, 460, 40, 0, 467, 0, 84,
+ 465, 95, 89, 467, 0, 0, 97, 71, 0, 0,
+ 109, 451, 449, 450, 445, 447, 0, 55, 56, 0,
+ 59, 80, 347, 349, 344, 127, 0, 0, 0, 0,
+ 0, 421, 467, 0, 0, 172, 0, 0, 467, 0,
+ 0, 467, 0, 467, 203, 322, 181, 467, 402, 401,
+ 403, 467, 399, 0, 361, 0, 0, 467, 96, 0,
+ 91, 467, 86, 72, 102, 448, 443, 0, 128, 0,
+ 419, 420, 422, 0, 415, 416, 124, 120, 467, 0,
+ 467, 0, 139, 467, 0, 0, 0, 0, 201, 467,
+ 467, 398, 0, 0, 94, 412, 0, 85, 0, 111,
+ 417, 418, 0, 424, 125, 0, 0, 467, 0, 467,
+ 467, 467, 225, 467, 0, 207, 208, 0, 400, 140,
+ 137, 0, 413, 87, 423, 168, 467, 192, 0, 467,
+ 0, 0, 191, 0, 204, 205, 141, 193, 0, 220,
+ 221, 196, 467, 467, 202, 0, 222, 224, 340, 195,
+ 194, 206, 0, 223
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 4, 5, 92, 93, 94, 549, 613, 614, 615,
+ 616, 99, 339, 340, 617, 618, 589, 102, 103, 619,
+ 105, 620, 107, 621, 551, 184, 622, 110, 623, 557,
+ 447, 624, 314, 625, 323, 206, 334, 207, 626, 627,
+ 628, 629, 435, 118, 602, 482, 119, 120, 121, 122,
+ 123, 735, 485, 870, 630, 631, 587, 699, 343, 344,
+ 345, 468, 632, 127, 454, 320, 633, 786, 717, 634,
+ 635, 636, 637, 638, 639, 640, 863, 839, 895, 864,
+ 641, 877, 887, 642, 643, 258, 167, 293, 168, 240,
+ 241, 378, 242, 149, 150, 328, 151, 271, 152, 153,
+ 154, 218, 40, 41, 243, 180, 43, 44, 45, 46,
+ 263, 264, 362, 594, 595, 772, 245, 267, 247, 248,
+ 488, 489, 645, 731, 732, 801, 47, 48, 733, 888,
+ 713, 780, 821, 822, 132, 300, 337, 49, 163, 50,
+ 582, 690, 249, 560, 175, 301, 546, 169
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -550
+static const yytype_int16 yypact[] =
+{
+ 590, 3291, 3341, 121, 117, 2846, -550, -550, -67, -550,
+ -550, -550, -550, -550, -550, -550, -550, -550, -550, -550,
+ -550, -67, -550, -550, -550, -550, -550, 115, -550, -550,
+ -550, -550, -550, 191, -550, -550, 75, 161, -550, 156,
+ 3797, 717, 325, 717, -550, -550, 1803, -550, 191, -550,
+ 100, -550, 221, 227, 3549, -550, 166, -550, -550, -550,
+ 288, -550, -550, 318, 298, 3401, 303, -550, -550, 298,
+ 311, 333, 366, -550, -550, -550, 392, -550, 116, 42,
+ 420, 106, 431, 429, 384, 3599, 3599, 442, 455, 318,
+ 465, 600, -550, -550, -550, -550, -550, -550, -550, -550,
+ -550, -550, 298, -550, -550, -550, -550, -550, -550, -550,
+ 983, -550, -550, -550, -550, -550, -550, -550, -550, -550,
+ -550, -550, -550, -550, -550, -550, -550, -550, -550, 3648,
+ -550, 1740, -550, -550, -550, 296, -550, 49, 461, -550,
+ 717, -550, 2522, 463, 1862, 2350, 87, 241, 191, -550,
+ -550, 104, 323, 104, 356, 176, 252, -550, -550, -550,
+ -550, 518, 77, -550, -550, -550, 484, -550, 487, -550,
+ -550, 377, -550, 126, 377, 377, -550, 532, 108, 1003,
+ -550, 256, 191, 530, 571, -550, 377, 1522, 3549, 191,
+ 562, 129, -550, 573, 616, -550, -550, 377, 620, -550,
+ -550, -550, 623, 3549, 583, 228, 592, 596, 377, 318,
+ 623, 3549, 3549, 191, 318, 270, 381, 377, 312, 535,
+ 194, 1014, 85, -550, -550, -550, -550, -550, -550, -550,
+ -550, 2350, 610, 2350, 2350, 2350, 2350, 2350, 2350, -550,
+ 557, -550, 613, 621, 113, 1699, -8, -550, -550, 623,
+ -550, -550, -550, 100, 568, -550, 2626, 742, 615, 626,
+ 928, 561, -550, 614, 2350, -550, 1825, -550, 1699, 2626,
+ 191, 387, 356, -550, -550, 552, -550, -550, 3549, 1984,
+ -550, 3549, 2106, 87, 387, 356, 575, 720, -550, -550,
+ 100, 635, 3549, -550, -550, -550, 641, 623, -550, -550,
+ 330, 646, -550, -550, -550, 715, 104, -550, 649, 650,
+ 657, 652, 53, 667, 669, -550, 673, 684, -550, 191,
+ -550, -550, 688, 698, -550, 700, 703, 3599, -550, -550,
+ -550, -550, -550, 3599, -550, -550, -550, 705, -550, -550,
+ 207, 131, 706, 655, -550, 708, -550, 43, -550, -550,
+ 20, 317, 933, 933, 648, 722, 105, 738, 381, 681,
+ 720, 83, 745, -550, 2687, 625, -550, 287, 1197, 3698,
+ 1163, -550, -550, -550, -550, -550, -550, 1740, -550, -550,
+ -550, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350,
+ 2350, 2350, 2350, 2350, 2350, 2350, 2350, 2350, -550, 461,
+ 443, 341, 689, 284, -550, -550, -550, 443, 394, 696,
+ 933, 2350, 1699, -550, 970, 13, -550, 3549, 2228, -550,
+ 752, -550, 1947, 762, -550, 2069, 387, 356, 1027, 381,
+ 387, -550, -550, 487, 304, -550, 377, 1212, -550, 765,
+ 766, -550, -550, -550, 509, 651, 1958, 770, 3549, 1003,
+ 779, -550, 769, 2935, -550, 865, 3599, 497, 787, 782,
+ 596, 281, 789, 377, 3549, 538, -550, 3549, -550, -550,
+ -550, 933, 299, 381, 25, -550, 874, -550, 829, 793,
+ 648, 801, 690, -550, 203, 1621, -550, -550, 798, -550,
+ -550, 2350, 1404, 2472, 15, 325, 613, 1057, 1057, 1122,
+ 1122, 2716, 1382, 1479, 1489, 1249, 1163, 828, 828, 692,
+ 692, -550, -550, -550, 191, 696, -550, -550, -550, 443,
+ 407, 2191, 493, 696, -550, 381, 808, -550, 2313, -550,
+ -550, -550, -550, 381, 387, 356, 387, -550, -550, -550,
+ 623, 3024, -550, 809, -550, 131, 811, -550, -550, 1621,
+ -550, -550, 623, -550, -550, -550, 814, -550, 674, 623,
+ -550, 802, 78, 265, 651, -550, 674, -550, -550, -550,
+ 3113, 318, 3747, 351, -550, -550, 3549, -550, -550, 213,
+ 736, -550, 774, -550, 818, 821, -550, 730, 708, -550,
+ 674, 230, 381, 816, 94, -550, -550, 823, 3549, 1003,
+ -550, -550, -550, 831, -550, -550, -550, 830, 813, 815,
+ 817, 748, 518, -550, -550, -550, -550, -550, -550, -550,
+ -550, -550, -550, -550, -550, -550, -550, -550, -550, -550,
+ -550, -550, -550, 836, 1621, -550, -550, -550, -550, -550,
+ -550, -550, -550, 3450, 845, 822, -550, 1699, 2350, 2472,
+ 2740, 2350, 852, 853, -550, 2350, 104, -550, -550, -550,
+ 498, -550, -550, 387, -550, 377, 377, 855, 3549, 871,
+ 835, 538, -550, 1212, 879, 377, 875, -550, 674, 877,
+ -550, 623, -1, 1003, -550, 3599, -550, 882, 912, 84,
+ -550, 111, 1740, 196, -550, -550, -550, -550, -550, -550,
+ -550, -550, 3500, -550, 3202, 884, -550, 2350, 829, 926,
+ 3549, -550, 851, -550, 887, 625, 3549, 1621, -550, -550,
+ -550, -550, 518, 889, 1003, -550, 3698, 41, 212, 890,
+ -550, 888, -550, 369, -550, 1621, 1699, 1699, 2350, -550,
+ 1837, -550, -550, -550, -550, -550, 894, 3549, 916, -550,
+ 623, 917, -550, 674, 948, 538, -550, -550, 918, 922,
+ -550, -550, 213, -550, 213, -550, 873, -550, -550, 1032,
+ -550, -550, -550, 1699, -550, -550, 690, 929, 931, 191,
+ 505, -550, 104, 690, 930, -550, 1621, 932, 3549, 690,
+ -15, 2687, 2350, 19, -550, 198, -550, 822, -550, -550,
+ -550, 822, -550, 934, 1699, 936, 949, 3549, -550, 950,
+ -550, 674, -550, -550, -550, -550, -550, 951, -550, 514,
+ -550, 953, -550, 935, -550, -550, -550, -550, 104, 956,
+ 3549, 959, -550, 3549, 965, 967, 972, 1618, -550, 1003,
+ 822, -550, 191, 978, -550, -550, 973, -550, 974, -550,
+ -550, -550, 191, -550, -550, 1621, 975, 674, 985, 3549,
+ 3549, 823, -550, 1003, 981, -550, -550, 372, -550, -550,
+ -550, 690, -550, -550, -550, -550, 674, -550, 543, 674,
+ 987, 990, -550, 996, -550, -550, -550, -550, 447, -550,
+ -550, -550, 674, 674, -550, 997, -550, -550, -550, -550,
+ -550, -550, 999, -550
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -550, -550, -314, -550, -550, -550, -550, 10, 12, 23,
+ 24, -550, 605, -550, 28, 30, -550, -550, -550, 35,
+ -550, 36, -550, 38, -550, -550, 50, -550, 54, -446,
+ -549, 55, -550, 63, -550, -311, 545, -84, 66, 70,
+ 72, 76, -550, 425, -377, 332, -550, -550, -550, -550,
+ 467, -550, -550, -550, -2, 5, -550, -550, -550, -550,
+ 588, 468, 81, -550, -550, -550, -536, -550, -550, -550,
+ 472, -550, 473, 90, -550, -550, -550, -550, -550, 199,
+ -550, -550, -375, -550, -3, 186, -550, 628, 222, 373,
+ -550, 570, 691, -97, 572, -550, -44, -117, -181, -112,
+ -121, -22, -34, -550, 576, 45, -36, -550, 1028, -550,
+ -286, -550, -550, -550, 365, -550, 966, -119, -410, -550,
+ -550, -550, -550, 236, 280, -550, -201, -33, 277, -493,
+ 219, -550, -550, 234, 1061, -114, -550, 739, -142, -113,
+ -550, -202, 726, 516, 183, -165, -409, 0
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -468
+static const yytype_int16 yytable[] =
+{
+ 6, 204, 129, 124, 140, 130, 453, 141, 133, 158,
+ 125, 347, 246, 667, 676, 95, 459, 96, 439, 586,
+ 155, 133, 833, 131, 253, 272, 298, 544, 97, 98,
+ 259, -248, 324, 100, 285, 101, 544, 563, 284, 757,
+ 104, 106, 157, 108, 8, 191, 42, 42, 288, 290,
+ 355, 524, 8, 651, 277, 109, 280, 296, 213, 111,
+ 112, 302, 838, 524, 176, 671, 217, 308, 113, 176,
+ 185, 114, 312, 679, 470, 115, 403, 116, 791, 408,
+ 8, 117, -155, -248, 298, 192, 126, 762, 8, 131,
+ 8, 445, 446, 330, 336, 128, 222, 705, 725, 42,
+ 834, 284, 176, 357, 712, 254, 255, 147, 8, 131,
+ 195, 398, 792, 275, 764, 525, 8, 55, 677, 8,
+ 260, 541, 53, 477, 269, 274, -342, 592, 366, -428,
+ 652, 250, 298, 708, -155, 306, 272, 298, 709, 285,
+ 570, 144, 36, 36, 259, 573, 38, 38, 431, 196,
+ 142, 157, -467, 157, 252, 143, 216, 259, 54, 304,
+ 135, 329, 427, 147, 143, 148, 426, 144, 294, 299,
+ 430, 403, 408, 131, 464, 145, 244, 365, 133, 8,
+ 319, 785, 289, 155, 145, 755, 36, 42, 36, 763,
+ 38, 133, 38, 353, 8, 189, 139, 361, 131, 803,
+ 767, 137, 808, 161, -467, 331, 36, 335, 338, 440,
+ 38, 270, 348, 269, 36, 793, 765, 36, 38, 131,
+ 363, 38, 155, 39, 52, 749, 162, 147, 146, 520,
+ 144, 8, 42, 42, 401, 147, 298, 148, 486, 768,
+ 166, 426, 379, 430, 157, 462, 463, 414, 42, 460,
+ 829, 138, 182, 419, 143, 794, 42, 42, 246, 295,
+ 809, 164, 172, 544, 751, 142, 347, 165, 483, 840,
+ 706, 542, 170, 351, 145, 704, 172, 36, 603, 272,
+ 285, 38, 144, 353, 579, 214, 427, 28, 29, 30,
+ 520, 283, 36, 285, 307, 36, 38, 522, 584, 38,
+ 270, 42, 8, 674, 675, 172, 157, 535, 538, 812,
+ 172, 534, 536, 36, 42, 8, 688, 38, 848, 875,
+ 6, 278, 517, 42, 172, 171, 42, 486, 8, 36,
+ -467, 484, 561, 38, 473, 174, 305, 42, 279, 689,
+ 181, 251, 353, 146, 8, 469, 494, 539, 183, 356,
+ 147, 133, 148, 239, 287, 553, 522, 172, 487, 534,
+ 278, 133, 142, 147, 878, 157, 514, 490, 712, 436,
+ 186, 36, 8, 315, 316, 38, 143, 279, 256, 144,
+ 295, 437, 580, 172, 8, 352, 581, 604, 201, 326,
+ 172, 684, 147, 281, 555, 144, 145, 342, 535, 818,
+ 36, 558, 685, 187, 38, 566, 827, 131, 660, 42,
+ 282, 797, 832, 36, 216, 885, 663, 38, 356, -467,
+ -467, 147, 244, 148, 417, 778, 36, 358, 590, 188,
+ 38, 278, 518, 294, 346, 6, 270, 798, 799, 800,
+ 146, 418, 36, -467, 278, 657, 38, 147, 279, 148,
+ 129, 124, 572, 130, 6, 130, 407, 194, 125, 650,
+ 335, 279, 42, 95, 420, 96, 198, 423, 197, 199,
+ 36, 274, 200, 155, 38, 660, 97, 98, 596, 208,
+ 256, 100, 36, 101, 157, 644, 38, 896, 104, 106,
+ 897, 108, 209, 42, 886, 157, 379, 144, 898, 723,
+ 743, 744, 211, 109, 891, 270, 262, 111, 112, 42,
+ 31, 32, 42, 550, 433, 172, 113, 899, 900, 114,
+ 678, 8, 291, 115, 670, 116, 292, 34, 35, 117,
+ 417, 659, 670, 310, 126, 417, 742, 574, 129, 124,
+ 575, 130, 553, 128, 172, 824, 125, 418, 825, 644,
+ 479, 95, 418, 96, 850, 715, 670, 851, 672, 741,
+ 815, 561, 816, 670, 97, 98, 672, 129, 124, 100,
+ 130, 101, 303, 246, 311, 125, 104, 106, 554, 108,
+ 95, 555, 96, 889, 702, 697, 890, 130, 469, 6,
+ 672, 109, 698, 97, 98, 111, 112, 672, 100, 239,
+ 101, 759, 318, 526, 113, 104, 106, 114, 108, 787,
+ 728, 115, 902, 116, 140, 650, 321, 117, 483, 322,
+ 109, 42, 126, 325, 111, 112, 327, 274, 419, 298,
+ 753, 128, 332, 113, 644, 333, 114, 360, 556, 758,
+ 115, 179, 116, 42, 670, 734, 117, 369, 376, 31,
+ 32, 126, 377, 405, 8, 553, 157, 172, 380, 399,
+ 128, 205, 205, 410, 406, 776, 34, 35, 411, 222,
+ 565, 28, 29, 30, 147, 432, 143, 428, 672, 434,
+ 789, 484, 133, 365, 438, 826, 585, 441, 305, 346,
+ 212, 554, 250, 442, 555, 443, 145, 1, 2, 3,
+ 481, 129, 124, 444, 130, 221, 448, 449, 596, 125,
+ 811, 450, 781, 42, 95, 157, 96, 644, 8, 670,
+ 28, 29, 30, 8, 451, 365, 455, 97, 98, 599,
+ 600, 854, 100, 601, 101, 644, 456, 244, 457, 104,
+ 106, 458, 108, 461, 465, 8, 466, 467, 61, 669,
+ 471, 556, 36, 672, 109, 42, 38, 356, 111, 112,
+ 472, 42, 687, 28, 29, 30, 216, 113, 835, 353,
+ 114, 571, 136, 147, 115, 148, 116, 670, 475, 142,
+ 117, 156, 157, 476, 714, 126, 644, 160, 478, 173,
+ 529, 516, 42, 133, 128, 865, 144, 734, 519, 871,
+ 531, 734, 73, 74, 75, 547, 548, 77, 564, 568,
+ 202, 672, 395, 396, 397, 210, 36, 190, 193, 865,
+ 38, 36, 567, 670, 576, 38, 577, 670, 157, 583,
+ 352, 597, 593, 42, 91, 429, 42, 147, 598, 866,
+ 734, 646, 670, 36, 270, 670, 661, 38, 665, 219,
+ 666, 668, 42, 673, 746, 644, 693, 672, 670, 670,
+ 710, 672, 691, 866, 692, 694, 148, 707, 716, 28,
+ 29, 30, 722, 718, 711, 42, 672, 8, 42, 672,
+ 724, 261, 8, 61, 719, 273, 720, 276, 721, -170,
+ 738, 739, 672, 672, 286, 730, 777, 297, 669, 745,
+ 297, 297, 784, 205, 42, 42, 571, 297, 747, 205,
+ 748, 356, 297, 754, 239, 761, 305, 756, 219, 752,
+ 760, 309, 779, 297, 771, 782, 788, 797, 317, 8,
+ 796, 8, 805, 806, 297, 341, 8, 73, 74, 75,
+ 350, 297, 77, 297, 156, 495, 393, 394, 395, 396,
+ 397, 8, 349, 807, 354, 273, 675, 359, 813, 136,
+ 219, 367, 814, 305, 817, 142, 775, 819, 828, 830,
+ 305, 820, 853, 8, 831, 36, 844, 836, 843, 38,
+ 36, 8, 144, 156, 38, 305, 8, 845, 810, 533,
+ 847, 849, 852, 846, 216, 402, 404, 857, 270, 409,
+ 855, 147, 859, 148, 860, 578, 8, 269, 415, 416,
+ 861, 872, 695, 876, 873, 305, 856, 8, 869, 858,
+ 215, 884, 273, 879, 144, 892, 273, 36, 893, 36,
+ 8, 38, 205, 38, 36, 8, 894, 901, 38, 903,
+ 305, 216, 543, 407, 354, 880, 881, 783, 147, 36,
+ 148, 364, 148, 38, 696, 588, 703, 148, 452, 700,
+ 701, 537, 883, 216, 269, 766, 654, 653, 496, 791,
+ 147, 36, 148, 774, 159, 38, 867, 841, 842, 36,
+ 882, 144, 134, 38, 36, 407, 874, 0, 38, 686,
+ 0, 404, 404, 216, 270, 474, 0, 273, 216, 273,
+ 147, 0, 148, 480, 36, 147, 0, 148, 38, 0,
+ 266, 268, 0, 0, 0, 36, 0, 0, 216, 38,
+ 0, 0, 0, 0, 0, 147, 0, 148, 36, 216,
+ 0, 0, 38, 36, 0, 0, 147, 38, 148, 0,
+ 515, 0, 533, 0, 0, 0, 0, 216, 683, 404,
+ 0, 270, 0, 523, 147, 0, 148, 0, 0, 0,
+ 540, 0, 297, 545, 0, 0, 0, 273, 273, 0,
+ 552, 559, 562, 391, 392, 393, 394, 395, 396, 397,
+ 0, 0, 0, 0, 219, 0, 0, 0, 219, 297,
+ 0, 559, 0, 0, 0, 0, 0, 368, 591, 370,
+ 371, 372, 373, 374, 375, 0, 0, 0, 0, 0,
+ 404, 219, 273, 0, 0, 273, 381, 382, 172, 727,
+ 0, 0, 0, 224, 225, 226, 227, 228, 229, 230,
+ 412, 0, 0, 0, 156, 491, 0, 0, 391, 392,
+ 393, 394, 395, 396, 397, 422, 0, 0, 425, 0,
+ 0, 0, 0, 656, 0, 0, 0, 381, 382, 383,
+ 384, 205, 0, 0, 273, 0, 0, 0, 0, 0,
+ 0, 0, 273, 0, 0, 0, 0, 0, 769, 391,
+ 392, 393, 394, 395, 396, 397, 0, 0, 0, 0,
+ 559, 381, 382, 383, 384, 385, 0, 681, 0, 559,
+ 0, 0, 790, 219, 0, 0, 0, 0, 386, 387,
+ 388, 389, 492, 391, 392, 393, 394, 395, 396, 493,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 273, 0, 0, 0, 0, 0, 0, 219, 0,
+ 0, 0, 0, 381, 382, 383, 384, 497, 498, 499,
+ 500, 501, 502, 503, 504, 505, 506, 507, 508, 509,
+ 510, 511, 512, 513, 390, 391, 392, 393, 394, 395,
+ 396, 397, 0, 0, 0, 0, 0, 521, 0, 0,
+ 0, 0, 729, 0, 528, 0, 0, 0, 0, 0,
+ 0, 297, 297, 0, 0, 0, 0, 559, 0, 750,
+ 0, 297, 0, 0, 0, 0, 0, 8, 0, 0,
+ 172, 0, 0, 219, 223, 224, 225, 226, 227, 228,
+ 229, 230, 219, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 231, 648, 0, 0, 0, 0, 0, 219, 0,
+ 28, 29, 30, 31, 32, 0, 232, 647, 506, 513,
+ 0, 0, 0, 219, 0, 0, 219, 795, 0, 33,
+ 34, 35, 802, 0, 0, 0, 381, 382, 383, 384,
+ 0, 559, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 219, 387, 388, 389, 390, 391, 392,
+ 393, 394, 395, 396, 397, 36, 0, 0, 219, 38,
+ 0, 0, 0, 0, 0, 0, 0, 0, 823, 233,
+ 0, 0, 234, 235, 0, 8, 236, 237, 238, 0,
+ 480, 0, 0, 313, 0, 0, 0, 0, 0, 0,
+ 0, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 0,
+ 0, 0, 0, 0, 0, 0, 0, 27, 28, 29,
+ 30, 31, 32, 381, 382, 383, 384, 0, 219, 0,
+ 0, 868, 219, 381, 382, 383, 384, 33, 34, 35,
+ 0, 823, 388, 389, 390, 391, 392, 393, 394, 395,
+ 396, 397, 219, 389, 390, 391, 392, 393, 394, 395,
+ 396, 397, 0, 0, 736, 373, 0, 737, 0, 0,
+ 0, 740, 605, 36, -467, 57, 37, 38, 58, 59,
+ 60, 0, 0, 0, 0, 0, 0, 0, 0, 61,
+ -467, -467, -467, -467, -467, -467, -467, -467, -467, -467,
+ -467, -467, -467, -467, -467, -467, -467, -467, 862, 0,
+ 0, 606, 63, 0, 0, -467, 0, -467, -467, -467,
+ -467, -467, 0, 773, 0, 0, 0, 0, 65, 66,
+ 67, 68, 607, 70, 71, 72, -467, -467, -467, 608,
+ 609, 610, 0, 73, 611, 75, 0, 76, 77, 78,
+ 0, 0, 0, 82, 804, 84, 85, 86, 87, 88,
+ 89, 0, 381, 382, 383, 384, 385, 0, 0, 0,
+ 90, 0, -467, 0, 0, 91, -467, -467, 0, 386,
+ 387, 388, 389, 390, 391, 392, 393, 394, 395, 396,
+ 397, 0, 0, 8, 0, 612, 172, 0, 0, 0,
+ 223, 224, 225, 226, 227, 228, 229, 230, 837, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 231, 0, 0,
+ 0, 0, 0, 0, 0, 27, 28, 29, 30, 31,
+ 32, 0, 232, 381, 382, 383, 384, 385, 0, 0,
+ 0, 0, 0, 0, 0, 33, 34, 35, 0, 0,
+ 386, 387, 388, 389, 390, 391, 392, 393, 394, 395,
+ 396, 397, 9, 10, 11, 12, 13, 14, 15, 16,
+ 0, 18, 0, 20, 0, 0, 23, 24, 25, 26,
+ 0, 36, 0, 0, 37, 38, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 233, 0, 0, 234, 235,
+ 0, 0, 236, 237, 238, 8, 0, 0, 172, 0,
+ 0, 0, 223, 224, 225, 226, 227, 228, 229, 230,
+ 413, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 231,
+ 0, 0, 0, 0, 0, 0, 0, 0, 28, 29,
+ 30, 31, 32, 0, 232, 0, 0, 265, 0, 381,
+ 382, 383, 384, 385, 0, 0, 0, 33, 34, 35,
+ 0, 381, 382, 383, 384, 0, 386, 387, 388, 389,
+ 390, 391, 392, 393, 394, 395, 396, 397, 386, 387,
+ 388, 389, 390, 391, 392, 393, 394, 395, 396, 397,
+ 0, 295, 0, 36, 172, 0, 0, 38, 0, 224,
+ 225, 226, 227, 228, 229, 230, 0, 233, 0, 0,
+ 234, 235, 0, 0, 236, 237, 238, 8, 0, 0,
+ 172, 0, 0, 0, 223, 224, 225, 226, 227, 228,
+ 229, 230, 530, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 231, 0, 0, 0, 0, 0, 0, 0, 0,
+ 28, 29, 30, 31, 32, 0, 232, 0, 0, 421,
+ 0, 381, 382, 383, 384, 385, 0, 0, 0, 33,
+ 34, 35, 0, 0, 0, 0, 0, 0, 386, 387,
+ 388, 389, 390, 391, 392, 393, 394, 395, 396, 397,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 36, 0, 0, 0, 38,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 233,
+ 0, 0, 234, 235, 0, 0, 236, 237, 238, 8,
+ 0, 0, 172, 0, 0, 0, 223, 224, 225, 226,
+ 227, 228, 229, 230, 532, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 231, 0, 0, 0, 0, 0, 0,
+ 0, 0, 28, 29, 30, 31, 32, 0, 232, 0,
+ 0, 424, 0, 381, 382, 383, 384, 385, 0, 0,
+ 0, 33, 34, 35, 0, 0, 0, 0, 0, 0,
+ 386, 387, 388, 389, 390, 391, 392, 393, 394, 395,
+ 396, 397, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 36, 0, 0,
+ 0, 38, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 233, 0, 0, 234, 235, 0, 0, 236, 237,
+ 238, 8, 0, 0, 172, 0, 0, 0, 223, 224,
+ 225, 226, 227, 228, 229, 230, 658, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 231, 0, 0, 0, 0,
+ 0, 0, 0, 0, 28, 29, 30, 31, 32, 0,
+ 232, 0, 0, 527, 0, 381, 382, 383, 384, 385,
+ 0, 0, 0, 33, 34, 35, 0, 0, 0, 0,
+ 0, 0, 386, 387, 388, 389, 390, 391, 392, 393,
+ 394, 395, 396, 397, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 36,
+ 0, 0, 0, 38, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 233, 0, 0, 234, 235, 0, 0,
+ 236, 237, 238, 8, 0, 0, 172, 0, 0, 0,
+ 223, 224, 225, 226, 227, 228, 229, 230, 662, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 231, 0, 0,
+ 0, 0, 0, 0, 0, 0, 28, 29, 30, 31,
+ 32, 0, 232, 0, 0, 0, 0, 381, 382, 383,
+ 384, 385, 0, 0, 0, 33, 34, 35, 0, 0,
+ 0, 0, 0, 0, 386, 387, 388, 389, 390, 391,
+ 392, 393, 394, 395, 396, 397, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 36, 0, 0, 0, 38, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 233, 0, 0, 234, 235,
+ 0, 0, 236, 237, 238, 8, 0, 0, 172, 0,
+ 0, 0, 223, 224, 225, 226, 227, 228, 229, 230,
+ 0, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 231,
+ 0, 0, 0, 0, 0, 0, 0, 0, 28, 29,
+ 30, 31, 32, 0, 232, 8, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 33, 34, 35,
+ 0, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 256,
+ 0, 0, 0, 0, 0, 0, 0, 27, 28, 29,
+ 30, 31, 32, 36, 0, 0, 144, 38, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 33, 34, 35,
+ 234, 235, 0, 0, 649, 237, 238, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 36, 0, 0, 37, 38, 0, 8,
+ 0, 0, 0, 0, 0, 0, 0, 257, 0, 0,
+ 0, 0, 0, 0, 147, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 256, 0, 0, 0, 0, 0, 0,
+ 0, 27, 28, 29, 30, 31, 32, 0, 0, 0,
+ 144, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8, 33, 34, 35, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 0, 0, 0, 36, 0, 0,
+ 37, 38, 27, 28, 29, 30, 31, 32, 0, 0,
+ 0, 400, 0, 8, 0, 0, 0, 0, 147, 0,
+ 0, 0, 33, 34, 35, 0, 0, 0, 0, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 655, 36, 31,
+ 32, 37, 38, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 352, 0, 0, 33, 34, 35, 0, 147,
+ 381, 382, 383, 384, 385, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 386, 387, 388,
+ 389, 390, 391, 392, 393, 394, 395, 396, 397, 0,
+ 0, 36, 0, 0, 0, 38, -2, 56, 0, -467,
+ 57, 0, 0, 58, 59, 60, 0, 0, 0, 0,
+ 0, 0, 147, 0, 61, -467, -467, -467, -467, -467,
+ -467, -467, -467, -467, -467, -467, -467, -467, -467, -467,
+ -467, -467, -467, 0, 0, 0, 62, 63, 0, 0,
+ 0, 0, -467, -467, -467, -467, -467, 0, 0, 64,
+ 0, 0, 0, 65, 66, 67, 68, 69, 70, 71,
+ 72, -467, -467, -467, 0, 0, 0, 0, 73, 74,
+ 75, 0, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, 88, 89, 56, 0, -467, 57,
+ 0, 0, 58, 59, 60, 90, 0, -467, 0, 0,
+ 91, -467, 0, 61, -467, -467, -467, -467, -467, -467,
+ -467, -467, -467, -467, -467, -467, -467, -467, -467, -467,
+ -467, -467, 0, 0, 0, 62, 63, 0, 0, 569,
+ 0, -467, -467, -467, -467, -467, 0, 0, 64, 0,
+ 0, 0, 65, 66, 67, 68, 69, 70, 71, 72,
+ -467, -467, -467, 0, 0, 0, 0, 73, 74, 75,
+ 0, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 56, 0, -467, 57, 0,
+ 0, 58, 59, 60, 90, 0, -467, 0, 0, 91,
+ -467, 0, 61, -467, -467, -467, -467, -467, -467, -467,
+ -467, -467, -467, -467, -467, -467, -467, -467, -467, -467,
+ -467, 0, 0, 0, 62, 63, 0, 0, 664, 0,
+ -467, -467, -467, -467, -467, 0, 0, 64, 0, 0,
+ 0, 65, 66, 67, 68, 69, 70, 71, 72, -467,
+ -467, -467, 0, 0, 0, 0, 73, 74, 75, 0,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 56, 0, -467, 57, 0, 0,
+ 58, 59, 60, 90, 0, -467, 0, 0, 91, -467,
+ 0, 61, -467, -467, -467, -467, -467, -467, -467, -467,
+ -467, -467, -467, -467, -467, -467, -467, -467, -467, -467,
+ 0, 0, 0, 62, 63, 0, 0, 680, 0, -467,
+ -467, -467, -467, -467, 0, 0, 64, 0, 0, 0,
+ 65, 66, 67, 68, 69, 70, 71, 72, -467, -467,
+ -467, 0, 0, 0, 0, 73, 74, 75, 0, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 56, 0, -467, 57, 0, 0, 58,
+ 59, 60, 90, 0, -467, 0, 0, 91, -467, 0,
+ 61, -467, -467, -467, -467, -467, -467, -467, -467, -467,
+ -467, -467, -467, -467, -467, -467, -467, -467, -467, 0,
+ 0, 0, 62, 63, 0, 0, 0, 0, -467, -467,
+ -467, -467, -467, 0, 0, 64, 0, 770, 0, 65,
+ 66, 67, 68, 69, 70, 71, 72, -467, -467, -467,
+ 0, 0, 0, 0, 73, 74, 75, 0, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 7, 0, 8, 0, 0, 0, 0, 0,
+ 0, 90, 0, -467, 0, 0, 91, -467, 0, 0,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 0, 0,
+ 0, 0, 0, 0, 0, 0, 27, 28, 29, 30,
+ 31, 32, 51, 0, 8, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 33, 34, 35, 0,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 0, 0,
+ 0, 0, 0, 0, 0, 0, 27, 28, 29, 30,
+ 31, 32, 36, 0, 0, 37, 38, 0, 0, 0,
+ 0, 0, 177, 0, 178, 0, 33, 34, 35, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 0, 0,
+ 0, 0, 36, 0, 0, 37, 38, 28, 29, 30,
+ 31, 32, 0, 8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 33, 34, 35, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 28, 29, 30, 31,
+ 32, 0, 36, 8, 0, 0, 38, 0, 0, 0,
+ 0, 0, 0, 0, 0, 220, 34, 35, 0, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 28, 29, 30, 31,
+ 32, 36, 8, 0, 0, 38, 726, 0, 0, 0,
+ 0, 0, 0, 0, 0, 33, 34, 35, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 0, 0, 0, 0,
+ 0, 0, 0, 0, 27, 28, 29, 30, 31, 32,
+ 0, 36, 8, 0, 0, 38, 726, 0, 0, 0,
+ 0, 0, 0, 0, 33, 34, 35, 0, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 203, 0, 0, 0,
+ 0, 0, 0, 0, 0, 28, 29, 30, 31, 32,
+ 36, 8, 0, 37, 38, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 33, 34, 35, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 28, 29, 30, 31, 32, 0,
+ 36, 8, 0, 0, 38, 0, 0, 0, 0, 0,
+ 0, 0, 0, 220, 34, 35, 0, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 28, 29, 30, 31, 32, 36,
+ 682, 0, 0, 38, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 33, 34, 35, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 28, 29, 30, 31, 32, 0, 36,
+ 8, 0, 0, 38, 0, 0, 0, 0, 0, 0,
+ 0, 0, 33, 34, 35, 0, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 31, 32, 36, 0,
+ 0, 0, 38, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 33, 34, 35, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 36, 0,
+ 0, 0, 38
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 0, 85, 5, 5, 40, 5, 320, 41, 8, 43,
+ 5, 212, 131, 549, 563, 5, 327, 5, 304, 465,
+ 42, 21, 37, 90, 137, 146, 6, 437, 5, 5,
+ 142, 39, 197, 5, 155, 5, 446, 446, 155, 40,
+ 5, 5, 42, 5, 3, 3, 1, 2, 161, 162,
+ 215, 38, 3, 38, 151, 5, 153, 171, 91, 5,
+ 5, 175, 43, 38, 64, 558, 110, 181, 5, 69,
+ 70, 5, 186, 566, 54, 5, 257, 5, 37, 260,
+ 3, 5, 39, 91, 6, 43, 5, 3, 3, 90,
+ 3, 38, 39, 205, 208, 5, 129, 590, 634, 54,
+ 115, 218, 102, 217, 597, 138, 140, 122, 3, 90,
+ 4, 253, 71, 147, 3, 102, 3, 0, 564, 3,
+ 142, 435, 1, 40, 37, 147, 43, 102, 43, 51,
+ 115, 131, 6, 39, 91, 179, 257, 6, 44, 260,
+ 454, 54, 101, 101, 256, 456, 105, 105, 290, 43,
+ 37, 151, 39, 153, 105, 51, 115, 269, 37, 51,
+ 45, 205, 283, 122, 51, 124, 283, 54, 168, 43,
+ 287, 352, 353, 90, 43, 71, 131, 221, 178, 3,
+ 51, 717, 105, 205, 71, 678, 101, 142, 101, 105,
+ 105, 191, 105, 215, 3, 79, 40, 3, 90, 735,
+ 4, 126, 751, 103, 91, 205, 101, 207, 208, 306,
+ 105, 124, 212, 37, 101, 3, 105, 101, 105, 90,
+ 220, 105, 244, 1, 2, 671, 126, 122, 115, 410,
+ 54, 3, 187, 188, 256, 122, 6, 124, 40, 43,
+ 54, 358, 242, 360, 244, 38, 39, 269, 203, 333,
+ 786, 90, 69, 275, 51, 43, 211, 212, 377, 3,
+ 753, 40, 6, 673, 673, 37, 467, 40, 365, 71,
+ 40, 436, 106, 3, 71, 589, 6, 101, 75, 400,
+ 401, 105, 54, 305, 3, 102, 407, 46, 47, 48,
+ 471, 115, 101, 414, 38, 101, 105, 414, 463, 105,
+ 124, 256, 3, 38, 39, 6, 306, 428, 4, 755,
+ 6, 428, 429, 101, 269, 3, 103, 105, 811, 855,
+ 320, 37, 38, 278, 6, 37, 281, 40, 3, 101,
+ 43, 365, 446, 105, 356, 37, 37, 292, 54, 126,
+ 37, 45, 364, 115, 3, 345, 368, 43, 37, 37,
+ 122, 351, 124, 131, 102, 4, 473, 6, 71, 476,
+ 37, 361, 37, 122, 857, 365, 399, 367, 861, 39,
+ 37, 101, 3, 187, 188, 105, 51, 54, 37, 54,
+ 3, 51, 101, 6, 3, 115, 105, 484, 4, 203,
+ 6, 40, 122, 37, 43, 54, 71, 211, 519, 776,
+ 101, 445, 51, 37, 105, 449, 783, 90, 525, 364,
+ 54, 39, 789, 101, 115, 43, 533, 105, 37, 102,
+ 103, 122, 377, 124, 37, 711, 101, 115, 472, 37,
+ 105, 37, 38, 433, 212, 435, 124, 68, 69, 70,
+ 115, 54, 101, 126, 37, 38, 105, 122, 54, 124,
+ 453, 453, 455, 453, 454, 455, 115, 37, 453, 493,
+ 460, 54, 417, 453, 278, 453, 37, 281, 37, 40,
+ 101, 493, 43, 495, 105, 592, 453, 453, 478, 37,
+ 37, 453, 101, 453, 484, 485, 105, 40, 453, 453,
+ 43, 453, 37, 448, 871, 495, 496, 54, 51, 612,
+ 665, 666, 37, 453, 879, 124, 43, 453, 453, 464,
+ 49, 50, 467, 4, 292, 6, 453, 892, 893, 453,
+ 564, 3, 38, 453, 558, 453, 39, 66, 67, 453,
+ 37, 38, 566, 3, 453, 37, 38, 40, 541, 541,
+ 43, 541, 4, 453, 6, 40, 541, 54, 43, 549,
+ 364, 541, 54, 541, 40, 599, 590, 43, 558, 656,
+ 762, 675, 764, 597, 541, 541, 566, 570, 570, 541,
+ 570, 541, 40, 692, 3, 570, 541, 541, 40, 541,
+ 570, 43, 570, 40, 587, 587, 43, 587, 588, 589,
+ 590, 541, 587, 570, 570, 541, 541, 597, 570, 377,
+ 570, 685, 40, 417, 541, 570, 570, 541, 570, 722,
+ 643, 541, 898, 541, 650, 649, 43, 541, 715, 3,
+ 570, 576, 541, 3, 570, 570, 43, 649, 650, 6,
+ 674, 541, 40, 570, 634, 39, 570, 102, 100, 683,
+ 570, 65, 570, 598, 678, 645, 570, 37, 91, 49,
+ 50, 570, 39, 38, 3, 4, 656, 6, 37, 91,
+ 570, 85, 86, 102, 38, 709, 66, 67, 54, 702,
+ 448, 46, 47, 48, 122, 40, 51, 102, 678, 38,
+ 724, 715, 682, 727, 38, 782, 464, 38, 37, 467,
+ 90, 40, 692, 43, 43, 38, 71, 107, 108, 109,
+ 75, 704, 704, 51, 704, 129, 39, 38, 708, 704,
+ 754, 38, 712, 668, 704, 715, 704, 717, 3, 753,
+ 46, 47, 48, 3, 40, 769, 38, 704, 704, 39,
+ 40, 828, 704, 43, 704, 735, 38, 692, 38, 704,
+ 704, 38, 704, 38, 38, 3, 91, 39, 18, 75,
+ 102, 100, 101, 753, 704, 710, 105, 37, 704, 704,
+ 38, 716, 576, 46, 47, 48, 115, 704, 790, 791,
+ 704, 41, 33, 122, 704, 124, 704, 811, 40, 37,
+ 704, 42, 782, 102, 598, 704, 786, 48, 43, 63,
+ 38, 102, 747, 793, 704, 839, 54, 797, 102, 843,
+ 38, 801, 72, 73, 74, 40, 40, 77, 38, 40,
+ 84, 811, 120, 121, 122, 89, 101, 78, 79, 863,
+ 105, 101, 43, 857, 37, 105, 44, 861, 828, 40,
+ 115, 38, 3, 788, 104, 115, 791, 122, 37, 839,
+ 840, 43, 876, 101, 124, 879, 38, 105, 39, 110,
+ 39, 37, 807, 51, 668, 855, 38, 857, 892, 893,
+ 37, 861, 126, 863, 90, 44, 124, 51, 37, 46,
+ 47, 48, 124, 43, 51, 830, 876, 3, 833, 879,
+ 44, 142, 3, 18, 71, 146, 71, 148, 71, 44,
+ 38, 38, 892, 893, 155, 73, 710, 171, 75, 44,
+ 174, 175, 716, 327, 859, 860, 41, 181, 37, 333,
+ 75, 37, 186, 38, 692, 3, 37, 40, 179, 40,
+ 38, 182, 71, 197, 40, 38, 37, 39, 189, 3,
+ 40, 3, 38, 747, 208, 209, 3, 72, 73, 74,
+ 214, 215, 77, 217, 205, 369, 118, 119, 120, 121,
+ 122, 3, 213, 37, 215, 216, 39, 218, 40, 220,
+ 221, 222, 40, 37, 91, 37, 40, 38, 38, 37,
+ 37, 40, 37, 3, 788, 101, 40, 791, 44, 105,
+ 101, 3, 54, 244, 105, 37, 3, 38, 40, 115,
+ 40, 40, 39, 807, 115, 256, 257, 38, 124, 260,
+ 44, 122, 37, 124, 37, 460, 3, 37, 269, 270,
+ 38, 38, 587, 38, 40, 37, 830, 3, 40, 833,
+ 37, 40, 283, 38, 54, 38, 287, 101, 38, 101,
+ 3, 105, 456, 105, 101, 3, 40, 40, 105, 40,
+ 37, 115, 437, 115, 305, 859, 860, 715, 122, 101,
+ 124, 37, 124, 105, 587, 467, 588, 124, 319, 587,
+ 587, 433, 863, 115, 37, 692, 496, 495, 377, 37,
+ 122, 101, 124, 708, 46, 105, 840, 797, 801, 101,
+ 861, 54, 21, 105, 101, 115, 852, -1, 105, 573,
+ -1, 352, 353, 115, 124, 356, -1, 358, 115, 360,
+ 122, -1, 124, 364, 101, 122, -1, 124, 105, -1,
+ 144, 145, -1, -1, -1, 101, -1, -1, 115, 105,
+ -1, -1, -1, -1, -1, 122, -1, 124, 101, 115,
+ -1, -1, 105, 101, -1, -1, 122, 105, 124, -1,
+ 401, -1, 115, -1, -1, -1, -1, 115, 572, 410,
+ -1, 124, -1, 414, 122, -1, 124, -1, -1, -1,
+ 434, -1, 436, 437, -1, -1, -1, 428, 429, -1,
+ 444, 445, 446, 116, 117, 118, 119, 120, 121, 122,
+ -1, -1, -1, -1, 445, -1, -1, -1, 449, 463,
+ -1, 465, -1, -1, -1, -1, -1, 231, 472, 233,
+ 234, 235, 236, 237, 238, -1, -1, -1, -1, -1,
+ 471, 472, 473, -1, -1, 476, 94, 95, 6, 643,
+ -1, -1, -1, 11, 12, 13, 14, 15, 16, 17,
+ 264, -1, -1, -1, 495, 38, -1, -1, 116, 117,
+ 118, 119, 120, 121, 122, 279, -1, -1, 282, -1,
+ -1, -1, -1, 514, -1, -1, -1, 94, 95, 96,
+ 97, 685, -1, -1, 525, -1, -1, -1, -1, -1,
+ -1, -1, 533, -1, -1, -1, -1, -1, 702, 116,
+ 117, 118, 119, 120, 121, 122, -1, -1, -1, -1,
+ 564, 94, 95, 96, 97, 98, -1, 571, -1, 573,
+ -1, -1, 726, 564, -1, -1, -1, -1, 111, 112,
+ 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 592, -1, -1, -1, -1, -1, -1, 599, -1,
+ -1, -1, -1, 94, 95, 96, 97, 381, 382, 383,
+ 384, 385, 386, 387, 388, 389, 390, 391, 392, 393,
+ 394, 395, 396, 397, 115, 116, 117, 118, 119, 120,
+ 121, 122, -1, -1, -1, -1, -1, 411, -1, -1,
+ -1, -1, 643, -1, 418, -1, -1, -1, -1, -1,
+ -1, 665, 666, -1, -1, -1, -1, 671, -1, 673,
+ -1, 675, -1, -1, -1, -1, -1, 3, -1, -1,
+ 6, -1, -1, 674, 10, 11, 12, 13, 14, 15,
+ 16, 17, 683, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, -1, -1, -1, -1, -1, 709, -1,
+ 46, 47, 48, 49, 50, -1, 52, 491, 492, 493,
+ -1, -1, -1, 724, -1, -1, 727, 728, -1, 65,
+ 66, 67, 733, -1, -1, -1, 94, 95, 96, 97,
+ -1, 755, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 754, 112, 113, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 101, -1, -1, 769, 105,
+ -1, -1, -1, -1, -1, -1, -1, -1, 779, 115,
+ -1, -1, 118, 119, -1, 3, 122, 123, 124, -1,
+ 791, -1, -1, 11, -1, -1, -1, -1, -1, -1,
+ -1, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, -1,
+ -1, -1, -1, -1, -1, -1, -1, 45, 46, 47,
+ 48, 49, 50, 94, 95, 96, 97, -1, 839, -1,
+ -1, 842, 843, 94, 95, 96, 97, 65, 66, 67,
+ -1, 852, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 863, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, -1, -1, 648, 649, -1, 651, -1, -1,
+ -1, 655, 1, 101, 3, 4, 104, 105, 7, 8,
+ 9, -1, -1, -1, -1, -1, -1, -1, -1, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 40, -1,
+ -1, 40, 41, -1, -1, 44, -1, 46, 47, 48,
+ 49, 50, -1, 707, -1, -1, -1, -1, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, -1, 72, 73, 74, -1, 76, 77, 78,
+ -1, -1, -1, 82, 738, 84, 85, 86, 87, 88,
+ 89, -1, 94, 95, 96, 97, 98, -1, -1, -1,
+ 99, -1, 101, -1, -1, 104, 105, 106, -1, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, -1, -1, 3, -1, 124, 6, -1, -1, -1,
+ 10, 11, 12, 13, 14, 15, 16, 17, 792, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, -1, -1,
+ -1, -1, -1, -1, -1, 45, 46, 47, 48, 49,
+ 50, -1, 52, 94, 95, 96, 97, 98, -1, -1,
+ -1, -1, -1, -1, -1, 65, 66, 67, -1, -1,
+ 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 19, 20, 21, 22, 23, 24, 25, 26,
+ -1, 28, -1, 30, -1, -1, 33, 34, 35, 36,
+ -1, 101, -1, -1, 104, 105, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 115, -1, -1, 118, 119,
+ -1, -1, 122, 123, 124, 3, -1, -1, 6, -1,
+ -1, -1, 10, 11, 12, 13, 14, 15, 16, 17,
+ 55, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ -1, -1, -1, -1, -1, -1, -1, -1, 46, 47,
+ 48, 49, 50, -1, 52, -1, -1, 55, -1, 94,
+ 95, 96, 97, 98, -1, -1, -1, 65, 66, 67,
+ -1, 94, 95, 96, 97, -1, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 111, 112,
+ 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
+ -1, 3, -1, 101, 6, -1, -1, 105, -1, 11,
+ 12, 13, 14, 15, 16, 17, -1, 115, -1, -1,
+ 118, 119, -1, -1, 122, 123, 124, 3, -1, -1,
+ 6, -1, -1, -1, 10, 11, 12, 13, 14, 15,
+ 16, 17, 55, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, -1, -1, -1, -1, -1, -1, -1, -1,
+ 46, 47, 48, 49, 50, -1, 52, -1, -1, 55,
+ -1, 94, 95, 96, 97, 98, -1, -1, -1, 65,
+ 66, 67, -1, -1, -1, -1, -1, -1, 111, 112,
+ 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 101, -1, -1, -1, 105,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 115,
+ -1, -1, 118, 119, -1, -1, 122, 123, 124, 3,
+ -1, -1, 6, -1, -1, -1, 10, 11, 12, 13,
+ 14, 15, 16, 17, 55, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, -1, -1, -1, -1, -1, -1,
+ -1, -1, 46, 47, 48, 49, 50, -1, 52, -1,
+ -1, 55, -1, 94, 95, 96, 97, 98, -1, -1,
+ -1, 65, 66, 67, -1, -1, -1, -1, -1, -1,
+ 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 101, -1, -1,
+ -1, 105, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 115, -1, -1, 118, 119, -1, -1, 122, 123,
+ 124, 3, -1, -1, 6, -1, -1, -1, 10, 11,
+ 12, 13, 14, 15, 16, 17, 55, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, -1, -1, -1, -1,
+ -1, -1, -1, -1, 46, 47, 48, 49, 50, -1,
+ 52, -1, -1, 55, -1, 94, 95, 96, 97, 98,
+ -1, -1, -1, 65, 66, 67, -1, -1, -1, -1,
+ -1, -1, 111, 112, 113, 114, 115, 116, 117, 118,
+ 119, 120, 121, 122, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 101,
+ -1, -1, -1, 105, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 115, -1, -1, 118, 119, -1, -1,
+ 122, 123, 124, 3, -1, -1, 6, -1, -1, -1,
+ 10, 11, 12, 13, 14, 15, 16, 17, 55, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, -1, -1,
+ -1, -1, -1, -1, -1, -1, 46, 47, 48, 49,
+ 50, -1, 52, -1, -1, -1, -1, 94, 95, 96,
+ 97, 98, -1, -1, -1, 65, 66, 67, -1, -1,
+ -1, -1, -1, -1, 111, 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 101, -1, -1, -1, 105, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 115, -1, -1, 118, 119,
+ -1, -1, 122, 123, 124, 3, -1, -1, 6, -1,
+ -1, -1, 10, 11, 12, 13, 14, 15, 16, 17,
+ -1, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ -1, -1, -1, -1, -1, -1, -1, -1, 46, 47,
+ 48, 49, 50, -1, 52, 3, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 65, 66, 67,
+ -1, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ -1, -1, -1, -1, -1, -1, -1, 45, 46, 47,
+ 48, 49, 50, 101, -1, -1, 54, 105, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 65, 66, 67,
+ 118, 119, -1, -1, 122, 123, 124, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 101, -1, -1, 104, 105, -1, 3,
+ -1, -1, -1, -1, -1, -1, -1, 115, -1, -1,
+ -1, -1, -1, -1, 122, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, -1, -1, -1, -1, -1, -1,
+ -1, 45, 46, 47, 48, 49, 50, -1, -1, -1,
+ 54, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 3, 65, 66, 67, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, -1, -1, -1, 101, -1, -1,
+ 104, 105, 45, 46, 47, 48, 49, 50, -1, -1,
+ -1, 115, -1, 3, -1, -1, -1, -1, 122, -1,
+ -1, -1, 65, 66, 67, -1, -1, -1, -1, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 71, 101, 49,
+ 50, 104, 105, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 115, -1, -1, 65, 66, 67, -1, 122,
+ 94, 95, 96, 97, 98, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 111, 112, 113,
+ 114, 115, 116, 117, 118, 119, 120, 121, 122, -1,
+ -1, 101, -1, -1, -1, 105, 0, 1, -1, 3,
+ 4, -1, -1, 7, 8, 9, -1, -1, -1, -1,
+ -1, -1, 122, -1, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, -1, -1, -1, 40, 41, -1, -1,
+ -1, -1, 46, 47, 48, 49, 50, -1, -1, 53,
+ -1, -1, -1, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, -1, -1, -1, -1, 72, 73,
+ 74, -1, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, 88, 89, 1, -1, 3, 4,
+ -1, -1, 7, 8, 9, 99, -1, 101, -1, -1,
+ 104, 105, -1, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, -1, -1, -1, 40, 41, -1, -1, 44,
+ -1, 46, 47, 48, 49, 50, -1, -1, 53, -1,
+ -1, -1, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, -1, -1, -1, -1, 72, 73, 74,
+ -1, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 1, -1, 3, 4, -1,
+ -1, 7, 8, 9, 99, -1, 101, -1, -1, 104,
+ 105, -1, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, -1, -1, -1, 40, 41, -1, -1, 44, -1,
+ 46, 47, 48, 49, 50, -1, -1, 53, -1, -1,
+ -1, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, -1, -1, -1, -1, 72, 73, 74, -1,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 1, -1, 3, 4, -1, -1,
+ 7, 8, 9, 99, -1, 101, -1, -1, 104, 105,
+ -1, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ -1, -1, -1, 40, 41, -1, -1, 44, -1, 46,
+ 47, 48, 49, 50, -1, -1, 53, -1, -1, -1,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, -1, -1, -1, -1, 72, 73, 74, -1, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 1, -1, 3, 4, -1, -1, 7,
+ 8, 9, 99, -1, 101, -1, -1, 104, 105, -1,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, -1,
+ -1, -1, 40, 41, -1, -1, -1, -1, 46, 47,
+ 48, 49, 50, -1, -1, 53, -1, 55, -1, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ -1, -1, -1, -1, 72, 73, 74, -1, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 1, -1, 3, -1, -1, -1, -1, -1,
+ -1, 99, -1, 101, -1, -1, 104, 105, -1, -1,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, -1, -1,
+ -1, -1, -1, -1, -1, -1, 45, 46, 47, 48,
+ 49, 50, 1, -1, 3, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, 66, 67, -1,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, -1, -1,
+ -1, -1, -1, -1, -1, -1, 45, 46, 47, 48,
+ 49, 50, 101, -1, -1, 104, 105, -1, -1, -1,
+ -1, -1, 1, -1, 3, -1, 65, 66, 67, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, -1, -1,
+ -1, -1, 101, -1, -1, 104, 105, 46, 47, 48,
+ 49, 50, -1, 3, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, 66, 67, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 46, 47, 48, 49,
+ 50, -1, 101, 3, -1, -1, 105, -1, -1, -1,
+ -1, -1, -1, -1, -1, 65, 66, 67, -1, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 46, 47, 48, 49,
+ 50, 101, 3, -1, -1, 105, 106, -1, -1, -1,
+ -1, -1, -1, -1, -1, 65, 66, 67, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, -1, -1, -1, -1,
+ -1, -1, -1, -1, 45, 46, 47, 48, 49, 50,
+ -1, 101, 3, -1, -1, 105, 106, -1, -1, -1,
+ -1, -1, -1, -1, 65, 66, 67, -1, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, -1, -1, -1,
+ -1, -1, -1, -1, -1, 46, 47, 48, 49, 50,
+ 101, 3, -1, 104, 105, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 65, 66, 67, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 46, 47, 48, 49, 50, -1,
+ 101, 3, -1, -1, 105, -1, -1, -1, -1, -1,
+ -1, -1, -1, 65, 66, 67, -1, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 46, 47, 48, 49, 50, 101,
+ 3, -1, -1, 105, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 65, 66, 67, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 46, 47, 48, 49, 50, -1, 101,
+ 3, -1, -1, 105, -1, -1, -1, -1, -1, -1,
+ -1, -1, 65, 66, 67, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 49, 50, 101, -1,
+ -1, -1, 105, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 65, 66, 67, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 101, -1,
+ -1, -1, 105
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint16 yystos[] =
+{
+ 0, 107, 108, 109, 128, 129, 274, 1, 3, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 45, 46, 47,
+ 48, 49, 50, 65, 66, 67, 101, 104, 105, 215,
+ 229, 230, 232, 233, 234, 235, 236, 253, 254, 264,
+ 266, 1, 215, 1, 37, 0, 1, 4, 7, 8,
+ 9, 18, 40, 41, 53, 57, 58, 59, 60, 61,
+ 62, 63, 64, 72, 73, 74, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 99, 104, 130, 131, 132, 134, 135, 136, 137, 138,
+ 141, 142, 144, 145, 146, 147, 148, 149, 150, 153,
+ 154, 155, 158, 160, 165, 166, 167, 168, 170, 173,
+ 174, 175, 176, 177, 181, 182, 189, 190, 200, 211,
+ 274, 90, 261, 274, 261, 45, 264, 126, 90, 40,
+ 233, 229, 37, 51, 54, 71, 115, 122, 124, 220,
+ 221, 223, 225, 226, 227, 228, 264, 274, 229, 235,
+ 264, 103, 126, 265, 40, 40, 212, 213, 215, 274,
+ 106, 37, 6, 269, 37, 271, 274, 1, 3, 231,
+ 232, 37, 271, 37, 152, 274, 37, 37, 37, 79,
+ 264, 3, 43, 264, 37, 4, 43, 37, 37, 40,
+ 43, 4, 269, 37, 164, 231, 162, 164, 37, 37,
+ 269, 37, 90, 254, 271, 37, 115, 223, 228, 264,
+ 65, 231, 254, 10, 11, 12, 13, 14, 15, 16,
+ 17, 37, 52, 115, 118, 119, 122, 123, 124, 215,
+ 216, 217, 219, 231, 232, 243, 244, 245, 246, 269,
+ 274, 45, 105, 266, 254, 229, 37, 115, 212, 226,
+ 228, 264, 43, 237, 238, 55, 243, 244, 243, 37,
+ 124, 224, 227, 264, 228, 229, 264, 220, 37, 54,
+ 220, 37, 54, 115, 224, 227, 264, 102, 266, 105,
+ 266, 38, 39, 214, 274, 3, 262, 269, 6, 43,
+ 262, 272, 262, 40, 51, 37, 223, 38, 262, 264,
+ 3, 3, 262, 11, 159, 212, 212, 264, 40, 51,
+ 192, 43, 3, 161, 272, 3, 212, 43, 222, 223,
+ 226, 274, 40, 39, 163, 274, 262, 263, 274, 139,
+ 140, 269, 212, 185, 186, 187, 215, 253, 274, 264,
+ 269, 3, 115, 228, 264, 272, 37, 262, 115, 264,
+ 102, 3, 239, 274, 37, 223, 43, 264, 243, 37,
+ 243, 243, 243, 243, 243, 243, 91, 39, 218, 274,
+ 37, 94, 95, 96, 97, 98, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 265, 91,
+ 115, 228, 264, 225, 264, 38, 38, 115, 225, 264,
+ 102, 54, 243, 55, 228, 264, 264, 37, 54, 228,
+ 212, 55, 243, 212, 55, 243, 224, 227, 102, 115,
+ 224, 265, 40, 215, 38, 169, 39, 51, 38, 237,
+ 220, 38, 43, 38, 51, 38, 39, 157, 39, 38,
+ 38, 40, 264, 129, 191, 38, 38, 38, 38, 162,
+ 164, 38, 38, 39, 43, 38, 91, 39, 188, 274,
+ 54, 102, 38, 228, 264, 40, 102, 40, 43, 212,
+ 264, 75, 172, 220, 229, 179, 40, 71, 247, 248,
+ 274, 38, 115, 122, 228, 231, 219, 243, 243, 243,
+ 243, 243, 243, 243, 243, 243, 243, 243, 243, 243,
+ 243, 243, 243, 243, 254, 264, 102, 38, 38, 102,
+ 225, 243, 224, 264, 38, 102, 212, 55, 243, 38,
+ 55, 38, 55, 115, 224, 227, 224, 214, 4, 43,
+ 269, 129, 272, 139, 245, 269, 273, 40, 40, 133,
+ 4, 151, 269, 4, 40, 43, 100, 156, 223, 269,
+ 270, 262, 269, 273, 38, 215, 223, 43, 40, 44,
+ 129, 41, 211, 162, 40, 43, 37, 44, 163, 3,
+ 101, 105, 267, 40, 272, 215, 156, 183, 187, 143,
+ 223, 269, 102, 3, 240, 241, 274, 38, 37, 39,
+ 40, 43, 171, 75, 220, 1, 40, 61, 68, 69,
+ 70, 73, 124, 134, 135, 136, 137, 141, 142, 146,
+ 148, 150, 153, 155, 158, 160, 165, 166, 167, 168,
+ 181, 182, 189, 193, 196, 197, 198, 199, 200, 201,
+ 202, 207, 210, 211, 274, 249, 43, 243, 38, 122,
+ 229, 38, 115, 221, 218, 71, 264, 38, 55, 38,
+ 224, 38, 55, 224, 44, 39, 39, 193, 37, 75,
+ 229, 256, 274, 51, 38, 39, 157, 156, 223, 256,
+ 44, 269, 3, 231, 40, 51, 270, 212, 103, 126,
+ 268, 126, 90, 38, 44, 170, 177, 181, 182, 184,
+ 197, 199, 211, 188, 129, 256, 40, 51, 39, 44,
+ 37, 51, 256, 257, 212, 223, 37, 195, 43, 71,
+ 71, 71, 124, 266, 44, 193, 106, 231, 254, 264,
+ 73, 250, 251, 255, 274, 178, 243, 243, 38, 38,
+ 243, 220, 38, 272, 272, 44, 212, 37, 75, 156,
+ 269, 273, 40, 223, 38, 256, 40, 40, 223, 164,
+ 38, 3, 3, 105, 3, 105, 216, 4, 43, 231,
+ 55, 40, 242, 243, 241, 40, 223, 212, 237, 71,
+ 258, 274, 38, 172, 212, 193, 194, 266, 37, 223,
+ 231, 37, 71, 3, 43, 264, 40, 39, 68, 69,
+ 70, 252, 264, 193, 243, 38, 212, 37, 157, 256,
+ 40, 223, 156, 40, 40, 268, 268, 91, 171, 38,
+ 40, 259, 260, 264, 40, 43, 220, 171, 38, 193,
+ 37, 212, 171, 37, 115, 228, 212, 243, 43, 204,
+ 71, 251, 255, 44, 40, 38, 212, 40, 256, 40,
+ 40, 43, 39, 37, 220, 44, 212, 38, 212, 37,
+ 37, 38, 40, 203, 206, 223, 274, 250, 264, 40,
+ 180, 223, 38, 40, 260, 193, 38, 208, 256, 38,
+ 212, 212, 257, 206, 40, 43, 171, 209, 256, 40,
+ 43, 209, 38, 38, 40, 205, 40, 43, 51, 209,
+ 209, 40, 237, 40
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ yytype_int16 *bottom;
+ yytype_int16 *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+ YYSTYPE *yyvsp;
+ int yyrule;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ fprintf (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ YYUSE (yyvaluep);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol. */
+int yychar;
+
+/* The semantic value of the look-ahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+ int yystate;
+ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ look-ahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to look-ahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a look-ahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+#line 1593 "parser.y"
+ {
+ if (!classes) classes = NewHash();
+ Setattr((yyvsp[(1) - (1)].node),"classes",classes);
+ Setattr((yyvsp[(1) - (1)].node),"name",ModuleName);
+
+ if ((!module_node) && ModuleName) {
+ module_node = new_node("module");
+ Setattr(module_node,"name",ModuleName);
+ }
+ Setattr((yyvsp[(1) - (1)].node),"module",module_node);
+ check_extensions();
+ top = (yyvsp[(1) - (1)].node);
+ }
+ break;
+
+ case 3:
+#line 1606 "parser.y"
+ {
+ top = Copy(Getattr((yyvsp[(2) - (3)].p),"type"));
+ Delete((yyvsp[(2) - (3)].p));
+ }
+ break;
+
+ case 4:
+#line 1610 "parser.y"
+ {
+ top = 0;
+ }
+ break;
+
+ case 5:
+#line 1613 "parser.y"
+ {
+ top = (yyvsp[(2) - (3)].p);
+ }
+ break;
+
+ case 6:
+#line 1616 "parser.y"
+ {
+ top = 0;
+ }
+ break;
+
+ case 7:
+#line 1619 "parser.y"
+ {
+ top = (yyvsp[(3) - (5)].pl);
+ }
+ break;
+
+ case 8:
+#line 1622 "parser.y"
+ {
+ top = 0;
+ }
+ break;
+
+ case 9:
+#line 1627 "parser.y"
+ {
+ /* add declaration to end of linked list (the declaration isn't always a single declaration, sometimes it is a linked list itself) */
+ appendChild((yyvsp[(1) - (2)].node),(yyvsp[(2) - (2)].node));
+ (yyval.node) = (yyvsp[(1) - (2)].node);
+ }
+ break;
+
+ case 10:
+#line 1632 "parser.y"
+ {
+ (yyval.node) = new_node("top");
+ }
+ break;
+
+ case 11:
+#line 1637 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 12:
+#line 1638 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 13:
+#line 1639 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 14:
+#line 1640 "parser.y"
+ { (yyval.node) = 0; }
+ break;
+
+ case 15:
+#line 1641 "parser.y"
+ {
+ (yyval.node) = 0;
+ Swig_error(cparse_file, cparse_line,"Syntax error in input(1).\n");
+ exit(1);
+ }
+ break;
+
+ case 16:
+#line 1647 "parser.y"
+ {
+ if ((yyval.node)) {
+ add_symbols((yyval.node));
+ }
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ }
+ break;
+
+ case 17:
+#line 1663 "parser.y"
+ {
+ (yyval.node) = 0;
+ skip_decl();
+ }
+ break;
+
+ case 18:
+#line 1673 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 19:
+#line 1674 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 20:
+#line 1675 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 21:
+#line 1676 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 22:
+#line 1677 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 23:
+#line 1678 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 24:
+#line 1679 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 25:
+#line 1680 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 26:
+#line 1681 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 27:
+#line 1682 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 28:
+#line 1683 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 29:
+#line 1684 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 30:
+#line 1685 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 31:
+#line 1686 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 32:
+#line 1687 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 33:
+#line 1688 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 34:
+#line 1689 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 35:
+#line 1690 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 36:
+#line 1691 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 37:
+#line 1692 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 38:
+#line 1693 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 39:
+#line 1700 "parser.y"
+ {
+ Node *cls;
+ String *clsname;
+ cplus_mode = CPLUS_PUBLIC;
+ if (!classes) classes = NewHash();
+ if (!extendhash) extendhash = NewHash();
+ clsname = make_class_name((yyvsp[(3) - (4)].str));
+ 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((yyvsp[(3) - (4)].str));
+ 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;
+ extendmode = 1;
+ }
+ Classprefix = NewString((yyvsp[(3) - (4)].str));
+ Namespaceprefix= Swig_symbol_qualifiedscopename(0);
+ Delete(clsname);
+ }
+ break;
+
+ case 40:
+#line 1728 "parser.y"
+ {
+ String *clsname;
+ extendmode = 0;
+ (yyval.node) = new_node("extend");
+ Setattr((yyval.node),"symtab",Swig_symbol_popscope());
+ if (prev_symtab) {
+ Swig_symbol_setscope(prev_symtab);
+ }
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ clsname = make_class_name((yyvsp[(3) - (7)].str));
+ Setattr((yyval.node),"name",clsname);
+
+ /* Mark members as extend */
+
+ tag_nodes((yyvsp[(6) - (7)].node),"feature:extend",(char*) "1");
+ if (current_class) {
+ /* We add the extension to the previously defined class */
+ appendChild((yyval.node),(yyvsp[(6) - (7)].node));
+ appendChild(current_class,(yyval.node));
+ } 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,(yyvsp[(6) - (7)].node));
+ } else {
+ appendChild((yyval.node),(yyvsp[(6) - (7)].node));
+ Setattr(extendhash,clsname,(yyval.node));
+ }
+ }
+ current_class = 0;
+ Delete(Classprefix);
+ Delete(clsname);
+ Classprefix = 0;
+ prev_symtab = 0;
+ (yyval.node) = 0;
+
+ }
+ break;
+
+ case 41:
+#line 1772 "parser.y"
+ {
+ (yyval.node) = new_node("apply");
+ Setattr((yyval.node),"pattern",Getattr((yyvsp[(2) - (5)].p),"pattern"));
+ appendChild((yyval.node),(yyvsp[(4) - (5)].p));
+ }
+ break;
+
+ case 42:
+#line 1782 "parser.y"
+ {
+ (yyval.node) = new_node("clear");
+ appendChild((yyval.node),(yyvsp[(2) - (3)].p));
+ }
+ break;
+
+ case 43:
+#line 1793 "parser.y"
+ {
+ if (((yyvsp[(4) - (5)].dtype).type != T_ERROR) && ((yyvsp[(4) - (5)].dtype).type != T_SYMBOL)) {
+ SwigType *type = NewSwigType((yyvsp[(4) - (5)].dtype).type);
+ (yyval.node) = new_node("constant");
+ Setattr((yyval.node),"name",(yyvsp[(2) - (5)].id));
+ Setattr((yyval.node),"type",type);
+ Setattr((yyval.node),"value",(yyvsp[(4) - (5)].dtype).val);
+ if ((yyvsp[(4) - (5)].dtype).rawval) Setattr((yyval.node),"rawval", (yyvsp[(4) - (5)].dtype).rawval);
+ Setattr((yyval.node),"storage","%constant");
+ SetFlag((yyval.node),"feature:immutable");
+ add_symbols((yyval.node));
+ Delete(type);
+ } else {
+ if ((yyvsp[(4) - (5)].dtype).type == T_ERROR) {
+ Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n");
+ }
+ (yyval.node) = 0;
+ }
+
+ }
+ break;
+
+ case 44:
+#line 1814 "parser.y"
+ {
+ if (((yyvsp[(4) - (5)].dtype).type != T_ERROR) && ((yyvsp[(4) - (5)].dtype).type != T_SYMBOL)) {
+ SwigType_push((yyvsp[(2) - (5)].type),(yyvsp[(3) - (5)].decl).type);
+ /* Sneaky callback function trick */
+ if (SwigType_isfunction((yyvsp[(2) - (5)].type))) {
+ SwigType_add_pointer((yyvsp[(2) - (5)].type));
+ }
+ (yyval.node) = new_node("constant");
+ Setattr((yyval.node),"name",(yyvsp[(3) - (5)].decl).id);
+ Setattr((yyval.node),"type",(yyvsp[(2) - (5)].type));
+ Setattr((yyval.node),"value",(yyvsp[(4) - (5)].dtype).val);
+ if ((yyvsp[(4) - (5)].dtype).rawval) Setattr((yyval.node),"rawval", (yyvsp[(4) - (5)].dtype).rawval);
+ Setattr((yyval.node),"storage","%constant");
+ SetFlag((yyval.node),"feature:immutable");
+ add_symbols((yyval.node));
+ } else {
+ if ((yyvsp[(4) - (5)].dtype).type == T_ERROR) {
+ Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value\n");
+ }
+ (yyval.node) = 0;
+ }
+ }
+ break;
+
+ case 45:
+#line 1836 "parser.y"
+ {
+ Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n");
+ (yyval.node) = 0;
+ }
+ break;
+
+ case 46:
+#line 1847 "parser.y"
+ {
+ char temp[64];
+ Replace((yyvsp[(2) - (2)].str),"$file",cparse_file, DOH_REPLACE_ANY);
+ sprintf(temp,"%d", cparse_line);
+ Replace((yyvsp[(2) - (2)].str),"$line",temp,DOH_REPLACE_ANY);
+ Printf(stderr,"%s\n", (yyvsp[(2) - (2)].str));
+ Delete((yyvsp[(2) - (2)].str));
+ (yyval.node) = 0;
+ }
+ break;
+
+ case 47:
+#line 1856 "parser.y"
+ {
+ char temp[64];
+ String *s = NewString((yyvsp[(2) - (2)].id));
+ 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);
+ (yyval.node) = 0;
+ }
+ break;
+
+ case 48:
+#line 1875 "parser.y"
+ {
+ skip_balanced('{','}');
+ (yyval.node) = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
+ }
+ break;
+
+ case 49:
+#line 1881 "parser.y"
+ {
+ skip_balanced('{','}');
+ (yyval.node) = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
+ }
+ break;
+
+ case 50:
+#line 1887 "parser.y"
+ {
+ (yyval.node) = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
+ }
+ break;
+
+ case 51:
+#line 1892 "parser.y"
+ {
+ (yyval.node) = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
+ }
+ break;
+
+ case 52:
+#line 1899 "parser.y"
+ {
+ (yyval.node) = NewHash();
+ Setattr((yyval.node),"value",(yyvsp[(1) - (4)].id));
+ Setattr((yyval.node),"type",Getattr((yyvsp[(3) - (4)].p),"type"));
+ }
+ break;
+
+ case 53:
+#line 1906 "parser.y"
+ {
+ (yyval.node) = NewHash();
+ Setattr((yyval.node),"value",(yyvsp[(1) - (1)].id));
+ }
+ break;
+
+ case 54:
+#line 1910 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ }
+ break;
+
+ case 55:
+#line 1923 "parser.y"
+ {
+ Hash *p = (yyvsp[(5) - (7)].node);
+ (yyval.node) = new_node("fragment");
+ Setattr((yyval.node),"value",Getattr((yyvsp[(3) - (7)].node),"value"));
+ Setattr((yyval.node),"type",Getattr((yyvsp[(3) - (7)].node),"type"));
+ Setattr((yyval.node),"section",Getattr(p,"name"));
+ Setattr((yyval.node),"kwargs",nextSibling(p));
+ Setattr((yyval.node),"code",(yyvsp[(7) - (7)].str));
+ }
+ break;
+
+ case 56:
+#line 1932 "parser.y"
+ {
+ Hash *p = (yyvsp[(5) - (7)].node);
+ String *code;
+ skip_balanced('{','}');
+ (yyval.node) = new_node("fragment");
+ Setattr((yyval.node),"value",Getattr((yyvsp[(3) - (7)].node),"value"));
+ Setattr((yyval.node),"type",Getattr((yyvsp[(3) - (7)].node),"type"));
+ Setattr((yyval.node),"section",Getattr(p,"name"));
+ Setattr((yyval.node),"kwargs",nextSibling(p));
+ Delitem(scanner_ccode,0);
+ Delitem(scanner_ccode,DOH_END);
+ code = Copy(scanner_ccode);
+ Setattr((yyval.node),"code",code);
+ Delete(code);
+ }
+ break;
+
+ case 57:
+#line 1947 "parser.y"
+ {
+ (yyval.node) = new_node("fragment");
+ Setattr((yyval.node),"value",Getattr((yyvsp[(3) - (5)].node),"value"));
+ Setattr((yyval.node),"type",Getattr((yyvsp[(3) - (5)].node),"type"));
+ Setattr((yyval.node),"emitonly","1");
+ }
+ break;
+
+ case 58:
+#line 1960 "parser.y"
+ {
+ (yyvsp[(1) - (4)].loc).filename = Copy(cparse_file);
+ (yyvsp[(1) - (4)].loc).line = cparse_line;
+ scanner_set_location(NewString((yyvsp[(3) - (4)].id)),1);
+ if ((yyvsp[(2) - (4)].node)) {
+ String *maininput = Getattr((yyvsp[(2) - (4)].node), "maininput");
+ if (maininput)
+ scanner_set_main_input_file(NewString(maininput));
+ }
+ }
+ break;
+
+ case 59:
+#line 1969 "parser.y"
+ {
+ String *mname = 0;
+ (yyval.node) = (yyvsp[(6) - (7)].node);
+ scanner_set_location((yyvsp[(1) - (7)].loc).filename,(yyvsp[(1) - (7)].loc).line);
+ if (strcmp((yyvsp[(1) - (7)].loc).type,"include") == 0) set_nodeType((yyval.node),"include");
+ if (strcmp((yyvsp[(1) - (7)].loc).type,"import") == 0) {
+ mname = (yyvsp[(2) - (7)].node) ? Getattr((yyvsp[(2) - (7)].node),"module") : 0;
+ set_nodeType((yyval.node),"import");
+ if (import_mode) --import_mode;
+ }
+
+ Setattr((yyval.node),"name",(yyvsp[(3) - (7)].id));
+ /* Search for the module (if any) */
+ {
+ Node *n = firstChild((yyval.node));
+ while (n) {
+ if (Strcmp(nodeType(n),"module") == 0) {
+ if (mname) {
+ Setattr(n,"name", mname);
+ mname = 0;
+ }
+ Setattr((yyval.node),"module",Getattr(n,"name"));
+ break;
+ }
+ n = nextSibling(n);
+ }
+ if (mname) {
+ /* There is no module node in the import
+ node, ie, you imported a .h file
+ directly. We are forced then to create
+ a new import node with a module node.
+ */
+ Node *nint = new_node("import");
+ Node *mnode = new_node("module");
+ Setattr(mnode,"name", mname);
+ appendChild(nint,mnode);
+ Delete(mnode);
+ appendChild(nint,firstChild((yyval.node)));
+ (yyval.node) = nint;
+ Setattr((yyval.node),"module",mname);
+ }
+ }
+ Setattr((yyval.node),"options",(yyvsp[(2) - (7)].node));
+ }
+ break;
+
+ case 60:
+#line 2015 "parser.y"
+ { (yyval.loc).type = (char *) "include"; }
+ break;
+
+ case 61:
+#line 2016 "parser.y"
+ { (yyval.loc).type = (char *) "import"; ++import_mode;}
+ break;
+
+ case 62:
+#line 2023 "parser.y"
+ {
+ String *cpps;
+ if (Namespaceprefix) {
+ Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
+
+ (yyval.node) = 0;
+ } else {
+ (yyval.node) = new_node("insert");
+ Setattr((yyval.node),"code",(yyvsp[(2) - (2)].str));
+ /* Need to run through the preprocessor */
+ Setline((yyvsp[(2) - (2)].str),cparse_start_line);
+ Setfile((yyvsp[(2) - (2)].str),cparse_file);
+ Seek((yyvsp[(2) - (2)].str),0,SEEK_SET);
+ cpps = Preprocessor_parse((yyvsp[(2) - (2)].str));
+ start_inline(Char(cpps), cparse_start_line);
+ Delete((yyvsp[(2) - (2)].str));
+ Delete(cpps);
+ }
+
+ }
+ break;
+
+ case 63:
+#line 2043 "parser.y"
+ {
+ String *cpps;
+ int start_line = cparse_line;
+ skip_balanced('{','}');
+ if (Namespaceprefix) {
+ Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
+
+ (yyval.node) = 0;
+ } else {
+ String *code;
+ (yyval.node) = new_node("insert");
+ Delitem(scanner_ccode,0);
+ Delitem(scanner_ccode,DOH_END);
+ code = Copy(scanner_ccode);
+ Setattr((yyval.node),"code", code);
+ Delete(code);
+ cpps=Copy(scanner_ccode);
+ start_inline(Char(cpps), start_line);
+ Delete(cpps);
+ }
+ }
+ break;
+
+ case 64:
+#line 2074 "parser.y"
+ {
+ (yyval.node) = new_node("insert");
+ Setattr((yyval.node),"code",(yyvsp[(1) - (1)].str));
+ }
+ break;
+
+ case 65:
+#line 2078 "parser.y"
+ {
+ String *code = NewStringEmpty();
+ (yyval.node) = new_node("insert");
+ Setattr((yyval.node),"section",(yyvsp[(3) - (5)].id));
+ Setattr((yyval.node),"code",code);
+ if (Swig_insert_file((yyvsp[(5) - (5)].id),code) < 0) {
+ Swig_error(cparse_file, cparse_line, "Couldn't find '%s'.\n", (yyvsp[(5) - (5)].id));
+ (yyval.node) = 0;
+ }
+ }
+ break;
+
+ case 66:
+#line 2088 "parser.y"
+ {
+ (yyval.node) = new_node("insert");
+ Setattr((yyval.node),"section",(yyvsp[(3) - (5)].id));
+ Setattr((yyval.node),"code",(yyvsp[(5) - (5)].str));
+ }
+ break;
+
+ case 67:
+#line 2093 "parser.y"
+ {
+ String *code;
+ skip_balanced('{','}');
+ (yyval.node) = new_node("insert");
+ Setattr((yyval.node),"section",(yyvsp[(3) - (5)].id));
+ Delitem(scanner_ccode,0);
+ Delitem(scanner_ccode,DOH_END);
+ code = Copy(scanner_ccode);
+ Setattr((yyval.node),"code", code);
+ Delete(code);
+ }
+ break;
+
+ case 68:
+#line 2111 "parser.y"
+ {
+ (yyval.node) = new_node("module");
+ if ((yyvsp[(2) - (3)].node)) {
+ Setattr((yyval.node),"options",(yyvsp[(2) - (3)].node));
+ if (Getattr((yyvsp[(2) - (3)].node),"directors")) {
+ Wrapper_director_mode_set(1);
+ }
+ if (Getattr((yyvsp[(2) - (3)].node),"dirprot")) {
+ Wrapper_director_protected_mode_set(1);
+ }
+ if (Getattr((yyvsp[(2) - (3)].node),"allprotected")) {
+ Wrapper_all_protected_mode_set(1);
+ }
+ if (Getattr((yyvsp[(2) - (3)].node),"templatereduce")) {
+ template_reduce = 1;
+ }
+ if (Getattr((yyvsp[(2) - (3)].node),"notemplatereduce")) {
+ template_reduce = 0;
+ }
+ }
+ if (!ModuleName) ModuleName = NewString((yyvsp[(3) - (3)].id));
+ if (!import_mode) {
+ /* first module included, we apply global
+ ModuleName, which can be modify by -module */
+ String *mname = Copy(ModuleName);
+ Setattr((yyval.node),"name",mname);
+ Delete(mname);
+ } else {
+ /* import mode, we just pass the idstring */
+ Setattr((yyval.node),"name",(yyvsp[(3) - (3)].id));
+ }
+ if (!module_node) module_node = (yyval.node);
+ }
+ break;
+
+ case 69:
+#line 2151 "parser.y"
+ {
+ Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n");
+ Delete(yyrename);
+ yyrename = NewString((yyvsp[(3) - (4)].id));
+ (yyval.node) = 0;
+ }
+ break;
+
+ case 70:
+#line 2157 "parser.y"
+ {
+ Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n");
+ (yyval.node) = 0;
+ Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n");
+ }
+ break;
+
+ case 71:
+#line 2170 "parser.y"
+ {
+ (yyval.node) = new_node("native");
+ Setattr((yyval.node),"name",(yyvsp[(3) - (7)].id));
+ Setattr((yyval.node),"wrap:name",(yyvsp[(6) - (7)].id));
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 72:
+#line 2176 "parser.y"
+ {
+ if (!SwigType_isfunction((yyvsp[(7) - (8)].decl).type)) {
+ Swig_error(cparse_file,cparse_line,"%%native declaration '%s' is not a function.\n", (yyvsp[(7) - (8)].decl).id);
+ (yyval.node) = 0;
+ } else {
+ Delete(SwigType_pop_function((yyvsp[(7) - (8)].decl).type));
+ /* Need check for function here */
+ SwigType_push((yyvsp[(6) - (8)].type),(yyvsp[(7) - (8)].decl).type);
+ (yyval.node) = new_node("native");
+ Setattr((yyval.node),"name",(yyvsp[(3) - (8)].id));
+ Setattr((yyval.node),"wrap:name",(yyvsp[(7) - (8)].decl).id);
+ Setattr((yyval.node),"type",(yyvsp[(6) - (8)].type));
+ Setattr((yyval.node),"parms",(yyvsp[(7) - (8)].decl).parms);
+ Setattr((yyval.node),"decl",(yyvsp[(7) - (8)].decl).type);
+ }
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 73:
+#line 2202 "parser.y"
+ {
+ (yyval.node) = new_node("pragma");
+ Setattr((yyval.node),"lang",(yyvsp[(2) - (5)].id));
+ Setattr((yyval.node),"name",(yyvsp[(3) - (5)].id));
+ Setattr((yyval.node),"value",(yyvsp[(5) - (5)].str));
+ }
+ break;
+
+ case 74:
+#line 2208 "parser.y"
+ {
+ (yyval.node) = new_node("pragma");
+ Setattr((yyval.node),"lang",(yyvsp[(2) - (3)].id));
+ Setattr((yyval.node),"name",(yyvsp[(3) - (3)].id));
+ }
+ break;
+
+ case 75:
+#line 2215 "parser.y"
+ { (yyval.str) = NewString((yyvsp[(1) - (1)].id)); }
+ break;
+
+ case 76:
+#line 2216 "parser.y"
+ { (yyval.str) = (yyvsp[(1) - (1)].str); }
+ break;
+
+ case 77:
+#line 2219 "parser.y"
+ { (yyval.id) = (yyvsp[(2) - (3)].id); }
+ break;
+
+ case 78:
+#line 2220 "parser.y"
+ { (yyval.id) = (char *) "swig"; }
+ break;
+
+ case 79:
+#line 2228 "parser.y"
+ {
+ SwigType *t = (yyvsp[(2) - (4)].decl).type;
+ Hash *kws = NewHash();
+ String *fixname;
+ fixname = feature_identifier_fix((yyvsp[(2) - (4)].decl).id);
+ Setattr(kws,"name",(yyvsp[(3) - (4)].id));
+ if (!Len(t)) t = 0;
+ /* Special declarator check */
+ if (t) {
+ if (SwigType_isfunction(t)) {
+ SwigType *decl = SwigType_pop_function(t);
+ if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",fixname);
+ if ((yyvsp[(1) - (4)].ivalue)) {
+ Swig_name_rename_add(Namespaceprefix, nname,decl,kws,(yyvsp[(2) - (4)].decl).parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
+ }
+ Delete(nname);
+ } else {
+ if ((yyvsp[(1) - (4)].ivalue)) {
+ Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,(yyvsp[(2) - (4)].decl).parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
+ }
+ }
+ Delete(decl);
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",fixname);
+ if ((yyvsp[(1) - (4)].ivalue)) {
+ Swig_name_rename_add(Namespaceprefix,(nname),0,kws,(yyvsp[(2) - (4)].decl).parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
+ }
+ Delete(nname);
+ }
+ } else {
+ if ((yyvsp[(1) - (4)].ivalue)) {
+ Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,(yyvsp[(2) - (4)].decl).parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
+ }
+ }
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 80:
+#line 2274 "parser.y"
+ {
+ String *fixname;
+ Hash *kws = (yyvsp[(3) - (7)].node);
+ SwigType *t = (yyvsp[(5) - (7)].decl).type;
+ fixname = feature_identifier_fix((yyvsp[(5) - (7)].decl).id);
+ if (!Len(t)) t = 0;
+ /* Special declarator check */
+ if (t) {
+ if ((yyvsp[(6) - (7)].dtype).qualifier) SwigType_push(t,(yyvsp[(6) - (7)].dtype).qualifier);
+ if (SwigType_isfunction(t)) {
+ SwigType *decl = SwigType_pop_function(t);
+ if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",fixname);
+ if ((yyvsp[(1) - (7)].ivalue)) {
+ Swig_name_rename_add(Namespaceprefix, nname,decl,kws,(yyvsp[(5) - (7)].decl).parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
+ }
+ Delete(nname);
+ } else {
+ if ((yyvsp[(1) - (7)].ivalue)) {
+ Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,(yyvsp[(5) - (7)].decl).parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
+ }
+ }
+ Delete(decl);
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",fixname);
+ if ((yyvsp[(1) - (7)].ivalue)) {
+ Swig_name_rename_add(Namespaceprefix,(nname),0,kws,(yyvsp[(5) - (7)].decl).parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
+ }
+ Delete(nname);
+ }
+ } else {
+ if ((yyvsp[(1) - (7)].ivalue)) {
+ Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,(yyvsp[(5) - (7)].decl).parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
+ }
+ }
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 81:
+#line 2320 "parser.y"
+ {
+ if ((yyvsp[(1) - (6)].ivalue)) {
+ Swig_name_rename_add(Namespaceprefix,(yyvsp[(5) - (6)].id),0,(yyvsp[(3) - (6)].node),0);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(yyvsp[(5) - (6)].id),0,(yyvsp[(3) - (6)].node));
+ }
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 82:
+#line 2331 "parser.y"
+ {
+ (yyval.ivalue) = 1;
+ }
+ break;
+
+ case 83:
+#line 2334 "parser.y"
+ {
+ (yyval.ivalue) = 0;
+ }
+ break;
+
+ case 84:
+#line 2361 "parser.y"
+ {
+ String *val = (yyvsp[(7) - (7)].str) ? NewString((yyvsp[(7) - (7)].str)) : NewString("1");
+ new_feature((yyvsp[(3) - (7)].id), val, 0, (yyvsp[(5) - (7)].decl).id, (yyvsp[(5) - (7)].decl).type, (yyvsp[(5) - (7)].decl).parms, (yyvsp[(6) - (7)].dtype).qualifier);
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 85:
+#line 2367 "parser.y"
+ {
+ String *val = Len((yyvsp[(5) - (9)].id)) ? NewString((yyvsp[(5) - (9)].id)) : 0;
+ new_feature((yyvsp[(3) - (9)].id), val, 0, (yyvsp[(7) - (9)].decl).id, (yyvsp[(7) - (9)].decl).type, (yyvsp[(7) - (9)].decl).parms, (yyvsp[(8) - (9)].dtype).qualifier);
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 86:
+#line 2373 "parser.y"
+ {
+ String *val = (yyvsp[(8) - (8)].str) ? NewString((yyvsp[(8) - (8)].str)) : NewString("1");
+ new_feature((yyvsp[(3) - (8)].id), val, (yyvsp[(4) - (8)].node), (yyvsp[(6) - (8)].decl).id, (yyvsp[(6) - (8)].decl).type, (yyvsp[(6) - (8)].decl).parms, (yyvsp[(7) - (8)].dtype).qualifier);
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 87:
+#line 2379 "parser.y"
+ {
+ String *val = Len((yyvsp[(5) - (10)].id)) ? NewString((yyvsp[(5) - (10)].id)) : 0;
+ new_feature((yyvsp[(3) - (10)].id), val, (yyvsp[(6) - (10)].node), (yyvsp[(8) - (10)].decl).id, (yyvsp[(8) - (10)].decl).type, (yyvsp[(8) - (10)].decl).parms, (yyvsp[(9) - (10)].dtype).qualifier);
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 88:
+#line 2387 "parser.y"
+ {
+ String *val = (yyvsp[(5) - (5)].str) ? NewString((yyvsp[(5) - (5)].str)) : NewString("1");
+ new_feature((yyvsp[(3) - (5)].id), val, 0, 0, 0, 0, 0);
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 89:
+#line 2393 "parser.y"
+ {
+ String *val = Len((yyvsp[(5) - (7)].id)) ? NewString((yyvsp[(5) - (7)].id)) : 0;
+ new_feature((yyvsp[(3) - (7)].id), val, 0, 0, 0, 0, 0);
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 90:
+#line 2399 "parser.y"
+ {
+ String *val = (yyvsp[(6) - (6)].str) ? NewString((yyvsp[(6) - (6)].str)) : NewString("1");
+ new_feature((yyvsp[(3) - (6)].id), val, (yyvsp[(4) - (6)].node), 0, 0, 0, 0);
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 91:
+#line 2405 "parser.y"
+ {
+ String *val = Len((yyvsp[(5) - (8)].id)) ? NewString((yyvsp[(5) - (8)].id)) : 0;
+ new_feature((yyvsp[(3) - (8)].id), val, (yyvsp[(6) - (8)].node), 0, 0, 0, 0);
+ (yyval.node) = 0;
+ scanner_clear_rename();
+ }
+ break;
+
+ case 92:
+#line 2413 "parser.y"
+ { (yyval.str) = (yyvsp[(1) - (1)].str); }
+ break;
+
+ case 93:
+#line 2414 "parser.y"
+ { (yyval.str) = 0; }
+ break;
+
+ case 94:
+#line 2415 "parser.y"
+ { (yyval.str) = (yyvsp[(3) - (5)].pl); }
+ break;
+
+ case 95:
+#line 2418 "parser.y"
+ {
+ (yyval.node) = NewHash();
+ Setattr((yyval.node),"name",(yyvsp[(2) - (4)].id));
+ Setattr((yyval.node),"value",(yyvsp[(4) - (4)].id));
+ }
+ break;
+
+ case 96:
+#line 2423 "parser.y"
+ {
+ (yyval.node) = NewHash();
+ Setattr((yyval.node),"name",(yyvsp[(2) - (5)].id));
+ Setattr((yyval.node),"value",(yyvsp[(4) - (5)].id));
+ set_nextSibling((yyval.node),(yyvsp[(5) - (5)].node));
+ }
+ break;
+
+ case 97:
+#line 2433 "parser.y"
+ {
+ Parm *val;
+ String *name;
+ SwigType *t;
+ if (Namespaceprefix) name = NewStringf("%s::%s", Namespaceprefix, (yyvsp[(5) - (7)].decl).id);
+ else name = NewString((yyvsp[(5) - (7)].decl).id);
+ val = (yyvsp[(3) - (7)].pl);
+ if ((yyvsp[(5) - (7)].decl).parms) {
+ Setmeta(val,"parms",(yyvsp[(5) - (7)].decl).parms);
+ }
+ t = (yyvsp[(5) - (7)].decl).type;
+ if (!Len(t)) t = 0;
+ if (t) {
+ if ((yyvsp[(6) - (7)].dtype).qualifier) SwigType_push(t,(yyvsp[(6) - (7)].dtype).qualifier);
+ if (SwigType_isfunction(t)) {
+ SwigType *decl = SwigType_pop_function(t);
+ if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(Swig_cparse_features(), nname, decl, "feature:varargs", val, 0);
+ Delete(nname);
+ } else {
+ Swig_feature_set(Swig_cparse_features(), name, decl, "feature:varargs", val, 0);
+ }
+ Delete(decl);
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(Swig_cparse_features(),nname,0,"feature:varargs",val, 0);
+ Delete(nname);
+ }
+ } else {
+ Swig_feature_set(Swig_cparse_features(),name,0,"feature:varargs",val, 0);
+ }
+ Delete(name);
+ (yyval.node) = 0;
+ }
+ break;
+
+ case 98:
+#line 2469 "parser.y"
+ { (yyval.pl) = (yyvsp[(1) - (1)].pl); }
+ break;
+
+ case 99:
+#line 2470 "parser.y"
+ {
+ int i;
+ int n;
+ Parm *p;
+ n = atoi(Char((yyvsp[(1) - (3)].dtype).val));
+ if (n <= 0) {
+ Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n");
+ (yyval.pl) = 0;
+ } else {
+ (yyval.pl) = Copy((yyvsp[(3) - (3)].p));
+ Setattr((yyval.pl),"name","VARARGS_SENTINEL");
+ for (i = 0; i < n; i++) {
+ p = Copy((yyvsp[(3) - (3)].p));
+ set_nextSibling(p,(yyval.pl));
+ Delete((yyval.pl));
+ (yyval.pl) = p;
+ }
+ }
+ }
+ break;
+
+ case 100:
+#line 2500 "parser.y"
+ {
+ (yyval.node) = 0;
+ if ((yyvsp[(3) - (6)].tmap).method) {
+ String *code = 0;
+ (yyval.node) = new_node("typemap");
+ Setattr((yyval.node),"method",(yyvsp[(3) - (6)].tmap).method);
+ if ((yyvsp[(3) - (6)].tmap).kwargs) {
+ ParmList *kw = (yyvsp[(3) - (6)].tmap).kwargs;
+ code = remove_block(kw, (yyvsp[(6) - (6)].str));
+ Setattr((yyval.node),"kwargs", (yyvsp[(3) - (6)].tmap).kwargs);
+ }
+ code = code ? code : NewString((yyvsp[(6) - (6)].str));
+ Setattr((yyval.node),"code", code);
+ Delete(code);
+ appendChild((yyval.node),(yyvsp[(5) - (6)].p));
+ }
+ }
+ break;
+
+ case 101:
+#line 2517 "parser.y"
+ {
+ (yyval.node) = 0;
+ if ((yyvsp[(3) - (6)].tmap).method) {
+ (yyval.node) = new_node("typemap");
+ Setattr((yyval.node),"method",(yyvsp[(3) - (6)].tmap).method);
+ appendChild((yyval.node),(yyvsp[(5) - (6)].p));
+ }
+ }
+ break;
+
+ case 102:
+#line 2525 "parser.y"
+ {
+ (yyval.node) = 0;
+ if ((yyvsp[(3) - (8)].tmap).method) {
+ (yyval.node) = new_node("typemapcopy");
+ Setattr((yyval.node),"method",(yyvsp[(3) - (8)].tmap).method);
+ Setattr((yyval.node),"pattern", Getattr((yyvsp[(7) - (8)].p),"pattern"));
+ appendChild((yyval.node),(yyvsp[(5) - (8)].p));
+ }
+ }
+ break;
+
+ case 103:
+#line 2538 "parser.y"
+ {
+ Hash *p;
+ String *name;
+ p = nextSibling((yyvsp[(1) - (1)].node));
+ if (p && (!Getattr(p,"value"))) {
+ /* this is the deprecated two argument typemap form */
+ Swig_warning(WARN_DEPRECATED_TYPEMAP_LANG,cparse_file, cparse_line,
+ "Specifying the language name in %%typemap is deprecated - use #ifdef SWIG<LANG> instead.\n");
+ /* two argument typemap form */
+ name = Getattr((yyvsp[(1) - (1)].node),"name");
+ if (!name || (Strcmp(name,typemap_lang))) {
+ (yyval.tmap).method = 0;
+ (yyval.tmap).kwargs = 0;
+ } else {
+ (yyval.tmap).method = Getattr(p,"name");
+ (yyval.tmap).kwargs = nextSibling(p);
+ }
+ } else {
+ /* one-argument typemap-form */
+ (yyval.tmap).method = Getattr((yyvsp[(1) - (1)].node),"name");
+ (yyval.tmap).kwargs = p;
+ }
+ }
+ break;
+
+ case 104:
+#line 2563 "parser.y"
+ {
+ (yyval.p) = (yyvsp[(1) - (2)].p);
+ set_nextSibling((yyval.p),(yyvsp[(2) - (2)].p));
+ }
+ break;
+
+ case 105:
+#line 2569 "parser.y"
+ {
+ (yyval.p) = (yyvsp[(2) - (3)].p);
+ set_nextSibling((yyval.p),(yyvsp[(3) - (3)].p));
+ }
+ break;
+
+ case 106:
+#line 2573 "parser.y"
+ { (yyval.p) = 0;}
+ break;
+
+ case 107:
+#line 2576 "parser.y"
+ {
+ Parm *parm;
+ SwigType_push((yyvsp[(1) - (2)].type),(yyvsp[(2) - (2)].decl).type);
+ (yyval.p) = new_node("typemapitem");
+ parm = NewParm((yyvsp[(1) - (2)].type),(yyvsp[(2) - (2)].decl).id);
+ Setattr((yyval.p),"pattern",parm);
+ Setattr((yyval.p),"parms", (yyvsp[(2) - (2)].decl).parms);
+ Delete(parm);
+ /* $$ = NewParm($1,$2.id);
+ Setattr($$,"parms",$2.parms); */
+ }
+ break;
+
+ case 108:
+#line 2587 "parser.y"
+ {
+ (yyval.p) = new_node("typemapitem");
+ Setattr((yyval.p),"pattern",(yyvsp[(2) - (3)].pl));
+ /* Setattr($$,"multitype",$2); */
+ }
+ break;
+
+ case 109:
+#line 2592 "parser.y"
+ {
+ (yyval.p) = new_node("typemapitem");
+ Setattr((yyval.p),"pattern", (yyvsp[(2) - (6)].pl));
+ /* Setattr($$,"multitype",$2); */
+ Setattr((yyval.p),"parms",(yyvsp[(5) - (6)].pl));
+ }
+ break;
+
+ case 110:
+#line 2605 "parser.y"
+ {
+ (yyval.node) = new_node("types");
+ Setattr((yyval.node),"parms",(yyvsp[(3) - (5)].pl));
+ if ((yyvsp[(5) - (5)].str))
+ Setattr((yyval.node),"convcode",NewString((yyvsp[(5) - (5)].str)));
+ }
+ break;
+
+ case 111:
+#line 2617 "parser.y"
+ {
+ Parm *p, *tp;
+ Node *n;
+ Node *tnode = 0;
+ Symtab *tscope = 0;
+ int specialized = 0;
+
+ (yyval.node) = 0;
+
+ tscope = Swig_symbol_current(); /* Get the current scope */
+
+ /* If the class name is qualified, we need to create or lookup namespace entries */
+ if (!inclass) {
+ (yyvsp[(5) - (9)].str) = resolve_node_scope((yyvsp[(5) - (9)].str));
+ }
+
+ /*
+ We use the new namespace entry 'nscope' only to
+ emit the template node. The template parameters are
+ resolved in the current 'tscope'.
+
+ This is closer to the C++ (typedef) behavior.
+ */
+ n = Swig_cparse_template_locate((yyvsp[(5) - (9)].str),(yyvsp[(7) - (9)].p),tscope);
+
+ /* Patch the argument types to respect namespaces */
+ p = (yyvsp[(7) - (9)].p);
+ while (p) {
+ SwigType *value = Getattr(p,"value");
+ if (!value) {
+ SwigType *ty = Getattr(p,"type");
+ if (ty) {
+ SwigType *rty = 0;
+ int reduce = template_reduce;
+ if (reduce || !SwigType_ispointer(ty)) {
+ rty = Swig_symbol_typedef_reduce(ty,tscope);
+ if (!reduce) reduce = SwigType_ispointer(rty);
+ }
+ ty = reduce ? Swig_symbol_type_qualify(rty,tscope) : Swig_symbol_type_qualify(ty,tscope);
+ Setattr(p,"type",ty);
+ Delete(ty);
+ Delete(rty);
+ }
+ } else {
+ value = Swig_symbol_type_qualify(value,tscope);
+ Setattr(p,"value",value);
+ Delete(value);
+ }
+
+ p = nextSibling(p);
+ }
+
+ /* Look for the template */
+ {
+ Node *nn = n;
+ Node *linklistend = 0;
+ while (nn) {
+ Node *templnode = 0;
+ if (Strcmp(nodeType(nn),"template") == 0) {
+ int nnisclass = (Strcmp(Getattr(nn,"templatetype"),"class") == 0); /* if not a templated class it is a templated function */
+ Parm *tparms = Getattr(nn,"templateparms");
+ if (!tparms) {
+ specialized = 1;
+ }
+ if (nnisclass && !specialized && ((ParmList_len((yyvsp[(7) - (9)].p)) > ParmList_len(tparms)))) {
+ Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms));
+ } else if (nnisclass && !specialized && ((ParmList_len((yyvsp[(7) - (9)].p)) < ParmList_numrequired(tparms)))) {
+ Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", ParmList_numrequired(tparms));
+ } else if (!nnisclass && ((ParmList_len((yyvsp[(7) - (9)].p)) != ParmList_len(tparms)))) {
+ /* must be an overloaded templated method - ignore it as it is overloaded with a different number of template parameters */
+ nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions */
+ continue;
+ } else {
+ String *tname = Copy((yyvsp[(5) - (9)].str));
+ int def_supplied = 0;
+ /* Expand the template */
+ Node *templ = Swig_symbol_clookup((yyvsp[(5) - (9)].str),0);
+ Parm *targs = templ ? Getattr(templ,"templateparms") : 0;
+
+ ParmList *temparms;
+ if (specialized) temparms = CopyParmList((yyvsp[(7) - (9)].p));
+ else temparms = CopyParmList(tparms);
+
+ /* Create typedef's and arguments */
+ p = (yyvsp[(7) - (9)].p);
+ tp = temparms;
+ if (!p && ParmList_len(p) != ParmList_len(temparms)) {
+ /* we have no template parameters supplied in %template for a template that has default args*/
+ p = tp;
+ def_supplied = 1;
+ }
+
+ 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");
+ }
+ /* fix default arg values */
+ if (targs) {
+ Parm *pi = temparms;
+ Parm *ti = targs;
+ String *tv = Getattr(tp,"value");
+ if (!tv) tv = Getattr(tp,"type");
+ while(pi != tp && ti && pi) {
+ String *name = Getattr(ti,"name");
+ String *value = Getattr(pi,"value");
+ if (!value) value = Getattr(pi,"type");
+ Replaceid(tv, name, value);
+ pi = nextSibling(pi);
+ ti = nextSibling(ti);
+ }
+ }
+ p = nextSibling(p);
+ tp = nextSibling(tp);
+ if (!p && tp) {
+ p = tp;
+ def_supplied = 1;
+ }
+ }
+
+ templnode = copy_node(nn);
+ /* We need to set the node name based on name used to instantiate */
+ Setattr(templnode,"name",tname);
+ Delete(tname);
+ if (!specialized) {
+ Delattr(templnode,"sym:typename");
+ } else {
+ Setattr(templnode,"sym:typename","1");
+ }
+ if ((yyvsp[(3) - (9)].id)) {
+ /*
+ Comment this out for 1.3.28. We need to
+ re-enable it later but first we need to
+ move %ignore from using %rename to use
+ %feature(ignore).
+
+ String *symname = Swig_name_make(templnode,0,$3,0,0);
+ */
+ String *symname = (yyvsp[(3) - (9)].id);
+ Swig_cparse_template_expand(templnode,symname,temparms,tscope);
+ Setattr(templnode,"sym:name",symname);
+ } else {
+ static int cnt = 0;
+ String *nname = NewStringf("__dummy_%d__", cnt++);
+ Swig_cparse_template_expand(templnode,nname,temparms,tscope);
+ Setattr(templnode,"sym:name",nname);
+ Delete(nname);
+ Setattr(templnode,"feature:onlychildren",
+ "typemap,typemapitem,typemapcopy,typedef,types,fragment");
+ }
+ Delattr(templnode,"templatetype");
+ Setattr(templnode,"template",nn);
+ tnode = templnode;
+ Setfile(templnode,cparse_file);
+ Setline(templnode,cparse_line);
+ Delete(temparms);
+
+ add_symbols_copy(templnode);
+
+ if (Strcmp(nodeType(templnode),"class") == 0) {
+
+ /* Identify pure abstract methods */
+ Setattr(templnode,"abstract", pure_abstract(firstChild(templnode)));
+
+ /* Set up inheritance in symbol table */
+ {
+ Symtab *csyms;
+ List *baselist = Getattr(templnode,"baselist");
+ csyms = Swig_symbol_current();
+ Swig_symbol_setscope(Getattr(templnode,"symtab"));
+ if (baselist) {
+ List *bases = make_inherit_list(Getattr(templnode,"name"),baselist);
+ if (bases) {
+ Iterator s;
+ for (s = First(bases); s.item; s = Next(s)) {
+ Symtab *st = Getattr(s.item,"symtab");
+ if (st) {
+ Setfile(st,Getfile(s.item));
+ Setline(st,Getline(s.item));
+ Swig_symbol_inherit(st);
+ }
+ }
+ Delete(bases);
+ }
+ }
+ 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 *stmp = 0;
+ String *clsname;
+ Node *am;
+ if (Namespaceprefix) {
+ clsname = stmp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
+ } else {
+ clsname = Getattr(templnode,"name");
+ }
+ am = Getattr(extendhash,clsname);
+ if (am) {
+ Symtab *st = Swig_symbol_current();
+ Swig_symbol_setscope(Getattr(templnode,"symtab"));
+ /* Printf(stdout,"%s: %s %x %x\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */
+ merge_extensions(templnode,am);
+ Swig_symbol_setscope(st);
+ append_previous_extension(templnode,am);
+ Delattr(extendhash,clsname);
+ }
+ if (stmp) Delete(stmp);
+ }
+ /* Add to classes hash */
+ if (!classes) classes = NewHash();
+
+ {
+ if (Namespaceprefix) {
+ String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
+ Setattr(classes,temp,templnode);
+ Delete(temp);
+ } else {
+ String *qs = Swig_symbol_qualifiedscopename(templnode);
+ Setattr(classes, qs,templnode);
+ Delete(qs);
+ }
+ }
+ }
+ }
+
+ /* all the overloaded templated functions are added into a linked list */
+ if (nscope_inner) {
+ /* non-global namespace */
+ if (templnode) {
+ appendChild(nscope_inner,templnode);
+ Delete(templnode);
+ if (nscope) (yyval.node) = nscope;
+ }
+ } else {
+ /* global namespace */
+ if (!linklistend) {
+ (yyval.node) = templnode;
+ } else {
+ set_nextSibling(linklistend,templnode);
+ Delete(templnode);
+ }
+ linklistend = templnode;
+ }
+ }
+ nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions. If a templated class there will never be a sibling. */
+ }
+ }
+ Swig_symbol_setscope(tscope);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+ break;
+
+ case 112:
+#line 2890 "parser.y"
+ {
+ Swig_warning(0,cparse_file, cparse_line,"%s\n", (yyvsp[(2) - (2)].id));
+ (yyval.node) = 0;
+ }
+ break;
+
+ case 113:
+#line 2900 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ if ((yyval.node)) {
+ add_symbols((yyval.node));
+ default_arguments((yyval.node));
+ }
+ }
+ break;
+
+ case 114:
+#line 2907 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 115:
+#line 2908 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 116:
+#line 2912 "parser.y"
+ {
+ if (Strcmp((yyvsp[(2) - (3)].id),"C") == 0) {
+ cparse_externc = 1;
+ }
+ }
+ break;
+
+ case 117:
+#line 2916 "parser.y"
+ {
+ cparse_externc = 0;
+ if (Strcmp((yyvsp[(2) - (6)].id),"C") == 0) {
+ Node *n = firstChild((yyvsp[(5) - (6)].node));
+ (yyval.node) = new_node("extern");
+ Setattr((yyval.node),"name",(yyvsp[(2) - (6)].id));
+ appendChild((yyval.node),n);
+ while (n) {
+ SwigType *decl = Getattr(n,"decl");
+ if (SwigType_isfunction(decl)) {
+ Setattr(n,"storage","externc");
+ }
+ n = nextSibling(n);
+ }
+ } else {
+ Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", (yyvsp[(2) - (6)].id));
+ (yyval.node) = new_node("extern");
+ Setattr((yyval.node),"name",(yyvsp[(2) - (6)].id));
+ appendChild((yyval.node),firstChild((yyvsp[(5) - (6)].node)));
+ }
+ }
+ break;
+
+ case 118:
+#line 2943 "parser.y"
+ {
+ (yyval.node) = new_node("cdecl");
+ if ((yyvsp[(4) - (5)].dtype).qualifier) SwigType_push((yyvsp[(3) - (5)].decl).type,(yyvsp[(4) - (5)].dtype).qualifier);
+ Setattr((yyval.node),"type",(yyvsp[(2) - (5)].type));
+ Setattr((yyval.node),"storage",(yyvsp[(1) - (5)].id));
+ Setattr((yyval.node),"name",(yyvsp[(3) - (5)].decl).id);
+ Setattr((yyval.node),"decl",(yyvsp[(3) - (5)].decl).type);
+ Setattr((yyval.node),"parms",(yyvsp[(3) - (5)].decl).parms);
+ Setattr((yyval.node),"value",(yyvsp[(4) - (5)].dtype).val);
+ Setattr((yyval.node),"throws",(yyvsp[(4) - (5)].dtype).throws);
+ Setattr((yyval.node),"throw",(yyvsp[(4) - (5)].dtype).throwf);
+ if (!(yyvsp[(5) - (5)].node)) {
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr((yyval.node),"code",code);
+ Delete(code);
+ }
+ } else {
+ Node *n = (yyvsp[(5) - (5)].node);
+ /* Inherit attributes */
+ while (n) {
+ String *type = Copy((yyvsp[(2) - (5)].type));
+ Setattr(n,"type",type);
+ Setattr(n,"storage",(yyvsp[(1) - (5)].id));
+ n = nextSibling(n);
+ Delete(type);
+ }
+ }
+ if ((yyvsp[(4) - (5)].dtype).bitfield) {
+ Setattr((yyval.node),"bitfield", (yyvsp[(4) - (5)].dtype).bitfield);
+ }
+
+ /* Look for "::" declarations (ignored) */
+ if (Strstr((yyvsp[(3) - (5)].decl).id,"::")) {
+ /* This is a special case. If the scope name of the declaration exactly
+ matches that of the declaration, then we will allow it. Otherwise, delete. */
+ String *p = Swig_scopename_prefix((yyvsp[(3) - (5)].decl).id);
+ if (p) {
+ if ((Namespaceprefix && Strcmp(p,Namespaceprefix) == 0) ||
+ (inclass && Strcmp(p,Classprefix) == 0)) {
+ String *lstr = Swig_scopename_last((yyvsp[(3) - (5)].decl).id);
+ Setattr((yyval.node),"name",lstr);
+ Delete(lstr);
+ set_nextSibling((yyval.node),(yyvsp[(5) - (5)].node));
+ } else {
+ Delete((yyval.node));
+ (yyval.node) = (yyvsp[(5) - (5)].node);
+ }
+ Delete(p);
+ } else {
+ Delete((yyval.node));
+ (yyval.node) = (yyvsp[(5) - (5)].node);
+ }
+ } else {
+ set_nextSibling((yyval.node),(yyvsp[(5) - (5)].node));
+ }
+ }
+ break;
+
+ case 119:
+#line 3004 "parser.y"
+ {
+ (yyval.node) = 0;
+ Clear(scanner_ccode);
+ }
+ break;
+
+ case 120:
+#line 3008 "parser.y"
+ {
+ (yyval.node) = new_node("cdecl");
+ if ((yyvsp[(3) - (4)].dtype).qualifier) SwigType_push((yyvsp[(2) - (4)].decl).type,(yyvsp[(3) - (4)].dtype).qualifier);
+ Setattr((yyval.node),"name",(yyvsp[(2) - (4)].decl).id);
+ Setattr((yyval.node),"decl",(yyvsp[(2) - (4)].decl).type);
+ Setattr((yyval.node),"parms",(yyvsp[(2) - (4)].decl).parms);
+ Setattr((yyval.node),"value",(yyvsp[(3) - (4)].dtype).val);
+ Setattr((yyval.node),"throws",(yyvsp[(3) - (4)].dtype).throws);
+ Setattr((yyval.node),"throw",(yyvsp[(3) - (4)].dtype).throwf);
+ if ((yyvsp[(3) - (4)].dtype).bitfield) {
+ Setattr((yyval.node),"bitfield", (yyvsp[(3) - (4)].dtype).bitfield);
+ }
+ if (!(yyvsp[(4) - (4)].node)) {
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr((yyval.node),"code",code);
+ Delete(code);
+ }
+ } else {
+ set_nextSibling((yyval.node),(yyvsp[(4) - (4)].node));
+ }
+ }
+ break;
+
+ case 121:
+#line 3030 "parser.y"
+ {
+ skip_balanced('{','}');
+ (yyval.node) = 0;
+ }
+ break;
+
+ case 122:
+#line 3036 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(1) - (1)].dtype);
+ (yyval.dtype).qualifier = 0;
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ }
+ break;
+
+ case 123:
+#line 3042 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(2) - (2)].dtype);
+ (yyval.dtype).qualifier = (yyvsp[(1) - (2)].str);
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ }
+ break;
+
+ case 124:
+#line 3048 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(5) - (5)].dtype);
+ (yyval.dtype).qualifier = 0;
+ (yyval.dtype).throws = (yyvsp[(3) - (5)].pl);
+ (yyval.dtype).throwf = NewString("1");
+ }
+ break;
+
+ case 125:
+#line 3054 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(6) - (6)].dtype);
+ (yyval.dtype).qualifier = (yyvsp[(1) - (6)].str);
+ (yyval.dtype).throws = (yyvsp[(4) - (6)].pl);
+ (yyval.dtype).throwf = NewString("1");
+ }
+ break;
+
+ case 126:
+#line 3067 "parser.y"
+ {
+ SwigType *ty = 0;
+ (yyval.node) = new_node("enumforward");
+ ty = NewStringf("enum %s", (yyvsp[(3) - (4)].id));
+ Setattr((yyval.node),"name",(yyvsp[(3) - (4)].id));
+ Setattr((yyval.node),"type",ty);
+ Setattr((yyval.node),"sym:weak", "1");
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 127:
+#line 3082 "parser.y"
+ {
+ SwigType *ty = 0;
+ (yyval.node) = new_node("enum");
+ ty = NewStringf("enum %s", (yyvsp[(3) - (7)].id));
+ Setattr((yyval.node),"name",(yyvsp[(3) - (7)].id));
+ Setattr((yyval.node),"type",ty);
+ appendChild((yyval.node),(yyvsp[(5) - (7)].node));
+ add_symbols((yyval.node)); /* Add to tag space */
+ add_symbols((yyvsp[(5) - (7)].node)); /* Add enum values to id space */
+ }
+ break;
+
+ case 128:
+#line 3092 "parser.y"
+ {
+ Node *n;
+ SwigType *ty = 0;
+ String *unnamed = 0;
+ int unnamedinstance = 0;
+
+ (yyval.node) = new_node("enum");
+ if ((yyvsp[(3) - (8)].id)) {
+ Setattr((yyval.node),"name",(yyvsp[(3) - (8)].id));
+ ty = NewStringf("enum %s", (yyvsp[(3) - (8)].id));
+ } else if ((yyvsp[(7) - (8)].decl).id) {
+ unnamed = make_unnamed();
+ ty = NewStringf("enum %s", unnamed);
+ Setattr((yyval.node),"unnamed",unnamed);
+ /* name is not set for unnamed enum instances, e.g. enum { foo } Instance; */
+ if ((yyvsp[(1) - (8)].id) && Cmp((yyvsp[(1) - (8)].id),"typedef") == 0) {
+ Setattr((yyval.node),"name",(yyvsp[(7) - (8)].decl).id);
+ } else {
+ unnamedinstance = 1;
+ }
+ Setattr((yyval.node),"storage",(yyvsp[(1) - (8)].id));
+ }
+ if ((yyvsp[(7) - (8)].decl).id && Cmp((yyvsp[(1) - (8)].id),"typedef") == 0) {
+ Setattr((yyval.node),"tdname",(yyvsp[(7) - (8)].decl).id);
+ Setattr((yyval.node),"allows_typedef","1");
+ }
+ appendChild((yyval.node),(yyvsp[(5) - (8)].node));
+ n = new_node("cdecl");
+ Setattr(n,"type",ty);
+ Setattr(n,"name",(yyvsp[(7) - (8)].decl).id);
+ Setattr(n,"storage",(yyvsp[(1) - (8)].id));
+ Setattr(n,"decl",(yyvsp[(7) - (8)].decl).type);
+ Setattr(n,"parms",(yyvsp[(7) - (8)].decl).parms);
+ Setattr(n,"unnamed",unnamed);
+
+ if (unnamedinstance) {
+ SwigType *cty = NewString("enum ");
+ Setattr((yyval.node),"type",cty);
+ Setattr((yyval.node),"unnamedinstance","1");
+ Setattr(n,"unnamedinstance","1");
+ Delete(cty);
+ }
+ if ((yyvsp[(8) - (8)].node)) {
+ Node *p = (yyvsp[(8) - (8)].node);
+ set_nextSibling(n,p);
+ while (p) {
+ SwigType *cty = Copy(ty);
+ Setattr(p,"type",cty);
+ Setattr(p,"unnamed",unnamed);
+ Setattr(p,"storage",(yyvsp[(1) - (8)].id));
+ Delete(cty);
+ p = nextSibling(p);
+ }
+ } else {
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr(n,"code",code);
+ Delete(code);
+ }
+ }
+
+ /* Ensure that typedef enum ABC {foo} XYZ; uses XYZ for sym:name, like structs.
+ * Note that class_rename/yyrename are bit of a mess so used this simple approach to change the name. */
+ if ((yyvsp[(7) - (8)].decl).id && (yyvsp[(3) - (8)].id) && Cmp((yyvsp[(1) - (8)].id),"typedef") == 0) {
+ String *name = NewString((yyvsp[(7) - (8)].decl).id);
+ Setattr((yyval.node), "parser:makename", name);
+ Delete(name);
+ }
+
+ add_symbols((yyval.node)); /* Add enum to tag space */
+ set_nextSibling((yyval.node),n);
+ Delete(n);
+ add_symbols((yyvsp[(5) - (8)].node)); /* Add enum values to id space */
+ add_symbols(n);
+ Delete(unnamed);
+ }
+ break;
+
+ case 129:
+#line 3170 "parser.y"
+ {
+ /* This is a sick hack. If the ctor_end has parameters,
+ and the parms parameter only has 1 parameter, this
+ could be a declaration of the form:
+
+ type (id)(parms)
+
+ Otherwise it's an error. */
+ int err = 0;
+ (yyval.node) = 0;
+
+ if ((ParmList_len((yyvsp[(4) - (6)].pl)) == 1) && (!Swig_scopename_check((yyvsp[(2) - (6)].type)))) {
+ SwigType *ty = Getattr((yyvsp[(4) - (6)].pl),"type");
+ String *name = Getattr((yyvsp[(4) - (6)].pl),"name");
+ err = 1;
+ if (!name) {
+ (yyval.node) = new_node("cdecl");
+ Setattr((yyval.node),"type",(yyvsp[(2) - (6)].type));
+ Setattr((yyval.node),"storage",(yyvsp[(1) - (6)].id));
+ Setattr((yyval.node),"name",ty);
+
+ if ((yyvsp[(6) - (6)].decl).have_parms) {
+ SwigType *decl = NewStringEmpty();
+ SwigType_add_function(decl,(yyvsp[(6) - (6)].decl).parms);
+ Setattr((yyval.node),"decl",decl);
+ Setattr((yyval.node),"parms",(yyvsp[(6) - (6)].decl).parms);
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr((yyval.node),"code",code);
+ Delete(code);
+ }
+ }
+ if ((yyvsp[(6) - (6)].decl).defarg) {
+ Setattr((yyval.node),"value",(yyvsp[(6) - (6)].decl).defarg);
+ }
+ Setattr((yyval.node),"throws",(yyvsp[(6) - (6)].decl).throws);
+ Setattr((yyval.node),"throw",(yyvsp[(6) - (6)].decl).throwf);
+ err = 0;
+ }
+ }
+ if (err) {
+ Swig_error(cparse_file,cparse_line,"Syntax error in input(2).\n");
+ exit(1);
+ }
+ }
+ break;
+
+ case 130:
+#line 3221 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 131:
+#line 3222 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 132:
+#line 3223 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 133:
+#line 3224 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 134:
+#line 3225 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 135:
+#line 3226 "parser.y"
+ { (yyval.node) = 0; }
+ break;
+
+ case 136:
+#line 3232 "parser.y"
+ {
+ List *bases = 0;
+ Node *scope = 0;
+ (yyval.node) = new_node("class");
+ Setline((yyval.node),cparse_start_line);
+ Setattr((yyval.node),"kind",(yyvsp[(2) - (5)].id));
+ if ((yyvsp[(4) - (5)].bases)) {
+ Setattr((yyval.node),"baselist", Getattr((yyvsp[(4) - (5)].bases),"public"));
+ Setattr((yyval.node),"protectedbaselist", Getattr((yyvsp[(4) - (5)].bases),"protected"));
+ Setattr((yyval.node),"privatebaselist", Getattr((yyvsp[(4) - (5)].bases),"private"));
+ }
+ Setattr((yyval.node),"allows_typedef","1");
+
+ /* preserve the current scope */
+ prev_symtab = Swig_symbol_current();
+
+ /* If the class name is qualified. We need to create or lookup namespace/scope entries */
+ scope = resolve_node_scope((yyvsp[(3) - (5)].str));
+ Setfile(scope,cparse_file);
+ Setline(scope,cparse_line);
+ (yyvsp[(3) - (5)].str) = scope;
+
+ /* support for old nested classes "pseudo" support, such as:
+
+ %rename(Ala__Ola) Ala::Ola;
+ class Ala::Ola {
+ public:
+ Ola() {}
+ };
+
+ this should disappear when a proper implementation is added.
+ */
+ if (nscope_inner && Strcmp(nodeType(nscope_inner),"namespace") != 0) {
+ if (Namespaceprefix) {
+ String *name = NewStringf("%s::%s", Namespaceprefix, (yyvsp[(3) - (5)].str));
+ (yyvsp[(3) - (5)].str) = name;
+ Namespaceprefix = 0;
+ nscope_inner = 0;
+ }
+ }
+ Setattr((yyval.node),"name",(yyvsp[(3) - (5)].str));
+
+ Delete(class_rename);
+ class_rename = make_name((yyval.node),(yyvsp[(3) - (5)].str),0);
+ Classprefix = NewString((yyvsp[(3) - (5)].str));
+ /* Deal with inheritance */
+ if ((yyvsp[(4) - (5)].bases)) {
+ bases = make_inherit_list((yyvsp[(3) - (5)].str),Getattr((yyvsp[(4) - (5)].bases),"public"));
+ }
+ if (SwigType_istemplate((yyvsp[(3) - (5)].str))) {
+ String *fbase, *tbase, *prefix;
+ prefix = SwigType_templateprefix((yyvsp[(3) - (5)].str));
+ if (Namespaceprefix) {
+ fbase = NewStringf("%s::%s", Namespaceprefix,(yyvsp[(3) - (5)].str));
+ tbase = NewStringf("%s::%s", Namespaceprefix, prefix);
+ } else {
+ fbase = Copy((yyvsp[(3) - (5)].str));
+ tbase = Copy(prefix);
+ }
+ Swig_name_inherit(tbase,fbase);
+ Delete(fbase);
+ Delete(tbase);
+ Delete(prefix);
+ }
+ if (strcmp((yyvsp[(2) - (5)].id),"class") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else {
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ Swig_symbol_newscope();
+ Swig_symbol_setscopename((yyvsp[(3) - (5)].str));
+ if (bases) {
+ Iterator s;
+ for (s = First(bases); s.item; s = Next(s)) {
+ Symtab *st = Getattr(s.item,"symtab");
+ if (st) {
+ Setfile(st,Getfile(s.item));
+ Setline(st,Getline(s.item));
+ Swig_symbol_inherit(st);
+ }
+ }
+ Delete(bases);
+ }
+ Delete(Namespaceprefix);
+ 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) {
+ String *tpname = Copy(Getattr(tp,"name"));
+ Node *tn = new_node("templateparm");
+ Setattr(tn,"name",tpname);
+ Swig_symbol_cadd(tpname,tn);
+ tp = nextSibling(tp);
+ Delete(tpname);
+ }
+ }
+ if (class_level >= max_class_levels) {
+ if (!max_class_levels) {
+ max_class_levels = 16;
+ } else {
+ max_class_levels *= 2;
+ }
+ class_decl = (Node**) realloc(class_decl, sizeof(Node*) * max_class_levels);
+ if (!class_decl) {
+ Swig_error(cparse_file, cparse_line, "realloc() failed\n");
+ }
+ }
+ class_decl[class_level++] = (yyval.node);
+ inclass = 1;
+ }
+ break;
+
+ case 137:
+#line 3346 "parser.y"
+ {
+ Node *p;
+ SwigType *ty;
+ Symtab *cscope = prev_symtab;
+ Node *am = 0;
+ String *scpname = 0;
+ (yyval.node) = class_decl[--class_level];
+ inclass = 0;
+
+ /* Check for pure-abstract class */
+ Setattr((yyval.node),"abstract", pure_abstract((yyvsp[(7) - (9)].node)));
+
+ /* This bit of code merges in a previously defined %extend directive (if any) */
+
+ if (extendhash) {
+ String *clsname = Swig_symbol_qualifiedscopename(0);
+ am = Getattr(extendhash,clsname);
+ if (am) {
+ merge_extensions((yyval.node),am);
+ Delattr(extendhash,clsname);
+ }
+ Delete(clsname);
+ }
+ if (!classes) classes = NewHash();
+ scpname = Swig_symbol_qualifiedscopename(0);
+ Setattr(classes,scpname,(yyval.node));
+ Delete(scpname);
+
+ appendChild((yyval.node),(yyvsp[(7) - (9)].node));
+
+ if (am) append_previous_extension((yyval.node),am);
+
+ p = (yyvsp[(9) - (9)].node);
+ if (p) {
+ set_nextSibling((yyval.node),p);
+ }
+
+ if (cparse_cplusplus && !cparse_externc) {
+ ty = NewString((yyvsp[(3) - (9)].str));
+ } else {
+ ty = NewStringf("%s %s", (yyvsp[(2) - (9)].id),(yyvsp[(3) - (9)].str));
+ }
+ while (p) {
+ Setattr(p,"storage",(yyvsp[(1) - (9)].id));
+ Setattr(p,"type",ty);
+ p = nextSibling(p);
+ }
+ /* Dump nested classes */
+ {
+ String *name = (yyvsp[(3) - (9)].str);
+ if ((yyvsp[(9) - (9)].node)) {
+ SwigType *decltype = Getattr((yyvsp[(9) - (9)].node),"decl");
+ if (Cmp((yyvsp[(1) - (9)].id),"typedef") == 0) {
+ if (!decltype || !Len(decltype)) {
+ String *cname;
+ name = Getattr((yyvsp[(9) - (9)].node),"name");
+ cname = Copy(name);
+ Setattr((yyval.node),"tdname",cname);
+ Delete(cname);
+
+ /* Use typedef name as class name */
+ if (class_rename && (Strcmp(class_rename,(yyvsp[(3) - (9)].str)) == 0)) {
+ Delete(class_rename);
+ class_rename = NewString(name);
+ }
+ if (!Getattr(classes,name)) {
+ Setattr(classes,name,(yyval.node));
+ }
+ Setattr((yyval.node),"decl",decltype);
+ }
+ }
+ }
+ appendChild((yyval.node),dump_nested(Char(name)));
+ }
+
+ if (cplus_mode != CPLUS_PUBLIC) {
+ /* we 'open' the class at the end, to allow %template
+ to add new members */
+ Node *pa = new_node("access");
+ Setattr(pa,"kind","public");
+ cplus_mode = CPLUS_PUBLIC;
+ appendChild((yyval.node),pa);
+ Delete(pa);
+ }
+
+ Setattr((yyval.node),"symtab",Swig_symbol_popscope());
+
+ Classprefix = 0;
+ if (nscope_inner) {
+ /* this is tricky */
+ /* we add the declaration in the original namespace */
+ appendChild(nscope_inner,(yyval.node));
+ Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols((yyval.node));
+ if (nscope) (yyval.node) = nscope;
+ /* but the variable definition in the current scope */
+ Swig_symbol_setscope(cscope);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols((yyvsp[(9) - (9)].node));
+ } else {
+ Delete(yyrename);
+ yyrename = Copy(class_rename);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+
+ add_symbols((yyval.node));
+ add_symbols((yyvsp[(9) - (9)].node));
+ }
+ Swig_symbol_setscope(cscope);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+ break;
+
+ case 138:
+#line 3464 "parser.y"
+ {
+ String *unnamed;
+ unnamed = make_unnamed();
+ (yyval.node) = new_node("class");
+ Setline((yyval.node),cparse_start_line);
+ Setattr((yyval.node),"kind",(yyvsp[(2) - (3)].id));
+ Setattr((yyval.node),"storage",(yyvsp[(1) - (3)].id));
+ Setattr((yyval.node),"unnamed",unnamed);
+ Setattr((yyval.node),"allows_typedef","1");
+ Delete(class_rename);
+ class_rename = make_name((yyval.node),0,0);
+ if (strcmp((yyvsp[(2) - (3)].id),"class") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else {
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ Swig_symbol_newscope();
+ cparse_start_line = cparse_line;
+ if (class_level >= max_class_levels) {
+ if (!max_class_levels) {
+ max_class_levels = 16;
+ } else {
+ max_class_levels *= 2;
+ }
+ class_decl = (Node**) realloc(class_decl, sizeof(Node*) * max_class_levels);
+ if (!class_decl) {
+ Swig_error(cparse_file, cparse_line, "realloc() failed\n");
+ }
+ }
+ class_decl[class_level++] = (yyval.node);
+ inclass = 1;
+ Classprefix = NewStringEmpty();
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+ break;
+
+ case 139:
+#line 3498 "parser.y"
+ {
+ String *unnamed;
+ Node *n;
+ Classprefix = 0;
+ (yyval.node) = class_decl[--class_level];
+ inclass = 0;
+ unnamed = Getattr((yyval.node),"unnamed");
+
+ /* Check for pure-abstract class */
+ Setattr((yyval.node),"abstract", pure_abstract((yyvsp[(5) - (8)].node)));
+
+ n = new_node("cdecl");
+ Setattr(n,"name",(yyvsp[(7) - (8)].decl).id);
+ Setattr(n,"unnamed",unnamed);
+ Setattr(n,"type",unnamed);
+ Setattr(n,"decl",(yyvsp[(7) - (8)].decl).type);
+ Setattr(n,"parms",(yyvsp[(7) - (8)].decl).parms);
+ Setattr(n,"storage",(yyvsp[(1) - (8)].id));
+ if ((yyvsp[(8) - (8)].node)) {
+ Node *p = (yyvsp[(8) - (8)].node);
+ set_nextSibling(n,p);
+ while (p) {
+ String *type = Copy(unnamed);
+ Setattr(p,"name",(yyvsp[(7) - (8)].decl).id);
+ Setattr(p,"unnamed",unnamed);
+ Setattr(p,"type",type);
+ Delete(type);
+ Setattr(p,"storage",(yyvsp[(1) - (8)].id));
+ p = nextSibling(p);
+ }
+ }
+ set_nextSibling((yyval.node),n);
+ Delete(n);
+ {
+ /* If a proper typedef name was given, we'll use it to set the scope name */
+ String *name = 0;
+ if ((yyvsp[(1) - (8)].id) && (strcmp((yyvsp[(1) - (8)].id),"typedef") == 0)) {
+ if (!Len((yyvsp[(7) - (8)].decl).type)) {
+ String *scpname = 0;
+ name = (yyvsp[(7) - (8)].decl).id;
+ Setattr((yyval.node),"tdname",name);
+ Setattr((yyval.node),"name",name);
+ Swig_symbol_setscopename(name);
+
+ /* If a proper name was given, we use that as the typedef, not unnamed */
+ Clear(unnamed);
+ Append(unnamed, name);
+
+ n = nextSibling(n);
+ set_nextSibling((yyval.node),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((yyval.node),am);
+ append_previous_extension((yyval.node),am);
+ Delattr(extendhash,clsname);
+ }
+ Delete(clsname);
+ }
+ if (!classes) classes = NewHash();
+ scpname = Swig_symbol_qualifiedscopename(0);
+ Setattr(classes,scpname,(yyval.node));
+ Delete(scpname);
+ } else {
+ Swig_symbol_setscopename((char*)"<unnamed>");
+ }
+ }
+ appendChild((yyval.node),(yyvsp[(5) - (8)].node));
+ appendChild((yyval.node),dump_nested(Char(name)));
+ }
+ /* Pop the scope */
+ Setattr((yyval.node),"symtab",Swig_symbol_popscope());
+ if (class_rename) {
+ Delete(yyrename);
+ yyrename = NewString(class_rename);
+ }
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols((yyval.node));
+ add_symbols(n);
+ Delete(unnamed);
+ }
+ break;
+
+ case 140:
+#line 3586 "parser.y"
+ { (yyval.node) = 0; }
+ break;
+
+ case 141:
+#line 3587 "parser.y"
+ {
+ (yyval.node) = new_node("cdecl");
+ Setattr((yyval.node),"name",(yyvsp[(1) - (2)].decl).id);
+ Setattr((yyval.node),"decl",(yyvsp[(1) - (2)].decl).type);
+ Setattr((yyval.node),"parms",(yyvsp[(1) - (2)].decl).parms);
+ set_nextSibling((yyval.node),(yyvsp[(2) - (2)].node));
+ }
+ break;
+
+ case 142:
+#line 3599 "parser.y"
+ {
+ if ((yyvsp[(1) - (4)].id) && (Strcmp((yyvsp[(1) - (4)].id),"friend") == 0)) {
+ /* Ignore */
+ (yyval.node) = 0;
+ } else {
+ (yyval.node) = new_node("classforward");
+ Setfile((yyval.node),cparse_file);
+ Setline((yyval.node),cparse_line);
+ Setattr((yyval.node),"kind",(yyvsp[(2) - (4)].id));
+ Setattr((yyval.node),"name",(yyvsp[(3) - (4)].str));
+ Setattr((yyval.node),"sym:weak", "1");
+ add_symbols((yyval.node));
+ }
+ }
+ break;
+
+ case 143:
+#line 3619 "parser.y"
+ { template_parameters = (yyvsp[(3) - (4)].tparms); }
+ break;
+
+ case 144:
+#line 3619 "parser.y"
+ {
+ String *tname = 0;
+ int error = 0;
+
+ /* check if we get a namespace node with a class declaration, and retrieve the class */
+ Symtab *cscope = Swig_symbol_current();
+ Symtab *sti = 0;
+ Node *ntop = (yyvsp[(6) - (6)].node);
+ Node *ni = ntop;
+ SwigType *ntype = ni ? nodeType(ni) : 0;
+ while (ni && Strcmp(ntype,"namespace") == 0) {
+ sti = Getattr(ni,"symtab");
+ ni = firstChild(ni);
+ ntype = nodeType(ni);
+ }
+ if (sti) {
+ Swig_symbol_setscope(sti);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ (yyvsp[(6) - (6)].node) = ni;
+ }
+
+ template_parameters = 0;
+ (yyval.node) = (yyvsp[(6) - (6)].node);
+ if ((yyval.node)) tname = Getattr((yyval.node),"name");
+
+ /* Check if the class is a template specialization */
+ if (((yyval.node)) && (Strchr(tname,'<')) && (!is_operator(tname))) {
+ /* 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_WARN_NODE_BEGIN(tempn);
+ Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile((yyval.node)),Getline((yyval.node)),"Specialization of non-template '%s'.\n", tbase);
+ SWIG_WARN_NODE_END(tempn);
+ tempn = 0;
+ error = 1;
+ }
+ Delete(tbase);
+ }
+ Setattr((yyval.node),"specialization","1");
+ Setattr((yyval.node),"templatetype",nodeType((yyval.node)));
+ set_nodeType((yyval.node),"template");
+ /* Template partial specialization */
+ if (tempn && ((yyvsp[(3) - (6)].tparms)) && ((yyvsp[(6) - (6)].node))) {
+ List *tlist;
+ String *targs = SwigType_templateargs(tname);
+ tlist = SwigType_parmlist(targs);
+ /* Printf(stdout,"targs = '%s' %s\n", targs, tlist); */
+ if (!Getattr((yyval.node),"sym:weak")) {
+ Setattr((yyval.node),"sym:typename","1");
+ }
+
+ if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
+ Swig_error(Getfile((yyval.node)),Getline((yyval.node)),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
+
+ } else {
+
+ /* This code builds the argument list for the partial template
+ specialization. This is a little hairy, but the idea is as
+ follows:
+
+ $3 contains a list of arguments supplied for the template.
+ For example template<class T>.
+
+ tlist is a list of the specialization arguments--which may be
+ different. For example class<int,T>.
+
+ tp is a copy of the arguments in the original template definition.
+
+ The patching algorithm walks through the list of supplied
+ arguments ($3), finds the position in the specialization arguments
+ (tlist), and then patches the name in the argument list of the
+ original template.
+ */
+
+ {
+ String *pn;
+ Parm *p, *p1;
+ int i, nargs;
+ Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
+ nargs = Len(tlist);
+ p = (yyvsp[(3) - (6)].tparms);
+ while (p) {
+ for (i = 0; i < nargs; i++){
+ pn = Getattr(p,"name");
+ if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
+ int j;
+ Parm *p1 = tp;
+ for (j = 0; j < i; j++) {
+ p1 = nextSibling(p1);
+ }
+ Setattr(p1,"name",pn);
+ Setattr(p1,"partialarg","1");
+ }
+ }
+ p = nextSibling(p);
+ }
+ p1 = tp;
+ i = 0;
+ while (p1) {
+ if (!Getattr(p1,"partialarg")) {
+ Delattr(p1,"name");
+ Setattr(p1,"type", Getitem(tlist,i));
+ }
+ i++;
+ p1 = nextSibling(p1);
+ }
+ Setattr((yyval.node),"templateparms",tp);
+ Delete(tp);
+ }
+#if 0
+ /* Patch the parameter list */
+ if (tempn) {
+ Parm *p,*p1;
+ ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
+ p = (yyvsp[(3) - (6)].tparms);
+ p1 = tp;
+ while (p && p1) {
+ String *pn = Getattr(p,"name");
+ Printf(stdout,"pn = '%s'\n", pn);
+ if (pn) Setattr(p1,"name",pn);
+ else Delattr(p1,"name");
+ pn = Getattr(p,"type");
+ if (pn) Setattr(p1,"type",pn);
+ p = nextSibling(p);
+ p1 = nextSibling(p1);
+ }
+ Setattr((yyval.node),"templateparms",tp);
+ Delete(tp);
+ } else {
+ Setattr((yyval.node),"templateparms",(yyvsp[(3) - (6)].tparms));
+ }
+#endif
+ Delattr((yyval.node),"specialization");
+ Setattr((yyval.node),"partialspecialization","1");
+ /* Create a specialized name for matching */
+ {
+ Parm *p = (yyvsp[(3) - (6)].tparms);
+ String *fname = NewString(Getattr((yyval.node),"name"));
+ String *ffname = 0;
+
+ char tmp[32];
+ int i, ilen;
+ while (p) {
+ String *n = Getattr(p,"name");
+ if (!n) {
+ p = nextSibling(p);
+ continue;
+ }
+ ilen = Len(tlist);
+ for (i = 0; i < ilen; i++) {
+ if (Strstr(Getitem(tlist,i),n)) {
+ sprintf(tmp,"$%d",i+1);
+ Replaceid(fname,n,tmp);
+ }
+ }
+ p = nextSibling(p);
+ }
+ /* Patch argument names with typedef */
+ {
+ Iterator tt;
+ List *tparms = SwigType_parmlist(fname);
+ ffname = SwigType_templateprefix(fname);
+ Append(ffname,"<(");
+ for (tt = First(tparms); tt.item; ) {
+ SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0);
+ SwigType *ttr = Swig_symbol_type_qualify(rtt,0);
+ Append(ffname,ttr);
+ tt = Next(tt);
+ if (tt.item) Putc(',',ffname);
+ Delete(rtt);
+ Delete(ttr);
+ }
+ Delete(tparms);
+ Append(ffname,")>");
+ }
+ {
+ String *partials = Getattr(tempn,"partials");
+ if (!partials) {
+ partials = NewList();
+ Setattr(tempn,"partials",partials);
+ Delete(partials);
+ }
+ /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */
+ Append(partials,ffname);
+ }
+ Setattr((yyval.node),"partialargs",ffname);
+ Swig_symbol_cadd(ffname,(yyval.node));
+ }
+ }
+ Delete(tlist);
+ Delete(targs);
+ } else {
+ /* Need to resolve exact specialization name */
+ /* add default args from generic template */
+ String *ty = Swig_symbol_template_deftype(tname,0);
+ String *fname = Swig_symbol_type_qualify(ty,0);
+ Swig_symbol_cadd(fname,(yyval.node));
+ Delete(ty);
+ Delete(fname);
+ }
+ } else if ((yyval.node)) {
+ Setattr((yyval.node),"templatetype",nodeType((yyvsp[(6) - (6)].node)));
+ set_nodeType((yyval.node),"template");
+ Setattr((yyval.node),"templateparms", (yyvsp[(3) - (6)].tparms));
+ if (!Getattr((yyval.node),"sym:weak")) {
+ Setattr((yyval.node),"sym:typename","1");
+ }
+ add_symbols((yyval.node));
+ default_arguments((yyval.node));
+ /* We also place a fully parameterized version in the symbol table */
+ {
+ Parm *p;
+ String *fname = NewStringf("%s<(", Getattr((yyval.node),"name"));
+ p = (yyvsp[(3) - (6)].tparms);
+ while (p) {
+ String *n = Getattr(p,"name");
+ if (!n) n = Getattr(p,"type");
+ Append(fname,n);
+ p = nextSibling(p);
+ if (p) Putc(',',fname);
+ }
+ Append(fname,")>");
+ Swig_symbol_cadd(fname,(yyval.node));
+ }
+ }
+ (yyval.node) = ntop;
+ Swig_symbol_setscope(cscope);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ if (error) (yyval.node) = 0;
+ }
+ break;
+
+ case 145:
+#line 3854 "parser.y"
+ {
+ Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
+ (yyval.node) = 0;
+ }
+ break;
+
+ case 146:
+#line 3860 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ }
+ break;
+
+ case 147:
+#line 3863 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ }
+ break;
+
+ case 148:
+#line 3866 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ }
+ break;
+
+ case 149:
+#line 3869 "parser.y"
+ {
+ (yyval.node) = 0;
+ }
+ break;
+
+ case 150:
+#line 3872 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ }
+ break;
+
+ case 151:
+#line 3875 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ }
+ break;
+
+ case 152:
+#line 3880 "parser.y"
+ {
+ /* Rip out the parameter names */
+ Parm *p = (yyvsp[(1) - (1)].pl);
+ (yyval.tparms) = (yyvsp[(1) - (1)].pl);
+
+ 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);
+ }
+ }
+ break;
+
+ case 153:
+#line 3910 "parser.y"
+ {
+ set_nextSibling((yyvsp[(1) - (2)].p),(yyvsp[(2) - (2)].pl));
+ (yyval.pl) = (yyvsp[(1) - (2)].p);
+ }
+ break;
+
+ case 154:
+#line 3914 "parser.y"
+ { (yyval.pl) = 0; }
+ break;
+
+ case 155:
+#line 3917 "parser.y"
+ {
+ (yyval.p) = NewParm(NewString((yyvsp[(1) - (1)].id)), 0);
+ }
+ break;
+
+ case 156:
+#line 3920 "parser.y"
+ {
+ (yyval.p) = (yyvsp[(1) - (1)].p);
+ }
+ break;
+
+ case 157:
+#line 3925 "parser.y"
+ {
+ set_nextSibling((yyvsp[(2) - (3)].p),(yyvsp[(3) - (3)].pl));
+ (yyval.pl) = (yyvsp[(2) - (3)].p);
+ }
+ break;
+
+ case 158:
+#line 3929 "parser.y"
+ { (yyval.pl) = 0; }
+ break;
+
+ case 159:
+#line 3934 "parser.y"
+ {
+ String *uname = Swig_symbol_type_qualify((yyvsp[(2) - (3)].str),0);
+ String *name = Swig_scopename_last((yyvsp[(2) - (3)].str));
+ (yyval.node) = new_node("using");
+ Setattr((yyval.node),"uname",uname);
+ Setattr((yyval.node),"name", name);
+ Delete(uname);
+ Delete(name);
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 160:
+#line 3944 "parser.y"
+ {
+ Node *n = Swig_symbol_clookup((yyvsp[(3) - (4)].str),0);
+ if (!n) {
+ Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", (yyvsp[(3) - (4)].str));
+ (yyval.node) = 0;
+ } else {
+
+ while (Strcmp(nodeType(n),"using") == 0) {
+ n = Getattr(n,"node");
+ }
+ if (n) {
+ if (Strcmp(nodeType(n),"namespace") == 0) {
+ Symtab *current = Swig_symbol_current();
+ Symtab *symtab = Getattr(n,"symtab");
+ (yyval.node) = new_node("using");
+ Setattr((yyval.node),"node",n);
+ Setattr((yyval.node),"namespace", (yyvsp[(3) - (4)].str));
+ if (current != symtab) {
+ Swig_symbol_inherit(symtab);
+ }
+ } else {
+ Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", (yyvsp[(3) - (4)].str));
+ (yyval.node) = 0;
+ }
+ } else {
+ (yyval.node) = 0;
+ }
+ }
+ }
+ break;
+
+ case 161:
+#line 3975 "parser.y"
+ {
+ Hash *h;
+ (yyvsp[(1) - (3)].node) = Swig_symbol_current();
+ h = Swig_symbol_clookup((yyvsp[(2) - (3)].str),0);
+ if (h && ((yyvsp[(1) - (3)].node) == Getattr(h,"sym:symtab")) && (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",
+ (yyvsp[(2) - (3)].str), Getattr(h,"name"));
+ (yyvsp[(2) - (3)].str) = Getattr(h,"name");
+ }
+ Swig_symbol_setscope(Getattr(h,"symtab"));
+ } else {
+ Swig_symbol_newscope();
+ Swig_symbol_setscopename((yyvsp[(2) - (3)].str));
+ }
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+ break;
+
+ case 162:
+#line 3993 "parser.y"
+ {
+ Node *n = (yyvsp[(5) - (6)].node);
+ set_nodeType(n,"namespace");
+ Setattr(n,"name",(yyvsp[(2) - (6)].str));
+ Setattr(n,"symtab", Swig_symbol_popscope());
+ Swig_symbol_setscope((yyvsp[(1) - (6)].node));
+ (yyval.node) = n;
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 163:
+#line 4004 "parser.y"
+ {
+ Hash *h;
+ (yyvsp[(1) - (2)].node) = Swig_symbol_current();
+ h = Swig_symbol_clookup((char *)" ",0);
+ if (h && (Strcmp(nodeType(h),"namespace") == 0)) {
+ Swig_symbol_setscope(Getattr(h,"symtab"));
+ } else {
+ Swig_symbol_newscope();
+ /* we don't use "__unnamed__", but a long 'empty' name */
+ Swig_symbol_setscopename(" ");
+ }
+ Namespaceprefix = 0;
+ }
+ break;
+
+ case 164:
+#line 4016 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(4) - (5)].node);
+ set_nodeType((yyval.node),"namespace");
+ Setattr((yyval.node),"unnamed","1");
+ Setattr((yyval.node),"symtab", Swig_symbol_popscope());
+ Swig_symbol_setscope((yyvsp[(1) - (5)].node));
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 165:
+#line 4026 "parser.y"
+ {
+ /* Namespace alias */
+ Node *n;
+ (yyval.node) = new_node("namespace");
+ Setattr((yyval.node),"name",(yyvsp[(2) - (5)].id));
+ Setattr((yyval.node),"alias",(yyvsp[(4) - (5)].str));
+ n = Swig_symbol_clookup((yyvsp[(4) - (5)].str),0);
+ if (!n) {
+ Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", (yyvsp[(4) - (5)].str));
+ (yyval.node) = 0;
+ } else {
+ if (Strcmp(nodeType(n),"namespace") != 0) {
+ Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",(yyvsp[(4) - (5)].str));
+ (yyval.node) = 0;
+ } else {
+ while (Getattr(n,"alias")) {
+ n = Getattr(n,"namespace");
+ }
+ Setattr((yyval.node),"namespace",n);
+ add_symbols((yyval.node));
+ /* Set up a scope alias */
+ Swig_symbol_alias((yyvsp[(2) - (5)].id),Getattr(n,"symtab"));
+ }
+ }
+ }
+ break;
+
+ case 166:
+#line 4053 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(1) - (2)].node);
+ /* Insert cpp_member (including any siblings) to the front of the cpp_members linked list */
+ if ((yyval.node)) {
+ Node *p = (yyval.node);
+ Node *pp =0;
+ while (p) {
+ pp = p;
+ p = nextSibling(p);
+ }
+ set_nextSibling(pp,(yyvsp[(2) - (2)].node));
+ } else {
+ (yyval.node) = (yyvsp[(2) - (2)].node);
+ }
+ }
+ break;
+
+ case 167:
+#line 4068 "parser.y"
+ {
+ if (cplus_mode != CPLUS_PUBLIC) {
+ Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n");
+ }
+ }
+ break;
+
+ case 168:
+#line 4072 "parser.y"
+ {
+ (yyval.node) = new_node("extend");
+ tag_nodes((yyvsp[(4) - (6)].node),"feature:extend",(char*) "1");
+ appendChild((yyval.node),(yyvsp[(4) - (6)].node));
+ set_nextSibling((yyval.node),(yyvsp[(6) - (6)].node));
+ }
+ break;
+
+ case 169:
+#line 4078 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 170:
+#line 4079 "parser.y"
+ { (yyval.node) = 0;}
+ break;
+
+ case 171:
+#line 4080 "parser.y"
+ {
+ int start_line = cparse_line;
+ skip_decl();
+ Swig_error(cparse_file,start_line,"Syntax error in input(3).\n");
+ exit(1);
+ }
+ break;
+
+ case 172:
+#line 4085 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(3) - (3)].node);
+ }
+ break;
+
+ case 173:
+#line 4096 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 174:
+#line 4097 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ if (extendmode) {
+ String *symname;
+ symname= make_name((yyval.node),Getattr((yyval.node),"name"), Getattr((yyval.node),"decl"));
+ if (Strcmp(symname,Getattr((yyval.node),"name")) == 0) {
+ /* No renaming operation. Set name to class name */
+ Delete(yyrename);
+ yyrename = NewString(Getattr(current_class,"sym:name"));
+ } else {
+ Delete(yyrename);
+ yyrename = symname;
+ }
+ }
+ add_symbols((yyval.node));
+ default_arguments((yyval.node));
+ }
+ break;
+
+ case 175:
+#line 4114 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 176:
+#line 4115 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 177:
+#line 4116 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 178:
+#line 4117 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 179:
+#line 4118 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 180:
+#line 4119 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 181:
+#line 4120 "parser.y"
+ { (yyval.node) = 0; }
+ break;
+
+ case 182:
+#line 4121 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 183:
+#line 4122 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 184:
+#line 4123 "parser.y"
+ { (yyval.node) = 0; }
+ break;
+
+ case 185:
+#line 4124 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 186:
+#line 4125 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 187:
+#line 4126 "parser.y"
+ { (yyval.node) = 0; }
+ break;
+
+ case 188:
+#line 4127 "parser.y"
+ {(yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 189:
+#line 4128 "parser.y"
+ {(yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 190:
+#line 4129 "parser.y"
+ { (yyval.node) = 0; }
+ break;
+
+ case 191:
+#line 4138 "parser.y"
+ {
+ if (Classprefix) {
+ SwigType *decl = NewStringEmpty();
+ (yyval.node) = new_node("constructor");
+ Setattr((yyval.node),"storage",(yyvsp[(1) - (6)].id));
+ Setattr((yyval.node),"name",(yyvsp[(2) - (6)].type));
+ Setattr((yyval.node),"parms",(yyvsp[(4) - (6)].pl));
+ SwigType_add_function(decl,(yyvsp[(4) - (6)].pl));
+ Setattr((yyval.node),"decl",decl);
+ Setattr((yyval.node),"throws",(yyvsp[(6) - (6)].decl).throws);
+ Setattr((yyval.node),"throw",(yyvsp[(6) - (6)].decl).throwf);
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr((yyval.node),"code",code);
+ Delete(code);
+ }
+ SetFlag((yyval.node),"feature:new");
+ } else {
+ (yyval.node) = 0;
+ }
+ }
+ break;
+
+ case 192:
+#line 4163 "parser.y"
+ {
+ String *name = NewStringf("%s",(yyvsp[(2) - (6)].str));
+ if (*(Char(name)) != '~') Insert(name,0,"~");
+ (yyval.node) = new_node("destructor");
+ Setattr((yyval.node),"name",name);
+ Delete(name);
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr((yyval.node),"code",code);
+ Delete(code);
+ }
+ {
+ String *decl = NewStringEmpty();
+ SwigType_add_function(decl,(yyvsp[(4) - (6)].pl));
+ Setattr((yyval.node),"decl",decl);
+ Delete(decl);
+ }
+ Setattr((yyval.node),"throws",(yyvsp[(6) - (6)].dtype).throws);
+ Setattr((yyval.node),"throw",(yyvsp[(6) - (6)].dtype).throwf);
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 193:
+#line 4187 "parser.y"
+ {
+ String *name;
+ char *c = 0;
+ (yyval.node) = new_node("destructor");
+ /* Check for template names. If the class is a template
+ and the constructor is missing the template part, we
+ add it */
+ if (Classprefix) {
+ c = strchr(Char(Classprefix),'<');
+ if (c && !Strchr((yyvsp[(3) - (7)].str),'<')) {
+ (yyvsp[(3) - (7)].str) = NewStringf("%s%s",(yyvsp[(3) - (7)].str),c);
+ }
+ }
+ Setattr((yyval.node),"storage","virtual");
+ name = NewStringf("%s",(yyvsp[(3) - (7)].str));
+ if (*(Char(name)) != '~') Insert(name,0,"~");
+ Setattr((yyval.node),"name",name);
+ Delete(name);
+ Setattr((yyval.node),"throws",(yyvsp[(7) - (7)].dtype).throws);
+ Setattr((yyval.node),"throw",(yyvsp[(7) - (7)].dtype).throwf);
+ if ((yyvsp[(7) - (7)].dtype).val) {
+ Setattr((yyval.node),"value","0");
+ }
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr((yyval.node),"code",code);
+ Delete(code);
+ }
+ {
+ String *decl = NewStringEmpty();
+ SwigType_add_function(decl,(yyvsp[(5) - (7)].pl));
+ Setattr((yyval.node),"decl",decl);
+ Delete(decl);
+ }
+
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 194:
+#line 4228 "parser.y"
+ {
+ (yyval.node) = new_node("cdecl");
+ Setattr((yyval.node),"type",(yyvsp[(3) - (8)].type));
+ Setattr((yyval.node),"name",(yyvsp[(2) - (8)].str));
+ Setattr((yyval.node),"storage",(yyvsp[(1) - (8)].id));
+
+ SwigType_add_function((yyvsp[(4) - (8)].type),(yyvsp[(6) - (8)].pl));
+ if ((yyvsp[(8) - (8)].dtype).qualifier) {
+ SwigType_push((yyvsp[(4) - (8)].type),(yyvsp[(8) - (8)].dtype).qualifier);
+ }
+ Setattr((yyval.node),"decl",(yyvsp[(4) - (8)].type));
+ Setattr((yyval.node),"parms",(yyvsp[(6) - (8)].pl));
+ Setattr((yyval.node),"conversion_operator","1");
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 195:
+#line 4243 "parser.y"
+ {
+ SwigType *decl;
+ (yyval.node) = new_node("cdecl");
+ Setattr((yyval.node),"type",(yyvsp[(3) - (8)].type));
+ Setattr((yyval.node),"name",(yyvsp[(2) - (8)].str));
+ Setattr((yyval.node),"storage",(yyvsp[(1) - (8)].id));
+ decl = NewStringEmpty();
+ SwigType_add_reference(decl);
+ SwigType_add_function(decl,(yyvsp[(6) - (8)].pl));
+ if ((yyvsp[(8) - (8)].dtype).qualifier) {
+ SwigType_push(decl,(yyvsp[(8) - (8)].dtype).qualifier);
+ }
+ Setattr((yyval.node),"decl",decl);
+ Setattr((yyval.node),"parms",(yyvsp[(6) - (8)].pl));
+ Setattr((yyval.node),"conversion_operator","1");
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 196:
+#line 4261 "parser.y"
+ {
+ String *t = NewStringEmpty();
+ (yyval.node) = new_node("cdecl");
+ Setattr((yyval.node),"type",(yyvsp[(3) - (7)].type));
+ Setattr((yyval.node),"name",(yyvsp[(2) - (7)].str));
+ Setattr((yyval.node),"storage",(yyvsp[(1) - (7)].id));
+ SwigType_add_function(t,(yyvsp[(5) - (7)].pl));
+ if ((yyvsp[(7) - (7)].dtype).qualifier) {
+ SwigType_push(t,(yyvsp[(7) - (7)].dtype).qualifier);
+ }
+ Setattr((yyval.node),"decl",t);
+ Setattr((yyval.node),"parms",(yyvsp[(5) - (7)].pl));
+ Setattr((yyval.node),"conversion_operator","1");
+ add_symbols((yyval.node));
+ }
+ break;
+
+ case 197:
+#line 4280 "parser.y"
+ {
+ skip_balanced('{','}');
+ (yyval.node) = 0;
+ }
+ break;
+
+ case 198:
+#line 4287 "parser.y"
+ {
+ (yyval.node) = new_node("access");
+ Setattr((yyval.node),"kind","public");
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ break;
+
+ case 199:
+#line 4294 "parser.y"
+ {
+ (yyval.node) = new_node("access");
+ Setattr((yyval.node),"kind","private");
+ cplus_mode = CPLUS_PRIVATE;
+ }
+ break;
+
+ case 200:
+#line 4302 "parser.y"
+ {
+ (yyval.node) = new_node("access");
+ Setattr((yyval.node),"kind","protected");
+ cplus_mode = CPLUS_PROTECTED;
+ }
+ break;
+
+ case 201:
+#line 4325 "parser.y"
+ { cparse_start_line = cparse_line; skip_balanced('{','}');
+ }
+ break;
+
+ case 202:
+#line 4326 "parser.y"
+ {
+ (yyval.node) = 0;
+ if (cplus_mode == CPLUS_PUBLIC) {
+ if ((yyvsp[(6) - (7)].decl).id && strcmp((yyvsp[(2) - (7)].id), "class") != 0) {
+ Nested *n = (Nested *) malloc(sizeof(Nested));
+ n->code = NewStringEmpty();
+ Printv(n->code, "typedef ", (yyvsp[(2) - (7)].id), " ",
+ Char(scanner_ccode), " $classname_", (yyvsp[(6) - (7)].decl).id, ";\n", NIL);
+
+ n->name = Swig_copy_string((yyvsp[(6) - (7)].decl).id);
+ n->line = cparse_start_line;
+ n->type = NewStringEmpty();
+ n->kind = (yyvsp[(2) - (7)].id);
+ n->unnamed = 0;
+ SwigType_push(n->type, (yyvsp[(6) - (7)].decl).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", (yyvsp[(2) - (7)].id));
+ if (strcmp((yyvsp[(2) - (7)].id), "class") == 0) {
+ /* For now, just treat the nested class as a forward
+ * declaration (SF bug #909387). */
+ (yyval.node) = new_node("classforward");
+ Setfile((yyval.node),cparse_file);
+ Setline((yyval.node),cparse_line);
+ Setattr((yyval.node),"kind",(yyvsp[(2) - (7)].id));
+ Setattr((yyval.node),"name",(yyvsp[(3) - (7)].id));
+ Setattr((yyval.node),"sym:weak", "1");
+ add_symbols((yyval.node));
+ }
+ }
+ }
+ }
+ break;
+
+ case 203:
+#line 4360 "parser.y"
+ { cparse_start_line = cparse_line; skip_balanced('{','}');
+ }
+ break;
+
+ case 204:
+#line 4361 "parser.y"
+ {
+ (yyval.node) = 0;
+ if (cplus_mode == CPLUS_PUBLIC) {
+ if (strcmp((yyvsp[(2) - (6)].id),"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 ((yyvsp[(5) - (6)].decl).id) {
+ /* Generate some code for a new class */
+ Nested *n = (Nested *) malloc(sizeof(Nested));
+ n->code = NewStringEmpty();
+ Printv(n->code, "typedef ", (yyvsp[(2) - (6)].id), " " ,
+ Char(scanner_ccode), " $classname_", (yyvsp[(5) - (6)].decl).id, ";\n",NIL);
+ n->name = Swig_copy_string((yyvsp[(5) - (6)].decl).id);
+ n->line = cparse_start_line;
+ n->type = NewStringEmpty();
+ n->kind = (yyvsp[(2) - (6)].id);
+ n->unnamed = 1;
+ SwigType_push(n->type,(yyvsp[(5) - (6)].decl).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", (yyvsp[(2) - (6)].id));
+ }
+ }
+ }
+ break;
+
+ case 205:
+#line 4391 "parser.y"
+ { cparse_start_line = cparse_line; skip_balanced('{','}');
+ }
+ break;
+
+ case 206:
+#line 4392 "parser.y"
+ {
+ (yyval.node) = 0;
+ if (cplus_mode == CPLUS_PUBLIC) {
+ Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
+ }
+ }
+ break;
+
+ case 207:
+#line 4409 "parser.y"
+ { (yyval.decl) = (yyvsp[(1) - (1)].decl);}
+ break;
+
+ case 208:
+#line 4410 "parser.y"
+ { (yyval.decl).id = 0; }
+ break;
+
+ case 209:
+#line 4416 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 210:
+#line 4419 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 211:
+#line 4423 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 212:
+#line 4426 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 213:
+#line 4427 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 214:
+#line 4428 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 215:
+#line 4429 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 216:
+#line 4430 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 217:
+#line 4431 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 218:
+#line 4432 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 219:
+#line 4433 "parser.y"
+ { (yyval.node) = (yyvsp[(1) - (1)].node); }
+ break;
+
+ case 220:
+#line 4436 "parser.y"
+ {
+ Clear(scanner_ccode);
+ (yyval.dtype).throws = (yyvsp[(1) - (2)].dtype).throws;
+ (yyval.dtype).throwf = (yyvsp[(1) - (2)].dtype).throwf;
+ }
+ break;
+
+ case 221:
+#line 4441 "parser.y"
+ {
+ skip_balanced('{','}');
+ (yyval.dtype).throws = (yyvsp[(1) - (2)].dtype).throws;
+ (yyval.dtype).throwf = (yyvsp[(1) - (2)].dtype).throwf;
+ }
+ break;
+
+ case 222:
+#line 4448 "parser.y"
+ {
+ Clear(scanner_ccode);
+ (yyval.dtype).val = 0;
+ (yyval.dtype).qualifier = (yyvsp[(1) - (2)].dtype).qualifier;
+ (yyval.dtype).bitfield = 0;
+ (yyval.dtype).throws = (yyvsp[(1) - (2)].dtype).throws;
+ (yyval.dtype).throwf = (yyvsp[(1) - (2)].dtype).throwf;
+ }
+ break;
+
+ case 223:
+#line 4456 "parser.y"
+ {
+ Clear(scanner_ccode);
+ (yyval.dtype).val = (yyvsp[(3) - (4)].dtype).val;
+ (yyval.dtype).qualifier = (yyvsp[(1) - (4)].dtype).qualifier;
+ (yyval.dtype).bitfield = 0;
+ (yyval.dtype).throws = (yyvsp[(1) - (4)].dtype).throws;
+ (yyval.dtype).throwf = (yyvsp[(1) - (4)].dtype).throwf;
+ }
+ break;
+
+ case 224:
+#line 4464 "parser.y"
+ {
+ skip_balanced('{','}');
+ (yyval.dtype).val = 0;
+ (yyval.dtype).qualifier = (yyvsp[(1) - (2)].dtype).qualifier;
+ (yyval.dtype).bitfield = 0;
+ (yyval.dtype).throws = (yyvsp[(1) - (2)].dtype).throws;
+ (yyval.dtype).throwf = (yyvsp[(1) - (2)].dtype).throwf;
+ }
+ break;
+
+ case 225:
+#line 4475 "parser.y"
+ { }
+ break;
+
+ case 226:
+#line 4481 "parser.y"
+ { (yyval.id) = "extern"; }
+ break;
+
+ case 227:
+#line 4482 "parser.y"
+ {
+ if (strcmp((yyvsp[(2) - (2)].id),"C") == 0) {
+ (yyval.id) = "externc";
+ } else {
+ Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", (yyvsp[(2) - (2)].id));
+ (yyval.id) = 0;
+ }
+ }
+ break;
+
+ case 228:
+#line 4490 "parser.y"
+ { (yyval.id) = "static"; }
+ break;
+
+ case 229:
+#line 4491 "parser.y"
+ { (yyval.id) = "typedef"; }
+ break;
+
+ case 230:
+#line 4492 "parser.y"
+ { (yyval.id) = "virtual"; }
+ break;
+
+ case 231:
+#line 4493 "parser.y"
+ { (yyval.id) = "friend"; }
+ break;
+
+ case 232:
+#line 4494 "parser.y"
+ { (yyval.id) = "explicit"; }
+ break;
+
+ case 233:
+#line 4495 "parser.y"
+ { (yyval.id) = 0; }
+ break;
+
+ case 234:
+#line 4502 "parser.y"
+ {
+ Parm *p;
+ (yyval.pl) = (yyvsp[(1) - (1)].pl);
+ p = (yyvsp[(1) - (1)].pl);
+ while (p) {
+ Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
+ p = nextSibling(p);
+ }
+ }
+ break;
+
+ case 235:
+#line 4513 "parser.y"
+ {
+ set_nextSibling((yyvsp[(1) - (2)].p),(yyvsp[(2) - (2)].pl));
+ (yyval.pl) = (yyvsp[(1) - (2)].p);
+ }
+ break;
+
+ case 236:
+#line 4517 "parser.y"
+ { (yyval.pl) = 0; }
+ break;
+
+ case 237:
+#line 4520 "parser.y"
+ {
+ set_nextSibling((yyvsp[(2) - (3)].p),(yyvsp[(3) - (3)].pl));
+ (yyval.pl) = (yyvsp[(2) - (3)].p);
+ }
+ break;
+
+ case 238:
+#line 4524 "parser.y"
+ { (yyval.pl) = 0; }
+ break;
+
+ case 239:
+#line 4528 "parser.y"
+ {
+ SwigType_push((yyvsp[(1) - (2)].type),(yyvsp[(2) - (2)].decl).type);
+ (yyval.p) = NewParm((yyvsp[(1) - (2)].type),(yyvsp[(2) - (2)].decl).id);
+ Setfile((yyval.p),cparse_file);
+ Setline((yyval.p),cparse_line);
+ if ((yyvsp[(2) - (2)].decl).defarg) {
+ Setattr((yyval.p),"value",(yyvsp[(2) - (2)].decl).defarg);
+ }
+ }
+ break;
+
+ case 240:
+#line 4538 "parser.y"
+ {
+ (yyval.p) = NewParm(NewStringf("template<class> %s %s", (yyvsp[(5) - (7)].id),(yyvsp[(6) - (7)].str)), 0);
+ Setfile((yyval.p),cparse_file);
+ Setline((yyval.p),cparse_line);
+ if ((yyvsp[(7) - (7)].dtype).val) {
+ Setattr((yyval.p),"value",(yyvsp[(7) - (7)].dtype).val);
+ }
+ }
+ break;
+
+ case 241:
+#line 4546 "parser.y"
+ {
+ SwigType *t = NewString("v(...)");
+ (yyval.p) = NewParm(t, 0);
+ Setfile((yyval.p),cparse_file);
+ Setline((yyval.p),cparse_line);
+ }
+ break;
+
+ case 242:
+#line 4554 "parser.y"
+ {
+ Parm *p;
+ (yyval.p) = (yyvsp[(1) - (1)].p);
+ p = (yyvsp[(1) - (1)].p);
+ while (p) {
+ if (Getattr(p,"type")) {
+ Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY);
+ }
+ p = nextSibling(p);
+ }
+ }
+ break;
+
+ case 243:
+#line 4567 "parser.y"
+ {
+ set_nextSibling((yyvsp[(1) - (2)].p),(yyvsp[(2) - (2)].p));
+ (yyval.p) = (yyvsp[(1) - (2)].p);
+ }
+ break;
+
+ case 244:
+#line 4571 "parser.y"
+ { (yyval.p) = 0; }
+ break;
+
+ case 245:
+#line 4574 "parser.y"
+ {
+ set_nextSibling((yyvsp[(2) - (3)].p),(yyvsp[(3) - (3)].p));
+ (yyval.p) = (yyvsp[(2) - (3)].p);
+ }
+ break;
+
+ case 246:
+#line 4578 "parser.y"
+ { (yyval.p) = 0; }
+ break;
+
+ case 247:
+#line 4582 "parser.y"
+ {
+ (yyval.p) = (yyvsp[(1) - (1)].p);
+ {
+ /* We need to make a possible adjustment for integer parameters. */
+ SwigType *type;
+ Node *n = 0;
+
+ while (!n) {
+ type = Getattr((yyvsp[(1) - (1)].p),"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) {
+ String *v = Copy(value);
+ Setattr((yyvsp[(1) - (1)].p),"type",v);
+ Delete(v);
+ n = 0;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ }
+ break;
+
+ case 248:
+#line 4610 "parser.y"
+ {
+ (yyval.p) = NewParm(0,0);
+ Setfile((yyval.p),cparse_file);
+ Setline((yyval.p),cparse_line);
+ Setattr((yyval.p),"value",(yyvsp[(1) - (1)].dtype).val);
+ }
+ break;
+
+ case 249:
+#line 4618 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(2) - (2)].dtype);
+ if ((yyvsp[(2) - (2)].dtype).type == T_ERROR) {
+ Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
+ (yyval.dtype).val = 0;
+ (yyval.dtype).rawval = 0;
+ (yyval.dtype).bitfield = 0;
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ }
+ }
+ break;
+
+ case 250:
+#line 4629 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(2) - (5)].dtype);
+ if ((yyvsp[(2) - (5)].dtype).type == T_ERROR) {
+ Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
+ (yyval.dtype) = (yyvsp[(2) - (5)].dtype);
+ (yyval.dtype).val = 0;
+ (yyval.dtype).rawval = 0;
+ (yyval.dtype).bitfield = 0;
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ } else {
+ (yyval.dtype).val = NewStringf("%s[%s]",(yyvsp[(2) - (5)].dtype).val,(yyvsp[(4) - (5)].dtype).val);
+ }
+ }
+ break;
+
+ case 251:
+#line 4643 "parser.y"
+ {
+ skip_balanced('{','}');
+ (yyval.dtype).val = 0;
+ (yyval.dtype).rawval = 0;
+ (yyval.dtype).type = T_INT;
+ (yyval.dtype).bitfield = 0;
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ }
+ break;
+
+ case 252:
+#line 4652 "parser.y"
+ {
+ (yyval.dtype).val = 0;
+ (yyval.dtype).rawval = 0;
+ (yyval.dtype).type = 0;
+ (yyval.dtype).bitfield = (yyvsp[(2) - (2)].dtype).val;
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ }
+ break;
+
+ case 253:
+#line 4660 "parser.y"
+ {
+ (yyval.dtype).val = 0;
+ (yyval.dtype).rawval = 0;
+ (yyval.dtype).type = T_INT;
+ (yyval.dtype).bitfield = 0;
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ }
+ break;
+
+ case 254:
+#line 4670 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(1) - (2)].decl);
+ (yyval.decl).defarg = (yyvsp[(2) - (2)].dtype).rawval ? (yyvsp[(2) - (2)].dtype).rawval : (yyvsp[(2) - (2)].dtype).val;
+ }
+ break;
+
+ case 255:
+#line 4674 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(1) - (2)].decl);
+ (yyval.decl).defarg = (yyvsp[(2) - (2)].dtype).rawval ? (yyvsp[(2) - (2)].dtype).rawval : (yyvsp[(2) - (2)].dtype).val;
+ }
+ break;
+
+ case 256:
+#line 4678 "parser.y"
+ {
+ (yyval.decl).type = 0;
+ (yyval.decl).id = 0;
+ (yyval.decl).defarg = (yyvsp[(1) - (1)].dtype).rawval ? (yyvsp[(1) - (1)].dtype).rawval : (yyvsp[(1) - (1)].dtype).val;
+ }
+ break;
+
+ case 257:
+#line 4685 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(1) - (1)].decl);
+ if (SwigType_isfunction((yyvsp[(1) - (1)].decl).type)) {
+ Delete(SwigType_pop_function((yyvsp[(1) - (1)].decl).type));
+ } else if (SwigType_isarray((yyvsp[(1) - (1)].decl).type)) {
+ SwigType *ta = SwigType_pop_arrays((yyvsp[(1) - (1)].decl).type);
+ if (SwigType_isfunction((yyvsp[(1) - (1)].decl).type)) {
+ Delete(SwigType_pop_function((yyvsp[(1) - (1)].decl).type));
+ } else {
+ (yyval.decl).parms = 0;
+ }
+ SwigType_push((yyvsp[(1) - (1)].decl).type,ta);
+ Delete(ta);
+ } else {
+ (yyval.decl).parms = 0;
+ }
+ }
+ break;
+
+ case 258:
+#line 4702 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(1) - (1)].decl);
+ if (SwigType_isfunction((yyvsp[(1) - (1)].decl).type)) {
+ Delete(SwigType_pop_function((yyvsp[(1) - (1)].decl).type));
+ } else if (SwigType_isarray((yyvsp[(1) - (1)].decl).type)) {
+ SwigType *ta = SwigType_pop_arrays((yyvsp[(1) - (1)].decl).type);
+ if (SwigType_isfunction((yyvsp[(1) - (1)].decl).type)) {
+ Delete(SwigType_pop_function((yyvsp[(1) - (1)].decl).type));
+ } else {
+ (yyval.decl).parms = 0;
+ }
+ SwigType_push((yyvsp[(1) - (1)].decl).type,ta);
+ Delete(ta);
+ } else {
+ (yyval.decl).parms = 0;
+ }
+ }
+ break;
+
+ case 259:
+#line 4719 "parser.y"
+ {
+ (yyval.decl).type = 0;
+ (yyval.decl).id = 0;
+ (yyval.decl).parms = 0;
+ }
+ break;
+
+ case 260:
+#line 4727 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(2) - (2)].decl);
+ if ((yyval.decl).type) {
+ SwigType_push((yyvsp[(1) - (2)].type),(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = (yyvsp[(1) - (2)].type);
+ }
+ break;
+
+ case 261:
+#line 4735 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(3) - (3)].decl);
+ SwigType_add_reference((yyvsp[(1) - (3)].type));
+ if ((yyval.decl).type) {
+ SwigType_push((yyvsp[(1) - (3)].type),(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = (yyvsp[(1) - (3)].type);
+ }
+ break;
+
+ case 262:
+#line 4744 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(1) - (1)].decl);
+ if (!(yyval.decl).type) (yyval.decl).type = NewStringEmpty();
+ }
+ break;
+
+ case 263:
+#line 4748 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(2) - (2)].decl);
+ (yyval.decl).type = NewStringEmpty();
+ SwigType_add_reference((yyval.decl).type);
+ if ((yyvsp[(2) - (2)].decl).type) {
+ SwigType_push((yyval.decl).type,(yyvsp[(2) - (2)].decl).type);
+ Delete((yyvsp[(2) - (2)].decl).type);
+ }
+ }
+ break;
+
+ case 264:
+#line 4757 "parser.y"
+ {
+ SwigType *t = NewStringEmpty();
+
+ (yyval.decl) = (yyvsp[(3) - (3)].decl);
+ SwigType_add_memberpointer(t,(yyvsp[(1) - (3)].str));
+ if ((yyval.decl).type) {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = t;
+ }
+ break;
+
+ case 265:
+#line 4768 "parser.y"
+ {
+ SwigType *t = NewStringEmpty();
+ (yyval.decl) = (yyvsp[(4) - (4)].decl);
+ SwigType_add_memberpointer(t,(yyvsp[(2) - (4)].str));
+ SwigType_push((yyvsp[(1) - (4)].type),t);
+ if ((yyval.decl).type) {
+ SwigType_push((yyvsp[(1) - (4)].type),(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = (yyvsp[(1) - (4)].type);
+ Delete(t);
+ }
+ break;
+
+ case 266:
+#line 4780 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(5) - (5)].decl);
+ SwigType_add_memberpointer((yyvsp[(1) - (5)].type),(yyvsp[(2) - (5)].str));
+ SwigType_add_reference((yyvsp[(1) - (5)].type));
+ if ((yyval.decl).type) {
+ SwigType_push((yyvsp[(1) - (5)].type),(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = (yyvsp[(1) - (5)].type);
+ }
+ break;
+
+ case 267:
+#line 4790 "parser.y"
+ {
+ SwigType *t = NewStringEmpty();
+ (yyval.decl) = (yyvsp[(4) - (4)].decl);
+ SwigType_add_memberpointer(t,(yyvsp[(1) - (4)].str));
+ SwigType_add_reference(t);
+ if ((yyval.decl).type) {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = t;
+ }
+ break;
+
+ case 268:
+#line 4803 "parser.y"
+ {
+ /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */
+ (yyval.decl).id = Char((yyvsp[(1) - (1)].str));
+ (yyval.decl).type = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ }
+ break;
+
+ case 269:
+#line 4810 "parser.y"
+ {
+ (yyval.decl).id = Char(NewStringf("~%s",(yyvsp[(2) - (2)].str)));
+ (yyval.decl).type = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ }
+ break;
+
+ case 270:
+#line 4818 "parser.y"
+ {
+ (yyval.decl).id = Char((yyvsp[(2) - (3)].str));
+ (yyval.decl).type = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ }
+ break;
+
+ case 271:
+#line 4834 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(3) - (4)].decl);
+ if ((yyval.decl).type) {
+ SwigType_push((yyvsp[(2) - (4)].type),(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = (yyvsp[(2) - (4)].type);
+ }
+ break;
+
+ case 272:
+#line 4842 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(4) - (5)].decl);
+ t = NewStringEmpty();
+ SwigType_add_memberpointer(t,(yyvsp[(2) - (5)].str));
+ if ((yyval.decl).type) {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = t;
+ }
+ break;
+
+ case 273:
+#line 4853 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(1) - (3)].decl);
+ t = NewStringEmpty();
+ SwigType_add_array(t,(char*)"");
+ if ((yyval.decl).type) {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = t;
+ }
+ break;
+
+ case 274:
+#line 4864 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(1) - (4)].decl);
+ t = NewStringEmpty();
+ SwigType_add_array(t,(yyvsp[(3) - (4)].dtype).val);
+ if ((yyval.decl).type) {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = t;
+ }
+ break;
+
+ case 275:
+#line 4875 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(1) - (4)].decl);
+ t = NewStringEmpty();
+ SwigType_add_function(t,(yyvsp[(3) - (4)].pl));
+ if (!(yyval.decl).have_parms) {
+ (yyval.decl).parms = (yyvsp[(3) - (4)].pl);
+ (yyval.decl).have_parms = 1;
+ }
+ if (!(yyval.decl).type) {
+ (yyval.decl).type = t;
+ } else {
+ SwigType_push(t, (yyval.decl).type);
+ Delete((yyval.decl).type);
+ (yyval.decl).type = t;
+ }
+ }
+ break;
+
+ case 276:
+#line 4894 "parser.y"
+ {
+ /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */
+ (yyval.decl).id = Char((yyvsp[(1) - (1)].str));
+ (yyval.decl).type = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ }
+ break;
+
+ case 277:
+#line 4902 "parser.y"
+ {
+ (yyval.decl).id = Char(NewStringf("~%s",(yyvsp[(2) - (2)].str)));
+ (yyval.decl).type = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ }
+ break;
+
+ case 278:
+#line 4919 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(3) - (4)].decl);
+ if ((yyval.decl).type) {
+ SwigType_push((yyvsp[(2) - (4)].type),(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = (yyvsp[(2) - (4)].type);
+ }
+ break;
+
+ case 279:
+#line 4927 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(3) - (4)].decl);
+ if (!(yyval.decl).type) {
+ (yyval.decl).type = NewStringEmpty();
+ }
+ SwigType_add_reference((yyval.decl).type);
+ }
+ break;
+
+ case 280:
+#line 4934 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(4) - (5)].decl);
+ t = NewStringEmpty();
+ SwigType_add_memberpointer(t,(yyvsp[(2) - (5)].str));
+ if ((yyval.decl).type) {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = t;
+ }
+ break;
+
+ case 281:
+#line 4945 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(1) - (3)].decl);
+ t = NewStringEmpty();
+ SwigType_add_array(t,(char*)"");
+ if ((yyval.decl).type) {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = t;
+ }
+ break;
+
+ case 282:
+#line 4956 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(1) - (4)].decl);
+ t = NewStringEmpty();
+ SwigType_add_array(t,(yyvsp[(3) - (4)].dtype).val);
+ if ((yyval.decl).type) {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = t;
+ }
+ break;
+
+ case 283:
+#line 4967 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(1) - (4)].decl);
+ t = NewStringEmpty();
+ SwigType_add_function(t,(yyvsp[(3) - (4)].pl));
+ if (!(yyval.decl).have_parms) {
+ (yyval.decl).parms = (yyvsp[(3) - (4)].pl);
+ (yyval.decl).have_parms = 1;
+ }
+ if (!(yyval.decl).type) {
+ (yyval.decl).type = t;
+ } else {
+ SwigType_push(t, (yyval.decl).type);
+ Delete((yyval.decl).type);
+ (yyval.decl).type = t;
+ }
+ }
+ break;
+
+ case 284:
+#line 4986 "parser.y"
+ {
+ (yyval.decl).type = (yyvsp[(1) - (1)].type);
+ (yyval.decl).id = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ }
+ break;
+
+ case 285:
+#line 4992 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(2) - (2)].decl);
+ SwigType_push((yyvsp[(1) - (2)].type),(yyvsp[(2) - (2)].decl).type);
+ (yyval.decl).type = (yyvsp[(1) - (2)].type);
+ Delete((yyvsp[(2) - (2)].decl).type);
+ }
+ break;
+
+ case 286:
+#line 4998 "parser.y"
+ {
+ (yyval.decl).type = (yyvsp[(1) - (2)].type);
+ SwigType_add_reference((yyval.decl).type);
+ (yyval.decl).id = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ }
+ break;
+
+ case 287:
+#line 5005 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(3) - (3)].decl);
+ SwigType_add_reference((yyvsp[(1) - (3)].type));
+ if ((yyval.decl).type) {
+ SwigType_push((yyvsp[(1) - (3)].type),(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = (yyvsp[(1) - (3)].type);
+ }
+ break;
+
+ case 288:
+#line 5014 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(1) - (1)].decl);
+ }
+ break;
+
+ case 289:
+#line 5017 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(2) - (2)].decl);
+ (yyval.decl).type = NewStringEmpty();
+ SwigType_add_reference((yyval.decl).type);
+ if ((yyvsp[(2) - (2)].decl).type) {
+ SwigType_push((yyval.decl).type,(yyvsp[(2) - (2)].decl).type);
+ Delete((yyvsp[(2) - (2)].decl).type);
+ }
+ }
+ break;
+
+ case 290:
+#line 5026 "parser.y"
+ {
+ (yyval.decl).id = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ (yyval.decl).type = NewStringEmpty();
+ SwigType_add_reference((yyval.decl).type);
+ }
+ break;
+
+ case 291:
+#line 5033 "parser.y"
+ {
+ (yyval.decl).type = NewStringEmpty();
+ SwigType_add_memberpointer((yyval.decl).type,(yyvsp[(1) - (2)].str));
+ (yyval.decl).id = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ }
+ break;
+
+ case 292:
+#line 5040 "parser.y"
+ {
+ SwigType *t = NewStringEmpty();
+ (yyval.decl).type = (yyvsp[(1) - (3)].type);
+ (yyval.decl).id = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ SwigType_add_memberpointer(t,(yyvsp[(2) - (3)].str));
+ SwigType_push((yyval.decl).type,t);
+ Delete(t);
+ }
+ break;
+
+ case 293:
+#line 5050 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(4) - (4)].decl);
+ SwigType_add_memberpointer((yyvsp[(1) - (4)].type),(yyvsp[(2) - (4)].str));
+ if ((yyval.decl).type) {
+ SwigType_push((yyvsp[(1) - (4)].type),(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = (yyvsp[(1) - (4)].type);
+ }
+ break;
+
+ case 294:
+#line 5061 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(1) - (3)].decl);
+ t = NewStringEmpty();
+ SwigType_add_array(t,(char*)"");
+ if ((yyval.decl).type) {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = t;
+ }
+ break;
+
+ case 295:
+#line 5072 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(1) - (4)].decl);
+ t = NewStringEmpty();
+ SwigType_add_array(t,(yyvsp[(3) - (4)].dtype).val);
+ if ((yyval.decl).type) {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ }
+ (yyval.decl).type = t;
+ }
+ break;
+
+ case 296:
+#line 5083 "parser.y"
+ {
+ (yyval.decl).type = NewStringEmpty();
+ (yyval.decl).id = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ SwigType_add_array((yyval.decl).type,(char*)"");
+ }
+ break;
+
+ case 297:
+#line 5090 "parser.y"
+ {
+ (yyval.decl).type = NewStringEmpty();
+ (yyval.decl).id = 0;
+ (yyval.decl).parms = 0;
+ (yyval.decl).have_parms = 0;
+ SwigType_add_array((yyval.decl).type,(yyvsp[(2) - (3)].dtype).val);
+ }
+ break;
+
+ case 298:
+#line 5097 "parser.y"
+ {
+ (yyval.decl) = (yyvsp[(2) - (3)].decl);
+ }
+ break;
+
+ case 299:
+#line 5100 "parser.y"
+ {
+ SwigType *t;
+ (yyval.decl) = (yyvsp[(1) - (4)].decl);
+ t = NewStringEmpty();
+ SwigType_add_function(t,(yyvsp[(3) - (4)].pl));
+ if (!(yyval.decl).type) {
+ (yyval.decl).type = t;
+ } else {
+ SwigType_push(t,(yyval.decl).type);
+ Delete((yyval.decl).type);
+ (yyval.decl).type = t;
+ }
+ if (!(yyval.decl).have_parms) {
+ (yyval.decl).parms = (yyvsp[(3) - (4)].pl);
+ (yyval.decl).have_parms = 1;
+ }
+ }
+ break;
+
+ case 300:
+#line 5117 "parser.y"
+ {
+ (yyval.decl).type = NewStringEmpty();
+ SwigType_add_function((yyval.decl).type,(yyvsp[(2) - (3)].pl));
+ (yyval.decl).parms = (yyvsp[(2) - (3)].pl);
+ (yyval.decl).have_parms = 1;
+ (yyval.decl).id = 0;
+ }
+ break;
+
+ case 301:
+#line 5127 "parser.y"
+ {
+ (yyval.type) = NewStringEmpty();
+ SwigType_add_pointer((yyval.type));
+ SwigType_push((yyval.type),(yyvsp[(2) - (3)].str));
+ SwigType_push((yyval.type),(yyvsp[(3) - (3)].type));
+ Delete((yyvsp[(3) - (3)].type));
+ }
+ break;
+
+ case 302:
+#line 5134 "parser.y"
+ {
+ (yyval.type) = NewStringEmpty();
+ SwigType_add_pointer((yyval.type));
+ SwigType_push((yyval.type),(yyvsp[(2) - (2)].type));
+ Delete((yyvsp[(2) - (2)].type));
+ }
+ break;
+
+ case 303:
+#line 5140 "parser.y"
+ {
+ (yyval.type) = NewStringEmpty();
+ SwigType_add_pointer((yyval.type));
+ SwigType_push((yyval.type),(yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 304:
+#line 5145 "parser.y"
+ {
+ (yyval.type) = NewStringEmpty();
+ SwigType_add_pointer((yyval.type));
+ }
+ break;
+
+ case 305:
+#line 5151 "parser.y"
+ {
+ (yyval.str) = NewStringEmpty();
+ if ((yyvsp[(1) - (1)].id)) SwigType_add_qualifier((yyval.str),(yyvsp[(1) - (1)].id));
+ }
+ break;
+
+ case 306:
+#line 5155 "parser.y"
+ {
+ (yyval.str) = (yyvsp[(2) - (2)].str);
+ if ((yyvsp[(1) - (2)].id)) SwigType_add_qualifier((yyval.str),(yyvsp[(1) - (2)].id));
+ }
+ break;
+
+ case 307:
+#line 5161 "parser.y"
+ { (yyval.id) = "const"; }
+ break;
+
+ case 308:
+#line 5162 "parser.y"
+ { (yyval.id) = "volatile"; }
+ break;
+
+ case 309:
+#line 5163 "parser.y"
+ { (yyval.id) = 0; }
+ break;
+
+ case 310:
+#line 5169 "parser.y"
+ {
+ (yyval.type) = (yyvsp[(1) - (1)].type);
+ Replace((yyval.type),"typename ","", DOH_REPLACE_ANY);
+ }
+ break;
+
+ case 311:
+#line 5175 "parser.y"
+ {
+ (yyval.type) = (yyvsp[(2) - (2)].type);
+ SwigType_push((yyval.type),(yyvsp[(1) - (2)].str));
+ }
+ break;
+
+ case 312:
+#line 5179 "parser.y"
+ { (yyval.type) = (yyvsp[(1) - (1)].type); }
+ break;
+
+ case 313:
+#line 5180 "parser.y"
+ {
+ (yyval.type) = (yyvsp[(1) - (2)].type);
+ SwigType_push((yyval.type),(yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 314:
+#line 5184 "parser.y"
+ {
+ (yyval.type) = (yyvsp[(2) - (3)].type);
+ SwigType_push((yyval.type),(yyvsp[(3) - (3)].str));
+ SwigType_push((yyval.type),(yyvsp[(1) - (3)].str));
+ }
+ break;
+
+ case 315:
+#line 5191 "parser.y"
+ { (yyval.type) = (yyvsp[(1) - (1)].type);
+ /* Printf(stdout,"primitive = '%s'\n", $$);*/
+ }
+ break;
+
+ case 316:
+#line 5194 "parser.y"
+ { (yyval.type) = (yyvsp[(1) - (1)].type); }
+ break;
+
+ case 317:
+#line 5195 "parser.y"
+ { (yyval.type) = (yyvsp[(1) - (1)].type); }
+ break;
+
+ case 318:
+#line 5196 "parser.y"
+ { (yyval.type) = NewStringf("%s%s",(yyvsp[(1) - (2)].type),(yyvsp[(2) - (2)].id)); }
+ break;
+
+ case 319:
+#line 5197 "parser.y"
+ { (yyval.type) = NewStringf("enum %s", (yyvsp[(2) - (2)].str)); }
+ break;
+
+ case 320:
+#line 5198 "parser.y"
+ { (yyval.type) = (yyvsp[(1) - (1)].type); }
+ break;
+
+ case 321:
+#line 5200 "parser.y"
+ {
+ (yyval.type) = (yyvsp[(1) - (1)].str);
+ }
+ break;
+
+ case 322:
+#line 5203 "parser.y"
+ {
+ (yyval.type) = NewStringf("%s %s", (yyvsp[(1) - (2)].id), (yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 323:
+#line 5208 "parser.y"
+ {
+ if (!(yyvsp[(1) - (1)].ptype).type) (yyvsp[(1) - (1)].ptype).type = NewString("int");
+ if ((yyvsp[(1) - (1)].ptype).us) {
+ (yyval.type) = NewStringf("%s %s", (yyvsp[(1) - (1)].ptype).us, (yyvsp[(1) - (1)].ptype).type);
+ Delete((yyvsp[(1) - (1)].ptype).us);
+ Delete((yyvsp[(1) - (1)].ptype).type);
+ } else {
+ (yyval.type) = (yyvsp[(1) - (1)].ptype).type;
+ }
+ if (Cmp((yyval.type),"signed int") == 0) {
+ Delete((yyval.type));
+ (yyval.type) = NewString("int");
+ } else if (Cmp((yyval.type),"signed long") == 0) {
+ Delete((yyval.type));
+ (yyval.type) = NewString("long");
+ } else if (Cmp((yyval.type),"signed short") == 0) {
+ Delete((yyval.type));
+ (yyval.type) = NewString("short");
+ } else if (Cmp((yyval.type),"signed long long") == 0) {
+ Delete((yyval.type));
+ (yyval.type) = NewString("long long");
+ }
+ }
+ break;
+
+ case 324:
+#line 5233 "parser.y"
+ {
+ (yyval.ptype) = (yyvsp[(1) - (1)].ptype);
+ }
+ break;
+
+ case 325:
+#line 5236 "parser.y"
+ {
+ if ((yyvsp[(1) - (2)].ptype).us && (yyvsp[(2) - (2)].ptype).us) {
+ Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", (yyvsp[(2) - (2)].ptype).us);
+ }
+ (yyval.ptype) = (yyvsp[(2) - (2)].ptype);
+ if ((yyvsp[(1) - (2)].ptype).us) (yyval.ptype).us = (yyvsp[(1) - (2)].ptype).us;
+ if ((yyvsp[(1) - (2)].ptype).type) {
+ if (!(yyvsp[(2) - (2)].ptype).type) (yyval.ptype).type = (yyvsp[(1) - (2)].ptype).type;
+ else {
+ int err = 0;
+ if ((Cmp((yyvsp[(1) - (2)].ptype).type,"long") == 0)) {
+ if ((Cmp((yyvsp[(2) - (2)].ptype).type,"long") == 0) || (Strncmp((yyvsp[(2) - (2)].ptype).type,"double",6) == 0)) {
+ (yyval.ptype).type = NewStringf("long %s", (yyvsp[(2) - (2)].ptype).type);
+ } else if (Cmp((yyvsp[(2) - (2)].ptype).type,"int") == 0) {
+ (yyval.ptype).type = (yyvsp[(1) - (2)].ptype).type;
+ } else {
+ err = 1;
+ }
+ } else if ((Cmp((yyvsp[(1) - (2)].ptype).type,"short")) == 0) {
+ if (Cmp((yyvsp[(2) - (2)].ptype).type,"int") == 0) {
+ (yyval.ptype).type = (yyvsp[(1) - (2)].ptype).type;
+ } else {
+ err = 1;
+ }
+ } else if (Cmp((yyvsp[(1) - (2)].ptype).type,"int") == 0) {
+ (yyval.ptype).type = (yyvsp[(2) - (2)].ptype).type;
+ } else if (Cmp((yyvsp[(1) - (2)].ptype).type,"double") == 0) {
+ if (Cmp((yyvsp[(2) - (2)].ptype).type,"long") == 0) {
+ (yyval.ptype).type = NewString("long double");
+ } else if (Cmp((yyvsp[(2) - (2)].ptype).type,"complex") == 0) {
+ (yyval.ptype).type = NewString("double complex");
+ } else {
+ err = 1;
+ }
+ } else if (Cmp((yyvsp[(1) - (2)].ptype).type,"float") == 0) {
+ if (Cmp((yyvsp[(2) - (2)].ptype).type,"complex") == 0) {
+ (yyval.ptype).type = NewString("float complex");
+ } else {
+ err = 1;
+ }
+ } else if (Cmp((yyvsp[(1) - (2)].ptype).type,"complex") == 0) {
+ (yyval.ptype).type = NewStringf("%s complex", (yyvsp[(2) - (2)].ptype).type);
+ } else {
+ err = 1;
+ }
+ if (err) {
+ Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", (yyvsp[(1) - (2)].ptype).type);
+ }
+ }
+ }
+ }
+ break;
+
+ case 326:
+#line 5290 "parser.y"
+ {
+ (yyval.ptype).type = NewString("int");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 327:
+#line 5294 "parser.y"
+ {
+ (yyval.ptype).type = NewString("short");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 328:
+#line 5298 "parser.y"
+ {
+ (yyval.ptype).type = NewString("long");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 329:
+#line 5302 "parser.y"
+ {
+ (yyval.ptype).type = NewString("char");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 330:
+#line 5306 "parser.y"
+ {
+ (yyval.ptype).type = NewString("wchar_t");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 331:
+#line 5310 "parser.y"
+ {
+ (yyval.ptype).type = NewString("float");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 332:
+#line 5314 "parser.y"
+ {
+ (yyval.ptype).type = NewString("double");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 333:
+#line 5318 "parser.y"
+ {
+ (yyval.ptype).us = NewString("signed");
+ (yyval.ptype).type = 0;
+ }
+ break;
+
+ case 334:
+#line 5322 "parser.y"
+ {
+ (yyval.ptype).us = NewString("unsigned");
+ (yyval.ptype).type = 0;
+ }
+ break;
+
+ case 335:
+#line 5326 "parser.y"
+ {
+ (yyval.ptype).type = NewString("complex");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 336:
+#line 5330 "parser.y"
+ {
+ (yyval.ptype).type = NewString("__int8");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 337:
+#line 5334 "parser.y"
+ {
+ (yyval.ptype).type = NewString("__int16");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 338:
+#line 5338 "parser.y"
+ {
+ (yyval.ptype).type = NewString("__int32");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 339:
+#line 5342 "parser.y"
+ {
+ (yyval.ptype).type = NewString("__int64");
+ (yyval.ptype).us = 0;
+ }
+ break;
+
+ case 340:
+#line 5348 "parser.y"
+ { /* scanner_check_typedef(); */ }
+ break;
+
+ case 341:
+#line 5348 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(2) - (2)].dtype);
+ if ((yyval.dtype).type == T_STRING) {
+ (yyval.dtype).rawval = NewStringf("\"%(escape)s\"",(yyval.dtype).val);
+ } else if ((yyval.dtype).type != T_CHAR) {
+ (yyval.dtype).rawval = 0;
+ }
+ (yyval.dtype).bitfield = 0;
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ scanner_ignore_typedef();
+ }
+ break;
+
+ case 342:
+#line 5374 "parser.y"
+ { (yyval.id) = (yyvsp[(1) - (1)].id); }
+ break;
+
+ case 343:
+#line 5375 "parser.y"
+ { (yyval.id) = (char *) 0;}
+ break;
+
+ case 344:
+#line 5378 "parser.y"
+ {
+
+ /* Ignore if there is a trailing comma in the enum list */
+ if ((yyvsp[(3) - (3)].node)) {
+ Node *leftSibling = Getattr((yyvsp[(1) - (3)].node),"_last");
+ if (!leftSibling) {
+ leftSibling=(yyvsp[(1) - (3)].node);
+ }
+ set_nextSibling(leftSibling,(yyvsp[(3) - (3)].node));
+ Setattr((yyvsp[(1) - (3)].node),"_last",(yyvsp[(3) - (3)].node));
+ }
+ (yyval.node) = (yyvsp[(1) - (3)].node);
+ }
+ break;
+
+ case 345:
+#line 5391 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(1) - (1)].node);
+ if ((yyvsp[(1) - (1)].node)) {
+ Setattr((yyvsp[(1) - (1)].node),"_last",(yyvsp[(1) - (1)].node));
+ }
+ }
+ break;
+
+ case 346:
+#line 5399 "parser.y"
+ {
+ SwigType *type = NewSwigType(T_INT);
+ (yyval.node) = new_node("enumitem");
+ Setattr((yyval.node),"name",(yyvsp[(1) - (1)].id));
+ Setattr((yyval.node),"type",type);
+ SetFlag((yyval.node),"feature:immutable");
+ Delete(type);
+ }
+ break;
+
+ case 347:
+#line 5407 "parser.y"
+ {
+ (yyval.node) = new_node("enumitem");
+ Setattr((yyval.node),"name",(yyvsp[(1) - (3)].id));
+ Setattr((yyval.node),"enumvalue", (yyvsp[(3) - (3)].dtype).val);
+ if ((yyvsp[(3) - (3)].dtype).type == T_CHAR) {
+ SwigType *type = NewSwigType(T_CHAR);
+ Setattr((yyval.node),"value",NewStringf("\'%(escape)s\'", (yyvsp[(3) - (3)].dtype).val));
+ Setattr((yyval.node),"type",type);
+ Delete(type);
+ } else {
+ SwigType *type = NewSwigType(T_INT);
+ Setattr((yyval.node),"value",(yyvsp[(1) - (3)].id));
+ Setattr((yyval.node),"type",type);
+ Delete(type);
+ }
+ SetFlag((yyval.node),"feature:immutable");
+ }
+ break;
+
+ case 348:
+#line 5424 "parser.y"
+ { (yyval.node) = 0; }
+ break;
+
+ case 349:
+#line 5427 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(1) - (1)].dtype);
+ if (((yyval.dtype).type != T_INT) && ((yyval.dtype).type != T_UINT) &&
+ ((yyval.dtype).type != T_LONG) && ((yyval.dtype).type != T_ULONG) &&
+ ((yyval.dtype).type != T_SHORT) && ((yyval.dtype).type != T_USHORT) &&
+ ((yyval.dtype).type != T_SCHAR) && ((yyval.dtype).type != T_UCHAR) &&
+ ((yyval.dtype).type != T_CHAR)) {
+ Swig_error(cparse_file,cparse_line,"Type error. Expecting an int\n");
+ }
+ if ((yyval.dtype).type == T_CHAR) (yyval.dtype).type = T_INT;
+ }
+ break;
+
+ case 350:
+#line 5442 "parser.y"
+ { (yyval.dtype) = (yyvsp[(1) - (1)].dtype); }
+ break;
+
+ case 351:
+#line 5443 "parser.y"
+ {
+ Node *n;
+ (yyval.dtype).val = (yyvsp[(1) - (1)].type);
+ (yyval.dtype).type = T_INT;
+ /* Check if value is in scope */
+ n = Swig_symbol_clookup((yyvsp[(1) - (1)].type),0);
+ if (n) {
+ /* A band-aid for enum values used in expressions. */
+ if (Strcmp(nodeType(n),"enumitem") == 0) {
+ String *q = Swig_symbol_qualified(n);
+ if (q) {
+ (yyval.dtype).val = NewStringf("%s::%s", q, Getattr(n,"name"));
+ Delete(q);
+ }
+ }
+ }
+ }
+ break;
+
+ case 352:
+#line 5462 "parser.y"
+ { (yyval.dtype) = (yyvsp[(1) - (1)].dtype); }
+ break;
+
+ case 353:
+#line 5463 "parser.y"
+ {
+ (yyval.dtype).val = NewString((yyvsp[(1) - (1)].id));
+ (yyval.dtype).type = T_STRING;
+ }
+ break;
+
+ case 354:
+#line 5467 "parser.y"
+ {
+ SwigType_push((yyvsp[(3) - (5)].type),(yyvsp[(4) - (5)].decl).type);
+ (yyval.dtype).val = NewStringf("sizeof(%s)",SwigType_str((yyvsp[(3) - (5)].type),0));
+ (yyval.dtype).type = T_ULONG;
+ }
+ break;
+
+ case 355:
+#line 5472 "parser.y"
+ { (yyval.dtype) = (yyvsp[(1) - (1)].dtype); }
+ break;
+
+ case 356:
+#line 5473 "parser.y"
+ {
+ (yyval.dtype).val = NewString((yyvsp[(1) - (1)].str));
+ if (Len((yyval.dtype).val)) {
+ (yyval.dtype).rawval = NewStringf("'%(escape)s'", (yyval.dtype).val);
+ } else {
+ (yyval.dtype).rawval = NewString("'\\0'");
+ }
+ (yyval.dtype).type = T_CHAR;
+ (yyval.dtype).bitfield = 0;
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ }
+ break;
+
+ case 357:
+#line 5487 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("(%s)",(yyvsp[(2) - (3)].dtype).val);
+ (yyval.dtype).type = (yyvsp[(2) - (3)].dtype).type;
+ }
+ break;
+
+ case 358:
+#line 5494 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(4) - (4)].dtype);
+ if ((yyvsp[(4) - (4)].dtype).type != T_STRING) {
+ switch ((yyvsp[(2) - (4)].dtype).type) {
+ case T_FLOAT:
+ case T_DOUBLE:
+ case T_LONGDOUBLE:
+ case T_FLTCPLX:
+ case T_DBLCPLX:
+ (yyval.dtype).val = NewStringf("(%s)%s", (yyvsp[(2) - (4)].dtype).val, (yyvsp[(4) - (4)].dtype).val); /* SwigType_str and decimal points don't mix! */
+ break;
+ default:
+ (yyval.dtype).val = NewStringf("(%s) %s", SwigType_str((yyvsp[(2) - (4)].dtype).val,0), (yyvsp[(4) - (4)].dtype).val);
+ break;
+ }
+ }
+ }
+ break;
+
+ case 359:
+#line 5511 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(5) - (5)].dtype);
+ if ((yyvsp[(5) - (5)].dtype).type != T_STRING) {
+ SwigType_push((yyvsp[(2) - (5)].dtype).val,(yyvsp[(3) - (5)].type));
+ (yyval.dtype).val = NewStringf("(%s) %s", SwigType_str((yyvsp[(2) - (5)].dtype).val,0), (yyvsp[(5) - (5)].dtype).val);
+ }
+ }
+ break;
+
+ case 360:
+#line 5518 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(5) - (5)].dtype);
+ if ((yyvsp[(5) - (5)].dtype).type != T_STRING) {
+ SwigType_add_reference((yyvsp[(2) - (5)].dtype).val);
+ (yyval.dtype).val = NewStringf("(%s) %s", SwigType_str((yyvsp[(2) - (5)].dtype).val,0), (yyvsp[(5) - (5)].dtype).val);
+ }
+ }
+ break;
+
+ case 361:
+#line 5525 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(6) - (6)].dtype);
+ if ((yyvsp[(6) - (6)].dtype).type != T_STRING) {
+ SwigType_push((yyvsp[(2) - (6)].dtype).val,(yyvsp[(3) - (6)].type));
+ SwigType_add_reference((yyvsp[(2) - (6)].dtype).val);
+ (yyval.dtype).val = NewStringf("(%s) %s", SwigType_str((yyvsp[(2) - (6)].dtype).val,0), (yyvsp[(6) - (6)].dtype).val);
+ }
+ }
+ break;
+
+ case 362:
+#line 5533 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(2) - (2)].dtype);
+ (yyval.dtype).val = NewStringf("&%s",(yyvsp[(2) - (2)].dtype).val);
+ }
+ break;
+
+ case 363:
+#line 5537 "parser.y"
+ {
+ (yyval.dtype) = (yyvsp[(2) - (2)].dtype);
+ (yyval.dtype).val = NewStringf("*%s",(yyvsp[(2) - (2)].dtype).val);
+ }
+ break;
+
+ case 364:
+#line 5543 "parser.y"
+ { (yyval.dtype) = (yyvsp[(1) - (1)].dtype); }
+ break;
+
+ case 365:
+#line 5544 "parser.y"
+ { (yyval.dtype) = (yyvsp[(1) - (1)].dtype); }
+ break;
+
+ case 366:
+#line 5545 "parser.y"
+ { (yyval.dtype) = (yyvsp[(1) - (1)].dtype); }
+ break;
+
+ case 367:
+#line 5546 "parser.y"
+ { (yyval.dtype) = (yyvsp[(1) - (1)].dtype); }
+ break;
+
+ case 368:
+#line 5547 "parser.y"
+ { (yyval.dtype) = (yyvsp[(1) - (1)].dtype); }
+ break;
+
+ case 369:
+#line 5548 "parser.y"
+ { (yyval.dtype) = (yyvsp[(1) - (1)].dtype); }
+ break;
+
+ case 370:
+#line 5549 "parser.y"
+ { (yyval.dtype) = (yyvsp[(1) - (1)].dtype); }
+ break;
+
+ case 371:
+#line 5552 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s+%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = promote((yyvsp[(1) - (3)].dtype).type,(yyvsp[(3) - (3)].dtype).type);
+ }
+ break;
+
+ case 372:
+#line 5556 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s-%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = promote((yyvsp[(1) - (3)].dtype).type,(yyvsp[(3) - (3)].dtype).type);
+ }
+ break;
+
+ case 373:
+#line 5560 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s*%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = promote((yyvsp[(1) - (3)].dtype).type,(yyvsp[(3) - (3)].dtype).type);
+ }
+ break;
+
+ case 374:
+#line 5564 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s/%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = promote((yyvsp[(1) - (3)].dtype).type,(yyvsp[(3) - (3)].dtype).type);
+ }
+ break;
+
+ case 375:
+#line 5568 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s%%%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = promote((yyvsp[(1) - (3)].dtype).type,(yyvsp[(3) - (3)].dtype).type);
+ }
+ break;
+
+ case 376:
+#line 5572 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s&%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = promote((yyvsp[(1) - (3)].dtype).type,(yyvsp[(3) - (3)].dtype).type);
+ }
+ break;
+
+ case 377:
+#line 5576 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s|%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = promote((yyvsp[(1) - (3)].dtype).type,(yyvsp[(3) - (3)].dtype).type);
+ }
+ break;
+
+ case 378:
+#line 5580 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s^%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = promote((yyvsp[(1) - (3)].dtype).type,(yyvsp[(3) - (3)].dtype).type);
+ }
+ break;
+
+ case 379:
+#line 5584 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s << %s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = promote_type((yyvsp[(1) - (3)].dtype).type);
+ }
+ break;
+
+ case 380:
+#line 5588 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s >> %s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = promote_type((yyvsp[(1) - (3)].dtype).type);
+ }
+ break;
+
+ case 381:
+#line 5592 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s&&%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = T_INT;
+ }
+ break;
+
+ case 382:
+#line 5596 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s||%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = T_INT;
+ }
+ break;
+
+ case 383:
+#line 5600 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s==%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = T_INT;
+ }
+ break;
+
+ case 384:
+#line 5604 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s!=%s",(yyvsp[(1) - (3)].dtype).val,(yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = T_INT;
+ }
+ break;
+
+ case 385:
+#line 5618 "parser.y"
+ {
+ /* Putting >= in the expression literally causes an infinite
+ * loop somewhere in the type system. Just workaround for now
+ * - SWIG_GE is defined in swiglabels.swg. */
+ (yyval.dtype).val = NewStringf("%s SWIG_GE %s", (yyvsp[(1) - (3)].dtype).val, (yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = T_INT;
+ }
+ break;
+
+ case 386:
+#line 5625 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s SWIG_LE %s", (yyvsp[(1) - (3)].dtype).val, (yyvsp[(3) - (3)].dtype).val);
+ (yyval.dtype).type = T_INT;
+ }
+ break;
+
+ case 387:
+#line 5629 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("%s?%s:%s", (yyvsp[(1) - (5)].dtype).val, (yyvsp[(3) - (5)].dtype).val, (yyvsp[(5) - (5)].dtype).val);
+ /* This may not be exactly right, but is probably good enough
+ * for the purposes of parsing constant expressions. */
+ (yyval.dtype).type = promote((yyvsp[(3) - (5)].dtype).type, (yyvsp[(5) - (5)].dtype).type);
+ }
+ break;
+
+ case 388:
+#line 5635 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("-%s",(yyvsp[(2) - (2)].dtype).val);
+ (yyval.dtype).type = (yyvsp[(2) - (2)].dtype).type;
+ }
+ break;
+
+ case 389:
+#line 5639 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("+%s",(yyvsp[(2) - (2)].dtype).val);
+ (yyval.dtype).type = (yyvsp[(2) - (2)].dtype).type;
+ }
+ break;
+
+ case 390:
+#line 5643 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("~%s",(yyvsp[(2) - (2)].dtype).val);
+ (yyval.dtype).type = (yyvsp[(2) - (2)].dtype).type;
+ }
+ break;
+
+ case 391:
+#line 5647 "parser.y"
+ {
+ (yyval.dtype).val = NewStringf("!%s",(yyvsp[(2) - (2)].dtype).val);
+ (yyval.dtype).type = T_INT;
+ }
+ break;
+
+ case 392:
+#line 5651 "parser.y"
+ {
+ String *qty;
+ skip_balanced('(',')');
+ qty = Swig_symbol_type_qualify((yyvsp[(1) - (2)].type),0);
+ if (SwigType_istemplate(qty)) {
+ String *nstr = SwigType_namestr(qty);
+ Delete(qty);
+ qty = nstr;
+ }
+ (yyval.dtype).val = NewStringf("%s%s",qty,scanner_ccode);
+ Clear(scanner_ccode);
+ (yyval.dtype).type = T_INT;
+ Delete(qty);
+ }
+ break;
+
+ case 393:
+#line 5667 "parser.y"
+ {
+ (yyval.bases) = (yyvsp[(1) - (1)].bases);
+ }
+ break;
+
+ case 394:
+#line 5672 "parser.y"
+ { inherit_list = 1; }
+ break;
+
+ case 395:
+#line 5672 "parser.y"
+ { (yyval.bases) = (yyvsp[(3) - (3)].bases); inherit_list = 0; }
+ break;
+
+ case 396:
+#line 5673 "parser.y"
+ { (yyval.bases) = 0; }
+ break;
+
+ case 397:
+#line 5676 "parser.y"
+ {
+ Hash *list = NewHash();
+ Node *base = (yyvsp[(1) - (1)].node);
+ Node *name = Getattr(base,"name");
+ List *lpublic = NewList();
+ List *lprotected = NewList();
+ List *lprivate = NewList();
+ Setattr(list,"public",lpublic);
+ Setattr(list,"protected",lprotected);
+ Setattr(list,"private",lprivate);
+ Delete(lpublic);
+ Delete(lprotected);
+ Delete(lprivate);
+ Append(Getattr(list,Getattr(base,"access")),name);
+ (yyval.bases) = list;
+ }
+ break;
+
+ case 398:
+#line 5693 "parser.y"
+ {
+ Hash *list = (yyvsp[(1) - (3)].bases);
+ Node *base = (yyvsp[(3) - (3)].node);
+ Node *name = Getattr(base,"name");
+ Append(Getattr(list,Getattr(base,"access")),name);
+ (yyval.bases) = list;
+ }
+ break;
+
+ case 399:
+#line 5702 "parser.y"
+ {
+ (yyval.node) = NewHash();
+ Setfile((yyval.node),cparse_file);
+ Setline((yyval.node),cparse_line);
+ Setattr((yyval.node),"name",(yyvsp[(2) - (2)].str));
+ if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) {
+ Setattr((yyval.node),"access","private");
+ Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file,cparse_line,
+ "No access specifier given for base class %s (ignored).\n",(yyvsp[(2) - (2)].str));
+ } else {
+ Setattr((yyval.node),"access","public");
+ }
+ }
+ break;
+
+ case 400:
+#line 5715 "parser.y"
+ {
+ (yyval.node) = NewHash();
+ Setfile((yyval.node),cparse_file);
+ Setline((yyval.node),cparse_line);
+ Setattr((yyval.node),"name",(yyvsp[(4) - (4)].str));
+ Setattr((yyval.node),"access",(yyvsp[(2) - (4)].id));
+ if (Strcmp((yyvsp[(2) - (4)].id),"public") != 0) {
+ Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file,
+ cparse_line,"%s inheritance ignored.\n", (yyvsp[(2) - (4)].id));
+ }
+ }
+ break;
+
+ case 401:
+#line 5728 "parser.y"
+ { (yyval.id) = (char*)"public"; }
+ break;
+
+ case 402:
+#line 5729 "parser.y"
+ { (yyval.id) = (char*)"private"; }
+ break;
+
+ case 403:
+#line 5730 "parser.y"
+ { (yyval.id) = (char*)"protected"; }
+ break;
+
+ case 404:
+#line 5734 "parser.y"
+ {
+ (yyval.id) = (char*)"class";
+ if (!inherit_list) last_cpptype = (yyval.id);
+ }
+ break;
+
+ case 405:
+#line 5738 "parser.y"
+ {
+ (yyval.id) = (char *)"typename";
+ if (!inherit_list) last_cpptype = (yyval.id);
+ }
+ break;
+
+ case 406:
+#line 5744 "parser.y"
+ {
+ (yyval.id) = (yyvsp[(1) - (1)].id);
+ }
+ break;
+
+ case 407:
+#line 5747 "parser.y"
+ {
+ (yyval.id) = (char*)"struct";
+ if (!inherit_list) last_cpptype = (yyval.id);
+ }
+ break;
+
+ case 408:
+#line 5751 "parser.y"
+ {
+ (yyval.id) = (char*)"union";
+ if (!inherit_list) last_cpptype = (yyval.id);
+ }
+ break;
+
+ case 411:
+#line 5761 "parser.y"
+ {
+ (yyval.dtype).qualifier = (yyvsp[(1) - (1)].str);
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ }
+ break;
+
+ case 412:
+#line 5766 "parser.y"
+ {
+ (yyval.dtype).qualifier = 0;
+ (yyval.dtype).throws = (yyvsp[(3) - (4)].pl);
+ (yyval.dtype).throwf = NewString("1");
+ }
+ break;
+
+ case 413:
+#line 5771 "parser.y"
+ {
+ (yyval.dtype).qualifier = (yyvsp[(1) - (5)].str);
+ (yyval.dtype).throws = (yyvsp[(4) - (5)].pl);
+ (yyval.dtype).throwf = NewString("1");
+ }
+ break;
+
+ case 414:
+#line 5776 "parser.y"
+ {
+ (yyval.dtype).qualifier = 0;
+ (yyval.dtype).throws = 0;
+ (yyval.dtype).throwf = 0;
+ }
+ break;
+
+ case 415:
+#line 5783 "parser.y"
+ {
+ Clear(scanner_ccode);
+ (yyval.decl).have_parms = 0;
+ (yyval.decl).defarg = 0;
+ (yyval.decl).throws = (yyvsp[(1) - (3)].dtype).throws;
+ (yyval.decl).throwf = (yyvsp[(1) - (3)].dtype).throwf;
+ }
+ break;
+
+ case 416:
+#line 5790 "parser.y"
+ {
+ skip_balanced('{','}');
+ (yyval.decl).have_parms = 0;
+ (yyval.decl).defarg = 0;
+ (yyval.decl).throws = (yyvsp[(1) - (3)].dtype).throws;
+ (yyval.decl).throwf = (yyvsp[(1) - (3)].dtype).throwf;
+ }
+ break;
+
+ case 417:
+#line 5797 "parser.y"
+ {
+ Clear(scanner_ccode);
+ (yyval.decl).parms = (yyvsp[(2) - (4)].pl);
+ (yyval.decl).have_parms = 1;
+ (yyval.decl).defarg = 0;
+ (yyval.decl).throws = 0;
+ (yyval.decl).throwf = 0;
+ }
+ break;
+
+ case 418:
+#line 5805 "parser.y"
+ {
+ skip_balanced('{','}');
+ (yyval.decl).parms = (yyvsp[(2) - (4)].pl);
+ (yyval.decl).have_parms = 1;
+ (yyval.decl).defarg = 0;
+ (yyval.decl).throws = 0;
+ (yyval.decl).throwf = 0;
+ }
+ break;
+
+ case 419:
+#line 5813 "parser.y"
+ {
+ (yyval.decl).have_parms = 0;
+ (yyval.decl).defarg = (yyvsp[(2) - (3)].dtype).val;
+ (yyval.decl).throws = 0;
+ (yyval.decl).throwf = 0;
+ }
+ break;
+
+ case 424:
+#line 5829 "parser.y"
+ {
+ skip_balanced('(',')');
+ Clear(scanner_ccode);
+ }
+ break;
+
+ case 425:
+#line 5835 "parser.y"
+ {
+ String *s = NewStringEmpty();
+ SwigType_add_template(s,(yyvsp[(2) - (3)].p));
+ (yyval.id) = Char(s);
+ scanner_last_id(1);
+ }
+ break;
+
+ case 426:
+#line 5841 "parser.y"
+ { (yyval.id) = (char*)""; }
+ break;
+
+ case 427:
+#line 5844 "parser.y"
+ { (yyval.id) = (yyvsp[(1) - (1)].id); }
+ break;
+
+ case 428:
+#line 5845 "parser.y"
+ { (yyval.id) = (yyvsp[(1) - (1)].id); }
+ break;
+
+ case 429:
+#line 5848 "parser.y"
+ { (yyval.id) = (yyvsp[(1) - (1)].id); }
+ break;
+
+ case 430:
+#line 5849 "parser.y"
+ { (yyval.id) = 0; }
+ break;
+
+ case 431:
+#line 5852 "parser.y"
+ {
+ (yyval.str) = 0;
+ if (!(yyval.str)) (yyval.str) = NewStringf("%s%s", (yyvsp[(1) - (2)].str),(yyvsp[(2) - (2)].str));
+ Delete((yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 432:
+#line 5857 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s%s",(yyvsp[(3) - (4)].str),(yyvsp[(4) - (4)].str));
+ Delete((yyvsp[(4) - (4)].str));
+ }
+ break;
+
+ case 433:
+#line 5861 "parser.y"
+ {
+ (yyval.str) = NewString((yyvsp[(1) - (1)].str));
+ }
+ break;
+
+ case 434:
+#line 5864 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s",(yyvsp[(3) - (3)].str));
+ }
+ break;
+
+ case 435:
+#line 5867 "parser.y"
+ {
+ (yyval.str) = NewString((yyvsp[(1) - (1)].str));
+ }
+ break;
+
+ case 436:
+#line 5870 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s",(yyvsp[(3) - (3)].str));
+ }
+ break;
+
+ case 437:
+#line 5875 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s%s",(yyvsp[(2) - (3)].str),(yyvsp[(3) - (3)].str));
+ Delete((yyvsp[(3) - (3)].str));
+ }
+ break;
+
+ case 438:
+#line 5879 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s",(yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 439:
+#line 5882 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s",(yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 440:
+#line 5889 "parser.y"
+ {
+ (yyval.str) = NewStringf("::~%s",(yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 441:
+#line 5895 "parser.y"
+ {
+ (yyval.str) = NewStringf("%s%s",(yyvsp[(1) - (2)].id),(yyvsp[(2) - (2)].id));
+ /* if (Len($2)) {
+ scanner_last_id(1);
+ } */
+ }
+ break;
+
+ case 442:
+#line 5904 "parser.y"
+ {
+ (yyval.str) = 0;
+ if (!(yyval.str)) (yyval.str) = NewStringf("%s%s", (yyvsp[(1) - (2)].id),(yyvsp[(2) - (2)].str));
+ Delete((yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 443:
+#line 5909 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s%s",(yyvsp[(3) - (4)].id),(yyvsp[(4) - (4)].str));
+ Delete((yyvsp[(4) - (4)].str));
+ }
+ break;
+
+ case 444:
+#line 5913 "parser.y"
+ {
+ (yyval.str) = NewString((yyvsp[(1) - (1)].id));
+ }
+ break;
+
+ case 445:
+#line 5916 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s",(yyvsp[(3) - (3)].id));
+ }
+ break;
+
+ case 446:
+#line 5919 "parser.y"
+ {
+ (yyval.str) = NewString((yyvsp[(1) - (1)].str));
+ }
+ break;
+
+ case 447:
+#line 5922 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s",(yyvsp[(3) - (3)].str));
+ }
+ break;
+
+ case 448:
+#line 5927 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s%s",(yyvsp[(2) - (3)].id),(yyvsp[(3) - (3)].str));
+ Delete((yyvsp[(3) - (3)].str));
+ }
+ break;
+
+ case 449:
+#line 5931 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s",(yyvsp[(2) - (2)].id));
+ }
+ break;
+
+ case 450:
+#line 5934 "parser.y"
+ {
+ (yyval.str) = NewStringf("::%s",(yyvsp[(2) - (2)].str));
+ }
+ break;
+
+ case 451:
+#line 5937 "parser.y"
+ {
+ (yyval.str) = NewStringf("::~%s",(yyvsp[(2) - (2)].id));
+ }
+ break;
+
+ case 452:
+#line 5943 "parser.y"
+ {
+ (yyval.id) = (char *) malloc(strlen((yyvsp[(1) - (2)].id))+strlen((yyvsp[(2) - (2)].id))+1);
+ strcpy((yyval.id),(yyvsp[(1) - (2)].id));
+ strcat((yyval.id),(yyvsp[(2) - (2)].id));
+ }
+ break;
+
+ case 453:
+#line 5948 "parser.y"
+ { (yyval.id) = (yyvsp[(1) - (1)].id);}
+ break;
+
+ case 454:
+#line 5951 "parser.y"
+ {
+ (yyval.str) = NewString((yyvsp[(1) - (1)].id));
+ }
+ break;
+
+ case 455:
+#line 5954 "parser.y"
+ {
+ skip_balanced('{','}');
+ (yyval.str) = NewString(scanner_ccode);
+ }
+ break;
+
+ case 456:
+#line 5958 "parser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+ }
+ break;
+
+ case 457:
+#line 5963 "parser.y"
+ {
+ Hash *n;
+ (yyval.node) = NewHash();
+ n = (yyvsp[(2) - (3)].node);
+ while(n) {
+ String *name, *value;
+ name = Getattr(n,"name");
+ value = Getattr(n,"value");
+ if (!value) value = (String *) "1";
+ Setattr((yyval.node),name, value);
+ n = nextSibling(n);
+ }
+ }
+ break;
+
+ case 458:
+#line 5976 "parser.y"
+ { (yyval.node) = 0; }
+ break;
+
+ case 459:
+#line 5980 "parser.y"
+ {
+ (yyval.node) = NewHash();
+ Setattr((yyval.node),"name",(yyvsp[(1) - (3)].id));
+ Setattr((yyval.node),"value",(yyvsp[(3) - (3)].id));
+ }
+ break;
+
+ case 460:
+#line 5985 "parser.y"
+ {
+ (yyval.node) = NewHash();
+ Setattr((yyval.node),"name",(yyvsp[(1) - (5)].id));
+ Setattr((yyval.node),"value",(yyvsp[(3) - (5)].id));
+ set_nextSibling((yyval.node),(yyvsp[(5) - (5)].node));
+ }
+ break;
+
+ case 461:
+#line 5991 "parser.y"
+ {
+ (yyval.node) = NewHash();
+ Setattr((yyval.node),"name",(yyvsp[(1) - (1)].id));
+ }
+ break;
+
+ case 462:
+#line 5995 "parser.y"
+ {
+ (yyval.node) = NewHash();
+ Setattr((yyval.node),"name",(yyvsp[(1) - (3)].id));
+ set_nextSibling((yyval.node),(yyvsp[(3) - (3)].node));
+ }
+ break;
+
+ case 463:
+#line 6000 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(3) - (3)].node);
+ Setattr((yyval.node),"name",(yyvsp[(1) - (3)].id));
+ }
+ break;
+
+ case 464:
+#line 6004 "parser.y"
+ {
+ (yyval.node) = (yyvsp[(3) - (5)].node);
+ Setattr((yyval.node),"name",(yyvsp[(1) - (5)].id));
+ set_nextSibling((yyval.node),(yyvsp[(5) - (5)].node));
+ }
+ break;
+
+ case 465:
+#line 6011 "parser.y"
+ {
+ (yyval.id) = (yyvsp[(1) - (1)].id);
+ }
+ break;
+
+ case 466:
+#line 6014 "parser.y"
+ {
+ (yyval.id) = Char((yyvsp[(1) - (1)].dtype).val);
+ }
+ break;
+
+
+/* Line 1267 of yacc.c. */
+#line 10178 "y.tab.c"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse look-ahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse look-ahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ *++yyvsp = yylval;
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+#line 6021 "parser.y"
+
+
+SwigType *Swig_cparse_type(String *s) {
+ String *ns;
+ 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;
+}
+
+
+Parm *Swig_cparse_parm(String *s) {
+ String *ns;
+ ns = NewStringf("%s;",s);
+ Seek(ns,0,SEEK_SET);
+ scanner_file(ns);
+ top = 0;
+ scanner_next_token(PARSEPARM);
+ yyparse();
+ /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
+ Delete(ns);
+ return top;
+}
+
+
+ParmList *Swig_cparse_parms(String *s) {
+ String *ns;
+ char *cs = Char(s);
+ if (cs && cs[0] != '(') {
+ ns = NewStringf("(%s);",s);
+ } else {
+ ns = NewStringf("%s;",s);
+ }
+ Seek(ns,0,SEEK_SET);
+ scanner_file(ns);
+ top = 0;
+ scanner_next_token(PARSEPARMS);
+ yyparse();
+ /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
+ return top;
+}
+
+
diff --git a/Source/CParse/parser.h b/Source/CParse/parser.h
new file mode 100644
index 0000000..47c4459
--- /dev/null
+++ b/Source/CParse/parser.h
@@ -0,0 +1,351 @@
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ID = 258,
+ HBLOCK = 259,
+ POUND = 260,
+ STRING = 261,
+ INCLUDE = 262,
+ IMPORT = 263,
+ INSERT = 264,
+ CHARCONST = 265,
+ NUM_INT = 266,
+ NUM_FLOAT = 267,
+ NUM_UNSIGNED = 268,
+ NUM_LONG = 269,
+ NUM_ULONG = 270,
+ NUM_LONGLONG = 271,
+ NUM_ULONGLONG = 272,
+ TYPEDEF = 273,
+ TYPE_INT = 274,
+ TYPE_UNSIGNED = 275,
+ TYPE_SHORT = 276,
+ TYPE_LONG = 277,
+ TYPE_FLOAT = 278,
+ TYPE_DOUBLE = 279,
+ TYPE_CHAR = 280,
+ TYPE_WCHAR = 281,
+ TYPE_VOID = 282,
+ TYPE_SIGNED = 283,
+ TYPE_BOOL = 284,
+ TYPE_COMPLEX = 285,
+ TYPE_TYPEDEF = 286,
+ TYPE_RAW = 287,
+ TYPE_NON_ISO_INT8 = 288,
+ TYPE_NON_ISO_INT16 = 289,
+ TYPE_NON_ISO_INT32 = 290,
+ TYPE_NON_ISO_INT64 = 291,
+ LPAREN = 292,
+ RPAREN = 293,
+ COMMA = 294,
+ SEMI = 295,
+ EXTERN = 296,
+ INIT = 297,
+ LBRACE = 298,
+ RBRACE = 299,
+ PERIOD = 300,
+ CONST_QUAL = 301,
+ VOLATILE = 302,
+ REGISTER = 303,
+ STRUCT = 304,
+ UNION = 305,
+ EQUAL = 306,
+ SIZEOF = 307,
+ MODULE = 308,
+ LBRACKET = 309,
+ RBRACKET = 310,
+ ILLEGAL = 311,
+ CONSTANT = 312,
+ NAME = 313,
+ RENAME = 314,
+ NAMEWARN = 315,
+ EXTEND = 316,
+ PRAGMA = 317,
+ FEATURE = 318,
+ VARARGS = 319,
+ ENUM = 320,
+ CLASS = 321,
+ TYPENAME = 322,
+ PRIVATE = 323,
+ PUBLIC = 324,
+ PROTECTED = 325,
+ COLON = 326,
+ STATIC = 327,
+ VIRTUAL = 328,
+ FRIEND = 329,
+ THROW = 330,
+ CATCH = 331,
+ EXPLICIT = 332,
+ USING = 333,
+ NAMESPACE = 334,
+ NATIVE = 335,
+ INLINE = 336,
+ TYPEMAP = 337,
+ EXCEPT = 338,
+ ECHO = 339,
+ APPLY = 340,
+ CLEAR = 341,
+ SWIGTEMPLATE = 342,
+ FRAGMENT = 343,
+ WARN = 344,
+ LESSTHAN = 345,
+ GREATERTHAN = 346,
+ MODULO = 347,
+ DELETE_KW = 348,
+ LESSTHANOREQUALTO = 349,
+ GREATERTHANOREQUALTO = 350,
+ EQUALTO = 351,
+ NOTEQUALTO = 352,
+ QUESTIONMARK = 353,
+ TYPES = 354,
+ PARMS = 355,
+ NONID = 356,
+ DSTAR = 357,
+ DCNOT = 358,
+ TEMPLATE = 359,
+ OPERATOR = 360,
+ COPERATOR = 361,
+ PARSETYPE = 362,
+ PARSEPARM = 363,
+ PARSEPARMS = 364,
+ CAST = 365,
+ LOR = 366,
+ LAND = 367,
+ OR = 368,
+ XOR = 369,
+ AND = 370,
+ RSHIFT = 371,
+ LSHIFT = 372,
+ MINUS = 373,
+ PLUS = 374,
+ MODULUS = 375,
+ SLASH = 376,
+ STAR = 377,
+ LNOT = 378,
+ NOT = 379,
+ UMINUS = 380,
+ DCOLON = 381
+ };
+#endif
+/* Tokens. */
+#define ID 258
+#define HBLOCK 259
+#define POUND 260
+#define STRING 261
+#define INCLUDE 262
+#define IMPORT 263
+#define INSERT 264
+#define CHARCONST 265
+#define NUM_INT 266
+#define NUM_FLOAT 267
+#define NUM_UNSIGNED 268
+#define NUM_LONG 269
+#define NUM_ULONG 270
+#define NUM_LONGLONG 271
+#define NUM_ULONGLONG 272
+#define TYPEDEF 273
+#define TYPE_INT 274
+#define TYPE_UNSIGNED 275
+#define TYPE_SHORT 276
+#define TYPE_LONG 277
+#define TYPE_FLOAT 278
+#define TYPE_DOUBLE 279
+#define TYPE_CHAR 280
+#define TYPE_WCHAR 281
+#define TYPE_VOID 282
+#define TYPE_SIGNED 283
+#define TYPE_BOOL 284
+#define TYPE_COMPLEX 285
+#define TYPE_TYPEDEF 286
+#define TYPE_RAW 287
+#define TYPE_NON_ISO_INT8 288
+#define TYPE_NON_ISO_INT16 289
+#define TYPE_NON_ISO_INT32 290
+#define TYPE_NON_ISO_INT64 291
+#define LPAREN 292
+#define RPAREN 293
+#define COMMA 294
+#define SEMI 295
+#define EXTERN 296
+#define INIT 297
+#define LBRACE 298
+#define RBRACE 299
+#define PERIOD 300
+#define CONST_QUAL 301
+#define VOLATILE 302
+#define REGISTER 303
+#define STRUCT 304
+#define UNION 305
+#define EQUAL 306
+#define SIZEOF 307
+#define MODULE 308
+#define LBRACKET 309
+#define RBRACKET 310
+#define ILLEGAL 311
+#define CONSTANT 312
+#define NAME 313
+#define RENAME 314
+#define NAMEWARN 315
+#define EXTEND 316
+#define PRAGMA 317
+#define FEATURE 318
+#define VARARGS 319
+#define ENUM 320
+#define CLASS 321
+#define TYPENAME 322
+#define PRIVATE 323
+#define PUBLIC 324
+#define PROTECTED 325
+#define COLON 326
+#define STATIC 327
+#define VIRTUAL 328
+#define FRIEND 329
+#define THROW 330
+#define CATCH 331
+#define EXPLICIT 332
+#define USING 333
+#define NAMESPACE 334
+#define NATIVE 335
+#define INLINE 336
+#define TYPEMAP 337
+#define EXCEPT 338
+#define ECHO 339
+#define APPLY 340
+#define CLEAR 341
+#define SWIGTEMPLATE 342
+#define FRAGMENT 343
+#define WARN 344
+#define LESSTHAN 345
+#define GREATERTHAN 346
+#define MODULO 347
+#define DELETE_KW 348
+#define LESSTHANOREQUALTO 349
+#define GREATERTHANOREQUALTO 350
+#define EQUALTO 351
+#define NOTEQUALTO 352
+#define QUESTIONMARK 353
+#define TYPES 354
+#define PARMS 355
+#define NONID 356
+#define DSTAR 357
+#define DCNOT 358
+#define TEMPLATE 359
+#define OPERATOR 360
+#define COPERATOR 361
+#define PARSETYPE 362
+#define PARSEPARM 363
+#define PARSEPARMS 364
+#define CAST 365
+#define LOR 366
+#define LAND 367
+#define OR 368
+#define XOR 369
+#define AND 370
+#define RSHIFT 371
+#define LSHIFT 372
+#define MINUS 373
+#define PLUS 374
+#define MODULUS 375
+#define SLASH 376
+#define STAR 377
+#define LNOT 378
+#define NOT 379
+#define UMINUS 380
+#define DCOLON 381
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 1440 "parser.y"
+{
+ char *id;
+ List *bases;
+ struct Define {
+ String *val;
+ String *rawval;
+ int type;
+ String *qualifier;
+ String *bitfield;
+ Parm *throws;
+ String *throwf;
+ } dtype;
+ struct {
+ char *type;
+ String *filename;
+ int line;
+ } loc;
+ struct {
+ char *id;
+ SwigType *type;
+ String *defarg;
+ ParmList *parms;
+ short have_parms;
+ ParmList *throws;
+ String *throwf;
+ } decl;
+ Parm *tparms;
+ struct {
+ String *method;
+ Hash *kwargs;
+ } tmap;
+ struct {
+ String *type;
+ String *us;
+ } ptype;
+ SwigType *type;
+ String *str;
+ Parm *p;
+ ParmList *pl;
+ int ivalue;
+ Node *node;
+}
+/* Line 1489 of yacc.c. */
+#line 344 "y.tab.h"
+ YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
new file mode 100644
index 0000000..9a36030
--- /dev/null
+++ b/Source/CParse/parser.y
@@ -0,0 +1,6066 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+%{
+
+#define yylex yylex
+
+char cvsroot_parser_y[] = "$Id: parser.y 11582 2009-08-15 10:40:19Z wsfulton $";
+
+#include "swig.h"
+#include "cparse.h"
+#include "preprocessor.h"
+#include <ctype.h>
+
+/* We do this for portability */
+#undef alloca
+#define alloca malloc
+
+/* -----------------------------------------------------------------------------
+ * Externals
+ * ----------------------------------------------------------------------------- */
+
+int yyparse();
+
+/* NEW Variables */
+
+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;
+static int extendmode = 0;
+static int compact_default_args = 0;
+static int template_reduce = 0;
+static int cparse_externc = 0;
+
+static int max_class_levels = 0;
+static int class_level = 0;
+static Node **class_decl = NULL;
+
+/* -----------------------------------------------------------------------------
+ * Assist Functions
+ * ----------------------------------------------------------------------------- */
+
+
+
+/* Called by the parser (yyparse) when an error is found.*/
+static void yyerror (const char *e) {
+ (void)e;
+}
+
+static Node *new_node(const_String_or_char_ptr 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;
+ Iterator k;
+ nn = NewHash();
+ Setfile(nn,Getfile(n));
+ Setline(nn,Getline(n));
+ for (k = First(n); k.key; k = Next(k)) {
+ String *ci;
+ String *key = k.key;
+ char *ckey = Char(key);
+ if ((strcmp(ckey,"nextSibling") == 0) ||
+ (strcmp(ckey,"previousSibling") == 0) ||
+ (strcmp(ckey,"parentNode") == 0) ||
+ (strcmp(ckey,"lastChild") == 0)) {
+ continue;
+ }
+ if (Strncmp(key,"csym:",5) == 0) continue;
+ /* We do copy sym:name. For templates */
+ if ((strcmp(ckey,"sym:name") == 0) ||
+ (strcmp(ckey,"sym:weak") == 0) ||
+ (strcmp(ckey,"sym:typename") == 0)) {
+ String *ci = Copy(k.item);
+ Setattr(nn,key, ci);
+ Delete(ci);
+ continue;
+ }
+ if (strcmp(ckey,"sym:symtab") == 0) {
+ Setattr(nn,"sym:needs_symtab", "1");
+ }
+ /* We don't copy any other symbol table attributes */
+ if (strncmp(ckey,"sym:",4) == 0) {
+ continue;
+ }
+ /* If children. We copy them recursively using this function */
+ if (strcmp(ckey,"firstChild") == 0) {
+ /* Copy children */
+ Node *cn = k.item;
+ while (cn) {
+ Node *copy = copy_node(cn);
+ appendChild(nn,copy);
+ Delete(copy);
+ 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(ckey,"symtab") == 0) {
+ /* Node defined a symbol table. */
+ Setattr(nn,"requires_symtab","1");
+ continue;
+ }
+ /* Can't copy nodes */
+ if (strcmp(ckey,"node") == 0) {
+ continue;
+ }
+ if ((strcmp(ckey,"parms") == 0) || (strcmp(ckey,"pattern") == 0) || (strcmp(ckey,"throws") == 0)
+ || (strcmp(ckey,"kwargs") == 0)) {
+ ParmList *pl = CopyParmList(k.item);
+ Setattr(nn,key,pl);
+ Delete(pl);
+ continue;
+ }
+ /* Looks okay. Just copy the data using Copy */
+ ci = Copy(k.item);
+ Setattr(nn, key, ci);
+ Delete(ci);
+ }
+ return nn;
+}
+
+/* -----------------------------------------------------------------------------
+ * Variables
+ * ----------------------------------------------------------------------------- */
+
+static 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
+
+/* include types */
+static int import_mode = 0;
+
+void SWIG_typemap_lang(const char *tm_lang) {
+ typemap_lang = Swig_copy_string(tm_lang);
+}
+
+void SWIG_cparse_set_compact_default_args(int defargs) {
+ compact_default_args = defargs;
+}
+
+int SWIG_cparse_template_reduce(int treduce) {
+ template_reduce = treduce;
+ return treduce;
+}
+
+/* -----------------------------------------------------------------------------
+ * Assist functions
+ * ----------------------------------------------------------------------------- */
+
+static int promote_type(int t) {
+ if (t <= T_UCHAR || t == T_CHAR) return T_INT;
+ return t;
+}
+
+/* Perform type-promotion for binary operators */
+static int promote(int t1, int t2) {
+ t1 = promote_type(t1);
+ t2 = promote_type(t2);
+ return t1 > t2 ? t1 : t2;
+}
+
+static String *yyrename = 0;
+
+/* Forward renaming operator */
+
+static String *resolve_node_scope(String *cname);
+
+
+Hash *Swig_cparse_features(void) {
+ static Hash *features_hash = 0;
+ if (!features_hash) features_hash = NewHash();
+ return features_hash;
+}
+
+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);
+ }
+}
+
+/* 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(Node *n, String *name,SwigType *decl) {
+ int destructor = name && (*(Char(name)) == '~');
+
+ if (yyrename) {
+ String *s = NewString(yyrename);
+ Delete(yyrename);
+ yyrename = 0;
+ if (destructor && (*(Char(s)) != '~')) {
+ Insert(s,0,"~");
+ }
+ return s;
+ }
+
+ if (!name) return 0;
+ return Swig_name_make(n,Namespaceprefix,name,decl,add_oldname);
+}
+
+/* Generate an unnamed identifier */
+static String *make_unnamed() {
+ unnamed++;
+ return NewStringf("$unnamed%d$",unnamed);
+}
+
+/* Return if the node is a friend declaration */
+static int is_friend(Node *n) {
+ return Cmp(Getattr(n,"storage"),"friend") == 0;
+}
+
+static int is_operator(String *name) {
+ return Strncmp(name,"operator ", 9) == 0;
+}
+
+
+/* Add declaration list to symbol table */
+static int add_only_one = 0;
+
+static void add_symbols(Node *n) {
+ String *decl;
+ String *wrn = 0;
+ if (inclass && n) {
+ cparse_normalize_void(n);
+ }
+ while (n) {
+ String *symname = 0;
+ /* for friends, we need to pop the scope once */
+ String *old_prefix = 0;
+ Symtab *old_scope = 0;
+ int isfriend = inclass && is_friend(n);
+ int iscdecl = Cmp(nodeType(n),"cdecl") == 0;
+ int only_csymbol = 0;
+ if (extendmode) {
+ Setattr(n,"isextension","1");
+ }
+
+ if (inclass) {
+ String *name = Getattr(n, "name");
+ if (isfriend) {
+ /* for friends, we need to add the scopename if needed */
+ String *prefix = name ? Swig_scopename_prefix(name) : 0;
+ old_prefix = Namespaceprefix;
+ old_scope = Swig_symbol_popscope();
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ if (!prefix) {
+ if (name && !is_operator(name) && Namespaceprefix) {
+ String *nname = NewStringf("%s::%s", Namespaceprefix, name);
+ Setattr(n,"name",nname);
+ Delete(nname);
+ }
+ } else {
+ Symtab *st = Swig_symbol_getscope(prefix);
+ String *ns = st ? Getattr(st,"name") : prefix;
+ String *base = Swig_scopename_last(name);
+ String *nname = NewStringf("%s::%s", ns, base);
+ Setattr(n,"name",nname);
+ Delete(nname);
+ Delete(base);
+ Delete(prefix);
+ }
+ Namespaceprefix = 0;
+ } else {
+ /* for member functions, we need to remove the redundant
+ class scope if provided, as in
+
+ struct Foo {
+ int Foo::method(int a);
+ };
+
+ */
+ String *prefix = name ? Swig_scopename_prefix(name) : 0;
+ if (prefix) {
+ if (Classprefix && (Equal(prefix,Classprefix))) {
+ String *base = Swig_scopename_last(name);
+ Setattr(n,"name",base);
+ Delete(base);
+ }
+ Delete(prefix);
+ }
+
+ /*
+ if (!Getattr(n,"parentNode") && class_level) set_parentNode(n,class_decl[class_level - 1]);
+ */
+ Setattr(n,"ismember","1");
+ }
+ }
+ if (!isfriend && inclass) {
+ if ((cplus_mode != CPLUS_PUBLIC)) {
+ only_csymbol = 1;
+ if (cplus_mode == CPLUS_PROTECTED) {
+ Setattr(n,"access", "protected");
+ only_csymbol = !Swig_need_protected(n);
+ } else {
+ Setattr(n,"access", "private");
+ /* private are needed only when they are pure virtuals - why? */
+ if ((Cmp(Getattr(n,"storage"),"virtual") == 0) && (Cmp(Getattr(n,"value"),"0") == 0)) {
+ only_csymbol = 0;
+ }
+ }
+ } else {
+ Setattr(n,"access", "public");
+ }
+ }
+ if (Getattr(n,"sym:name")) {
+ n = nextSibling(n);
+ continue;
+ }
+ decl = Getattr(n,"decl");
+ if (!SwigType_isfunction(decl)) {
+ String *name = Getattr(n,"name");
+ String *makename = Getattr(n,"parser:makename");
+ if (iscdecl) {
+ String *storage = Getattr(n, "storage");
+ if (Cmp(storage,"typedef") == 0) {
+ Setattr(n,"kind","typedef");
+ } else {
+ SwigType *type = Getattr(n,"type");
+ String *value = Getattr(n,"value");
+ Setattr(n,"kind","variable");
+ if (value && Len(value)) {
+ Setattr(n,"hasvalue","1");
+ }
+ if (type) {
+ SwigType *ty;
+ SwigType *tmp = 0;
+ if (decl) {
+ ty = tmp = Copy(type);
+ SwigType_push(ty,decl);
+ } else {
+ ty = type;
+ }
+ if (!SwigType_ismutable(ty)) {
+ SetFlag(n,"hasconsttype");
+ SetFlag(n,"feature:immutable");
+ }
+ if (tmp) Delete(tmp);
+ }
+ if (!type) {
+ Printf(stderr,"notype name %s\n", name);
+ }
+ }
+ }
+ Swig_features_get(Swig_cparse_features(), Namespaceprefix, name, 0, n);
+ if (makename) {
+ symname = make_name(n, makename,0);
+ Delattr(n,"parser:makename"); /* temporary information, don't leave it hanging around */
+ } else {
+ makename = name;
+ symname = make_name(n, makename,0);
+ }
+
+ if (!symname) {
+ symname = Copy(Getattr(n,"unnamed"));
+ }
+ if (symname) {
+ wrn = Swig_name_warning(n, Namespaceprefix, symname,0);
+ }
+ } else {
+ String *name = Getattr(n,"name");
+ SwigType *fdecl = Copy(decl);
+ SwigType *fun = SwigType_pop_function(fdecl);
+ if (iscdecl) {
+ Setattr(n,"kind","function");
+ }
+
+ Swig_features_get(Swig_cparse_features(),Namespaceprefix,name,fun,n);
+
+ symname = make_name(n, name,fun);
+ wrn = Swig_name_warning(n, Namespaceprefix,symname,fun);
+
+ Delete(fdecl);
+ Delete(fun);
+
+ }
+ if (!symname) {
+ n = nextSibling(n);
+ continue;
+ }
+ if (only_csymbol || GetFlag(n,"feature:ignore")) {
+ /* Only add to C symbol table and continue */
+ Swig_symbol_add(0, n);
+ } else if (strncmp(Char(symname),"$ignore",7) == 0) {
+ char *c = Char(symname)+7;
+ SetFlag(n,"feature:ignore");
+ if (strlen(c)) {
+ SWIG_WARN_NODE_BEGIN(n);
+ Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1);
+ SWIG_WARN_NODE_END(n);
+ }
+ Swig_symbol_add(0, n);
+ } else {
+ Node *c;
+ if ((wrn) && (Len(wrn))) {
+ String *metaname = symname;
+ if (!Getmeta(metaname,"already_warned")) {
+ SWIG_WARN_NODE_BEGIN(n);
+ Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn);
+ SWIG_WARN_NODE_END(n);
+ Setmeta(metaname,"already_warned","1");
+ }
+ }
+ c = Swig_symbol_add(symname,n);
+
+ if (c != n) {
+ /* symbol conflict attempting to add in the new symbol */
+ if (Getattr(n,"sym:weak")) {
+ Setattr(n,"sym:name",symname);
+ } else {
+ String *e = NewStringEmpty();
+ String *en = NewStringEmpty();
+ String *ec = NewStringEmpty();
+ int redefined = Swig_need_redefined_warn(n,c,inclass);
+ if (redefined) {
+ Printf(en,"Identifier '%s' redefined (ignored)",symname);
+ Printf(ec,"previous definition of '%s'",symname);
+ } else {
+ Printf(en,"Redundant redeclaration of '%s'",symname);
+ Printf(ec,"previous declaration of '%s'",symname);
+ }
+ if (Cmp(symname,Getattr(n,"name"))) {
+ Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name")));
+ }
+ Printf(en,",");
+ if (Cmp(symname,Getattr(c,"name"))) {
+ Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name")));
+ }
+ Printf(ec,".");
+ SWIG_WARN_NODE_BEGIN(n);
+ if (redefined) {
+ Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
+ Swig_warning(WARN_PARSE_REDEFINED,Getfile(c),Getline(c),"%s\n",ec);
+ } else if (!is_friend(n) && !is_friend(c)) {
+ Swig_warning(WARN_PARSE_REDUNDANT,Getfile(n),Getline(n),"%s\n",en);
+ Swig_warning(WARN_PARSE_REDUNDANT,Getfile(c),Getline(c),"%s\n",ec);
+ }
+ SWIG_WARN_NODE_END(n);
+ Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(n),Getline(n),en,
+ Getfile(c),Getline(c),ec);
+ Setattr(n,"error",e);
+ Delete(e);
+ Delete(en);
+ Delete(ec);
+ }
+ }
+ }
+ /* restore the class scope if needed */
+ if (isfriend) {
+ Swig_symbol_setscope(old_scope);
+ if (old_prefix) {
+ Delete(Namespaceprefix);
+ Namespaceprefix = old_prefix;
+ }
+ }
+ Delete(symname);
+
+ if (add_only_one) return;
+ n = nextSibling(n);
+ }
+}
+
+
+/* add symbols a parse tree node copy */
+
+static void add_symbols_copy(Node *n) {
+ String *name;
+ int emode = 0;
+ while (n) {
+ char *cnodeType = Char(nodeType(n));
+
+ if (strcmp(cnodeType,"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);
+ /* Disable this, it prevents %rename to work with templates */
+ /* If already renamed, we used that name */
+ /*
+ if (Strcmp(add_oldname, Getattr(n,"name")) != 0) {
+ Delete(yyrename);
+ yyrename = Copy(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);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+ if (strcmp(cnodeType,"class") == 0) {
+ inclass = 1;
+ current_class = n;
+ if (Strcmp(Getattr(n,"kind"),"class") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else {
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ }
+ if (strcmp(cnodeType,"extend") == 0) {
+ emode = cplus_mode;
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ add_symbols_copy(firstChild(n));
+ if (strcmp(cnodeType,"extend") == 0) {
+ cplus_mode = emode;
+ }
+ if (Getattr(n,"requires_symtab")) {
+ Setattr(n,"symtab", Swig_symbol_popscope());
+ Delattr(n,"requires_symtab");
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+ if (add_oldname) {
+ Delete(add_oldname);
+ add_oldname = 0;
+ }
+ if (strcmp(cnodeType,"class") == 0) {
+ inclass = 0;
+ current_class = 0;
+ }
+ } else {
+ if (strcmp(cnodeType,"extend") == 0) {
+ emode = cplus_mode;
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ add_symbols_copy(firstChild(n));
+ if (strcmp(cnodeType,"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 *cls, Node *am) {
+ Node *n;
+ Node *csym;
+
+ n = firstChild(am);
+ while (n) {
+ String *symname;
+ if (Strcmp(nodeType(n),"constructor") == 0) {
+ symname = Getattr(n,"sym:name");
+ if (symname) {
+ if (Strcmp(symname,Getattr(n,"name")) == 0) {
+ /* If the name and the sym:name of a constructor are the same,
+ then it hasn't been renamed. However---the name of the class
+ itself might have been renamed so we need to do a consistency
+ check here */
+ if (Getattr(cls,"sym:name")) {
+ Setattr(n,"sym:name", Getattr(cls,"sym:name"));
+ }
+ }
+ }
+ }
+
+ 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 = NewStringEmpty();
+ String *en = NewStringEmpty();
+ String *ec = NewStringEmpty();
+ Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
+ Printf(en,"%%extend definition of '%s'.",symname);
+ SWIG_WARN_NODE_BEGIN(n);
+ Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
+ Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
+ SWIG_WARN_NODE_END(n);
+ Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec,
+ Getfile(n),Getline(n),en);
+ Setattr(csym,"error",e);
+ Delete(e);
+ Delete(en);
+ Delete(ec);
+ Swig_symbol_remove(csym); /* Remove class definition */
+ Swig_symbol_add(symname,n); /* Insert extend definition */
+ }
+ }
+ n = nextSibling(n);
+ }
+}
+
+static void append_previous_extension(Node *cls, Node *am) {
+ Node *n, *ne;
+ Node *pe = 0;
+ Node *ae = 0;
+
+ if (!am) return;
+
+ n = firstChild(am);
+ while (n) {
+ ne = nextSibling(n);
+ set_nextSibling(n,0);
+ /* typemaps and fragments need to be prepended */
+ if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
+ if (!pe) pe = new_node("extend");
+ appendChild(pe, n);
+ } else {
+ if (!ae) ae = new_node("extend");
+ appendChild(ae, n);
+ }
+ n = ne;
+ }
+ if (pe) prependChild(cls,pe);
+ if (ae) appendChild(cls,ae);
+}
+
+
+/* Check for unused %extend. Special case, don't report unused
+ extensions for templates */
+
+static void check_extensions() {
+ Iterator ki;
+
+ if (!extendhash) return;
+ for (ki = First(extendhash); ki.key; ki = Next(ki)) {
+ if (!Strchr(ki.key,'<')) {
+ SWIG_WARN_NODE_BEGIN(ki.item);
+ Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", ki.key);
+ SWIG_WARN_NODE_END(ki.item);
+ }
+ }
+}
+
+/* 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);
+ Delete(args);
+ Delete(qargs);
+ nname = prefix;
+ }
+ return nname;
+}
+
+static List *make_inherit_list(String *clsname, List *names) {
+ int i, ilen;
+ String *derived;
+ List *bases = NewList();
+
+ if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname);
+ else derived = NewString(clsname);
+
+ ilen = Len(names);
+ for (i = 0; i < ilen; 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"));
+ Delete(q);
+ } else {
+ base = NewString(Getattr(s,"name"));
+ }
+ } else {
+ base = NewString(n);
+ }
+ } else {
+ base = NewString(n);
+ }
+ if (base) {
+ Swig_name_inherit(base,derived);
+ Delete(base);
+ }
+ }
+ return bases;
+}
+
+/* If the class name is qualified. We need to create or lookup namespace entries */
+
+static Symtab *get_global_scope() {
+ Symtab *symtab = Swig_symbol_current();
+ Node *pn = parentNode(symtab);
+ while (pn) {
+ symtab = pn;
+ pn = parentNode(symtab);
+ if (!pn) break;
+ }
+ Swig_symbol_setscope(symtab);
+ return symtab;
+}
+
+/* Remove the block braces, { and }, if the 'noblock' attribute is set.
+ * Node *kw can be either a Hash or Parmlist. */
+static String *remove_block(Node *kw, const String *inputcode) {
+ String *modified_code = 0;
+ while (kw) {
+ String *name = Getattr(kw,"name");
+ if (name && (Cmp(name,"noblock") == 0)) {
+ char *cstr = Char(inputcode);
+ size_t len = Len(inputcode);
+ if (len && cstr[0] == '{') {
+ --len; ++cstr;
+ if (len && cstr[len - 1] == '}') { --len; }
+ /* we now remove the extra spaces */
+ while (len && isspace((int)cstr[0])) { --len; ++cstr; }
+ while (len && isspace((int)cstr[len - 1])) { --len; }
+ modified_code = NewStringWithSize(cstr, len);
+ break;
+ }
+ }
+ kw = nextSibling(kw);
+ }
+ return modified_code;
+}
+
+
+static Node *nscope = 0;
+static Node *nscope_inner = 0;
+static String *resolve_node_scope(String *cname) {
+ Symtab *gscope = 0;
+ nscope = 0;
+ nscope_inner = 0;
+ if (Swig_scopename_check(cname)) {
+ Node *ns;
+ String *prefix = Swig_scopename_prefix(cname);
+ String *base = Swig_scopename_last(cname);
+ if (prefix && (Strncmp(prefix,"::",2) == 0)) {
+ /* Use the global scope */
+ String *nprefix = NewString(Char(prefix)+2);
+ Delete(prefix);
+ prefix= nprefix;
+ gscope = get_global_scope();
+ }
+ if (!prefix || (Len(prefix) == 0)) {
+ /* Use the global scope, but we need to add a 'global' namespace. */
+ if (!gscope) gscope = get_global_scope();
+ /* note that this namespace is not the "unnamed" one,
+ and we don't use Setattr(nscope,"name", ""),
+ because the unnamed namespace is private */
+ nscope = new_node("namespace");
+ Setattr(nscope,"symtab", gscope);;
+ nscope_inner = nscope;
+ return base;
+ }
+ /* 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 {
+ Symtab *nstab = Getattr(ns,"symtab");
+ if (!nstab) {
+ Swig_error(cparse_file,cparse_line,
+ "'%s' is not defined as a valid scope.\n", prefix);
+ ns = 0;
+ } else {
+ /* Check if the node scope is the current scope */
+ String *tname = Swig_symbol_qualifiedscopename(0);
+ String *nname = Swig_symbol_qualifiedscopename(nstab);
+ if (tname && (Strcmp(tname,nname) == 0)) {
+ ns = 0;
+ cname = base;
+ }
+ Delete(tname);
+ Delete(nname);
+ }
+ if (ns) {
+ /* we will try to create a new node using the namespaces we
+ can find in the scope name */
+ List *scopes;
+ String *sname;
+ Iterator si;
+ String *name = NewString(prefix);
+ scopes = NewList();
+ while (name) {
+ String *base = Swig_scopename_last(name);
+ String *tprefix = Swig_scopename_prefix(name);
+ Insert(scopes,0,base);
+ Delete(base);
+ Delete(name);
+ name = tprefix;
+ }
+ for (si = First(scopes); si.item; si = Next(si)) {
+ Node *ns1,*ns2;
+ sname = si.item;
+ ns1 = Swig_symbol_clookup(sname,0);
+ assert(ns1);
+ if (Strcmp(nodeType(ns1),"namespace") == 0) {
+ if (Getattr(ns1,"alias")) {
+ ns1 = Getattr(ns1,"namespace");
+ }
+ } else {
+ /* now this last part is a class */
+ si = Next(si);
+ ns1 = Swig_symbol_clookup(sname,0);
+ /* or a nested class tree, which is unrolled here */
+ for (; si.item; si = Next(si)) {
+ if (si.item) {
+ Printf(sname,"::%s",si.item);
+ }
+ }
+ /* we get the 'inner' class */
+ nscope_inner = Swig_symbol_clookup(sname,0);
+ /* set the scope to the inner class */
+ Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
+ /* save the last namespace prefix */
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ /* and return the node name, including the inner class prefix */
+ break;
+ }
+ /* here we just populate the namespace tree as usual */
+ ns2 = new_node("namespace");
+ Setattr(ns2,"name",sname);
+ Setattr(ns2,"symtab", Getattr(ns1,"symtab"));
+ add_symbols(ns2);
+ Swig_symbol_setscope(Getattr(ns1,"symtab"));
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ if (nscope_inner) {
+ if (Getattr(nscope_inner,"symtab") != Getattr(ns2,"symtab")) {
+ appendChild(nscope_inner,ns2);
+ Delete(ns2);
+ }
+ }
+ nscope_inner = ns2;
+ if (!nscope) nscope = ns2;
+ }
+ cname = base;
+ Delete(scopes);
+ }
+ }
+ Delete(prefix);
+ }
+ return cname;
+}
+
+
+
+
+
+/* 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 */
+ int unnamed; /* unnamed 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;
+ }
+}
+
+/* Strips C-style and C++-style comments from string in-place. */
+static void strip_comments(char *string) {
+ int state = 0; /*
+ * 0 - not in comment
+ * 1 - in c-style comment
+ * 2 - in c++-style comment
+ * 3 - in string
+ * 4 - after reading / not in comments
+ * 5 - after reading * in c-style comments
+ * 6 - after reading \ in strings
+ */
+ char * c = string;
+ while (*c) {
+ switch (state) {
+ case 0:
+ if (*c == '\"')
+ state = 3;
+ else if (*c == '/')
+ state = 4;
+ break;
+ case 1:
+ if (*c == '*')
+ state = 5;
+ *c = ' ';
+ break;
+ case 2:
+ if (*c == '\n')
+ state = 0;
+ else
+ *c = ' ';
+ break;
+ case 3:
+ if (*c == '\"')
+ state = 0;
+ else if (*c == '\\')
+ state = 6;
+ break;
+ case 4:
+ if (*c == '/') {
+ *(c-1) = ' ';
+ *c = ' ';
+ state = 2;
+ } else if (*c == '*') {
+ *(c-1) = ' ';
+ *c = ' ';
+ state = 1;
+ } else
+ state = 0;
+ break;
+ case 5:
+ if (*c == '/')
+ state = 0;
+ else
+ state = 1;
+ *c = ' ';
+ break;
+ case 6:
+ state = 3;
+ break;
+ }
+ ++c;
+ }
+}
+
+/* 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(const char *parent) {
+ Nested *n,*n1;
+ Node *ret = 0;
+ n = nested_list;
+ if (!parent) {
+ nested_list = 0;
+ return 0;
+ }
+ while (n) {
+ Node *retx;
+ SwigType *nt;
+ /* 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) */
+ 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);
+ nt = Copy(n->type);
+ Setattr(retx,"type",nt);
+ Delete(nt);
+ Setattr(retx,"nested",parent);
+ if (n->unnamed) {
+ Setattr(retx,"unnamed","1");
+ }
+
+ add_symbols(retx);
+ if (ret) {
+ set_nextSibling(retx,ret);
+ Delete(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;
+ */
+
+ /* Strip comments - further code may break in presence of comments. */
+ strip_comments(Char(n->code));
+
+ /* 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 opening brace */
+
+ code_ptr = strstr(code_ptr, types_array[i]);
+ if (code_ptr) {
+ char *open_bracket_pos;
+ code_ptr += strlen(types_array[i]);
+ open_bracket_pos = strchr(code_ptr, '{');
+ if (open_bracket_pos) {
+ /* Make sure we don't have something like struct A a; */
+ char* semi_colon_pos = strchr(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 = strchr(code_ptr, ';');
+ if (directive_end_pos) {
+ while (code_ptr <= directive_end_pos)
+ *code_ptr++ = ' ';
+ }
+ }
+ }
+ }
+ {
+ Node *head = new_node("insert");
+ String *code = NewStringf("\n%s\n",n->code);
+ Setattr(head,"code", code);
+ Delete(code);
+ set_nextSibling(head,ret);
+ Delete(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) {
+ scanner_file(f);
+ top = 0;
+ yyparse();
+ return top;
+}
+
+static void single_new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
+ String *fname;
+ String *name;
+ String *fixname;
+ SwigType *t = Copy(type);
+
+ /* Printf(stdout, "single_new_feature: [%s] [%s] [%s] [%s] [%s] [%s]\n", featurename, val, declaratorid, t, ParmList_str_defaultargs(declaratorparms), qualifier); */
+
+ fname = NewStringf("feature:%s",featurename);
+ if (declaratorid) {
+ fixname = feature_identifier_fix(declaratorid);
+ } else {
+ fixname = NewStringEmpty();
+ }
+ if (Namespaceprefix) {
+ name = NewStringf("%s::%s",Namespaceprefix, fixname);
+ } else {
+ name = fixname;
+ }
+
+ if (declaratorparms) Setmeta(val,"parms",declaratorparms);
+ if (!Len(t)) t = 0;
+ if (t) {
+ if (qualifier) SwigType_push(t,qualifier);
+ if (SwigType_isfunction(t)) {
+ SwigType *decl = SwigType_pop_function(t);
+ if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(Swig_cparse_features(), nname, decl, fname, val, featureattribs);
+ Delete(nname);
+ } else {
+ Swig_feature_set(Swig_cparse_features(), name, decl, fname, val, featureattribs);
+ }
+ Delete(decl);
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(Swig_cparse_features(),nname,0,fname,val, featureattribs);
+ Delete(nname);
+ }
+ } else {
+ /* Global feature, that is, feature not associated with any particular symbol */
+ Swig_feature_set(Swig_cparse_features(),name,0,fname,val, featureattribs);
+ }
+ Delete(fname);
+ Delete(name);
+}
+
+/* Add a new feature to the Hash. Additional features are added if the feature has a parameter list (declaratorparms)
+ * and one or more of the parameters have a default argument. An extra feature is added for each defaulted parameter,
+ * simulating the equivalent overloaded method. */
+static void new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
+
+ ParmList *declparms = declaratorparms;
+
+ /* remove the { and } braces if the noblock attribute is set */
+ String *newval = remove_block(featureattribs, val);
+ val = newval ? newval : val;
+
+ /* Add the feature */
+ single_new_feature(featurename, val, featureattribs, declaratorid, type, declaratorparms, qualifier);
+
+ /* Add extra features if there are default parameters in the parameter list */
+ if (type) {
+ while (declparms) {
+ if (ParmList_has_defaultargs(declparms)) {
+
+ /* Create a parameter list for the new feature by copying all
+ but the last (defaulted) parameter */
+ ParmList* newparms = CopyParmListMax(declparms, ParmList_len(declparms)-1);
+
+ /* Create new declaration - with the last parameter removed */
+ SwigType *newtype = Copy(type);
+ Delete(SwigType_pop_function(newtype)); /* remove the old parameter list from newtype */
+ SwigType_add_function(newtype,newparms);
+
+ single_new_feature(featurename, Copy(val), featureattribs, declaratorid, newtype, newparms, qualifier);
+ declparms = newparms;
+ } else {
+ declparms = 0;
+ }
+ }
+ }
+}
+
+/* check if a function declaration is a plain C object */
+static int is_cfunction(Node *n) {
+ if (!cparse_cplusplus || cparse_externc) return 1;
+ if (Cmp(Getattr(n,"storage"),"externc") == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/* If the Node is a function with parameters, check to see if any of the parameters
+ * have default arguments. If so create a new function for each defaulted argument.
+ * The additional functions form a linked list of nodes with the head being the original Node n. */
+static void default_arguments(Node *n) {
+ Node *function = n;
+
+ if (function) {
+ ParmList *varargs = Getattr(function,"feature:varargs");
+ if (varargs) {
+ /* Handles the %varargs directive by looking for "feature:varargs" and
+ * substituting ... with an alternative set of arguments. */
+ Parm *p = Getattr(function,"parms");
+ Parm *pp = 0;
+ while (p) {
+ SwigType *t = Getattr(p,"type");
+ if (Strcmp(t,"v(...)") == 0) {
+ if (pp) {
+ ParmList *cv = Copy(varargs);
+ set_nextSibling(pp,cv);
+ Delete(cv);
+ } else {
+ ParmList *cv = Copy(varargs);
+ Setattr(function,"parms", cv);
+ Delete(cv);
+ }
+ break;
+ }
+ pp = p;
+ p = nextSibling(p);
+ }
+ }
+
+ /* Do not add in functions if kwargs is being used or if user wants old default argument wrapping
+ (one wrapped method per function irrespective of number of default arguments) */
+ if (compact_default_args
+ || is_cfunction(function)
+ || GetFlag(function,"feature:compactdefaultargs")
+ || GetFlag(function,"feature:kwargs")) {
+ ParmList *p = Getattr(function,"parms");
+ if (p)
+ Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */
+ function = 0; /* don't add in extra methods */
+ }
+ }
+
+ while (function) {
+ ParmList *parms = Getattr(function,"parms");
+ if (ParmList_has_defaultargs(parms)) {
+
+ /* Create a parameter list for the new function by copying all
+ but the last (defaulted) parameter */
+ ParmList* newparms = CopyParmListMax(parms,ParmList_len(parms)-1);
+
+ /* Create new function and add to symbol table */
+ {
+ SwigType *ntype = Copy(nodeType(function));
+ char *cntype = Char(ntype);
+ Node *new_function = new_node(ntype);
+ SwigType *decl = Copy(Getattr(function,"decl"));
+ int constqualifier = SwigType_isconst(decl);
+ String *ccode = Copy(Getattr(function,"code"));
+ String *cstorage = Copy(Getattr(function,"storage"));
+ String *cvalue = Copy(Getattr(function,"value"));
+ SwigType *ctype = Copy(Getattr(function,"type"));
+ String *cthrow = Copy(Getattr(function,"throw"));
+
+ Delete(SwigType_pop_function(decl)); /* remove the old parameter list from decl */
+ SwigType_add_function(decl,newparms);
+ if (constqualifier)
+ SwigType_add_qualifier(decl,"const");
+
+ Setattr(new_function,"name", Getattr(function,"name"));
+ Setattr(new_function,"code", ccode);
+ Setattr(new_function,"decl", decl);
+ Setattr(new_function,"parms", newparms);
+ Setattr(new_function,"storage", cstorage);
+ Setattr(new_function,"value", cvalue);
+ Setattr(new_function,"type", ctype);
+ Setattr(new_function,"throw", cthrow);
+
+ Delete(ccode);
+ Delete(cstorage);
+ Delete(cvalue);
+ Delete(ctype);
+ Delete(cthrow);
+ Delete(decl);
+
+ {
+ Node *throws = Getattr(function,"throws");
+ ParmList *pl = CopyParmList(throws);
+ if (throws) Setattr(new_function,"throws",pl);
+ Delete(pl);
+ }
+
+ /* copy specific attributes for global (or in a namespace) template functions - these are not templated class methods */
+ if (strcmp(cntype,"template") == 0) {
+ Node *templatetype = Getattr(function,"templatetype");
+ Node *symtypename = Getattr(function,"sym:typename");
+ Parm *templateparms = Getattr(function,"templateparms");
+ if (templatetype) {
+ Node *tmp = Copy(templatetype);
+ Setattr(new_function,"templatetype",tmp);
+ Delete(tmp);
+ }
+ if (symtypename) {
+ Node *tmp = Copy(symtypename);
+ Setattr(new_function,"sym:typename",tmp);
+ Delete(tmp);
+ }
+ if (templateparms) {
+ Parm *tmp = CopyParmList(templateparms);
+ Setattr(new_function,"templateparms",tmp);
+ Delete(tmp);
+ }
+ } else if (strcmp(cntype,"constructor") == 0) {
+ /* only copied for constructors as this is not a user defined feature - it is hard coded in the parser */
+ if (GetFlag(function,"feature:new")) SetFlag(new_function,"feature:new");
+ }
+
+ add_symbols(new_function);
+ /* mark added functions as ones with overloaded parameters and point to the parsed method */
+ Setattr(new_function,"defaultargs", n);
+
+ /* Point to the new function, extending the linked list */
+ set_nextSibling(function, new_function);
+ Delete(new_function);
+ function = new_function;
+
+ Delete(ntype);
+ }
+ } else {
+ function = 0;
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * tag_nodes()
+ *
+ * Used by the parser to mark subtypes with extra information.
+ * ----------------------------------------------------------------------------- */
+
+static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
+ while (n) {
+ Setattr(n, attrname, value);
+ tag_nodes(firstChild(n), attrname, value);
+ n = nextSibling(n);
+ }
+}
+
+%}
+
+%union {
+ char *id;
+ List *bases;
+ struct Define {
+ String *val;
+ String *rawval;
+ int type;
+ String *qualifier;
+ String *bitfield;
+ Parm *throws;
+ String *throwf;
+ } dtype;
+ struct {
+ char *type;
+ String *filename;
+ int line;
+ } loc;
+ struct {
+ char *id;
+ SwigType *type;
+ String *defarg;
+ ParmList *parms;
+ short have_parms;
+ ParmList *throws;
+ String *throwf;
+ } decl;
+ Parm *tparms;
+ struct {
+ String *method;
+ 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_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64
+%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD
+%token CONST_QUAL VOLATILE REGISTER 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 EXPLICIT
+%token USING
+%token <node> NAMESPACE
+%token NATIVE INLINE
+%token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT
+%token WARN
+%token LESSTHAN GREATERTHAN MODULO DELETE_KW
+%token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO
+%token QUESTIONMARK
+%token TYPES PARMS
+%token NONID DSTAR DCNOT
+%token <ivalue> TEMPLATE
+%token <str> OPERATOR
+%token <str> COPERATOR
+%token PARSETYPE PARSEPARM PARSEPARMS
+
+%left CAST
+%left QUESTIONMARK
+%left LOR
+%left LAND
+%left OR
+%left XOR
+%left AND
+%left EQUALTO NOTEQUALTO
+%left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO
+%left LSHIFT RSHIFT
+%left PLUS MINUS
+%left STAR SLASH MODULUS
+%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_enum_forward_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 <pl> templateparameters templateparameterstail;
+%type <p> parm valparm rawvalparms valparms valptail ;
+%type <p> typemap_parm tm_list tm_tail ;
+%type <p> templateparameter ;
+%type <id> templcpptype 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 valexpr;
+%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_end cpp_vend;
+%type <ivalue> rename_namewarn;
+%type <ptype> type_specifier primitive_type_list ;
+%type <node> fname stringtype;
+%type <node> featattr;
+
+%%
+
+/* ======================================================================
+ * High-level Interface file
+ *
+ * An interface is just a sequence of declarations which may be SWIG directives
+ * or normal C declarations.
+ * ====================================================================== */
+
+program : interface {
+ if (!classes) classes = NewHash();
+ 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 = Copy(Getattr($2,"type"));
+ Delete($2);
+ }
+ | PARSETYPE error {
+ top = 0;
+ }
+ | PARSEPARM parm SEMI {
+ top = $2;
+ }
+ | PARSEPARM error {
+ top = 0;
+ }
+ | PARSEPARMS LPAREN parms RPAREN SEMI {
+ top = $3;
+ }
+ | PARSEPARMS error SEMI {
+ top = 0;
+ }
+ ;
+
+interface : interface declaration {
+ /* add declaration to end of linked list (the declaration isn't always a single declaration, sometimes it is a linked list itself) */
+ appendChild($1,$2);
+ $$ = $1;
+ }
+ | empty {
+ $$ = new_node("top");
+ }
+ ;
+
+declaration : swig_directive { $$ = $1; }
+ | c_declaration { $$ = $1; }
+ | cpp_declaration { $$ = $1; }
+ | SEMI { $$ = 0; }
+ | error {
+ $$ = 0;
+ Swig_error(cparse_file, cparse_line,"Syntax error in input(1).\n");
+ exit(1);
+ }
+/* Out of class constructor/destructor declarations */
+ | c_constructor_decl {
+ if ($$) {
+ add_symbols($$);
+ }
+ $$ = $1;
+ }
+
+/* Out of class conversion operator. For example:
+ inline A::operator char *() const { ... }.
+
+ This is nearly impossible to parse normally. We just let the
+ first part generate a syntax error and then resynchronize on the
+ COPERATOR token---discarding the rest of the definition. Ugh.
+
+ */
+
+ | error COPERATOR {
+ $$ = 0;
+ skip_decl();
+ }
+ ;
+
+/* ======================================================================
+ * 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);
+ 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;
+ extendmode = 1;
+ }
+ Classprefix = NewString($3);
+ Namespaceprefix= Swig_symbol_qualifiedscopename(0);
+ Delete(clsname);
+ } cpp_members RBRACE {
+ String *clsname;
+ extendmode = 0;
+ $$ = 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 */
+
+ 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)) {
+ SwigType *type = NewSwigType($4.type);
+ $$ = new_node("constant");
+ Setattr($$,"name",$2);
+ Setattr($$,"type",type);
+ Setattr($$,"value",$4.val);
+ if ($4.rawval) Setattr($$,"rawval", $4.rawval);
+ Setattr($$,"storage","%constant");
+ SetFlag($$,"feature:immutable");
+ add_symbols($$);
+ Delete(type);
+ } 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);
+ if ($4.rawval) Setattr($$,"rawval", $4.rawval);
+ Setattr($$,"storage","%constant");
+ SetFlag($$,"feature:immutable");
+ 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.\n");
+ }
+
+ | EXCEPT LBRACE {
+ skip_balanced('{','}');
+ $$ = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
+ }
+
+ | EXCEPT LPAREN ID RPAREN SEMI {
+ $$ = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
+ }
+
+ | EXCEPT SEMI {
+ $$ = 0;
+ Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n");
+ }
+ ;
+
+/* fragment keyword arguments */
+stringtype : string LBRACE parm RBRACE {
+ $$ = NewHash();
+ Setattr($$,"value",$1);
+ Setattr($$,"type",Getattr($3,"type"));
+ }
+ ;
+
+fname : string {
+ $$ = NewHash();
+ Setattr($$,"value",$1);
+ }
+ | stringtype {
+ $$ = $1;
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %fragment(name, section) %{ ... %}
+ %fragment("name" {type}, "section") %{ ... %}
+ %fragment("name", "section", fragment="fragment1", fragment="fragment2") %{ ... %}
+ Also as above but using { ... }
+ %fragment("name");
+ ------------------------------------------------------------ */
+
+fragment_directive: FRAGMENT LPAREN fname COMMA kwargs RPAREN HBLOCK {
+ Hash *p = $5;
+ $$ = new_node("fragment");
+ Setattr($$,"value",Getattr($3,"value"));
+ Setattr($$,"type",Getattr($3,"type"));
+ Setattr($$,"section",Getattr(p,"name"));
+ Setattr($$,"kwargs",nextSibling(p));
+ Setattr($$,"code",$7);
+ }
+ | FRAGMENT LPAREN fname COMMA kwargs RPAREN LBRACE {
+ Hash *p = $5;
+ String *code;
+ skip_balanced('{','}');
+ $$ = new_node("fragment");
+ Setattr($$,"value",Getattr($3,"value"));
+ Setattr($$,"type",Getattr($3,"type"));
+ Setattr($$,"section",Getattr(p,"name"));
+ Setattr($$,"kwargs",nextSibling(p));
+ Delitem(scanner_ccode,0);
+ Delitem(scanner_ccode,DOH_END);
+ code = Copy(scanner_ccode);
+ Setattr($$,"code",code);
+ Delete(code);
+ }
+ | FRAGMENT LPAREN fname RPAREN SEMI {
+ $$ = new_node("fragment");
+ Setattr($$,"value",Getattr($3,"value"));
+ Setattr($$,"type",Getattr($3,"type"));
+ Setattr($$,"emitonly","1");
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %includefile "filename" [option1="xyz", ...] [ declarations ]
+ %importfile "filename" [option1="xyz", ...] [ declarations ]
+ ------------------------------------------------------------ */
+
+include_directive: includetype options string LBRACKET {
+ $1.filename = Copy(cparse_file);
+ $1.line = cparse_line;
+ scanner_set_location(NewString($3),1);
+ if ($2) {
+ String *maininput = Getattr($2, "maininput");
+ if (maininput)
+ scanner_set_main_input_file(NewString(maininput));
+ }
+ } interface RBRACKET {
+ String *mname = 0;
+ $$ = $6;
+ scanner_set_location($1.filename,$1.line);
+ if (strcmp($1.type,"include") == 0) set_nodeType($$,"include");
+ if (strcmp($1.type,"import") == 0) {
+ mname = $2 ? Getattr($2,"module") : 0;
+ set_nodeType($$,"import");
+ if (import_mode) --import_mode;
+ }
+
+ Setattr($$,"name",$3);
+ /* Search for the module (if any) */
+ {
+ Node *n = firstChild($$);
+ while (n) {
+ if (Strcmp(nodeType(n),"module") == 0) {
+ if (mname) {
+ Setattr(n,"name", mname);
+ mname = 0;
+ }
+ Setattr($$,"module",Getattr(n,"name"));
+ break;
+ }
+ n = nextSibling(n);
+ }
+ if (mname) {
+ /* There is no module node in the import
+ node, ie, you imported a .h file
+ directly. We are forced then to create
+ a new import node with a module node.
+ */
+ Node *nint = new_node("import");
+ Node *mnode = new_node("module");
+ Setattr(mnode,"name", mname);
+ appendChild(nint,mnode);
+ Delete(mnode);
+ appendChild(nint,firstChild($$));
+ $$ = nint;
+ Setattr($$,"module",mname);
+ }
+ }
+ Setattr($$,"options",$2);
+ }
+ ;
+
+includetype : INCLUDE { $$.type = (char *) "include"; }
+ | IMPORT { $$.type = (char *) "import"; ++import_mode;}
+ ;
+
+/* ------------------------------------------------------------
+ %inline %{ ... %}
+ ------------------------------------------------------------ */
+
+inline_directive : INLINE HBLOCK {
+ String *cpps;
+ if (Namespaceprefix) {
+ Swig_error(cparse_file, cparse_start_line, "%%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);
+ }
+
+ }
+ | INLINE LBRACE {
+ String *cpps;
+ int start_line = cparse_line;
+ skip_balanced('{','}');
+ if (Namespaceprefix) {
+ Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
+
+ $$ = 0;
+ } else {
+ String *code;
+ $$ = new_node("insert");
+ Delitem(scanner_ccode,0);
+ Delitem(scanner_ccode,DOH_END);
+ code = Copy(scanner_ccode);
+ Setattr($$,"code", code);
+ Delete(code);
+ cpps=Copy(scanner_ccode);
+ start_inline(Char(cpps), start_line);
+ 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 = NewStringEmpty();
+ $$ = 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 {
+ String *code;
+ skip_balanced('{','}');
+ $$ = new_node("insert");
+ Setattr($$,"section",$3);
+ Delitem(scanner_ccode,0);
+ Delitem(scanner_ccode,DOH_END);
+ code = Copy(scanner_ccode);
+ Setattr($$,"code", code);
+ Delete(code);
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %module modname
+ %module "modname"
+ ------------------------------------------------------------ */
+
+module_directive: MODULE options idstring {
+ $$ = new_node("module");
+ if ($2) {
+ Setattr($$,"options",$2);
+ if (Getattr($2,"directors")) {
+ Wrapper_director_mode_set(1);
+ }
+ if (Getattr($2,"dirprot")) {
+ Wrapper_director_protected_mode_set(1);
+ }
+ if (Getattr($2,"allprotected")) {
+ Wrapper_all_protected_mode_set(1);
+ }
+ if (Getattr($2,"templatereduce")) {
+ template_reduce = 1;
+ }
+ if (Getattr($2,"notemplatereduce")) {
+ template_reduce = 0;
+ }
+ }
+ if (!ModuleName) ModuleName = NewString($3);
+ if (!import_mode) {
+ /* first module included, we apply global
+ ModuleName, which can be modify by -module */
+ String *mname = Copy(ModuleName);
+ Setattr($$,"name",mname);
+ Delete(mname);
+ } else {
+ /* import mode, we just pass the idstring */
+ Setattr($$,"name",$3);
+ }
+ if (!module_node) module_node = $$;
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %name(newname) declaration
+ %name("newname") declaration
+ ------------------------------------------------------------ */
+
+name_directive : NAME LPAREN idstring RPAREN {
+ Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n");
+ Delete(yyrename);
+ yyrename = NewString($3);
+ $$ = 0;
+ }
+ | NAME LPAREN RPAREN {
+ Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n");
+ $$ = 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;
+ Hash *kws = NewHash();
+ String *fixname;
+ fixname = feature_identifier_fix($2.id);
+ Setattr(kws,"name",$3);
+ if (!Len(t)) t = 0;
+ /* Special declarator check */
+ if (t) {
+ if (SwigType_isfunction(t)) {
+ SwigType *decl = SwigType_pop_function(t);
+ if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",fixname);
+ if ($1) {
+ Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$2.parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
+ }
+ Delete(nname);
+ } else {
+ if ($1) {
+ Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$2.parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
+ }
+ }
+ Delete(decl);
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",fixname);
+ if ($1) {
+ Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$2.parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
+ }
+ Delete(nname);
+ }
+ } else {
+ if ($1) {
+ Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$2.parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
+ }
+ }
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ | rename_namewarn LPAREN kwargs RPAREN declarator cpp_const SEMI {
+ String *fixname;
+ Hash *kws = $3;
+ 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) {
+ Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$5.parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws);
+ }
+ Delete(nname);
+ } else {
+ if ($1) {
+ Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$5.parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws);
+ }
+ }
+ Delete(decl);
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",fixname);
+ if ($1) {
+ Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$5.parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws);
+ }
+ Delete(nname);
+ }
+ } else {
+ if ($1) {
+ Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$5.parms);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws);
+ }
+ }
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ | rename_namewarn LPAREN kwargs RPAREN string SEMI {
+ if ($1) {
+ Swig_name_rename_add(Namespaceprefix,$5,0,$3,0);
+ } else {
+ Swig_name_namewarn_add(Namespaceprefix,$5,0,$3);
+ }
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ ;
+
+rename_namewarn : RENAME {
+ $$ = 1;
+ }
+ | NAMEWARN {
+ $$ = 0;
+ };
+
+
+/* ------------------------------------------------------------
+ Feature targeting a symbol name (non-global feature):
+
+ %feature(featurename) name "val";
+ %feature(featurename, val) name;
+
+ where "val" could instead be the other bracket types, that is,
+ { val } or %{ val %} or indeed omitted whereupon it defaults to "1".
+ Or, the global feature which does not target a symbol name:
+
+ %feature(featurename) "val";
+ %feature(featurename, val);
+
+ An empty val (empty string) clears the feature.
+ Any number of feature attributes can optionally be added, for example
+ a non-global feature with 2 attributes:
+
+ %feature(featurename, attrib1="attribval1", attrib2="attribval2") name "val";
+ %feature(featurename, val, attrib1="attribval1", attrib2="attribval2") name;
+ ------------------------------------------------------------ */
+
+ /* Non-global feature */
+feature_directive : FEATURE LPAREN idstring RPAREN declarator cpp_const stringbracesemi {
+ String *val = $7 ? NewString($7) : NewString("1");
+ new_feature($3, val, 0, $5.id, $5.type, $5.parms, $6.qualifier);
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ | FEATURE LPAREN idstring COMMA stringnum RPAREN declarator cpp_const SEMI {
+ String *val = Len($5) ? NewString($5) : 0;
+ new_feature($3, val, 0, $7.id, $7.type, $7.parms, $8.qualifier);
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ | FEATURE LPAREN idstring featattr RPAREN declarator cpp_const stringbracesemi {
+ String *val = $8 ? NewString($8) : NewString("1");
+ new_feature($3, val, $4, $6.id, $6.type, $6.parms, $7.qualifier);
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ | FEATURE LPAREN idstring COMMA stringnum featattr RPAREN declarator cpp_const SEMI {
+ String *val = Len($5) ? NewString($5) : 0;
+ new_feature($3, val, $6, $8.id, $8.type, $8.parms, $9.qualifier);
+ $$ = 0;
+ scanner_clear_rename();
+ }
+
+ /* Global feature */
+ | FEATURE LPAREN idstring RPAREN stringbracesemi {
+ String *val = $5 ? NewString($5) : NewString("1");
+ new_feature($3, val, 0, 0, 0, 0, 0);
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ | FEATURE LPAREN idstring COMMA stringnum RPAREN SEMI {
+ String *val = Len($5) ? NewString($5) : 0;
+ new_feature($3, val, 0, 0, 0, 0, 0);
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ | FEATURE LPAREN idstring featattr RPAREN stringbracesemi {
+ String *val = $6 ? NewString($6) : NewString("1");
+ new_feature($3, val, $4, 0, 0, 0, 0);
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ | FEATURE LPAREN idstring COMMA stringnum featattr RPAREN SEMI {
+ String *val = Len($5) ? NewString($5) : 0;
+ new_feature($3, val, $6, 0, 0, 0, 0);
+ $$ = 0;
+ scanner_clear_rename();
+ }
+ ;
+
+stringbracesemi : stringbrace { $$ = $1; }
+ | SEMI { $$ = 0; }
+ | PARMS LPAREN parms RPAREN SEMI { $$ = $3; }
+ ;
+
+featattr : COMMA idstring EQUAL stringnum {
+ $$ = NewHash();
+ Setattr($$,"name",$2);
+ Setattr($$,"value",$4);
+ }
+ | COMMA idstring EQUAL stringnum featattr {
+ $$ = NewHash();
+ Setattr($$,"name",$2);
+ Setattr($$,"value",$4);
+ set_nextSibling($$,$5);
+ }
+ ;
+
+/* %varargs() directive. */
+
+varargs_directive : VARARGS LPAREN varargs_parms RPAREN declarator cpp_const SEMI {
+ Parm *val;
+ String *name;
+ SwigType *t;
+ 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(Swig_cparse_features(), nname, decl, "feature:varargs", val, 0);
+ Delete(nname);
+ } else {
+ Swig_feature_set(Swig_cparse_features(), name, decl, "feature:varargs", val, 0);
+ }
+ Delete(decl);
+ } else if (SwigType_ispointer(t)) {
+ String *nname = NewStringf("*%s",name);
+ Swig_feature_set(Swig_cparse_features(),nname,0,"feature:varargs",val, 0);
+ Delete(nname);
+ }
+ } else {
+ Swig_feature_set(Swig_cparse_features(),name,0,"feature:varargs",val, 0);
+ }
+ 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,$$);
+ Delete($$);
+ $$ = 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.method) {
+ String *code = 0;
+ $$ = new_node("typemap");
+ Setattr($$,"method",$3.method);
+ if ($3.kwargs) {
+ ParmList *kw = $3.kwargs;
+ code = remove_block(kw, $6);
+ Setattr($$,"kwargs", $3.kwargs);
+ }
+ code = code ? code : NewString($6);
+ Setattr($$,"code", code);
+ Delete(code);
+ appendChild($$,$5);
+ }
+ }
+ | TYPEMAP LPAREN typemap_type RPAREN tm_list SEMI {
+ $$ = 0;
+ if ($3.method) {
+ $$ = new_node("typemap");
+ Setattr($$,"method",$3.method);
+ appendChild($$,$5);
+ }
+ }
+ | TYPEMAP LPAREN typemap_type RPAREN tm_list EQUAL typemap_parm SEMI {
+ $$ = 0;
+ if ($3.method) {
+ $$ = new_node("typemapcopy");
+ Setattr($$,"method",$3.method);
+ 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"))) {
+ /* this is the deprecated two argument typemap form */
+ Swig_warning(WARN_DEPRECATED_TYPEMAP_LANG,cparse_file, cparse_line,
+ "Specifying the language name in %%typemap is deprecated - use #ifdef SWIG<LANG> instead.\n");
+ /* two argument typemap form */
+ name = Getattr($1,"name");
+ if (!name || (Strcmp(name,typemap_lang))) {
+ $$.method = 0;
+ $$.kwargs = 0;
+ } else {
+ $$.method = Getattr(p,"name");
+ $$.kwargs = nextSibling(p);
+ }
+ } else {
+ /* one-argument typemap-form */
+ $$.method = 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 {
+ Parm *parm;
+ SwigType_push($1,$2.type);
+ $$ = new_node("typemapitem");
+ parm = NewParm($1,$2.id);
+ Setattr($$,"pattern",parm);
+ Setattr($$,"parms", $2.parms);
+ Delete(parm);
+ /* $$ = 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(parmlist) %{ ... %}
+ ------------------------------------------------------------ */
+
+types_directive : TYPES LPAREN parms RPAREN stringbracesemi {
+ $$ = new_node("types");
+ Setattr($$,"parms",$3);
+ if ($5)
+ Setattr($$,"convcode",NewString($5));
+ }
+ ;
+
+/* ------------------------------------------------------------
+ %template(name) tname<args>;
+ ------------------------------------------------------------ */
+
+template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI {
+ Parm *p, *tp;
+ Node *n;
+ Node *tnode = 0;
+ Symtab *tscope = 0;
+ int specialized = 0;
+
+ $$ = 0;
+
+ tscope = Swig_symbol_current(); /* Get the current scope */
+
+ /* If the class name is qualified, we need to create or lookup namespace entries */
+ if (!inclass) {
+ $5 = resolve_node_scope($5);
+ }
+
+ /*
+ We use the new namespace entry 'nscope' only to
+ emit the template node. The template parameters are
+ resolved in the current 'tscope'.
+
+ This is closer to the C++ (typedef) behavior.
+ */
+ n = Swig_cparse_template_locate($5,$7,tscope);
+
+ /* Patch the argument types to respect namespaces */
+ p = $7;
+ while (p) {
+ SwigType *value = Getattr(p,"value");
+ if (!value) {
+ SwigType *ty = Getattr(p,"type");
+ if (ty) {
+ SwigType *rty = 0;
+ int reduce = template_reduce;
+ if (reduce || !SwigType_ispointer(ty)) {
+ rty = Swig_symbol_typedef_reduce(ty,tscope);
+ if (!reduce) reduce = SwigType_ispointer(rty);
+ }
+ ty = reduce ? Swig_symbol_type_qualify(rty,tscope) : Swig_symbol_type_qualify(ty,tscope);
+ Setattr(p,"type",ty);
+ Delete(ty);
+ Delete(rty);
+ }
+ } else {
+ value = Swig_symbol_type_qualify(value,tscope);
+ Setattr(p,"value",value);
+ Delete(value);
+ }
+
+ p = nextSibling(p);
+ }
+
+ /* Look for the template */
+ {
+ Node *nn = n;
+ Node *linklistend = 0;
+ while (nn) {
+ Node *templnode = 0;
+ if (Strcmp(nodeType(nn),"template") == 0) {
+ int nnisclass = (Strcmp(Getattr(nn,"templatetype"),"class") == 0); /* if not a templated class it is a templated function */
+ Parm *tparms = Getattr(nn,"templateparms");
+ if (!tparms) {
+ specialized = 1;
+ }
+ if (nnisclass && !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 (nnisclass && !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 if (!nnisclass && ((ParmList_len($7) != ParmList_len(tparms)))) {
+ /* must be an overloaded templated method - ignore it as it is overloaded with a different number of template parameters */
+ nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions */
+ continue;
+ } else {
+ String *tname = Copy($5);
+ int def_supplied = 0;
+ /* Expand the template */
+ Node *templ = Swig_symbol_clookup($5,0);
+ Parm *targs = templ ? Getattr(templ,"templateparms") : 0;
+
+ ParmList *temparms;
+ if (specialized) temparms = CopyParmList($7);
+ else temparms = CopyParmList(tparms);
+
+ /* Create typedef's and arguments */
+ p = $7;
+ tp = temparms;
+ if (!p && ParmList_len(p) != ParmList_len(temparms)) {
+ /* we have no template parameters supplied in %template for a template that has default args*/
+ p = tp;
+ def_supplied = 1;
+ }
+
+ 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");
+ }
+ /* fix default arg values */
+ if (targs) {
+ Parm *pi = temparms;
+ Parm *ti = targs;
+ String *tv = Getattr(tp,"value");
+ if (!tv) tv = Getattr(tp,"type");
+ while(pi != tp && ti && pi) {
+ String *name = Getattr(ti,"name");
+ String *value = Getattr(pi,"value");
+ if (!value) value = Getattr(pi,"type");
+ Replaceid(tv, name, value);
+ pi = nextSibling(pi);
+ ti = nextSibling(ti);
+ }
+ }
+ p = nextSibling(p);
+ tp = nextSibling(tp);
+ if (!p && tp) {
+ p = tp;
+ def_supplied = 1;
+ }
+ }
+
+ templnode = copy_node(nn);
+ /* We need to set the node name based on name used to instantiate */
+ Setattr(templnode,"name",tname);
+ Delete(tname);
+ if (!specialized) {
+ Delattr(templnode,"sym:typename");
+ } else {
+ Setattr(templnode,"sym:typename","1");
+ }
+ if ($3) {
+ /*
+ Comment this out for 1.3.28. We need to
+ re-enable it later but first we need to
+ move %ignore from using %rename to use
+ %feature(ignore).
+
+ String *symname = Swig_name_make(templnode,0,$3,0,0);
+ */
+ String *symname = $3;
+ Swig_cparse_template_expand(templnode,symname,temparms,tscope);
+ Setattr(templnode,"sym:name",symname);
+ } else {
+ static int cnt = 0;
+ String *nname = NewStringf("__dummy_%d__", cnt++);
+ Swig_cparse_template_expand(templnode,nname,temparms,tscope);
+ Setattr(templnode,"sym:name",nname);
+ Delete(nname);
+ Setattr(templnode,"feature:onlychildren",
+ "typemap,typemapitem,typemapcopy,typedef,types,fragment");
+ }
+ Delattr(templnode,"templatetype");
+ Setattr(templnode,"template",nn);
+ tnode = templnode;
+ Setfile(templnode,cparse_file);
+ Setline(templnode,cparse_line);
+ Delete(temparms);
+
+ add_symbols_copy(templnode);
+
+ if (Strcmp(nodeType(templnode),"class") == 0) {
+
+ /* Identify pure abstract methods */
+ Setattr(templnode,"abstract", pure_abstract(firstChild(templnode)));
+
+ /* Set up inheritance in symbol table */
+ {
+ Symtab *csyms;
+ List *baselist = Getattr(templnode,"baselist");
+ csyms = Swig_symbol_current();
+ Swig_symbol_setscope(Getattr(templnode,"symtab"));
+ if (baselist) {
+ List *bases = make_inherit_list(Getattr(templnode,"name"),baselist);
+ if (bases) {
+ Iterator s;
+ for (s = First(bases); s.item; s = Next(s)) {
+ Symtab *st = Getattr(s.item,"symtab");
+ if (st) {
+ Setfile(st,Getfile(s.item));
+ Setline(st,Getline(s.item));
+ Swig_symbol_inherit(st);
+ }
+ }
+ Delete(bases);
+ }
+ }
+ 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 *stmp = 0;
+ String *clsname;
+ Node *am;
+ if (Namespaceprefix) {
+ clsname = stmp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
+ } else {
+ clsname = Getattr(templnode,"name");
+ }
+ am = Getattr(extendhash,clsname);
+ if (am) {
+ Symtab *st = Swig_symbol_current();
+ Swig_symbol_setscope(Getattr(templnode,"symtab"));
+ /* Printf(stdout,"%s: %s %x %x\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */
+ merge_extensions(templnode,am);
+ Swig_symbol_setscope(st);
+ append_previous_extension(templnode,am);
+ Delattr(extendhash,clsname);
+ }
+ if (stmp) Delete(stmp);
+ }
+ /* Add to classes hash */
+ if (!classes) classes = NewHash();
+
+ {
+ if (Namespaceprefix) {
+ String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
+ Setattr(classes,temp,templnode);
+ Delete(temp);
+ } else {
+ String *qs = Swig_symbol_qualifiedscopename(templnode);
+ Setattr(classes, qs,templnode);
+ Delete(qs);
+ }
+ }
+ }
+ }
+
+ /* all the overloaded templated functions are added into a linked list */
+ if (nscope_inner) {
+ /* non-global namespace */
+ if (templnode) {
+ appendChild(nscope_inner,templnode);
+ Delete(templnode);
+ if (nscope) $$ = nscope;
+ }
+ } else {
+ /* global namespace */
+ if (!linklistend) {
+ $$ = templnode;
+ } else {
+ set_nextSibling(linklistend,templnode);
+ Delete(templnode);
+ }
+ linklistend = templnode;
+ }
+ }
+ nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions. If a templated class there will never be a sibling. */
+ }
+ }
+ Swig_symbol_setscope(tscope);
+ Delete(Namespaceprefix);
+ 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($$);
+ default_arguments($$);
+ }
+ }
+ | c_enum_decl { $$ = $1; }
+ | c_enum_forward_decl { $$ = $1; }
+
+/* An extern C type declaration, disable cparse_cplusplus if needed. */
+
+ | EXTERN string LBRACE {
+ if (Strcmp($2,"C") == 0) {
+ cparse_externc = 1;
+ }
+ } interface RBRACE {
+ cparse_externc = 0;
+ if (Strcmp($2,"C") == 0) {
+ Node *n = firstChild($5);
+ $$ = new_node("extern");
+ Setattr($$,"name",$2);
+ appendChild($$,n);
+ while (n) {
+ SwigType *decl = Getattr(n,"decl");
+ if (SwigType_isfunction(decl)) {
+ Setattr(n,"storage","externc");
+ }
+ n = nextSibling(n);
+ }
+ } else {
+ Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
+ $$ = new_node("extern");
+ Setattr($$,"name",$2);
+ appendChild($$,firstChild($5));
+ }
+ }
+ ;
+
+/* ------------------------------------------------------------
+ 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);
+ Setattr($$,"throw",$4.throwf);
+ if (!$5) {
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr($$,"code",code);
+ Delete(code);
+ }
+ } else {
+ Node *n = $5;
+ /* Inherit attributes */
+ while (n) {
+ String *type = Copy($2);
+ Setattr(n,"type",type);
+ Setattr(n,"storage",$1);
+ n = nextSibling(n);
+ Delete(type);
+ }
+ }
+ if ($4.bitfield) {
+ Setattr($$,"bitfield", $4.bitfield);
+ }
+
+ /* Look for "::" declarations (ignored) */
+ if (Strstr($3.id,"::")) {
+ /* This is a special case. If the scope name of the declaration exactly
+ matches that of the declaration, then we will allow it. Otherwise, delete. */
+ String *p = Swig_scopename_prefix($3.id);
+ if (p) {
+ if ((Namespaceprefix && Strcmp(p,Namespaceprefix) == 0) ||
+ (inclass && Strcmp(p,Classprefix) == 0)) {
+ String *lstr = Swig_scopename_last($3.id);
+ Setattr($$,"name",lstr);
+ Delete(lstr);
+ set_nextSibling($$,$5);
+ } else {
+ Delete($$);
+ $$ = $5;
+ }
+ Delete(p);
+ } else {
+ 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);
+ Setattr($$,"throw",$3.throwf);
+ if ($3.bitfield) {
+ Setattr($$,"bitfield", $3.bitfield);
+ }
+ if (!$4) {
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr($$,"code",code);
+ Delete(code);
+ }
+ } else {
+ set_nextSibling($$,$4);
+ }
+ }
+ | LBRACE {
+ skip_balanced('{','}');
+ $$ = 0;
+ }
+ ;
+
+initializer : def_args {
+ $$ = $1;
+ $$.qualifier = 0;
+ $$.throws = 0;
+ $$.throwf = 0;
+ }
+ | type_qualifier def_args {
+ $$ = $2;
+ $$.qualifier = $1;
+ $$.throws = 0;
+ $$.throwf = 0;
+ }
+ | THROW LPAREN parms RPAREN def_args {
+ $$ = $5;
+ $$.qualifier = 0;
+ $$.throws = $3;
+ $$.throwf = NewString("1");
+ }
+ | type_qualifier THROW LPAREN parms RPAREN def_args {
+ $$ = $6;
+ $$.qualifier = $1;
+ $$.throws = $4;
+ $$.throwf = NewString("1");
+ }
+ ;
+
+
+/* ------------------------------------------------------------
+ enum Name;
+ ------------------------------------------------------------ */
+
+c_enum_forward_decl : storage_class ENUM ID SEMI {
+ SwigType *ty = 0;
+ $$ = new_node("enumforward");
+ ty = NewStringf("enum %s", $3);
+ Setattr($$,"name",$3);
+ Setattr($$,"type",ty);
+ Setattr($$,"sym:weak", "1");
+ add_symbols($$);
+ }
+ ;
+
+/* ------------------------------------------------------------
+ enum { ... }
+ * ------------------------------------------------------------ */
+
+c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI {
+ SwigType *ty = 0;
+ $$ = new_node("enum");
+ ty = NewStringf("enum %s", $3);
+ Setattr($$,"name",$3);
+ Setattr($$,"type",ty);
+ 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;
+ int unnamedinstance = 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);
+ /* name is not set for unnamed enum instances, e.g. enum { foo } Instance; */
+ if ($1 && Cmp($1,"typedef") == 0) {
+ Setattr($$,"name",$7.id);
+ } else {
+ unnamedinstance = 1;
+ }
+ Setattr($$,"storage",$1);
+ }
+ if ($7.id && Cmp($1,"typedef") == 0) {
+ Setattr($$,"tdname",$7.id);
+ Setattr($$,"allows_typedef","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 (unnamedinstance) {
+ SwigType *cty = NewString("enum ");
+ Setattr($$,"type",cty);
+ Setattr($$,"unnamedinstance","1");
+ Setattr(n,"unnamedinstance","1");
+ Delete(cty);
+ }
+ if ($8) {
+ Node *p = $8;
+ set_nextSibling(n,p);
+ while (p) {
+ SwigType *cty = Copy(ty);
+ Setattr(p,"type",cty);
+ Setattr(p,"unnamed",unnamed);
+ Setattr(p,"storage",$1);
+ Delete(cty);
+ p = nextSibling(p);
+ }
+ } else {
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr(n,"code",code);
+ Delete(code);
+ }
+ }
+
+ /* Ensure that typedef enum ABC {foo} XYZ; uses XYZ for sym:name, like structs.
+ * Note that class_rename/yyrename are bit of a mess so used this simple approach to change the name. */
+ if ($7.id && $3 && Cmp($1,"typedef") == 0) {
+ String *name = NewString($7.id);
+ Setattr($$, "parser:makename", name);
+ Delete(name);
+ }
+
+ add_symbols($$); /* Add enum to tag space */
+ set_nextSibling($$,n);
+ Delete(n);
+ add_symbols($5); /* Add enum values to id space */
+ add_symbols(n);
+ Delete(unnamed);
+ }
+ ;
+
+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 parameter 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 = NewStringEmpty();
+ SwigType_add_function(decl,$6.parms);
+ Setattr($$,"decl",decl);
+ Setattr($$,"parms",$6.parms);
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr($$,"code",code);
+ Delete(code);
+ }
+ }
+ if ($6.defarg) {
+ Setattr($$,"value",$6.defarg);
+ }
+ Setattr($$,"throws",$6.throws);
+ Setattr($$,"throw",$6.throwf);
+ err = 0;
+ }
+ }
+ if (err) {
+ Swig_error(cparse_file,cparse_line,"Syntax error in input(2).\n");
+ exit(1);
+ }
+ }
+ ;
+
+/* ======================================================================
+ * 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;
+ Node *scope = 0;
+ $<node>$ = new_node("class");
+ Setline($<node>$,cparse_start_line);
+ Setattr($<node>$,"kind",$2);
+ if ($4) {
+ Setattr($<node>$,"baselist", Getattr($4,"public"));
+ Setattr($<node>$,"protectedbaselist", Getattr($4,"protected"));
+ Setattr($<node>$,"privatebaselist", Getattr($4,"private"));
+ }
+ Setattr($<node>$,"allows_typedef","1");
+
+ /* preserve the current scope */
+ prev_symtab = Swig_symbol_current();
+
+ /* If the class name is qualified. We need to create or lookup namespace/scope entries */
+ scope = resolve_node_scope($3);
+ Setfile(scope,cparse_file);
+ Setline(scope,cparse_line);
+ $3 = scope;
+
+ /* support for old nested classes "pseudo" support, such as:
+
+ %rename(Ala__Ola) Ala::Ola;
+ class Ala::Ola {
+ public:
+ Ola() {}
+ };
+
+ this should disappear when a proper implementation is added.
+ */
+ if (nscope_inner && Strcmp(nodeType(nscope_inner),"namespace") != 0) {
+ if (Namespaceprefix) {
+ String *name = NewStringf("%s::%s", Namespaceprefix, $3);
+ $3 = name;
+ Namespaceprefix = 0;
+ nscope_inner = 0;
+ }
+ }
+ Setattr($<node>$,"name",$3);
+
+ Delete(class_rename);
+ class_rename = make_name($<node>$,$3,0);
+ Classprefix = NewString($3);
+ /* Deal with inheritance */
+ if ($4) {
+ bases = make_inherit_list($3,Getattr($4,"public"));
+ }
+ 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);
+ }
+ Swig_name_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) {
+ Iterator s;
+ for (s = First(bases); s.item; s = Next(s)) {
+ Symtab *st = Getattr(s.item,"symtab");
+ if (st) {
+ Setfile(st,Getfile(s.item));
+ Setline(st,Getline(s.item));
+ Swig_symbol_inherit(st);
+ }
+ }
+ Delete(bases);
+ }
+ Delete(Namespaceprefix);
+ 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) {
+ String *tpname = Copy(Getattr(tp,"name"));
+ Node *tn = new_node("templateparm");
+ Setattr(tn,"name",tpname);
+ Swig_symbol_cadd(tpname,tn);
+ tp = nextSibling(tp);
+ Delete(tpname);
+ }
+ }
+ if (class_level >= max_class_levels) {
+ if (!max_class_levels) {
+ max_class_levels = 16;
+ } else {
+ max_class_levels *= 2;
+ }
+ class_decl = (Node**) realloc(class_decl, sizeof(Node*) * max_class_levels);
+ if (!class_decl) {
+ Swig_error(cparse_file, cparse_line, "realloc() failed\n");
+ }
+ }
+ class_decl[class_level++] = $<node>$;
+ inclass = 1;
+ } cpp_members RBRACE cpp_opt_declarators {
+ Node *p;
+ SwigType *ty;
+ Symtab *cscope = prev_symtab;
+ Node *am = 0;
+ String *scpname = 0;
+ $$ = class_decl[--class_level];
+ inclass = 0;
+
+ /* 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);
+ am = Getattr(extendhash,clsname);
+ if (am) {
+ merge_extensions($$,am);
+ Delattr(extendhash,clsname);
+ }
+ Delete(clsname);
+ }
+ if (!classes) classes = NewHash();
+ scpname = Swig_symbol_qualifiedscopename(0);
+ Setattr(classes,scpname,$$);
+ Delete(scpname);
+
+ appendChild($$,$7);
+
+ if (am) append_previous_extension($$,am);
+
+ p = $9;
+ if (p) {
+ set_nextSibling($$,p);
+ }
+
+ if (cparse_cplusplus && !cparse_externc) {
+ 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)) {
+ String *cname;
+ name = Getattr($9,"name");
+ cname = Copy(name);
+ Setattr($$,"tdname",cname);
+ Delete(cname);
+
+ /* Use typedef name as class name */
+ if (class_rename && (Strcmp(class_rename,$3) == 0)) {
+ Delete(class_rename);
+ class_rename = NewString(name);
+ }
+ if (!Getattr(classes,name)) {
+ Setattr(classes,name,$$);
+ }
+ Setattr($$,"decl",decltype);
+ }
+ }
+ }
+ appendChild($$,dump_nested(Char(name)));
+ }
+
+ if (cplus_mode != CPLUS_PUBLIC) {
+ /* we 'open' the class at the end, to allow %template
+ to add new members */
+ Node *pa = new_node("access");
+ Setattr(pa,"kind","public");
+ cplus_mode = CPLUS_PUBLIC;
+ appendChild($$,pa);
+ Delete(pa);
+ }
+
+ Setattr($$,"symtab",Swig_symbol_popscope());
+
+ Classprefix = 0;
+ if (nscope_inner) {
+ /* this is tricky */
+ /* we add the declaration in the original namespace */
+ appendChild(nscope_inner,$$);
+ Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols($$);
+ if (nscope) $$ = nscope;
+ /* but the variable definition in the current scope */
+ Swig_symbol_setscope(cscope);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols($9);
+ } else {
+ Delete(yyrename);
+ yyrename = Copy(class_rename);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+
+ add_symbols($$);
+ add_symbols($9);
+ }
+ Swig_symbol_setscope(cscope);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ }
+
+/* An unnamed struct, possibly with a typedef */
+
+ | storage_class cpptype LBRACE {
+ String *unnamed;
+ unnamed = make_unnamed();
+ $<node>$ = new_node("class");
+ Setline($<node>$,cparse_start_line);
+ Setattr($<node>$,"kind",$2);
+ Setattr($<node>$,"storage",$1);
+ Setattr($<node>$,"unnamed",unnamed);
+ Setattr($<node>$,"allows_typedef","1");
+ Delete(class_rename);
+ class_rename = make_name($<node>$,0,0);
+ if (strcmp($2,"class") == 0) {
+ cplus_mode = CPLUS_PRIVATE;
+ } else {
+ cplus_mode = CPLUS_PUBLIC;
+ }
+ Swig_symbol_newscope();
+ cparse_start_line = cparse_line;
+ if (class_level >= max_class_levels) {
+ if (!max_class_levels) {
+ max_class_levels = 16;
+ } else {
+ max_class_levels *= 2;
+ }
+ class_decl = (Node**) realloc(class_decl, sizeof(Node*) * max_class_levels);
+ if (!class_decl) {
+ Swig_error(cparse_file, cparse_line, "realloc() failed\n");
+ }
+ }
+ class_decl[class_level++] = $<node>$;
+ inclass = 1;
+ Classprefix = NewStringEmpty();
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ } cpp_members RBRACE declarator c_decl_tail {
+ String *unnamed;
+ Node *n;
+ Classprefix = 0;
+ $$ = class_decl[--class_level];
+ inclass = 0;
+ unnamed = Getattr($$,"unnamed");
+
+ /* 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);
+ if ($8) {
+ Node *p = $8;
+ set_nextSibling(n,p);
+ while (p) {
+ String *type = Copy(unnamed);
+ Setattr(p,"name",$7.id);
+ Setattr(p,"unnamed",unnamed);
+ Setattr(p,"type",type);
+ Delete(type);
+ Setattr(p,"storage",$1);
+ p = nextSibling(p);
+ }
+ }
+ set_nextSibling($$,n);
+ Delete(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)) {
+ String *scpname = 0;
+ name = $7.id;
+ Setattr($$,"tdname",name);
+ Setattr($$,"name",name);
+ Swig_symbol_setscopename(name);
+
+ /* If a proper name was 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);
+ append_previous_extension($$,am);
+ Delattr(extendhash,clsname);
+ }
+ Delete(clsname);
+ }
+ if (!classes) classes = NewHash();
+ scpname = Swig_symbol_qualifiedscopename(0);
+ Setattr(classes,scpname,$$);
+ Delete(scpname);
+ } else {
+ Swig_symbol_setscopename((char*)"<unnamed>");
+ }
+ }
+ appendChild($$,$5);
+ appendChild($$,dump_nested(Char(name)));
+ }
+ /* Pop the scope */
+ Setattr($$,"symtab",Swig_symbol_popscope());
+ if (class_rename) {
+ Delete(yyrename);
+ yyrename = NewString(class_rename);
+ }
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols($$);
+ add_symbols(n);
+ Delete(unnamed);
+ }
+ ;
+
+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");
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ 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;
+
+ /* check if we get a namespace node with a class declaration, and retrieve the class */
+ Symtab *cscope = Swig_symbol_current();
+ Symtab *sti = 0;
+ Node *ntop = $6;
+ Node *ni = ntop;
+ SwigType *ntype = ni ? nodeType(ni) : 0;
+ while (ni && Strcmp(ntype,"namespace") == 0) {
+ sti = Getattr(ni,"symtab");
+ ni = firstChild(ni);
+ ntype = nodeType(ni);
+ }
+ if (sti) {
+ Swig_symbol_setscope(sti);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ $6 = ni;
+ }
+
+ template_parameters = 0;
+ $$ = $6;
+ if ($$) tname = Getattr($$,"name");
+
+ /* Check if the class is a template specialization */
+ if (($$) && (Strchr(tname,'<')) && (!is_operator(tname))) {
+ /* 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_WARN_NODE_BEGIN(tempn);
+ Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase);
+ SWIG_WARN_NODE_END(tempn);
+ 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' %s\n", targs, tlist); */
+ if (!Getattr($$,"sym:weak")) {
+ Setattr($$,"sym:typename","1");
+ }
+
+ if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
+ Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
+
+ } else {
+
+ /* This code builds the argument list for the partial template
+ specialization. This is a little hairy, but the idea is as
+ follows:
+
+ $3 contains a list of arguments supplied for the template.
+ For example template<class T>.
+
+ tlist is a list of the specialization arguments--which may be
+ different. For example class<int,T>.
+
+ tp is a copy of the arguments in the original template definition.
+
+ The patching algorithm walks through the list of supplied
+ arguments ($3), finds the position in the specialization arguments
+ (tlist), and then patches the name in the argument list of the
+ original template.
+ */
+
+ {
+ String *pn;
+ Parm *p, *p1;
+ int i, nargs;
+ Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
+ nargs = Len(tlist);
+ p = $3;
+ while (p) {
+ for (i = 0; i < nargs; i++){
+ pn = Getattr(p,"name");
+ if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
+ int j;
+ Parm *p1 = tp;
+ for (j = 0; j < i; j++) {
+ p1 = nextSibling(p1);
+ }
+ Setattr(p1,"name",pn);
+ Setattr(p1,"partialarg","1");
+ }
+ }
+ p = nextSibling(p);
+ }
+ p1 = tp;
+ i = 0;
+ while (p1) {
+ if (!Getattr(p1,"partialarg")) {
+ Delattr(p1,"name");
+ Setattr(p1,"type", Getitem(tlist,i));
+ }
+ i++;
+ p1 = nextSibling(p1);
+ }
+ Setattr($$,"templateparms",tp);
+ Delete(tp);
+ }
+#if 0
+ /* 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");
+ Printf(stdout,"pn = '%s'\n", pn);
+ if (pn) Setattr(p1,"name",pn);
+ else Delattr(p1,"name");
+ pn = Getattr(p,"type");
+ if (pn) Setattr(p1,"type",pn);
+ p = nextSibling(p);
+ p1 = nextSibling(p1);
+ }
+ Setattr($$,"templateparms",tp);
+ Delete(tp);
+ } else {
+ Setattr($$,"templateparms",$3);
+ }
+#endif
+ 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, ilen;
+ while (p) {
+ String *n = Getattr(p,"name");
+ if (!n) {
+ p = nextSibling(p);
+ continue;
+ }
+ ilen = Len(tlist);
+ for (i = 0; i < ilen; i++) {
+ if (Strstr(Getitem(tlist,i),n)) {
+ sprintf(tmp,"$%d",i+1);
+ Replaceid(fname,n,tmp);
+ }
+ }
+ p = nextSibling(p);
+ }
+ /* Patch argument names with typedef */
+ {
+ Iterator tt;
+ List *tparms = SwigType_parmlist(fname);
+ ffname = SwigType_templateprefix(fname);
+ Append(ffname,"<(");
+ for (tt = First(tparms); tt.item; ) {
+ SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0);
+ SwigType *ttr = Swig_symbol_type_qualify(rtt,0);
+ Append(ffname,ttr);
+ tt = Next(tt);
+ if (tt.item) Putc(',',ffname);
+ Delete(rtt);
+ Delete(ttr);
+ }
+ Delete(tparms);
+ Append(ffname,")>");
+ }
+ {
+ String *partials = Getattr(tempn,"partials");
+ if (!partials) {
+ partials = NewList();
+ Setattr(tempn,"partials",partials);
+ Delete(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 */
+ /* add default args from generic template */
+ String *ty = Swig_symbol_template_deftype(tname,0);
+ String *fname = Swig_symbol_type_qualify(ty,0);
+ Swig_symbol_cadd(fname,$$);
+ Delete(ty);
+ Delete(fname);
+ }
+ } else if ($$) {
+ Setattr($$,"templatetype",nodeType($6));
+ set_nodeType($$,"template");
+ Setattr($$,"templateparms", $3);
+ if (!Getattr($$,"sym:weak")) {
+ Setattr($$,"sym:typename","1");
+ }
+ add_symbols($$);
+ default_arguments($$);
+ /* 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");
+ Append(fname,n);
+ p = nextSibling(p);
+ if (p) Putc(',',fname);
+ }
+ Append(fname,")>");
+ Swig_symbol_cadd(fname,$$);
+ }
+ }
+ $$ = ntop;
+ Swig_symbol_setscope(cscope);
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ if (error) $$ = 0;
+ }
+ | TEMPLATE cpptype idcolon {
+ Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
+ $$ = 0;
+ }
+ ;
+
+cpp_temp_possible: c_decl {
+ $$ = $1;
+ }
+ | cpp_class_decl {
+ $$ = $1;
+ }
+ | cpp_constructor_decl {
+ $$ = $1;
+ }
+ | cpp_template_decl {
+ $$ = 0;
+ }
+ | cpp_forward_class_decl {
+ $$ = $1;
+ }
+ | cpp_conversion_operator {
+ $$ = $1;
+ }
+ ;
+
+template_parms : templateparameters {
+ /* 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);
+ }
+ }
+ ;
+
+templateparameters : templateparameter templateparameterstail {
+ set_nextSibling($1,$2);
+ $$ = $1;
+ }
+ | empty { $$ = 0; }
+ ;
+
+templateparameter : templcpptype {
+ $$ = NewParm(NewString($1), 0);
+ }
+ | parm {
+ $$ = $1;
+ }
+ ;
+
+templateparameterstail : COMMA templateparameter templateparameterstail {
+ set_nextSibling($2,$3);
+ $$ = $2;
+ }
+ | empty { $$ = 0; }
+ ;
+
+/* Namespace support */
+
+cpp_using_decl : USING idcolon SEMI {
+ String *uname = Swig_symbol_type_qualify($2,0);
+ String *name = Swig_scopename_last($2);
+ $$ = new_node("using");
+ Setattr($$,"uname",uname);
+ Setattr($$,"name", name);
+ Delete(uname);
+ Delete(name);
+ 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) {
+ Symtab *current = Swig_symbol_current();
+ Symtab *symtab = Getattr(n,"symtab");
+ $$ = new_node("using");
+ Setattr($$,"node",n);
+ Setattr($$,"namespace", $3);
+ if (current != symtab) {
+ Swig_symbol_inherit(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 && ($1 == Getattr(h,"sym:symtab")) && (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);
+ }
+ Delete(Namespaceprefix);
+ 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;
+ Delete(Namespaceprefix);
+ Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+ add_symbols($$);
+ }
+ | NAMESPACE LBRACE {
+ Hash *h;
+ $1 = Swig_symbol_current();
+ h = Swig_symbol_clookup((char *)" ",0);
+ if (h && (Strcmp(nodeType(h),"namespace") == 0)) {
+ Swig_symbol_setscope(Getattr(h,"symtab"));
+ } else {
+ Swig_symbol_newscope();
+ /* we don't use "__unnamed__", but a long 'empty' name */
+ Swig_symbol_setscopename(" ");
+ }
+ Namespaceprefix = 0;
+ } interface RBRACE {
+ $$ = $4;
+ set_nodeType($$,"namespace");
+ Setattr($$,"unnamed","1");
+ Setattr($$,"symtab", Swig_symbol_popscope());
+ Swig_symbol_setscope($1);
+ Delete(Namespaceprefix);
+ 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;
+ /* Insert cpp_member (including any siblings) to the front of the cpp_members linked list */
+ 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");
+ tag_nodes($4,"feature:extend",(char*) "1");
+ appendChild($$,$4);
+ set_nextSibling($$,$6);
+ }
+ | include_directive { $$ = $1; }
+ | empty { $$ = 0;}
+ | error {
+ int start_line = cparse_line;
+ skip_decl();
+ Swig_error(cparse_file,start_line,"Syntax error in input(3).\n");
+ exit(1);
+ } 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;
+ if (extendmode) {
+ String *symname;
+ symname= make_name($$,Getattr($$,"name"), Getattr($$,"decl"));
+ if (Strcmp(symname,Getattr($$,"name")) == 0) {
+ /* No renaming operation. Set name to class name */
+ Delete(yyrename);
+ yyrename = NewString(Getattr(current_class,"sym:name"));
+ } else {
+ Delete(yyrename);
+ yyrename = symname;
+ }
+ }
+ add_symbols($$);
+ default_arguments($$);
+ }
+ | 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; }
+ | anonymous_bitfield { $$ = 0; }
+ | fragment_directive {$$ = $1; }
+ | types_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 = NewStringEmpty();
+ $$ = new_node("constructor");
+ Setattr($$,"storage",$1);
+ Setattr($$,"name",$2);
+ Setattr($$,"parms",$4);
+ SwigType_add_function(decl,$4);
+ Setattr($$,"decl",decl);
+ Setattr($$,"throws",$6.throws);
+ Setattr($$,"throw",$6.throwf);
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr($$,"code",code);
+ Delete(code);
+ }
+ SetFlag($$,"feature:new");
+ } else {
+ $$ = 0;
+ }
+ }
+ ;
+
+/* A destructor (hopefully) */
+
+cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
+ String *name = NewStringf("%s",$2);
+ if (*(Char(name)) != '~') Insert(name,0,"~");
+ $$ = new_node("destructor");
+ Setattr($$,"name",name);
+ Delete(name);
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr($$,"code",code);
+ Delete(code);
+ }
+ {
+ String *decl = NewStringEmpty();
+ SwigType_add_function(decl,$4);
+ Setattr($$,"decl",decl);
+ Delete(decl);
+ }
+ Setattr($$,"throws",$6.throws);
+ Setattr($$,"throw",$6.throwf);
+ add_symbols($$);
+ }
+
+/* A virtual destructor */
+
+ | VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend {
+ String *name;
+ char *c = 0;
+ $$ = new_node("destructor");
+ /* Check for template names. If the class is a template
+ and the constructor is missing the template part, we
+ add it */
+ if (Classprefix) {
+ c = strchr(Char(Classprefix),'<');
+ if (c && !Strchr($3,'<')) {
+ $3 = NewStringf("%s%s",$3,c);
+ }
+ }
+ Setattr($$,"storage","virtual");
+ name = NewStringf("%s",$3);
+ if (*(Char(name)) != '~') Insert(name,0,"~");
+ Setattr($$,"name",name);
+ Delete(name);
+ Setattr($$,"throws",$7.throws);
+ Setattr($$,"throw",$7.throwf);
+ if ($7.val) {
+ Setattr($$,"value","0");
+ }
+ if (Len(scanner_ccode)) {
+ String *code = Copy(scanner_ccode);
+ Setattr($$,"code",code);
+ Delete(code);
+ }
+ {
+ String *decl = NewStringEmpty();
+ SwigType_add_function(decl,$5);
+ Setattr($$,"decl",decl);
+ Delete(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);
+ Setattr($$,"storage",$1);
+
+ 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);
+ Setattr($$,"storage",$1);
+ decl = NewStringEmpty();
+ 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 = NewStringEmpty();
+ $$ = new_node("cdecl");
+ Setattr($$,"type",$3);
+ Setattr($$,"name",$2);
+ Setattr($$,"storage",$1);
+ 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 && strcmp($2, "class") != 0) {
+ Nested *n = (Nested *) malloc(sizeof(Nested));
+ n->code = NewStringEmpty();
+ 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 = NewStringEmpty();
+ n->kind = $2;
+ n->unnamed = 0;
+ 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);
+ if (strcmp($2, "class") == 0) {
+ /* For now, just treat the nested class as a forward
+ * declaration (SF bug #909387). */
+ $$ = new_node("classforward");
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Setattr($$,"kind",$2);
+ Setattr($$,"name",$3);
+ Setattr($$,"sym:weak", "1");
+ add_symbols($$);
+ }
+ }
+ }
+ }
+/* A struct { } id; declaration */
+ | 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 = NewStringEmpty();
+ 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 = NewStringEmpty();
+ n->kind = $2;
+ n->unnamed = 1;
+ 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);
+ }
+ }
+ }
+/* A 'class name : base_list { };' declaration, always ignored */
+/*****
+ This fixes derived_nested.i, but it adds one shift/reduce. Anyway,
+ we are waiting for the nested class support.
+ *****/
+ | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
+ } SEMI {
+ $$ = 0;
+ if (cplus_mode == CPLUS_PUBLIC) {
+ Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
+ }
+ }
+/*
+ | TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
+ } SEMI {
+ $$ = 0;
+ if (cplus_mode == CPLUS_PUBLIC) {
+ Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
+ }
+ }
+*/
+ ;
+
+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);
+ $$.throws = $1.throws;
+ $$.throwf = $1.throwf;
+ }
+ | cpp_const LBRACE {
+ skip_balanced('{','}');
+ $$.throws = $1.throws;
+ $$.throwf = $1.throwf;
+ }
+ ;
+
+cpp_vend : cpp_const SEMI {
+ Clear(scanner_ccode);
+ $$.val = 0;
+ $$.qualifier = $1.qualifier;
+ $$.bitfield = 0;
+ $$.throws = $1.throws;
+ $$.throwf = $1.throwf;
+ }
+ | cpp_const EQUAL definetype SEMI {
+ Clear(scanner_ccode);
+ $$.val = $3.val;
+ $$.qualifier = $1.qualifier;
+ $$.bitfield = 0;
+ $$.throws = $1.throws;
+ $$.throwf = $1.throwf;
+ }
+ | cpp_const LBRACE {
+ skip_balanced('{','}');
+ $$.val = 0;
+ $$.qualifier = $1.qualifier;
+ $$.bitfield = 0;
+ $$.throws = $1.throws;
+ $$.throwf = $1.throwf;
+ }
+ ;
+
+
+anonymous_bitfield : storage_class type COLON expr SEMI { };
+
+/* ======================================================================
+ * 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\".\n", $2);
+ $$ = 0;
+ }
+ }
+ | STATIC { $$ = "static"; }
+ | TYPEDEF { $$ = "typedef"; }
+ | VIRTUAL { $$ = "virtual"; }
+ | FRIEND { $$ = "friend"; }
+ | EXPLICIT { $$ = "explicit"; }
+ | 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 {
+ set_nextSibling($1,$2);
+ $$ = $1;
+ }
+ | 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 def_args {
+ $$ = NewParm(NewStringf("template<class> %s %s", $5,$6), 0);
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ if ($7.val) {
+ Setattr($$,"value",$7.val);
+ }
+ }
+ | 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 {
+ set_nextSibling($1,$2);
+ $$ = $1;
+ }
+ | 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) {
+ String *v = Copy(value);
+ Setattr($1,"type",v);
+ Delete(v);
+ n = 0;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ }
+ | valexpr {
+ $$ = NewParm(0,0);
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Setattr($$,"value",$1.val);
+ }
+ ;
+
+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;
+ $$.throwf = 0;
+ }
+ }
+ | EQUAL definetype LBRACKET expr RBRACKET {
+ $$ = $2;
+ if ($2.type == T_ERROR) {
+ Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
+ $$ = $2;
+ $$.val = 0;
+ $$.rawval = 0;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ $$.throwf = 0;
+ } else {
+ $$.val = NewStringf("%s[%s]",$2.val,$4.val);
+ }
+ }
+ | EQUAL LBRACE {
+ skip_balanced('{','}');
+ $$.val = 0;
+ $$.rawval = 0;
+ $$.type = T_INT;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ $$.throwf = 0;
+ }
+ | COLON expr {
+ $$.val = 0;
+ $$.rawval = 0;
+ $$.type = 0;
+ $$.bitfield = $2.val;
+ $$.throws = 0;
+ $$.throwf = 0;
+ }
+ | empty {
+ $$.val = 0;
+ $$.rawval = 0;
+ $$.type = T_INT;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ $$.throwf = 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 = NewStringEmpty();
+ }
+ | AND notso_direct_declarator {
+ $$ = $2;
+ $$.type = NewStringEmpty();
+ SwigType_add_reference($$.type);
+ if ($2.type) {
+ SwigType_push($$.type,$2.type);
+ Delete($2.type);
+ }
+ }
+ | idcolon DSTAR notso_direct_declarator {
+ SwigType *t = NewStringEmpty();
+
+ $$ = $3;
+ SwigType_add_memberpointer(t,$1);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | pointer idcolon DSTAR notso_direct_declarator {
+ SwigType *t = NewStringEmpty();
+ $$ = $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 = NewStringEmpty();
+ $$ = $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;
+ }
+
+/*
+ | LPAREN AND idcolon RPAREN {
+ $$.id = Char($3);
+ $$.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 = NewStringEmpty();
+ SwigType_add_memberpointer(t,$2);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | notso_direct_declarator LBRACKET RBRACKET {
+ SwigType *t;
+ $$ = $1;
+ t = NewStringEmpty();
+ 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 = NewStringEmpty();
+ 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 = NewStringEmpty();
+ 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 AND direct_declarator RPAREN {
+ $$ = $3;
+ if (!$$.type) {
+ $$.type = NewStringEmpty();
+ }
+ SwigType_add_reference($$.type);
+ }
+ | LPAREN idcolon DSTAR direct_declarator RPAREN {
+ SwigType *t;
+ $$ = $4;
+ t = NewStringEmpty();
+ SwigType_add_memberpointer(t,$2);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | direct_declarator LBRACKET RBRACKET {
+ SwigType *t;
+ $$ = $1;
+ t = NewStringEmpty();
+ SwigType_add_array(t,(char*)"");
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | direct_declarator LBRACKET expr RBRACKET {
+ SwigType *t;
+ $$ = $1;
+ t = NewStringEmpty();
+ 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 = NewStringEmpty();
+ 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 = NewStringEmpty();
+ SwigType_add_reference($$.type);
+ if ($2.type) {
+ SwigType_push($$.type,$2.type);
+ Delete($2.type);
+ }
+ }
+ | AND {
+ $$.id = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ $$.type = NewStringEmpty();
+ SwigType_add_reference($$.type);
+ }
+ | idcolon DSTAR {
+ $$.type = NewStringEmpty();
+ SwigType_add_memberpointer($$.type,$1);
+ $$.id = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ }
+ | pointer idcolon DSTAR {
+ SwigType *t = NewStringEmpty();
+ $$.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 = NewStringEmpty();
+ 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 = NewStringEmpty();
+ SwigType_add_array(t,$3.val);
+ if ($$.type) {
+ SwigType_push(t,$$.type);
+ Delete($$.type);
+ }
+ $$.type = t;
+ }
+ | LBRACKET RBRACKET {
+ $$.type = NewStringEmpty();
+ $$.id = 0;
+ $$.parms = 0;
+ $$.have_parms = 0;
+ SwigType_add_array($$.type,(char*)"");
+ }
+ | LBRACKET expr RBRACKET {
+ $$.type = NewStringEmpty();
+ $$.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 = NewStringEmpty();
+ 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 = NewStringEmpty();
+ SwigType_add_function($$.type,$2);
+ $$.parms = $2;
+ $$.have_parms = 1;
+ $$.id = 0;
+ }
+ ;
+
+
+pointer : STAR type_qualifier pointer {
+ $$ = NewStringEmpty();
+ SwigType_add_pointer($$);
+ SwigType_push($$,$2);
+ SwigType_push($$,$3);
+ Delete($3);
+ }
+ | STAR pointer {
+ $$ = NewStringEmpty();
+ SwigType_add_pointer($$);
+ SwigType_push($$,$2);
+ Delete($2);
+ }
+ | STAR type_qualifier {
+ $$ = NewStringEmpty();
+ SwigType_add_pointer($$);
+ SwigType_push($$,$2);
+ }
+ | STAR {
+ $$ = NewStringEmpty();
+ SwigType_add_pointer($$);
+ }
+ ;
+
+type_qualifier : type_qualifier_raw {
+ $$ = NewStringEmpty();
+ if ($1) SwigType_add_qualifier($$,$1);
+ }
+ | type_qualifier_raw type_qualifier {
+ $$ = $2;
+ if ($1) SwigType_add_qualifier($$,$1);
+ }
+ ;
+
+type_qualifier_raw : CONST_QUAL { $$ = "const"; }
+ | VOLATILE { $$ = "volatile"; }
+ | REGISTER { $$ = 0; }
+ ;
+
+/* 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 type_qualifier {
+ $$ = $1;
+ SwigType_push($$,$2);
+ }
+ | type_qualifier type_right type_qualifier {
+ $$ = $2;
+ SwigType_push($$,$3);
+ SwigType_push($$,$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; }
+
+ | 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) || (Strncmp($2.type,"double",6) == 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 if (Cmp($2.type,"complex") == 0) {
+ $$.type = NewString("double complex");
+ } else {
+ err = 1;
+ }
+ } else if (Cmp($1.type,"float") == 0) {
+ if (Cmp($2.type,"complex") == 0) {
+ $$.type = NewString("float complex");
+ } else {
+ err = 1;
+ }
+ } else if (Cmp($1.type,"complex") == 0) {
+ $$.type = NewStringf("%s complex", $2.type);
+ } 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_WCHAR {
+ $$.type = NewString("wchar_t");
+ $$.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;
+ }
+ | TYPE_COMPLEX {
+ $$.type = NewString("complex");
+ $$.us = 0;
+ }
+ | TYPE_NON_ISO_INT8 {
+ $$.type = NewString("__int8");
+ $$.us = 0;
+ }
+ | TYPE_NON_ISO_INT16 {
+ $$.type = NewString("__int16");
+ $$.us = 0;
+ }
+ | TYPE_NON_ISO_INT32 {
+ $$.type = NewString("__int32");
+ $$.us = 0;
+ }
+ | TYPE_NON_ISO_INT64 {
+ $$.type = NewString("__int64");
+ $$.us = 0;
+ }
+ ;
+
+definetype : { /* scanner_check_typedef(); */ } expr {
+ $$ = $2;
+ if ($$.type == T_STRING) {
+ $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
+ } else if ($$.type != T_CHAR) {
+ $$.rawval = 0;
+ }
+ $$.bitfield = 0;
+ $$.throws = 0;
+ $$.throwf = 0;
+ scanner_ignore_typedef();
+ }
+/*
+ | string {
+ $$.val = NewString($1);
+ $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
+ $$.type = T_STRING;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ $$.throwf = 0;
+ }
+*/
+ ;
+
+/* Some stuff for handling enums */
+
+ename : ID { $$ = $1; }
+ | empty { $$ = (char *) 0;}
+ ;
+
+enumlist : enumlist COMMA edecl {
+
+ /* Ignore if there is a trailing comma in the enum list */
+ if ($3) {
+ Node *leftSibling = Getattr($1,"_last");
+ if (!leftSibling) {
+ leftSibling=$1;
+ }
+ set_nextSibling(leftSibling,$3);
+ Setattr($1,"_last",$3);
+ }
+ $$ = $1;
+ }
+ | edecl {
+ $$ = $1;
+ if ($1) {
+ Setattr($1,"_last",$1);
+ }
+ }
+ ;
+
+edecl : ID {
+ SwigType *type = NewSwigType(T_INT);
+ $$ = new_node("enumitem");
+ Setattr($$,"name",$1);
+ Setattr($$,"type",type);
+ SetFlag($$,"feature:immutable");
+ Delete(type);
+ }
+ | ID EQUAL etype {
+ $$ = new_node("enumitem");
+ Setattr($$,"name",$1);
+ Setattr($$,"enumvalue", $3.val);
+ if ($3.type == T_CHAR) {
+ SwigType *type = NewSwigType(T_CHAR);
+ Setattr($$,"value",NewStringf("\'%(escape)s\'", $3.val));
+ Setattr($$,"type",type);
+ Delete(type);
+ } else {
+ SwigType *type = NewSwigType(T_INT);
+ Setattr($$,"value",$1);
+ Setattr($$,"type",type);
+ Delete(type);
+ }
+ SetFlag($$,"feature:immutable");
+ }
+ | 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) &&
+ ($$.type != T_CHAR)) {
+ Swig_error(cparse_file,cparse_line,"Type error. Expecting an int\n");
+ }
+ if ($$.type == T_CHAR) $$.type = T_INT;
+ }
+ ;
+
+/* Arithmetic expressions. Used for constants, C++ templates, and other cool stuff. */
+
+expr : valexpr { $$ = $1; }
+ | type {
+ Node *n;
+ $$.val = $1;
+ $$.type = T_INT;
+ /* Check if value is in scope */
+ n = Swig_symbol_clookup($1,0);
+ if (n) {
+ /* A band-aid for enum values used in expressions. */
+ if (Strcmp(nodeType(n),"enumitem") == 0) {
+ String *q = Swig_symbol_qualified(n);
+ if (q) {
+ $$.val = NewStringf("%s::%s", q, Getattr(n,"name"));
+ Delete(q);
+ }
+ }
+ }
+ }
+ ;
+
+valexpr : exprnum { $$ = $1; }
+ | string {
+ $$.val = NewString($1);
+ $$.type = T_STRING;
+ }
+ | SIZEOF LPAREN type parameter_declarator RPAREN {
+ SwigType_push($3,$4.type);
+ $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0));
+ $$.type = T_ULONG;
+ }
+ | exprcompound { $$ = $1; }
+ | CHARCONST {
+ $$.val = NewString($1);
+ if (Len($$.val)) {
+ $$.rawval = NewStringf("'%(escape)s'", $$.val);
+ } else {
+ $$.rawval = NewString("'\\0'");
+ }
+ $$.type = T_CHAR;
+ $$.bitfield = 0;
+ $$.throws = 0;
+ $$.throwf = 0;
+ }
+
+/* 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;
+ if ($4.type != T_STRING) {
+ switch ($2.type) {
+ case T_FLOAT:
+ case T_DOUBLE:
+ case T_LONGDOUBLE:
+ case T_FLTCPLX:
+ case T_DBLCPLX:
+ $$.val = NewStringf("(%s)%s", $2.val, $4.val); /* SwigType_str and decimal points don't mix! */
+ break;
+ default:
+ $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $4.val);
+ break;
+ }
+ }
+ }
+ | LPAREN expr pointer RPAREN expr %prec CAST {
+ $$ = $5;
+ if ($5.type != T_STRING) {
+ SwigType_push($2.val,$3);
+ $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
+ }
+ }
+ | LPAREN expr AND RPAREN expr %prec CAST {
+ $$ = $5;
+ if ($5.type != T_STRING) {
+ 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;
+ if ($6.type != T_STRING) {
+ SwigType_push($2.val,$3);
+ SwigType_add_reference($2.val);
+ $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val);
+ }
+ }
+ | AND expr {
+ $$ = $2;
+ $$.val = NewStringf("&%s",$2.val);
+ }
+ | STAR expr {
+ $$ = $2;
+ $$.val = NewStringf("*%s",$2.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 MODULUS 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_type($1.type);
+ }
+ | expr RSHIFT expr {
+ $$.val = NewStringf("%s >> %s",$1.val,$3.val);
+ $$.type = promote_type($1.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;
+ }
+ | expr EQUALTO expr {
+ $$.val = NewStringf("%s==%s",$1.val,$3.val);
+ $$.type = T_INT;
+ }
+ | expr NOTEQUALTO expr {
+ $$.val = NewStringf("%s!=%s",$1.val,$3.val);
+ $$.type = T_INT;
+ }
+/* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these.
+ | expr GREATERTHAN expr {
+ $$.val = NewStringf("%s SWIG_LT %s", $1.val, $3.val);
+ $$.type = T_INT;
+ }
+ | expr LESSTHAN expr {
+ $$.val = NewStringf("%s SWIG_GT %s", $1.val, $3.val);
+ $$.type = T_INT;
+ }
+*/
+ | expr GREATERTHANOREQUALTO expr {
+ /* Putting >= in the expression literally causes an infinite
+ * loop somewhere in the type system. Just workaround for now
+ * - SWIG_GE is defined in swiglabels.swg. */
+ $$.val = NewStringf("%s SWIG_GE %s", $1.val, $3.val);
+ $$.type = T_INT;
+ }
+ | expr LESSTHANOREQUALTO expr {
+ $$.val = NewStringf("%s SWIG_LE %s", $1.val, $3.val);
+ $$.type = T_INT;
+ }
+ | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
+ $$.val = NewStringf("%s?%s:%s", $1.val, $3.val, $5.val);
+ /* This may not be exactly right, but is probably good enough
+ * for the purposes of parsing constant expressions. */
+ $$.type = promote($3.type, $5.type);
+ }
+ | MINUS expr %prec UMINUS {
+ $$.val = NewStringf("-%s",$2.val);
+ $$.type = $2.type;
+ }
+ | PLUS 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 {
+ String *qty;
+ skip_balanced('(',')');
+ qty = Swig_symbol_type_qualify($1,0);
+ if (SwigType_istemplate(qty)) {
+ String *nstr = SwigType_namestr(qty);
+ Delete(qty);
+ qty = nstr;
+ }
+ $$.val = NewStringf("%s%s",qty,scanner_ccode);
+ Clear(scanner_ccode);
+ $$.type = T_INT;
+ Delete(qty);
+ }
+ ;
+
+inherit : raw_inherit {
+ $$ = $1;
+ }
+ ;
+
+raw_inherit : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list = 0; }
+ | empty { $$ = 0; }
+ ;
+
+base_list : base_specifier {
+ Hash *list = NewHash();
+ Node *base = $1;
+ Node *name = Getattr(base,"name");
+ List *lpublic = NewList();
+ List *lprotected = NewList();
+ List *lprivate = NewList();
+ Setattr(list,"public",lpublic);
+ Setattr(list,"protected",lprotected);
+ Setattr(list,"private",lprivate);
+ Delete(lpublic);
+ Delete(lprotected);
+ Delete(lprivate);
+ Append(Getattr(list,Getattr(base,"access")),name);
+ $$ = list;
+ }
+
+ | base_list COMMA base_specifier {
+ Hash *list = $1;
+ Node *base = $3;
+ Node *name = Getattr(base,"name");
+ Append(Getattr(list,Getattr(base,"access")),name);
+ $$ = list;
+ }
+ ;
+
+base_specifier : opt_virtual idcolon {
+ $$ = NewHash();
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Setattr($$,"name",$2);
+ if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) {
+ Setattr($$,"access","private");
+ Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file,cparse_line,
+ "No access specifier given for base class %s (ignored).\n",$2);
+ } else {
+ Setattr($$,"access","public");
+ }
+ }
+ | opt_virtual access_specifier opt_virtual idcolon {
+ $$ = NewHash();
+ Setfile($$,cparse_file);
+ Setline($$,cparse_line);
+ Setattr($$,"name",$4);
+ Setattr($$,"access",$2);
+ if (Strcmp($2,"public") != 0) {
+ 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"; }
+ ;
+
+
+templcpptype : CLASS {
+ $$ = (char*)"class";
+ if (!inherit_list) last_cpptype = $$;
+ }
+ | TYPENAME {
+ $$ = (char *)"typename";
+ if (!inherit_list) last_cpptype = $$;
+ }
+ ;
+
+cpptype : templcpptype {
+ $$ = $1;
+ }
+ | STRUCT {
+ $$ = (char*)"struct";
+ if (!inherit_list) last_cpptype = $$;
+ }
+ | UNION {
+ $$ = (char*)"union";
+ if (!inherit_list) last_cpptype = $$;
+ }
+ ;
+
+opt_virtual : VIRTUAL
+ | empty
+ ;
+
+cpp_const : type_qualifier {
+ $$.qualifier = $1;
+ $$.throws = 0;
+ $$.throwf = 0;
+ }
+ | THROW LPAREN parms RPAREN {
+ $$.qualifier = 0;
+ $$.throws = $3;
+ $$.throwf = NewString("1");
+ }
+ | type_qualifier THROW LPAREN parms RPAREN {
+ $$.qualifier = $1;
+ $$.throws = $4;
+ $$.throwf = NewString("1");
+ }
+ | empty {
+ $$.qualifier = 0;
+ $$.throws = 0;
+ $$.throwf = 0;
+ }
+ ;
+
+ctor_end : cpp_const ctor_initializer SEMI {
+ Clear(scanner_ccode);
+ $$.have_parms = 0;
+ $$.defarg = 0;
+ $$.throws = $1.throws;
+ $$.throwf = $1.throwf;
+ }
+ | cpp_const ctor_initializer LBRACE {
+ skip_balanced('{','}');
+ $$.have_parms = 0;
+ $$.defarg = 0;
+ $$.throws = $1.throws;
+ $$.throwf = $1.throwf;
+ }
+ | LPAREN parms RPAREN SEMI {
+ Clear(scanner_ccode);
+ $$.parms = $2;
+ $$.have_parms = 1;
+ $$.defarg = 0;
+ $$.throws = 0;
+ $$.throwf = 0;
+ }
+ | LPAREN parms RPAREN LBRACE {
+ skip_balanced('{','}');
+ $$.parms = $2;
+ $$.have_parms = 1;
+ $$.defarg = 0;
+ $$.throws = 0;
+ $$.throwf = 0;
+ }
+ | EQUAL definetype SEMI {
+ $$.have_parms = 0;
+ $$.defarg = $2.val;
+ $$.throws = 0;
+ $$.throwf = 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 = NewStringEmpty();
+ SwigType_add_template(s,$2);
+ $$ = Char(s);
+ scanner_last_id(1);
+ }
+ | 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);
+ }
+/* | DCOLON COPERATOR {
+ $$ = NewString($2);
+ } */
+
+ | DCNOT idtemplate {
+ $$ = NewStringf("::~%s",$2);
+ }
+ ;
+
+
+idtemplate : ID template_decl {
+ $$ = NewStringf("%s%s",$1,$2);
+ /* if (Len($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);
+ }
+ | idstring EQUAL stringtype {
+ $$ = $3;
+ Setattr($$,"name",$1);
+ }
+ | idstring EQUAL stringtype COMMA kwargs {
+ $$ = $3;
+ Setattr($$,"name",$1);
+ set_nextSibling($$,$5);
+ }
+ ;
+
+stringnum : string {
+ $$ = $1;
+ }
+ | exprnum {
+ $$ = Char($1.val);
+ }
+ ;
+
+empty : ;
+
+%%
+
+SwigType *Swig_cparse_type(String *s) {
+ String *ns;
+ 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;
+}
+
+
+Parm *Swig_cparse_parm(String *s) {
+ String *ns;
+ ns = NewStringf("%s;",s);
+ Seek(ns,0,SEEK_SET);
+ scanner_file(ns);
+ top = 0;
+ scanner_next_token(PARSEPARM);
+ yyparse();
+ /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
+ Delete(ns);
+ return top;
+}
+
+
+ParmList *Swig_cparse_parms(String *s) {
+ String *ns;
+ char *cs = Char(s);
+ if (cs && cs[0] != '(') {
+ ns = NewStringf("(%s);",s);
+ } else {
+ ns = NewStringf("%s;",s);
+ }
+ Seek(ns,0,SEEK_SET);
+ scanner_file(ns);
+ top = 0;
+ scanner_next_token(PARSEPARMS);
+ 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 0000000..3fa4111
--- /dev/null
+++ b/Source/CParse/templ.c
@@ -0,0 +1,675 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * templ.c
+ *
+ * Expands a template into a specialized version.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_templ_c[] = "$Id: templ.c 11097 2009-01-30 10:27:37Z bhy $";
+
+#include "swig.h"
+#include "cparse.h"
+
+static int template_debug = 0;
+
+
+const char *baselists[3];
+
+void SwigType_template_init() {
+ baselists[0] = "baselist";
+ baselists[1] = "protectedbaselist";
+ baselists[2] = "privatebaselist";
+}
+
+
+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(typelist, val);
+ Append(patchlist, val);
+ p = nextSibling(p);
+ }
+}
+
+void Swig_cparse_debug_templates(int x) {
+ template_debug = x;
+}
+
+/* -----------------------------------------------------------------------------
+ * 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;
+ String *nodeType;
+ if (!n)
+ return 0;
+ nodeType = nodeType(n);
+ if (Getattr(n, "error"))
+ return 0;
+
+ if (Equal(nodeType, "template")) {
+ /* 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 (Equal(nodeType, "cdecl")) {
+ /* 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 (Equal(nodeType, "class")) {
+ /* Patch base classes */
+ {
+ int b = 0;
+ for (b = 0; b < 3; ++b) {
+ List *bases = Getattr(n, baselists[b]);
+ if (bases) {
+ int i;
+ int ilen = Len(bases);
+ for (i = 0; i < ilen; 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 (Equal(nodeType, "constructor")) {
+ 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 (strchr(Char(name), '<')) {
+ Append(patchlist, Getattr(n, "name"));
+ } else {
+ Append(name, templateargs);
+ }
+ name = Getattr(n, "sym:name");
+ if (name) {
+ if (strchr(Char(name), '<')) {
+ Clear(name);
+ Append(name, rname);
+ } else {
+ String *tmp = Copy(name);
+ Replace(tmp, tname, rname, DOH_REPLACE_ANY);
+ Clear(name);
+ Append(name, tmp);
+ Delete(tmp);
+ }
+ }
+ /* 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 (Equal(nodeType, "destructor")) {
+ String *name = Getattr(n, "name");
+ if (name) {
+ if (strchr(Char(name), '<'))
+ Append(patchlist, Getattr(n, "name"));
+ else
+ Append(name, templateargs);
+ }
+ name = Getattr(n, "sym:name");
+ if (name) {
+ if (strchr(Char(name), '<')) {
+ String *sn = Copy(tname);
+ Setattr(n, "sym:name", sn);
+ Delete(sn);
+ } else {
+ Replace(name, tname, rname, DOH_REPLACE_ANY);
+ }
+ }
+ /* Setattr(n,"sym:name",name); */
+ Append(cpatchlist, Getattr(n, "code"));
+ } else if (Equal(nodeType, "using")) {
+ String *uname = Getattr(n, "uname");
+ if (uname && strchr(Char(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, "kwargs"), 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;
+}
+
+static
+String *partial_arg(String *s, String *p) {
+ char *c;
+ char *cp = Char(p);
+ String *prefix;
+ String *newarg;
+
+ /* Find the prefix on the partial argument */
+
+ c = strchr(cp, '$');
+ if (!c) {
+ return Copy(s);
+ }
+ prefix = NewStringWithSize(cp, c - cp);
+ newarg = Copy(s);
+ Replace(newarg, prefix, "", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
+ Delete(prefix);
+ return newarg;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cparse_template_expand()
+ * ----------------------------------------------------------------------------- */
+
+int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope) {
+ List *patchlist, *cpatchlist, *typelist;
+ String *templateargs;
+ String *tname;
+ String *iname;
+ String *tbase;
+ patchlist = NewList();
+ cpatchlist = NewList();
+ typelist = NewList();
+
+ {
+ String *tmp = NewStringEmpty();
+ if (tparms) {
+ SwigType_add_template(tmp, tparms);
+ }
+ templateargs = Copy(tmp);
+ Delete(tmp);
+ }
+
+ tname = Copy(Getattr(n, "name"));
+ tbase = Swig_scopename_last(tname);
+
+ /* Look for partial specialization matching */
+ if (Getattr(n, "partialargs")) {
+ Parm *p, *tp;
+ ParmList *ptargs = SwigType_function_parms(Getattr(n, "partialargs"));
+ p = ptargs;
+ tp = tparms;
+ while (p && tp) {
+ SwigType *ptype;
+ SwigType *tptype;
+ SwigType *partial_type;
+ ptype = Getattr(p, "type");
+ tptype = Getattr(tp, "type");
+ if (ptype && tptype) {
+ partial_type = partial_arg(tptype, ptype);
+ /* Printf(stdout,"partial '%s' '%s' ---> '%s'\n", tptype, ptype, partial_type); */
+ Setattr(tp, "type", partial_type);
+ Delete(partial_type);
+ }
+ p = nextSibling(p);
+ tp = nextSibling(tp);
+ }
+ assert(ParmList_len(ptargs) == ParmList_len(tparms));
+ Delete(ptargs);
+ }
+
+ /*
+ Parm *p = tparms;
+ while (p) {
+ Printf(stdout, "tparm: '%s' '%s' '%s'\n", Getattr(p, "name"), Getattr(p, "type"), Getattr(p, "value"));
+ p = nextSibling(p);
+ }
+ */
+
+ /* Printf(stdout,"targs = '%s'\n", templateargs);
+ Printf(stdout,"rname = '%s'\n", rname);
+ Printf(stdout,"tname = '%s'\n", tname); */
+ 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;
+ /* Printf(stdout,"%s\n", ParmList_str_defaultargs(tp)); */
+
+ if (tp) {
+ Symtab *tsdecl = Getattr(n, "sym:symtab");
+ while (p && tp) {
+ String *name, *value, *valuestr, *tydef, *tmp, *tmpr;
+ int sz, i;
+ String *dvalue = 0;
+ String *qvalue = 0;
+
+ name = Getattr(tp, "name");
+ value = Getattr(p, "value");
+ tydef = Getattr(p, "typedef");
+
+ if (name) {
+ if (!value)
+ value = Getattr(p, "type");
+ qvalue = Swig_symbol_typedef_reduce(value, tsdecl);
+ dvalue = Swig_symbol_type_qualify(qvalue, tsdecl);
+ if (SwigType_istemplate(dvalue)) {
+ String *ty = Swig_symbol_template_deftype(dvalue, tscope);
+ Delete(dvalue);
+ dvalue = ty;
+ }
+
+ assert(dvalue);
+ valuestr = SwigType_str(dvalue, 0);
+ /* Need to patch default arguments */
+ {
+ Parm *rp = nextSibling(p);
+ while (rp) {
+ String *rvalue = Getattr(rp, "value");
+ if (rvalue) {
+ Replace(rvalue, name, dvalue, DOH_REPLACE_ID);
+ }
+ rp = nextSibling(rp);
+ }
+ }
+ sz = Len(patchlist);
+ for (i = 0; i < sz; i++) {
+ String *s = Getitem(patchlist, i);
+ Replace(s, name, dvalue, DOH_REPLACE_ID);
+ }
+ sz = Len(typelist);
+ for (i = 0; i < sz; i++) {
+ String *s = Getitem(typelist, i);
+ /* Replace(s,name,value, DOH_REPLACE_ID); */
+ /* Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, dvalue, tbase, iname, s); */
+ SwigType_typename_replace(s, name, dvalue);
+ SwigType_typename_replace(s, tbase, iname);
+ /* Printf(stdout,"'%s'\n", s); */
+ }
+
+ if (!tydef) {
+ tydef = dvalue;
+ }
+ tmp = NewStringf("#%s", name);
+ tmpr = NewStringf("\"%s\"", valuestr);
+
+ 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);
+ Delete(dvalue);
+ Delete(qvalue);
+ }
+ 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) {
+ Iterator b;
+ for (b = First(bases); b.item; b = Next(b)) {
+ String *qn = Swig_symbol_type_qualify(b.item, tscope);
+ Clear(b.item);
+ Append(b.item, qn);
+ Delete(qn);
+ }
+ }
+ }
+ Delete(patchlist);
+ Delete(cpatchlist);
+ Delete(typelist);
+ Delete(tbase);
+ Delete(tname);
+ Delete(templateargs);
+
+ /* set_nodeType(n,"template"); */
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * template_locate()
+ *
+ * Search for a template that matches name with given parameters.
+ * ----------------------------------------------------------------------------- */
+
+static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) {
+ Node *n;
+ String *tname, *rname = 0;
+ Node *templ;
+ List *mpartials = 0;
+ Parm *p;
+ Parm *parms;
+ Parm *targs;
+ ParmList *expandedparms;
+
+ tname = Copy(name);
+ parms = CopyParmList(tparms);
+
+ /* Search for generic template */
+ templ = Swig_symbol_clookup(name, 0);
+
+ /* Add default values from generic template */
+ if (templ) {
+ Symtab *tsdecl = Getattr(templ, "sym:symtab");
+
+ targs = Getattr(templ, "templateparms");
+ expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, tsdecl);
+ } else {
+ expandedparms = parms;
+ }
+
+
+ /* reduce the typedef */
+ p = expandedparms;
+ while (p) {
+ SwigType *ty = Getattr(p, "type");
+ if (ty) {
+ SwigType *nt = Swig_symbol_type_qualify(ty, tscope);
+ Setattr(p, "type", nt);
+ Delete(nt);
+ }
+ p = nextSibling(p);
+ }
+
+ SwigType_add_template(tname, expandedparms);
+
+ 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) {
+ SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope);
+ if (!Equal(rname, tname)) {
+ if (template_debug) {
+ Printf(stdout, " searching: '%s' (exact specialization)\n", rname);
+ }
+ n = Swig_symbol_clookup_local(rname, 0);
+ }
+ Delete(rname);
+ }
+ if (n) {
+ Node *tn;
+ String *nodeType = nodeType(n);
+ if (Equal(nodeType, "template"))
+ 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 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)
+ t = Getattr(p, "value");
+ if (t) {
+ String *ty = Swig_symbol_typedef_reduce(t, tscope);
+ String *tb = SwigType_base(ty);
+ String *td = SwigType_default(ty);
+ Replaceid(td, "enum SWIGTYPE", tb);
+ Replaceid(td, "SWIGTYPE", tb);
+ Append(rname, td);
+ Delete(tb);
+ Delete(ty);
+ Delete(td);
+ }
+ p = nextSibling(p);
+ if (p) {
+ Append(rname, ",");
+ }
+ }
+ Append(rname, ")>");
+
+ mpartials = NewList();
+ if (templ) {
+ /* First, we search using an exact type prototype */
+ Parm *p;
+ char tmp[32];
+ int i;
+ List *partials;
+ String *ss;
+ Iterator pi;
+
+ partials = Getattr(templ, "partials");
+ if (partials) {
+ for (pi = First(partials); pi.item; pi = Next(pi)) {
+ ss = Copy(pi.item);
+ p = parms;
+ i = 1;
+ while (p) {
+ String *t, *tn;
+ sprintf(tmp, "$%d", i);
+ t = Getattr(p, "type");
+ if (!t)
+ t = Getattr(p, "value");
+ if (t) {
+ String *ty = Swig_symbol_typedef_reduce(t, tscope);
+ tn = SwigType_base(ty);
+ Replaceid(ss, tmp, tn);
+ Delete(tn);
+ Delete(ty);
+ }
+ i++;
+ p = nextSibling(p);
+ }
+ if (template_debug) {
+ Printf(stdout, " searching: '%s' (partial specialization - %s)\n", ss, pi.item);
+ }
+ if ((Equal(ss, tname)) || (Equal(ss, rname))) {
+ Append(mpartials, pi.item);
+ }
+ 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,\n", SwigType_namestr(tname));
+ Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), " instantiation '%s' is used.\n", SwigType_namestr(Getattr(n, "name")));
+ }
+ }
+ }
+
+ if (!n) {
+ n = templ;
+ }
+ if (!n) {
+ Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name);
+ } else if (n) {
+ String *nodeType = nodeType(n);
+ if (!Equal(nodeType, "template")) {
+ Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType);
+ n = 0;
+ }
+ }
+success:
+ Delete(tname);
+ Delete(rname);
+ Delete(mpartials);
+ if ((template_debug) && (n)) {
+ Printf(stdout, "Node: %p\n", n);
+ Swig_print_node(n);
+ }
+ Delete(parms);
+ return n;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_cparse_template_locate()
+ *
+ * Search for a template that matches name with given parameters.
+ * For templated classes finds the specialized template should there be one.
+ * For templated functions finds the unspecialized template even if a specialized
+ * template exists.
+ * ----------------------------------------------------------------------------- */
+
+Node *Swig_cparse_template_locate(String *name, Parm *tparms, Symtab *tscope) {
+ Node *n = template_locate(name, tparms, tscope); /* this function does what we want for templated classes */
+
+ if (n) {
+ String *nodeType = nodeType(n);
+ int isclass = 0;
+ assert(Equal(nodeType, "template"));
+ isclass = (Equal(Getattr(n, "templatetype"), "class"));
+ if (!isclass) {
+ /* If not a templated class we must have a templated function.
+ The template found is not necessarily the one we want when dealing with templated
+ functions. We don't want any specialized templated functions as they won't have
+ the default parameters. Lets look for the unspecialized template. Also make sure
+ the number of template parameters is correct as it is possible to overload a
+ templated function with different numbers of template parameters. */
+
+ if (template_debug) {
+ Printf(stdout, " Not a templated class, seeking most appropriate templated function\n");
+ }
+
+ n = Swig_symbol_clookup_local(name, 0);
+ while (n) {
+ Parm *tparmsfound = Getattr(n, "templateparms");
+ if (ParmList_len(tparms) == ParmList_len(tparmsfound)) {
+ /* successful match */
+ break;
+ }
+ /* repeat until we find a match with correct number of templated parameters */
+ n = Getattr(n, "sym:nextSibling");
+ }
+
+ if (!n) {
+ Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name);
+ }
+
+ if ((template_debug) && (n)) {
+ Printf(stdout, "Templated function found: %p\n", n);
+ Swig_print_node(n);
+ }
+ }
+ }
+
+ return n;
+}
diff --git a/Source/CParse/util.c b/Source/CParse/util.c
new file mode 100644
index 0000000..de374c8
--- /dev/null
+++ b/Source/CParse/util.c
@@ -0,0 +1,88 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * util.c
+ *
+ * Parsing utilities.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_util_c[] = "$Id: util.c 9632 2007-01-03 20:58:19Z beazley $";
+
+#include "swig.h"
+#include "cparse.h"
+
+/* -----------------------------------------------------------------------------
+ * 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;
+ char *c = 0;
+
+ while ((c = strstr(Char(s), "$descriptor("))) {
+ char *d = tmp;
+ int level = 0;
+ 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);
+ Delete(t);
+ } else {
+ Swig_error(Getfile(s), Getline(s), "Bad $descriptor() macro.\n");
+ break;
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * cparse_normalize_void()
+ *
+ * This function is used to replace arguments of the form (void) with empty
+ * arguments in C++
+ * ----------------------------------------------------------------------------- */
+
+void cparse_normalize_void(Node *n) {
+ String *decl = Getattr(n, "decl");
+ Parm *parms = Getattr(n, "parms");
+
+ if (SwigType_isfunction(decl)) {
+ if ((ParmList_len(parms) == 1) && (SwigType_type(Getattr(parms, "type")) == T_VOID)) {
+ Replaceall(decl, "f(void).", "f().");
+ Delattr(n, "parms");
+ }
+ }
+}
diff --git a/Source/DOH/README b/Source/DOH/README
new file mode 100644
index 0000000..9a42e8b
--- /dev/null
+++ b/Source/DOH/README
@@ -0,0 +1,118 @@
+DOH (Dave's Object Hack)
+
+Overview:
+---------
+DOH is a small C library that provides a number of simple yet powerful
+data structures. The data structures are built around a dynamic typing
+model in which any given object is allowed to support one or more
+classes of operations. Furthermore, a simple garbage collection
+scheme and a variety of interesting library methods are available.
+All and all, the operation of DOH makes massive abuse of the C type
+system and would probably make the language purists scream and
+performance addicts run away in horror. However, I really don't
+care--so there! However, for the rest of us, DOH is actually kind of
+fun to use. This is only a short description of the methods and is no
+way meant to be exhaustive.
+
+Common Operations (for all types)
+---------------------------------
+Delete(obj) Decrease the reference count and destroy if zero
+Copy(obj) Make a copy of an object.
+Clear(obj) Clear an object.
+Setscope(obj) Set scope of an object (guru's only)
+Str(obj) Create a string representation of obj.
+Data(obj) Return pointer to raw data in an object
+Char(obj) Convert to a char *
+Len(obj) Length of an object
+Hash(obj) Hash value (used for mapping)
+Cmp(obj1,obj2) Compare two objects.
+Name(obj) Return the object name
+First(obj) Return first object (iterator)
+Next(obj) Return next object
+Dump(obj,out) Serialize on out
+Load(in) Unserialize from in
+First(obj) Iterator
+Next(iter) Next iterator
+
+Mapping Operations (for hash table behavior)
+--------------------------------------------
+Getattr(hash,key) Get an attribute
+Setattr(hash,key,value) Set an attribute
+Delattr(hash,key) Delete an attribute
+First(hash) Get first object (iterator)
+Next(hash) Get next object
+GetInt(hash,key) Get attribute as an 'int'
+SetInt(hash,key,ivalue) Set attribute as an 'int'
+GetDouble(hash,key) Get attribute as a 'double'
+SetDouble(hash,key,dvalue) Set Attribute as a 'double'
+GetChar(hash,key) Get attribute as a 'char *'
+
+Sequence Operations
+-------------------
+Getitem(list,index) Get an item
+Setitem(list,index,val) Set an item
+Delitem(list,index,val) Delete an item
+Insert(list,index,val) Insert an item
+Append(list,val) Append to end
+Push(list,val) Insert at beginning
+
+File Operations
+---------------
+Read(obj,buffer,len) Read data
+Write(obj,buffer,len) Write data
+Getc(obj) Get a character
+Putc(ch,obj) Put a character
+Ungetc(ch,obj) Put character back on input stream
+Seek(obj,offset,whence) Seek
+Tell(obj) Return file pointer
+Close(obj) Close
+
+String Operations
+-----------------
+Replace(obj, orig, rep, flags) Replace occurences of orig with rep.
+Chop(obj) Remove trailing whitespace
+
+flags is one of the following:
+ DOH_REPLACE_ANY
+ DOH_REPLACE_NOQUOTE
+ DOH_REPLACE_ID
+ DOH_REPLACE_FIRST
+
+Callable Operations
+-------------------
+Call(obj, args) Perform a function call with arguments args.
+
+Miscellaneous library functions
+-------------------------------
+NewScope() Create a new scope
+DelScope(s) Delete scope s
+Readline(in) Read a line of input from in
+Printf(out,fmt,...) Formatted output
+DohEncoding(name, fn) Register a format encoding for Printf
+
+Currently Available datatypes
+------------------------------
+NewString(char *initial) Strings
+NewHash() Hash
+NewList() List
+NewVoid(void *ptr, void (*del)(void *)) Void
+NewFile(char *filename, char *mode, List *newfiles) File
+NewCallable(DOH *(*func)(DOH *, DOH *)) Callable object
+
+
+Odds and ends:
+
+ 1. All objects are of type 'DOH *'
+ 2. When in doubt, see rule (1)
+ 3. In certain cases, DOH performs implicit conversions
+ of 'char *' to an appropriate DOH string representation.
+ For operations involving files, DOH works with many
+ kinds of objects including FILE *, DOH File objects,
+ and DOH strings. Don't even ask how this works.
+
+ 4. More complete documentation is forthcoming.
+
+
+
+
+
diff --git a/Source/DOH/base.c b/Source/DOH/base.c
new file mode 100644
index 0000000..4262e70
--- /dev/null
+++ b/Source/DOH/base.c
@@ -0,0 +1,943 @@
+/* -----------------------------------------------------------------------------
+ * base.c
+ *
+ * This file contains the function entry points for dispatching methods on
+ * DOH objects. A number of small utility functions are also included.
+ *
+ * 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_base_c[] = "$Id: base.c 11097 2009-01-30 10:27:37Z bhy $";
+
+#include "dohint.h"
+
+/* -----------------------------------------------------------------------------
+ * DohDelete()
+ * ----------------------------------------------------------------------------- */
+
+#ifndef SWIG_DEBUG_DELETE
+#define SWIG_DEBUG_DELETE 0
+#endif
+
+void DohDelete(DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+
+ if (!obj)
+ return;
+#if SWIG_DEBUG_DELETE
+ if (!DohCheck(b)) {
+ fputs("DOH: Fatal error. Attempt to delete a non-doh object.\n", stderr);
+ abort();
+ }
+#endif
+ if (b->flag_intern)
+ return;
+ assert(b->refcount > 0);
+ b->refcount--;
+ if (b->refcount <= 0) {
+ objinfo = b->type;
+ if (objinfo->doh_del) {
+ (objinfo->doh_del) (b);
+ } else {
+ if (b->data)
+ DohFree(b->data);
+ }
+ DohObjFree(b);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * DohCopy()
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohCopy(const DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+
+ if (!obj)
+ return 0;
+ 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;
+}
+
+void DohIncref(DOH *obj) {
+ Incref(obj);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohClear()
+ * ----------------------------------------------------------------------------- */
+
+void DohClear(DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo->doh_clear)
+ (objinfo->doh_clear) (b);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohStr()
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohStr(const DOH *obj) {
+ char buffer[512];
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (DohCheck(b)) {
+ objinfo = b->type;
+ if (objinfo->doh_str) {
+ return (objinfo->doh_str) (b);
+ }
+ sprintf(buffer, "<Object '%s' at %p>", objinfo->objname, (void *) b);
+ return NewString(buffer);
+ } else {
+ return NewString(obj);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * DohDump()
+ * ----------------------------------------------------------------------------- */
+
+int DohDump(const DOH *obj, DOH *out) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo->doh_dump) {
+ return (objinfo->doh_dump) (b, out);
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohLen() - Defaults to strlen() if not a DOH object
+ * ----------------------------------------------------------------------------- */
+int DohLen(const DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (!b)
+ return 0;
+ if (DohCheck(b)) {
+ objinfo = b->type;
+ if (objinfo->doh_len) {
+ return (objinfo->doh_len) (b);
+ }
+ return 0;
+ } else {
+ return strlen((char *) obj);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * DohHashVal()
+ * ----------------------------------------------------------------------------- */
+
+int DohHashval(const DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ /* obj is already checked and/or converted into DohBase* */
+ /* if (DohCheck(b)) */
+ {
+ objinfo = b->type;
+ if (objinfo->doh_hashval) {
+ return (objinfo->doh_hashval) (b);
+ }
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohData()
+ * ----------------------------------------------------------------------------- */
+
+void *DohData(const DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (DohCheck(obj)) {
+ objinfo = b->type;
+ if (objinfo->doh_data) {
+ return (objinfo->doh_data) (b);
+ }
+ return 0;
+ }
+ return (void *) obj;
+}
+
+/* -----------------------------------------------------------------------------
+ * RawData()
+ * ----------------------------------------------------------------------------- */
+
+static void *RawData(DohBase *b) {
+ DohObjInfo *objinfo = b->type;
+ return (objinfo->doh_data) ? (objinfo->doh_data) (b) : 0;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * DohCmp()
+ * ----------------------------------------------------------------------------- */
+
+int DohCmp(const DOH *obj1, const DOH *obj2) {
+ DohBase *b1, *b2;
+ DohObjInfo *b1info, *b2info;
+ int c1, c2;
+ b1 = (DohBase *) obj1;
+ b2 = (DohBase *) obj2;
+ c1 = DohCheck(b1);
+ c2 = DohCheck(b2);
+ /* most of the times, obj2 is a plain c string */
+ if (!c1 || !c2) {
+ if ((b1 == 0) && (b2 == 0))
+ return 0;
+ if (b1 && !b2)
+ return 1;
+ if (!b1 && b2)
+ return -1;
+ return strcmp((char *) (c1 ? RawData(b1) : (void *) obj1), (char *) (c2 ? RawData(b2) : (void *) obj2));
+ }
+ b1info = b1->type;
+ b2info = b2->type;
+ if ((b1info == b2info) && (b1info->doh_cmp))
+ return (b1info->doh_cmp) (b1, b2);
+ return 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohEqual()
+ * ----------------------------------------------------------------------------- */
+
+int DohEqual(const DOH *obj1, const DOH *obj2) {
+ DohBase *b1 = (DohBase *) obj1;
+ DohBase *b2 = (DohBase *) obj2;
+ if (!b1) {
+ return !b2;
+ } else if (!b2) {
+ return 0;
+ } else {
+ DohObjInfo *b1info = 0;
+ DohObjInfo *b2info = 0;
+ if (DohCheck(b1)) {
+ b1info = b1->type;
+ if (DohCheck(b2)) {
+ b2info = b2->type;
+ } else {
+ int len = (b1info->doh_len) (b1);
+ char *cobj = (char *) obj2;
+ return len == (int) strlen(cobj) ? (memcmp(RawData(b1), cobj, len) == 0) : 0;
+ }
+ } else if (DohCheck(b2)) {
+ int len = (b2->type->doh_len) (b2);
+ char *cobj = (char *) obj1;
+ return len == (int) strlen(cobj) ? (memcmp(RawData(b2), cobj, len) == 0) : 0;
+ } else {
+ return strcmp((char *) obj1, (char *) obj2) == 0;
+ }
+
+ if (!b1info) {
+ return obj1 == obj2;
+ } else if ((b1info == b2info)) {
+ return b1info->doh_equal ? (b1info->doh_equal) (b1, b2) : (b1info->doh_cmp ? (b1info->doh_cmp) (b1, b2) == 0 : (b1 == b2));
+ } else {
+ return 0;
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * DohFirst()
+ * ----------------------------------------------------------------------------- */
+
+DohIterator DohFirst(DOH *obj) {
+ DohIterator iter;
+ DohBase *b;
+ DohObjInfo *binfo;
+
+ b = (DohBase *) obj;
+ if (DohCheck(b)) {
+ binfo = b->type;
+ if (binfo->doh_first) {
+ return (binfo->doh_first) (b);
+ }
+ }
+ iter.object = 0;
+ iter.item = 0;
+ iter.key = 0;
+ iter._current = 0;
+ iter._index = 0;
+ return iter;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohNext()
+ * ----------------------------------------------------------------------------- */
+
+DohIterator DohNext(DohIterator iter) {
+ DohIterator niter;
+
+ if (iter.object) {
+ DohBase *b;
+ DohObjInfo *binfo;
+
+ b = (DohBase *) iter.object;
+ binfo = b->type;
+ if (binfo->doh_next) {
+ return (binfo->doh_next) (iter);
+ }
+ }
+ niter = iter;
+ return niter;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohIsMapping()
+ * ----------------------------------------------------------------------------- */
+int DohIsMapping(const DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (!DohCheck(b))
+ return 0;
+ objinfo = b->type;
+ if (objinfo->doh_hash)
+ return 1;
+ else
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohGetattr()
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohGetattr(DOH *obj, const DOH *name) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo->doh_hash && objinfo->doh_hash->doh_getattr) {
+ DOH *r = (objinfo->doh_hash->doh_getattr) (b, (DOH *) name);
+ return (r == DohNone) ? 0 : r;
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSetattr()
+ * ----------------------------------------------------------------------------- */
+
+int DohSetattr(DOH *obj, const DOH *name, const DOH *value) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo->doh_hash && objinfo->doh_hash->doh_setattr) {
+ return (objinfo->doh_hash->doh_setattr) (b, (DOH *) name, (DOH *) value);
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohDelattr()
+ * ----------------------------------------------------------------------------- */
+
+int DohDelattr(DOH *obj, const DOH *name) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo->doh_hash && objinfo->doh_hash->doh_delattr) {
+ return (objinfo->doh_hash->doh_delattr) (b, (DOH *) name);
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohCheckattr()
+ * ----------------------------------------------------------------------------- */
+
+int DohCheckattr(DOH *obj, const DOH *name, const DOH *value) {
+ DOH *attr = Getattr(obj,name);
+ if (!attr) return 0;
+ return DohEqual(attr,value);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohKeys()
+ * ----------------------------------------------------------------------------- */
+
+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()
+ * ----------------------------------------------------------------------------- */
+
+int DohGetInt(DOH *obj, const DOH *name) {
+ DOH *val;
+ val = Getattr(obj, (DOH *) name);
+ if (!val)
+ return 0;
+ if (DohIsString(val)) {
+ return atoi((char *) Data(val));
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohGetDouble()
+ * ----------------------------------------------------------------------------- */
+
+double DohGetDouble(DOH *obj, const DOH *name) {
+ DOH *val;
+ val = Getattr(obj, (DOH *) name);
+ if (!val)
+ return 0;
+ if (DohIsString(val)) {
+ return atof((char *) Data(val));
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohGetChar()
+ * ----------------------------------------------------------------------------- */
+
+char *DohGetChar(DOH *obj, const DOH *name) {
+ DOH *val;
+ val = Getattr(obj, (DOH *) name);
+ if (!val)
+ return 0;
+ if (DohIsString(val)) {
+ return (char *) Data(val);
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohGetFlagAttr() / DohGetFlag()
+ * A flag is unset if the attribute (name) does not exist on the node (obj),
+ * or it is set to "0". If the attribute is set to any other value,
+ * the flag is set.
+ *
+ * DohGetFlag() returns if the flag is set or not
+ * DohGetFlagAttr() returns the flag value if is set, NULL otherwise
+ * ----------------------------------------------------------------------------- */
+
+
+DOH *DohGetFlagAttr(DOH *obj, const DOH *name) {
+ DOH *val = Getattr(obj, (DOH *) name);
+ if (!val) {
+ return NULL;
+ } else {
+ const char *cval = Char(val);
+ if (!cval)
+ return val;
+ return (strcmp(cval, "0") != 0) ? val : NULL;
+ }
+}
+
+int DohGetFlag(DOH *obj, const DOH *name) {
+ return DohGetFlagAttr(obj, name) ? 1 : 0;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * DohGetVoid()
+ * ----------------------------------------------------------------------------- */
+
+void *DohGetVoid(DOH *obj, const DOH *name) {
+ DOH *val;
+ val = Getattr(obj, (DOH *) name);
+ if (!val)
+ return 0;
+ return (void *) Data(val);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSetInt()
+ * ----------------------------------------------------------------------------- */
+
+void DohSetInt(DOH *obj, const DOH *name, int value) {
+ DOH *temp;
+ temp = NewStringEmpty();
+ Printf(temp, "%d", value);
+ Setattr(obj, (DOH *) name, temp);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSetDouble()
+ * ----------------------------------------------------------------------------- */
+
+void DohSetDouble(DOH *obj, const DOH *name, double value) {
+ DOH *temp;
+ temp = NewStringEmpty();
+ Printf(temp, "%0.17f", value);
+ Setattr(obj, (DOH *) name, temp);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSetChar()
+ * ----------------------------------------------------------------------------- */
+
+void DohSetChar(DOH *obj, const DOH *name, char *value) {
+ Setattr(obj, (DOH *) name, NewString(value));
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSetFlag()
+ * ----------------------------------------------------------------------------- */
+
+void DohSetFlagAttr(DOH *obj, const DOH *name, const DOH *attr) {
+ Setattr(obj, (DOH *) name, attr ? attr : NewString("0"));
+}
+
+void DohSetFlag(DOH *obj, const DOH *name) {
+ Setattr(obj, (DOH *) name, NewString("1"));
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSetVoid()
+ * ----------------------------------------------------------------------------- */
+
+void DohSetVoid(DOH *obj, const DOH *name, void *value) {
+ Setattr(obj, (DOH *) name, NewVoid(value, 0));
+}
+
+/* -----------------------------------------------------------------------------
+ * DohIsSequence()
+ * ----------------------------------------------------------------------------- */
+
+int DohIsSequence(const DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (!DohCheck(b))
+ return 0;
+ objinfo = b->type;
+ if (objinfo->doh_list)
+ return 1;
+ else
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohGetitem()
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohGetitem(DOH *obj, int index) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo->doh_list && objinfo->doh_list->doh_getitem) {
+ return (objinfo->doh_list->doh_getitem) (b, index);
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSetitem()
+ * ----------------------------------------------------------------------------- */
+
+int DohSetitem(DOH *obj, int index, const DOH *value) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo->doh_list && objinfo->doh_list->doh_setitem) {
+ return (objinfo->doh_list->doh_setitem) (b, index, (DOH *) value);
+ }
+ return -1;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohDelitem()
+ * ----------------------------------------------------------------------------- */
+
+int DohDelitem(DOH *obj, int index) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo->doh_list && objinfo->doh_list->doh_delitem) {
+ return (objinfo->doh_list->doh_delitem) (b, index);
+ }
+ return -1;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohInsertitem()
+ * ----------------------------------------------------------------------------- */
+
+int DohInsertitem(DOH *obj, int index, const DOH *value) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo->doh_list && objinfo->doh_list->doh_insitem) {
+ return (objinfo->doh_list->doh_insitem) (b, index, (DOH *) value);
+ }
+ return -1;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * DohDelslice()
+ * ----------------------------------------------------------------------------- */
+
+int DohDelslice(DOH *obj, int sindex, int eindex) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo = b->type;
+ if (objinfo->doh_list && objinfo->doh_list->doh_delslice) {
+ return (objinfo->doh_list->doh_delslice) (b, sindex, eindex);
+ }
+ return -1;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohIsFile()
+ * ----------------------------------------------------------------------------- */
+
+int DohIsFile(const DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (!DohCheck(b))
+ return 0;
+ objinfo = b->type;
+ if (objinfo->doh_file)
+ return 1;
+ else
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohRead()
+ * ----------------------------------------------------------------------------- */
+
+int DohRead(DOH *obj, void *buffer, int length) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (DohCheck(obj)) {
+ objinfo = b->type;
+ if ((objinfo->doh_file) && (objinfo->doh_file->doh_read)) {
+ return (objinfo->doh_file->doh_read) (b, buffer, length);
+ }
+ return -1;
+ }
+ /* Hmmm. Not a file. Maybe it's a real FILE */
+ return fread(buffer, 1, length, (FILE *) b);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohWrite()
+ * ----------------------------------------------------------------------------- */
+
+int DohWrite(DOH *obj, void *buffer, int length) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (DohCheck(obj)) {
+ objinfo = b->type;
+ if ((objinfo->doh_file) && (objinfo->doh_file->doh_write)) {
+ return (objinfo->doh_file->doh_write) (b, buffer, length);
+ }
+ return -1;
+ }
+ /* Hmmm. Not a file. Maybe it's a real FILE */
+ return fwrite(buffer, 1, length, (FILE *) b);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSeek()
+ * ----------------------------------------------------------------------------- */
+
+int DohSeek(DOH *obj, long offset, int whence) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (DohCheck(obj)) {
+ objinfo = b->type;
+ if ((objinfo->doh_file) && (objinfo->doh_file->doh_seek)) {
+ return (objinfo->doh_file->doh_seek) (b, offset, whence);
+ }
+ return -1;
+ }
+ return fseek((FILE *) b, offset, whence);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohTell()
+ * ----------------------------------------------------------------------------- */
+
+long DohTell(DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (DohCheck(obj)) {
+ objinfo = b->type;
+ if ((objinfo->doh_file) && (objinfo->doh_file->doh_tell)) {
+ return (objinfo->doh_file->doh_tell) (b);
+ }
+ return -1;
+ }
+ return ftell((FILE *) b);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohGetc()
+ * ----------------------------------------------------------------------------- */
+
+int DohGetc(DOH *obj) {
+ static DOH *lastdoh = 0;
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (obj == lastdoh) {
+ objinfo = b->type;
+ return (objinfo->doh_file->doh_getc) (b);
+ }
+ if (DohCheck(obj)) {
+ objinfo = b->type;
+ if (objinfo->doh_file->doh_getc) {
+ lastdoh = obj;
+ return (objinfo->doh_file->doh_getc) (b);
+ }
+ return EOF;
+ }
+ return fgetc((FILE *) b);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohPutc()
+ * ----------------------------------------------------------------------------- */
+
+int DohPutc(int ch, DOH *obj) {
+ static DOH *lastdoh = 0;
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+
+ if (obj == lastdoh) {
+ objinfo = b->type;
+ return (objinfo->doh_file->doh_putc) (b, ch);
+ }
+ if (DohCheck(obj)) {
+ objinfo = b->type;
+ if (objinfo->doh_file->doh_putc) {
+ lastdoh = obj;
+ return (objinfo->doh_file->doh_putc) (b, ch);
+ }
+ return EOF;
+ }
+ return fputc(ch, (FILE *) b);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohUngetc()
+ * ----------------------------------------------------------------------------- */
+
+int DohUngetc(int ch, DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (DohCheck(obj)) {
+ objinfo = b->type;
+ if (objinfo->doh_file->doh_ungetc) {
+ return (objinfo->doh_file->doh_ungetc) (b, ch);
+ }
+ return EOF;
+ }
+ return ungetc(ch, (FILE *) b);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohClose()
+ * ----------------------------------------------------------------------------- */
+
+int DohClose(DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (DohCheck(obj)) {
+ objinfo = b->type;
+ if (objinfo->doh_file->doh_close) {
+ return (objinfo->doh_file->doh_close) (b);
+ }
+ return 0;
+ }
+ return fclose((FILE *) obj);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohIsString()
+ * ----------------------------------------------------------------------------- */
+
+int DohIsString(const DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ DohObjInfo *objinfo;
+ if (!DohCheck(b))
+ return 0;
+ objinfo = b->type;
+ if (objinfo->doh_string)
+ return 1;
+ else
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohReplace()
+ * ----------------------------------------------------------------------------- */
+
+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 = b->type;
+ if (objinfo->doh_string->doh_replace) {
+ return (objinfo->doh_string->doh_replace) (b, (DOH *) token, (DOH *) rep, flags);
+ }
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohChop()
+ * ----------------------------------------------------------------------------- */
+
+void DohChop(DOH *src) {
+ DohBase *b = (DohBase *) src;
+ DohObjInfo *objinfo;
+ if (DohIsString(src)) {
+ objinfo = b->type;
+ if (objinfo->doh_string->doh_chop) {
+ (objinfo->doh_string->doh_chop) (b);
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSetFile()
+ * ----------------------------------------------------------------------------- */
+void DohSetfile(DOH *ho, DOH *file) {
+ DohBase *h = (DohBase *) ho;
+ DohObjInfo *objinfo;
+ if (!h)
+ return;
+ objinfo = h->type;
+ if (objinfo->doh_setfile)
+ (objinfo->doh_setfile) (h, file);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohGetFile()
+ * ----------------------------------------------------------------------------- */
+DOH *DohGetfile(const DOH *ho) {
+ DohBase *h = (DohBase *) ho;
+ DohObjInfo *objinfo;
+ if (!h)
+ return 0;
+ objinfo = h->type;
+ if (objinfo->doh_getfile)
+ return (objinfo->doh_getfile) (h);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSetLine()
+ * ----------------------------------------------------------------------------- */
+void DohSetline(DOH *ho, int l) {
+ DohBase *h = (DohBase *) ho;
+ DohObjInfo *objinfo;
+ if (!h)
+ return;
+ objinfo = h->type;
+ if (objinfo->doh_setline)
+ (objinfo->doh_setline) (h, l);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohGetLine()
+ * ----------------------------------------------------------------------------- */
+int DohGetline(const DOH *ho) {
+ DohBase *h = (DohBase *) ho;
+ DohObjInfo *objinfo;
+ if (!h)
+ return 0;
+ 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;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohCall()
+ *
+ * Invokes a function via DOH. A Function is represented by a hash table with
+ * the following attributes:
+ *
+ * "builtin" - Pointer to built-in function (if any)
+ *
+ * (Additional attributes may be added later)
+ *
+ * Returns a DOH object with result on success. Returns NULL on error
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohCall(DOH *func, DOH *args) {
+ DOH *result;
+ DOH *(*builtin) (DOH *);
+
+ builtin = (DOH *(*)(DOH *)) GetVoid(func, "builtin");
+ if (!builtin)
+ return 0;
+ result = (*builtin) (args);
+ return result;
+}
diff --git a/Source/DOH/doh.h b/Source/DOH/doh.h
new file mode 100644
index 0000000..b731e95
--- /dev/null
+++ b/Source/DOH/doh.h
@@ -0,0 +1,442 @@
+/* -----------------------------------------------------------------------------
+ * doh.h
+ *
+ * This file describes of the externally visible functions in DOH.
+ *
+ * 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.
+ *
+ * $Id: doh.h 11097 2009-01-30 10:27:37Z bhy $
+ * ----------------------------------------------------------------------------- */
+
+#ifndef _DOH_H
+#define _DOH_H
+
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+
+#include <stdio.h>
+#include <stdarg.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 DohEqual DOH_NAMESPACE(Equal)
+#define DohIncref DOH_NAMESPACE(Incref)
+#define DohCheckattr DOH_NAMESPACE(Checkattr)
+#define DohSetattr DOH_NAMESPACE(Setattr)
+#define DohDelattr DOH_NAMESPACE(Delattr)
+#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 DohDelslice DOH_NAMESPACE(Delslice)
+#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 DohNewStringEmpty DOH_NAMESPACE(NewStringEmpty)
+#define DohNewStringWithSize DOH_NAMESPACE(NewStringWithSize)
+#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 DohFileErrorDisplay DOH_NAMESPACE(FileErrorDisplay)
+#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 DohSplitLines DOH_NAMESPACE(SplitLines)
+#define DohNone DOH_NAMESPACE(None)
+#define DohCall DOH_NAMESPACE(Call)
+#define DohObjMalloc DOH_NAMESPACE(ObjMalloc)
+#define DohObjFree DOH_NAMESPACE(ObjFree)
+#define DohMemoryDebug DOH_NAMESPACE(MemoryDebug)
+#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)
+#define DohIterator DOH_NAMESPACE(Iterator)
+#define DohFirst DOH_NAMESPACE(First)
+#define DohNext DOH_NAMESPACE(Next)
+#endif
+
+#define DOH_MAJOR_VERSION 0
+#define DOH_MINOR_VERSION 1
+
+typedef void DOH;
+
+/*
+ * With dynamic typing, all DOH objects are technically of type 'void *'.
+ * However, to clarify the reading of source code, the following symbolic
+ * names are used.
+ */
+
+#define DOHString DOH
+#define DOHList DOH
+#define DOHHash DOH
+#define DOHFile DOH
+#define DOHVoid DOH
+#define DOHString_or_char DOH
+#define DOHObj_or_char DOH
+
+typedef const DOHString_or_char * const_String_or_char_ptr;
+typedef const DOHString_or_char * DOHconst_String_or_char_ptr;
+
+#define DOH_BEGIN -1
+#define DOH_END -2
+#define DOH_CUR -3
+#define DOH_CURRENT -3
+
+/* Iterator objects */
+
+typedef struct {
+ void *key; /* Current key (if any) */
+ void *item; /* Current item */
+ void *object; /* Object being iterated over */
+ void *_current; /* Internal use */
+ int _index; /* Internal use */
+} DohIterator;
+
+/* Memory management */
+
+#ifndef DohMalloc
+#define DohMalloc malloc
+#endif
+#ifndef DohRealloc
+#define DohRealloc realloc
+#endif
+#ifndef DohFree
+#define DohFree free
+#endif
+
+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 */
+
+extern void DohDelete(DOH *obj); /* Delete an object */
+extern DOH *DohCopy(const DOH *obj);
+extern void DohClear(DOH *obj);
+extern DOHString *DohStr(const DOH *obj);
+extern void *DohData(const DOH *obj);
+extern int DohDump(const DOH *obj, DOHFile * out);
+extern int DohLen(const DOH *obj);
+extern int DohHashval(const DOH *obj);
+extern int DohCmp(const DOH *obj1, const DOH *obj2);
+extern int DohEqual(const DOH *obj1, const DOH *obj2);
+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 int DohDelattr(DOH *obj, const DOHString_or_char *name);
+extern int DohCheckattr(DOH *obj, const DOHString_or_char *name, const DOHString_or_char *value);
+extern DOH *DohKeys(DOH *obj);
+extern int DohGetInt(DOH *obj, const DOHString_or_char *name);
+extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int);
+extern double DohGetDouble(DOH *obj, const DOHString_or_char *name);
+extern void DohSetDouble(DOH *obj, const DOHString_or_char *name, double);
+extern char *DohGetChar(DOH *obj, const DOHString_or_char *name);
+extern void DohSetChar(DOH *obj, const DOH *name, char *value);
+extern void *DohGetFlagAttr(DOH *obj, const DOHString_or_char *name);
+extern int DohGetFlag(DOH *obj, const DOHString_or_char *name);
+extern void DohSetFlagAttr(DOH *obj, const DOHString_or_char *name, const DOHString_or_char *attr);
+extern void DohSetFlag(DOH *obj, const DOHString_or_char *name);
+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 int DohDelslice(DOH *obj, int sindex, int eindex);
+
+/* 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);
+
+
+
+/* Iterators */
+extern DohIterator DohFirst(DOH *obj);
+extern DohIterator DohNext(DohIterator x);
+
+/* Positional */
+
+extern int DohGetline(const DOH *obj);
+extern void DohSetline(DOH *obj, int line);
+extern DOH *DohGetfile(const 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);
+
+/* 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);
+
+ /* 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 void DohSetmark(DOH *obj, int x);
+extern int DohGetmark(DOH *obj);
+
+/* -----------------------------------------------------------------------------
+ * Strings.
+ * ----------------------------------------------------------------------------- */
+
+extern DOHString *DohNewStringEmpty(void);
+extern DOHString *DohNewString(const DOH *c);
+extern DOHString *DohNewStringWithSize(const DOH *c, int len);
+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 DOH_REPLACE_ID_BEGIN 0x10
+#define DOH_REPLACE_ID_END 0x20
+
+#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 *filename, const char *mode, DOHList *outfiles);
+extern DOHFile *DohNewFileFromFile(FILE *f);
+extern DOHFile *DohNewFileFromFd(int fd);
+extern void DohFileErrorDisplay(DOHString * filename);
+extern int DohClose(DOH *file);
+extern int DohCopyto(DOHFile * input, DOHFile * output);
+
+
+/* -----------------------------------------------------------------------------
+ * List
+ * ----------------------------------------------------------------------------- */
+
+extern DOHList *DohNewList(void);
+extern void DohSortList(DOH *lo, int (*cmp) (const DOH *, const DOH *));
+
+/* -----------------------------------------------------------------------------
+ * Hash
+ * ----------------------------------------------------------------------------- */
+
+extern DOHHash *DohNewHash(void);
+
+/* -----------------------------------------------------------------------------
+ * Void
+ * ----------------------------------------------------------------------------- */
+
+extern DOHVoid *DohNewVoid(void *ptr, void (*del) (void *));
+extern DOHList *DohSplit(DOHFile * input, char ch, int nsplits);
+extern DOHList *DohSplitLines(DOHFile * input);
+extern DOH *DohNone;
+
+extern void DohMemoryDebug(void);
+
+#ifndef DOH_LONG_NAMES
+/* Macros to invoke the above functions. Includes the location of
+ the caller to simplify debugging if something goes wrong */
+
+#define Delete DohDelete
+#define Copy DohCopy
+#define Clear DohClear
+#define Str DohStr
+#define Dump DohDump
+#define Getattr DohGetattr
+#define Setattr DohSetattr
+#define Delattr DohDelattr
+#define Checkattr DohCheckattr
+#define Hashval DohHashval
+#define Getitem DohGetitem
+#define Setitem DohSetitem
+#define Delitem DohDelitem
+#define Insert DohInsertitem
+#define Delslice DohDelslice
+#define Append(s,x) DohInsertitem(s,DOH_END,x)
+#define Push(s,x) DohInsertitem(s,DOH_BEGIN,x)
+#define Len DohLen
+#define Data DohData
+#define Char (char *) Data
+#define Cmp DohCmp
+#define Equal DohEqual
+#define Setline DohSetline
+#define Getline DohGetline
+#define Setfile DohSetfile
+#define Getfile DohGetfile
+#define Write DohWrite
+#define Read DohRead
+#define Seek DohSeek
+#define Tell DohTell
+#define Printf DohPrintf
+#define Printv DohPrintv
+#define Getc DohGetc
+#define Putc DohPutc
+#define Ungetc DohUngetc
+
+/* #define StringPutc DohStringPutc */
+/* #define StringGetc DohStringGetc */
+/* #define StringUngetc DohStringUngetc */
+/* #define StringAppend Append */
+/* #define StringLen DohStringLen */
+/* #define StringChar DohStringChar */
+/* #define StringEqual DohStringEqual */
+
+#define Close DohClose
+#define vPrintf DohvPrintf
+#define GetInt DohGetInt
+#define GetDouble DohGetDouble
+#define GetChar DohGetChar
+#define GetVoid DohGetVoid
+#define GetFlagAttr DohGetFlagAttr
+#define GetFlag DohGetFlag
+#define SetInt DohSetInt
+#define SetDouble DohSetDouble
+#define SetChar DohSetattr
+#define SetVoid DohSetVoid
+#define SetFlagAttr DohSetFlagAttr
+#define SetFlag DohSetFlag
+#define UnsetFlag(o,n) DohSetFlagAttr(o,n,NULL)
+#define ClearFlag(o,n) DohSetFlagAttr(o,n,"")
+#define Readline DohReadline
+#define Replace DohReplace
+#define Chop DohChop
+#define Getmeta DohGetmeta
+#define Setmeta DohSetmeta
+#define Delmeta DohDelmeta
+#define NewString DohNewString
+#define NewStringEmpty DohNewStringEmpty
+#define NewStringWithSize DohNewStringWithSize
+#define NewStringf DohNewStringf
+#define NewHash DohNewHash
+#define NewList DohNewList
+#define NewFile DohNewFile
+#define NewFileFromFile DohNewFileFromFile
+#define NewFileFromFd DohNewFileFromFd
+#define FileErrorDisplay DohFileErrorDisplay
+#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 SplitLines DohSplitLines
+#define Setmark DohSetmark
+#define Getmark DohGetmark
+#define None DohNone
+#define Call DohCall
+#define First DohFirst
+#define Next DohNext
+#define Iterator DohIterator
+#define SortList DohSortList
+#endif
+
+#ifdef NIL
+#undef NIL
+#endif
+
+#define NIL (char *) NULL
+
+
+#endif /* DOH_H */
diff --git a/Source/DOH/dohint.h b/Source/DOH/dohint.h
new file mode 100644
index 0000000..8f52d28
--- /dev/null
+++ b/Source/DOH/dohint.h
@@ -0,0 +1,133 @@
+
+/* -----------------------------------------------------------------------------
+ * dohint.h
+ *
+ * This file describes internally managed objects.
+ *
+ * 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.
+ *
+ * $Id: dohint.h 9607 2006-12-05 22:11:40Z beazley $
+ * ----------------------------------------------------------------------------- */
+
+#ifndef _DOHINT_H
+#define _DOHINT_H
+
+#include "doh.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+/* Hash objects */
+typedef struct {
+ DOH *(*doh_getattr) (DOH *obj, DOH *name); /* Get attribute */
+ int (*doh_setattr) (DOH *obj, DOH *name, DOH *value); /* Set attribute */
+ int (*doh_delattr) (DOH *obj, DOH *name); /* Del attribute */
+ DOH *(*doh_keys) (DOH *obj); /* All keys as a list */
+} DohHashMethods;
+
+/* List objects */
+typedef struct {
+ DOH *(*doh_getitem) (DOH *obj, int index); /* Get item */
+ int (*doh_setitem) (DOH *obj, int index, DOH *value); /* Set item */
+ int (*doh_delitem) (DOH *obj, int index); /* Delete item */
+ int (*doh_insitem) (DOH *obj, int index, DOH *value); /* Insert item */
+ int (*doh_delslice) (DOH *obj, int sindex, int eindex); /* Delete slice */
+} DohListMethods;
+
+/* File methods */
+typedef struct {
+ int (*doh_read) (DOH *obj, void *buffer, int nbytes); /* Read bytes */
+ int (*doh_write) (DOH *obj, void *buffer, int nbytes); /* Write bytes */
+ int (*doh_putc) (DOH *obj, int ch); /* Put character */
+ int (*doh_getc) (DOH *obj); /* Get character */
+ int (*doh_ungetc) (DOH *obj, int ch); /* Unget character */
+ int (*doh_seek) (DOH *obj, long offset, int whence); /* Seek */
+ long (*doh_tell) (DOH *obj); /* Tell */
+ int (*doh_close) (DOH *obj); /* Close */
+} DohFileMethods;
+
+/* String methods */
+typedef struct {
+ int (*doh_replace) (DOH *obj, DOH *old, DOH *rep, int flags);
+ void (*doh_chop) (DOH *obj);
+} DohStringMethods;
+
+/* -----------------------------------------------------------------------------
+ * DohObjInfo
+ * ----------------------------------------------------------------------------- */
+
+typedef struct DohObjInfo {
+ char *objname; /* Object name */
+
+ /* Basic object methods */
+ void (*doh_del) (DOH *obj); /* Delete object */
+ DOH *(*doh_copy) (DOH *obj); /* Copy and object */
+ void (*doh_clear) (DOH *obj); /* Clear an object */
+
+ /* I/O methods */
+ DOH *(*doh_str) (DOH *obj); /* Make a full string */
+ void *(*doh_data) (DOH *obj); /* Return raw data */
+ int (*doh_dump) (DOH *obj, DOH *out); /* Serialize on out */
+
+ /* Length and hash values */
+ int (*doh_len) (DOH *obj);
+ int (*doh_hashval) (DOH *obj);
+
+ /* Compare */
+ int (*doh_cmp) (DOH *obj1, DOH *obj2);
+
+ /* Equal */
+ int (*doh_equal) (DOH *obj1, DOH *obj2);
+
+ /* Iterators */
+ DohIterator (*doh_first) (DOH *obj);
+ DohIterator (*doh_next) (DohIterator);
+
+ /* Positional */
+ void (*doh_setfile) (DOH *obj, DOHString_or_char *file);
+ DOH *(*doh_getfile) (DOH *obj);
+ void (*doh_setline) (DOH *obj, int line);
+ int (*doh_getline) (DOH *obj);
+
+ DohHashMethods *doh_hash; /* Hash methods */
+ DohListMethods *doh_list; /* List methods */
+ DohFileMethods *doh_file; /* File methods */
+ DohStringMethods *doh_string; /* String methods */
+ void *doh_reserved; /* Reserved */
+ void *clientdata; /* User data */
+} DohObjInfo;
+
+typedef struct {
+ void *data; /* Data pointer */
+ DohObjInfo *type;
+ void *meta; /* Meta data */
+ unsigned int flag_intern:1; /* Interned object */
+ unsigned int flag_marked:1; /* Mark flag. Used to avoid recursive loops in places */
+ unsigned int flag_user:1; /* User flag */
+ unsigned int flag_usermark:1; /* User marked */
+ unsigned 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
+
+/* 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
+
+extern DOH *DohObjMalloc(DohObjInfo *type, void *data); /* Allocate a DOH object */
+extern void DohObjFree(DOH *ptr); /* Free a DOH object */
+
+#endif /* DOHINT_H */
diff --git a/Source/DOH/file.c b/Source/DOH/file.c
new file mode 100644
index 0000000..2384850
--- /dev/null
+++ b/Source/DOH/file.c
@@ -0,0 +1,299 @@
+/* -----------------------------------------------------------------------------
+ * file.c
+ *
+ * This file implements a file-like object that can be built around an
+ * ordinary FILE * or integer file descriptor.
+ *
+ * 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_file_c[] = "$Id: file.c 10898 2008-11-03 12:51:45Z wsfulton $";
+
+#include "dohint.h"
+
+#ifdef DOH_INTFILE
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+typedef struct {
+ FILE *filep;
+ int fd;
+ int closeondel;
+} DohFile;
+
+/* -----------------------------------------------------------------------------
+ * DelFile()
+ * ----------------------------------------------------------------------------- */
+
+static void DelFile(DOH *fo) {
+ DohFile *f = (DohFile *) ObjData(fo);
+ if (f->closeondel) {
+ if (f->filep) {
+ fclose(f->filep);
+ }
+#ifdef DOH_INTFILE
+ if (f->fd) {
+ close(f->fd);
+ }
+#endif
+ }
+ DohFree(f);
+}
+
+/* -----------------------------------------------------------------------------
+ * File_read()
+ * ----------------------------------------------------------------------------- */
+
+static int File_read(DOH *fo, void *buffer, int len) {
+ DohFile *f = (DohFile *) ObjData(fo);
+
+ if (f->filep) {
+ return fread(buffer, 1, len, f->filep);
+ } else if (f->fd) {
+#ifdef DOH_INTFILE
+ return read(f->fd, buffer, len);
+#endif
+ }
+ return -1;
+}
+
+/* -----------------------------------------------------------------------------
+ * File_write()
+ * ----------------------------------------------------------------------------- */
+
+static int File_write(DOH *fo, void *buffer, int len) {
+ DohFile *f = (DohFile *) ObjData(fo);
+ if (f->filep) {
+ int ret = (int) fwrite(buffer, 1, len, f->filep);
+ int err = (ret != len) ? ferror(f->filep) : 0;
+ return err ? -1 : ret;
+ } else if (f->fd) {
+#ifdef DOH_INTFILE
+ return write(f->fd, buffer, len);
+#endif
+ }
+ return -1;
+}
+
+/* -----------------------------------------------------------------------------
+ * File_seek()
+ * ----------------------------------------------------------------------------- */
+
+static int File_seek(DOH *fo, long offset, int whence) {
+ DohFile *f = (DohFile *) ObjData(fo);
+ if (f->filep) {
+ return fseek(f->filep, offset, whence);
+ } else if (f->fd) {
+#ifdef DOH_INTFILE
+ return lseek(f->fd, offset, whence);
+#endif
+ }
+ return -1;
+}
+
+/* -----------------------------------------------------------------------------
+ * File_tell()
+ * ----------------------------------------------------------------------------- */
+
+static long File_tell(DOH *fo) {
+ DohFile *f = (DohFile *) ObjData(fo);
+ if (f->filep) {
+ return ftell(f->filep);
+ } else if (f->fd) {
+#ifdef DOH_INTFILE
+ return lseek(f->fd, 0, SEEK_CUR);
+#endif
+ }
+ return -1;
+}
+
+/* -----------------------------------------------------------------------------
+ * File_putc()
+ * ----------------------------------------------------------------------------- */
+
+static int File_putc(DOH *fo, int ch) {
+ 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
+ }
+ return -1;
+}
+
+/* -----------------------------------------------------------------------------
+ * File_getc()
+ * ----------------------------------------------------------------------------- */
+
+static int File_getc(DOH *fo) {
+ DohFile *f = (DohFile *) ObjData(fo);
+ if (f->filep) {
+ return fgetc(f->filep);
+ } else if (f->fd) {
+#ifdef DOH_INTFILE
+ unsigned char c;
+ if (read(f->fd, &c, 1) < 0)
+ return EOF;
+ return c;
+#endif
+ }
+ return EOF;
+}
+
+/* -----------------------------------------------------------------------------
+ * File_ungetc()
+ *
+ * Put a character back onto the input
+ * ----------------------------------------------------------------------------- */
+
+static int File_ungetc(DOH *fo, int ch) {
+ DohFile *f = (DohFile *) ObjData(fo);
+ if (f->filep) {
+ return ungetc(ch, f->filep);
+ } else if (f->fd) {
+#ifdef DOH_INTFILE
+ /* Not implemented yet */
+#endif
+ }
+ 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,
+ File_putc,
+ File_getc,
+ File_ungetc,
+ File_seek,
+ File_tell,
+ File_close, /* close */
+};
+
+static DohObjInfo DohFileType = {
+ "DohFile", /* objname */
+ DelFile, /* doh_del */
+ 0, /* doh_copy */
+ 0, /* doh_clear */
+ 0, /* doh_str */
+ 0, /* doh_data */
+ 0, /* doh_dump */
+ 0, /* doh_len */
+ 0, /* doh_hash */
+ 0, /* doh_cmp */
+ 0, /* doh_equal */
+ 0, /* doh_first */
+ 0, /* doh_next */
+ 0, /* doh_setfile */
+ 0, /* doh_getfile */
+ 0, /* doh_setline */
+ 0, /* doh_getline */
+ 0, /* doh_mapping */
+ 0, /* doh_sequence */
+ &FileFileMethods, /* doh_file */
+ 0, /* doh_string */
+ 0, /* doh_callable */
+ 0, /* doh_position */
+};
+
+/* -----------------------------------------------------------------------------
+ * NewFile()
+ *
+ * Create a new file from a given filename and mode.
+ * If newfiles is non-zero, the filename is added to the list of new files.
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohNewFile(DOH *filename, const char *mode, DOHList *newfiles) {
+ DohFile *f;
+ FILE *file;
+ char *filen;
+
+ filen = Char(filename);
+ file = fopen(filen, mode);
+ if (!file)
+ return 0;
+
+ f = (DohFile *) DohMalloc(sizeof(DohFile));
+ if (!f) {
+ fclose(file);
+ return 0;
+ }
+ if (newfiles)
+ Append(newfiles, filename);
+ f->filep = file;
+ f->fd = 0;
+ f->closeondel = 1;
+ return DohObjMalloc(&DohFileType, f);
+}
+
+/* -----------------------------------------------------------------------------
+ * NewFileFromFile()
+ *
+ * Create a file object from an already open FILE *.
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohNewFileFromFile(FILE *file) {
+ DohFile *f;
+ f = (DohFile *) DohMalloc(sizeof(DohFile));
+ if (!f)
+ return 0;
+ f->filep = file;
+ f->fd = 0;
+ f->closeondel = 0;
+ return DohObjMalloc(&DohFileType, f);
+}
+
+/* -----------------------------------------------------------------------------
+ * NewFileFromFd()
+ *
+ * Create a file object from an already open FILE *.
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohNewFileFromFd(int fd) {
+ DohFile *f;
+ f = (DohFile *) DohMalloc(sizeof(DohFile));
+ if (!f)
+ return 0;
+ f->filep = 0;
+ f->fd = fd;
+ f->closeondel = 0;
+ return DohObjMalloc(&DohFileType, f);
+}
+
+/* -----------------------------------------------------------------------------
+ * FileErrorDisplay()
+ *
+ * Display cause of one of the NewFile functions failing.
+ * ----------------------------------------------------------------------------- */
+
+void DohFileErrorDisplay(DOHString * filename) {
+ Printf(stderr, "Unable to open file %s: %s\n", filename, strerror(errno));
+}
diff --git a/Source/DOH/fio.c b/Source/DOH/fio.c
new file mode 100644
index 0000000..7f3eb8b
--- /dev/null
+++ b/Source/DOH/fio.c
@@ -0,0 +1,589 @@
+/* -----------------------------------------------------------------------------
+ * fio.c
+ *
+ * This file implements a number of standard I/O operations included
+ * formatted output, readline, and splitting.
+ *
+ * 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_fio_c[] = "$Id: fio.c 9607 2006-12-05 22:11:40Z beazley $";
+
+#include "dohint.h"
+
+#define OBUFLEN 512
+
+static DOH *encodings = 0; /* Encoding hash */
+
+/* -----------------------------------------------------------------------------
+ * Writen()
+ *
+ * Write's N characters of output and retries until all characters are
+ * written. This is useful should a write operation encounter a spurious signal.
+ * ----------------------------------------------------------------------------- */
+
+static int Writen(DOH *out, void *buffer, int len) {
+ int nw = len, ret;
+ char *cb = (char *) buffer;
+ while (nw) {
+ ret = Write(out, cb, nw);
+ if (ret < 0)
+ return -1;
+ nw = nw - ret;
+ cb += ret;
+ }
+ return len;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohEncoding()
+ *
+ * Registers a new printf encoding method. An encoder function should accept
+ * two file-like objects and operate as a filter.
+ * ----------------------------------------------------------------------------- */
+
+void DohEncoding(char *name, DOH *(*fn) (DOH *s)) {
+ if (!encodings)
+ encodings = NewHash();
+ Setattr(encodings, (void *) name, NewVoid((void *) fn, 0));
+}
+
+/* internal function for processing an encoding */
+static DOH *encode(char *name, DOH *s) {
+ DOH *handle, *ns;
+ DOH *(*fn) (DOH *);
+ long pos;
+ char *cfmt = strchr(name, ':');
+ DOH *tmp = 0;
+ if (cfmt) {
+ tmp = NewString(cfmt + 1);
+ Append(tmp, s);
+ Setfile(tmp, Getfile((DOH *) s));
+ Setline(tmp, Getline((DOH *) s));
+ *cfmt = '\0';
+ }
+ if (!encodings || !(handle = Getattr(encodings, name))) {
+ return Copy(s);
+ }
+ if (tmp)
+ s = tmp;
+ pos = Tell(s);
+ Seek(s, 0, SEEK_SET);
+ fn = (DOH *(*)(DOH *)) Data(handle);
+ ns = (*fn) (s);
+ Seek(s, pos, SEEK_SET);
+ if (tmp)
+ Delete(tmp);
+ return ns;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohvPrintf()
+ *
+ * DOH implementation of printf. Output can be directed to any file-like object
+ * including bare FILE * objects. The same formatting codes as printf are
+ * recognized with two extensions:
+ *
+ * %s - Prints a "char *" or the string representation of any
+ * DOH object. This will implicitly result in a call to
+ * Str(obj).
+ *
+ * %(encoder)* - Filters the output through an encoding function registered
+ * with DohEncoder().
+ *
+ * Note: This function is not particularly memory efficient with large strings.
+ * It's better to use Dump() or some other method instead.
+ * ----------------------------------------------------------------------------- */
+
+int DohvPrintf(DOH *so, const char *format, va_list ap) {
+ static char *fmt_codes = "dioxXucsSfeEgGpn";
+ int state = 0;
+ const char *p = format;
+ char newformat[256];
+ char obuffer[OBUFLEN];
+ char *fmt = 0;
+ char temp[64];
+ int widthval = 0;
+ int precval = 0;
+ int maxwidth;
+ char *w = 0;
+ int ivalue;
+ double dvalue;
+ void *pvalue;
+ char *stemp;
+ int nbytes = 0;
+ char encoder[128], *ec = 0;
+ int plevel = 0;
+
+ memset(newformat, 0, sizeof(newformat));
+
+ while (*p) {
+ switch (state) {
+ case 0: /* Ordinary text */
+ if (*p != '%') {
+ Putc(*p, so);
+ nbytes++;
+ } else {
+ fmt = newformat;
+ widthval = 0;
+ precval = 0;
+ *(fmt++) = *p;
+ encoder[0] = 0;
+ state = 10;
+ }
+ break;
+ case 10: /* Look for a width and precision */
+ if (isdigit((int) *p) && (*p != '0')) {
+ w = temp;
+ *(w++) = *p;
+ *(fmt++) = *p;
+ state = 20;
+ } else if (strchr(fmt_codes, *p)) {
+ /* Got one of the formatting codes */
+ p--;
+ state = 100;
+ } else if (*p == '*') {
+ /* Width field is specified in the format list */
+ widthval = va_arg(ap, int);
+ sprintf(temp, "%d", widthval);
+ for (w = temp; *w; w++) {
+ *(fmt++) = *w;
+ }
+ state = 30;
+ } else if (*p == '%') {
+ Putc(*p, so);
+ fmt = newformat;
+ nbytes++;
+ state = 0;
+ } else if (*p == '(') {
+ ++plevel;
+ ec = encoder;
+ state = 60;
+ } else {
+ *(fmt++) = *p;
+ }
+ break;
+
+ case 20: /* Hmmm. At the start of a width field */
+ if (isdigit((int) *p)) {
+ *(w++) = *p;
+ *(fmt++) = *p;
+ } else if (strchr(fmt_codes, *p)) {
+ /* Got one of the formatting codes */
+ /* Figure out width */
+ *w = 0;
+ widthval = atoi(temp);
+ p--;
+ state = 100;
+ } else if (*p == '.') {
+ *w = 0;
+ widthval = atoi(temp);
+ w = temp;
+ *(fmt++) = *p;
+ state = 40;
+ } else {
+ /* ??? */
+ *w = 0;
+ widthval = atoi(temp);
+ state = 50;
+ }
+ break;
+
+ case 30: /* Parsed a width from an argument. Look for a . */
+ if (*p == '.') {
+ w = temp;
+ *(fmt++) = *p;
+ state = 40;
+ } else if (strchr(fmt_codes, *p)) {
+ /* Got one of the formatting codes */
+ /* Figure out width */
+ p--;
+ state = 100;
+ } else {
+ /* hmmm. Something else. */
+ state = 50;
+ }
+ break;
+
+ case 40:
+ /* Start of precision expected */
+ if (isdigit((int) *p) && (*p != '0')) {
+ *(fmt++) = *p;
+ *(w++) = *p;
+ state = 41;
+ } else if (*p == '*') {
+ /* Precision field is specified in the format list */
+ precval = va_arg(ap, int);
+ sprintf(temp, "%d", precval);
+ for (w = temp; *w; w++) {
+ *(fmt++) = *w;
+ }
+ state = 50;
+ } else if (strchr(fmt_codes, *p)) {
+ p--;
+ state = 100;
+ } else {
+ *(fmt++) = *p;
+ state = 50;
+ }
+ break;
+ case 41:
+ if (isdigit((int) *p)) {
+ *(fmt++) = *p;
+ *(w++) = *p;
+ } else if (strchr(fmt_codes, *p)) {
+ /* Got one of the formatting codes */
+ /* Figure out width */
+ *w = 0;
+ precval = atoi(temp);
+ p--;
+ state = 100;
+ } else {
+ *w = 0;
+ precval = atoi(temp);
+ *(fmt++) = *p;
+ state = 50;
+ }
+ break;
+ /* Hang out, wait for format specifier */
+ case 50:
+ if (strchr(fmt_codes, *p)) {
+ p--;
+ state = 100;
+ } else {
+ *(fmt++) = *p;
+ }
+ break;
+
+ /* Got an encoding header */
+ case 60:
+ if (*p == '(') {
+ ++plevel;
+ *ec = *p;
+ ec++;
+ } else if (*p == ')') {
+ --plevel;
+ if (plevel <= 0) {
+ *ec = 0;
+ state = 10;
+ } else {
+ *ec = *p;
+ ec++;
+ }
+ } else {
+ *ec = *p;
+ ec++;
+ }
+ break;
+ case 100:
+ /* Got a formatting code */
+ if (widthval < precval)
+ maxwidth = precval;
+ else
+ maxwidth = widthval;
+ if ((*p == 's') || (*p == 'S')) { /* Null-Terminated string */
+ DOH *doh;
+ DOH *Sval;
+ DOH *enc = 0;
+ doh = va_arg(ap, DOH *);
+ if (DohCheck(doh)) {
+ /* Is a DOH object. */
+ if (DohIsString(doh)) {
+ Sval = doh;
+ } else {
+ Sval = Str(doh);
+ }
+ if (strlen(encoder)) {
+ enc = encode(encoder, Sval);
+ maxwidth = maxwidth + strlen(newformat) + Len(enc);
+ } else {
+ maxwidth = maxwidth + strlen(newformat) + Len(Sval);
+ }
+ *(fmt++) = 's';
+ *fmt = 0;
+ if ((maxwidth + 1) < OBUFLEN) {
+ stemp = obuffer;
+ } else {
+ stemp = (char *) DohMalloc(maxwidth + 1);
+ }
+ if (enc) {
+ nbytes += sprintf(stemp, newformat, Data(enc));
+ } else {
+ nbytes += sprintf(stemp, newformat, Data(Sval));
+ }
+ if (Writen(so, stemp, strlen(stemp)) < 0)
+ return -1;
+ if ((DOH *) Sval != doh) {
+ Delete(Sval);
+ }
+ if (enc)
+ Delete(enc);
+ if (*p == 'S') {
+ Delete(doh);
+ }
+ if (stemp != obuffer) {
+ DohFree(stemp);
+ }
+ } else {
+ if (!doh)
+ doh = (char *) "";
+
+ if (strlen(encoder)) {
+ DOH *s = NewString(doh);
+ Seek(s, 0, SEEK_SET);
+ enc = encode(encoder, s);
+ Delete(s);
+ doh = Char(enc);
+ } else {
+ enc = 0;
+ }
+ maxwidth = maxwidth + strlen(newformat) + strlen((char *) doh);
+ *(fmt++) = 's';
+ *fmt = 0;
+ if ((maxwidth + 1) < OBUFLEN) {
+ stemp = obuffer;
+ } else {
+ stemp = (char *) DohMalloc(maxwidth + 1);
+ }
+ nbytes += sprintf(stemp, newformat, doh);
+ if (Writen(so, stemp, strlen(stemp)) < 0)
+ return -1;
+ if (stemp != obuffer) {
+ DohFree(stemp);
+ }
+ if (enc)
+ Delete(enc);
+ }
+ } else {
+ *(fmt++) = *p;
+ *fmt = 0;
+ maxwidth = maxwidth + strlen(newformat) + 64;
+
+ /* Only allocate a buffer if it is too big to fit. Shouldn't have to do
+ this very often */
+
+ if (maxwidth < OBUFLEN)
+ stemp = obuffer;
+ else
+ stemp = (char *) DohMalloc(maxwidth + 1);
+ switch (*p) {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ ivalue = va_arg(ap, int);
+ nbytes += sprintf(stemp, newformat, ivalue);
+ break;
+ case 'f':
+ case 'g':
+ case 'e':
+ case 'E':
+ case 'G':
+ dvalue = va_arg(ap, double);
+ nbytes += sprintf(stemp, newformat, dvalue);
+ break;
+ case 'p':
+ pvalue = va_arg(ap, void *);
+ nbytes += sprintf(stemp, newformat, pvalue);
+ break;
+ default:
+ break;
+ }
+ if (Writen(so, stemp, strlen(stemp)) < 0)
+ return -1;
+ if (stemp != obuffer)
+ DohFree(stemp);
+ }
+ state = 0;
+ break;
+ }
+ p++;
+ }
+ if (state) {
+ int r;
+ *fmt = 0;
+ r = Writen(so, fmt, strlen(fmt));
+ if (r < 0)
+ return -1;
+ nbytes += r;
+ }
+ return nbytes;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohPrintf()
+ *
+ * Variable length argument entry point to Printf
+ * ----------------------------------------------------------------------------- */
+
+int DohPrintf(DOH *obj, const char *format, ...) {
+ va_list ap;
+ int ret;
+ va_start(ap, format);
+ ret = DohvPrintf(obj, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohPrintv()
+ *
+ * Print a null-terminated variable length list of DOH objects
+ * ----------------------------------------------------------------------------- */
+
+int DohPrintv(DOHFile * f, ...) {
+ va_list ap;
+ int ret = 0;
+ DOH *obj;
+ va_start(ap, f);
+ while (1) {
+ obj = va_arg(ap, void *);
+ if ((!obj) || (obj == DohNone))
+ break;
+ if (DohCheck(obj)) {
+ ret += DohDump(obj, f);
+ } else {
+ ret += DohWrite(f, obj, strlen((char *) obj));
+ }
+ }
+ va_end(ap);
+ return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohCopyto()
+ *
+ * Copies all of the input from an input stream to an output stream. Returns the
+ * number of bytes copied.
+ * ----------------------------------------------------------------------------- */
+
+int DohCopyto(DOH *in, DOH *out) {
+ int nbytes = 0, ret;
+ int nwrite = 0, wret;
+ char *cw;
+ char buffer[16384];
+
+ if ((!in) || (!out))
+ return 0;
+ while (1) {
+ ret = Read(in, buffer, 16384);
+ if (ret > 0) {
+ nwrite = ret;
+ cw = buffer;
+ while (nwrite) {
+ wret = Write(out, cw, nwrite);
+ if (wret < 0)
+ return -1;
+ nwrite = nwrite - wret;
+ cw += wret;
+ }
+ nbytes += ret;
+ } else {
+ return nbytes;
+ }
+ }
+}
+
+
+/* -----------------------------------------------------------------------------
+ * DohSplit()
+ *
+ * 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 ch, int nsplits) {
+ DOH *list;
+ DOH *str;
+ int c;
+
+ list = NewList();
+
+ if (DohIsString(in)) {
+ Seek(in, 0, SEEK_SET);
+ }
+
+ while (1) {
+ str = NewStringEmpty();
+ do {
+ c = Getc(in);
+ } while ((c != EOF) && (c == ch));
+ if (c != EOF) {
+ Putc(c, str);
+ while (1) {
+ c = Getc(in);
+ if ((c == EOF) || ((c == ch) && (nsplits != 0)))
+ break;
+ Putc(c, str);
+ }
+ nsplits--;
+ }
+ Append(list, str);
+ Delete(str);
+ if (c == EOF)
+ break;
+ }
+ return list;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohSplitLines()
+ *
+ * Split an input stream into a list of strings delimited by newline characters.
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohSplitLines(DOH *in) {
+ DOH *list;
+ DOH *str;
+ int c = 0;
+
+ list = NewList();
+
+ if (DohIsString(in)) {
+ Seek(in, 0, SEEK_SET);
+ }
+
+ while (c != EOF) {
+ str = NewStringEmpty();
+ while ((c = Getc(in)) != '\n' && c != EOF) {
+ Putc(c, str);
+ }
+ Append(list, str);
+ Delete(str);
+ }
+ return list;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * DohReadline()
+ *
+ * Read a single input line and return it as a string.
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohReadline(DOH *in) {
+ char c;
+ int n = 0;
+ DOH *s = NewStringEmpty();
+ while (1) {
+ if (Read(in, &c, 1) < 0) {
+ if (n == 0) {
+ Delete(s);
+ return 0;
+ }
+ return s;
+ }
+ if (c == '\n')
+ return s;
+ if (c == '\r')
+ continue;
+ Putc(c, s);
+ n++;
+ }
+}
diff --git a/Source/DOH/hash.c b/Source/DOH/hash.c
new file mode 100644
index 0000000..071a6a6
--- /dev/null
+++ b/Source/DOH/hash.c
@@ -0,0 +1,551 @@
+/* -----------------------------------------------------------------------------
+ * hash.c
+ *
+ * Implements a simple hash table object.
+ *
+ * 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_hash_c[] = "$Id: hash.c 10926 2008-11-11 22:17:40Z wsfulton $";
+
+#include "dohint.h"
+
+extern DohObjInfo DohHashType;
+
+/* Hash node */
+typedef struct HashNode {
+ DOH *key;
+ DOH *object;
+ struct HashNode *next;
+} HashNode;
+
+/* Hash object */
+typedef struct Hash {
+ DOH *file;
+ int line;
+ HashNode **hashtable;
+ int hashsize;
+ int nitems;
+} Hash;
+
+/* Key interning structure */
+typedef struct KeyValue {
+ char *cstr;
+ DOH *sstr;
+ struct KeyValue *left;
+ struct KeyValue *right;
+} KeyValue;
+
+static KeyValue *root = 0;
+
+/* Find or create a key in the interned key table */
+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) {
+ s = r;
+ d = strcmp(r->cstr, c);
+ if (d == 0)
+ return r->sstr;
+ if (d < 0)
+ r = r->left;
+ else
+ r = r->right;
+ }
+ /* fprintf(stderr,"Interning '%s'\n", c); */
+ r = (KeyValue *) DohMalloc(sizeof(KeyValue));
+ r->cstr = (char *) DohMalloc(strlen(c) + 1);
+ strcpy(r->cstr, c);
+ r->sstr = NewString(c);
+ DohIntern(r->sstr);
+ r->left = 0;
+ r->right = 0;
+ if (!s) {
+ root = r;
+ } else {
+ if (d < 0)
+ s->left = r;
+ else
+ s->right = r;
+ }
+ return r->sstr;
+}
+
+#define HASH_INIT_SIZE 7
+
+/* Create a new hash node */
+static HashNode *NewNode(DOH *k, void *obj) {
+ HashNode *hn = (HashNode *) DohMalloc(sizeof(HashNode));
+ hn->key = k;
+ Incref(hn->key);
+ hn->object = obj;
+ Incref(obj);
+ hn->next = 0;
+ return hn;
+}
+
+/* Delete a hash node */
+static void DelNode(HashNode *hn) {
+ Delete(hn->key);
+ Delete(hn->object);
+ DohFree(hn);
+}
+
+/* -----------------------------------------------------------------------------
+ * DelHash()
+ *
+ * Delete a hash table.
+ * ----------------------------------------------------------------------------- */
+
+static void DelHash(DOH *ho) {
+ Hash *h = (Hash *) ObjData(ho);
+ HashNode *n, *next;
+ int i;
+
+ for (i = 0; i < h->hashsize; i++) {
+ n = h->hashtable[i];
+ while (n) {
+ next = n->next;
+ DelNode(n);
+ n = next;
+ }
+ }
+ DohFree(h->hashtable);
+ h->hashtable = 0;
+ h->hashsize = 0;
+ DohFree(h);
+}
+
+/* -----------------------------------------------------------------------------
+ * Hash_clear()
+ *
+ * Clear all of the entries in the hash table.
+ * ----------------------------------------------------------------------------- */
+
+static void Hash_clear(DOH *ho) {
+ Hash *h = (Hash *) ObjData(ho);
+ HashNode *n, *next;
+ int i;
+
+ for (i = 0; i < h->hashsize; i++) {
+ n = h->hashtable[i];
+ while (n) {
+ next = n->next;
+ DelNode(n);
+ n = next;
+ }
+ h->hashtable[i] = 0;
+ }
+ h->nitems = 0;
+}
+
+/* resize the hash table */
+static void resize(Hash *h) {
+ HashNode *n, *next, **table;
+ int oldsize, newsize;
+ int i, p, hv;
+
+ if (h->nitems < 2 * h->hashsize)
+ return;
+
+ /* Too big. We have to rescale everything now */
+ oldsize = h->hashsize;
+
+ /* Calculate a new size */
+ newsize = 2 * oldsize + 1;
+ p = 3;
+ while (p < (newsize >> 1)) {
+ if (((newsize / p) * p) == newsize) {
+ newsize += 2;
+ p = 3;
+ continue;
+ }
+ p = p + 2;
+ }
+
+ table = (HashNode **) DohMalloc(newsize * sizeof(HashNode *));
+ for (i = 0; i < newsize; i++) {
+ table[i] = 0;
+ }
+
+ /* Walk down the old set of nodes and re-place */
+ h->hashsize = newsize;
+ for (i = 0; i < oldsize; i++) {
+ n = h->hashtable[i];
+ while (n) {
+ hv = Hashval(n->key) % newsize;
+ next = n->next;
+ n->next = table[hv];
+ table[hv] = n;
+ n = next;
+ }
+ }
+ DohFree(h->hashtable);
+ h->hashtable = table;
+}
+
+/* -----------------------------------------------------------------------------
+ * Hash_setattr()
+ *
+ * Set an attribute in the hash table. Deletes the existing entry if it already
+ * exists.
+ * ----------------------------------------------------------------------------- */
+
+static int Hash_setattr(DOH *ho, DOH *k, DOH *obj) {
+ int hv;
+ HashNode *n, *prev;
+ Hash *h = (Hash *) ObjData(ho);
+
+ if (!obj) {
+ return DohDelattr(ho, k);
+ }
+ if (!DohCheck(k))
+ k = find_key(k);
+ if (!DohCheck(obj)) {
+ obj = NewString((char *) obj);
+ Decref(obj);
+ }
+ hv = (Hashval(k)) % h->hashsize;
+ n = h->hashtable[hv];
+ prev = 0;
+ while (n) {
+ if (Cmp(n->key, k) == 0) {
+ /* Node already exists. Just replace its contents */
+ if (n->object == obj) {
+ /* Whoa. Same object. Do nothing */
+ return 1;
+ }
+ Delete(n->object);
+ n->object = obj;
+ Incref(obj);
+ return 1; /* Return 1 to indicate a replacement */
+ } else {
+ prev = n;
+ n = n->next;
+ }
+ }
+ /* Add this to the table */
+ n = NewNode(k, obj);
+ if (prev)
+ prev->next = n;
+ else
+ h->hashtable[hv] = n;
+ h->nitems++;
+ resize(h);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Hash_getattr()
+ *
+ * Get an attribute from the hash table. Returns 0 if it doesn't exist.
+ * ----------------------------------------------------------------------------- */
+typedef int (*binop) (DOH *obj1, DOH *obj2);
+
+
+static DOH *Hash_getattr(DOH *h, DOH *k) {
+ DOH *obj = 0;
+ Hash *ho = (Hash *) ObjData(h);
+ DOH *ko = DohCheck(k) ? k : find_key(k);
+ int hv = Hashval(ko) % ho->hashsize;
+ DohObjInfo *k_type = ((DohBase*)ko)->type;
+ HashNode *n = ho->hashtable[hv];
+ if (k_type->doh_equal) {
+ binop equal = k_type->doh_equal;
+ while (n) {
+ DohBase *nk = (DohBase *)n->key;
+ if ((k_type == nk->type) && equal(ko, nk)) obj = n->object;
+ n = n->next;
+ }
+ } else {
+ binop cmp = k_type->doh_cmp;
+ while (n) {
+ DohBase *nk = (DohBase *)n->key;
+ if ((k_type == nk->type) && (cmp(ko, nk) == 0)) obj = n->object;
+ n = n->next;
+ }
+ }
+ return obj;
+}
+
+/* -----------------------------------------------------------------------------
+ * Hash_delattr()
+ *
+ * Delete an object from the hash table.
+ * ----------------------------------------------------------------------------- */
+
+static int Hash_delattr(DOH *ho, DOH *k) {
+ HashNode *n, *prev;
+ int hv;
+ Hash *h = (Hash *) ObjData(ho);
+
+ if (!DohCheck(k))
+ k = find_key(k);
+ hv = Hashval(k) % h->hashsize;
+ n = h->hashtable[hv];
+ prev = 0;
+ while (n) {
+ if (Cmp(n->key, k) == 0) {
+ /* Found it, kill it */
+
+ if (prev) {
+ prev->next = n->next;
+ } else {
+ h->hashtable[hv] = n->next;
+ }
+ DelNode(n);
+ h->nitems--;
+ return 1;
+ }
+ prev = n;
+ n = n->next;
+ }
+ return 0;
+}
+
+static DohIterator Hash_firstiter(DOH *ho) {
+ DohIterator iter;
+ Hash *h = (Hash *) ObjData(ho);
+ iter.object = ho;
+ iter._current = 0;
+ iter.item = 0;
+ iter.key = 0;
+ iter._index = 0; /* Index in hash table */
+ while ((iter._index < h->hashsize) && !h->hashtable[iter._index])
+ iter._index++;
+
+ if (iter._index >= h->hashsize) {
+ return iter;
+ }
+ iter._current = h->hashtable[iter._index];
+ iter.item = ((HashNode *) iter._current)->object;
+ iter.key = ((HashNode *) iter._current)->key;
+
+ /* Actually save the next slot in the hash. This makes it possible to
+ delete the item being iterated over without trashing the universe */
+ iter._current = ((HashNode *) iter._current)->next;
+ return iter;
+}
+
+static DohIterator Hash_nextiter(DohIterator iter) {
+ Hash *h = (Hash *) ObjData(iter.object);
+ if (!iter._current) {
+ iter._index++;
+ while ((iter._index < h->hashsize) && !h->hashtable[iter._index]) {
+ iter._index++;
+ }
+ if (iter._index >= h->hashsize) {
+ iter.item = 0;
+ iter.key = 0;
+ iter._current = 0;
+ return iter;
+ }
+ iter._current = h->hashtable[iter._index];
+ }
+ iter.key = ((HashNode *) iter._current)->key;
+ iter.item = ((HashNode *) iter._current)->object;
+
+ /* Store the next node to iterator on */
+ iter._current = ((HashNode *) iter._current)->next;
+ return iter;
+}
+
+/* -----------------------------------------------------------------------------
+ * Hash_keys(DOH *)
+ *
+ * Return a list of keys
+ * ----------------------------------------------------------------------------- */
+
+static DOH *Hash_keys(DOH *so) {
+ DOH *keys;
+ Iterator i;
+
+ keys = NewList();
+ for (i = First(so); i.key; i = Next(i)) {
+ Append(keys, i.key);
+ }
+ return keys;
+}
+
+/* -----------------------------------------------------------------------------
+ * Hash_str()
+ *
+ * Create a string representation of a hash table (mainly for debugging).
+ * ----------------------------------------------------------------------------- */
+
+static DOH *Hash_str(DOH *ho) {
+ int i, j;
+ HashNode *n;
+ DOH *s;
+ static int indent = 4;
+ Hash *h = (Hash *) ObjData(ho);
+
+ s = NewStringEmpty();
+ if (ObjGetMark(ho)) {
+ Printf(s, "Hash(0x%x)", ho);
+ return s;
+ }
+ ObjSetMark(ho, 1);
+ Printf(s, "Hash {\n");
+ for (i = 0; i < h->hashsize; i++) {
+ n = h->hashtable[i];
+ while (n) {
+ for (j = 0; j < indent; j++)
+ Putc(' ', s);
+ indent += 4;
+ Printf(s, "'%s' : %s, \n", n->key, n->object);
+ indent -= 4;
+ n = n->next;
+ }
+ }
+ for (j = 0; j < (indent - 4); j++)
+ Putc(' ', s);
+ Printf(s, "}\n");
+ ObjSetMark(ho, 0);
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * Hash_len()
+ *
+ * Return number of entries in the hash table.
+ * ----------------------------------------------------------------------------- */
+
+static int Hash_len(DOH *ho) {
+ Hash *h = (Hash *) ObjData(ho);
+ return h->nitems;
+}
+
+/* -----------------------------------------------------------------------------
+ * CopyHash()
+ *
+ * Make a copy of a hash table. Note: this is a shallow copy.
+ * ----------------------------------------------------------------------------- */
+
+static DOH *CopyHash(DOH *ho) {
+ Hash *h, *nh;
+ HashNode *n;
+ DOH *nho;
+
+ int i;
+ h = (Hash *) ObjData(ho);
+ nh = (Hash *) DohMalloc(sizeof(Hash));
+ nh->hashsize = h->hashsize;
+ nh->hashtable = (HashNode **) DohMalloc(nh->hashsize * sizeof(HashNode *));
+ for (i = 0; i < nh->hashsize; i++) {
+ nh->hashtable[i] = 0;
+ }
+ nh->nitems = 0;
+ nh->line = h->line;
+ nh->file = h->file;
+ if (nh->file)
+ Incref(nh->file);
+
+ nho = DohObjMalloc(&DohHashType, nh);
+ for (i = 0; i < h->hashsize; i++) {
+ n = h->hashtable[i];
+ while (n) {
+ Hash_setattr(nho, n->key, n->object);
+ n = n->next;
+ }
+ }
+ return nho;
+}
+
+
+
+static void Hash_setfile(DOH *ho, DOH *file) {
+ DOH *fo;
+ Hash *h = (Hash *) ObjData(ho);
+
+ if (!DohCheck(file)) {
+ fo = NewString(file);
+ Decref(fo);
+ } else
+ fo = file;
+ Incref(fo);
+ Delete(h->file);
+ h->file = fo;
+}
+
+static DOH *Hash_getfile(DOH *ho) {
+ Hash *h = (Hash *) ObjData(ho);
+ return h->file;
+}
+
+static void Hash_setline(DOH *ho, int line) {
+ Hash *h = (Hash *) ObjData(ho);
+ h->line = line;
+}
+
+static int Hash_getline(DOH *ho) {
+ Hash *h = (Hash *) ObjData(ho);
+ return h->line;
+}
+
+/* -----------------------------------------------------------------------------
+ * type information
+ * ----------------------------------------------------------------------------- */
+
+static DohHashMethods HashHashMethods = {
+ Hash_getattr,
+ Hash_setattr,
+ Hash_delattr,
+ Hash_keys,
+};
+
+DohObjInfo DohHashType = {
+ "Hash", /* objname */
+ DelHash, /* doh_del */
+ CopyHash, /* doh_copy */
+ Hash_clear, /* doh_clear */
+ Hash_str, /* doh_str */
+ 0, /* doh_data */
+ 0, /* doh_dump */
+ Hash_len, /* doh_len */
+ 0, /* doh_hash */
+ 0, /* doh_cmp */
+ 0, /* doh_equal */
+ Hash_firstiter, /* doh_first */
+ Hash_nextiter, /* doh_next */
+ Hash_setfile, /* doh_setfile */
+ Hash_getfile, /* doh_getfile */
+ Hash_setline, /* doh_setline */
+ Hash_getline, /* doh_getline */
+ &HashHashMethods, /* doh_mapping */
+ 0, /* doh_sequence */
+ 0, /* doh_file */
+ 0, /* doh_string */
+ 0, /* doh_positional */
+ 0,
+};
+
+/* -----------------------------------------------------------------------------
+ * NewHash()
+ *
+ * Create a new hash table.
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohNewHash(void) {
+ Hash *h;
+ int i;
+ h = (Hash *) DohMalloc(sizeof(Hash));
+ h->hashsize = HASH_INIT_SIZE;
+ h->hashtable = (HashNode **) DohMalloc(h->hashsize * sizeof(HashNode *));
+ for (i = 0; i < h->hashsize; i++) {
+ h->hashtable[i] = 0;
+ }
+ h->nitems = 0;
+ h->file = 0;
+ h->line = 0;
+ return DohObjMalloc(&DohHashType, h);
+}
diff --git a/Source/DOH/list.c b/Source/DOH/list.c
new file mode 100644
index 0000000..b7e23ad
--- /dev/null
+++ b/Source/DOH/list.c
@@ -0,0 +1,377 @@
+/* -----------------------------------------------------------------------------
+ * list.c
+ *
+ * Implements a simple list object.
+ *
+ * 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_list_c[] = "$Id: list.c 10926 2008-11-11 22:17:40Z wsfulton $";
+
+#include "dohint.h"
+
+typedef struct List {
+ int maxitems; /* Max size */
+ int nitems; /* Num items */
+ DOH *file;
+ int line;
+ DOH **items;
+} List;
+
+extern DohObjInfo DohListType;
+
+/* Doubles amount of memory in a list */
+static
+void more(List *l) {
+ l->items = (void **) DohRealloc(l->items, l->maxitems * 2 * sizeof(void *));
+ assert(l->items);
+ l->maxitems *= 2;
+}
+
+/* -----------------------------------------------------------------------------
+ * CopyList()
+ *
+ * Make a shallow copy of a list.
+ * ----------------------------------------------------------------------------- */
+static DOH *CopyList(DOH *lo) {
+ List *l, *nl;
+ int i;
+ l = (List *) ObjData(lo);
+ nl = (List *) DohMalloc(sizeof(List));
+ nl->nitems = l->nitems;
+ nl->maxitems = l->maxitems;
+ nl->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
+ for (i = 0; i < l->nitems; i++) {
+ nl->items[i] = l->items[i];
+ Incref(nl->items[i]);
+ }
+ nl->file = l->file;
+ if (nl->file)
+ Incref(nl->file);
+ nl->line = l->line;
+ return DohObjMalloc(&DohListType, nl);
+}
+
+/* -----------------------------------------------------------------------------
+ * DelList()
+ *
+ * Delete a list.
+ * ----------------------------------------------------------------------------- */
+
+static void DelList(DOH *lo) {
+ List *l = (List *) ObjData(lo);
+ int i;
+ for (i = 0; i < l->nitems; i++)
+ Delete(l->items[i]);
+ DohFree(l->items);
+ DohFree(l);
+}
+
+/* -----------------------------------------------------------------------------
+ * List_clear()
+ *
+ * Remove all of the list entries, but keep the list object intact.
+ * ----------------------------------------------------------------------------- */
+
+static void List_clear(DOH *lo) {
+ List *l = (List *) ObjData(lo);
+ int i;
+ for (i = 0; i < l->nitems; i++) {
+ Delete(l->items[i]);
+ }
+ l->nitems = 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * List_insert()
+ *
+ * Insert an item into the list. If the item is not a DOH object, it is assumed
+ * to be a 'char *' and is used to construct an equivalent string object.
+ * ----------------------------------------------------------------------------- */
+
+static int List_insert(DOH *lo, int pos, DOH *item) {
+ List *l = (List *) ObjData(lo);
+ int i;
+
+ if (!item)
+ return -1;
+ if (!DohCheck(item)) {
+ item = NewString(item);
+ Decref(item);
+ }
+ if (pos == DOH_END)
+ pos = l->nitems;
+ if (pos < 0)
+ pos = 0;
+ if (pos > l->nitems)
+ pos = l->nitems;
+ if (l->nitems == l->maxitems)
+ more(l);
+ for (i = l->nitems; i > pos; i--) {
+ l->items[i] = l->items[i - 1];
+ }
+ l->items[pos] = item;
+ Incref(item);
+ l->nitems++;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * List_remove()
+ *
+ * Remove an item from a list.
+ * ----------------------------------------------------------------------------- */
+
+static int List_remove(DOH *lo, int pos) {
+ List *l = (List *) ObjData(lo);
+ int i;
+ if (pos == DOH_END)
+ pos = l->nitems - 1;
+ if (pos == DOH_BEGIN)
+ pos = 0;
+ assert(!((pos < 0) || (pos >= l->nitems)));
+ Delete(l->items[pos]);
+ for (i = pos; i < l->nitems - 1; i++) {
+ l->items[i] = l->items[i + 1];
+ }
+ l->nitems--;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * List_len()
+ *
+ * Return the number of elements in the list
+ * ----------------------------------------------------------------------------- */
+
+static int List_len(DOH *lo) {
+ List *l = (List *) ObjData(lo);
+ return l->nitems;
+}
+
+/* -----------------------------------------------------------------------------
+ * List_get()
+ *
+ * Get the nth item from the list.
+ * ----------------------------------------------------------------------------- */
+
+static DOH *List_get(DOH *lo, int n) {
+ List *l = (List *) ObjData(lo);
+ if (n == DOH_END)
+ n = l->nitems - 1;
+ if (n == DOH_BEGIN)
+ n = 0;
+ assert(!((n < 0) || (n >= l->nitems)));
+ return l->items[n];
+}
+
+/* -----------------------------------------------------------------------------
+ * List_set()
+ *
+ * Set the nth item in the list replacing any previous item.
+ * ----------------------------------------------------------------------------- */
+
+static int List_set(DOH *lo, int n, DOH *val) {
+ List *l = (List *) ObjData(lo);
+ if (!val)
+ return -1;
+ assert(!((n < 0) || (n >= l->nitems)));
+ if (!DohCheck(val)) {
+ val = NewString(val);
+ Decref(val);
+ }
+ Delete(l->items[n]);
+ l->items[n] = val;
+ Incref(val);
+ Delete(val);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * List_first()
+ *
+ * Return the first item in the list.
+ * ----------------------------------------------------------------------------- */
+
+static DohIterator List_first(DOH *lo) {
+ DohIterator iter;
+ List *l = (List *) ObjData(lo);
+ iter.object = lo;
+ iter._index = 0;
+ iter._current = 0;
+ iter.key = 0;
+ if (l->nitems > 0) {
+ iter.item = l->items[0];
+ } else {
+ iter.item = 0;
+ }
+ return iter;
+}
+
+/* -----------------------------------------------------------------------------
+ * List_next()
+ *
+ * Return the next item in the list.
+ * ----------------------------------------------------------------------------- */
+
+static DohIterator List_next(DohIterator iter) {
+ List *l = (List *) ObjData(iter.object);
+ iter._index = iter._index + 1;
+ if (iter._index >= l->nitems) {
+ iter.item = 0;
+ iter.key = 0;
+ } else {
+ iter.item = l->items[iter._index];
+ }
+ return iter;
+}
+
+/* -----------------------------------------------------------------------------
+ * List_str()
+ *
+ * Create a string representation of the list.
+ * ----------------------------------------------------------------------------- */
+static DOH *List_str(DOH *lo) {
+ DOH *s;
+ int i;
+ List *l = (List *) ObjData(lo);
+ s = NewStringEmpty();
+ if (ObjGetMark(lo)) {
+ Printf(s, "List(%x)", lo);
+ return s;
+ }
+ ObjSetMark(lo, 1);
+ Printf(s, "List[ ");
+ for (i = 0; i < l->nitems; i++) {
+ Printf(s, "%s", l->items[i]);
+ if ((i + 1) < l->nitems)
+ Printf(s, ", ");
+ }
+ Printf(s, " ]\n");
+ ObjSetMark(lo, 0);
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * List_dump()
+ *
+ * Dump the items to an output stream.
+ * ----------------------------------------------------------------------------- */
+
+static int List_dump(DOH *lo, DOH *out) {
+ int nsent = 0;
+ int i, ret;
+ List *l = (List *) ObjData(lo);
+ for (i = 0; i < l->nitems; i++) {
+ ret = Dump(l->items[i], out);
+ if (ret < 0)
+ return -1;
+ nsent += ret;
+ }
+ return nsent;
+}
+
+static void List_setfile(DOH *lo, DOH *file) {
+ DOH *fo;
+ List *l = (List *) ObjData(lo);
+
+ if (!DohCheck(file)) {
+ fo = NewString(file);
+ Decref(fo);
+ } else
+ fo = file;
+ Incref(fo);
+ Delete(l->file);
+ l->file = fo;
+}
+
+static DOH *List_getfile(DOH *lo) {
+ List *l = (List *) ObjData(lo);
+ return l->file;
+}
+
+static void List_setline(DOH *lo, int line) {
+ List *l = (List *) ObjData(lo);
+ l->line = line;
+}
+
+static int List_getline(DOH *lo) {
+ List *l = (List *) ObjData(lo);
+ return l->line;
+}
+
+static DohListMethods ListListMethods = {
+ List_get,
+ List_set,
+ List_remove,
+ List_insert,
+ 0, /* delslice */
+};
+
+DohObjInfo DohListType = {
+ "List", /* objname */
+ DelList, /* doh_del */
+ CopyList, /* doh_copy */
+ List_clear, /* doh_clear */
+ List_str, /* doh_str */
+ 0, /* doh_data */
+ List_dump, /* doh_dump */
+ List_len, /* doh_len */
+ 0, /* doh_hash */
+ 0, /* doh_cmp */
+ 0, /* doh_equal */
+ List_first, /* doh_first */
+ List_next, /* doh_next */
+ List_setfile, /* doh_setfile */
+ List_getfile, /* doh_getfile */
+ List_setline, /* doh_setline */
+ List_getline, /* doh_getline */
+ 0, /* doh_mapping */
+ &ListListMethods, /* doh_sequence */
+ 0, /* doh_file */
+ 0, /* doh_string */
+ 0, /* doh_callable */
+ 0, /* doh_position */
+};
+
+/* -----------------------------------------------------------------------------
+ * NewList()
+ *
+ * Create a new list.
+ * ----------------------------------------------------------------------------- */
+
+#define MAXLISTITEMS 8
+
+DOH *DohNewList(void) {
+ List *l;
+ int i;
+ l = (List *) DohMalloc(sizeof(List));
+ l->nitems = 0;
+ l->maxitems = MAXLISTITEMS;
+ l->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
+ for (i = 0; i < MAXLISTITEMS; i++) {
+ l->items[i] = 0;
+ }
+ l->file = 0;
+ l->line = 0;
+ return DohObjMalloc(&DohListType, l);
+}
+
+static int (*List_sort_compare_func) (const DOH *, const DOH *);
+static int List_qsort_compare(const void *a, const void *b) {
+ return List_sort_compare_func(*((DOH **) a), *((DOH **) b));
+}
+
+/* Sort a list */
+void DohSortList(DOH *lo, int (*cmp) (const DOH *, const DOH *)) {
+ List *l = (List *) ObjData(lo);
+ if (cmp) {
+ List_sort_compare_func = cmp;
+ } else {
+ List_sort_compare_func = DohCmp;
+ }
+ qsort(l->items, l->nitems, sizeof(DOH *), List_qsort_compare);
+}
diff --git a/Source/DOH/memory.c b/Source/DOH/memory.c
new file mode 100644
index 0000000..79ff21c
--- /dev/null
+++ b/Source/DOH/memory.c
@@ -0,0 +1,220 @@
+/* -----------------------------------------------------------------------------
+ * memory.c
+ *
+ * This file implements all of DOH's memory management including allocation
+ * of objects and checking of objects.
+ *
+ * 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_memory_c[] = "$Id: memory.c 9607 2006-12-05 22:11:40Z beazley $";
+
+#include "dohint.h"
+
+#ifndef DOH_POOL_SIZE
+#define DOH_POOL_SIZE 16384
+#endif
+
+static int PoolSize = DOH_POOL_SIZE;
+
+DOH *DohNone = 0; /* The DOH None object */
+
+typedef struct pool {
+ DohBase *ptr; /* Start of pool */
+ int len; /* Length of pool */
+ int blen; /* Byte length of pool */
+ int current; /* Current position for next allocation */
+ char *pbeg; /* Beg of pool */
+ char *pend; /* End of pool */
+ struct pool *next; /* Next pool */
+} Pool;
+
+static DohBase *FreeList = 0; /* List of free objects */
+static Pool *Pools = 0;
+static int pools_initialized = 0;
+
+/* ----------------------------------------------------------------------
+ * CreatePool() - Create a new memory pool
+ * ---------------------------------------------------------------------- */
+
+static void CreatePool() {
+ Pool *p = 0;
+ p = (Pool *) DohMalloc(sizeof(Pool));
+ assert(p);
+ p->ptr = (DohBase *) DohMalloc(sizeof(DohBase) * PoolSize);
+ assert(p->ptr);
+ memset(p->ptr, 0, sizeof(DohBase) * PoolSize);
+ p->len = PoolSize;
+ p->blen = PoolSize * sizeof(DohBase);
+ p->current = 0;
+ p->pbeg = ((char *) p->ptr);
+ p->pend = p->pbeg + p->blen;
+ p->next = Pools;
+ Pools = p;
+}
+
+/* ----------------------------------------------------------------------
+ * InitPools() - Initialize the memory allocator
+ * ---------------------------------------------------------------------- */
+
+static void InitPools() {
+ if (pools_initialized)
+ return;
+ CreatePool(); /* Create initial pool */
+ pools_initialized = 1;
+ DohNone = NewVoid(0, 0); /* Create the None object */
+ DohIntern(DohNone);
+}
+
+/* ----------------------------------------------------------------------
+ * DohCheck()
+ *
+ * Returns 1 if an arbitrary pointer is a DOH object.
+ * ---------------------------------------------------------------------- */
+
+int DohCheck(const DOH *ptr) {
+ register Pool *p = Pools;
+ register char *cptr = (char *) ptr;
+ while (p) {
+ if ((cptr >= p->pbeg) && (cptr < p->pend))
+ return 1;
+ /*
+ pptr = (char *) p->ptr;
+ if ((cptr >= pptr) && (cptr < (pptr+(p->current*sizeof(DohBase))))) return 1; */
+ p = p->next;
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DohIntern()
+ * ----------------------------------------------------------------------------- */
+
+void DohIntern(DOH *obj) {
+ DohBase *b = (DohBase *) obj;
+ b->flag_intern = 1;
+}
+
+/* ----------------------------------------------------------------------
+ * DohObjMalloc()
+ *
+ * Allocate memory for a new object.
+ * ---------------------------------------------------------------------- */
+
+DOH *DohObjMalloc(DohObjInfo *type, void *data) {
+ DohBase *obj;
+ if (!pools_initialized)
+ InitPools();
+ if (FreeList) {
+ obj = FreeList;
+ FreeList = (DohBase *) obj->data;
+ } else {
+ while (Pools->current == Pools->len) {
+ CreatePool();
+ }
+ obj = Pools->ptr + Pools->current;
+ ++Pools->current;
+ }
+ 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;
+}
+
+/* ----------------------------------------------------------------------
+ * DohObjFree() - Free a DOH object
+ * ---------------------------------------------------------------------- */
+
+void DohObjFree(DOH *ptr) {
+ DohBase *b, *meta;
+ b = (DohBase *) ptr;
+ if (b->flag_intern)
+ return;
+ meta = (DohBase *) b->meta;
+ b->data = (void *) FreeList;
+ b->meta = 0;
+ b->type = 0;
+ FreeList = b;
+ if (meta) {
+ Delete(meta);
+ }
+}
+
+/* ----------------------------------------------------------------------
+ * DohMemoryDebug()
+ *
+ * Display memory usage statistics
+ * ---------------------------------------------------------------------- */
+
+void DohMemoryDebug(void) {
+ extern DohObjInfo DohStringType;
+ extern DohObjInfo DohListType;
+ extern DohObjInfo DohHashType;
+
+ Pool *p;
+ int totsize = 0;
+ int totused = 0;
+ int totfree = 0;
+
+ int numstring = 0;
+ int numlist = 0;
+ int numhash = 0;
+
+ printf("Memory statistics:\n\n");
+ printf("Pools:\n");
+
+ p = Pools;
+ while (p) {
+ /* Calculate number of used, free items */
+ int i;
+ int nused = 0, nfree = 0;
+ for (i = 0; i < p->len; i++) {
+ if (p->ptr[i].refcount <= 0)
+ nfree++;
+ else {
+ nused++;
+ if (p->ptr[i].type == &DohStringType)
+ numstring++;
+ else if (p->ptr[i].type == &DohListType)
+ numlist++;
+ else if (p->ptr[i].type == &DohHashType)
+ numhash++;
+ }
+ }
+ printf(" Pool %8p: size = %10d. used = %10d. free = %10d\n", (void *) p, p->len, nused, nfree);
+ totsize += p->len;
+ totused += nused;
+ totfree += nfree;
+ p = p->next;
+ }
+ printf("\n Total: size = %10d, used = %10d, free = %10d\n", totsize, totused, totfree);
+
+ printf("\nObject types\n");
+ printf(" Strings : %d\n", numstring);
+ printf(" Lists : %d\n", numlist);
+ printf(" Hashes : %d\n", numhash);
+
+#if 0
+ p = Pools;
+ while (p) {
+ int i;
+ for (i = 0; i < p->len; i++) {
+ if (p->ptr[i].refcount > 0) {
+ if (p->ptr[i].type == &DohStringType) {
+ Printf(stdout, "%s\n", p->ptr + i);
+ }
+ }
+ }
+ p = p->next;
+ }
+#endif
+
+}
diff --git a/Source/DOH/string.c b/Source/DOH/string.c
new file mode 100644
index 0000000..425a39f
--- /dev/null
+++ b/Source/DOH/string.c
@@ -0,0 +1,1158 @@
+/* -----------------------------------------------------------------------------
+ * string.c
+ *
+ * Implements a string object that supports both sequence operations and
+ * file semantics.
+ *
+ * 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_string_c[] = "$Id: string.c 10926 2008-11-11 22:17:40Z wsfulton $";
+
+#include "dohint.h"
+
+extern DohObjInfo DohStringType;
+
+typedef struct String {
+ DOH *file;
+ int line;
+ int maxsize; /* Max size allocated */
+ int len; /* Current length */
+ int hashkey; /* Hash key value */
+ int sp; /* Current position */
+ char *str; /* String data */
+} String;
+
+/* -----------------------------------------------------------------------------
+ * void *String_data() - Return as a 'void *'
+ * ----------------------------------------------------------------------------- */
+
+static void *String_data(DOH *so) {
+ String *s = (String *) ObjData(so);
+ s->str[s->len] = 0;
+ return (void *) s->str;
+}
+
+/* static char *String_char(DOH *so) {
+ return (char *) String_data(so);
+}
+*/
+
+/* -----------------------------------------------------------------------------
+ * int String_dump() - Serialize a string onto out
+ * ----------------------------------------------------------------------------- */
+
+static int String_dump(DOH *so, DOH *out) {
+ int nsent;
+ int ret;
+ String *s = (String *) ObjData(so);
+ nsent = 0;
+ while (nsent < s->len) {
+ ret = Write(out, s->str + nsent, (s->len - nsent));
+ if (ret < 0)
+ return ret;
+ nsent += ret;
+ }
+ return nsent;
+}
+
+/* -----------------------------------------------------------------------------
+ * CopyString() - Copy a string
+ * ----------------------------------------------------------------------------- */
+
+static DOH *CopyString(DOH *so) {
+ String *str;
+ String *s = (String *) ObjData(so);
+ str = (String *) DohMalloc(sizeof(String));
+ str->hashkey = s->hashkey;
+ str->sp = s->sp;
+ str->line = s->line;
+ str->file = s->file;
+ if (str->file)
+ Incref(str->file);
+ str->str = (char *) DohMalloc(s->len + 1);
+ memcpy(str->str, s->str, s->len);
+ str->maxsize = s->len;
+ str->len = s->len;
+ str->str[str->len] = 0;
+
+ return DohObjMalloc(&DohStringType, str);
+}
+
+/* -----------------------------------------------------------------------------
+ * DelString() - Delete a string
+ * ----------------------------------------------------------------------------- */
+
+static void DelString(DOH *so) {
+ String *s = (String *) ObjData(so);
+ DohFree(s->str);
+ DohFree(s);
+}
+
+/* -----------------------------------------------------------------------------
+ * DohString_len() - Length of a string
+ * ----------------------------------------------------------------------------- */
+
+static int String_len(DOH *so) {
+ String *s = (String *) ObjData(so);
+ return s->len;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * int String_cmp() - Compare two strings
+ * ----------------------------------------------------------------------------- */
+
+static int String_cmp(DOH *so1, DOH *so2) {
+ String *s1, *s2;
+ char *c1, *c2;
+ int maxlen, i;
+ s1 = (String *) ObjData(so1);
+ s2 = (String *) ObjData(so2);
+ maxlen = s1->len;
+ if (s2->len < maxlen)
+ maxlen = s2->len;
+ c1 = s1->str;
+ c2 = s2->str;
+ for (i = maxlen; i; --i, c1++, c2++) {
+ if (*c1 != *c2)
+ break;
+ }
+ if (i != 0) {
+ if (*c1 < *c2)
+ return -1;
+ else
+ return 1;
+ }
+ if (s1->len == s2->len)
+ return 0;
+ if (s1->len > s2->len)
+ return 1;
+ return -1;
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_equal() - Say if two string are equal
+ * ----------------------------------------------------------------------------- */
+
+static int String_equal(DOH *so1, DOH *so2) {
+ String *s1 = (String *) ObjData(so1);
+ String *s2 = (String *) ObjData(so2);
+ register int len = s1->len;
+ if (len != s2->len) {
+ return 0;
+ } else {
+ register char *c1 = s1->str;
+ register char *c2 = s2->str;
+#if 0
+ register int mlen = len >> 2;
+ register int i = mlen;
+ for (; i; --i) {
+ if (*(c1++) != *(c2++))
+ return 0;
+ if (*(c1++) != *(c2++))
+ return 0;
+ if (*(c1++) != *(c2++))
+ return 0;
+ if (*(c1++) != *(c2++))
+ return 0;
+ }
+ for (i = len - (mlen << 2); i; --i) {
+ if (*(c1++) != *(c2++))
+ return 0;
+ }
+ return 1;
+#else
+ return memcmp(c1, c2, len) == 0;
+#endif
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_hash() - Compute string hash value
+ * ----------------------------------------------------------------------------- */
+
+static int String_hash(DOH *so) {
+ String *s = (String *) ObjData(so);
+ if (s->hashkey >= 0) {
+ return s->hashkey;
+ } else {
+ register char *c = s->str;
+ register int len = s->len > 50 ? 50 : s->len;
+ register int h = 0;
+ register int mlen = len >> 2;
+ register int i = mlen;
+ for (; i; --i) {
+ h = (h << 5) + *(c++);
+ h = (h << 5) + *(c++);
+ h = (h << 5) + *(c++);
+ h = (h << 5) + *(c++);
+ }
+ for (i = len - (mlen << 2); i; --i) {
+ h = (h << 5) + *(c++);
+ }
+ h &= 0x7fffffff;
+ s->hashkey = h;
+ return h;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * DohString_append(String *s, const char *newstr) - Append to s
+ * ----------------------------------------------------------------------------- */
+
+void DohString_append(DOH *so, DOH *str) {
+ int oldlen, newlen, newmaxsize, l, sp;
+ char *tc;
+ String *s = (String *) ObjData(so);
+ char *newstr = 0;
+
+ if (DohCheck(str)) {
+ String *ss = (String *) ObjData(str);
+ newstr = (char *) String_data((DOH *) str);
+ l = ss->len;
+ } else {
+ newstr = (char *) (str);
+ l = (int) strlen(newstr);
+ }
+ if (!newstr)
+ return;
+ s->hashkey = -1;
+
+ oldlen = s->len;
+ newlen = oldlen + l + 1;
+ if (newlen >= s->maxsize - 1) {
+ newmaxsize = 2 * s->maxsize;
+ if (newlen >= newmaxsize - 1)
+ newmaxsize = newlen + 1;
+ s->str = (char *) DohRealloc(s->str, newmaxsize);
+ assert(s->str);
+ s->maxsize = newmaxsize;
+ }
+ tc = s->str;
+ memcpy(tc + oldlen, newstr, l + 1);
+ sp = s->sp;
+ if (sp >= oldlen) {
+ int i = oldlen + l - sp;
+ tc += sp;
+ for (; i; --i) {
+ if (*(tc++) == '\n')
+ s->line++;
+ }
+ s->sp = oldlen + l;
+ }
+ s->len += l;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * void String_clear() - Clear a string
+ * ----------------------------------------------------------------------------- */
+
+static void String_clear(DOH *so) {
+ String *s = (String *) ObjData(so);
+ s->hashkey = -1;
+ s->len = 0;
+ *(s->str) = 0;
+ s->sp = 0;
+ s->line = 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * void String_insert() - Insert a string
+ * ----------------------------------------------------------------------------- */
+
+static int String_insert(DOH *so, int pos, DOH *str) {
+ String *s;
+ char *nstr;
+ int len;
+ char *data;
+
+ if (pos == DOH_END) {
+ DohString_append(so, str);
+ return 0;
+ }
+
+
+ s = (String *) ObjData(so);
+ s->hashkey = -1;
+ if (DohCheck(str)) {
+ String *ss = (String *) ObjData(str);
+ data = (char *) String_data(str);
+ len = ss->len;
+ } else {
+ data = (char *) (str);
+ len = (int) strlen(data);
+ }
+ nstr = s->str;
+
+ if (pos < 0)
+ pos = 0;
+ else if (pos > s->len)
+ pos = s->len;
+
+ /* See if there is room to insert the new data */
+ while (s->maxsize <= s->len + len) {
+ int newsize = 2 * s->maxsize;
+ s->str = (char *) DohRealloc(s->str, newsize);
+ assert(s->str);
+ s->maxsize = newsize;
+ }
+ memmove(s->str + pos + len, s->str + pos, (s->len - pos));
+ memcpy(s->str + pos, data, len);
+ if (s->sp >= pos) {
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (data[i] == '\n')
+ s->line++;
+ }
+ s->sp += len;
+ }
+ s->len += len;
+ s->str[s->len] = 0;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_delitem() - Delete a character
+ * ----------------------------------------------------------------------------- */
+
+static int String_delitem(DOH *so, int pos) {
+ String *s = (String *) ObjData(so);
+ s->hashkey = -1;
+ if (pos == DOH_END)
+ pos = s->len - 1;
+ if (pos == DOH_BEGIN)
+ pos = 0;
+ if (s->len == 0)
+ return 0;
+
+ if (s->sp > pos) {
+ s->sp--;
+ assert(s->sp >= 0);
+ if (s->str[pos] == '\n')
+ s->line--;
+ }
+ memmove(s->str + pos, s->str + pos + 1, ((s->len - 1) - pos));
+ s->len--;
+ s->str[s->len] = 0;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_delslice() - Delete a range
+ * ----------------------------------------------------------------------------- */
+
+static int String_delslice(DOH *so, int sindex, int eindex) {
+ String *s = (String *) ObjData(so);
+ int size;
+ if (s->len == 0)
+ return 0;
+ s->hashkey = -1;
+ if (eindex == DOH_END)
+ eindex = s->len;
+ if (sindex == DOH_BEGIN)
+ sindex = 0;
+
+ size = eindex - sindex;
+ if (s->sp > sindex) {
+ /* Adjust the file pointer and line count */
+ int i, end;
+ if (s->sp > eindex) {
+ end = eindex;
+ s->sp -= size;
+ } else {
+ end = s->sp;
+ s->sp = sindex;
+ }
+ for (i = sindex; i < end; i++) {
+ if (s->str[i] == '\n')
+ s->line--;
+ }
+ assert(s->sp >= 0);
+ }
+ memmove(s->str + sindex, s->str + eindex, s->len - eindex);
+ s->len -= size;
+ s->str[s->len] = 0;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * DOH *String_str() - Returns a string (used by printing commands)
+ * ----------------------------------------------------------------------------- */
+
+static DOH *String_str(DOH *so) {
+ String *s = (String *) ObjData(so);
+ s->str[s->len] = 0;
+ return NewString(s->str);
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_read() - Read data from a string
+ * ----------------------------------------------------------------------------- */
+
+static int String_read(DOH *so, void *buffer, int len) {
+ int reallen, retlen;
+ char *cb;
+ String *s = (String *) ObjData(so);
+ if ((s->sp + len) > s->len)
+ reallen = (s->len - s->sp);
+ else
+ reallen = len;
+
+ cb = (char *) buffer;
+ retlen = reallen;
+
+ if (reallen > 0) {
+ memmove(cb, s->str + s->sp, reallen);
+ s->sp += reallen;
+ }
+ return retlen;
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_write() - Write data to a string
+ * ----------------------------------------------------------------------------- */
+static int String_write(DOH *so, void *buffer, int len) {
+ int newlen;
+ String *s = (String *) ObjData(so);
+ s->hashkey = -1;
+ if (s->sp > s->len)
+ s->sp = s->len;
+ newlen = s->sp + len + 1;
+ if (newlen > s->maxsize) {
+ s->str = (char *) DohRealloc(s->str, newlen);
+ assert(s->str);
+ s->maxsize = newlen;
+ s->len = s->sp + len;
+ }
+ if ((s->sp + len) > s->len)
+ s->len = s->sp + len;
+ memmove(s->str + s->sp, buffer, len);
+ s->sp += len;
+ s->str[s->len] = 0;
+ return len;
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_seek() - Seek to a new position
+ * ----------------------------------------------------------------------------- */
+
+static int String_seek(DOH *so, long offset, int whence) {
+ int pos, nsp, inc;
+ String *s = (String *) ObjData(so);
+ if (whence == SEEK_SET)
+ pos = 0;
+ else if (whence == SEEK_CUR)
+ pos = s->sp;
+ else if (whence == SEEK_END) {
+ pos = s->len;
+ offset = -offset;
+ } else
+ pos = s->sp;
+
+ nsp = pos + offset;
+ if (nsp < 0)
+ nsp = 0;
+ if (s->len > 0 && nsp > s->len)
+ nsp = s->len;
+
+ inc = (nsp > s->sp) ? 1 : -1;
+
+ {
+#if 0
+ register int sp = s->sp;
+ register char *tc = s->str;
+ register int len = s->len;
+ while (sp != nsp) {
+ int prev = sp + inc;
+ if (prev >= 0 && prev <= len && tc[prev] == '\n')
+ s->line += inc;
+ sp += inc;
+ }
+#else
+ register int sp = s->sp;
+ register char *tc = s->str;
+ if (inc > 0) {
+ while (sp != nsp) {
+ if (tc[++sp] == '\n')
+ ++s->line;
+ }
+ } else {
+ while (sp != nsp) {
+ if (tc[--sp] == '\n')
+ --s->line;
+ }
+ }
+#endif
+ s->sp = sp;
+ }
+ assert(s->sp >= 0);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * long String_tell() - Return current position
+ * ----------------------------------------------------------------------------- */
+
+static long String_tell(DOH *so) {
+ String *s = (String *) ObjData(so);
+ return (long) (s->sp);
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_putc()
+ * ----------------------------------------------------------------------------- */
+
+static int String_putc(DOH *so, int ch) {
+ String *s = (String *) ObjData(so);
+ register int len = s->len;
+ register int sp = s->sp;
+ s->hashkey = -1;
+ if (sp >= len) {
+ register int maxsize = s->maxsize;
+ register char *tc = s->str;
+ if (len > (maxsize - 2)) {
+ maxsize *= 2;
+ tc = (char *) DohRealloc(tc, maxsize);
+ assert(tc);
+ s->maxsize = (int) maxsize;
+ s->str = tc;
+ }
+ tc += sp;
+ *tc = (char) ch;
+ *(++tc) = 0;
+ s->len = s->sp = sp + 1;
+ } else {
+ s->str[s->sp++] = (char) ch;
+ }
+ if (ch == '\n')
+ s->line++;
+ return ch;
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_getc()
+ * ----------------------------------------------------------------------------- */
+
+static int String_getc(DOH *so) {
+ int c;
+ String *s = (String *) ObjData(so);
+ if (s->sp >= s->len)
+ c = EOF;
+ else
+ c = (int)(unsigned char) s->str[s->sp++];
+ if (c == '\n')
+ s->line++;
+ return c;
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_ungetc()
+ * ----------------------------------------------------------------------------- */
+
+static int String_ungetc(DOH *so, int ch) {
+ String *s = (String *) ObjData(so);
+ if (ch == EOF)
+ return ch;
+ if (s->sp <= 0)
+ return EOF;
+ s->sp--;
+ if (ch == '\n')
+ s->line--;
+ return ch;
+}
+
+/* -----------------------------------------------------------------------------
+ * replace_simple(String *str, char *token, char *rep, int flags, int count)
+ *
+ * Replaces count non-overlapping occurrences of token with rep in a string.
+ * ----------------------------------------------------------------------------- */
+
+static char *end_quote(char *s) {
+ char *qs;
+ char qc;
+ char *q;
+ char *nl;
+ qc = *s;
+ qs = s;
+ while (1) {
+ q = strpbrk(s + 1, "\"\'");
+ nl = strchr(s + 1, '\n');
+ if (nl && (nl < q)) {
+ /* A new line appears before the end of the string */
+ if (*(nl - 1) == '\\') {
+ s = nl + 1;
+ continue;
+ }
+ /* String was terminated by a newline. Wing it */
+ return qs;
+ }
+ if (!q && nl) {
+ return qs;
+ }
+ if (!q)
+ return 0;
+ if ((*q == qc) && (*(q - 1) != '\\'))
+ return q;
+ s = q;
+ }
+}
+
+static char *match_simple(char *base, char *s, char *token, int tokenlen) {
+ (void) base;
+ (void) tokenlen;
+ return strstr(s, token);
+}
+
+static char *match_identifier(char *base, char *s, char *token, int tokenlen) {
+ while (s) {
+ s = strstr(s, token);
+ if (!s)
+ return 0;
+ if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) {
+ s += tokenlen;
+ continue;
+ }
+ if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) {
+ s += tokenlen;
+ continue;
+ }
+ return s;
+ }
+ return 0;
+}
+
+
+static char *match_identifier_begin(char *base, char *s, char *token, int tokenlen) {
+ while (s) {
+ s = strstr(s, token);
+ if (!s)
+ return 0;
+ if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) {
+ s += tokenlen;
+ continue;
+ }
+ return s;
+ }
+ return 0;
+}
+
+static char *match_identifier_end(char *base, char *s, char *token, int tokenlen) {
+ (void) base;
+ while (s) {
+ s = strstr(s, token);
+ if (!s)
+ return 0;
+ if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) {
+ s += tokenlen;
+ continue;
+ }
+ return s;
+ }
+ return 0;
+}
+
+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 */
+ int delta, expand = 0;
+ int ic;
+ int rcount = 0;
+ int noquote = 0;
+ char *c, *s, *t, *first;
+ char *q, *q2;
+ register char *base;
+ int i;
+
+ /* Figure out if anything gets replaced */
+ if (!strlen(token))
+ return 0;
+
+ base = str->str;
+ tokenlen = strlen(token);
+ s = (*match) (base, base, token, tokenlen);
+
+ if (!s)
+ return 0; /* No matches. Who cares */
+
+ str->hashkey = -1;
+
+ if (flags & DOH_REPLACE_NOQUOTE)
+ noquote = 1;
+
+ /* If we are not replacing inside quotes, we need to do a little extra work */
+ if (noquote) {
+ q = strpbrk(base, "\"\'");
+ if (!q) {
+ noquote = 0; /* Well, no quotes to worry about. Oh well */
+ } else {
+ while (q && (q < s)) {
+ /* First match was found inside a quote. Try to find another match */
+ q2 = end_quote(q);
+ if (!q2) {
+ return 0;
+ }
+ if (q2 > s) {
+ /* Find next match */
+ s = (*match) (base, q2 + 1, token, tokenlen);
+ }
+ if (!s)
+ return 0; /* Oh well, no matches */
+ q = strpbrk(q2 + 1, "\"\'");
+ if (!q)
+ noquote = 0; /* No more quotes */
+ }
+ }
+ }
+
+ first = s;
+ replen = strlen(rep);
+
+ delta = (replen - tokenlen);
+
+ if (delta <= 0) {
+ /* String is either shrinking or staying the same size */
+ /* In this case, we do the replacement in place without memory reallocation */
+ ic = count;
+ t = s; /* Target of memory copies */
+ while (ic && s) {
+ if (replen) {
+ memcpy(t, rep, replen);
+ t += replen;
+ }
+ rcount++;
+ expand += delta;
+ /* Find the next location */
+ s += tokenlen;
+ if (ic == 1)
+ break;
+ c = (*match) (base, s, token, tokenlen);
+
+ if (noquote) {
+ q = strpbrk(s, "\"\'");
+ if (!q) {
+ noquote = 0;
+ } else {
+ while (q && (q < c)) {
+ /* First match was found inside a quote. Try to find another match */
+ q2 = end_quote(q);
+ if (!q2) {
+ c = 0;
+ break;
+ }
+ if (q2 > c)
+ c = (*match) (base, q2 + 1, token, tokenlen);
+ if (!c)
+ break;
+ q = strpbrk(q2 + 1, "\"\'");
+ if (!q)
+ noquote = 0; /* No more quotes */
+ }
+ }
+ }
+ if (delta) {
+ if (c) {
+ memmove(t, s, c - s);
+ t += (c - s);
+ } else {
+ memmove(t, s, (str->str + str->len) - s + 1);
+ }
+ } else {
+ t += (c - s);
+ }
+ s = c;
+ ic--;
+ }
+ if (s && delta) {
+ memmove(t, s, (str->str + str->len) - s + 1);
+ }
+ str->len += expand;
+ str->str[str->len] = 0;
+ if (str->sp >= str->len)
+ str->sp += expand; /* Fix the end of file pointer */
+ return rcount;
+ }
+ /* The string is expanding as a result of the replacement */
+ /* Figure out how much expansion is going to occur and allocate a new string */
+ {
+ char *ns;
+ int newsize;
+
+ rcount++;
+ ic = count - 1;
+ s += tokenlen;
+ while (ic && (c = (*match) (base, s, token, tokenlen))) {
+ if (noquote) {
+ q = strpbrk(s, "\"\'");
+ if (!q) {
+ break;
+ } else {
+ while (q && (q < c)) {
+ /* First match was found inside a quote. Try to find another match */
+ q2 = end_quote(q);
+ if (!q2) {
+ c = 0;
+ break;
+ }
+ if (q2 > c) {
+ c = (*match) (base, q2 + 1, token, tokenlen);
+ if (!c)
+ break;
+ }
+ q = strpbrk(q2 + 1, "\"\'");
+ if (!q)
+ noquote = 0;
+ }
+ }
+ }
+ if (c) {
+ rcount++;
+ ic--;
+ s = c + tokenlen;
+ } else {
+ break;
+ }
+ }
+
+ expand = delta * rcount; /* Total amount of expansion for the replacement */
+ newsize = str->maxsize;
+ while ((str->len + expand) >= newsize)
+ newsize *= 2;
+
+ ns = (char *) DohMalloc(newsize);
+ assert(ns);
+ t = ns;
+ s = first;
+
+ /* Copy the first part of the string */
+ if (first > str->str) {
+ memcpy(t, str->str, (first - str->str));
+ t += (first - str->str);
+ }
+ for (i = 0; i < rcount; i++) {
+ memcpy(t, rep, replen);
+ t += replen;
+ s += tokenlen;
+ c = (*match) (base, s, token, tokenlen);
+ if (noquote) {
+ q = strpbrk(s, "\"\'");
+ if (!q) {
+ noquote = 0;
+ } else {
+ while (q && (q < c)) {
+ /* First match was found inside a quote. Try to find another match */
+ q2 = end_quote(q);
+ if (!q2) {
+ c = 0;
+ break;
+ }
+ if (q2 > c) {
+ c = (*match) (base, q2 + 1, token, tokenlen);
+ if (!c)
+ break;
+ }
+ q = strpbrk(q2 + 1, "\"\'");
+ if (!q)
+ noquote = 0; /* No more quotes */
+ }
+ }
+ }
+ if (i < (rcount - 1)) {
+ memcpy(t, s, c - s);
+ t += (c - s);
+ } else {
+ memcpy(t, s, (str->str + str->len) - s + 1);
+ }
+ s = c;
+ }
+ c = str->str;
+ str->str = ns;
+ if (str->sp >= str->len)
+ str->sp += expand;
+ str->len += expand;
+ str->str[str->len] = 0;
+ str->maxsize = newsize;
+ DohFree(c);
+ return rcount;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * int String_replace()
+ * ----------------------------------------------------------------------------- */
+
+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_END) {
+ return replace_simple(str, Char(token), Char(rep), flags, count, match_identifier_end);
+ } else if (flags & DOH_REPLACE_ID_BEGIN) {
+ return replace_simple(str, Char(token), Char(rep), flags, count, match_identifier_begin);
+ } else if (flags & DOH_REPLACE_ID) {
+ return replace_simple(str, Char(token), Char(rep), flags, count, match_identifier);
+ } else {
+ return replace_simple(str, Char(token), Char(rep), flags, count, match_simple);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * void String_chop(DOH *str)
+ * ----------------------------------------------------------------------------- */
+
+static void String_chop(DOH *so) {
+ char *c;
+ String *str = (String *) ObjData(so);
+ /* Replace trailing whitespace */
+ c = str->str + str->len - 1;
+ while ((str->len > 0) && (isspace((int) *c))) {
+ if (str->sp >= str->len) {
+ str->sp--;
+ if (*c == '\n')
+ str->line--;
+ }
+ str->len--;
+ c--;
+ }
+ str->str[str->len] = 0;
+ assert(str->sp >= 0);
+ str->hashkey = -1;
+}
+
+static void String_setfile(DOH *so, DOH *file) {
+ DOH *fo;
+ String *str = (String *) ObjData(so);
+
+ if (!DohCheck(file)) {
+ fo = NewString(file);
+ Decref(fo);
+ } else
+ fo = file;
+ Incref(fo);
+ Delete(str->file);
+ str->file = fo;
+}
+
+static DOH *String_getfile(DOH *so) {
+ String *str = (String *) ObjData(so);
+ return str->file;
+}
+
+static void String_setline(DOH *so, int line) {
+ String *str = (String *) ObjData(so);
+ str->line = line;
+}
+
+static int String_getline(DOH *so) {
+ String *str = (String *) ObjData(so);
+ return str->line;
+}
+
+static DohListMethods StringListMethods = {
+ 0, /* doh_getitem */
+ 0, /* doh_setitem */
+ String_delitem, /* doh_delitem */
+ String_insert, /* doh_insitem */
+ String_delslice, /* doh_delslice */
+};
+
+static DohFileMethods StringFileMethods = {
+ String_read,
+ String_write,
+ String_putc,
+ String_getc,
+ String_ungetc,
+ String_seek,
+ String_tell,
+ 0, /* close */
+};
+
+static DohStringMethods StringStringMethods = {
+ String_replace,
+ String_chop,
+};
+
+DohObjInfo DohStringType = {
+ "String", /* objname */
+ DelString, /* doh_del */
+ CopyString, /* doh_copy */
+ String_clear, /* doh_clear */
+ String_str, /* doh_str */
+ String_data, /* doh_data */
+ String_dump, /* doh_dump */
+ String_len, /* doh_len */
+ String_hash, /* doh_hash */
+ String_cmp, /* doh_cmp */
+ String_equal, /* doh_equal */
+ 0, /* doh_first */
+ 0, /* doh_next */
+ String_setfile, /* doh_setfile */
+ String_getfile, /* doh_getfile */
+ String_setline, /* doh_setline */
+ String_getline, /* doh_getline */
+ 0, /* doh_mapping */
+ &StringListMethods, /* doh_sequence */
+ &StringFileMethods, /* doh_file */
+ &StringStringMethods, /* doh_string */
+ 0, /* doh_position */
+ 0
+};
+
+
+#define INIT_MAXSIZE 16
+
+/* -----------------------------------------------------------------------------
+ * NewString(const char *c) - Create a new string
+ * ----------------------------------------------------------------------------- */
+
+DOHString *DohNewString(const DOH *so) {
+ int l = 0, max;
+ String *str;
+ char *s;
+ int hashkey = -1;
+ if (DohCheck(so)) {
+ str = (String *) ObjData(so);
+ s = (char *) String_data((String *) so);
+ l = s ? str->len : 0;
+ hashkey = str->hashkey;
+ } else {
+ s = (char *) so;
+ l = s ? (int) strlen(s) : 0;
+ }
+
+ str = (String *) DohMalloc(sizeof(String));
+ str->hashkey = hashkey;
+ str->sp = 0;
+ str->line = 1;
+ str->file = 0;
+ max = INIT_MAXSIZE;
+ if (s) {
+ if ((l + 1) > max)
+ max = l + 1;
+ }
+ str->str = (char *) DohMalloc(max);
+ str->maxsize = max;
+ if (s) {
+ strcpy(str->str, s);
+ str->len = l;
+ str->sp = l;
+ } else {
+ str->str[0] = 0;
+ str->len = 0;
+ }
+ return DohObjMalloc(&DohStringType, str);
+}
+
+
+/* -----------------------------------------------------------------------------
+ * NewStringEmpty() - Create a new string
+ * ----------------------------------------------------------------------------- */
+
+DOHString *DohNewStringEmpty(void) {
+ int max = INIT_MAXSIZE;
+ String *str = (String *) DohMalloc(sizeof(String));
+ str->hashkey = 0;
+ str->sp = 0;
+ str->line = 1;
+ str->file = 0;
+ str->str = (char *) DohMalloc(max);
+ str->maxsize = max;
+ str->str[0] = 0;
+ str->len = 0;
+ return DohObjMalloc(&DohStringType, str);
+}
+
+/* -----------------------------------------------------------------------------
+ * NewStringWithSize(const char *c, int len) - Create a new string
+ * ----------------------------------------------------------------------------- */
+
+DOHString *DohNewStringWithSize(const DOH *so, int len) {
+ int l = 0, max;
+ String *str;
+ char *s;
+ if (DohCheck(so)) {
+ s = (char *) String_data((String *) so);
+ } else {
+ s = (char *) so;
+ }
+
+ str = (String *) DohMalloc(sizeof(String));
+ str->hashkey = -1;
+ str->sp = 0;
+ str->line = 1;
+ str->file = 0;
+ max = INIT_MAXSIZE;
+ if (s) {
+ l = (int) len;
+ if ((l + 1) > max)
+ max = l + 1;
+ }
+ str->str = (char *) DohMalloc(max);
+ str->maxsize = max;
+ if (s) {
+ strncpy(str->str, s, len);
+ str->len = l;
+ str->sp = l;
+ } else {
+ str->str[0] = 0;
+ str->len = 0;
+ }
+ return DohObjMalloc(&DohStringType, str);
+}
+
+/* -----------------------------------------------------------------------------
+ * NewStringf(DOH *fmt, ...)
+ *
+ * Create a new string from a list of objects.
+ * ----------------------------------------------------------------------------- */
+
+DOHString *DohNewStringf(const DOH *fmt, ...) {
+ va_list ap;
+ DOH *r;
+ va_start(ap, fmt);
+ r = NewStringEmpty();
+ DohvPrintf(r, Char(fmt), ap);
+ 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) {
+ const char *c1 = Char(s1);
+ const char *c2 = Char(s2);
+ if (c1 && c2) {
+ return strcmp(c1, c2);
+ } else {
+ return c1 < c2;
+ }
+}
+
+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) {
+ char *p1 = Char(s1);
+ char *p2 = Char(s2);
+ return p1 == 0 || p2 == 0 || *p2 == '\0' ? p1 : strstr(p1, p2);
+}
+
+char *DohStrchr(const DOHString_or_char *s1, int ch) {
+ return strchr(Char(s1), ch);
+}
diff --git a/Source/DOH/void.c b/Source/DOH/void.c
new file mode 100644
index 0000000..ed34da1
--- /dev/null
+++ b/Source/DOH/void.c
@@ -0,0 +1,96 @@
+/* -----------------------------------------------------------------------------
+ * void.c
+ *
+ * Implements a "void" object that is really just a DOH container around
+ * an arbitrary C object represented as a void *.
+ *
+ * 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_void_c[] = "$Id: void.c 9607 2006-12-05 22:11:40Z beazley $";
+
+#include "dohint.h"
+
+typedef struct {
+ void *ptr;
+ void (*del) (void *);
+} VoidObj;
+
+/* -----------------------------------------------------------------------------
+ * Void_delete()
+ *
+ * Delete a void object. Invokes the destructor supplied at the time of creation.
+ * ----------------------------------------------------------------------------- */
+
+static void Void_delete(DOH *vo) {
+ VoidObj *v = (VoidObj *) ObjData(vo);
+ if (v->del)
+ (*v->del) (v->ptr);
+ DohFree(v);
+}
+
+/* -----------------------------------------------------------------------------
+ * Void_copy()
+ *
+ * Copies a void object. This is only a shallow copy. The object destruction
+ * function is not copied in order to avoid potential double-free problems.
+ * ----------------------------------------------------------------------------- */
+
+static DOH *Void_copy(DOH *vo) {
+ VoidObj *v = (VoidObj *) ObjData(vo);
+ return NewVoid(v->ptr, 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * Void_data()
+ *
+ * Returns the void * stored in the object.
+ * ----------------------------------------------------------------------------- */
+
+static void *Void_data(DOH *vo) {
+ VoidObj *v = (VoidObj *) ObjData(vo);
+ return v->ptr;
+}
+
+static DohObjInfo DohVoidType = {
+ "VoidObj", /* objname */
+ Void_delete, /* doh_del */
+ Void_copy, /* doh_copy */
+ 0, /* doh_clear */
+ 0, /* doh_str */
+ Void_data, /* doh_data */
+ 0, /* doh_dump */
+ 0, /* doh_len */
+ 0, /* doh_hash */
+ 0, /* doh_cmp */
+ 0, /* doh_equal */
+ 0, /* doh_first */
+ 0, /* doh_next */
+ 0, /* doh_setfile */
+ 0, /* doh_getfile */
+ 0, /* doh_setline */
+ 0, /* doh_getline */
+ 0, /* doh_mapping */
+ 0, /* doh_sequence */
+ 0, /* doh_file */
+ 0, /* doh_string */
+ 0, /* doh_reserved */
+ 0, /* clientdata */
+};
+
+/* -----------------------------------------------------------------------------
+ * NewVoid()
+ *
+ * Creates a new Void object given a void * and an optional destructor function.
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohNewVoid(void *obj, void (*del) (void *)) {
+ VoidObj *v;
+ v = (VoidObj *) DohMalloc(sizeof(VoidObj));
+ v->ptr = obj;
+ v->del = del;
+ return DohObjMalloc(&DohVoidType, v);
+}
diff --git a/Source/Include/swigconfig.h.in b/Source/Include/swigconfig.h.in
new file mode 100644
index 0000000..7b1a023
--- /dev/null
+++ b/Source/Include/swigconfig.h.in
@@ -0,0 +1,93 @@
+/* Source/Include/swigconfig.h.in. Generated from configure.in by autoheader. */
+
+/* Define to 1 if the system has the type `bool'. */
+#undef HAVE_BOOL
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the `dld' library (-ldld). */
+#undef HAVE_LIBDLD
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if popen is available */
+#undef HAVE_POPEN
+
+/* Define if rxspencer is available */
+#undef HAVE_RXSPENCER
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Compiler that built SWIG */
+#undef SWIG_CXX
+
+/* Directory for SWIG system-independent libraries */
+#undef SWIG_LIB
+
+/* Directory for SWIG system-independent libraries (Unix install on native
+ Windows) */
+#undef SWIG_LIB_WIN_UNIX
+
+/* Platform that SWIG is built for */
+#undef SWIG_PLATFORM
+
+/* Version number of package */
+#undef VERSION
+
+
+/* Default language */
+#define SWIG_LANG "-tcl"
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if defined(_MSC_VER)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h
new file mode 100644
index 0000000..194cf49
--- /dev/null
+++ b/Source/Include/swigwarn.h
@@ -0,0 +1,261 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * swigwarn.h
+ *
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: swigwarn.h 11459 2009-07-28 11:47:36Z vmiklos $ */
+
+#ifndef SWIGWARN_H_
+#define SWIGWARN_H_
+
+#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
+#define WARN_DEPRECATED_OPTC 120
+#define WARN_DEPRECATED_NAME 121
+#define WARN_DEPRECATED_NOEXTERN 122
+#define WARN_DEPRECATED_NODEFAULT 123
+#define WARN_DEPRECATED_TYPEMAP_LANG 124
+#define WARN_DEPRECATED_INPUT_FILE 125
+
+/* -- Preprocessor -- */
+
+#define WARN_PP_MISSING_FILE 201
+#define WARN_PP_EVALUATION 202
+#define WARN_PP_INCLUDEALL_IMPORTALL 203
+#define WARN_PP_CPP_WARNING 204
+#define WARN_PP_CPP_ERROR 205
+
+/* -- 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_PARSE_EXPLICIT_TEMPLATE 320
+#define WARN_PARSE_BUILTIN_NAME 321
+#define WARN_PARSE_REDUNDANT 322
+#define WARN_PARSE_REC_INHERITANCE 323
+
+#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_OPERATOR_DELARR 395 /* delete [] */
+#define WARN_IGNORE_OPERATOR_REF 396 /* operator *() */
+
+/* 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_SWIGTYPELEAK 454
+
+#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
+#define WARN_TYPEMAP_DIRECTORIN_UNDEF 469
+#define WARN_TYPEMAP_THREAD_UNSAFE 470 /* mostly used in directorout typemaps */
+#define WARN_TYPEMAP_DIRECTOROUT_UNDEF 471
+#define WARN_TYPEMAP_TYPECHECK_UNDEF 472
+#define WARN_TYPEMAP_DIRECTOROUT_PTR 473
+#define WARN_TYPEMAP_OUT_OPTIMAL_IGNORED 474
+#define WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE 475
+
+/* -- Fragments -- */
+#define WARN_FRAGMENT_NOT_FOUND 490
+
+/* -- 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
+#define WARN_LANG_DIRECTOR_VDESTRUCT 514
+#define WARN_LANG_DISCARD_CONST 515
+#define WARN_LANG_OVERLOAD_IGNORED 516
+#define WARN_LANG_DIRECTOR_ABSTRACT 517
+#define WARN_LANG_PORTABILITY_FILENAME 518
+#define WARN_LANG_TEMPLATE_METHOD_IGNORE 519
+
+/* -- 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_JAVABODY_UNDEF 816
+#define WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF 817
+#define WARN_JAVA_TYPEMAP_JAVAIN_UNDEF 818
+#define WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF 819
+#define WARN_JAVA_TYPEMAP_JAVADIRECTOROUT_UNDEF 820
+#define WARN_JAVA_COVARIANT_RET 822
+#define WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF 823
+#define WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC 824
+#define WARN_JAVA_NO_DIRECTORCONNECT_ATTR 825
+
+/* please leave 810-829 free for Java */
+
+#define WARN_CSHARP_TYPEMAP_CTYPE_UNDEF 830
+#define WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF 831
+#define WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF 832
+#define WARN_CSHARP_MULTIPLE_INHERITANCE 833
+#define WARN_CSHARP_TYPEMAP_GETCPTR_UNDEF 834
+#define WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF 835
+#define WARN_CSHARP_TYPEMAP_CSBODY_UNDEF 836
+#define WARN_CSHARP_TYPEMAP_CSOUT_UNDEF 837
+#define WARN_CSHARP_TYPEMAP_CSIN_UNDEF 838
+#define WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF 839
+#define WARN_CSHARP_TYPEMAP_CSDIRECTOROUT_UNDEF 840
+#define WARN_CSHARP_COVARIANT_RET 842
+#define WARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF 843
+#define WARN_CSHARP_EXCODE 844
+#define WARN_CSHARP_CANTHROW 845
+#define WARN_CSHARP_NO_DIRECTORCONNECT_ATTR 846
+
+/* please leave 830-849 free for C# */
+
+#define WARN_MODULA3_TYPEMAP_TYPE_UNDEF 850
+#define WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF 851
+#define WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF 852
+#define WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF 853
+#define WARN_MODULA3_TYPEMAP_MULTIPLE_RETURN 854
+#define WARN_MODULA3_MULTIPLE_INHERITANCE 855
+#define WARN_MODULA3_TYPECONSTRUCTOR_UNKNOWN 856
+#define WARN_MODULA3_UNKNOWN_PRAGMA 857
+#define WARN_MODULA3_BAD_ENUMERATION 858
+#define WARN_MODULA3_DOUBLE_ID 859
+#define WARN_MODULA3_BAD_IMPORT 860
+
+/* please leave 850-869 free for Modula 3 */
+
+#define WARN_PHP_MULTIPLE_INHERITANCE 870
+#define WARN_PHP_UNKNOWN_PRAGMA 871
+#define WARN_PHP_PUBLIC_BASE 872
+
+/* please leave 870-889 free for PHP */
+
+
+/* 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/Makefile.am b/Source/Makefile.am
new file mode 100644
index 0000000..aadf50d
--- /dev/null
+++ b/Source/Makefile.am
@@ -0,0 +1,144 @@
+## Process this file with automake to produce Makefile.in
+
+# subdir-objects generates object files using the directory structure of the source files.
+AUTOMAKE_OPTIONS = foreign nostdinc subdir-objects 1.7.2
+
+SOURCE_DIR=$(top_srcdir)/Source
+BUILD_SOURCE_DIR=$(top_builddir)/Source
+
+SWIG_CXX_DEFS = @SWILL@
+
+AM_CPPFLAGS = -I$(BUILD_SOURCE_DIR)/Include \
+ -I$(BUILD_SOURCE_DIR)/CParse \
+ -I$(SOURCE_DIR)/Include \
+ -I$(SOURCE_DIR)/DOH \
+ -I$(SOURCE_DIR)/CParse \
+ -I$(SOURCE_DIR)/Preprocessor \
+ -I$(SOURCE_DIR)/Swig \
+ -I$(SOURCE_DIR)/Modules
+
+AM_CXXFLAGS = $(SWIG_CXX_DEFS)
+
+AM_YFLAGS = -d
+
+BUILT_SOURCES = CParse/parser.h
+eswig_SOURCES = CParse/cscanner.c \
+ CParse/parser.y \
+ CParse/templ.c \
+ CParse/util.c \
+ DOH/base.c \
+ DOH/file.c \
+ DOH/fio.c \
+ DOH/hash.c \
+ DOH/list.c \
+ DOH/memory.c \
+ DOH/string.c \
+ DOH/void.c \
+ Modules/allegrocl.cxx \
+ Modules/allocate.cxx \
+ Modules/browser.cxx \
+ Modules/cffi.cxx \
+ Modules/chicken.cxx \
+ Modules/clisp.cxx \
+ Modules/contract.cxx \
+ Modules/csharp.cxx \
+ Modules/directors.cxx \
+ Modules/emit.cxx \
+ Modules/guile.cxx \
+ Modules/java.cxx \
+ Modules/lang.cxx \
+ Modules/lua.cxx \
+ Modules/main.cxx \
+ Modules/modula3.cxx \
+ Modules/module.cxx \
+ Modules/mzscheme.cxx \
+ Modules/ocaml.cxx \
+ Modules/octave.cxx \
+ Modules/overload.cxx \
+ Modules/perl5.cxx \
+ Modules/php.cxx \
+ Modules/pike.cxx \
+ Modules/python.cxx \
+ Modules/r.cxx \
+ Modules/ruby.cxx \
+ Modules/s-exp.cxx \
+ Modules/swigmain.cxx \
+ Modules/tcl8.cxx \
+ Modules/typepass.cxx \
+ Modules/uffi.cxx \
+ Modules/utils.cxx \
+ Modules/xml.cxx \
+ Preprocessor/cpp.c \
+ Preprocessor/expr.c \
+ Swig/cwrap.c \
+ Swig/deprecate.c \
+ Swig/error.c \
+ Swig/fragment.c \
+ Swig/getopt.c \
+ Swig/include.c \
+ Swig/misc.c \
+ Swig/naming.c \
+ Swig/parms.c \
+ Swig/scanner.c \
+ Swig/stype.c \
+ Swig/symbol.c \
+ Swig/tree.c \
+ Swig/typeobj.c \
+ Swig/typemap.c \
+ Swig/typesys.c \
+ Swig/warn.c \
+ Swig/wrapfunc.c
+
+bin_PROGRAMS = eswig
+eswig_LDADD = @SWIGLIBS@
+
+# Override the link stage to avoid using Libtool
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+
+# The executable is copied to the root directory for installation and running the test-suite.
+# This occurs on each invocation of make and is a step towards providing support for multiple
+# build directories.
+all-local: eswig@EXEEXT@
+ cp -f $(top_builddir)/Source/eswig@EXEEXT@ $(top_builddir)/swig@EXEEXT@
+
+clean-local:
+ rm -f $(top_builddir)/swig@EXEEXT@
+ rm -f core @EXTRA_CLEAN@
+
+
+# Beautify the code.
+# Note that this works well on C code, but does some odd joining of lines for C++ code.
+# Compiling with -DNDEBUG and no optimisations will allow one to do a binary diff of the
+# swig executable as a way of checking before and after the 'beautifying'.
+# Single files can be beautified with the beautify-file target, eg: 'make beautify-file INDENTFILE=chosenfile.c'
+
+SWIGTYPEDEFS=-T File -T DohObjInfo -T Parm -T Language -T List -T Typetab -T ModuleFactory -T ErrorMessageFormat -T Symtab -T Hash -T String -T DohBase -T Node -T String_or_char -T SwigType -T Dispatcher -T Wrapper -T DohStringMethods -T DohFileMethods -T DohListMethods -T DohHashMethods -T DOH -T DohIterator -T ParmList -T FILE -T HashNode -T DOHString_or_char
+INDENTBAKSDIR=../IndentBaks
+
+beautify:
+ rm -rf $(INDENTBAKSDIR)
+ mkdir $(INDENTBAKSDIR)
+ mkdir $(INDENTBAKSDIR)/CParse
+ mkdir $(INDENTBAKSDIR)/DOH
+ mkdir $(INDENTBAKSDIR)/Modules
+ mkdir $(INDENTBAKSDIR)/Preprocessor
+ mkdir $(INDENTBAKSDIR)/Swig
+ mkdir $(INDENTBAKSDIR)/Include
+ (csources=`find . -name "*.c"` && \
+ hsources=`find . -name "*.h"` && \
+ cxxsources=`find . -name "*.cxx"` && \
+ for file in $$csources $$hsources $$cxxsources; do \
+ $(MAKE) beautify-file INDENTFILE=$$file; \
+ done; )
+
+beautify-file:
+ test -e $(INDENTBAKSDIR) || (echo $(INDENTBAKSDIR) directory does not exist && exit 1;)
+ test -n "$(INDENTFILE)" || (echo INDENTFILE not defined && exit 1;)
+ test -e $(INDENTFILE) || (echo File does not exist: $(INDENTFILE) && exit 1;)
+ cp $(INDENTFILE) $(INDENTBAKSDIR)/$(INDENTFILE);
+ unix2dos $(INDENTFILE)
+ dos2unix $(INDENTFILE)
+ indent -kr --honour-newlines --line-length160 --indent-level2 --braces-on-func-def-line --leave-optional-blank-lines $(SWIGTYPEDEFS) $(INDENTFILE) -o $(INDENTFILE).tmp;
+ cat $(INDENTFILE).tmp | sed -e 's/const const /const /' > $(INDENTFILE);
+ rm $(INDENTFILE).tmp;
+
diff --git a/Source/Makefile.in b/Source/Makefile.in
new file mode 100644
index 0000000..d165ede
--- /dev/null
+++ b/Source/Makefile.in
@@ -0,0 +1,1072 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = eswig$(EXEEXT)
+subdir = Source
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ CParse/parser.c CParse/parser.h
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = \
+ $(top_srcdir)/Tools/config/ac_compare_version.m4 \
+ $(top_srcdir)/Tools/config/ac_compile_warnings.m4 \
+ $(top_srcdir)/Tools/config/ac_define_dir.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/Source/Include/swigconfig.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_eswig_OBJECTS = CParse/cscanner.$(OBJEXT) CParse/parser.$(OBJEXT) \
+ CParse/templ.$(OBJEXT) CParse/util.$(OBJEXT) \
+ DOH/base.$(OBJEXT) DOH/file.$(OBJEXT) DOH/fio.$(OBJEXT) \
+ DOH/hash.$(OBJEXT) DOH/list.$(OBJEXT) DOH/memory.$(OBJEXT) \
+ DOH/string.$(OBJEXT) DOH/void.$(OBJEXT) \
+ Modules/allegrocl.$(OBJEXT) Modules/allocate.$(OBJEXT) \
+ Modules/browser.$(OBJEXT) Modules/cffi.$(OBJEXT) \
+ Modules/chicken.$(OBJEXT) Modules/clisp.$(OBJEXT) \
+ Modules/contract.$(OBJEXT) Modules/csharp.$(OBJEXT) \
+ Modules/directors.$(OBJEXT) Modules/emit.$(OBJEXT) \
+ Modules/guile.$(OBJEXT) Modules/java.$(OBJEXT) \
+ Modules/lang.$(OBJEXT) Modules/lua.$(OBJEXT) \
+ Modules/main.$(OBJEXT) Modules/modula3.$(OBJEXT) \
+ Modules/module.$(OBJEXT) Modules/mzscheme.$(OBJEXT) \
+ Modules/ocaml.$(OBJEXT) Modules/octave.$(OBJEXT) \
+ Modules/overload.$(OBJEXT) Modules/perl5.$(OBJEXT) \
+ Modules/php.$(OBJEXT) Modules/pike.$(OBJEXT) \
+ Modules/python.$(OBJEXT) Modules/r.$(OBJEXT) \
+ Modules/ruby.$(OBJEXT) Modules/s-exp.$(OBJEXT) \
+ Modules/swigmain.$(OBJEXT) Modules/tcl8.$(OBJEXT) \
+ Modules/typepass.$(OBJEXT) Modules/uffi.$(OBJEXT) \
+ Modules/utils.$(OBJEXT) Modules/xml.$(OBJEXT) \
+ Preprocessor/cpp.$(OBJEXT) Preprocessor/expr.$(OBJEXT) \
+ Swig/cwrap.$(OBJEXT) Swig/deprecate.$(OBJEXT) \
+ Swig/error.$(OBJEXT) Swig/fragment.$(OBJEXT) \
+ Swig/getopt.$(OBJEXT) Swig/include.$(OBJEXT) \
+ Swig/misc.$(OBJEXT) Swig/naming.$(OBJEXT) Swig/parms.$(OBJEXT) \
+ Swig/scanner.$(OBJEXT) Swig/stype.$(OBJEXT) \
+ Swig/symbol.$(OBJEXT) Swig/tree.$(OBJEXT) \
+ Swig/typeobj.$(OBJEXT) Swig/typemap.$(OBJEXT) \
+ Swig/typesys.$(OBJEXT) Swig/warn.$(OBJEXT) \
+ Swig/wrapfunc.$(OBJEXT)
+eswig_OBJECTS = $(am_eswig_OBJECTS)
+eswig_DEPENDENCIES =
+DEFAULT_INCLUDES =
+depcomp = $(SHELL) $(top_srcdir)/Tools/config/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+YLWRAP = $(top_srcdir)/Tools/config/ylwrap
+SOURCES = $(eswig_SOURCES)
+DIST_SOURCES = $(eswig_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLEGROCLBIN = @ALLEGROCLBIN@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CCSHARED = @CCSHARED@
+CFLAGS = @CFLAGS@
+CHICKEN = @CHICKEN@
+CHICKENLIB = @CHICKENLIB@
+CHICKENOPTS = @CHICKENOPTS@
+CHICKENSHAREDLIB = @CHICKENSHAREDLIB@
+CHICKEN_CSC = @CHICKEN_CSC@
+CHICKEN_CSI = @CHICKEN_CSI@
+CLISPBIN = @CLISPBIN@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CSHARPCFLAGS = @CSHARPCFLAGS@
+CSHARPCILINTERPRETER = @CSHARPCILINTERPRETER@
+CSHARPCOMPILER = @CSHARPCOMPILER@
+CSHARPCYGPATH_W = @CSHARPCYGPATH_W@
+CSHARPDYNAMICLINKING = @CSHARPDYNAMICLINKING@
+CSHARPLIBRARYPREFIX = @CSHARPLIBRARYPREFIX@
+CSHARPPATHSEPARATOR = @CSHARPPATHSEPARATOR@
+CSHARPSO = @CSHARPSO@
+CXX = @CXX@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXSHARED = @CXXSHARED@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_CCACHE = @ENABLE_CCACHE@
+EXEEXT = @EXEEXT@
+EXTRA_CLEAN = @EXTRA_CLEAN@
+GCJ = @GCJ@
+GCJH = @GCJH@
+GREP = @GREP@
+GUILE = @GUILE@
+GUILEINCLUDE = @GUILEINCLUDE@
+GUILELIB = @GUILELIB@
+GUILELINK = @GUILELINK@
+GUILE_CONFIG = @GUILE_CONFIG@
+GUILE_GH_INTERFACE = @GUILE_GH_INTERFACE@
+GUILE_SCM_INTERFACE = @GUILE_SCM_INTERFACE@
+GUILE_SO = @GUILE_SO@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+JAVA = @JAVA@
+JAVAC = @JAVAC@
+JAVACFLAGS = @JAVACFLAGS@
+JAVACXXSHARED = @JAVACXXSHARED@
+JAVADYNAMICLINKING = @JAVADYNAMICLINKING@
+JAVAINC = @JAVAINC@
+JAVALDSHARED = @JAVALDSHARED@
+JAVALIBRARYPREFIX = @JAVALIBRARYPREFIX@
+JAVASO = @JAVASO@
+LDFLAGS = @LDFLAGS@
+LDSHARED = @LDSHARED@
+LIBC = @LIBC@
+LIBCRYPT = @LIBCRYPT@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LINKFORSHARED = @LINKFORSHARED@
+LTLIBOBJS = @LTLIBOBJS@
+LUABIN = @LUABIN@
+LUADYNAMICLINKING = @LUADYNAMICLINKING@
+LUAFLAGS = @LUAFLAGS@
+LUALINK = @LUALINK@
+LUA_SO = @LUA_SO@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MZC = @MZC@
+MZDYNOBJ = @MZDYNOBJ@
+MZSCHEME = @MZSCHEME@
+MZSCHEME_SO = @MZSCHEME_SO@
+OBJEXT = @OBJEXT@
+OCAMLBIN = @OCAMLBIN@
+OCAMLC = @OCAMLC@
+OCAMLDLGEN = @OCAMLDLGEN@
+OCAMLFIND = @OCAMLFIND@
+OCAMLINC = @OCAMLINC@
+OCAMLLOC = @OCAMLLOC@
+OCAMLMKTOP = @OCAMLMKTOP@
+OCAMLVER = @OCAMLVER@
+OCTAVE = @OCTAVE@
+OCTAVECCFLAGS = @OCTAVECCFLAGS@
+OCTAVEDYNAMICLINKING = @OCTAVEDYNAMICLINKING@
+OCTAVEEXT = @OCTAVEEXT@
+OCTAVELIB = @OCTAVELIB@
+OCTAVE_SO = @OCTAVE_SO@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PERL5CCFLAGS = @PERL5CCFLAGS@
+PERL5DYNAMICLINKING = @PERL5DYNAMICLINKING@
+PERL5EXT = @PERL5EXT@
+PERL5LIB = @PERL5LIB@
+PHP = @PHP@
+PHPINC = @PHPINC@
+PHP_SO = @PHP_SO@
+PIKE = @PIKE@
+PIKECCDLFLAGS = @PIKECCDLFLAGS@
+PIKECONFIG = @PIKECONFIG@
+PIKEDYNAMICLINKING = @PIKEDYNAMICLINKING@
+PIKEINCLUDE = @PIKEINCLUDE@
+PLATFLAGS = @PLATFLAGS@
+PY3CONFIG = @PY3CONFIG@
+PY3INCLUDE = @PY3INCLUDE@
+PY3LIB = @PY3LIB@
+PY3LINK = @PY3LINK@
+PYINCLUDE = @PYINCLUDE@
+PYLIB = @PYLIB@
+PYLINK = @PYLINK@
+PYTHON = @PYTHON@
+PYTHON3 = @PYTHON3@
+PYTHON3DYNAMICLINKING = @PYTHON3DYNAMICLINKING@
+PYTHONDYNAMICLINKING = @PYTHONDYNAMICLINKING@
+PYTHON_SO = @PYTHON_SO@
+RANLIB = @RANLIB@
+RBIN = @RBIN@
+ROOT_DIR = @ROOT_DIR@
+RPATH = @RPATH@
+RUBY = @RUBY@
+RUBYCCDLFLAGS = @RUBYCCDLFLAGS@
+RUBYDYNAMICLINKING = @RUBYDYNAMICLINKING@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+RUBYLINK = @RUBYLINK@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SKIP_ALLEGROCL = @SKIP_ALLEGROCL@
+SKIP_CFFI = @SKIP_CFFI@
+SKIP_CHICKEN = @SKIP_CHICKEN@
+SKIP_CLISP = @SKIP_CLISP@
+SKIP_CSHARP = @SKIP_CSHARP@
+SKIP_GCJ = @SKIP_GCJ@
+SKIP_GUILE = @SKIP_GUILE@
+SKIP_GUILESCM = @SKIP_GUILESCM@
+SKIP_JAVA = @SKIP_JAVA@
+SKIP_LUA = @SKIP_LUA@
+SKIP_MODULA3 = @SKIP_MODULA3@
+SKIP_MZSCHEME = @SKIP_MZSCHEME@
+SKIP_OCAML = @SKIP_OCAML@
+SKIP_OCTAVE = @SKIP_OCTAVE@
+SKIP_PERL5 = @SKIP_PERL5@
+SKIP_PHP = @SKIP_PHP@
+SKIP_PIKE = @SKIP_PIKE@
+SKIP_PYTHON = @SKIP_PYTHON@
+SKIP_PYTHON3 = @SKIP_PYTHON3@
+SKIP_R = @SKIP_R@
+SKIP_RUBY = @SKIP_RUBY@
+SKIP_TCL = @SKIP_TCL@
+SKIP_UFFI = @SKIP_UFFI@
+SO = @SO@
+STRIP = @STRIP@
+SWIGLIBS = @SWIGLIBS@
+SWIG_LIB = @SWIG_LIB@
+SWILL = @SWILL@
+TCLCXXSHARED = @TCLCXXSHARED@
+TCLDYNAMICLINKING = @TCLDYNAMICLINKING@
+TCLINCLUDE = @TCLINCLUDE@
+TCLLDSHARED = @TCLLDSHARED@
+TCLLIB = @TCLLIB@
+TCL_SO = @TCL_SO@
+TRYLINKINGWITHCXX = @TRYLINKINGWITHCXX@
+VERSION = @VERSION@
+XINCLUDES = @XINCLUDES@
+XLIBSW = @XLIBSW@
+XMKMF = @XMKMF@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+YODL2HTML = @YODL2HTML@
+YODL2MAN = @YODL2MAN@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_aux_dir = @ac_aux_dir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+swig_lib = @swig_lib@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# subdir-objects generates object files using the directory structure of the source files.
+AUTOMAKE_OPTIONS = foreign nostdinc subdir-objects 1.7.2
+SOURCE_DIR = $(top_srcdir)/Source
+BUILD_SOURCE_DIR = $(top_builddir)/Source
+SWIG_CXX_DEFS = @SWILL@
+AM_CPPFLAGS = -I$(BUILD_SOURCE_DIR)/Include \
+ -I$(BUILD_SOURCE_DIR)/CParse \
+ -I$(SOURCE_DIR)/Include \
+ -I$(SOURCE_DIR)/DOH \
+ -I$(SOURCE_DIR)/CParse \
+ -I$(SOURCE_DIR)/Preprocessor \
+ -I$(SOURCE_DIR)/Swig \
+ -I$(SOURCE_DIR)/Modules
+
+AM_CXXFLAGS = $(SWIG_CXX_DEFS)
+AM_YFLAGS = -d
+BUILT_SOURCES = CParse/parser.h
+eswig_SOURCES = CParse/cscanner.c \
+ CParse/parser.y \
+ CParse/templ.c \
+ CParse/util.c \
+ DOH/base.c \
+ DOH/file.c \
+ DOH/fio.c \
+ DOH/hash.c \
+ DOH/list.c \
+ DOH/memory.c \
+ DOH/string.c \
+ DOH/void.c \
+ Modules/allegrocl.cxx \
+ Modules/allocate.cxx \
+ Modules/browser.cxx \
+ Modules/cffi.cxx \
+ Modules/chicken.cxx \
+ Modules/clisp.cxx \
+ Modules/contract.cxx \
+ Modules/csharp.cxx \
+ Modules/directors.cxx \
+ Modules/emit.cxx \
+ Modules/guile.cxx \
+ Modules/java.cxx \
+ Modules/lang.cxx \
+ Modules/lua.cxx \
+ Modules/main.cxx \
+ Modules/modula3.cxx \
+ Modules/module.cxx \
+ Modules/mzscheme.cxx \
+ Modules/ocaml.cxx \
+ Modules/octave.cxx \
+ Modules/overload.cxx \
+ Modules/perl5.cxx \
+ Modules/php.cxx \
+ Modules/pike.cxx \
+ Modules/python.cxx \
+ Modules/r.cxx \
+ Modules/ruby.cxx \
+ Modules/s-exp.cxx \
+ Modules/swigmain.cxx \
+ Modules/tcl8.cxx \
+ Modules/typepass.cxx \
+ Modules/uffi.cxx \
+ Modules/utils.cxx \
+ Modules/xml.cxx \
+ Preprocessor/cpp.c \
+ Preprocessor/expr.c \
+ Swig/cwrap.c \
+ Swig/deprecate.c \
+ Swig/error.c \
+ Swig/fragment.c \
+ Swig/getopt.c \
+ Swig/include.c \
+ Swig/misc.c \
+ Swig/naming.c \
+ Swig/parms.c \
+ Swig/scanner.c \
+ Swig/stype.c \
+ Swig/symbol.c \
+ Swig/tree.c \
+ Swig/typeobj.c \
+ Swig/typemap.c \
+ Swig/typesys.c \
+ Swig/warn.c \
+ Swig/wrapfunc.c
+
+eswig_LDADD = @SWIGLIBS@
+
+# Override the link stage to avoid using Libtool
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+
+# Beautify the code.
+# Note that this works well on C code, but does some odd joining of lines for C++ code.
+# Compiling with -DNDEBUG and no optimisations will allow one to do a binary diff of the
+# swig executable as a way of checking before and after the 'beautifying'.
+# Single files can be beautified with the beautify-file target, eg: 'make beautify-file INDENTFILE=chosenfile.c'
+SWIGTYPEDEFS = -T File -T DohObjInfo -T Parm -T Language -T List -T Typetab -T ModuleFactory -T ErrorMessageFormat -T Symtab -T Hash -T String -T DohBase -T Node -T String_or_char -T SwigType -T Dispatcher -T Wrapper -T DohStringMethods -T DohFileMethods -T DohListMethods -T DohHashMethods -T DOH -T DohIterator -T ParmList -T FILE -T HashNode -T DOHString_or_char
+INDENTBAKSDIR = ../IndentBaks
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cxx .o .obj .y
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Source/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Source/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+CParse/$(am__dirstamp):
+ @$(MKDIR_P) CParse
+ @: > CParse/$(am__dirstamp)
+CParse/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) CParse/$(DEPDIR)
+ @: > CParse/$(DEPDIR)/$(am__dirstamp)
+CParse/cscanner.$(OBJEXT): CParse/$(am__dirstamp) \
+ CParse/$(DEPDIR)/$(am__dirstamp)
+CParse/parser.h: CParse/parser.c
+ @if test ! -f $@; then \
+ rm -f CParse/parser.c; \
+ $(MAKE) $(AM_MAKEFLAGS) CParse/parser.c; \
+ else :; fi
+CParse/parser.$(OBJEXT): CParse/$(am__dirstamp) \
+ CParse/$(DEPDIR)/$(am__dirstamp)
+CParse/templ.$(OBJEXT): CParse/$(am__dirstamp) \
+ CParse/$(DEPDIR)/$(am__dirstamp)
+CParse/util.$(OBJEXT): CParse/$(am__dirstamp) \
+ CParse/$(DEPDIR)/$(am__dirstamp)
+DOH/$(am__dirstamp):
+ @$(MKDIR_P) DOH
+ @: > DOH/$(am__dirstamp)
+DOH/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) DOH/$(DEPDIR)
+ @: > DOH/$(DEPDIR)/$(am__dirstamp)
+DOH/base.$(OBJEXT): DOH/$(am__dirstamp) DOH/$(DEPDIR)/$(am__dirstamp)
+DOH/file.$(OBJEXT): DOH/$(am__dirstamp) DOH/$(DEPDIR)/$(am__dirstamp)
+DOH/fio.$(OBJEXT): DOH/$(am__dirstamp) DOH/$(DEPDIR)/$(am__dirstamp)
+DOH/hash.$(OBJEXT): DOH/$(am__dirstamp) DOH/$(DEPDIR)/$(am__dirstamp)
+DOH/list.$(OBJEXT): DOH/$(am__dirstamp) DOH/$(DEPDIR)/$(am__dirstamp)
+DOH/memory.$(OBJEXT): DOH/$(am__dirstamp) \
+ DOH/$(DEPDIR)/$(am__dirstamp)
+DOH/string.$(OBJEXT): DOH/$(am__dirstamp) \
+ DOH/$(DEPDIR)/$(am__dirstamp)
+DOH/void.$(OBJEXT): DOH/$(am__dirstamp) DOH/$(DEPDIR)/$(am__dirstamp)
+Modules/$(am__dirstamp):
+ @$(MKDIR_P) Modules
+ @: > Modules/$(am__dirstamp)
+Modules/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) Modules/$(DEPDIR)
+ @: > Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/allegrocl.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/allocate.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/browser.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/cffi.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/chicken.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/clisp.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/contract.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/csharp.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/directors.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/emit.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/guile.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/java.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/lang.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/lua.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/main.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/modula3.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/module.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/mzscheme.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/ocaml.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/octave.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/overload.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/perl5.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/php.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/pike.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/python.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/r.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/ruby.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/s-exp.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/swigmain.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/tcl8.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/typepass.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/uffi.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/utils.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Modules/xml.$(OBJEXT): Modules/$(am__dirstamp) \
+ Modules/$(DEPDIR)/$(am__dirstamp)
+Preprocessor/$(am__dirstamp):
+ @$(MKDIR_P) Preprocessor
+ @: > Preprocessor/$(am__dirstamp)
+Preprocessor/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) Preprocessor/$(DEPDIR)
+ @: > Preprocessor/$(DEPDIR)/$(am__dirstamp)
+Preprocessor/cpp.$(OBJEXT): Preprocessor/$(am__dirstamp) \
+ Preprocessor/$(DEPDIR)/$(am__dirstamp)
+Preprocessor/expr.$(OBJEXT): Preprocessor/$(am__dirstamp) \
+ Preprocessor/$(DEPDIR)/$(am__dirstamp)
+Swig/$(am__dirstamp):
+ @$(MKDIR_P) Swig
+ @: > Swig/$(am__dirstamp)
+Swig/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) Swig/$(DEPDIR)
+ @: > Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/cwrap.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/deprecate.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/error.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/fragment.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/getopt.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/include.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/misc.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/naming.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/parms.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/scanner.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/stype.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/symbol.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/tree.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/typeobj.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/typemap.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/typesys.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/warn.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+Swig/wrapfunc.$(OBJEXT): Swig/$(am__dirstamp) \
+ Swig/$(DEPDIR)/$(am__dirstamp)
+eswig$(EXEEXT): $(eswig_OBJECTS) $(eswig_DEPENDENCIES)
+ @rm -f eswig$(EXEEXT)
+ $(CXXLINK) $(eswig_OBJECTS) $(eswig_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f CParse/cscanner.$(OBJEXT)
+ -rm -f CParse/parser.$(OBJEXT)
+ -rm -f CParse/templ.$(OBJEXT)
+ -rm -f CParse/util.$(OBJEXT)
+ -rm -f DOH/base.$(OBJEXT)
+ -rm -f DOH/file.$(OBJEXT)
+ -rm -f DOH/fio.$(OBJEXT)
+ -rm -f DOH/hash.$(OBJEXT)
+ -rm -f DOH/list.$(OBJEXT)
+ -rm -f DOH/memory.$(OBJEXT)
+ -rm -f DOH/string.$(OBJEXT)
+ -rm -f DOH/void.$(OBJEXT)
+ -rm -f Modules/allegrocl.$(OBJEXT)
+ -rm -f Modules/allocate.$(OBJEXT)
+ -rm -f Modules/browser.$(OBJEXT)
+ -rm -f Modules/cffi.$(OBJEXT)
+ -rm -f Modules/chicken.$(OBJEXT)
+ -rm -f Modules/clisp.$(OBJEXT)
+ -rm -f Modules/contract.$(OBJEXT)
+ -rm -f Modules/csharp.$(OBJEXT)
+ -rm -f Modules/directors.$(OBJEXT)
+ -rm -f Modules/emit.$(OBJEXT)
+ -rm -f Modules/guile.$(OBJEXT)
+ -rm -f Modules/java.$(OBJEXT)
+ -rm -f Modules/lang.$(OBJEXT)
+ -rm -f Modules/lua.$(OBJEXT)
+ -rm -f Modules/main.$(OBJEXT)
+ -rm -f Modules/modula3.$(OBJEXT)
+ -rm -f Modules/module.$(OBJEXT)
+ -rm -f Modules/mzscheme.$(OBJEXT)
+ -rm -f Modules/ocaml.$(OBJEXT)
+ -rm -f Modules/octave.$(OBJEXT)
+ -rm -f Modules/overload.$(OBJEXT)
+ -rm -f Modules/perl5.$(OBJEXT)
+ -rm -f Modules/php.$(OBJEXT)
+ -rm -f Modules/pike.$(OBJEXT)
+ -rm -f Modules/python.$(OBJEXT)
+ -rm -f Modules/r.$(OBJEXT)
+ -rm -f Modules/ruby.$(OBJEXT)
+ -rm -f Modules/s-exp.$(OBJEXT)
+ -rm -f Modules/swigmain.$(OBJEXT)
+ -rm -f Modules/tcl8.$(OBJEXT)
+ -rm -f Modules/typepass.$(OBJEXT)
+ -rm -f Modules/uffi.$(OBJEXT)
+ -rm -f Modules/utils.$(OBJEXT)
+ -rm -f Modules/xml.$(OBJEXT)
+ -rm -f Preprocessor/cpp.$(OBJEXT)
+ -rm -f Preprocessor/expr.$(OBJEXT)
+ -rm -f Swig/cwrap.$(OBJEXT)
+ -rm -f Swig/deprecate.$(OBJEXT)
+ -rm -f Swig/error.$(OBJEXT)
+ -rm -f Swig/fragment.$(OBJEXT)
+ -rm -f Swig/getopt.$(OBJEXT)
+ -rm -f Swig/include.$(OBJEXT)
+ -rm -f Swig/misc.$(OBJEXT)
+ -rm -f Swig/naming.$(OBJEXT)
+ -rm -f Swig/parms.$(OBJEXT)
+ -rm -f Swig/scanner.$(OBJEXT)
+ -rm -f Swig/stype.$(OBJEXT)
+ -rm -f Swig/symbol.$(OBJEXT)
+ -rm -f Swig/tree.$(OBJEXT)
+ -rm -f Swig/typemap.$(OBJEXT)
+ -rm -f Swig/typeobj.$(OBJEXT)
+ -rm -f Swig/typesys.$(OBJEXT)
+ -rm -f Swig/warn.$(OBJEXT)
+ -rm -f Swig/wrapfunc.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@CParse/$(DEPDIR)/cscanner.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@CParse/$(DEPDIR)/parser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@CParse/$(DEPDIR)/templ.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@CParse/$(DEPDIR)/util.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DOH/$(DEPDIR)/base.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DOH/$(DEPDIR)/file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DOH/$(DEPDIR)/fio.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DOH/$(DEPDIR)/hash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DOH/$(DEPDIR)/list.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DOH/$(DEPDIR)/memory.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DOH/$(DEPDIR)/string.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DOH/$(DEPDIR)/void.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/allegrocl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/allocate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/browser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/cffi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/chicken.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/clisp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/contract.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/csharp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/directors.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/emit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/guile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/java.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/lang.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/lua.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/modula3.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/module.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/mzscheme.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/ocaml.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/octave.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/overload.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/perl5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/php.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/pike.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/python.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/r.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/ruby.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/s-exp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/swigmain.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/tcl8.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/typepass.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/uffi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/xml.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Preprocessor/$(DEPDIR)/cpp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Preprocessor/$(DEPDIR)/expr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/cwrap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/deprecate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/error.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/fragment.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/getopt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/include.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/misc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/naming.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/parms.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/scanner.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/stype.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/symbol.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/tree.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/typemap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/typeobj.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/typesys.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/warn.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Swig/$(DEPDIR)/wrapfunc.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ mv -f $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ mv -f $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cxx.o:
+@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ mv -f $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cxx.obj:
+@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCXX_TRUE@ mv -f $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.y.c:
+ $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE)
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(PROGRAMS) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -rm -f CParse/$(DEPDIR)/$(am__dirstamp)
+ -rm -f CParse/$(am__dirstamp)
+ -rm -f DOH/$(DEPDIR)/$(am__dirstamp)
+ -rm -f DOH/$(am__dirstamp)
+ -rm -f Modules/$(DEPDIR)/$(am__dirstamp)
+ -rm -f Modules/$(am__dirstamp)
+ -rm -f Preprocessor/$(DEPDIR)/$(am__dirstamp)
+ -rm -f Preprocessor/$(am__dirstamp)
+ -rm -f Swig/$(DEPDIR)/$(am__dirstamp)
+ -rm -f Swig/$(am__dirstamp)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -rm -f CParse/parser.c
+ -rm -f CParse/parser.h
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf CParse/$(DEPDIR) DOH/$(DEPDIR) Modules/$(DEPDIR) Preprocessor/$(DEPDIR) Swig/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf CParse/$(DEPDIR) DOH/$(DEPDIR) Modules/$(DEPDIR) Preprocessor/$(DEPDIR) Swig/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \
+ clean-binPROGRAMS clean-generic clean-local ctags distclean \
+ distclean-compile distclean-generic distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS
+
+
+# The executable is copied to the root directory for installation and running the test-suite.
+# This occurs on each invocation of make and is a step towards providing support for multiple
+# build directories.
+all-local: eswig@EXEEXT@
+ cp -f $(top_builddir)/Source/eswig@EXEEXT@ $(top_builddir)/swig@EXEEXT@
+
+clean-local:
+ rm -f $(top_builddir)/swig@EXEEXT@
+ rm -f core @EXTRA_CLEAN@
+
+beautify:
+ rm -rf $(INDENTBAKSDIR)
+ mkdir $(INDENTBAKSDIR)
+ mkdir $(INDENTBAKSDIR)/CParse
+ mkdir $(INDENTBAKSDIR)/DOH
+ mkdir $(INDENTBAKSDIR)/Modules
+ mkdir $(INDENTBAKSDIR)/Preprocessor
+ mkdir $(INDENTBAKSDIR)/Swig
+ mkdir $(INDENTBAKSDIR)/Include
+ (csources=`find . -name "*.c"` && \
+ hsources=`find . -name "*.h"` && \
+ cxxsources=`find . -name "*.cxx"` && \
+ for file in $$csources $$hsources $$cxxsources; do \
+ $(MAKE) beautify-file INDENTFILE=$$file; \
+ done; )
+
+beautify-file:
+ test -e $(INDENTBAKSDIR) || (echo $(INDENTBAKSDIR) directory does not exist && exit 1;)
+ test -n "$(INDENTFILE)" || (echo INDENTFILE not defined && exit 1;)
+ test -e $(INDENTFILE) || (echo File does not exist: $(INDENTFILE) && exit 1;)
+ cp $(INDENTFILE) $(INDENTBAKSDIR)/$(INDENTFILE);
+ unix2dos $(INDENTFILE)
+ dos2unix $(INDENTFILE)
+ indent -kr --honour-newlines --line-length160 --indent-level2 --braces-on-func-def-line --leave-optional-blank-lines $(SWIGTYPEDEFS) $(INDENTFILE) -o $(INDENTFILE).tmp;
+ cat $(INDENTFILE).tmp | sed -e 's/const const /const /' > $(INDENTFILE);
+ rm $(INDENTFILE).tmp;
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Source/Modules/README b/Source/Modules/README
new file mode 100644
index 0000000..058779d
--- /dev/null
+++ b/Source/Modules/README
@@ -0,0 +1,9 @@
+06/25/2002
+
+This directory contains all of the SWIG language modules. Many of these
+modules contain code that dates back to SWIG1.0. The module API has changed
+a lot in the development releases so this is fairly messy. We're working on
+cleaning it up, but you'll have to bear with us until it's done.
+
+-- Dave
+
diff --git a/Source/Modules/allegrocl.cxx b/Source/Modules/allegrocl.cxx
new file mode 100644
index 0000000..d40538d
--- /dev/null
+++ b/Source/Modules/allegrocl.cxx
@@ -0,0 +1,3222 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * allegrocl.cxx
+ *
+ * ALLEGROCL language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_allegrocl_cxx[] = "$Id: allegrocl.cxx 11471 2009-07-29 20:52:29Z wsfulton $";
+
+#include "swigmod.h"
+#include "cparse.h"
+#include <ctype.h>
+
+// #define ALLEGROCL_DEBUG
+// #define ALLEGROCL_WRAP_DEBUG
+// #define ALLEGROCL_TYPE_DEBUG
+// #define ALLEGROCL_CLASS_DEBUG
+
+static File *f_cl = 0;
+String *f_clhead = NewString("");
+String *f_clwrap = NewString("(swig-in-package ())\n\n");
+static File *f_begin;
+static File *f_runtime;
+static File *f_cxx_header = 0;
+static File *f_cxx_wrapper = 0;
+
+static String *module_name = 0;
+static String *swig_package = 0;
+
+const char *identifier_converter = "identifier-convert-null";
+
+static bool CWrap = true; // generate wrapper file for C code by default. most correct.
+static bool Generate_Wrapper = false;
+static bool unique_swig_package = false;
+
+static SwigType *fwdref_ffi_type = NewString("__SWIGACL_FwdReference");
+
+static String *current_namespace = NewString("");
+static String *current_package = NewString("");
+static Hash *defined_namespace_packages = NewHash();
+static Node *in_class = 0;
+
+static Node *first_linked_type = 0;
+static Hash *defined_foreign_types = NewHash();
+static Hash *defined_foreign_ltypes = NewHash();
+
+static String *anon_type_name = NewString("anontype");
+static int anon_type_count = 0;
+
+// stub
+String *convert_literal(String *num_param, String *type, bool try_to_split = true);
+
+class ALLEGROCL:public Language {
+public:
+ virtual void main(int argc, char *argv[]);
+ virtual int top(Node *n);
+ virtual int functionWrapper(Node *n);
+ virtual int namespaceDeclaration(Node *n);
+ virtual int constructorHandler(Node *n);
+ virtual int destructorHandler(Node *n);
+ virtual int globalvariableHandler(Node *n);
+ virtual int variableWrapper(Node *n);
+ virtual int constantWrapper(Node *n);
+ virtual int memberfunctionHandler(Node *n);
+ virtual int membervariableHandler(Node *n);
+ virtual int classHandler(Node *n);
+ virtual int emit_one(Node *n);
+ virtual int enumDeclaration(Node *n);
+ virtual int enumvalueDeclaration(Node *n);
+ virtual int typedefHandler(Node *n);
+ virtual int classforwardDeclaration(Node *n);
+ virtual int templateDeclaration(Node *n);
+ virtual int validIdentifier(String *s);
+private:
+ int emit_defun(Node *n, File *f_cl);
+ int emit_dispatch_defun(Node *n);
+ int emit_buffered_defuns(Node *n);
+ int cClassHandler(Node *n);
+ int cppClassHandler(Node *n);
+};
+static ALLEGROCL *allegrocl = 0;
+
+static String *trim(String *str) {
+ char *c = Char(str);
+ while (*c != '\0' && isspace((int) *c))
+ ++c;
+ String *result = NewString(c);
+ Chop(result);
+ return result;
+}
+
+int is_integer(String *s) {
+ char *c = Char(s);
+ if (c[0] == '#' && (c[1] == 'x' || c[1] == 'o'))
+ c += 2;
+
+ while (*c) {
+ if (!isdigit(*c))
+ return 0;
+ c++;
+ }
+ return 1;
+}
+
+String *class_from_class_or_class_ref(String *type) {
+ SwigType *stripped = SwigType_strip_qualifiers(type);
+ if (SwigType_isclass(stripped))
+ return stripped;
+
+ if (SwigType_ispointer(stripped) || SwigType_isreference(stripped)) {
+ // Printf(stderr,"It is a pointer/reference. Is it a class?\n");
+ SwigType_pop(stripped);
+ if (SwigType_isclass(stripped)) {
+ return stripped;
+ }
+ }
+ return 0;
+}
+
+String *lookup_defined_foreign_type(String *k) {
+
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "Looking up defined type '%s'.\n Found: '%s'\n", k, Getattr(defined_foreign_types, k));
+#endif
+
+ return Getattr(defined_foreign_types, k);
+}
+
+String *listify_namespace(String *namespaze) {
+ if (Len(namespaze) == 0)
+ return NewString("()");
+ String *result = NewStringf("(\"%s\")", namespaze);
+ Replaceall(result, "::", "\" \"");
+ return result;
+}
+
+String *namespaced_name(Node *n, String *ns = current_namespace) {
+
+ return NewStringf("%s%s%s", ns, (Len(ns) != 0) ? "::" : "", Getattr(n, "sym:name"));
+}
+
+// "Namespace::Nested::Class2::Baz" -> "Baz"
+static String *strip_namespaces(String *str) {
+ char *result = Char(str);
+ String *stripped_one;
+ while ((stripped_one = Strstr(result, "::")))
+ result = Char(stripped_one) + 2;
+ return NewString(result);
+}
+
+static String *namespace_of(String *str) {
+ char *p = Char(str);
+ char *start = Char(str);
+ char *result = 0;
+ String *stripped_one;
+
+ while ((stripped_one = Strstr(p, "::"))) {
+ p = Char(stripped_one) + 2;
+ }
+ if (p > start) {
+ int len = p - start - 1;
+ result = (char *) malloc(len);
+ strncpy(result, start, len - 1);
+ result[len - 1] = 0;
+ }
+ return Char(result);
+}
+
+void add_linked_type(Node *n) {
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "Adding linked node of type: %s(%s) %s(%x)\n\n", nodeType(n), Getattr(n, "storage"), Getattr(n, "name"), n);
+ // Swig_print_node(n);
+#endif
+ if (!first_linked_type) {
+ first_linked_type = n;
+ Setattr(n, "allegrocl:last_linked_type", n);
+ } else {
+ Node *t = Getattr(first_linked_type, "allegrocl:last_linked_type");
+ Setattr(t, "allegrocl:next_linked_type", n);
+ Setattr(first_linked_type, "allegrocl:last_linked_type", n);
+ }
+}
+
+void replace_linked_type(Node *old, Node *new_node) {
+ Node *prev = Getattr(old, "allegrocl:prev_linked_type");
+
+ Setattr(new_node, "allegrocl:next_linked_type", Getattr(old, "allegrocl:next_linked_type"));
+ if (prev)
+ Setattr(prev, "allegrocl:next_linked_type", new_node);
+ Delattr(old, "allegrocl:next_linked_type");
+ Delattr(old, "allegrocl:prev_linked_type");
+
+ // check if we're replacing the first link.
+ if (first_linked_type == old) {
+ first_linked_type = new_node;
+ Setattr(first_linked_type, "allegrocl:last_linked_type", Getattr(old, "allegrocl:last_linked_type"));
+ }
+ // check if we're replacing the last link.
+ if (Getattr(first_linked_type, "allegrocl:last_linked_type") == old)
+ Setattr(first_linked_type, "allegrocl:last_linked_type", new_node);
+}
+
+void insert_linked_type_at(Node *old, Node *new_node, int before = 1) {
+ Node *p = 0;
+
+ if (!first_linked_type) {
+ add_linked_type(new_node);
+ return;
+ }
+
+ if (!before) {
+ Setattr(new_node, "allegrocl:next_linked_type", Getattr(old, "allegrocl:next_linked_type"));
+ Setattr(old, "allegrocl:next_linked_type", new_node);
+ if (Getattr(first_linked_type, "allegrocl:last_linked_type") == old)
+ Setattr(first_linked_type, "allegrocl:last_linked_type", new_node);
+ } else {
+ Node *c = first_linked_type;
+ while (c) {
+ if (c == old) {
+ break;
+ } else {
+ p = c;
+ c = Getattr(c, "allegrocl:next_linked_type");
+ }
+ }
+ if (c == old) {
+ Setattr(new_node, "allegrocl:next_linked_type", c);
+ if (first_linked_type == c) {
+ first_linked_type = new_node;
+ Setattr(first_linked_type, "allegrocl:last_linked_type", Getattr(c, "allegrocl:last_linked_type"));
+ Delattr(c, "allegrocl:last_linked_type");
+ }
+ if (p)
+ Setattr(p, "allegrocl:next_linked_type", new_node);
+ }
+ }
+}
+
+Node *find_linked_type_by_name(String *name) {
+ Node *p = 0;
+ Node *c = first_linked_type;
+
+ // Printf(stderr,"in find_linked_type_by_name '%s'...", name);
+ while (c) {
+ String *key = Getattr(c, "name");
+ if (!Strcmp(key, name)) {
+ break;
+ } else {
+ p = c;
+ c = Getattr(c, "allegrocl:next_linked_type");
+ }
+ }
+ // Printf(stderr,"exit find_linked_type_by_name.\n");
+
+ if (p && c)
+ Setattr(c, "allegrocl:prev_linked_type", p);
+ // Printf(stderr,"find_linked_type_by_name: DONE\n");
+ return c;
+}
+
+Node *get_primary_synonym_of(Node *n) {
+ Node *p = Getattr(n, "allegrocl:synonym-of");
+ Node *prim = n;
+
+ // Printf(stderr, "getting primary synonym of %x\n", n);
+ while (p) {
+ // Printf(stderr, " found one! %x\n", p);
+ prim = p;
+ p = Getattr(p, "allegrocl:synonym-of");
+ }
+ // Printf(stderr,"get_primary_syn: DONE. returning %s(%x)\n", Getattr(prim,"name"),prim);
+ return prim;
+}
+
+void add_forward_referenced_type(Node *n, int overwrite = 0) {
+ String *k = Getattr(n, "name");
+ String *name = Getattr(n, "sym:name");
+ String *ns = listify_namespace(current_namespace);
+
+ String *val = Getattr(defined_foreign_types, k);
+
+ if (!val || overwrite) {
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "Adding forward reference for %s (overwrite=%d)\n", k, overwrite);
+#endif
+ Setattr(defined_foreign_types, Copy(k), NewString("forward-reference"));
+
+ String *mangled_lname_gen = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)", name, ns);
+
+ Setattr(defined_foreign_ltypes, Copy(k), mangled_lname_gen);
+ // Printf(f_cl, ";; forward reference stub\n"
+ // "(swig-def-foreign-class \"%s\" (ff:foreign-pointer) (:class ))\n\n"
+ // , name);
+
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "Linking forward reference type = %s(%x)\n", k, n);
+#endif
+ add_linked_type(n);
+ }
+}
+
+void add_defined_foreign_type(Node *n, int overwrite = 0, String *k = 0,
+ String *name = 0, String *ns = current_namespace) {
+
+ String *val;
+ String *ns_list = listify_namespace(ns);
+ String *templated = n ? Getattr(n, "template") : 0;
+ String *cDeclName = n ? Getattr(n, "classDeclaration:name") : 0;
+
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "IN A-D-F-T. (n=%x, ow=%d, k=%s, name=%s, ns=%s\n", n, overwrite, k, name, ns);
+ Printf(stderr, " templated = '%x', classDecl = '%x'\n", templated, cDeclName);
+#endif
+ if (n) {
+ if (!name)
+ name = Getattr(n, "sym:name");
+ if (!name)
+ name = strip_namespaces(Getattr(n, "name"));
+ if (templated) {
+ k = namespaced_name(n);
+ } else {
+ String *kind_of_type = Getattr(n, "kind");
+
+ /*
+ For typedefs of the form:
+
+ typedef struct __xxx { ... } xxx;
+
+ behavior differs between C mode and C++ mode.
+
+ C Mode:
+ add_defined_foreign_type will be called once via classHandler
+ to define the type for 'struct __xxx' and add the mapping from
+ 'struct __xxx' -> 'xxx'
+
+ It will also be called once via typedefHandler to add the
+ mapping 'xxx' -> 'xxx'
+
+ C++ Mode:
+ add_defined_foreign_type will be called once via classHandler
+ to define the type for 'xxx'. it also adds the mapping from
+ 'xxx' -> 'xxx' and also for 'struct xxx' -> 'xxx'
+
+ In typedefHandler, we again try to add the mapping from
+ 'xxx' -> 'xxx', which already exists. This second mapping
+ is ignored.
+
+ Both modes:
+
+ All references to this typedef'd struct will appear in
+ generated lisp code as an objectd of type 'xxx'. For
+ non-typedef'd structs, the classHand mapping will be
+
+ struct __xxx -> (swig-insert-id "__xxx")
+ */
+ // Swig_print_node(n);
+ String *unnamed = Getattr(n, "unnamed");
+ if (kind_of_type && (!Strcmp(kind_of_type, "struct")
+ || !Strcmp(kind_of_type, "union")) && cDeclName && !unnamed) {
+ k = NewStringf("%s %s", kind_of_type, cDeclName);
+ } else {
+ if (!Strcmp(nodeType(n), "enum") && unnamed) {
+ name = NewStringf("%s%d", anon_type_name, anon_type_count++);
+ k = NewStringf("enum %s", name);
+ Setattr(n, "allegrocl:name", name);
+
+ } else {
+ k = k ? k : Getattr(n, "name");
+ }
+ }
+ }
+ // Swig_print_node(n);
+ }
+
+ if (SwigType_istemplate(name)) {
+ String *temp = strip_namespaces(SwigType_templateprefix(name));
+ name = NewStringf("%s%s%s", temp, SwigType_templateargs(name), SwigType_templatesuffix(name));
+ }
+
+ val = lookup_defined_foreign_type(k);
+
+ int is_fwd_ref = 0;
+ if (val)
+ is_fwd_ref = !Strcmp(val, "forward-reference");
+
+ if (!val || overwrite || is_fwd_ref) {
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "Adding defined type '%s' = '%s' '%s' (overwrite=%d, in-class=%d)\n", k, ns, name, overwrite, in_class);
+#endif
+ String *mangled_name_gen = NewStringf("#.(swig-insert-id \"%s\" %s :type :type)", name, ns_list);
+ String *mangled_lname_gen = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)", name, ns_list);
+
+ Setattr(defined_foreign_types, Copy(k), Copy(mangled_name_gen));
+ Setattr(defined_foreign_ltypes, Copy(k), Copy(mangled_lname_gen));
+
+ if (CPlusPlus) {
+ bool cpp_struct = Strstr(k, "struct ") ? true : false;
+ bool cpp_union = Strstr(k, "union ") ? true : false;
+
+ String *cpp_type = 0;
+ if (cpp_struct) {
+ cpp_type = Copy(k);
+ Replaceall(cpp_type, "struct ", "");
+ } else if (cpp_union) {
+ cpp_type = Copy(k);
+ Replaceall(cpp_type, "union ", "");
+ }
+
+ if (cpp_struct || cpp_union) {
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, " Also adding defined type '%s' = '%s' '%s' (overwrite=%d)\n", cpp_type, ns, name, overwrite);
+#endif
+ Setattr(defined_foreign_types, Copy(cpp_type), Copy(mangled_name_gen));
+ Setattr(defined_foreign_ltypes, Copy(cpp_type), Copy(mangled_lname_gen));
+ }
+ }
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "looking to add %s/%s(%x) to linked_type_list...\n", k, name, n);
+#endif
+ if (is_fwd_ref) {
+ // Printf(stderr,"*** 1\n");
+ add_linked_type(n);
+ } else {
+ // Printf(stderr,"*** 1-a\n");
+ if (SwigType_istemplate(k)) {
+ SwigType *resolved = SwigType_typedef_resolve_all(k);
+ // Printf(stderr,"*** 1-b\n");
+ Node *match = find_linked_type_by_name(resolved);
+ Node *new_node = 0;
+ // Printf(stderr, "*** temp-1\n");
+ if (n) {
+ new_node = n;
+ } else {
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "Creating a new templateInst:\n");
+ Printf(stderr, " name = %s\n", resolved);
+ Printf(stderr, " sym:name = %s\n", name);
+ Printf(stderr, " real-name = %s\n", k);
+ Printf(stderr, " type = %s\n", resolved);
+ Printf(stderr, " ns = %s\n\n", ns);
+#endif
+ new_node = NewHash();
+ Setattr(new_node, "nodeType", "templateInst");
+ Setattr(new_node, "name", Copy(resolved));
+ Setattr(new_node, "sym:name", Copy(name));
+ Setattr(new_node, "real-name", Copy(k));
+ Setattr(new_node, "type", Copy(resolved));
+ Setattr(new_node, "allegrocl:namespace", ns);
+ Setattr(new_node, "allegrocl:package", ns);
+ }
+
+ if (!match) {
+ if (!Strcmp(nodeType(new_node), "templateInst") && in_class) {
+ /* this is an implicit template instantiation found while
+ walking a class. need to insert this into the
+ linked_type list before the current class definition */
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "trying to insert a templateInst before a class\n");
+#endif
+ insert_linked_type_at(in_class, new_node);
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "DID IT!\n");
+#endif
+ } else {
+ // Printf(stderr,"*** 3\n");
+ add_linked_type(new_node);
+ }
+ Setattr(new_node, "allegrocl:synonym:is-primary", "1");
+ } else {
+ // a synonym type was found (held in variable 'match')
+ // Printf(stderr, "setting primary synonym of %x to %x\n", new_node, match);
+ if (new_node == match)
+ Printf(stderr, "Hey-4 * - '%s' is a synonym of iteself!\n", Getattr(new_node, "name"));
+ Setattr(new_node, "allegrocl:synonym-of", match);
+ // Printf(stderr,"*** 4\n");
+ add_linked_type(new_node);
+ }
+ } else {
+ Node *match;
+
+ if (!Strcmp(nodeType(n), "cdecl") && !Strcmp(Getattr(n, "storage"), "typedef")) {
+ SwigType *type = SwigType_strip_qualifiers(Getattr(n, "type"));
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "Examining typedef '%s' for class references. (%d)\n", type, SwigType_isclass(type));
+#endif
+ if (SwigType_isclass(type)) {
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "Found typedef of a class '%s'\n", type);
+#endif
+ /*
+ For the following parsed expression:
+
+ typedef struct __xxx { ... } xxx;
+
+ if n is of kind "class" (defining the class 'struct __xxx'
+ then we add n to the linked type list.
+
+ if n is "cdecl" node of storage "typedef" (to note
+ that xxx is equivalent to 'struct __xxx' then we don't
+ want to add this node to the linked type list.
+ */
+ String *defined_type = lookup_defined_foreign_type(type);
+ String *defined_key_type = lookup_defined_foreign_type(k);
+
+ if ((Strstr(type, "struct ") || Strstr(type, "union "))
+ && defined_type && !Strcmp(defined_type, defined_key_type)) {
+ // mark as a synonym but don't add to linked_type list
+ // Printf(stderr,"*** 4.8\n");
+ Setattr(n, "allegrocl:synonym", "1");
+ } else {
+ SwigType *lookup_type = SwigType_istemplate(type) ? SwigType_typedef_resolve_all(type) : Copy(type);
+ match = find_linked_type_by_name(lookup_type);
+ if (match) {
+ Setattr(n, "allegrocl:synonym", "1");
+ Setattr(n, "allegrocl:synonym-of", match);
+ Setattr(n, "real-name", Copy(lookup_type));
+
+ // Printf(stderr, "*** pre-5: found match of '%s'(%x)\n", Getattr(match,"name"),match);
+ // if(n == match) Printf(stderr, "Hey-5 *** setting synonym of %x to %x\n", n, match);
+ // Printf(stderr,"*** 5\n");
+ add_linked_type(n);
+ } else {
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "Creating classfoward node for struct stub in typedef.\n");
+#endif
+ Node *new_node = NewHash();
+ String *symname = Copy(type);
+ Replaceall(symname, "struct ", "");
+ Setattr(new_node, "nodeType", "classforward");
+ Setattr(new_node, "name", Copy(type));
+ Setattr(new_node, "sym:name", symname);
+ Setattr(new_node, "allegrocl:namespace", ns);
+ Setattr(new_node, "allegrocl:package", ns);
+
+ String *mangled_new_name = NewStringf("#.(swig-insert-id \"%s\" %s)", symname, ns_list);
+ String *mangled_new_lname = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)", symname, ns_list);
+ Setattr(defined_foreign_types, Copy(symname), Copy(mangled_new_name));
+ Setattr(defined_foreign_ltypes, Copy(symname), Copy(mangled_new_lname));
+
+ // Printf(stderr,"Weird! Can't find the type!\n");
+ add_forward_referenced_type(new_node);
+ add_linked_type(new_node);
+
+ Setattr(n, "allegrocl:synonym", "1");
+ Setattr(n, "allegrocl:synonym-of", new_node);
+
+ add_linked_type(n);
+ }
+ Delete(lookup_type);
+ }
+ } else {
+ // check if it's a pointer or reference to a class.
+ // Printf(stderr,"Checking if '%s' is a p. or r. to a class\n", type);
+ String *class_ref = class_from_class_or_class_ref(type);
+ if (class_ref) {
+ match = find_linked_type_by_name(class_ref);
+ Setattr(n, "allegrocl:synonym", "1");
+ Setattr(n, "allegrocl:synonym-of", match);
+ add_linked_type(n);
+ }
+ }
+ Delete(type);
+ // synonym types have already been added.
+ // Printf(stderr,"*** 10\n");
+ if (!Getattr(n, "allegrocl:synonym"))
+ add_linked_type(n);
+ } else if (Getattr(n, "template")) {
+ // Printf(stderr, "this is a class template node(%s)\n", nodeType(n));
+ String *resolved = SwigType_typedef_resolve_all(Getattr(n, "name"));
+
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, " looking up %s for linked type match with %s...\n", Getattr(n, "sym:name"), resolved);
+#endif
+ match = find_linked_type_by_name(resolved);
+ if (!match) {
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "found no implicit instantiation of %%template node %s(%x)\n", Getattr(n, "name"), n);
+#endif
+ add_linked_type(n);
+ } else {
+ Node *primary = get_primary_synonym_of(match);
+
+ Setattr(n, "allegrocl:synonym:is-primary", "1");
+ Delattr(primary, "allegrocl:synonym:is-primary");
+ if (n == match)
+ Printf(stderr, "Hey-7 * setting synonym of %x to %x\n (match = %x)", primary, n, match);
+ Setattr(primary, "allegrocl:synonym-of", n);
+ // Printf(stderr,"*** 7\n");
+ add_linked_type(n);
+ }
+ } else {
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "linking type '%s'(%x)\n", k, n);
+#endif
+ // Printf(stderr,"*** 8\n");
+ add_linked_type(n);
+ }
+ }
+ }
+ Delete(mangled_name_gen);
+ Delete(mangled_lname_gen);
+ } else {
+ if (!CPlusPlus || Strcmp(Getattr(n,"kind"),"typedef")) {
+ Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n),
+ "Attempting to store a foreign type that exists: %s (%s)\n",
+ k, val);
+ }
+ }
+
+ Delete(ns_list);
+
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "OUT A-D-F-T\n");
+#endif
+}
+
+void note_implicit_template_instantiation(SwigType *t) {
+ // the namespace of the implicit instantiation is not necessarily
+ // current_namespace. Attempt to cull this from the type.
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "culling namespace of '%s' from '%s'\n", t, SwigType_templateprefix(t));
+#endif
+ String *implicit_ns = namespace_of(SwigType_templateprefix(t));
+ add_defined_foreign_type(0, 0, t, t, implicit_ns ? implicit_ns : current_namespace);
+}
+
+String *get_ffi_type(Node *n, SwigType *ty, const_String_or_char_ptr name) {
+ /* lookup defined foreign type.
+ if it exists, it will return a form suitable for placing
+ into lisp code to generate the def-foreign-type name */
+
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "inside g_f_t: looking up '%s' '%s'\n", ty, name);
+#endif
+
+ String *found_type = lookup_defined_foreign_type(ty);
+
+ if (found_type) {
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "found_type '%s'\n", found_type);
+#endif
+ return (Strcmp(found_type, "forward-reference") ? Copy(found_type) : get_ffi_type(n, fwdref_ffi_type, ""));
+ } else {
+ Node *node = NewHash();
+ Setattr(node, "type", ty);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *tm = Swig_typemap_lookup("ffitype", node, name, 0);
+ Delete(node);
+
+ if (tm) {
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "g-f-t: found ffitype typemap '%s'\n", tm);
+#endif
+ return NewString(tm);
+ }
+
+ if (SwigType_istemplate(ty)) {
+ note_implicit_template_instantiation(ty);
+ return Copy(lookup_defined_foreign_type(ty));
+ }
+ }
+ return 0;
+}
+
+String *lookup_defined_foreign_ltype(String *l) {
+
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "Looking up defined ltype '%s'.\n Found: '%s'\n", l, Getattr(defined_foreign_ltypes, l));
+#endif
+ return Getattr(defined_foreign_ltypes, l);
+}
+
+/* walk type and return string containing lisp version.
+ recursive. */
+String *internal_compose_foreign_type(Node *n, SwigType *ty) {
+
+ SwigType *tok;
+ String *ffiType = NewString("");
+
+ // for a function type, need to walk the parm list.
+ while (Len(ty) != 0) {
+ tok = SwigType_pop(ty);
+
+ if (SwigType_isfunction(tok)) {
+ // Generate Function wrapper
+ Printf(ffiType, "(:function ");
+ // walk parm list
+ List *pl = SwigType_parmlist(tok);
+
+ Printf(ffiType, "("); // start parm list
+ for (Iterator i = First(pl); i.item; i = Next(i)) {
+ SwigType *f_arg = SwigType_strip_qualifiers(i.item);
+ Printf(ffiType, "%s ", internal_compose_foreign_type(n, f_arg));
+ Delete(f_arg);
+ }
+ Printf(ffiType, ")"); // end parm list.
+
+ // do function return type.
+ Printf(ffiType, " %s)", internal_compose_foreign_type(n, ty));
+ break;
+ } else if (SwigType_ispointer(tok) || SwigType_isreference(tok)) {
+ Printf(ffiType, "(* %s)", internal_compose_foreign_type(n, ty));
+ } else if (SwigType_isarray(tok)) {
+ Printf(ffiType, "(:array %s", internal_compose_foreign_type(n, ty));
+ String *atype = NewString("int");
+ String *dim = convert_literal(SwigType_array_getdim(tok, 0), atype);
+ Delete(atype);
+ if (is_integer(dim)) {
+ Printf(ffiType, " %s)", dim);
+ } else {
+ Printf(ffiType, " #| %s |#)", SwigType_array_getdim(tok, 0));
+ }
+ } else if (SwigType_ismemberpointer(tok)) {
+ // temp
+ Printf(ffiType, "(* %s)", internal_compose_foreign_type(n, ty));
+ } else {
+ String *res = get_ffi_type(n, tok, "");
+ if (res) {
+ Printf(ffiType, "%s", res);
+ } else {
+ SwigType *resolved_type = SwigType_typedef_resolve(tok);
+ if (resolved_type) {
+ res = get_ffi_type(n, resolved_type, "");
+ if (res) {
+ } else {
+ res = internal_compose_foreign_type(n, resolved_type);
+ }
+ if (res)
+ Printf(ffiType, "%s", res);
+ }
+
+ if (!res) {
+ String *is_struct = 0;
+ String *tok_remove_text = 0;
+ String *tok_name = Copy(tok);
+ String *tok_key = SwigType_str(tok,0);
+ if ((is_struct = Strstr(tok_key, "struct ")) || Strstr(tok_key, "union ")) {
+ tok_remove_text = NewString(is_struct ? "struct " : "union ");
+ }
+
+ /* be more permissive of opaque types. This is the swig way.
+ compiles will notice if these types are ultimately not
+ present. */
+
+ if(tok_remove_text) {
+ Replaceall(tok_name,tok_remove_text,"");
+ }
+ tok_name = strip_namespaces(tok_name);
+ Delete(tok_remove_text);
+ // Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(tok), Getline(tok), "Unable to find definition of '%s', assuming forward reference.\n", tok);
+
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "i-c-f-t: adding forward reference for unknown type '%s'. mapping: %s -> %s\n", tok, tok_key, tok_name);
+#endif
+ Node *nn = NewHash();
+ Setattr(nn,"nodeType","classforward");
+ Setattr(nn,"kind","class");
+ Setattr(nn,"sym:name",tok_name);
+ Setattr(nn,"name",tok_key);
+ Setattr(nn,"allegrocl:package",current_namespace);
+
+ add_forward_referenced_type(nn, 0);
+ // tok_name is dangling here, unused. ouch. why?
+ Printf(ffiType, "%s", get_ffi_type(n, tok, ""), tok_name);
+ }
+ }
+ }
+ }
+ return ffiType;
+}
+
+String *compose_foreign_type(Node *n, SwigType *ty, String * /*id*/ = 0) {
+
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "compose_foreign_type: ENTER (%s)...\n ", ty);
+ // Printf(stderr, "compose_foreign_type: ENTER (%s)(%s)...\n ", ty, (id ? id : 0));
+ /* String *id_ref = SwigType_str(ty, id);
+ Printf(stderr, "looking up typemap for %s, found '%s'(%x)\n",
+ id_ref, lookup_res ? Getattr(lookup_res, "code") : 0, lookup_res);
+ if (lookup_res) Swig_print_node(lookup_res);
+ */
+#endif
+
+ /* should we allow named lookups in the typemap here? YES! */
+ /* unnamed lookups should be found in get_ffi_type, called
+ by internal_compose_foreign_type(), below. */
+
+ /* I'm reverting to 'no' for the question above. I can no longer
+ remember why I needed it. If a user needed it, I'll find out
+ as soon as they upgrade. Sigh. -mutandiz 9/16/2008. */
+
+/*
+ if(id && lookup_res) {
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "compose_foreign_type: EXIT-1 (%s)\n ", Getattr(lookup_res, "code"));
+#endif
+ return NewString(Getattr(lookup_res, "code"));
+ }
+*/
+
+ SwigType *temp = SwigType_strip_qualifiers(ty);
+ String *res = internal_compose_foreign_type(n, temp);
+ Delete(temp);
+
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "compose_foreign_type: EXIT (%s)\n ", res);
+#endif
+
+ return res;
+}
+
+void update_package_if_needed(Node *n, File *f = f_clwrap) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "update_package: ENTER... \n");
+ Printf(stderr, " current_package = '%s'\n", current_package);
+ Printf(stderr, " node_package = '%s'\n", Getattr(n, "allegrocl:package"));
+ Printf(stderr, " node(%x) = '%s'\n", n, Getattr(n, "name"));
+#endif
+ String *node_package = Getattr(n, "allegrocl:package");
+ if (Strcmp(current_package, node_package)) {
+ String *lispy_package = listify_namespace(node_package);
+
+ Delete(current_package);
+ current_package = Copy(node_package);
+ Printf(f, "\n(swig-in-package %s)\n", lispy_package);
+ Delete(lispy_package);
+ }
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "update_package: EXIT.\n");
+#endif
+}
+
+static String *mangle_name(Node *n, char const *prefix = "ACL", String *ns = current_namespace) {
+ String *suffix = Getattr(n, "sym:overname");
+ String *pre_mangled_name = NewStringf("%s_%s__%s%s", prefix, ns, Getattr(n, "sym:name"), suffix);
+ String *mangled_name = Swig_name_mangle(pre_mangled_name);
+ Delete(pre_mangled_name);
+ return mangled_name;
+}
+
+/* utilities */
+
+/* remove a pointer from ffitype. non-destructive.
+ (* :char) ==> :char
+ (* (:array :int 30)) ==> (:array :int 30) */
+String *dereference_ffitype(String *ffitype) {
+ char *start;
+ char *temp = Char(ffitype);
+ String *reduced_type = 0;
+
+ if(temp && temp[0] == '(' && temp[1] == '*') {
+ temp += 2;
+
+ // walk past start of pointer references
+ while(*temp == ' ') temp++;
+ start = temp;
+ // temp = Char(reduced_type);
+ reduced_type = NewString(start);
+ temp = Char(reduced_type);
+ // walk to end of string. remove closing paren
+ while(*temp != '\0') temp++;
+ *(--temp) = '\0';
+ }
+
+ return reduced_type ? reduced_type : Copy(ffitype);
+}
+
+/* returns new string w/ parens stripped */
+String *strip_parens(String *string) {
+ string = Copy(string);
+ Replaceall(string, "(", "");
+ Replaceall(string, ")", "");
+ return string;
+}
+
+int ALLEGROCL::validIdentifier(String *s) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "validIdentifier %s\n", s);
+#endif
+
+ char *c = Char(s);
+
+ bool got_dot = false;
+ bool only_dots = true;
+
+ /* Check that s is a valid common lisp symbol. There's a lot of leeway here.
+ A common lisp symbol is essentially any token that's not a number and
+ does not consist of only dots.
+
+ We are expressly not allowing spaces in identifiers here, but spaces
+ could be added via the identifier converter. */
+ while (*c) {
+ if (*c == '.') {
+ got_dot = true;
+ } else {
+ only_dots = false;
+ }
+ if (!isgraph(*c))
+ return 0;
+ c++;
+ }
+
+ return (got_dot && only_dots) ? 0 : 1;
+}
+
+String *infix_to_prefix(String *val, char split_op, const String *op, String *type) {
+ List *ored = Split(val, split_op, -1);
+
+ // some float hackery
+ if (((split_op == '+') || (split_op == '-')) && Len(ored) == 2 &&
+ (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || SwigType_type(type) == T_LONGDOUBLE)) {
+ // check that we're not splitting a float
+ String *possible_result = convert_literal(val, type, false);
+ if (possible_result)
+ return possible_result;
+
+ }
+ // try parsing the split results. if any part fails, kick out.
+ bool part_failed = false;
+ if (Len(ored) > 1) {
+ String *result = NewStringf("(%s", op);
+ for (Iterator i = First(ored); i.item; i = Next(i)) {
+ String *converted = convert_literal(i.item, type);
+ if (converted) {
+ Printf(result, " %s", converted);
+ Delete(converted);
+ } else {
+ part_failed = true;
+ break;
+ }
+ }
+ Printf(result, ")");
+ Delete(ored);
+ return part_failed ? 0 : result;
+ }
+ Delete(ored);
+ return 0;
+}
+
+/* To be called by code generating the lisp interface
+ Will return a containing the literal based on type.
+ Will return null if there are problems.
+
+ try_to_split defaults to true (see stub above).
+ */
+String *convert_literal(String *literal, String *type, bool try_to_split) {
+ String *num_param = Copy(literal);
+ String *trimmed = trim(num_param);
+ String *num = strip_parens(trimmed), *res = 0;
+ char *s = Char(num);
+
+ String *ns = listify_namespace(current_namespace);
+
+ // very basic parsing of infix expressions.
+ if (try_to_split && SwigType_type(type) != T_STRING) {
+ if ((res = infix_to_prefix(num, '|', "logior", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '&', "logand", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '^', "logxor", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '*', "*", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '/', "/", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '+', "+", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '-', "-", type)))
+ return res;
+ // if ((res = infix_to_prefix(num, '~', "lognot", type))) return res;
+ // if( (res = infix_to_prefix(num, '<<', "ash", type)) ) return res;
+ }
+
+ // unary complement...
+ if (s[0] == '~' && Len(num) >= 2) {
+ String *id = NewString(++s);
+ String *id_conv = convert_literal(id, type, false);
+ Delete(id);
+ if (id_conv)
+ return NewStringf("(lognot %s)", id_conv);
+ s--;
+ }
+
+ if (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || SwigType_type(type) == T_LONGDOUBLE) {
+ // Use CL syntax for float literals
+ String *oldnum = Copy(num);
+
+ // careful. may be a float identifier or float constant.
+ char *num_start = Char(num);
+ char *num_end = num_start + strlen(num_start) - 1;
+
+ bool is_literal = isdigit(*num_start) || (*num_start == '.');
+
+ String *lisp_exp = 0;
+ if (is_literal) {
+ if (*num_end == 'f' || *num_end == 'F') {
+ lisp_exp = NewString("f");
+ } else {
+ lisp_exp = NewString("d");
+ }
+
+ if (*num_end == 'l' || *num_end == 'L' || *num_end == 'f' || *num_end == 'F') {
+ *num_end = '\0';
+ num_end--;
+ }
+
+ int exponents = Replaceall(num, "e", lisp_exp) + Replaceall(num, "E", lisp_exp);
+
+ if (!exponents)
+ Printf(num, "%s0", lisp_exp);
+
+ if (exponents > 1 || (exponents + Replaceall(num, ".", ".") == 0)) {
+ // Printf(stderr, "Can't parse '%s' as type '%s'.\n", oldnum, type);
+ Delete(num);
+ num = 0;
+ }
+ Delete(lisp_exp);
+ } else {
+ String *id = NewStringf("#.(swig-insert-id \"%s\" %s :type :constant)",
+ num, ns);
+ Delete(num);
+ num = id;
+ }
+
+ Delete(oldnum);
+ Delete(trimmed);
+ Delete(ns);
+ return num;
+ } else if (SwigType_type(type) == T_CHAR) {
+ /* Use CL syntax for character literals */
+ Delete(num);
+ Delete(trimmed);
+ return NewStringf("#\\%s", num_param);
+ } else if (SwigType_type(type) == T_STRING) {
+ /* Use CL syntax for string literals */
+ Delete(num);
+ Delete(trimmed);
+ return NewStringf("\"%s\"", num_param);
+ } else if (Len(num) >= 1 && (isdigit(s[0]) || s[0] == '+' || s[0] == '-')) {
+ /* use CL syntax for numbers */
+ String *oldnum = Copy(num);
+ int usuffixes = Replaceall(num, "u", "") + Replaceall(num, "U", "");
+ int lsuffixes = Replaceall(num, "l", "") + Replaceall(num, "L", "");
+ if (usuffixes > 1 || lsuffixes > 1) {
+ Printf(stderr, "Weird!! number %s looks invalid.\n", oldnum);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ s = Char(num);
+ if (s[0] == '0' && Len(num) >= 2) {
+ /*octal or hex */
+ res = NewStringf("#%c%s", tolower(s[1]) == 'x' ? 'x' : 'o', s + 2);
+ Delete(num);
+ } else {
+ res = num;
+ }
+ Delete(oldnum);
+ Delete(trimmed);
+ return res;
+ } else if (allegrocl->validIdentifier(num)) {
+ /* convert C/C++ identifiers to CL symbols */
+ res = NewStringf("#.(swig-insert-id \"%s\" %s :type :constant)", num, ns);
+ Delete(num);
+ Delete(trimmed);
+ Delete(ns);
+ return res;
+ } else {
+ Delete(trimmed);
+ return num;
+ }
+}
+
+
+void emit_stub_class(Node *n) {
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_stub_class: ENTER... '%s'(%x)\n", Getattr(n, "sym:name"), n);
+#endif
+
+
+ String *name = Getattr(n, "sym:name");
+
+ if (Getattr(n, "allegrocl:synonym:already-been-stubbed"))
+ return;
+
+ if (SwigType_istemplate(name)) {
+ String *temp = strip_namespaces(SwigType_templateprefix(name));
+ name = NewStringf("%s%s%s", temp, SwigType_templateargs(name), SwigType_templatesuffix(name));
+
+ Delete(temp);
+ } else {
+ name = strip_namespaces(name);
+ }
+
+ // Printf(f_clhead, ";; from emit-stub-class\n");
+ update_package_if_needed(n, f_clhead);
+ Printf(f_clhead, ";; class template stub.\n");
+ Printf(f_clhead, "(swig-def-foreign-stub \"%s\")\n", name);
+
+ Setattr(n, "allegrocl:synonym:already-been-stubbed", "1");
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_stub_class: EXIT\n");
+#endif
+}
+
+void emit_synonym(Node *synonym) {
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_synonym: ENTER... \n");
+#endif
+
+ // Printf(stderr,"in emit_synonym for %s(%x)\n", Getattr(synonym,"name"),synonym);
+ int is_tempInst = !Strcmp(nodeType(synonym), "templateInst");
+ String *synonym_type;
+
+ Node *of = get_primary_synonym_of(synonym);
+
+ if (is_tempInst) {
+ // Printf(stderr, "*** using real-name '%s'\n", Getattr(synonym,"real-name"));
+ synonym_type = Getattr(synonym, "real-name");
+ } else {
+ // Printf(stderr, "*** using name '%s'\n", Getattr(synonym,"name"));
+ synonym_type = Getattr(synonym, "name");
+ }
+
+ String *synonym_ns = listify_namespace(Getattr(synonym, "allegrocl:namespace"));
+ String *syn_ltype, *syn_type, *of_ltype;
+ // String *of_cdeclname = Getattr(of,"allegrocl:classDeclarationName");
+ String *of_ns = Getattr(of, "allegrocl:namespace");
+ String *of_ns_list = listify_namespace(of_ns);
+ // String *of_name = of_cdeclname ? NewStringf("struct %s", Getattr(of,"name")) : NewStringf("%s::%s", of_ns, Getattr(of,"sym:name"));
+ // String *of_name = NewStringf("%s::%s", of_ns, Getattr(of,"sym:name"));
+ String *of_name = namespaced_name(of, of_ns);
+
+ if (CPlusPlus && !Strcmp(nodeType(synonym), "cdecl")) {
+ syn_ltype = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)",
+ strip_namespaces(Getattr(synonym, "real-name")), synonym_ns);
+ syn_type = NewStringf("#.(swig-insert-id \"%s\" %s :type :type)",
+ strip_namespaces(Getattr(synonym, "real-name")), synonym_ns);
+ } else {
+ syn_ltype = lookup_defined_foreign_ltype(synonym_type);
+ syn_type = lookup_defined_foreign_type(synonym_type);
+ }
+
+ of_ltype = lookup_defined_foreign_ltype(of_name);
+
+ // Printf(stderr,";; from emit-synonym syn='%s' of_ltype='%s'\n", syn_ltype, of_ltype);
+ if( of_ltype )
+ Printf(f_clhead, "(swig-def-synonym-type %s\n %s\n %s)\n", syn_ltype, of_ltype, syn_type);
+
+ Delete(synonym_ns);
+ Delete(of_ns_list);
+ Delete(of_name);
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_synonym: EXIT\n");
+#endif
+}
+
+void emit_full_class(Node *n) {
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_full_class: ENTER... \n");
+#endif
+
+ String *name = Getattr(n, "sym:name");
+ String *kind = Getattr(n, "kind");
+
+ // Printf(stderr,"in emit_full_class: '%s'(%x).", Getattr(n,"name"),n);
+ if (Getattr(n, "allegrocl:synonym-of")) {
+ // Printf(stderr,"but it's a synonym of something.\n");
+ update_package_if_needed(n, f_clhead);
+ emit_synonym(n);
+ return;
+ }
+ // collect superclasses
+ String *bases = Getattr(n, "bases");
+ String *supers = NewString("(");
+ if (bases) {
+ int first = 1;
+ for (Iterator i = First(bases); i.item; i = Next(i)) {
+ if (!first)
+ Printf(supers, " ");
+ String *s = lookup_defined_foreign_ltype(Getattr(i.item, "name"));
+ // String *name = Getattr(i.item,"name");
+ if (s) {
+ Printf(supers, "%s", s);
+ } else {
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "emit_templ_inst: did not find ltype for base class %s (%s)", Getattr(i.item, "name"), Getattr(n, "allegrocl:namespace"));
+#endif
+ }
+ }
+ } else {
+ Printf(supers, "ff:foreign-pointer");
+ }
+
+ Printf(supers, ")");
+
+ // Walk children to generate type definition.
+ String *slotdefs = NewString(" ");
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, " walking children...\n");
+#endif
+
+ Node *c;
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ String *storage_type = Getattr(c, "storage");
+ if ((!Strcmp(nodeType(c), "cdecl") && (!storage_type || Strcmp(storage_type, "typedef")))) {
+ String *access = Getattr(c, "access");
+
+ // hack. why would decl have a value of "variableHandler" and now "0"?
+ String *childDecl = Getattr(c, "decl");
+ // Printf(stderr,"childDecl = '%s' (%s)\n", childDecl, Getattr(c,"view"));
+ if (!Strcmp(childDecl, "0"))
+ childDecl = NewString("");
+
+ SwigType *childType;
+ String *cname;
+
+ // don't include types for private slots (yet). spr33959.
+ if(access && Strcmp(access,"public")) {
+ childType = NewStringf("int");
+ cname = NewString("nil");
+ } else {
+ childType = NewStringf("%s%s", childDecl, Getattr(c, "type"));
+ cname = Copy(Getattr(c, "name"));
+ }
+
+ if (!SwigType_isfunction(childType)) {
+ // Printf(slotdefs, ";;; member functions don't appear as slots.\n ");
+ // Printf(slotdefs, ";; ");
+ String *ns = listify_namespace(Getattr(n, "allegrocl:package"));
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "slot name = '%s' ns = '%s' class-of '%s' and type = '%s'\n", cname, ns, name, childType);
+#endif
+ Printf(slotdefs, "(#.(swig-insert-id \"%s\" %s :type :slot :class \"%s\") %s)", cname, ns, name, compose_foreign_type(n, childType));
+ Delete(ns);
+ if (access && Strcmp(access, "public"))
+ Printf(slotdefs, " ;; %s member", access);
+
+ Printf(slotdefs, "\n ");
+ }
+ Delete(childType);
+ Delete(cname);
+ }
+ }
+
+ String *ns_list = listify_namespace(Getattr(n, "allegrocl:namespace"));
+ update_package_if_needed(n, f_clhead);
+ Printf(f_clhead, "(swig-def-foreign-class \"%s\"\n %s\n (:%s\n%s))\n\n", name, supers, kind, slotdefs);
+
+ Delete(supers);
+ Delete(ns_list);
+
+ Setattr(n, "allegrocl:synonym:already-been-stubbed", "1");
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_full_class: EXIT\n");
+#endif
+
+}
+
+void emit_class(Node *n) {
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_class: ENTER... '%s'(%x)\n", Getattr(n, "sym:name"), n);
+#endif
+
+ int is_tempInst = !Strcmp(nodeType(n), "templateInst");
+
+ String *ns_list = listify_namespace(Getattr(n, "allegrocl:namespace"));
+ String *name = Getattr(n, is_tempInst ? "real-name" : "name");
+
+ if (SwigType_istemplate(name)) {
+ String *temp = strip_namespaces(SwigType_templateprefix(name));
+ name = NewStringf("%s%s%s", temp, SwigType_templateargs(name), SwigType_templatesuffix(name));
+
+ Delete(temp);
+ } else {
+ name = strip_namespaces(name);
+ }
+
+ if (Getattr(n, "allegrocl:synonym:is-primary")) {
+ // Printf(stderr," is primary... ");
+ if (is_tempInst) {
+ emit_stub_class(n);
+ } else {
+ emit_full_class(n);
+ }
+ } else {
+ // Node *primary = Getattr(n,"allegrocl:synonym-of");
+ Node *primary = get_primary_synonym_of(n);
+ if (primary && (primary != n)) {
+ // Printf(stderr," emitting synonym... ");
+ emit_stub_class(primary);
+ update_package_if_needed(n, f_clhead);
+ emit_synonym(n);
+ } else {
+ emit_full_class(n);
+ }
+ }
+ // Printf(stderr,"DONE\n");
+ Delete(name);
+ Delete(ns_list);
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_class: EXIT\n");
+#endif
+}
+
+void emit_typedef(Node *n) {
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_typedef: ENTER... \n");
+#endif
+
+ String *name;
+ String *sym_name = Getattr(n, "sym:name");
+ String *type = NewStringf("%s%s", Getattr(n, "decl"), Getattr(n, "type"));
+ String *lisp_type = compose_foreign_type(n, type);
+ Delete(type);
+ Node *in_class = Getattr(n, "allegrocl:typedef:in-class");
+
+ // Printf(stderr,"in emit_typedef: '%s'(%x).",Getattr(n,"name"),n);
+ if (Getattr(n, "allegrocl:synonym-of")) {
+ // Printf(stderr," but it's a synonym of something.\n");
+ emit_synonym(n);
+ return;
+ }
+
+ if (in_class) {
+ String *class_name = Getattr(in_class, "name");
+ if (SwigType_istemplate(class_name)) {
+ String *temp = strip_namespaces(SwigType_templateprefix(class_name));
+ class_name = NewStringf("%s%s%s", temp, SwigType_templateargs(class_name), SwigType_templatesuffix(class_name));
+ Delete(temp);
+ }
+
+ name = NewStringf("%s__%s", class_name, sym_name);
+ Setattr(n, "allegrocl:in-class", in_class);
+ } else {
+ name = sym_name ? Copy(sym_name) : Copy(Getattr(n, "name"));
+ }
+
+ // leave these in for now. might want to change these to def-foreign-class at some point.
+// Printf(f_clhead, ";; %s\n", SwigType_typedef_resolve_all(lisp_type));
+ Printf(f_clhead, "(swig-def-foreign-type \"%s\"\n %s)\n", name, lisp_type);
+
+ Delete(name);
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_typedef: EXIT\n");
+#endif
+}
+
+void emit_enum_type_no_wrap(Node *n) {
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_enum_type_no_wrap: ENTER... \n");
+#endif
+
+ String *unnamed = Getattr(n, "unnamed");
+ String *name;
+ // SwigType *enumtype;
+
+ name = unnamed ? Getattr(n, "allegrocl:name") : Getattr(n, "sym:name");
+ SwigType *tmp = NewStringf("enum %s", unnamed ? unnamed : name);
+
+ Node *node = NewHash();
+ Setattr(node, "type", tmp);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *enumtype = Swig_typemap_lookup("ffitype", node, "", 0);
+ Delete(node);
+
+ Delete(tmp);
+
+ if (name) {
+ String *ns = listify_namespace(current_namespace);
+
+ Printf(f_clhead, "(swig-def-foreign-type \"%s\" %s)\n", name, enumtype);
+ Delete(ns);
+
+ // walk children.
+ Node *c;
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ if (!Getattr(c, "error")) {
+ String *val = Getattr(c, "enumvalue");
+ if (!val)
+ val = Getattr(c, "enumvalueex");
+ String *converted_val = convert_literal(val, Getattr(c, "type"));
+ String *valname = Getattr(c, "sym:name");
+
+ if (converted_val) {
+ Printf(f_clhead, "(swig-defconstant \"%s\" %s)\n", valname, converted_val);
+ Delete(converted_val);
+ } else {
+ Swig_warning(WARN_LANG_DISCARD_CONST, Getfile(n), Getline(n), "Unable to parse enum value '%s'. Setting to NIL\n", val);
+ Printf(f_clhead, "(swig-defconstant \"%s\" nil #| %s |#)\n", valname, val);
+ }
+ }
+ }
+ }
+ Printf(f_clhead, "\n");
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_enum_type_no_wrap: EXIT\n");
+#endif
+
+}
+
+void emit_enum_type(Node *n) {
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_enum_type: ENTER... \n");
+#endif
+
+ if (!Generate_Wrapper) {
+ emit_enum_type_no_wrap(n);
+ return;
+ }
+
+ String *unnamed = Getattr(n, "unnamed");
+ String *name;
+ // SwigType *enumtype;
+
+ name = unnamed ? Getattr(n, "allegrocl:name") : Getattr(n, "sym:name");
+ SwigType *tmp = NewStringf("enum %s", unnamed ? unnamed : name);
+
+ Node *node = NewHash();
+ Setattr(node, "type", tmp);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *enumtype = Swig_typemap_lookup("ffitype", node, "", 0);
+ Delete(node);
+
+ Delete(tmp);
+
+ if (name) {
+ String *ns = listify_namespace(current_namespace);
+
+ Printf(f_clhead, "(swig-def-foreign-type \"%s\" %s)\n", name, enumtype);
+ Delete(ns);
+
+ // walk children.
+ Node *c;
+ for(c = firstChild(n); c; c=nextSibling(c)) {
+ String *mangled_name = mangle_name(c, "ACL_ENUM", Getattr(c,"allegrocl:package"));
+ Printf(f_clhead, "(swig-defvar \"%s\" \"%s\" :type :constant :ftype :signed-long)\n", Getattr(c, "sym:name"), mangled_name);
+ Delete(mangled_name);
+ }
+ }
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_enum_type: EXIT\n");
+#endif
+
+}
+
+void emit_default_linked_type(Node *n) {
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_default_linked_type: ENTER... \n");
+#endif
+
+ // catchall for non class types.
+ if (!Strcmp(nodeType(n), "classforward")) {
+ Printf(f_clhead, ";; forward referenced stub.\n");
+ Printf(f_clhead, "(swig-def-foreign-class \"%s\" (ff:foreign-pointer) (:class ))\n\n", Getattr(n, "sym:name"));
+ } else if (!Strcmp(nodeType(n), "enum")) {
+ emit_enum_type(n);
+ } else {
+ Printf(stderr, "Don't know how to emit node type '%s' named '%s'\n", nodeType(n), Getattr(n, "name"));
+ }
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_default_linked_type: EXIT\n");
+#endif
+
+}
+
+void dump_linked_types(File *f) {
+ Node *n = first_linked_type;
+ int i = 0;
+ while (n) {
+ Printf(f, "%d: (%x) node '%s' name '%s'\n", i++, n, nodeType(n), Getattr(n, "sym:name"));
+
+ Node *t = Getattr(n, "allegrocl:synonym-of");
+ if (t)
+ Printf(f, " synonym-of %s(%x)\n", Getattr(t, "name"), t);
+ n = Getattr(n, "allegrocl:next_linked_type");
+ }
+}
+
+void emit_linked_types() {
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_linked_types: ENTER... ");
+#endif
+
+ Node *n = first_linked_type;
+
+ while (n) {
+ String *node_type = nodeType(n);
+
+ // Printf(stderr,"emitting node %s(%x) of type %s.", Getattr(n,"name"),n, nodeType(n));
+ if (!Strcmp(node_type, "class") || !Strcmp(node_type, "templateInst")) {
+ // may need to emit a stub, so it will update the package itself.
+ // Printf(stderr," Passing to emit_class.");
+ emit_class(n);
+ } else if (!Strcmp(nodeType(n), "cdecl")) {
+ // Printf(stderr," Passing to emit_typedef.");
+ update_package_if_needed(n, f_clhead);
+ emit_typedef(n);
+ } else {
+ // Printf(stderr," Passing to default_emitter.");
+ update_package_if_needed(n, f_clhead);
+ emit_default_linked_type(n);
+ }
+
+ n = Getattr(n, "allegrocl:next_linked_type");
+ // Printf(stderr,"returned.\n");
+ }
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_linked_types: EXIT\n");
+#endif
+}
+
+extern "C" Language *swig_allegrocl(void) {
+ return (allegrocl = new ALLEGROCL());
+}
+
+void ALLEGROCL::main(int argc, char *argv[]) {
+ int i;
+
+ Preprocessor_define("SWIGALLEGROCL 1", 0);
+ SWIG_library_directory("allegrocl");
+ SWIG_config_file("allegrocl.swg");
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-identifier-converter")) {
+ char *conv = argv[i + 1];
+
+ if (!conv)
+ Swig_arg_error();
+
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+
+ /* check for built-ins */
+ if (!strcmp(conv, "lispify")) {
+ identifier_converter = "identifier-convert-lispify";
+ } else if (!strcmp(conv, "null")) {
+ identifier_converter = "identifier-convert-null";
+ } else {
+ /* Must be user defined */
+ char *idconv = new char[strlen(conv) + 1];
+ strcpy(idconv, conv);
+ identifier_converter = idconv;
+ }
+ } else if (!strcmp(argv[i], "-cwrap")) {
+ CWrap = true;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i], "-nocwrap")) {
+ CWrap = false;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i], "-isolate")) {
+ unique_swig_package = true;
+ Swig_mark_arg(i);
+ }
+
+ if (!strcmp(argv[i], "-help")) {
+ fprintf(stdout, "Allegro CL Options (available with -allegrocl)\n");
+ fprintf(stdout,
+ " -identifier-converter <type or funcname>\n"
+ "\tSpecifies the type of conversion to do on C identifiers to convert\n"
+ "\tthem to symbols. There are two built-in converters: 'null' and\n"
+ "\t 'lispify'. The default is 'null'. If you supply a name other\n"
+ "\tthan one of the built-ins, then a function by that name will be\n"
+ "\tcalled to convert identifiers to symbols.\n"
+ "\n"
+ " -[no]cwrap\n"
+ "\tTurn on or turn off generation of an intermediate C file when\n" "\tcreating a C interface. By default this is only done for C++ code.\n"
+ " -isolate\n"
+ "Define all SWIG helper functions in a package unique to this module. Avoids redefinition warnings when loading multiple SWIGged modules\n"
+ "into the same running Allegro CL image.\n");
+
+ }
+
+ }
+
+ allow_overloading();
+}
+
+int ALLEGROCL::top(Node *n) {
+ module_name = Getattr(n, "name");
+ String *cxx_filename = Getattr(n, "outfile");
+ String *cl_filename = NewString("");
+
+ swig_package = unique_swig_package ? NewStringf("swig.%s", module_name) : NewString("swig");
+
+ Printf(cl_filename, "%s%s.cl", SWIG_output_directory(), module_name);
+
+ f_cl = NewFile(cl_filename, "w", SWIG_output_files());
+ if (!f_cl) {
+ Printf(stderr, "Unable to open %s for writing\n", cl_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Generate_Wrapper = CPlusPlus || CWrap;
+
+ if (Generate_Wrapper) {
+ f_begin = NewFile(cxx_filename, "w", SWIG_output_files());
+ if (!f_begin) {
+ Close(f_cl);
+ Delete(f_cl);
+ Printf(stderr, "Unable to open %s for writing\n", cxx_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ } else
+ f_begin = NewString("");
+
+ f_runtime = NewString("");
+ f_cxx_header = f_runtime;
+ f_cxx_wrapper = NewString("");
+
+ Swig_register_filebyname("header", f_cxx_header);
+ Swig_register_filebyname("wrapper", f_cxx_wrapper);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("lisp", f_clwrap);
+ Swig_register_filebyname("lisphead", f_cl);
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGALLEGROCL\n");
+ Printf(f_runtime, "\n");
+
+ Swig_banner_target_lang(f_cl, ";;");
+
+ Printf(f_cl, "\n"
+ "(defpackage :%s\n"
+ " (:use :common-lisp :ff :excl)\n"
+ " (:export #:*swig-identifier-converter* #:*swig-module-name*\n"
+ " #:*void* #:*swig-export-list*))\n"
+ "(in-package :%s)\n\n"
+ "(eval-when (:compile-toplevel :load-toplevel :execute)\n"
+ " (defparameter *swig-identifier-converter* '%s)\n"
+ " (defparameter *swig-module-name* :%s))\n\n", swig_package, swig_package, identifier_converter, module_name);
+ Printf(f_cl, "(defpackage :%s\n" " (:use :common-lisp :%s :ff :excl))\n\n", module_name, swig_package);
+
+ Printf(f_clhead, "(in-package :%s)\n", module_name);
+
+ // Swig_print_tree(n);
+
+ Language::top(n);
+
+ // SwigType_emit_type_table(f_runtime,f_cxx_wrapper);
+
+ // Swig_print_tree(n);
+#ifdef ALLEGROCL_TYPE_DEBUG
+ dump_linked_types(stderr);
+#endif
+ emit_linked_types();
+
+ Printf(f_clwrap, "\n(cl::in-package :%s)\n", swig_package);
+ Printf(f_clwrap, "\n(macrolet ((swig-do-export ()\n");
+ Printf(f_clwrap, " `(dolist (s ',*swig-export-list*)\n");
+ Printf(f_clwrap, " (apply #'export s))))\n");
+ Printf(f_clwrap, " (swig-do-export))\n");
+ Printf(f_clwrap, "\n(setq *swig-export-list* nil)\n");
+
+ Printf(f_cl, "%s\n", f_clhead);
+ Printf(f_cl, "%s\n", f_clwrap);
+
+ Close(f_cl);
+ Delete(f_cl); // Delete the handle, not the file
+ Delete(f_clhead);
+ Delete(f_clwrap);
+
+ Dump(f_runtime, f_begin);
+ Printf(f_begin, "%s\n", f_cxx_wrapper);
+
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+ Delete(f_cxx_wrapper);
+
+ // Swig_print_tree(n);
+
+ return SWIG_OK;
+}
+
+/* very shamelessly 'borrowed' from overload.cxx, which
+ keeps the below Swig_overload_rank() code to itself.
+ We don't need a dispatch function in the C++ wrapper
+ code; we want it over on the lisp side. */
+
+#define MAX_OVERLOAD 256
+
+/* Overload "argc" and "argv" */
+// String *argv_template_string;
+// String *argc_template_string;
+
+struct Overloaded {
+ Node *n; /* Node */
+ int argc; /* Argument count */
+ ParmList *parms; /* Parameters used for overload check */
+ int error; /* Ambiguity error */
+};
+
+/* -----------------------------------------------------------------------------
+ * Swig_overload_rank()
+ *
+ * This function takes an overloaded declaration and creates a list that ranks
+ * all overloaded methods in an order that can be used to generate a dispatch
+ * function.
+ * Slight difference in the way this function is used by scripting languages and
+ * statically typed languages. The script languages call this method via
+ * Swig_overload_dispatch() - where wrappers for all overloaded methods are generated,
+ * however sometimes the code can never be executed. The non-scripting languages
+ * call this method via Swig_overload_check() for each overloaded method in order
+ * to determine whether or not the method should be wrapped. Note the slight
+ * difference when overloading methods that differ by const only. The
+ * scripting languages will ignore the const method, whereas the non-scripting
+ * languages ignore the first method parsed.
+ * ----------------------------------------------------------------------------- */
+
+static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
+ Overloaded nodes[MAX_OVERLOAD];
+ int nnodes = 0;
+ Node *o = Getattr(n, "sym:overloaded");
+ Node *c;
+
+ if (!o)
+ return 0;
+
+ c = o;
+ while (c) {
+ if (Getattr(c, "error")) {
+ c = Getattr(c, "sym:nextSibling");
+ continue;
+ }
+ /* if (SmartPointer && Getattr(c,"cplus:staticbase")) {
+ c = Getattr(c,"sym:nextSibling");
+ continue;
+ } */
+
+ /* Make a list of all the declarations (methods) that are overloaded with
+ * this one particular method name */
+ if (Getattr(c, "wrap:name")) {
+ nodes[nnodes].n = c;
+ nodes[nnodes].parms = Getattr(c, "wrap:parms");
+ nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
+ nodes[nnodes].error = 0;
+ nnodes++;
+ }
+ c = Getattr(c, "sym:nextSibling");
+ }
+
+ /* Sort the declarations by required argument count */
+ {
+ int i, j;
+ for (i = 0; i < nnodes; i++) {
+ for (j = i + 1; j < nnodes; j++) {
+ if (nodes[i].argc > nodes[j].argc) {
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ }
+ }
+ }
+ }
+
+ /* Sort the declarations by argument types */
+ {
+ int i, j;
+ for (i = 0; i < nnodes - 1; i++) {
+ if (nodes[i].argc == nodes[i + 1].argc) {
+ for (j = i + 1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
+ Parm *p1 = nodes[i].parms;
+ Parm *p2 = nodes[j].parms;
+ int differ = 0;
+ int num_checked = 0;
+ while (p1 && p2 && (num_checked < nodes[i].argc)) {
+ // Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
+ if (checkAttribute(p1, "tmap:in:numinputs", "0")) {
+ p1 = Getattr(p1, "tmap:in:next");
+ continue;
+ }
+ if (checkAttribute(p2, "tmap:in:numinputs", "0")) {
+ p2 = Getattr(p2, "tmap:in:next");
+ continue;
+ }
+ String *t1 = Getattr(p1, "tmap:typecheck:precedence");
+ String *t2 = Getattr(p2, "tmap:typecheck:precedence");
+ if ((!t1) && (!nodes[i].error)) {
+ Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
+ "Overloaded method %s not supported (no type checking rule for '%s').\n",
+ Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0));
+ nodes[i].error = 1;
+ } else if ((!t2) && (!nodes[j].error)) {
+ Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s not supported (no type checking rule for '%s').\n",
+ Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0));
+ nodes[j].error = 1;
+ }
+ if (t1 && t2) {
+ int t1v, t2v;
+ t1v = atoi(Char(t1));
+ t2v = atoi(Char(t2));
+ differ = t1v - t2v;
+ } else if (!t1 && t2)
+ differ = 1;
+ else if (t1 && !t2)
+ differ = -1;
+ else if (!t1 && !t2)
+ differ = -1;
+ num_checked++;
+ if (differ > 0) {
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ break;
+ } else if ((differ == 0) && (Strcmp(t1, "0") == 0)) {
+ t1 = Getattr(p1, "ltype");
+ if (!t1) {
+ t1 = SwigType_ltype(Getattr(p1, "type"));
+ if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) {
+ SwigType_add_pointer(t1);
+ }
+ Setattr(p1, "ltype", t1);
+ }
+ t2 = Getattr(p2, "ltype");
+ if (!t2) {
+ t2 = SwigType_ltype(Getattr(p2, "type"));
+ if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) {
+ SwigType_add_pointer(t2);
+ }
+ Setattr(p2, "ltype", t2);
+ }
+
+ /* Need subtype check here. If t2 is a subtype of t1, then we need to change the
+ order */
+
+ if (SwigType_issubtype(t2, t1)) {
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ }
+
+ if (Strcmp(t1, t2) != 0) {
+ differ = 1;
+ break;
+ }
+ } else if (differ) {
+ break;
+ }
+ if (Getattr(p1, "tmap:in:next")) {
+ p1 = Getattr(p1, "tmap:in:next");
+ } else {
+ p1 = nextSibling(p1);
+ }
+ if (Getattr(p2, "tmap:in:next")) {
+ p2 = Getattr(p2, "tmap:in:next");
+ } else {
+ p2 = nextSibling(p2);
+ }
+ }
+ if (!differ) {
+ /* See if declarations differ by const only */
+ String *d1 = Getattr(nodes[i].n, "decl");
+ String *d2 = Getattr(nodes[j].n, "decl");
+ if (d1 && d2) {
+ String *dq1 = Copy(d1);
+ String *dq2 = Copy(d2);
+ if (SwigType_isconst(d1)) {
+ Delete(SwigType_pop(dq1));
+ }
+ if (SwigType_isconst(d2)) {
+ Delete(SwigType_pop(dq2));
+ }
+ if (Strcmp(dq1, dq2) == 0) {
+
+ if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
+ if (script_lang_wrapping) {
+ // Swap nodes so that the const method gets ignored (shadowed by the non-const method)
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ }
+ differ = 1;
+ if (!nodes[j].error) {
+ if (script_lang_wrapping) {
+ Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n",
+ Getattr(nodes[j].n, "name"), ParmList_errorstr(nodes[j].parms), Getfile(nodes[i].n), Getline(nodes[i].n));
+ } else {
+ if (!Getattr(nodes[j].n, "overload:ignore"))
+ Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s(%s) ignored. Method %s(%s) const at %s:%d used.\n",
+ Getattr(nodes[j].n, "name"), ParmList_errorstr(nodes[j].parms),
+ Getattr(nodes[i].n, "name"), ParmList_errorstr(nodes[i].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) {
+ if (script_lang_wrapping) {
+ 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_errorstr(nodes[j].parms), Getfile(nodes[i].n), Getline(nodes[i].n));
+ } else {
+ if (!Getattr(nodes[j].n, "overload:ignore"))
+ Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s(%s) const ignored. Method %s(%s) at %s:%d used.\n",
+ Getattr(nodes[j].n, "name"), ParmList_errorstr(nodes[j].parms),
+ Getattr(nodes[i].n, "name"), ParmList_errorstr(nodes[i].parms), Getfile(nodes[i].n), Getline(nodes[i].n));
+ }
+ }
+ nodes[j].error = 1;
+ }
+ }
+ Delete(dq1);
+ Delete(dq2);
+ }
+ }
+ if (!differ) {
+ if (!nodes[j].error) {
+ if (script_lang_wrapping) {
+ Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s is shadowed by %s at %s:%d.\n",
+ Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ } else {
+ if (!Getattr(nodes[j].n, "overload:ignore"))
+ Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s ignored. Method %s at %s:%d used.\n",
+ Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ }
+ nodes[j].error = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ List *result = NewList();
+ {
+ int i;
+ for (i = 0; i < nnodes; i++) {
+ if (nodes[i].error)
+ Setattr(nodes[i].n, "overload:ignore", "1");
+ Append(result, nodes[i].n);
+ // Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms));
+ // Swig_print_node(nodes[i].n);
+ }
+ }
+ return result;
+}
+
+/* end shameless borrowing */
+
+int any_varargs(ParmList *pl) {
+ Parm *p;
+
+ for (p = pl; p; p = nextSibling(p)) {
+ if (SwigType_isvarargs(Getattr(p, "type")))
+ return 1;
+ }
+
+ return 0;
+}
+
+String *get_lisp_type(Node *n, SwigType *ty, const_String_or_char_ptr name) {
+ Node *node = NewHash();
+ Setattr(node, "type", ty);
+ Setattr(node, "name", name);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *tm = Swig_typemap_lookup("lisptype", node, "", 0);
+ Delete(node);
+
+ return tm ? NewString(tm) : NewString("");
+}
+
+Node *parent_node_skipping_extends(Node *n) {
+ Node *result = n;
+ do {
+ result = parentNode(result);
+ }
+ while (Cmp("extend", nodeType(result)) == 0);
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_num_lin_arguments()
+ *
+ * Calculate the total number of arguments. This function is safe for use
+ * with multi-argument typemaps which may change the number of arguments in
+ * strange ways.
+ * ----------------------------------------------------------------------------- */
+
+int emit_num_lin_arguments(ParmList *parms) {
+ Parm *p = parms;
+ int nargs = 0;
+
+ while (p) {
+ // Printf(stderr,"enla: '%s' lin='%x'\n", Getattr(p,"name"), Getattr(p,"tmap:lin"));
+ if (Getattr(p, "tmap:lin")) {
+ nargs += GetInt(p, "tmap:lin:numinputs");
+ p = Getattr(p, "tmap:lin:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* DB 04/02/2003: Not sure this is necessary with tmap:in:numinputs */
+ /*
+ if (parms && (p = Getattr(parms,"emit:varargs"))) {
+ if (!nextSibling(p)) {
+ nargs--;
+ }
+ }
+ */
+ return nargs;
+}
+
+String *id_converter_type(SwigType const *type) {
+ SwigType *t = Copy(type);
+ String *result = 0;
+
+ if (SwigType_ispointer(t)) {
+ SwigType_pop(t);
+ String *pointee = id_converter_type(t);
+ result = NewStringf("(:* %s)", pointee);
+ Delete(pointee);
+ } else if (SwigType_ismemberpointer(t)) {
+ String *klass = SwigType_parm(t);
+ SwigType_pop(t);
+ String *member = id_converter_type(t);
+ result = NewStringf("(:member \"%s\" %s)", klass, member);
+ Delete(klass);
+ Delete(member);
+ } else if (SwigType_isreference(t)) {
+ SwigType_pop(t);
+ String *referencee = id_converter_type(t);
+ result = NewStringf("(:& %s)", referencee);
+ Delete(referencee);
+ } else if (SwigType_isarray(t)) {
+ String *size = SwigType_parm(t);
+ SwigType_pop(t);
+ String *element_type = id_converter_type(t);
+ result = NewStringf("(:array %s \"%s\")", element_type, size);
+ Delete(size);
+ Delete(element_type);
+ } else if (SwigType_isfunction(t)) {
+ result = NewString("(:function (");
+ String *parmlist_str = SwigType_parm(t);
+ List *parms = SwigType_parmlist(parmlist_str);
+
+ for (Iterator i = First(parms); i.item;) {
+ String *parm = id_converter_type((SwigType *) i.item);
+ Printf(result, "%s", parm);
+ i = Next(i);
+ if (i.item)
+ Printf(result, " ");
+ Delete(parm);
+ }
+ SwigType_pop(t);
+ String *ret = id_converter_type(t);
+ Printf(result, ") %s)", ret);
+
+ Delete(parmlist_str);
+ Delete(parms);
+ Delete(ret);
+ } else if (SwigType_isqualifier(t)) {
+ result = NewString("(:qualified (");
+ String *qualifiers_str = Copy(SwigType_parm(t)); // ?!
+ // Replaceall below SEGVs if we don't put the Copy here...
+ SwigType_pop(t);
+ String *qualifiee = id_converter_type(t);
+
+ Replaceall(qualifiers_str, " ", " :");
+ if (Len(qualifiers_str) > 0)
+ Printf(result, ":");
+ Printf(result, "%s) %s)", qualifiers_str, qualifiee);
+
+ Delete(qualifiers_str);
+ Delete(qualifiee);
+ } else if (SwigType_istemplate(t)) {
+ result = NewStringf("(:template \"%s\")", t);
+ } else { /* if (SwigType_issimple(t)) */
+
+ if (Strstr(Char(t), "::")) {
+ result = listify_namespace(t);
+ } else {
+ result = NewStringf("\"%s\"", t);
+ }
+ }
+
+ Delete(t);
+ return result;
+}
+
+static ParmList *parmlist_with_names(ParmList *pl) {
+ ParmList *pl2 = CopyParmList(pl);
+ for (Parm *p = pl, *p2 = pl2; p2; p = nextSibling(p), p2 = nextSibling(p2)) {
+ if (!Getattr(p2, "name"))
+ Setattr(p2, "name", Getattr(p2, "lname"));
+ Setattr(p2, "name", strip_namespaces(Getattr(p2, "name")));
+ Setattr(p2, "tmap:ctype", Getattr(p, "tmap:ctype"));
+
+ String *temp = Getattr(p, "tmap:lin");
+ if (temp) {
+ Setattr(p2, "tmap:lin", temp);
+ Setattr(p2, "tmap:lin:next", Getattr(p, "tmap:lin:next"));
+ }
+ }
+ return pl2;
+}
+
+static String *parmlist_str_id_converter(ParmList *pl) {
+ String *result = NewString("");
+ for (Parm *p = pl; p;) {
+ String *lispy_type = id_converter_type(Getattr(p, "type"));
+ Printf(result, "(\"%s\" %s)", Getattr(p, "name"), lispy_type);
+ Delete(lispy_type);
+ if ((p = nextSibling(p)))
+ Printf(result, " ");
+ }
+ return result;
+}
+
+String *collect_others_args(Node *overload) {
+ String *overloaded_from = Getattr(overload, "sym:overloaded");
+ String *others_args = NewString("");
+ int first_overload = 1;
+
+ for (Node *overload2 = overloaded_from; overload2; overload2 = Getattr(overload2, "sym:nextSibling")) {
+ if (overload2 == overload || GetInt(overload2, "overload:ignore"))
+ continue;
+
+ ParmList *opl = parmlist_with_names(Getattr(overload2, "wrap:parms"));
+ String *args = parmlist_str_id_converter(opl);
+ if (!first_overload)
+ Printf(others_args, "\n ");
+ Printf(others_args, "(%s)", args);
+ Delete(args);
+ Delete(opl);
+ first_overload = 0;
+ }
+ return others_args;
+}
+
+struct IDargs {
+ String *name;
+ String *type;
+ String *klass;
+ String *arity;
+
+ IDargs():name(0), type(0), klass(0), arity(0) {
+ }
+
+ String *full_quoted_str() {
+ String *result = no_others_quoted_str();
+ if (arity)
+ Printf(result, " :arity %s", arity);
+ return result;
+ }
+
+ String *no_others_quoted_str() {
+ String *result = NewString("");
+ Printf(result, "\"%s\" :type :%s", name, type);
+ if (klass)
+ Printf(result, " :class \"%s\"", klass);
+ return result;
+ }
+
+ String *noname_str() {
+ String *result = NewString("");
+ Printf(result, " :type :%s", type);
+ if (klass)
+ Printf(result, " :class \"%s\"", klass);
+ if (arity)
+ Printf(result, " :arity %s", arity);
+ return result;
+ }
+};
+IDargs *id_converter_arguments(Node *n) {
+ IDargs *result = (IDargs *) GetVoid(n, "allegrocl:id-converter-args");
+ if (!result)
+ result = new IDargs;
+
+ // Base name
+ if (!result->name) {
+ result->name = Getattr(n, "allegrocl:old-sym:name");
+ if (!result->name)
+ result->name = Getattr(n, "sym:name");
+ result->name = Copy(result->name);
+ }
+ // :type
+ if (result->type)
+ Delete(result->type);
+ if (!Getattr(n, "allegrocl:kind"))
+ Setattr(n, "allegrocl:kind", "function");
+ if (Strstr(Getattr(n, "name"), "operator "))
+ Replaceall(Getattr(n, "allegrocl:kind"), "function", "operator");
+ if (Strstr(Getattr(n, "allegrocl:kind"), "variable")) {
+ int name_end = Len(Getattr(n, "sym:name")) - 4;
+ char *str = Char(Getattr(n, "sym:name"));
+ String *get_set = NewString(str + name_end + 1);
+ result->type = Copy(Getattr(n, "allegrocl:kind"));
+ Replaceall(result->type, "variable", "");
+ Printf(result->type, "%ster", get_set);
+ Delete(get_set);
+ } else {
+ result->type = Copy(Getattr(n, "allegrocl:kind"));
+ }
+
+ // :class
+ if (Strstr(result->type, "member ")) {
+ Replaceall(result->type, "member ", "");
+ if (!result->klass)
+ result->klass = Copy(Getattr(parent_node_skipping_extends(n), "sym:name"));
+ }
+ // :arity
+ if (Getattr(n, "sym:overloaded")) {
+ if (result->arity)
+ Delete(result->arity);
+ result->arity = NewStringf("%d",
+ // emit_num_arguments(Getattr(n, "wrap:parms")));
+ emit_num_lin_arguments(Getattr(n, "wrap:parms")));
+ // Printf(stderr, "got arity of '%s' node '%s' '%x'\n", result->arity, Getattr(n,"name"), Getattr(n,"wrap:parms"));
+ }
+
+ SetVoid(n, "allegrocl:id-converter-args", result);
+ return result;
+}
+
+int ALLEGROCL::emit_buffered_defuns(Node *n) {
+
+ Node *overloaded_from = Getattr(n, "sym:overloaded");
+
+ String *wrap;
+
+ if (!overloaded_from) {
+ wrap = Getattr(n, "allegrocl:lisp-wrap");
+
+ Printf(f_clwrap, "%s\n", wrap);
+ Delattr(n, "allegrocl:lisp-wrap");
+ Delete(wrap);
+ } else {
+ for (Node *overload = overloaded_from; overload; overload = Getattr(overload, "sym:nextSibling")) {
+ String *others_args = collect_others_args(overload);
+ wrap = Getattr(overload, "allegrocl:lisp-wrap");
+
+ Replaceall(wrap, "@@OTHERS-ARGS-GO-HERE@@", others_args);
+// IDargs* id_args = id_converter_arguments(overload);
+// Replaceall(id_args->others_args, "@@OTHERS-ARGS-GO-HERE@@", others_args);
+
+ if (!GetInt(overload, "overload:ignore"))
+ Printf(f_clwrap, "%s", wrap);
+
+ Delattr(overload, "allegrocl:lisp-wrap");
+ Delete(wrap);
+ }
+ }
+ return SWIG_OK;
+}
+
+String *dispatching_type(Node *n, Parm *p) {
+ String *result = 0;
+
+ String *parsed = Getattr(p, "type"); //Swig_cparse_type(Getattr(p,"tmap:ctype"));
+ String *cl_t = SwigType_typedef_resolve_all(parsed);
+
+ Node *node = NewHash();
+ Setattr(node, "type", parsed);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *tm = Swig_typemap_lookup("lispclass", node, Getattr(p, "name"), 0);
+ Delete(node);
+
+ if (tm) {
+ result = Copy(tm);
+ } else {
+ String *lookup_type = class_from_class_or_class_ref(parsed);
+ if (lookup_type)
+ result = lookup_defined_foreign_ltype(lookup_type);
+ }
+
+ // if (!result && SwigType_ispointer(cl_t)) {
+ // SwigType_pop(cl_t);
+ // result = lookup_defined_foreign_ltype(cl_t);
+ // }
+
+ if (!result)
+ result = NewStringf("ff:foreign-pointer");
+
+ // Delete(parsed);
+ Delete(cl_t);
+ return result;
+}
+
+int ALLEGROCL::emit_dispatch_defun(Node *n) {
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_dispatch_defun: ENTER... ");
+#endif
+ List *overloads = Swig_overload_rank(n, true);
+
+ String *id_args = id_converter_arguments(n)->no_others_quoted_str();
+ Printf(f_clwrap, "(swig-dispatcher (%s :arities (", id_args);
+
+ int last_arity = -1;
+ for (Iterator i = First(overloads); i.item; i = Next(i)) {
+ int arity = emit_num_lin_arguments(Getattr(i.item, "wrap:parms"));
+ if (arity == last_arity)
+ continue;
+
+ Printf(f_clwrap, "%s%d", last_arity == -1 ? "" : " ", arity);
+
+ last_arity = arity;
+ }
+ Printf(f_clwrap, ")))\n");
+
+ Delete(id_args);
+ Delete(overloads);
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_dispatch_defun: EXIT\n");
+#endif
+
+ return SWIG_OK;
+}
+
+int ALLEGROCL::emit_defun(Node *n, File *fcl) {
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_defun: ENTER... ");
+#endif
+
+#ifdef ALLEGROCL_DEBUG
+ int auto_generated = Cmp(Getattr(n, "view"), "globalfunctionHandler");
+ Printf(stderr, "%s%sfunction %s%s%s\n", auto_generated ? "> " : "", Getattr(n, "sym:overloaded")
+ ? "overloaded " : "", current_namespace, (current_namespace) > 0 ? "::" : "", Getattr(n, "sym:name"));
+ Printf(stderr, " (view: %s)\n", Getattr(n, "view"));
+#endif
+
+ String *funcname = Getattr(n, "allegrocl:old-sym:name");
+ if (!funcname)
+ funcname = Getattr(n, "sym:name");
+ String *mangled_name = Getattr(n, "wrap:name");
+ ParmList *pl = parmlist_with_names(Getattr(n, "wrap:parms"));
+
+ // attach typemap info.
+ Wrapper *wrap = NewWrapper();
+ Swig_typemap_attach_parms("lin", pl, wrap);
+ // Swig_typemap_attach_parms("ffitype", pl, wrap);
+ Swig_typemap_lookup("lout", n, "result", 0);
+
+ SwigType *result_type = Swig_cparse_type(Getattr(n, "tmap:ctype"));
+ // prime the pump, with support for OUTPUT, INOUT typemaps.
+ Printf(wrap->code,
+ "(cl::let ((ACL_ffresult %s:*void*)\n ACL_result)\n $body\n (cl::if (cl::eq ACL_ffresult %s:*void*)\n (cl::values-list ACL_result)\n (cl::values-list (cl::cons ACL_ffresult ACL_result))))",
+ swig_package, swig_package);
+
+ Parm *p;
+ int largnum = 0, argnum = 0, first = 1;
+ // int varargs=0;
+ if (Generate_Wrapper) {
+ String *extra_parms = id_converter_arguments(n)->noname_str();
+ if (Getattr(n, "sym:overloaded"))
+ Printf(fcl, "(swig-defmethod (\"%s\" \"%s\"%s)\n", funcname, mangled_name, extra_parms);
+ else
+ Printf(fcl, "(swig-defun (\"%s\" \"%s\"%s)\n", funcname, mangled_name, extra_parms);
+ Delete(extra_parms);
+ }
+ // Just C
+ else {
+ Printf(fcl, "(swig-defun (\"%s\" \"%s\")\n", funcname, Generate_Wrapper ? mangled_name : funcname);
+ }
+
+ //////////////////////////////////////
+ // Lisp foreign call parameter list //
+ //////////////////////////////////////
+ Printf(fcl, " (");
+
+ /* Special cases */
+
+ if (ParmList_len(pl) == 0) {
+ Printf(fcl, ":void");
+/* } else if (any_varargs(pl)) {
+ Printf(fcl, "#| varargs |#");
+ varargs=1; */
+ } else {
+ String *largs = NewString("");
+
+ for (p = pl; p; p = nextSibling(p), argnum++, largnum++) {
+ // SwigType *argtype=Getattr(p, "type");
+ SwigType *argtype = Swig_cparse_type(Getattr(p, "tmap:ctype"));
+ SwigType *parmtype = Getattr(p,"type");
+
+ if (!first) {
+ Printf(fcl, "\n ");
+ }
+
+ /* by default, skip varargs */
+ if (!SwigType_isvarargs(parmtype)) {
+ String *argname = NewStringf("PARM%d_%s", largnum, Getattr(p, "name"));
+
+ // Printf(stderr,"%s\n", Getattr(p,"tmap:lin"));
+ String *ffitype = compose_foreign_type(n, argtype, Getattr(p,"name"));
+ String *deref_ffitype = dereference_ffitype(ffitype);
+ String *lisptype = get_lisp_type(n, parmtype, Getattr(p, "name"));
+
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "lisptype of '%s' '%s' = '%s'\n", parmtype,
+ Getattr(p, "name"), lisptype);
+#endif
+
+ // while we're walking the parameters, generating LIN
+ // wrapper code...
+ Setattr(p, "lname", NewStringf("SWIG_arg%d", largnum));
+
+ String *parm_code = Getattr(p, "tmap:lin");
+ if (parm_code) {
+ String *lname = Getattr(p, "lname");
+
+ Printf(largs, " %s", lname);
+ Replaceall(parm_code, "$in_fftype", ffitype); // must come before $in
+ Replaceall(parm_code, "$in", argname);
+ Replaceall(parm_code, "$out", lname);
+ Replaceall(parm_code, "$*in_fftype", deref_ffitype);
+ Replaceall(wrap->code, "$body", parm_code);
+ }
+
+ String *dispatchtype = Getattr(n, "sym:overloaded") ? dispatching_type(n, p) : NewString("");
+
+ // if this parameter has been removed from the C/++ wrapper
+ // it shouldn't be in the lisp wrapper either.
+ if (!checkAttribute(p, "tmap:in:numinputs", "0")) {
+ Printf(fcl, "(%s %s %s %s %s)",
+ // parms in the ff wrapper, but not in the lisp wrapper.
+ (checkAttribute(p, "tmap:lin:numinputs", "0") ? ":p-" : ":p+"), argname, dispatchtype, ffitype, lisptype);
+
+ first = 0;
+ }
+
+ Delete(argname);
+ Delete(ffitype);
+ Delete(deref_ffitype);
+ Delete(lisptype);
+ }
+ }
+
+ Printf(wrap->locals, "%s", largs);
+ }
+
+ String *lout = Getattr(n, "tmap:lout");
+ Replaceall(lout, "$owner", GetFlag(n, "feature:new") ? "t" : "nil");
+
+ Replaceall(wrap->code, "$body", lout);
+ // $lclass handling.
+ String *lclass = (String *) 0;
+ SwigType *parsed = Swig_cparse_type(Getattr(n, "tmap:ctype"));
+ // SwigType *cl_t = SwigType_typedef_resolve_all(parsed);
+ SwigType *cl_t = class_from_class_or_class_ref(parsed);
+ String *out_ffitype = compose_foreign_type(n, parsed);
+ String *deref_out_ffitype;
+ String *out_temp = Copy(parsed);
+
+ if (SwigType_ispointer(out_temp)) {
+ SwigType_pop(out_temp);
+ deref_out_ffitype = compose_foreign_type(n, out_temp);
+ } else {
+ deref_out_ffitype = Copy(out_ffitype);
+ }
+
+ Delete(out_temp);
+
+ Delete(parsed);
+
+ int isPtrReturn = 0;
+
+ if (cl_t) {
+ lclass = lookup_defined_foreign_ltype(cl_t);
+ isPtrReturn = 1;
+ }
+
+ int ff_foreign_ptr = 0;
+ if (!lclass) {
+ ff_foreign_ptr = 1;
+ lclass = NewStringf("ff:foreign-pointer");
+ }
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "for output wrapping %s: type=%s, ctype=%s\n", Getattr(n, "name"),
+ Getattr(n, "type"), Swig_cparse_type(Getattr(n, "tmap:ctype")));
+#endif
+
+ if (lclass)
+ Replaceall(wrap->code, "$lclass", lclass);
+ if (out_ffitype)
+ Replaceall(wrap->code, "$out_fftype", out_ffitype);
+ if (deref_out_ffitype)
+ Replaceall(wrap->code, "$*out_fftype", deref_out_ffitype);
+ // if(Replaceall(wrap->code,"$lclass", lclass) && !isPtrReturn) {
+ // Swig_warning(WARN_LANG_RETURN_TYPE,Getfile(n), Getline(n),
+ // "While Wrapping %s, replaced a $lclass reference when return type is non-pointer %s!\n",
+ // Getattr(n,"name"), cl_t);
+ // }
+
+ Replaceall(wrap->code, "$body", NewStringf("(swig-ff-call%s)", wrap->locals));
+// Replaceall(wrap->code,"$body",
+// (!Strcmp(result_type,"void") ?
+// NewStringf("(swig-ff-call%s)", wrap->locals) :
+// NewStringf("(push (swig-ff-call%s) ACL_result)", wrap->locals)));
+ String *ldestructor = Copy(lclass);
+ if (ff_foreign_ptr)
+ Replaceall(ldestructor, ldestructor, "identity");
+ else
+ Replaceall(ldestructor, ":type :class", ":type :destructor");
+ Replaceall(wrap->code, "$ldestructor", ldestructor);
+ Delete(ldestructor);
+
+ Printf(fcl, ")\n"); /* finish arg list */
+
+ /////////////////////////////////////////////////////
+ // Lisp foreign call return type and optimizations //
+ /////////////////////////////////////////////////////
+ Printf(fcl, " (:returning (%s %s)", compose_foreign_type(n, result_type), get_lisp_type(n, Getattr(n, "type"), "result"));
+
+ for (Iterator option = First(n); option.item; option = Next(option)) {
+ if (Strncmp("feature:ffargs:", option.key, 15))
+ continue;
+ String *option_val = option.item;
+ String *option_name = NewString(Char(option.key) + 14);
+ Replaceall(option_name, "_", "-");
+
+ // TODO: varargs vs call-direct ?
+ Printf(fcl, "\n %s %s", option_name, option_val);
+
+ Delete(option_name);
+ }
+
+ Printf(fcl, ")\n %s)\n\n", wrap->code);
+ // Wrapper_print(wrap, stderr);
+
+ Delete(result_type);
+ Delete(mangled_name);
+ Delete(pl);
+ DelWrapper(wrap);
+
+#ifdef ALLEGROCL_WRAP_DEBUG
+ Printf(stderr, "emit_defun: EXIT\n");
+#endif
+
+ return SWIG_OK;
+}
+
+int ALLEGROCL::functionWrapper(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "functionWrapper %s\n", Getattr(n,"name"));
+ Swig_print_node(n);
+#endif
+
+
+ ParmList *parms = CopyParmList(Getattr(n, "parms"));
+ Wrapper *f = NewWrapper();
+ SwigType *t = Getattr(n, "type");
+ String *name = Getattr(n, "name");
+
+ String *raw_return_type = Swig_typemap_lookup("ctype", n, "", 0);
+ SwigType *return_type = Swig_cparse_type(raw_return_type);
+ SwigType *resolved = SwigType_typedef_resolve_all(return_type);
+ int is_void_return = (Cmp(resolved, "void") == 0);
+
+ Delete(resolved);
+
+ if (!is_void_return) {
+ String *lresult_init =
+ NewStringf("= (%s)0",
+ SwigType_str(SwigType_strip_qualifiers(return_type),0));
+ Wrapper_add_localv(f, "lresult",
+ SwigType_lstr(SwigType_ltype(return_type), "lresult"),
+ lresult_init, NIL);
+ Delete(lresult_init);
+ }
+ // Emit all of the local variables for holding arguments.
+ emit_parameter_variables(parms, f);
+
+ // Attach the standard typemaps
+ Swig_typemap_attach_parms("ctype", parms, f);
+ Swig_typemap_attach_parms("lin", parms, f);
+ emit_attach_parmmaps(parms, f);
+
+ String *mangled = mangle_name(n);
+ Node *overloaded = Getattr(n, "sym:overloaded");
+
+ // Parameter overloading
+ Setattr(n, "wrap:parms", parms);
+ Setattr(n, "wrap:name", mangled);
+
+ if (overloaded) {
+ // emit warnings when overloading is impossible on the lisp side.
+ // basically Swig_overload_check(n), but with script_lang_wrapping
+ // set to true.
+ Delete(Swig_overload_rank(n, true));
+ if (Getattr(n, "overload:ignore")) {
+ // if we're the last overload, make sure to force the emit
+ // of the rest of the overloads before we leave.
+ Printf(stderr, "ignored overload %s(%x)\n", name, Getattr(n, "sym:nextSibling"));
+ if (!Getattr(n, "sym:nextSibling")) {
+ update_package_if_needed(n);
+ emit_buffered_defuns(n);
+ emit_dispatch_defun(n);
+ }
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+ }
+ // Get number of required and total arguments
+ int num_arguments = emit_num_arguments(parms);
+ int gencomma = 0;
+
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "Walking parameters for %s '%s'\n", Getattr(n, "allegrocl:kind"), name);
+#endif
+ // Now walk the function parameter list and generate code to get arguments
+ String *name_and_parms = NewStringf("%s (", mangled);
+ int i;
+ Parm *p;
+ for (i = 0, p = parms; i < num_arguments; i++) {
+
+ while (p && checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ if (!p)
+ break;
+
+ SwigType *c_parm_type = Swig_cparse_type(Getattr(p, "tmap:ctype"));
+ String *arg = NewStringf("l%s", Getattr(p, "lname"));
+
+ // Emit parameter declaration
+ if (gencomma)
+ Printf(name_and_parms, ", ");
+ String *parm_decl = SwigType_str(c_parm_type, arg);
+ Printf(name_and_parms, "%s", parm_decl);
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, " param: %s\n", parm_decl);
+#endif
+ Delete(parm_decl);
+ gencomma = 1;
+
+ // Emit parameter conversion code
+ String *parm_code = Getattr(p, "tmap:in");
+ //if (!parm_code) {
+ // Swig_warning(...);
+ // p = nextSibling(p);
+ /*} else */ {
+ // canThrow(n, "in", p);
+ Replaceall(parm_code, "$input", arg);
+ Setattr(p, "emit:input", arg);
+ Printf(f->code, "%s\n", parm_code);
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ Delete(arg);
+ }
+ Printf(name_and_parms, ")");
+
+ // Emit the function definition
+ String *signature = SwigType_str(return_type, name_and_parms);
+ Printf(f->def, "EXPORT %s {", signature);
+ if (CPlusPlus)
+ Printf(f->code, " try {\n");
+
+ String *actioncode = emit_action(n);
+
+ String *tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode);
+ if (!is_void_return && tm) {
+ if (tm) {
+ Replaceall(tm, "$result", "lresult");
+ Printf(f->code, "%s\n", tm);
+ Printf(f->code, " return lresult;\n");
+ Delete(tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s in function %s.\n",
+ SwigType_str(t, 0), name);
+ }
+ }
+
+ emit_return_variable(n, t, f);
+
+ if (CPlusPlus) {
+ Printf(f->code, " } catch (...) {\n");
+ if (!is_void_return)
+ Printf(f->code, " return (%s)0;\n",
+ SwigType_str(SwigType_strip_qualifiers(return_type),0));
+ Printf(f->code, " }\n");
+ }
+ Printf(f->code, "}\n");
+
+ /* print this when in C mode? make this a command-line arg? */
+ if (Generate_Wrapper)
+ Wrapper_print(f, f_cxx_wrapper);
+
+ String *f_buffer = NewString("");
+
+ emit_defun(n, f_buffer);
+ Setattr(n, "allegrocl:lisp-wrap", f_buffer);
+
+ if (!overloaded || !Getattr(n, "sym:nextSibling")) {
+ update_package_if_needed(n);
+ emit_buffered_defuns(n);
+ // this is the last overload.
+ if (overloaded) {
+ emit_dispatch_defun(n);
+ }
+ }
+
+ DelWrapper(f);
+
+ return SWIG_OK;
+}
+
+int ALLEGROCL::namespaceDeclaration(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "namespaceDecl: '%s'(0x%x) (fc=0x%x)\n", Getattr(n, "sym:name"), n, firstChild(n));
+#endif
+
+ /* don't wrap a namespace with no contents. package bloat.
+ also, test-suite/namespace_class.i claims an unnamed namespace
+ is 'private' and should not be wrapped. Complying...
+ */
+ if (Getattr(n,"unnamed") || !firstChild(n))
+ return SWIG_OK;
+
+ String *name = Getattr(n, "sym:name");
+
+ String *old_namespace = current_namespace;
+ if (Cmp(current_namespace, "") == 0)
+ current_namespace = NewStringf("%s", name);
+ else
+ current_namespace = NewStringf("%s::%s", current_namespace, name);
+
+ if (!GetInt(defined_namespace_packages, current_namespace)) {
+ SetInt(defined_namespace_packages, current_namespace, 1);
+ String *lispy_namespace = listify_namespace(current_namespace);
+ Printf(f_clhead, "(swig-defpackage %s)\n", lispy_namespace);
+ Delete(lispy_namespace);
+ }
+
+ emit_children(n);
+
+ Delete(current_namespace);
+ current_namespace = old_namespace;
+ return SWIG_OK;
+}
+
+int ALLEGROCL::constructorHandler(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "constructorHandler %s\n", Getattr(n, "name"));
+#endif
+ // Swig_print_node(n);
+ Setattr(n, "allegrocl:kind", "constructor");
+ Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
+
+ // Let SWIG generate a global forwarding function.
+ return Language::constructorHandler(n);
+}
+
+int ALLEGROCL::destructorHandler(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "destructorHandler %s\n", Getattr(n, "name"));
+#endif
+
+ Setattr(n, "allegrocl:kind", "destructor");
+ Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
+
+ // Let SWIG generate a global forwarding function.
+ return Language::destructorHandler(n);
+}
+
+int ALLEGROCL::constantWrapper(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "constantWrapper %s\n", Getattr(n, "name"));
+#endif
+
+ if (Generate_Wrapper) {
+ // Setattr(n,"wrap:name",mangle_name(n, "ACLPP"));
+ String *const_type = Getattr(n, "type");
+
+ String *const_val = 0;
+ String *raw_const = Getattr(n, "value");
+
+ if (SwigType_type(const_type) == T_STRING) {
+ const_val = NewStringf("\"%s\"", raw_const);
+ } else if (SwigType_type(const_type) == T_CHAR) {
+ const_val = NewStringf("'%s'", raw_const);
+ } else {
+ const_val = Copy(raw_const);
+ }
+
+ SwigType_add_qualifier(const_type, "const");
+
+ String *ppcname = NewStringf("ACLppc_%s", Getattr(n, "sym:name"));
+ // Printf(f_runtime, "static const %s = %s;\n", SwigType_lstr(const_type, ppcname), const_val);
+ Printf(f_runtime, "static %s = %s;\n", SwigType_lstr(const_type, ppcname), const_val);
+
+ Setattr(n, "name", ppcname);
+ SetFlag(n, "feature:immutable");
+
+ Delete(const_val);
+ return variableWrapper(n);
+ }
+
+ String *type = Getattr(n, "type");
+ String *value = Getattr(n, "value");
+ String *converted_value = convert_literal(value, type);
+ String *name = Getattr(n, "sym:name");
+
+ Setattr(n, "allegrocl:kind", "constant");
+ Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
+
+#if 0
+ Printf(stdout, "constant %s is of type %s. value: %s\n", name, type, converted_value);
+#endif
+
+ if (converted_value) {
+ Printf(f_clwrap, "(swig-defconstant \"%s\" %s)\n", name, converted_value);
+ } else {
+ Swig_warning(WARN_LANG_DISCARD_CONST, Getfile(n), Getline(n), "Unable to parse constant value '%s'. Setting to NIL\n", value);
+ Printf(f_clwrap, "(swig-defconstant \"%s\" nil #| %s |#)\n", name, value);
+ }
+
+ Delete(converted_value);
+
+ return SWIG_OK;
+}
+
+int ALLEGROCL::globalvariableHandler(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "globalvariableHandler %s\n", Getattr(n, "name"));
+#endif
+
+ if (Generate_Wrapper)
+ return Language::globalvariableHandler(n);
+
+ // String *name = Getattr(n, "name");
+ SwigType *type = Getattr(n, "type");
+ SwigType *ctype;
+ SwigType *rtype = SwigType_typedef_resolve_all(type);
+
+ int pointer_added = 0;
+
+ if (SwigType_isclass(rtype)) {
+ SwigType_add_pointer(type);
+ SwigType_add_pointer(rtype);
+ pointer_added = 1;
+ }
+
+ ctype = SwigType_str(type, 0);
+ // EXPORT <SwigType_str> <mangled_name>;
+ // <SwigType_str> <mangled_name> = <name>;
+ // Printf(f_runtime, "EXPORT %s %s;\n%s %s = %s%s;\n", ctype, mangled_name,
+ // ctype, mangled_name, (pointer_added ? "&" : ""), name);
+
+ Printf(f_clwrap, "(swig-defvar \"%s\" \"%s\" :type %s)\n",
+ Getattr(n, "sym:name"), Getattr(n, "sym:name"), ((SwigType_isconst(type)) ? ":constant" : ":variable"));
+
+ return SWIG_OK;
+}
+
+int ALLEGROCL::variableWrapper(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "variableWrapper %s\n", Getattr(n, "name"));
+#endif
+ Setattr(n, "allegrocl:kind", "variable");
+ Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
+
+ // Let SWIG generate a get/set function pair.
+ if (Generate_Wrapper)
+ return Language::variableWrapper(n);
+
+ String *name = Getattr(n, "name");
+ SwigType *type = Getattr(n, "type");
+ SwigType *ctype;
+ SwigType *rtype = SwigType_typedef_resolve_all(type);
+
+ String *mangled_name = mangle_name(n);
+
+ int pointer_added = 0;
+
+ if (SwigType_isclass(rtype)) {
+ SwigType_add_pointer(type);
+ SwigType_add_pointer(rtype);
+ pointer_added = 1;
+ }
+
+ ctype = SwigType_str(type, 0);
+
+ // EXPORT <SwigType_str> <mangled_name>;
+ // <SwigType_str> <mangled_name> = <name>;
+ Printf(f_runtime, "EXPORT %s %s;\n%s %s = %s%s;\n", ctype, mangled_name, ctype, mangled_name, (pointer_added ? "&" : ""), name);
+
+ Printf(f_cl, "(swig-defvar \"%s\" :type %s)\n", mangled_name, ((SwigType_isconst(type)) ? ":constant" : ":variable"));
+
+ Printf(stderr,"***\n");
+ Delete(mangled_name);
+
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "DONE variable %s\n", Getattr(n, "name"));
+#endif
+
+ return SWIG_OK;
+}
+
+int ALLEGROCL::memberfunctionHandler(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "memberfunctionHandler %s::%s\n", Getattr(parent_node_skipping_extends(n), "name"), Getattr(n, "name"));
+#endif
+ Setattr(n, "allegrocl:kind", "member function");
+ Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
+
+ // Let SWIG generate a global forwarding function.
+ return Language::memberfunctionHandler(n);
+}
+
+int ALLEGROCL::membervariableHandler(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "membervariableHandler %s::%s\n", Getattr(parent_node_skipping_extends(n), "name"), Getattr(n, "name"));
+#endif
+ Setattr(n, "allegrocl:kind", "member variable");
+ Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
+
+ // Let SWIG generate a get/set function pair.
+ return Language::membervariableHandler(n);
+}
+
+int ALLEGROCL::typedefHandler(Node *n) {
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "In typedefHandler\n");
+#endif
+
+ SwigType *typedef_type = Getattr(n,"type");
+ // has the side-effect of noting any implicit
+ // template instantiations in type.
+ String *ff_type = compose_foreign_type(n, typedef_type);
+
+ String *sym_name = Getattr(n, "sym:name");
+
+ String *name;
+ String *type_ref;
+
+ if (in_class) {
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, " typedef in class '%s'(%x)\n", Getattr(in_class, "sym:name"), in_class);
+#endif
+ Setattr(n, "allegrocl:typedef:in-class", in_class);
+
+ String *class_name = Getattr(in_class, "name");
+ name = NewStringf("%s__%s", class_name, sym_name);
+ type_ref = NewStringf("%s::%s", class_name, sym_name);
+ Setattr(n, "allegrocl:in-class", in_class);
+ } else {
+ name = Copy(sym_name);
+ type_ref = Copy(Getattr(n, "name"));
+ }
+
+ Setattr(n, "allegrocl:namespace", current_namespace);
+
+ String *lookup = lookup_defined_foreign_type(typedef_type);
+
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "** lookup='%s'(%x), typedef_type='%s', strcmp = '%d' strstr = '%d'\n", lookup, lookup, typedef_type, Strcmp(typedef_type,"void"), Strstr(ff_type,"__SWIGACL_FwdReference"));
+#endif
+
+ if(lookup || (!lookup && Strcmp(typedef_type,"void")) ||
+ (!lookup && Strstr(ff_type,"__SWIGACL_FwdReference"))) {
+ add_defined_foreign_type(n, 0, type_ref, name);
+ } else {
+ add_forward_referenced_type(n);
+ }
+
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "Out typedefHandler\n");
+#endif
+
+ Delete(ff_type);
+
+ return SWIG_OK;
+}
+
+// forward referenced classes are added specially to defined_foreign_types
+int ALLEGROCL::classforwardDeclaration(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "classforwardDeclaration %s\n", Getattr(n, "name"));
+#endif
+
+ add_forward_referenced_type(n);
+ return SWIG_OK;
+}
+
+int ALLEGROCL::classHandler(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "classHandler %s::%s\n", current_namespace, Getattr(n, "sym:name"));
+#endif
+
+ int result;
+
+ if (Generate_Wrapper)
+ result = cppClassHandler(n);
+ else
+ result = cClassHandler(n);
+
+ return result;
+}
+
+int ALLEGROCL::cClassHandler(Node *n) {
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "In cClassHandler\n");
+#endif
+ // String *cDeclName = Getattr(n,"classDeclaration:name");
+ // String *name= Getattr(n, "sym:name");
+ // String *kind = Getattr(n,"kind");
+ // Node *c;
+
+ /* Add this structure to the known lisp types */
+ // Printf(stderr, "Adding %s foreign type\n", name);
+ String *ns = listify_namespace(current_namespace);
+
+ add_defined_foreign_type(n);
+
+ Delete(ns);
+
+#ifdef ALLEGROCL_TYPE_DEBUG
+ Printf(stderr, "Out cClassHandler\n");
+#endif
+
+ return SWIG_OK;
+}
+
+int ALLEGROCL::cppClassHandler(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "cppClassHandler %s\n", Getattr(n, "name"));
+#endif
+
+ // String *name=Getattr(n, "sym:name");
+ // String *kind = Getattr(n,"kind");
+
+ /* Template instantiation.
+ Careful.
+ SWIG does not create instantiations of templated classes whenever
+ it sees a templated class reference (say, as a return type, or
+ in a parameter list).
+
+ The %template directive results in a templated class instantiation
+ that will actually be seen by <LANG> :: classHandler().
+
+ In this case, we don't want to error if the type already exists;
+ the point is to force the creation of wrappers for the templated
+ class.
+ */
+ String *templated = Getattr(n, "template");
+ String *t_name;
+ // String *ns = listify_namespace(current_namespace);
+
+ if (templated) {
+ t_name = namespaced_name(n);
+ } else {
+ t_name = Getattr(n, "name");
+ }
+
+ Setattr(n, "allegrocl:namespace", current_namespace);
+
+ /* Add this structure to the known lisp types.
+ Class may contain references to the type currently being
+ defined */
+ if (!templated || !lookup_defined_foreign_type(t_name)) {
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "Adding %s foreign type\n", Getattr(n, "sym:name"));
+#endif
+ add_defined_foreign_type(n);
+ } else {
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "cppClassHand: type %s already exists. Assuming %%template instantiation for wrapping purposes.\n", Getattr(n, "sym:name"));
+#endif
+ add_defined_foreign_type(n, 1);
+ }
+
+ // Generate slot accessors, constructor, and destructor.
+ Node *prev_class = in_class;
+ in_class = n;
+
+ Node *c;
+ // walk all member variables.
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, " MANUALLY walking class members... \n");
+#endif
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ // ping the types of all children--even protected and private
+ // so their types can be added to the linked_type_list.
+ SwigType *childType = NewStringf("%s%s", Getattr(c, "decl"),
+ Getattr(c, "type"));
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, "looking at child '%x' of type '%s'\n", c, childType);
+#endif
+ if (!SwigType_isfunction(childType))
+ Delete(compose_foreign_type(n, childType));
+
+ Delete(childType);
+ }
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, " MANUAL walk DONE.\n");
+#endif
+
+ // this will walk all necessary methods.
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, " LANGUAGE walk of children...\n");
+#endif
+ Language::classHandler(n);
+#ifdef ALLEGROCL_CLASS_DEBUG
+ Printf(stderr, " LANGUAGE walk DONE\n");
+#endif
+ in_class = prev_class;
+
+ return SWIG_OK;
+}
+
+int ALLEGROCL::emit_one(Node *n) {
+ // When the current package does not correspond with the current
+ // namespace we need to generate an IN-PACKAGE form, unless the
+ // current node is another namespace node.
+ if (Cmp(nodeType(n), "namespace") != 0 && Cmp(current_package, current_namespace) != 0) {
+ String *lispy_namespace = listify_namespace(current_namespace);
+ Printf(f_clwrap, "(swig-in-package %s)\n", lispy_namespace);
+ Delete(lispy_namespace);
+ Delete(current_package);
+ current_package = NewStringf("%s", current_namespace);
+ }
+
+ Setattr(n, "allegrocl:package", current_package);
+
+ return Language::emit_one(n);
+}
+
+int ALLEGROCL::enumDeclaration(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "enumDeclaration %s\n", Getattr(n, "name"));
+#endif
+
+ if (Getattr(n, "sym:name")) {
+ add_defined_foreign_type(n);
+ }
+ Node *c;
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ ALLEGROCL::enumvalueDeclaration(c);
+ // since we walk our own children, we need to add
+ // the current package ourselves.
+ Setattr(c, "allegrocl:package", current_package);
+ }
+ return SWIG_OK;
+}
+
+
+int ALLEGROCL::enumvalueDeclaration(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "enumvalueDeclaration %s\n", Getattr(n, "name"));
+#endif
+ /* print this when in C mode? make this a command-line arg? */
+ if (Generate_Wrapper) {
+ SwigType *enum_type = Copy(Getattr(n,"type"));
+ String *mangled_name =
+ mangle_name(n, "ACL_ENUM",
+ in_class ? Getattr(in_class,"name") :
+ current_namespace);
+
+ SwigType_add_qualifier(enum_type,"const");
+
+ String *enum_decl = SwigType_str(enum_type, mangled_name);
+ Printf(f_cxx_wrapper, "EXPORT %s;\n", enum_decl);
+ Printf(f_cxx_wrapper, "%s = %s;\n", enum_decl, Getattr(n, "value"));
+
+ Delete(mangled_name);
+ Delete(enum_type);
+ Delete(enum_decl);
+ }
+ return SWIG_OK;
+}
+
+int ALLEGROCL::templateDeclaration(Node *n) {
+#ifdef ALLEGROCL_DEBUG
+ Printf(stderr, "templateDeclaration %s\n", Getattr(n, "name"));
+#endif
+
+ String *type = Getattr(n, "templatetype");
+
+ // Printf(stderr, "tempDecl: %s %s\n", Getattr(n,"name"),
+ // type);
+ // Swig_print_node(n);
+
+ if (!Strcmp(type, "cdecl")) {
+ SwigType *ty = NewStringf("%s%s", Getattr(n, "decl"),
+ Getattr(n, "type"));
+ Delete(ty);
+ }
+
+ Delete(type);
+
+ return SWIG_OK;
+}
diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx
new file mode 100644
index 0000000..b52578b
--- /dev/null
+++ b/Source/Modules/allocate.cxx
@@ -0,0 +1,955 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_allocate_cxx[] = "$Id: allocate.cxx 11583 2009-08-15 23:22:20Z wsfulton $";
+
+#include "swigmod.h"
+#include "cparse.h"
+
+static int virtual_elimination_mode = 0; /* set to 0 on default */
+
+/* Set virtual_elimination_mode */
+void Wrapper_virtual_elimination_mode_set(int flag) {
+ virtual_elimination_mode = flag;
+}
+
+/* Helper function to assist with abstract class checking.
+ This is a major hack. Sorry. */
+
+extern "C" {
+ static String *search_decl = 0; /* Declarator being searched */
+ static int check_implemented(Node *n) {
+ String *decl;
+ if (!n)
+ return 0;
+ while (n) {
+ if (Strcmp(nodeType(n), "cdecl") == 0) {
+ decl = Getattr(n, "decl");
+ if (SwigType_isfunction(decl)) {
+ SwigType *decl1 = SwigType_typedef_resolve_all(decl);
+ SwigType *decl2 = SwigType_pop_function(decl1);
+ if (Strcmp(decl2, search_decl) == 0) {
+ if (!Getattr(n, "abstract")) {
+ Delete(decl1);
+ Delete(decl2);
+ return 1;
+ }
+ }
+ Delete(decl1);
+ Delete(decl2);
+ }
+ }
+ n = Getattr(n, "csym:nextSibling");
+ }
+ return 0;
+ }
+}
+
+class Allocate:public Dispatcher {
+ Node *inclass;
+ int extendmode;
+
+ /* Checks if a function, n, is the same as any in the base class, ie if the method is polymorphic.
+ * Also checks for methods which will be hidden (ie a base has an identical non-virtual method).
+ * Both methods must have public access for a match to occur. */
+ int function_is_defined_in_bases(Node *n, Node *bases) {
+
+ if (!bases)
+ return 0;
+
+ String *this_decl = Getattr(n, "decl");
+ if (!this_decl)
+ return 0;
+
+ String *name = Getattr(n, "name");
+ String *this_type = Getattr(n, "type");
+ String *resolved_decl = SwigType_typedef_resolve_all(this_decl);
+
+ // Search all base classes for methods with same signature
+ for (int i = 0; i < Len(bases); i++) {
+ Node *b = Getitem(bases, i);
+ Node *base = firstChild(b);
+ while (base) {
+ if (Strcmp(nodeType(base), "extend") == 0) {
+ // Loop through all the %extend methods
+ Node *extend = firstChild(base);
+ while (extend) {
+ if (function_is_defined_in_bases_seek(n, b, extend, this_decl, name, this_type, resolved_decl)) {
+ Delete(resolved_decl);
+ return 1;
+ }
+ extend = nextSibling(extend);
+ }
+ } else if (Strcmp(nodeType(base), "using") == 0) {
+ // Loop through all the using declaration methods
+ Node *usingdecl = firstChild(base);
+ while (usingdecl) {
+ if (function_is_defined_in_bases_seek(n, b, usingdecl, this_decl, name, this_type, resolved_decl)) {
+ Delete(resolved_decl);
+ return 1;
+ }
+ usingdecl = nextSibling(usingdecl);
+ }
+ } else {
+ // normal methods
+ if (function_is_defined_in_bases_seek(n, b, base, this_decl, name, this_type, resolved_decl)) {
+ Delete(resolved_decl);
+ return 1;
+ }
+ }
+ base = nextSibling(base);
+ }
+ }
+ Delete(resolved_decl);
+ resolved_decl = 0;
+ for (int j = 0; j < Len(bases); j++) {
+ Node *b = Getitem(bases, j);
+ if (function_is_defined_in_bases(n, Getattr(b, "allbases")))
+ return 1;
+ }
+ return 0;
+ }
+
+ /* Helper function for function_is_defined_in_bases */
+ int function_is_defined_in_bases_seek(Node *n, Node *b, Node *base, String *this_decl, String *name, String *this_type, String *resolved_decl) {
+
+ String *base_decl = Getattr(base, "decl");
+ SwigType *base_type = Getattr(base, "type");
+ if (base_decl && base_type) {
+ if (checkAttribute(base, "name", name) && !GetFlag(b, "feature:ignore") /* whole class is ignored */ ) {
+ if (SwigType_isfunction(resolved_decl) && SwigType_isfunction(base_decl)) {
+ // We have found a method that has the same name as one in a base class
+ bool covariant_returntype = false;
+ bool returntype_match = Strcmp(base_type, this_type) == 0 ? true : false;
+ bool decl_match = Strcmp(base_decl, this_decl) == 0 ? true : false;
+ if (returntype_match && decl_match) {
+ // Exact match - we have found a method with identical signature
+ // No typedef resolution was done, but skipping it speeds things up slightly
+ } else {
+ // Either we have:
+ // 1) matching methods but are one of them uses a different typedef (return type or parameter) to the one in base class' method
+ // 2) matching polymorphic methods with covariant return type
+ // 3) a non-matching method (ie an overloaded method of some sort)
+ // 4) a matching method which is not polymorphic, ie it hides the base class' method
+
+ // Check if fully resolved return types match (including
+ // covariant return types)
+ if (!returntype_match) {
+ String *this_returntype = function_return_type(n);
+ String *base_returntype = function_return_type(base);
+ returntype_match = Strcmp(this_returntype, base_returntype) == 0 ? true : false;
+ if (!returntype_match) {
+ covariant_returntype = SwigType_issubtype(this_returntype, base_returntype) ? true : false;
+ returntype_match = covariant_returntype;
+ }
+ Delete(this_returntype);
+ Delete(base_returntype);
+ }
+ // The return types must match at this point, for the whole method to match
+ if (returntype_match && !decl_match) {
+ // Now need to check the parameter list
+ // First do an inexpensive parameter count
+ ParmList *this_parms = Getattr(n, "parms");
+ ParmList *base_parms = Getattr(base, "parms");
+ if (ParmList_len(this_parms) == ParmList_len(base_parms)) {
+ // Number of parameters are the same, now check that all the parameters match
+ SwigType *base_fn = NewString("");
+ SwigType *this_fn = NewString("");
+ SwigType_add_function(base_fn, base_parms);
+ SwigType_add_function(this_fn, this_parms);
+ base_fn = SwigType_typedef_resolve_all(base_fn);
+ this_fn = SwigType_typedef_resolve_all(this_fn);
+ if (Strcmp(base_fn, this_fn) == 0) {
+ // Finally check that the qualifiers match
+ int base_qualifier = SwigType_isqualifier(resolved_decl);
+ int this_qualifier = SwigType_isqualifier(base_decl);
+ if (base_qualifier == this_qualifier) {
+ decl_match = true;
+ }
+ }
+ Delete(base_fn);
+ Delete(this_fn);
+ }
+ }
+ }
+ //Printf(stderr,"look %s %s %d %d\n",base_decl, this_decl, returntype_match, decl_match);
+
+ if (decl_match && returntype_match) {
+ // Found an identical method in the base class
+ bool this_wrapping_protected_members = is_member_director(n) ? true : false; // This should really check for dirprot rather than just being a director method
+ bool base_wrapping_protected_members = is_member_director(base) ? true : false; // This should really check for dirprot rather than just being a director method
+ bool both_have_public_access = is_public(n) && is_public(base);
+ bool both_have_protected_access = (is_protected(n) && this_wrapping_protected_members) && (is_protected(base) && base_wrapping_protected_members);
+ bool both_have_private_access = is_private(n) && is_private(base);
+ if (checkAttribute(base, "storage", "virtual")) {
+ // Found a polymorphic method.
+ // Mark the polymorphic method, in case the virtual keyword was not used.
+ Setattr(n, "storage", "virtual");
+
+ if (both_have_public_access || both_have_protected_access) {
+ if (!is_non_public_base(inclass, b))
+ Setattr(n, "override", base); // Note C# definition of override, ie access must be the same
+ } else if (!both_have_private_access) {
+ // Different access
+ if (this_wrapping_protected_members || base_wrapping_protected_members)
+ if (!is_non_public_base(inclass, b))
+ Setattr(n, "hides", base); // Note C# definition of hiding, ie hidden if access is different
+ }
+ // Try and find the most base's covariant return type
+ SwigType *most_base_covariant_type = Getattr(base, "covariant");
+ if (!most_base_covariant_type && covariant_returntype)
+ most_base_covariant_type = function_return_type(base, false);
+
+ if (!most_base_covariant_type) {
+ // Eliminate the derived virtual method.
+ if (virtual_elimination_mode)
+ if (both_have_public_access)
+ if (!is_non_public_base(inclass, b))
+ if (!Swig_symbol_isoverloaded(n)) {
+ // Don't eliminate if an overloaded method as this hides the method
+ // in the scripting languages: the dispatch function will hide the base method if ignored.
+ SetFlag(n, "feature:ignore");
+ }
+ } else {
+ // Some languages need to know about covariant return types
+ Setattr(n, "covariant", most_base_covariant_type);
+ }
+
+ } else {
+ // Found an identical method in the base class, but it is not polymorphic.
+ if (both_have_public_access || both_have_protected_access)
+ if (!is_non_public_base(inclass, b))
+ Setattr(n, "hides", base);
+ }
+ if (both_have_public_access || both_have_protected_access)
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ /* Determines whether the base class, b, is in the list of private
+ * or protected base classes for class n. */
+ bool is_non_public_base(Node *n, Node *b) {
+ bool non_public_base = false;
+ Node *bases = Getattr(n, "privatebases");
+ if (bases) {
+ for (int i = 0; i < Len(bases); i++) {
+ Node *base = Getitem(bases, i);
+ if (base == b)
+ non_public_base = true;
+ }
+ }
+ bases = Getattr(n, "protectedbases");
+ if (bases) {
+ for (int i = 0; i < Len(bases); i++) {
+ Node *base = Getitem(bases, i);
+ if (base == b)
+ non_public_base = true;
+ }
+ }
+ return non_public_base;
+ }
+
+ /* Returns the return type for a function. The node n should be a function.
+ If resolve is true the fully returned type is fully resolved.
+ Caller is responsible for deleting returned string. */
+ String *function_return_type(Node *n, bool resolve = true) {
+ String *decl = Getattr(n, "decl");
+ SwigType *type = Getattr(n, "type");
+ String *ty = NewString(type);
+ SwigType_push(ty, decl);
+ if (SwigType_isqualifier(ty))
+ Delete(SwigType_pop(ty));
+ Delete(SwigType_pop_function(ty));
+ if (resolve) {
+ String *unresolved = ty;
+ ty = SwigType_typedef_resolve_all(unresolved);
+ Delete(unresolved);
+ }
+ return ty;
+ }
+
+ /* Checks if a class member is the same as inherited from the class bases */
+ int class_member_is_defined_in_bases(Node *member, Node *classnode) {
+ Node *bases; /* bases is the closest ancestors of classnode */
+ int defined = 0;
+
+ bases = Getattr(classnode, "allbases");
+ if (!bases)
+ return 0;
+
+ {
+ int old_mode = virtual_elimination_mode;
+ if (is_member_director(classnode, member))
+ virtual_elimination_mode = 0;
+
+ if (function_is_defined_in_bases(member, bases)) {
+ defined = 1;
+ }
+
+ virtual_elimination_mode = old_mode;
+ }
+
+ if (defined)
+ return 1;
+ else
+ return 0;
+ }
+
+ /* Checks to see if a class is abstract through inheritance,
+ and saves the first node that seems to be abstract.
+ */
+ 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) {
+ int dabstract = 0;
+ int len = Len(abstract);
+ for (int i = 0; i < len; i++) {
+ Node *nn = Getitem(abstract, i);
+ String *name = Getattr(nn, "name");
+ if (!name)
+ continue;
+ String *base_decl = Getattr(nn, "decl");
+ if (base_decl)
+ base_decl = SwigType_typedef_resolve_all(base_decl);
+ if (Strchr(name, '~'))
+ continue; /* Don't care about destructors */
+
+ if (SwigType_isfunction(base_decl)) {
+ search_decl = SwigType_pop_function(base_decl);
+ }
+ Node *dn = Swig_symbol_clookup_local_check(name, 0, check_implemented);
+ Delete(search_decl);
+ Delete(base_decl);
+
+ if (!dn) {
+ List *nabstract = Getattr(n, "abstract");
+ if (!nabstract) {
+ nabstract = NewList();
+ Setattr(n, "abstract", nabstract);
+ Delete(nabstract);
+ }
+ Append(nabstract, nn);
+ if (!Getattr(n, "abstract:firstnode")) {
+ Setattr(n, "abstract:firstnode", nn);
+ }
+ dabstract = base != n;
+ }
+ }
+ if (dabstract)
+ return 1;
+ }
+ List *bases = Getattr(base, "allbases");
+ 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, int isconst, String *classname = 0) {
+ if (!methods) {
+ methods = NewList();
+ }
+
+ Node *c = firstChild(cls);
+ String *kind = Getattr(cls, "kind");
+ int mode = PUBLIC;
+ if (kind && (Strcmp(kind, "class") == 0))
+ mode = PRIVATE;
+
+ while (c) {
+ if (Getattr(c, "error") || GetFlag(c, "feature:ignore")) {
+ c = nextSibling(c);
+ continue;
+ }
+ if (!isconst && (Strcmp(nodeType(c), "extend") == 0)) {
+ methods = smart_pointer_methods(c, methods, isconst, Getattr(cls, "name"));
+ } else if (Strcmp(nodeType(c), "cdecl") == 0) {
+ if (!GetFlag(c, "feature:ignore")) {
+ String *storage = Getattr(c, "storage");
+ if (!((Cmp(storage, "typedef") == 0))
+ && !((Cmp(storage, "friend") == 0))) {
+ String *name = Getattr(c, "name");
+ String *symname = Getattr(c, "sym:name");
+ Node *e = Swig_symbol_clookup_local(name, 0);
+ if (e && is_public(e) && !GetFlag(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->(),\n", name);
+ Swig_warning(WARN_LANG_DEREF_SHADOW, Getfile(c), Getline(c), "previous declaration of '%s'.\n", name);
+ } 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) {
+ Node *cp = cc;
+ if (classname) {
+ Setattr(cp, "classname", classname);
+ }
+ Setattr(cp, "allocate:smartpointeraccess", "1");
+ /* If constant, we have to be careful */
+ if (isconst) {
+ SwigType *decl = Getattr(cp, "decl");
+ if (decl) {
+ if (SwigType_isfunction(decl)) { /* If method, we only add if it's a const method */
+ if (SwigType_isconst(decl)) {
+ Append(methods, cp);
+ }
+ } else {
+ Append(methods, cp);
+ }
+ } else {
+ Append(methods, cp);
+ }
+ } else {
+ Append(methods, cp);
+ }
+ 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, isconst);
+ }
+ }
+ /* Remove protected/private members */
+ {
+ for (int i = 0; i < Len(methods);) {
+ Node *n = Getitem(methods, i);
+ if (!is_public(n)) {
+ 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);
+ if (SwigType_isreference(t) || SwigType_ispointer(t) || SwigType_isarray(t)) {
+ Delete(SwigType_pop(t));
+ }
+ Node *c = Swig_symbol_clookup(t, 0);
+ if (c) {
+ if (!GetFlag(c, "feature:exceptionclass")) {
+ SetFlag(c, "feature:exceptionclass");
+ }
+ }
+ p = nextSibling(p);
+ Delete(t);
+ }
+ }
+
+
+ void process_exceptions(Node *n) {
+ ParmList *catchlist = 0;
+ /*
+ the "catchlist" attribute is used to emit the block
+
+ try {$action;}
+ catch <list of catches>;
+
+ in emit.cxx
+
+ and is either constructued from the "feature:catches" feature
+ or copied from the node "throws" list.
+ */
+ String *scatchlist = Getattr(n, "feature:catches");
+ if (scatchlist) {
+ catchlist = Swig_cparse_parms(scatchlist);
+ if (catchlist) {
+ Setattr(n, "catchlist", catchlist);
+ mark_exception_classes(catchlist);
+ Delete(catchlist);
+ }
+ }
+ ParmList *throws = Getattr(n, "throws");
+ if (throws) {
+ /* if there is no explicit catchlist, we catch everything in the throws list */
+ if (!catchlist) {
+ Setattr(n, "catchlist", throws);
+ }
+ mark_exception_classes(throws);
+ }
+ }
+
+public:
+Allocate():
+ inclass(NULL), extendmode(0) {
+ }
+
+ 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 (!Getattr(n, "abstract") && is_abstract_inherit(n)) {
+ if (((Getattr(n, "allocate:public_constructor") || (!GetFlag(n, "feature:nodefault") && !Getattr(n, "allocate:has_constructor"))))) {
+ if (!GetFlag(n, "feature:notabstract")) {
+ Node *na = Getattr(n, "abstract:firstnode");
+ if (na) {
+ Swig_warning(WARN_TYPE_ABSTRACT, Getfile(n), Getline(n),
+ "Class '%s' might be abstract, " "no constructors generated,\n", SwigType_namestr(Getattr(n, "name")));
+ Swig_warning(WARN_TYPE_ABSTRACT, Getfile(na), Getline(na), "Method %s might not be implemented.\n", Swig_name_decl(na));
+ if (!Getattr(n, "abstract")) {
+ List *abstract = NewList();
+ Append(abstract, na);
+ Setattr(n, "abstract", abstract);
+ Delete(abstract);
+ }
+ }
+ }
+ }
+ }
+
+ 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, "allbases");
+ 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_copy_constructor")) {
+ if (Getattr(n, "abstract")) {
+ Delattr(n, "allocate:copy_constructor");
+ }
+ if (!Getattr(n, "allocate:copy_constructor")) {
+ /* Check base classes */
+ List *bases = Getattr(n, "allbases");
+ int allows_copy = 1;
+
+ for (int i = 0; i < Len(bases); i++) {
+ Node *n = Getitem(bases, i);
+ /* If base class does not allow copy constructor, we don't allow it either */
+ if (!Getattr(n, "allocate:copy_constructor") && (!Getattr(n, "allocate:copy_base_constructor"))) {
+ allows_copy = 0;
+ }
+ }
+ if (allows_copy) {
+ Setattr(n, "allocate:copy_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, "allbases");
+ 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");
+ }
+ }
+
+ if (!Getattr(n, "allocate:has_assign")) {
+ /* No destructor was defined. We need to check a few things here too */
+ List *bases = Getattr(n, "allbases");
+ int allows_assign = 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:has_assign")) {
+ allows_assign = !Getattr(n, "allocate:noassign");
+ }
+ }
+ if (!allows_assign) {
+ Setattr(n, "allocate:noassign", "1");
+ }
+ }
+
+ if (!Getattr(n, "allocate:has_new")) {
+ /* No destructor was defined. We need to check a few things here too */
+ List *bases = Getattr(n, "allbases");
+ int allows_new = 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:has_new")) {
+ allows_new = !Getattr(n, "allocate:nonew");
+ }
+ }
+ if (!allows_new) {
+ Setattr(n, "allocate:nonew", "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 (GetFlag(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 usingDeclaration(Node *n) {
+
+ Node *c = 0;
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ if (Strcmp(nodeType(c), "cdecl") == 0) {
+ process_exceptions(c);
+
+ if (inclass)
+ class_member_is_defined_in_bases(c, inclass);
+ }
+ }
+
+ return SWIG_OK;
+ }
+
+ virtual int cDeclaration(Node *n) {
+
+ process_exceptions(n);
+
+ if (inclass) {
+ /* check whether the member node n is defined in class node in class's bases */
+ class_member_is_defined_in_bases(n, inclass);
+
+ /* Check to see if this is a static member or not. If so, we add an attribute
+ cplus:staticbase that saves the current class */
+
+ if (checkAttribute(n, "storage", "static")) {
+ Setattr(n, "cplus:staticbase", inclass);
+ }
+
+ String *name = Getattr(n, "name");
+ if (cplus_mode != PUBLIC) {
+ if (Strcmp(name, "operator =") == 0) {
+ /* Look for a private assignment operator */
+ Setattr(inclass, "allocate:has_assign", "1");
+ Setattr(inclass, "allocate:noassign", "1");
+ } else if (Strcmp(name, "operator new") == 0) {
+ /* Look for a private new operator */
+ Setattr(inclass, "allocate:has_new", "1");
+ Setattr(inclass, "allocate:nonew", "1");
+ }
+ } else {
+ if (Strcmp(name, "operator =") == 0) {
+ Setattr(inclass, "allocate:has_assign", "1");
+ } else if (Strcmp(name, "operator new") == 0) {
+ Setattr(inclass, "allocate:has_new", "1");
+ }
+ /* Look for smart pointer operator */
+ if ((Strcmp(name, "operator ->") == 0) && (!GetFlag(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.")) {
+ /* Need to check if type is a const pointer */
+ int isconst = 0;
+ Delete(SwigType_pop(type));
+ if (SwigType_isconst(type)) {
+ isconst = 1;
+ Setattr(inclass, "allocate:smartpointerconst", "1");
+ }
+ List *methods = smart_pointer_methods(sc, 0, isconst);
+ Setattr(inclass, "allocate:smartpointer", methods);
+ Setattr(inclass, "allocate:smartpointerbase", base);
+ } 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) {
+ Delete(base);
+ Delete(type);
+ sn = nn;
+ continue;
+ }
+ }
+ }
+ }
+ Delete(base);
+ Delete(type);
+ break;
+ }
+ }
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ virtual int constructorDeclaration(Node *n) {
+ if (!inclass)
+ return SWIG_OK;
+ Parm *parms = Getattr(n, "parms");
+
+ process_exceptions(n);
+ 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");
+ }
+ } else {
+ Setattr(inclass, "allocate:has_constructor", "1");
+ 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 *) */
+ int copy_constructor = 0;
+ SwigType *type = Getattr(inclass, "name");
+ String *tn = NewStringf("r.q(const).%s", type);
+ String *cc = SwigType_typedef_resolve_all(tn);
+ SwigType *rt = SwigType_typedef_resolve_all(Getattr(parms, "type"));
+ if (SwigType_istemplate(type)) {
+ String *tmp = Swig_symbol_template_deftype(cc, 0);
+ Delete(cc);
+ cc = tmp;
+ tmp = Swig_symbol_template_deftype(rt, 0);
+ Delete(rt);
+ rt = tmp;
+ }
+ if (Strcmp(cc, rt) == 0) {
+ copy_constructor = 1;
+ } else {
+ Delete(cc);
+ cc = NewStringf("r.%s", Getattr(inclass, "name"));
+ if (Strcmp(cc, Getattr(parms, "type")) == 0) {
+ copy_constructor = 1;
+ } else {
+ Delete(cc);
+ cc = NewStringf("p.%s", Getattr(inclass, "name"));
+ String *ty = SwigType_strip_qualifiers(Getattr(parms, "type"));
+ if (Strcmp(cc, ty) == 0) {
+ copy_constructor = 1;
+ }
+ Delete(ty);
+ }
+ }
+ Delete(cc);
+ Delete(rt);
+ Delete(tn);
+
+ if (copy_constructor) {
+ Setattr(n, "copy_constructor", "1");
+ Setattr(inclass, "allocate:has_copy_constructor", "1");
+ if (cplus_mode == PUBLIC) {
+ Setattr(inclass, "allocate:copy_constructor", "1");
+ } else if (cplus_mode == PROTECTED) {
+ Setattr(inclass, "allocate:copy_base_constructor", "1");
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ virtual int destructorDeclaration(Node *n) {
+ (void) n;
+ if (!inclass)
+ return SWIG_OK;
+ if (!extendmode) {
+ Setattr(inclass, "allocate:has_destructor", "1");
+ if (cplus_mode == PUBLIC) {
+ Setattr(inclass, "allocate:default_destructor", "1");
+ } else if (cplus_mode == PROTECTED) {
+ Setattr(inclass, "allocate:default_base_destructor", "1");
+ }
+ }
+ return SWIG_OK;
+ }
+};
+
+void Swig_default_allocators(Node *n) {
+ if (!n)
+ return;
+ Allocate *a = new Allocate;
+ a->top(n);
+ delete a;
+}
diff --git a/Source/Modules/browser.cxx b/Source/Modules/browser.cxx
new file mode 100644
index 0000000..dd1679a
--- /dev/null
+++ b/Source/Modules/browser.cxx
@@ -0,0 +1,413 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * browser.cxx
+ *
+ * A web-base parse tree browser using SWILL. This is an optional
+ * feature that's normally disabled.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_browser_cxx[] = "$Id: browser.cxx 10003 2007-10-17 21:42:11Z wsfulton $";
+
+#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;
+ Iterator ki;
+ ki = First(obj);
+ while (ki.key) {
+ k = ki.key;
+ 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));
+ }
+ }
+ ki = Next(ki);
+ }
+ 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_package_version());
+ Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_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;
+ Iterator ki;
+ String *os = NewString("");
+ Printf(os, "Hash {\n");
+ ki = First(obj);
+ while (ki.key) {
+ k = ki.key;
+ 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));
+ }
+ ki = Next(ki);
+ }
+ 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_package_version());
+ Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_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_package_version());
+ Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_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;
+#else
+ (void) top;
+ (void) port;
+#endif
+}
diff --git a/Source/Modules/cffi.cxx b/Source/Modules/cffi.cxx
new file mode 100644
index 0000000..053bab7
--- /dev/null
+++ b/Source/Modules/cffi.cxx
@@ -0,0 +1,1081 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * cffi.cxx
+ *
+ * cffi language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_cffi_cxx[] = "$Id: cffi.cxx 11380 2009-07-08 12:17:45Z wsfulton $";
+
+#include "swigmod.h"
+#include "cparse.h"
+#include <ctype.h>
+
+//#define CFFI_DEBUG
+//#define CFFI_WRAP_DEBUG
+
+class CFFI:public Language {
+public:
+ String *f_cl;
+ String *f_clhead;
+ String *f_clwrap;
+ bool CWrap; // generate wrapper file for C code?
+ File *f_begin;
+ File *f_runtime;
+ File *f_cxx_header;
+ File *f_cxx_wrapper;
+ File *f_clos;
+
+ String *module;
+ virtual void main(int argc, char *argv[]);
+ virtual int top(Node *n);
+ virtual int functionWrapper(Node *n);
+ virtual int variableWrapper(Node *n);
+ virtual int constantWrapper(Node *n);
+ // virtual int classDeclaration(Node *n);
+ virtual int enumDeclaration(Node *n);
+ virtual int typedefHandler(Node *n);
+
+ //c++ specific code
+ virtual int constructorHandler(Node *n);
+ virtual int destructorHandler(Node *n);
+ virtual int memberfunctionHandler(Node *n);
+ virtual int membervariableHandler(Node *n);
+ virtual int classHandler(Node *n);
+
+private:
+ void emit_defun(Node *n, String *name);
+ void emit_defmethod(Node *n);
+ void emit_initialize_instance(Node *n);
+ void emit_getter(Node *n);
+ void emit_setter(Node *n);
+ void emit_class(Node *n);
+ void emit_struct_union(Node *n, bool un);
+ void emit_export(Node *n, String *name);
+ void emit_inline(Node *n, String *name);
+ String *lispy_name(char *name);
+ String *lispify_name(Node *n, String *ty, const char *flag, bool kw = false);
+ String *convert_literal(String *num_param, String *type, bool try_to_split = true);
+ String *infix_to_prefix(String *val, char split_op, const String *op, String *type);
+ String *strip_parens(String *string);
+ String *trim(String *string);
+ int generate_typedef_flag;
+ bool no_swig_lisp;
+};
+
+void CFFI::main(int argc, char *argv[]) {
+ int i;
+
+ Preprocessor_define("SWIGCFFI 1", 0);
+ SWIG_library_directory("cffi");
+ SWIG_config_file("cffi.swg");
+ generate_typedef_flag = 0;
+ no_swig_lisp = false;
+ CWrap = false;
+ for (i = 1; i < argc; i++) {
+ if (!Strcmp(argv[i], "-help")) {
+ Printf(stdout, "cffi Options (available with -cffi)\n");
+ Printf(stdout,
+ " -generate-typedef\n"
+ "\tIf this option is given then defctype will be used to generate\n"
+ "\tshortcuts according to the typedefs in the input.\n"
+ " -[no]cwrap\n"
+ "\tTurn on or turn off generation of an intermediate C file when\n"
+ "\tcreating a C interface. By default this is only done for C++ code.\n"
+ " -[no]swig-lisp\n"
+ "\tTurns on or off generation of code for helper lisp macro, functions,\n"
+ "\tetc. which SWIG uses while generating wrappers. These macros, functions\n" "\tmay still be used by generated wrapper code.\n");
+ } else if (!strcmp(argv[i], "-cwrap")) {
+ CWrap = true;
+ Swig_mark_arg(i);
+ } else if ((Strcmp(argv[i], "-generate-typedef") == 0)) {
+ generate_typedef_flag = 1;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i], "-nocwrap")) {
+ CWrap = false;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i], "-swig-lisp")) {
+ no_swig_lisp = false;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i], "-noswig-lisp")) {
+ no_swig_lisp = true;
+ Swig_mark_arg(i);
+ }
+
+ }
+ f_clhead = NewString("");
+ f_clwrap = NewString("");
+ f_cl = NewString("");
+
+ allow_overloading();
+}
+
+int CFFI::top(Node *n) {
+ File *f_null = NewString("");
+ module = Getattr(n, "name");
+
+ String *cxx_filename = Getattr(n, "outfile");
+ String *lisp_filename = NewString("");
+
+ Printf(lisp_filename, "%s%s.lisp", SWIG_output_directory(), module);
+
+ File *f_lisp = NewFile(lisp_filename, "w", SWIG_output_files());
+ if (!f_lisp) {
+ FileErrorDisplay(lisp_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ if (CPlusPlus || CWrap) {
+ f_begin = NewFile(cxx_filename, "w", SWIG_output_files());
+ if (!f_begin) {
+ Close(f_lisp);
+ Delete(f_lisp);
+ Printf(stderr, "Unable to open %s for writing\n", cxx_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ String *clos_filename = NewString("");
+ Printf(clos_filename, "%s%s-clos.lisp", SWIG_output_directory(), module);
+ f_clos = NewFile(clos_filename, "w", SWIG_output_files());
+ if (!f_clos) {
+ Close(f_lisp);
+ Delete(f_lisp);
+ Printf(stderr, "Unable to open %s for writing\n", cxx_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ } else {
+ f_begin = NewString("");
+ f_clos = NewString("");
+ }
+
+ f_runtime = NewString("");
+ f_cxx_header = f_runtime;
+ f_cxx_wrapper = NewString("");
+
+ Swig_register_filebyname("header", f_cxx_header);
+ Swig_register_filebyname("wrapper", f_cxx_wrapper);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("lisphead", f_clhead);
+ if (!no_swig_lisp)
+ Swig_register_filebyname("swiglisp", f_cl);
+ else
+ Swig_register_filebyname("swiglisp", f_null);
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGCFFI\n");
+ Printf(f_runtime, "\n");
+
+ Swig_banner_target_lang(f_lisp, ";;;");
+
+ Language::top(n);
+ Printf(f_lisp, "%s\n", f_clhead);
+ Printf(f_lisp, "%s\n", f_cl);
+ Printf(f_lisp, "%s\n", f_clwrap);
+
+ Close(f_lisp);
+ Delete(f_lisp); // Deletes the handle, not the file
+ Delete(f_cl);
+ Delete(f_clhead);
+ Delete(f_clwrap);
+ Dump(f_runtime, f_begin);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+ Delete(f_cxx_wrapper);
+ Delete(f_null);
+
+ return SWIG_OK;
+}
+
+int CFFI::classHandler(Node *n) {
+#ifdef CFFI_DEBUG
+ Printf(stderr, "class %s::%s\n", "some namespace", //current_namespace,
+ Getattr(n, "sym:name"));
+#endif
+ String *name = Getattr(n, "sym:name");
+ String *kind = Getattr(n, "kind");
+
+ // maybe just remove this check and get rid of the else clause below.
+ if (Strcmp(kind, "struct") == 0) {
+ emit_struct_union(n, false);
+ return SWIG_OK;
+ } else if (Strcmp(kind, "union") == 0) {
+ emit_struct_union(n, true);
+ return SWIG_OK;
+ } else if (Strcmp(kind, "class") == 0) {
+ emit_class(n);
+ Language::classHandler(n);
+ } else {
+ Printf(stderr, "Don't know how to deal with %s kind of class yet.\n", kind);
+ Printf(stderr, " (name: %s)\n", name);
+ SWIG_exit(EXIT_FAILURE);
+ return SWIG_OK;
+ }
+
+ return SWIG_OK;
+}
+
+int CFFI::constructorHandler(Node *n) {
+#ifdef CFFI_DEBUG
+ Printf(stderr, "constructor %s\n", Getattr(n, "name"));
+ Printf(stderr, "constructor %s\n and %s and %s", Getattr(n, "kind"), Getattr(n, "sym:name"), Getattr(n, "allegrocl:old-sym:name"));
+#endif
+ Setattr(n, "cffi:constructorfunction", "1");
+ // Let SWIG generate a global forwarding function.
+ return Language::constructorHandler(n);
+}
+
+int CFFI::destructorHandler(Node *n) {
+#ifdef CFFI_DEBUG
+ Printf(stderr, "destructor %s\n", Getattr(n, "name"));
+#endif
+
+ // Let SWIG generate a global forwarding function.
+ return Language::destructorHandler(n);
+}
+
+void CFFI::emit_defmethod(Node *n) {
+ String *args_placeholder = NewStringf("");
+ String *args_call = NewStringf("");
+
+ ParmList *pl = Getattr(n, "parms");
+ int argnum = 0;
+ Node *parent = getCurrentClass();
+ bool first = 0;
+
+ for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
+ String *argname = Getattr(p, "name");
+ String *ffitype = Swig_typemap_lookup("lispclass", p, "", 0);
+
+ int tempargname = 0;
+
+ if(!first)
+ first = true;
+ else
+ Printf(args_placeholder, " ");
+
+ if (!argname) {
+ argname = NewStringf("arg%d", argnum);
+ tempargname = 1;
+ } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) {
+ argname = NewStringf("t-arg%d", argnum);
+ tempargname = 1;
+ }
+ if (Len(ffitype) > 0)
+ Printf(args_placeholder, "(%s %s)", argname, ffitype);
+ else
+ Printf(args_placeholder, "%s", argname);
+
+ if (ffitype && Strcmp(ffitype, lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'classname")) == 0)
+ Printf(args_call, " (ff-pointer %s)", argname);
+ else
+ Printf(args_call, " %s", argname);
+
+ Delete(ffitype);
+
+ if (tempargname)
+ Delete(argname);
+ }
+
+ String *method_name = Getattr(n, "name");
+ int x = Replace(method_name, "operator ", "", DOH_REPLACE_FIRST); //
+
+ if (x == 1)
+ Printf(f_clos, "(cl:shadow \"%s\")\n", method_name);
+
+ Printf(f_clos, "(cl:defmethod %s (%s)\n (%s%s))\n\n",
+ lispify_name(n, lispy_name(Char(method_name)), "'method"), args_placeholder,
+ lispify_name(n, Getattr(n, "sym:name"), "'function"), args_call);
+
+}
+
+void CFFI::emit_initialize_instance(Node *n) {
+ String *args_placeholder = NewStringf("");
+ String *args_call = NewStringf("");
+
+ ParmList *pl = Getattr(n, "parms");
+ int argnum = 0;
+ Node *parent = getCurrentClass();
+
+ for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
+ String *argname = Getattr(p, "name");
+ String *ffitype = Swig_typemap_lookup("lispclass", p, "", 0);
+
+ int tempargname = 0;
+ if (!argname) {
+ argname = NewStringf("arg%d", argnum);
+ tempargname = 1;
+ } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) {
+ argname = NewStringf("t-arg%d", argnum);
+ tempargname = 1;
+ }
+ if (Len(ffitype) > 0)
+ Printf(args_placeholder, " (%s %s)", argname, ffitype);
+ else
+ Printf(args_placeholder, " %s", argname);
+
+ if (Strcmp(ffitype, lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'classname")) == 0)
+ Printf(args_call, " (ff-pointer %s)", argname);
+ else
+ Printf(args_call, " %s", argname);
+
+ Delete(ffitype);
+
+ if (tempargname)
+ Delete(argname);
+ }
+
+ Printf(f_clos, "(cl:defmethod initialize-instance :after ((obj %s) &key%s)\n (setf (slot-value obj 'ff-pointer) (%s%s)))\n\n",
+ lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), args_placeholder,
+ lispify_name(n, Getattr(n, "sym:name"), "'function"), args_call);
+
+}
+
+void CFFI::emit_setter(Node *n) {
+ Node *parent = getCurrentClass();
+ Printf(f_clos, "(cl:defmethod (cl:setf %s) (arg0 (obj %s))\n (%s (ff-pointer obj) arg0))\n\n",
+ lispify_name(n, Getattr(n, "name"), "'method"),
+ lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), lispify_name(n, Getattr(n, "sym:name"), "'function"));
+}
+
+
+void CFFI::emit_getter(Node *n) {
+ Node *parent = getCurrentClass();
+ Printf(f_clos, "(cl:defmethod %s ((obj %s))\n (%s (ff-pointer obj)))\n\n",
+ lispify_name(n, Getattr(n, "name"), "'method"),
+ lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), lispify_name(n, Getattr(n, "sym:name"), "'function"));
+}
+
+int CFFI::memberfunctionHandler(Node *n) {
+ // Let SWIG generate a global forwarding function.
+ Setattr(n, "cffi:memberfunction", "1");
+ return Language::memberfunctionHandler(n);
+}
+
+int CFFI::membervariableHandler(Node *n) {
+ // Let SWIG generate a get/set function pair.
+ Setattr(n, "cffi:membervariable", "1");
+ return Language::membervariableHandler(n);
+}
+
+int CFFI::functionWrapper(Node *n) {
+
+ ParmList *parms = Getattr(n, "parms");
+ String *iname = Getattr(n, "sym:name");
+ Wrapper *f = NewWrapper();
+
+ String *raw_return_type = Swig_typemap_lookup("ctype", n, "", 0);
+ SwigType *return_type = Swig_cparse_type(raw_return_type);
+ SwigType *resolved = SwigType_typedef_resolve_all(return_type);
+ int is_void_return = (Cmp(resolved, "void") == 0);
+ Delete(resolved);
+
+ if (!is_void_return) {
+ String *lresult_init = NewStringf("lresult = (%s)0", raw_return_type);
+ Wrapper_add_localv(f, "lresult", raw_return_type, lresult_init, NIL);
+ Delete(lresult_init);
+ }
+
+ String *overname = 0;
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n)) {
+ DelWrapper(f);
+ return SWIG_ERROR;
+ }
+ }
+
+ String *wname = Swig_name_wrapper(iname);
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n, "wrap:name", wname);
+
+ // Emit all of the local variables for holding arguments.
+ emit_parameter_variables(parms, f);
+
+ // Attach the standard typemaps
+ Swig_typemap_attach_parms("ctype", parms, f);
+ emit_attach_parmmaps(parms, f);
+
+ int num_arguments = emit_num_arguments(parms);
+ String *name_and_parms = NewStringf("%s (", wname);
+ int i;
+ Parm *p;
+ int gencomma = 0;
+
+#ifdef CFFI_DEBUG
+ Printf(stderr, "function - %s - %d\n", Getattr(n, "name"), num_arguments);
+#endif
+
+ for (i = 0, p = parms; i < num_arguments; i++) {
+
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *c_parm_type = Swig_cparse_type(Getattr(p, "tmap:ctype"));
+ String *arg = NewStringf("l%s", Getattr(p, "lname"));
+
+ // Emit parameter declaration
+ if (gencomma)
+ Printf(name_and_parms, ", ");
+ String *parm_decl = SwigType_str(c_parm_type, arg);
+ Printf(name_and_parms, "%s", parm_decl);
+#ifdef CFFI_DEBUG
+ Printf(stderr, " param: %s\n", parm_decl);
+#endif
+ Delete(parm_decl);
+ gencomma = 1;
+
+ // Emit parameter conversion code
+ String *parm_code = Getattr(p, "tmap:in");
+ {
+ Replaceall(parm_code, "$input", arg);
+ Setattr(p, "emit:input", arg);
+ Printf(f->code, "%s\n", parm_code);
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ Delete(arg);
+ }
+ Printf(name_and_parms, ")");
+
+ // Emit the function definition
+ String *signature = SwigType_str(return_type, name_and_parms);
+ Printf(f->def, "EXPORT %s {", signature);
+ Printf(f->code, " try {\n");
+
+ String *actioncode = emit_action(n);
+
+ String *result_convert = Swig_typemap_lookup_out("out", n, "result", f, actioncode);
+ Replaceall(result_convert, "$result", "lresult");
+ Printf(f->code, "%s\n", result_convert);
+ if(!is_void_return) Printf(f->code, " return lresult;\n");
+ Delete(result_convert);
+ emit_return_variable(n, Getattr(n, "type"), f);
+
+ Printf(f->code, " } catch (...) {\n");
+ if (!is_void_return)
+ Printf(f->code, " return (%s)0;\n", raw_return_type);
+ Printf(f->code, " }\n");
+ Printf(f->code, "}\n");
+
+ if (CPlusPlus)
+ Wrapper_print(f, f_runtime);
+
+ if (CPlusPlus) {
+ emit_defun(n, wname);
+ if (Getattr(n, "cffi:memberfunction"))
+ emit_defmethod(n);
+ else if (Getattr(n, "cffi:membervariable")) {
+ if (Getattr(n, "memberget"))
+ emit_getter(n);
+ else if (Getattr(n, "memberset"))
+ emit_setter(n);
+ }
+ else if (Getattr(n, "cffi:constructorfunction")) {
+ emit_initialize_instance(n);
+ }
+ } else
+ emit_defun(n, iname);
+
+ // if (!overloaded || !Getattr(n, "sym:nextSibling")) {
+ // update_package_if_needed(n);
+ // emit_buffered_defuns(n);
+ // // this is the last overload.
+ // if (overloaded) {
+ // emit_dispatch_defun(n);
+ // }
+ // }
+
+ Delete(wname);
+ DelWrapper(f);
+
+ return SWIG_OK;
+}
+
+
+void CFFI::emit_defun(Node *n, String *name) {
+
+ // String *storage=Getattr(n,"storage");
+ // if(!storage || (Strcmp(storage,"extern") && Strcmp(storage,"externc")))
+ // return SWIG_OK;
+
+ String *func_name = Getattr(n, "sym:name");
+
+ ParmList *pl = Getattr(n, "parms");
+
+ int argnum = 0;
+
+ func_name = lispify_name(n, func_name, "'function");
+
+ emit_inline(n, func_name);
+
+ Printf(f_cl, "\n(cffi:defcfun (\"%s\" %s)", name, func_name);
+ String *ffitype = Swig_typemap_lookup("cout", n, ":pointer", 0);
+
+ Printf(f_cl, " %s", ffitype);
+ Delete(ffitype);
+
+ for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
+
+ if (SwigType_isvarargs(Getattr(p, "type"))) {
+ Printf(f_cl, "\n %s", NewString("&rest"));
+ continue;
+ }
+
+ String *argname = Getattr(p, "name");
+
+ ffitype = Swig_typemap_lookup("cin", p, "", 0);
+
+ int tempargname = 0;
+ if (!argname) {
+
+ argname = NewStringf("arg%d", argnum);
+ tempargname = 1;
+ } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) {
+ argname = NewStringf("t_arg%d", argnum);
+ tempargname = 1;
+ }
+
+ Printf(f_cl, "\n (%s %s)", argname, ffitype);
+
+ Delete(ffitype);
+
+ if (tempargname)
+ Delete(argname);
+ }
+ Printf(f_cl, ")\n"); /* finish arg list */
+
+ emit_export(n, func_name);
+}
+
+
+int CFFI::constantWrapper(Node *n) {
+ String *type = Getattr(n, "type");
+ String *converted_value = convert_literal(Getattr(n, "value"), type);
+ String *name = lispify_name(n, Getattr(n, "sym:name"), "'constant");
+
+ if (Strcmp(name, "t") == 0 || Strcmp(name, "T") == 0)
+ name = NewStringf("t_var");
+
+ Printf(f_cl, "\n(cl:defconstant %s %s)\n", name, converted_value);
+ Delete(converted_value);
+
+ emit_export(n, name);
+ return SWIG_OK;
+}
+
+int CFFI::variableWrapper(Node *n) {
+ // String *storage=Getattr(n,"storage");
+ // Printf(stdout,"\"%s\" %s)\n",storage,Getattr(n, "sym:name"));
+
+ // if(!storage || (Strcmp(storage,"extern") && Strcmp(storage,"externc")))
+ // return SWIG_OK;
+
+ String *var_name = Getattr(n, "sym:name");
+ String *lisp_type = Swig_typemap_lookup("cin", n, "", 0);
+ String *lisp_name = lispify_name(n, var_name, "'variable");
+
+ if (Strcmp(lisp_name, "t") == 0 || Strcmp(lisp_name, "T") == 0)
+ lisp_name = NewStringf("t_var");
+
+ Printf(f_cl, "\n(cffi:defcvar (\"%s\" %s)\n %s)\n", var_name, lisp_name, lisp_type);
+
+ Delete(lisp_type);
+
+ emit_export(n, lisp_name);
+ return SWIG_OK;
+}
+
+int CFFI::typedefHandler(Node *n) {
+ if (generate_typedef_flag && strncmp(Char(Getattr(n, "type")), "enum", 4)) {
+ String *lisp_name = lispify_name(n, Getattr(n, "name"), "'typename");
+ Printf(f_cl, "\n(cffi:defctype %s %s)\n", lisp_name, Swig_typemap_lookup("cin", n, "", 0));
+ emit_export(n, lisp_name);
+ }
+ return Language::typedefHandler(n);
+}
+
+int CFFI::enumDeclaration(Node *n) {
+ String *name = Getattr(n, "sym:name");
+ bool slot_name_keywords;
+ String *lisp_name = 0;
+ if (name && Len(name) != 0) {
+ lisp_name = lispify_name(n, name, "'enumname");
+ if (GetFlag(n, "feature:bitfield")) {
+ Printf(f_cl, "\n(cffi:defbitfield %s", lisp_name);
+ } else {
+ Printf(f_cl, "\n(cffi:defcenum %s", lisp_name);
+ }
+ slot_name_keywords = true;
+
+ //Registering the enum name to the cin and cout typemaps
+ Parm *pattern = NewParm(name, NULL);
+ Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
+ Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
+ Delete(pattern);
+ //Registering with the kind, i.e., enum
+ pattern = NewParm(NewStringf("enum %s", name), NULL);
+ Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
+ Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
+ Delete(pattern);
+
+ } else {
+ Printf(f_cl, "\n(defanonenum %s", name);
+ slot_name_keywords = false;
+ }
+
+ for (Node *c = firstChild(n); c; c = nextSibling(c)) {
+
+ String *slot_name = lispify_name(c, Getattr(c, "name"), "'enumvalue", slot_name_keywords);
+ String *value = Getattr(c, "enumvalue");
+
+ if (!value || GetFlag(n, "feature:bitfield:ignore_values"))
+ Printf(f_cl, "\n\t%s", slot_name);
+ else {
+ String *type = Getattr(c, "type");
+ String *converted_value = convert_literal(value, type);
+ Printf(f_cl, "\n\t(%s #.%s)", slot_name, converted_value);
+ Delete(converted_value);
+ }
+ Delete(value);
+ }
+
+ Printf(f_cl, ")\n");
+
+ // No need to export keywords
+ if (lisp_name && Len(lisp_name) != 0) {
+ emit_export(n, lisp_name);
+ } else {
+ for (Node *c = firstChild(n); c; c = nextSibling(c))
+ emit_export(c, lispify_name(c, Getattr(c, "name"), "'enumvalue"));
+ }
+
+ return SWIG_OK;
+}
+void CFFI::emit_class(Node *n) {
+
+#ifdef CFFI_WRAP_DEBUG
+ Printf(stderr, "emit_class: ENTER... '%s'(%x)\n", Getattr(n, "sym:name"), n);
+#endif
+
+ String *name = Getattr(n, "sym:name");
+ String *lisp_name = lispify_name(n, lispy_name(Char(name)), "'classname");
+
+ String *bases = Getattr(n, "bases");
+ String *supers = NewString("(");
+ if (bases) {
+ int first = 1;
+ for (Iterator i = First(bases); i.item; i = Next(i)) {
+ if (!first)
+ Printf(supers, " ");
+ String *s = Getattr(i.item, "name");
+ Printf(supers, "%s", lispify_name(i.item, s, "'classname"));
+ }
+ } else {
+ // Printf(supers,"ff:foreign-pointer");
+ }
+
+ Printf(supers, ")");
+ Printf(f_clos, "\n(cl:defclass %s%s", lisp_name, supers);
+ Printf(f_clos, "\n ((ff-pointer :reader ff-pointer)))\n\n");
+
+ Parm *pattern = NewParm(Getattr(n, "name"), NULL);
+
+ Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
+ SwigType_add_pointer(Getattr(pattern, "type"));
+ Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
+ SwigType_add_qualifier(Getattr(pattern, "type"), "const");
+ Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
+ SwigType_del_pointer(Getattr(pattern, "type"));
+ SwigType_add_reference(Getattr(pattern, "type"));
+ Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
+
+#ifdef CFFI_WRAP_DEBUG
+ Printf(stderr, " pattern %s name %s .. ... %s .\n", pattern, lisp_name);
+#endif
+
+ Delete(pattern);
+
+ // Walk children to generate type definition.
+ String *slotdefs = NewString(" ");
+
+#ifdef CFFI_WRAP_DEBUG
+ Printf(stderr, " walking children...\n");
+#endif
+
+ Node *c;
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ String *storage_type = Getattr(c, "storage");
+ if ((!Strcmp(nodeType(c), "cdecl") && (!storage_type || Strcmp(storage_type, "typedef")))) {
+ String *access = Getattr(c, "access");
+
+ // hack. why would decl have a value of "variableHandler" and now "0"?
+ String *childDecl = Getattr(c, "decl");
+ // Printf(stderr,"childDecl = '%s' (%s)\n", childDecl, Getattr(c,"view"));
+ if (!Strcmp(childDecl, "0"))
+ childDecl = NewString("");
+
+ SwigType *childType = NewStringf("%s%s", childDecl,
+ Getattr(c, "type"));
+ String *cname = (access && Strcmp(access, "public")) ? NewString("nil") : Copy(Getattr(c, "name"));
+
+ if (!SwigType_isfunction(childType)) {
+ // Printf(slotdefs, ";;; member functions don't appear as slots.\n ");
+ // Printf(slotdefs, ";; ");
+ // String *ns = listify_namespace(Getattr(n, "cffi:package"));
+ String *ns = NewString("");
+#ifdef CFFI_WRAP_DEBUG
+ Printf(stderr, "slot name = '%s' ns = '%s' class-of '%s' and type = '%s'\n", cname, ns, name, childType);
+#endif
+ Printf(slotdefs, "(#.(swig-insert-id \"%s\" %s :type :slot :class \"%s\") %s)", cname, ns, name, childType); //compose_foreign_type(childType)
+ Delete(ns);
+ if (access && Strcmp(access, "public"))
+ Printf(slotdefs, " ;; %s member", access);
+
+ Printf(slotdefs, "\n ");
+ }
+ Delete(childType);
+ Delete(cname);
+ }
+ }
+
+
+ // String *ns_list = listify_namespace(Getattr(n,"cffi:namespace"));
+ // update_package_if_needed(n,f_clhead);
+ // Printf(f_clos,
+ // "(swig-def-foreign-class \"%s\"\n %s\n (:%s\n%s))\n\n",
+ // name, supers, kind, slotdefs);
+
+ Delete(supers);
+ // Delete(ns_list);
+
+ // Parm *pattern = NewParm(name,NULL);
+ // Swig_typemap_register("cin",pattern,lisp_name,NULL,NULL);
+ //Swig_typemap_register("cout",pattern,lisp_name,NULL,NULL);
+ //Delete(pattern);
+
+#ifdef CFFI_WRAP_DEBUG
+ Printf(stderr, "emit_class: EXIT\n");
+#endif
+}
+
+// Includes structs
+void CFFI::emit_struct_union(Node *n, bool un = false) {
+#ifdef CFFI_DEBUG
+ Printf(stderr, "struct/union %s\n", Getattr(n, "name"));
+ Printf(stderr, "struct/union %s\n and %s", Getattr(n, "kind"), Getattr(n, "sym:name"));
+#endif
+
+ String *name = Getattr(n, "sym:name");
+ String *kind = Getattr(n, "kind");
+
+ if (Strcmp(kind, "struct") != 0 && Strcmp(kind, "union") != 0) {
+ Printf(stderr, "Don't know how to deal with %s kind of class yet.\n", kind);
+ Printf(stderr, " (name: %s)\n", name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ String *lisp_name = lispify_name(n, name, "'classname");
+
+ //Register the struct/union name to the cin and cout typemaps
+
+ Parm *pattern = NewParm(name, NULL);
+ Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
+ Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
+ Delete(pattern);
+ //Registering with the kind, i.e., struct or union
+ pattern = NewParm(NewStringf("%s %s", kind, name), NULL);
+ Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
+ Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
+ Delete(pattern);
+
+ if (un) {
+ Printf(f_cl, "\n(cffi:defcunion %s", lisp_name);
+ } else
+ Printf(f_cl, "\n(cffi:defcstruct %s", lisp_name);
+
+
+ for (Node *c = firstChild(n); c; c = nextSibling(c)) {
+#ifdef CFFI_DEBUG
+ Printf(stderr, "struct/union %s\n", Getattr(c, "name"));
+ Printf(stderr, "struct/union %s and %s \n", Getattr(c, "kind"), Getattr(c, "sym:name"));
+#endif
+
+ if (Strcmp(nodeType(c), "cdecl")) {
+ //C declaration ignore
+ // Printf(stderr, "Structure %s has a slot that we can't deal with.\n",
+ // name);
+ // Printf(stderr, "nodeType: %s, name: %s, type: %s\n",
+ // nodeType(c),
+ // Getattr(c, "name"),
+ // Getattr(c, "type"));
+ // SWIG_exit(EXIT_FAILURE);
+ } else {
+ SwigType *childType = NewStringf("%s%s", Getattr(c, "decl"), Getattr(c, "type"));
+
+ Node *node = NewHash();
+ Setattr(node, "type", childType);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *tm = Swig_typemap_lookup("cin", node, "", 0);
+
+ String *typespec = tm ? NewString(tm) : NewString("");
+
+ String *slot_name = lispify_name(c, Getattr(c, "sym:name"), "'slotname");
+ if (Strcmp(slot_name, "t") == 0 || Strcmp(slot_name, "T") == 0)
+ slot_name = NewStringf("t_var");
+
+ Printf(f_cl, "\n\t(%s %s)", slot_name, typespec);
+
+ Delete(node);
+ Delete(childType);
+ Delete(typespec);
+ }
+ }
+
+ Printf(f_cl, ")\n");
+
+ emit_export(n, lisp_name);
+ for (Node *child = firstChild(n); child; child = nextSibling(child)) {
+ if (!Strcmp(nodeType(child), "cdecl")) {
+ emit_export(child, lispify_name(child, Getattr(child, "sym:name"), "'slotname"));
+ }
+ }
+
+ /* Add this structure to the known lisp types */
+ //Printf(stdout, "Adding %s foreign type\n", name);
+ // add_defined_foreign_type(name);
+
+}
+
+void CFFI::emit_export(Node *n, String *name) {
+ if (GetInt(n, "feature:export"))
+ Printf(f_cl, "\n(cl:export '%s)\n", name);
+}
+
+void CFFI::emit_inline(Node *n, String *name) {
+ if (GetInt(n, "feature:inline"))
+ Printf(f_cl, "\n(cl:declaim (cl:inline %s))\n", name);
+}
+
+String *CFFI::lispify_name(Node *n, String *ty, const char *flag, bool kw) {
+ String *intern_func = Getattr(n, "feature:intern_function");
+ if (intern_func) {
+ if (Strcmp(intern_func, "1") == 0)
+ intern_func = NewStringf("swig-lispify");
+ return NewStringf("#.(%s \"%s\" %s%s)", intern_func, ty, flag, kw ? " :keyword" : "");
+ } else if (kw)
+ return NewStringf(":%s", ty);
+ else
+ return ty;
+}
+
+/* utilities */
+/* returns new string w/ parens stripped */
+String *CFFI::strip_parens(String *string) {
+ char *s = Char(string), *p;
+ int len = Len(string);
+ String *res;
+
+ if (len == 0 || s[0] != '(' || s[len - 1] != ')') {
+ return NewString(string);
+ }
+
+ p = (char *) malloc(len - 2 + 1);
+ if (!p) {
+ Printf(stderr, "Malloc failed\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ strncpy(p, s + 1, len - 1);
+ p[len - 2] = 0; /* null terminate */
+
+ res = NewString(p);
+ free(p);
+
+ return res;
+}
+
+String *CFFI::trim(String *str) {
+ char *c = Char(str);
+ while (*c != '\0' && isspace((int) *c))
+ ++c;
+ String *result = NewString(c);
+ Chop(result);
+ return result;
+}
+
+String *CFFI::infix_to_prefix(String *val, char split_op, const String *op, String *type) {
+ List *ored = Split(val, split_op, -1);
+
+ // some float hackery
+ //i don't understand it, if you do then please explain
+ // if ( ((split_op == '+') || (split_op == '-')) && Len(ored) == 2 &&
+ // (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE ||
+ // SwigType_type(type) == T_LONGDOUBLE) ) {
+ // // check that we're not splitting a float
+ // String *possible_result = convert_literal(val, type, false);
+ // if (possible_result) return possible_result;
+
+ // }
+
+ // try parsing the split results. if any part fails, kick out.
+ bool part_failed = false;
+ if (Len(ored) > 1) {
+ String *result = NewStringf("(%s", op);
+ for (Iterator i = First(ored); i.item; i = Next(i)) {
+ String *converted = convert_literal(i.item, type);
+ if (converted) {
+ Printf(result, " %s", converted);
+ Delete(converted);
+ } else {
+ part_failed = true;
+ break;
+ }
+ }
+ Printf(result, ")");
+ Delete(ored);
+ return part_failed ? 0 : result;
+ } else {
+ Delete(ored);
+ }
+ return 0;
+}
+
+/* To be called by code generating the lisp interface
+ Will return a String containing the literal based on type.
+ Will return null if there are problems.
+
+ try_to_split defaults to true (see stub above).
+*/
+String *CFFI::convert_literal(String *literal, String *type, bool try_to_split) {
+ String *num_param = Copy(literal);
+ String *trimmed = trim(num_param);
+ String *num = strip_parens(trimmed), *res = 0;
+ Delete(trimmed);
+ char *s = Char(num);
+
+ // very basic parsing of infix expressions.
+ if (try_to_split) {
+ if ((res = infix_to_prefix(num, '|', "cl:logior", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '&', "cl:logand", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '^', "cl:logxor", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '*', "cl:*", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '/', "cl:/", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '+', "cl:+", type)))
+ return res;
+ if ((res = infix_to_prefix(num, '-', "cl:-", type)))
+ return res;
+ }
+
+ if (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || SwigType_type(type) == T_LONGDOUBLE) {
+ // Use CL syntax for float literals
+
+ // careful. may be a float identifier or float constant.
+ char *num_start = Char(num);
+ char *num_end = num_start + strlen(num_start) - 1;
+
+ bool is_literal = isdigit(*num_start) || (*num_start == '.') || (*num_start == '+') || (*num_start == '-');
+
+ String *lisp_exp = 0;
+ if (is_literal) {
+ if (*num_end == 'f' || *num_end == 'F') {
+ lisp_exp = NewString("f");
+ } else {
+ lisp_exp = NewString("d");
+ }
+
+ if (*num_end == 'l' || *num_end == 'L' || *num_end == 'f' || *num_end == 'F') {
+ *num_end = '\0';
+ num_end--;
+ }
+
+ int exponents = Replaceall(num, "e", lisp_exp) + Replaceall(num, "E", lisp_exp);
+
+ if (!exponents)
+ Printf(num, "%s0", lisp_exp);
+
+ if (exponents > 1 || (exponents + Replaceall(num, ".", ".") == 0)) {
+ Delete(num);
+ num = 0;
+ }
+ }
+ return num;
+ } else if (SwigType_type(type) == T_CHAR) {
+ /* Use CL syntax for character literals */
+ String* result = NewStringf("#\\%c", s[2]);
+ Delete(num);
+ // Printf(stderr, "%s %c %d", s, s[2], s);
+ return result;
+ } else if (SwigType_type(type) == T_STRING) {
+ /* Use CL syntax for string literals */
+ String* result = NewStringf("\"%s\"", num_param);
+ Delete(num);
+ return result;
+ } else if (SwigType_type(type) == T_INT || SwigType_type(type) == T_UINT) {
+ // Printf(stderr, "Is a T_INT or T_UINT %s, before replaceall\n", s);
+ Replaceall(num, "u", "");
+ Replaceall(num, "U", "");
+ Replaceall(num, "l", "");
+ Replaceall(num, "L", "");
+
+ int i, j;
+ if (sscanf(s, "%d >> %d", &i, &j) == 2) {
+ String* result = NewStringf("(cl:ash %d -%d)", i, j);
+ Delete(num);
+ return result;
+ } else if (sscanf(s, "%d << %d", &i, &j) == 2) {
+ String* result = NewStringf("(cl:ash %d %d)", i, j);
+ Delete(num);
+ return result;
+ }
+ }
+
+ if (Len(num) >= 2 && s[0] == '0') { /* octal or hex */
+ if (s[1] == 'x'){
+ DohReplace(num,"0","#",DOH_REPLACE_FIRST);
+ }
+ else{
+ DohReplace(num,"0","#o",DOH_REPLACE_FIRST);
+ }
+ }
+ return num;
+}
+
+//less flexible as it does the conversion in C, the lispify name does the conversion in lisp
+String *CFFI::lispy_name(char *name) {
+ bool helper = false;
+ String *new_name = NewString("");
+ for (unsigned int i = 0; i < strlen(name); i++) {
+ if (name[i] == '_' || name[i] == '-') {
+ Printf(new_name, "%c", '-');
+ helper = false;
+ } else if (name[i] >= 'A' && name[i] <= 'Z') {
+ if (helper)
+ Printf(new_name, "%c", '-');
+ Printf(new_name, "%c", ('a' + (name[i] - 'A')));
+ helper = false;
+ } else {
+ helper = true;
+ Printf(new_name, "%c", name[i]);
+ }
+ }
+ return new_name;
+}
+
+extern "C" Language *swig_cffi(void) {
+ return new CFFI();
+}
diff --git a/Source/Modules/chicken.cxx b/Source/Modules/chicken.cxx
new file mode 100644
index 0000000..3bf6602
--- /dev/null
+++ b/Source/Modules/chicken.cxx
@@ -0,0 +1,1552 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * chicken.cxx
+ *
+ * CHICKEN language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_chicken_cxx[] = "$Id: chicken.cxx 11133 2009-02-20 07:52:24Z wsfulton $";
+
+#include "swigmod.h"
+
+#include <ctype.h>
+
+static const char *chicken_usage = (char *) "\
+\
+CHICKEN Options (available with -chicken)\n\
+ -proxy - Export TinyCLOS class definitions\n\
+ -closprefix <prefix> - Prepend <prefix> to all clos identifiers\n\
+ -useclassprefix - Prepend the class name to all clos identifiers\n\
+ -unhideprimitive - Unhide the primitive: symbols\n\
+ -nounit - Do not (declare (unit ...)) in scheme file\n\
+ -noclosuses - Do not (declare (uses ...)) in scheme file\n\
+ -nocollection - Do not register pointers with chicken garbage\n\
+ collector and export destructors\n\
+\n";
+
+static char *module = 0;
+static char *chicken_path = (char *) "chicken";
+static int num_methods = 0;
+
+static File *f_begin = 0;
+static File *f_runtime = 0;
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+static String *chickentext = 0;
+static String *closprefix = 0;
+static String *swigtype_ptr = 0;
+
+
+static String *f_sym_size = 0;
+
+/* some options */
+static int declare_unit = 1;
+static int no_collection = 0;
+static int clos_uses = 1;
+
+/* C++ Support + Clos Classes */
+static int clos = 0;
+static String *c_class_name = 0;
+static String *class_name = 0;
+static String *short_class_name = 0;
+
+static int in_class = 0;
+static int have_constructor = 0;
+static bool exporting_destructor = false;
+static bool exporting_constructor = false;
+static String *constructor_name = 0;
+static String *member_name = 0;
+
+/* sections of the .scm code */
+static String *scm_const_defs = 0;
+static String *clos_class_defines = 0;
+static String *clos_methods = 0;
+
+/* Some clos options */
+static int useclassprefix = 0;
+static String *clossymnameprefix = 0;
+static int hide_primitive = 1;
+static Hash *primitive_names = 0;
+
+/* Used for overloading constructors */
+static int has_constructor_args = 0;
+static List *constructor_arg_types = 0;
+static String *constructor_dispatch = 0;
+
+static Hash *overload_parameter_lists = 0;
+
+class CHICKEN:public Language {
+public:
+
+ virtual void main(int argc, char *argv[]);
+ virtual int top(Node *n);
+ virtual int functionWrapper(Node *n);
+ virtual int variableWrapper(Node *n);
+ virtual int constantWrapper(Node *n);
+ virtual int classHandler(Node *n);
+ virtual int memberfunctionHandler(Node *n);
+ virtual int membervariableHandler(Node *n);
+ virtual int constructorHandler(Node *n);
+ virtual int destructorHandler(Node *n);
+ virtual int validIdentifier(String *s);
+ virtual int staticmembervariableHandler(Node *n);
+ virtual int staticmemberfunctionHandler(Node *n);
+ virtual int importDirective(Node *n);
+
+protected:
+ void addMethod(String *scheme_name, String *function);
+ /* Return true iff T is a pointer type */
+ int isPointer(SwigType *t);
+ void dispatchFunction(Node *n);
+
+ String *chickenNameMapping(String *, const_String_or_char_ptr );
+ String *chickenPrimitiveName(String *);
+
+ String *runtimeCode();
+ String *defaultExternalRuntimeFilename();
+ String *buildClosFunctionCall(List *types, const_String_or_char_ptr closname, const_String_or_char_ptr funcname);
+};
+
+/* -----------------------------------------------------------------------
+ * swig_chicken() - Instantiate module
+ * ----------------------------------------------------------------------- */
+
+static Language *new_swig_chicken() {
+ return new CHICKEN();
+}
+
+extern "C" {
+ Language *swig_chicken(void) {
+ return new_swig_chicken();
+ }
+}
+
+void CHICKEN::main(int argc, char *argv[]) {
+ int i;
+
+ SWIG_library_directory(chicken_path);
+
+ // Look for certain command line options
+ for (i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-help") == 0) {
+ fputs(chicken_usage, stdout);
+ SWIG_exit(0);
+ } else if (strcmp(argv[i], "-proxy") == 0) {
+ clos = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-closprefix") == 0) {
+ if (argv[i + 1]) {
+ clossymnameprefix = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-useclassprefix") == 0) {
+ useclassprefix = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-unhideprimitive") == 0) {
+ hide_primitive = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nounit") == 0) {
+ declare_unit = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noclosuses") == 0) {
+ clos_uses = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nocollection") == 0) {
+ no_collection = 1;
+ Swig_mark_arg(i);
+ }
+ }
+ }
+
+ if (!clos)
+ hide_primitive = 0;
+
+ // Add a symbol for this module
+ Preprocessor_define("SWIGCHICKEN 1", 0);
+
+ // Set name of typemaps
+
+ SWIG_typemap_lang("chicken");
+
+ // Read in default typemaps */
+ SWIG_config_file("chicken.swg");
+ allow_overloading();
+}
+
+int CHICKEN::top(Node *n) {
+ String *chicken_filename = NewString("");
+ File *f_scm;
+ String *scmmodule;
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+ chickentext = NewString("");
+ closprefix = NewString("");
+ f_sym_size = NewString("");
+ primitive_names = NewHash();
+ overload_parameter_lists = NewHash();
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+
+ Swig_register_filebyname("chicken", chickentext);
+ Swig_register_filebyname("closprefix", closprefix);
+
+ clos_class_defines = NewString("");
+ clos_methods = NewString("");
+ scm_const_defs = NewString("");
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGCHICKEN\n");
+
+ if (no_collection)
+ Printf(f_runtime, "#define SWIG_CHICKEN_NO_COLLECTION 1\n");
+
+ Printf(f_runtime, "\n");
+
+ /* Set module name */
+ module = Swig_copy_string(Char(Getattr(n, "name")));
+ scmmodule = NewString(module);
+ Replaceall(scmmodule, "_", "-");
+
+ Printf(f_header, "#define SWIG_init swig_%s_init\n", module);
+ Printf(f_header, "#define SWIG_name \"%s\"\n", scmmodule);
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n");
+ Printf(f_wrappers, "extern \"C\" {\n");
+ Printf(f_wrappers, "#endif\n\n");
+
+ Language::top(n);
+
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n");
+ Printf(f_wrappers, "}\n");
+ Printf(f_wrappers, "#endif\n");
+
+ Printf(f_init, "C_kontinue (continuation, ret);\n");
+ Printf(f_init, "}\n\n");
+
+ Printf(f_init, "#ifdef __cplusplus\n");
+ Printf(f_init, "}\n");
+ Printf(f_init, "#endif\n");
+
+ Printf(chicken_filename, "%s%s.scm", SWIG_output_directory(), module);
+ if ((f_scm = NewFile(chicken_filename, "w", SWIG_output_files())) == 0) {
+ FileErrorDisplay(chicken_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Swig_banner_target_lang(f_scm, ";;");
+ Printf(f_scm, "\n");
+
+ if (declare_unit)
+ Printv(f_scm, "(declare (unit ", scmmodule, "))\n\n", NIL);
+ Printv(f_scm, "(declare \n",
+ tab4, "(hide swig-init swig-init-return)\n",
+ tab4, "(foreign-declare \"C_extern void swig_", module, "_init(C_word,C_word,C_word) C_noret;\"))\n", NIL);
+ Printv(f_scm, "(define swig-init (##core#primitive \"swig_", module, "_init\"))\n", NIL);
+ Printv(f_scm, "(define swig-init-return (swig-init))\n\n", NIL);
+
+ if (clos) {
+ //Printf (f_scm, "(declare (uses tinyclos))\n");
+ //New chicken versions have tinyclos as an egg
+ Printf(f_scm, "(require-extension tinyclos)\n");
+ Replaceall(closprefix, "$module", scmmodule);
+ Printf(f_scm, "%s\n", closprefix);
+ Printf(f_scm, "%s\n", clos_class_defines);
+ Printf(f_scm, "%s\n", clos_methods);
+ } else {
+ Printf(f_scm, "%s\n", scm_const_defs);
+ }
+
+ Printf(f_scm, "%s\n", chickentext);
+
+
+ Close(f_scm);
+ Delete(f_scm);
+
+ char buftmp[20];
+ sprintf(buftmp, "%d", num_methods);
+ Replaceall(f_init, "$nummethods", buftmp);
+ Replaceall(f_init, "$symsize", f_sym_size);
+
+ if (hide_primitive)
+ Replaceall(f_init, "$veclength", buftmp);
+ else
+ Replaceall(f_init, "$veclength", "0");
+
+ Delete(chicken_filename);
+ Delete(chickentext);
+ Delete(closprefix);
+ Delete(overload_parameter_lists);
+
+ Delete(clos_class_defines);
+ Delete(clos_methods);
+ Delete(scm_const_defs);
+
+ /* Close all of the files */
+ Delete(primitive_names);
+ Delete(scmmodule);
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_sym_size);
+ Delete(f_init);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+ return SWIG_OK;
+}
+
+int CHICKEN::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;
+ String *wname;
+ Wrapper *f;
+ String *mangle = NewString("");
+ String *get_pointers;
+ String *cleanup;
+ String *argout;
+ String *tm;
+ String *overname = 0;
+ String *declfunc = 0;
+ String *scmname;
+ bool any_specialized_arg = false;
+ List *function_arg_types = NewList();
+
+ int num_required;
+ int num_arguments;
+ int have_argout;
+
+ Printf(mangle, "\"%s\"", SwigType_manglestr(d));
+
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ }
+
+ f = NewWrapper();
+ wname = NewString("");
+ get_pointers = NewString("");
+ cleanup = NewString("");
+ argout = NewString("");
+ declfunc = NewString("");
+ scmname = NewString(iname);
+ Replaceall(scmname, "_", "-");
+
+ /* Local vars */
+ Wrapper_add_local(f, "resultobj", "C_word resultobj");
+
+ /* Write code to extract function parameters. */
+ emit_parameter_variables(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);
+
+ Append(wname, Swig_name_wrapper(iname));
+ if (overname) {
+ Append(wname, overname);
+ }
+ // Check for interrupts
+ Printv(f->code, "C_trace(\"", scmname, "\");\n", NIL);
+
+ Printv(f->def, "static ", "void ", wname, " (C_word argc, C_word closure, C_word continuation", NIL);
+ Printv(declfunc, "void ", wname, "(C_word,C_word,C_word", NIL);
+
+ /* Generate code for argument marshalling */
+ 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");
+
+ Printf(f->def, ", C_word scm%d", i + 1);
+ Printf(declfunc, ",C_word");
+
+ /* Look for an input typemap */
+ if ((tm = Getattr(p, "tmap:in"))) {
+ String *parse = Getattr(p, "tmap:in:parse");
+ if (!parse) {
+ String *source = NewStringf("scm%d", i + 1);
+ 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");
+ }
+
+ if (i >= num_required)
+ Printf(get_pointers, "if (argc-2>%i && (%s)) {\n", i, source);
+ Printv(get_pointers, tm, "\n", NIL);
+ if (i >= num_required)
+ Printv(get_pointers, "}\n", NIL);
+
+ if (clos) {
+ if (i < num_required) {
+ if (strcmp("void", Char(pt)) != 0) {
+ Node *class_node = 0;
+ String *clos_code = Getattr(p, "tmap:in:closcode");
+ class_node = classLookup(pt);
+ if (clos_code && class_node) {
+ String *class_name = NewStringf("<%s>", Getattr(class_node, "sym:name"));
+ Replaceall(class_name, "_", "-");
+ Append(function_arg_types, class_name);
+ Append(function_arg_types, Copy(clos_code));
+ any_specialized_arg = true;
+ Delete(class_name);
+ } else {
+ Append(function_arg_types, "<top>");
+ Append(function_arg_types, "$input");
+ }
+ }
+ }
+ }
+ Delete(source);
+ }
+
+ 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;
+ }
+ }
+
+ /* finish argument marshalling */
+
+ Printf(f->def, ") {");
+ Printf(declfunc, ")");
+
+ if (num_required != num_arguments) {
+ Append(function_arg_types, "^^##optional$$");
+ }
+
+ /* First check the number of arguments is correct */
+ if (num_arguments != num_required)
+ Printf(f->code, "if (argc-2<%i || argc-2>%i) C_bad_argc(argc,%i);\n", num_required, num_arguments, num_required + 2);
+ else
+ Printf(f->code, "if (argc!=%i) C_bad_argc(argc,%i);\n", num_arguments + 2, num_arguments + 2);
+
+ /* Now piece together the first part of the wrapper function */
+ Printv(f->code, get_pointers, NIL);
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:freearg"))) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Printv(cleanup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ have_argout = 0;
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+
+ if (!have_argout) {
+ have_argout = 1;
+ // Print initial argument output code
+ Printf(argout, "SWIG_Chicken_SetupArgout\n");
+ }
+
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$arg", Getattr(p, "emit:input"));
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printf(argout, "%s", tm);
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ Setattr(n, "wrap:name", wname);
+
+ /* Emit the function call */
+ String *actioncode = emit_action(n);
+
+ /* Return the function value */
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+ if (GetFlag(n, "feature:new")) {
+ Replaceall(tm, "$owner", "1");
+ } else {
+ Replaceall(tm, "$owner", "0");
+ }
+
+ Printf(f->code, "%s", tm);
+
+ if (have_argout)
+ Printf(f->code, "\nSWIG_APPEND_VALUE(resultobj);\n");
+
+ } 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);
+ }
+ emit_return_variable(n, d, f);
+
+ /* Insert the argumetn output code */
+ Printv(f->code, argout, NIL);
+
+ /* Output cleanup code */
+ Printv(f->code, cleanup, NIL);
+
+ /* Look to see if there is any newfree cleanup code */
+ if (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("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("ret", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+
+
+ if (have_argout) {
+ Printf(f->code, "C_kontinue(continuation,C_SCHEME_END_OF_LIST);\n");
+ } else {
+ if (exporting_constructor && clos && hide_primitive) {
+ /* Don't return a proxy, the wrapped CLOS class is the proxy */
+ Printf(f->code, "C_kontinue(continuation,resultobj);\n");
+ } else {
+ // make the continuation the proxy creation function, if one exists
+ Printv(f->code, "{\n",
+ "C_word func;\n",
+ "SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
+ "if (C_swig_is_closurep(func))\n",
+ " ((C_proc4)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
+ "else\n", " C_kontinue(continuation, resultobj);\n", "}\n", NIL);
+ }
+ }
+
+ /* Error handling code */
+#ifdef USE_FAIL
+ Printf(f->code, "fail:\n");
+ Printv(f->code, cleanup, NIL);
+ Printf(f->code, "swig_panic (\"failure in " "'$symname' SWIG function wrapper\");\n");
+#endif
+ 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 */
+ Printv(f_wrappers, "static ", declfunc, " C_noret;\n", NIL);
+ Wrapper_print(f, f_wrappers);
+
+ /* Now register the function with the interpreter. */
+ if (!Getattr(n, "sym:overloaded")) {
+ if (exporting_destructor && !no_collection) {
+ Printf(f_init, "((swig_chicken_clientdata *)(SWIGTYPE%s->clientdata))->destroy = (swig_chicken_destructor) %s;\n", swigtype_ptr, wname);
+ } else {
+ addMethod(scmname, wname);
+ }
+
+ /* Only export if we are not in a class, or if in a class memberfunction */
+ if (!in_class || member_name) {
+ String *method_def;
+ String *clos_name;
+ if (in_class)
+ clos_name = NewString(member_name);
+ else
+ clos_name = chickenNameMapping(scmname, (char *) "");
+
+ if (!any_specialized_arg) {
+ method_def = NewString("");
+ Printv(method_def, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")", NIL);
+ } else {
+ method_def = buildClosFunctionCall(function_arg_types, clos_name, chickenPrimitiveName(scmname));
+ }
+ Printv(clos_methods, method_def, "\n", NIL);
+ Delete(clos_name);
+ Delete(method_def);
+ }
+
+ if (have_constructor && !has_constructor_args && any_specialized_arg) {
+ has_constructor_args = 1;
+ constructor_arg_types = Copy(function_arg_types);
+ }
+ } else {
+ /* add function_arg_types to overload hash */
+ List *flist = Getattr(overload_parameter_lists, scmname);
+ if (!flist) {
+ flist = NewList();
+ Setattr(overload_parameter_lists, scmname, flist);
+ }
+
+ Append(flist, Copy(function_arg_types));
+
+ if (!Getattr(n, "sym:nextSibling")) {
+ dispatchFunction(n);
+ }
+ }
+
+
+ Delete(wname);
+ Delete(get_pointers);
+ Delete(cleanup);
+ Delete(declfunc);
+ Delete(mangle);
+ Delete(function_arg_types);
+ DelWrapper(f);
+ return SWIG_OK;
+}
+
+int CHICKEN::variableWrapper(Node *n) {
+ char *name = GetChar(n, "name");
+ char *iname = GetChar(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+
+ String *wname = NewString("");
+ String *mangle = NewString("");
+ String *tm;
+ String *tm2 = NewString("");;
+ String *argnum = NewString("0");
+ String *arg = NewString("argv[0]");
+ Wrapper *f;
+ String *overname = 0;
+ String *scmname;
+
+ int num_required;
+ int num_arguments;
+
+ scmname = NewString(iname);
+ Replaceall(scmname, "_", "-");
+
+ Printf(mangle, "\"%s\"", SwigType_manglestr(t));
+
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ }
+
+ f = NewWrapper();
+
+ /* 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);
+
+ // evaluation function names
+ Append(wname, Swig_name_wrapper(iname));
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n, "wrap:name", wname);
+
+ // Check for interrupts
+ Printv(f->code, "C_trace(\"", scmname, "\");\n", NIL);
+
+ if (1 || (SwigType_type(t) != T_USER) || (isPointer(t))) {
+
+ Printv(f->def, "static ", "void ", wname, "(C_word, C_word, C_word, C_word) C_noret;\n", NIL);
+ Printv(f->def, "static " "void ", wname, "(C_word argc, C_word closure, " "C_word continuation, C_word value) {\n", NIL);
+
+ Wrapper_add_local(f, "resultobj", "C_word resultobj");
+
+ Printf(f->code, "if (argc!=2 && argc!=3) C_bad_argc(argc,2);\n");
+
+ /* Check for a setting of the variable value */
+ if (!GetFlag(n, "feature:immutable")) {
+ Printf(f->code, "if (argc > 2) {\n");
+ if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
+ Replaceall(tm, "$source", "value");
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$input", "value");
+ /* Printv(f->code, tm, "\n",NIL); */
+ emit_action_code(n, f->code, 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(f->code, "}\n");
+ }
+
+ String *varname;
+ if (SwigType_istemplate((char *) name)) {
+ varname = SwigType_namestr((char *) name);
+ } else {
+ varname = name;
+ }
+
+ // Now return the value of the variable - regardless
+ // of evaluating or setting.
+ if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
+ Replaceall(tm, "$source", varname);
+ Replaceall(tm, "$varname", varname);
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+ /* Printf(f->code, "%s\n", tm); */
+ emit_action_code(n, f->code, tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
+ }
+
+ Printv(f->code, "{\n",
+ "C_word func;\n",
+ "SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
+ "if (C_swig_is_closurep(func))\n",
+ " ((C_proc4)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
+ "else\n", " C_kontinue(continuation, resultobj);\n", "}\n", NIL);
+
+ /* Error handling code */
+#ifdef USE_FAIL
+ Printf(f->code, "fail:\n");
+ Printf(f->code, "swig_panic (\"failure in " "'%s' SWIG wrapper\");\n", proc_name);
+#endif
+ Printf(f->code, "}\n");
+
+ Wrapper_print(f, f_wrappers);
+
+ /* Now register the variable with the interpreter. */
+ addMethod(scmname, wname);
+
+ if (!in_class || member_name) {
+ String *clos_name;
+ if (in_class)
+ clos_name = NewString(member_name);
+ else
+ clos_name = chickenNameMapping(scmname, (char *) "");
+
+ Node *class_node = classLookup(t);
+ String *clos_code = Getattr(n, "tmap:varin:closcode");
+ if (class_node && clos_code && !GetFlag(n, "feature:immutable")) {
+ Replaceall(clos_code, "$input", "(car lst)");
+ Printv(clos_methods, "(define (", clos_name, " . lst) (if (null? lst) (", chickenPrimitiveName(scmname), ") (",
+ chickenPrimitiveName(scmname), " ", clos_code, ")))\n", NIL);
+ } else {
+ /* Simply re-export the procedure */
+ if (GetFlag(n, "feature:immutable") && GetFlag(n, "feature:constasvar")) {
+ Printv(clos_methods, "(define ", clos_name, " (", chickenPrimitiveName(scmname), "))\n", NIL);
+ Printv(scm_const_defs, "(set! ", scmname, " (", scmname, "))\n", NIL);
+ } else {
+ Printv(clos_methods, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
+ }
+ }
+ Delete(clos_name);
+ }
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0));
+ }
+
+ Delete(wname);
+ Delete(argnum);
+ Delete(arg);
+ Delete(tm2);
+ Delete(mangle);
+ DelWrapper(f);
+ return SWIG_OK;
+}
+
+/* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+int CHICKEN::constantWrapper(Node *n) {
+
+ char *name = GetChar(n, "name");
+ char *iname = GetChar(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *value = Getattr(n, "value");
+
+ String *proc_name = NewString("");
+ String *wname = NewString("");
+ String *mangle = NewString("");
+ String *tm;
+ String *tm2 = NewString("");
+ String *source = NewString("");
+ String *argnum = NewString("0");
+ String *arg = NewString("argv[0]");
+ Wrapper *f;
+ String *overname = 0;
+ String *scmname;
+ String *rvalue;
+ SwigType *nctype;
+
+ int num_required;
+ int num_arguments;
+
+ scmname = NewString(iname);
+ Replaceall(scmname, "_", "-");
+
+ Printf(source, "swig_const_%s", iname);
+ Replaceall(source, "::", "__");
+
+ Printf(mangle, "\"%s\"", SwigType_manglestr(t));
+
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ }
+
+ Append(wname, Swig_name_wrapper(iname));
+ if (overname) {
+ Append(wname, overname);
+ }
+
+ nctype = NewString(t);
+ if (SwigType_isconst(nctype)) {
+ Delete(SwigType_pop(nctype));
+ }
+
+ 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);
+ }
+
+ /* Special hook for member pointer */
+ if (SwigType_type(t) == T_MPOINTER) {
+ Printf(f_header, "static %s = %s;\n", SwigType_str(t, source), rvalue);
+ } else {
+ if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
+ Replaceall(tm, "$source", rvalue);
+ Replaceall(tm, "$target", source);
+ Replaceall(tm, "$result", source);
+ Replaceall(tm, "$value", rvalue);
+ Printf(f_header, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+ }
+
+ f = NewWrapper();
+
+ /* 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);
+
+ // evaluation function names
+
+ // Check for interrupts
+ Printv(f->code, "C_trace(\"", scmname, "\");\n", NIL);
+
+ if (1 || (SwigType_type(t) != T_USER) || (isPointer(t))) {
+
+ Setattr(n, "wrap:name", wname);
+ Printv(f->def, "static ", "void ", wname, "(C_word, C_word, C_word) C_noret;\n", NIL);
+
+ Printv(f->def, "static ", "void ", wname, "(C_word argc, C_word closure, " "C_word continuation) {\n", NIL);
+
+ Wrapper_add_local(f, "resultobj", "C_word resultobj");
+
+ Printf(f->code, "if (argc!=2) C_bad_argc(argc,2);\n");
+
+ // Return the value of the variable
+ if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
+
+ Replaceall(tm, "$source", source);
+ Replaceall(tm, "$varname", source);
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+ /* Printf(f->code, "%s\n", tm); */
+ emit_action_code(n, f->code, tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
+ }
+
+ Printv(f->code, "{\n",
+ "C_word func;\n",
+ "SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
+ "if (C_swig_is_closurep(func))\n",
+ " ((C_proc4)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
+ "else\n", " C_kontinue(continuation, resultobj);\n", "}\n", NIL);
+
+ /* Error handling code */
+#ifdef USE_FAIL
+ Printf(f->code, "fail:\n");
+ Printf(f->code, "swig_panic (\"failure in " "'%s' SWIG wrapper\");\n", proc_name);
+#endif
+ Printf(f->code, "}\n");
+
+ Wrapper_print(f, f_wrappers);
+
+ /* Now register the variable with the interpreter. */
+ addMethod(scmname, wname);
+
+ if (!in_class || member_name) {
+ String *clos_name;
+ if (in_class)
+ clos_name = NewString(member_name);
+ else
+ clos_name = chickenNameMapping(scmname, (char *) "");
+ if (GetFlag(n, "feature:constasvar")) {
+ Printv(clos_methods, "(define ", clos_name, " (", chickenPrimitiveName(scmname), "))\n", NIL);
+ Printv(scm_const_defs, "(set! ", scmname, " (", scmname, "))\n", NIL);
+ } else {
+ Printv(clos_methods, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
+ }
+ Delete(clos_name);
+ }
+
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0));
+ }
+
+ Delete(wname);
+ Delete(nctype);
+ Delete(proc_name);
+ Delete(argnum);
+ Delete(arg);
+ Delete(tm2);
+ Delete(mangle);
+ Delete(source);
+ Delete(rvalue);
+ DelWrapper(f);
+ return SWIG_OK;
+}
+
+int CHICKEN::classHandler(Node *n) {
+ /* Create new strings for building up a wrapper function */
+ have_constructor = 0;
+ constructor_dispatch = 0;
+ constructor_name = 0;
+
+ c_class_name = NewString(Getattr(n, "sym:name"));
+ class_name = NewString("");
+ short_class_name = NewString("");
+ Printv(class_name, "<", c_class_name, ">", NIL);
+ Printv(short_class_name, c_class_name, NIL);
+ Replaceall(class_name, "_", "-");
+ Replaceall(short_class_name, "_", "-");
+
+ if (!addSymbol(class_name, n))
+ return SWIG_ERROR;
+
+ /* Handle inheritance */
+ String *base_class = NewString("");
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator base = First(baselist);
+ while (base.item) {
+ if (!Getattr(base.item, "feature:ignore"))
+ Printv(base_class, "<", Getattr(base.item, "sym:name"), "> ", NIL);
+ base = Next(base);
+ }
+ }
+
+ Replaceall(base_class, "_", "-");
+
+ String *scmmod = NewString(module);
+ Replaceall(scmmod, "_", "-");
+
+ Printv(clos_class_defines, "(define ", class_name, "\n", " (make <swig-metaclass-", scmmod, "> 'name \"", short_class_name, "\"\n", NIL);
+ Delete(scmmod);
+
+ if (Len(base_class)) {
+ Printv(clos_class_defines, " 'direct-supers (list ", base_class, ")\n", NIL);
+ } else {
+ Printv(clos_class_defines, " 'direct-supers (list <object>)\n", NIL);
+ }
+
+ Printf(clos_class_defines, " 'direct-slots (list 'swig-this\n");
+
+ String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name"));
+
+ SwigType *ct = NewStringf("p.%s", Getattr(n, "name"));
+ swigtype_ptr = SwigType_manglestr(ct);
+
+ Printf(f_runtime, "static swig_chicken_clientdata _swig_chicken_clientdata%s = { 0 };\n", mangled_classname);
+ Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", swigtype_ptr, ", (void *) &_swig_chicken_clientdata", mangled_classname, ");\n", NIL);
+ SwigType_remember(ct);
+
+ /* Emit all of the members */
+
+ in_class = 1;
+ Language::classHandler(n);
+ in_class = 0;
+
+ Printf(clos_class_defines, ")))\n\n");
+
+ if (have_constructor) {
+ Printv(clos_methods, "(define-method (initialize (obj ", class_name, ") initargs)\n", " (swig-initialize obj initargs ", NIL);
+ if (constructor_arg_types) {
+ String *initfunc_name = NewStringf("%s@@SWIG@initmethod", class_name);
+ String *func_call = buildClosFunctionCall(constructor_arg_types, initfunc_name, chickenPrimitiveName(constructor_name));
+ Printf(clos_methods, "%s)\n)\n", initfunc_name);
+ Printf(clos_methods, "(declare (hide %s))\n", initfunc_name);
+ Printf(clos_methods, "%s\n", func_call);
+ Delete(func_call);
+ Delete(initfunc_name);
+ Delete(constructor_arg_types);
+ constructor_arg_types = 0;
+ } else if (constructor_dispatch) {
+ Printf(clos_methods, "%s)\n)\n", constructor_dispatch);
+ Delete(constructor_dispatch);
+ constructor_dispatch = 0;
+ } else {
+ Printf(clos_methods, "%s)\n)\n", chickenPrimitiveName(constructor_name));
+ }
+ Delete(constructor_name);
+ constructor_name = 0;
+ } else {
+ Printv(clos_methods, "(define-method (initialize (obj ", class_name, ") initargs)\n", " (swig-initialize obj initargs (lambda x #f)))\n", NIL);
+ }
+
+ /* export class initialization function */
+ if (clos) {
+ String *funcname = NewString(mangled_classname);
+ Printf(funcname, "_swig_chicken_setclosclass");
+ String *closfuncname = NewString(funcname);
+ Replaceall(closfuncname, "_", "-");
+
+ Printv(f_wrappers, "static void ", funcname, "(C_word,C_word,C_word,C_word) C_noret;\n",
+ "static void ", funcname, "(C_word argc, C_word closure, C_word continuation, C_word cl) {\n",
+ " C_trace(\"", funcname, "\");\n",
+ " if (argc!=3) C_bad_argc(argc,3);\n",
+ " swig_chicken_clientdata *cdata = (swig_chicken_clientdata *) SWIGTYPE", swigtype_ptr, "->clientdata;\n",
+ " cdata->gc_proxy_create = CHICKEN_new_gc_root();\n",
+ " CHICKEN_gc_root_set(cdata->gc_proxy_create, cl);\n", " C_kontinue(continuation, C_SCHEME_UNDEFINED);\n", "}\n", NIL);
+ addMethod(closfuncname, funcname);
+
+ Printv(clos_methods, "(", chickenPrimitiveName(closfuncname), " (lambda (x lst) (if lst ",
+ "(cons (make ", class_name, " 'swig-this x) lst) ", "(make ", class_name, " 'swig-this x))))\n\n", NIL);
+ Delete(closfuncname);
+ Delete(funcname);
+ }
+
+ Delete(mangled_classname);
+ Delete(swigtype_ptr);
+ swigtype_ptr = 0;
+
+ Delete(class_name);
+ Delete(short_class_name);
+ Delete(c_class_name);
+ class_name = 0;
+ short_class_name = 0;
+ c_class_name = 0;
+
+ return SWIG_OK;
+}
+
+int CHICKEN::memberfunctionHandler(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+ String *proc = NewString(iname);
+ Replaceall(proc, "_", "-");
+
+ member_name = chickenNameMapping(proc, short_class_name);
+ Language::memberfunctionHandler(n);
+ Delete(member_name);
+ member_name = NULL;
+ Delete(proc);
+
+ return SWIG_OK;
+}
+
+int CHICKEN::staticmemberfunctionHandler(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+ String *proc = NewString(iname);
+ Replaceall(proc, "_", "-");
+
+ member_name = NewStringf("%s-%s", short_class_name, proc);
+ Language::staticmemberfunctionHandler(n);
+ Delete(member_name);
+ member_name = NULL;
+ Delete(proc);
+
+ return SWIG_OK;
+}
+
+int CHICKEN::membervariableHandler(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+ //String *pb = SwigType_typedef_resolve_all(SwigType_base(Getattr(n, "type")));
+
+ Language::membervariableHandler(n);
+
+ String *proc = NewString(iname);
+ Replaceall(proc, "_", "-");
+
+ //Node *class_node = Swig_symbol_clookup(pb, Getattr(n, "sym:symtab"));
+ Node *class_node = classLookup(Getattr(n, "type"));
+
+ //String *getfunc = NewStringf("%s-%s-get", short_class_name, proc);
+ //String *setfunc = NewStringf("%s-%s-set", short_class_name, proc);
+ String *getfunc = Swig_name_get(Swig_name_member(c_class_name, iname));
+ Replaceall(getfunc, "_", "-");
+ String *setfunc = Swig_name_set(Swig_name_member(c_class_name, iname));
+ Replaceall(setfunc, "_", "-");
+
+ Printv(clos_class_defines, " (list '", proc, " ':swig-virtual ':swig-get ", chickenPrimitiveName(getfunc), NIL);
+
+ if (!GetFlag(n, "feature:immutable")) {
+ if (class_node) {
+ Printv(clos_class_defines, " ':swig-set (lambda (x y) (", chickenPrimitiveName(setfunc), " x (slot-ref y 'swig-this))))\n", NIL);
+ } else {
+ Printv(clos_class_defines, " ':swig-set ", chickenPrimitiveName(setfunc), ")\n", NIL);
+ }
+ } else {
+ Printf(clos_class_defines, ")\n");
+ }
+
+ Delete(proc);
+ Delete(setfunc);
+ Delete(getfunc);
+ return SWIG_OK;
+}
+
+int CHICKEN::staticmembervariableHandler(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+ String *proc = NewString(iname);
+ Replaceall(proc, "_", "-");
+
+ member_name = NewStringf("%s-%s", short_class_name, proc);
+ Language::staticmembervariableHandler(n);
+ Delete(member_name);
+ member_name = NULL;
+ Delete(proc);
+
+ return SWIG_OK;
+}
+
+int CHICKEN::constructorHandler(Node *n) {
+ have_constructor = 1;
+ has_constructor_args = 0;
+
+
+ exporting_constructor = true;
+ Language::constructorHandler(n);
+ exporting_constructor = false;
+
+ has_constructor_args = 1;
+
+ String *iname = Getattr(n, "sym:name");
+ constructor_name = Swig_name_construct(iname);
+ Replaceall(constructor_name, "_", "-");
+ return SWIG_OK;
+}
+
+int CHICKEN::destructorHandler(Node *n) {
+
+ if (no_collection)
+ member_name = NewStringf("delete-%s", short_class_name);
+
+ exporting_destructor = true;
+ Language::destructorHandler(n);
+ exporting_destructor = false;
+
+ if (no_collection) {
+ Delete(member_name);
+ member_name = NULL;
+ }
+
+ return SWIG_OK;
+}
+
+int CHICKEN::importDirective(Node *n) {
+ String *modname = Getattr(n, "module");
+ if (modname && clos_uses) {
+
+ // Find the module node for this imported module. It should be the
+ // first child but search just in case.
+ Node *mod = firstChild(n);
+ while (mod && Strcmp(nodeType(mod), "module") != 0)
+ mod = nextSibling(mod);
+
+ if (mod) {
+ String *name = Getattr(mod, "name");
+ if (name) {
+ Printf(closprefix, "(declare (uses %s))\n", name);
+ }
+ }
+ }
+
+ return Language::importDirective(n);
+}
+
+String *CHICKEN::buildClosFunctionCall(List *types, const_String_or_char_ptr closname, const_String_or_char_ptr funcname) {
+ String *method_signature = NewString("");
+ String *func_args = NewString("");
+ String *func_call = NewString("");
+
+ Iterator arg_type;
+ int arg_count = 0;
+ int optional_arguments = 0;
+
+ for (arg_type = First(types); arg_type.item; arg_type = Next(arg_type)) {
+ if (Strcmp(arg_type.item, "^^##optional$$") == 0) {
+ optional_arguments = 1;
+ } else {
+ Printf(method_signature, " (arg%i %s)", arg_count, arg_type.item);
+ arg_type = Next(arg_type);
+ if (!arg_type.item)
+ break;
+
+ String *arg = NewStringf("arg%i", arg_count);
+ String *access_arg = Copy(arg_type.item);
+
+ Replaceall(access_arg, "$input", arg);
+ Printf(func_args, " %s", access_arg);
+
+ Delete(arg);
+ Delete(access_arg);
+ }
+ arg_count++;
+ }
+
+ if (optional_arguments) {
+ Printf(func_call, "(define-method (%s %s . args) (apply %s %s args))", closname, method_signature, funcname, func_args);
+ } else {
+ Printf(func_call, "(define-method (%s %s) (%s %s))", closname, method_signature, funcname, func_args);
+ }
+
+ Delete(method_signature);
+ Delete(func_args);
+
+ return func_call;
+}
+
+extern "C" {
+
+ /* compares based on non-primitive names */
+ static int compareTypeListsHelper(const DOH *a, const DOH *b, int opt_equal) {
+ List *la = (List *) a;
+ List *lb = (List *) b;
+
+ Iterator ia = First(la);
+ Iterator ib = First(lb);
+
+ while (ia.item && ib.item) {
+ int ret = Strcmp(ia.item, ib.item);
+ if (ret)
+ return ret;
+ ia = Next(Next(ia));
+ ib = Next(Next(ib));
+ } if (opt_equal && ia.item && Strcmp(ia.item, "^^##optional$$") == 0)
+ return 0;
+ if (ia.item)
+ return -1;
+ if (opt_equal && ib.item && Strcmp(ib.item, "^^##optional$$") == 0)
+ return 0;
+ if (ib.item)
+ return 1;
+
+ return 0;
+ }
+
+ static int compareTypeLists(const DOH *a, const DOH *b) {
+ return compareTypeListsHelper(a, b, 0);
+ }
+}
+
+void CHICKEN::dispatchFunction(Node *n) {
+ /* Last node in overloaded chain */
+
+ int maxargs;
+ String *tmp = NewString("");
+ String *dispatch = Swig_overload_dispatch(n, "%s (2+$numargs,closure," "continuation$commaargs);", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *f = NewWrapper();
+ String *iname = Getattr(n, "sym:name");
+ String *wname = NewString("");
+ String *scmname = NewString(iname);
+ Replaceall(scmname, "_", "-");
+
+ Append(wname, Swig_name_wrapper(iname));
+
+ Printv(f->def, "static void real_", wname, "(C_word, C_word, C_word, C_word) C_noret;\n", NIL);
+
+ Printv(f->def, "static void real_", wname, "(C_word oldargc, C_word closure, C_word continuation, C_word args) {", NIL);
+
+ Wrapper_add_local(f, "argc", "int argc");
+ Printf(tmp, "C_word argv[%d]", maxargs + 1);
+ Wrapper_add_local(f, "argv", tmp);
+ Wrapper_add_local(f, "ii", "int ii");
+ Wrapper_add_local(f, "t", "C_word t = args");
+ Printf(f->code, "if (!C_swig_is_list (args)) {\n");
+ Printf(f->code, " swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, " "\"Argument #1 must be a list of overloaded arguments\");\n");
+ Printf(f->code, "}\n");
+ Printf(f->code, "argc = C_unfix (C_i_length (args));\n");
+ Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++, t = C_block_item (t, 1)) {\n", maxargs);
+ Printf(f->code, "argv[ii] = C_block_item (t, 0);\n");
+ Printf(f->code, "}\n");
+
+ Printv(f->code, dispatch, "\n", NIL);
+ Printf(f->code, "swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE," "\"No matching function for overloaded '%s'\");\n", iname);
+ Printv(f->code, "}\n", NIL);
+ Wrapper_print(f, f_wrappers);
+ addMethod(scmname, wname);
+
+ DelWrapper(f);
+ f = NewWrapper();
+
+ /* varargs */
+ Printv(f->def, "void ", wname, "(C_word, C_word, C_word, ...) C_noret;\n", NIL);
+ Printv(f->def, "void ", wname, "(C_word c, C_word t0, C_word t1, ...) {", NIL);
+ Printv(f->code,
+ "C_word t2;\n",
+ "va_list v;\n",
+ "C_word *a, c2 = c;\n",
+ "C_save_rest (t1, c2, 2);\n", "a = C_alloc((c-2)*3);\n", "t2 = C_restore_rest (a, C_rest_count (0));\n", "real_", wname, " (3, t0, t1, t2);\n", NIL);
+ Printv(f->code, "}\n", NIL);
+ Wrapper_print(f, f_wrappers);
+
+ /* Now deal with overloaded function when exporting clos */
+ if (clos) {
+ List *flist = Getattr(overload_parameter_lists, scmname);
+ if (flist) {
+ Delattr(overload_parameter_lists, scmname);
+
+ SortList(flist, compareTypeLists);
+
+ String *clos_name;
+ int construct = 0;
+ if (have_constructor && !has_constructor_args) {
+ has_constructor_args = 1;
+ constructor_dispatch = NewStringf("%s@SWIG@new@dispatch", short_class_name);
+ clos_name = Copy(constructor_dispatch);
+ construct = 1;
+ Printf(clos_methods, "(declare (hide %s))\n", clos_name);
+ } else if (in_class)
+ clos_name = NewString(member_name);
+ else
+ clos_name = chickenNameMapping(scmname, (char *) "");
+
+ Iterator f;
+ List *prev = 0;
+ int all_primitive = 1;
+
+ /* first check for duplicates and an empty call */
+ String *newlist = NewList();
+ for (f = First(flist); f.item; f = Next(f)) {
+ /* check if cur is a duplicate of prev */
+ if (prev && compareTypeListsHelper(f.item, prev, 1) == 0) {
+ Delete(f.item);
+ } else {
+ Append(newlist, f.item);
+ prev = f.item;
+ Iterator j;
+ for (j = First(f.item); j.item; j = Next(j)) {
+ if (Strcmp(j.item, "^^##optional$$") != 0 && Strcmp(j.item, "<top>") != 0)
+ all_primitive = 0;
+ }
+ }
+ }
+ Delete(flist);
+ flist = newlist;
+
+ if (all_primitive) {
+ Printf(clos_methods, "(define %s %s)\n", clos_name, chickenPrimitiveName(scmname));
+ } else {
+ for (f = First(flist); f.item; f = Next(f)) {
+ /* now export clos code for argument */
+ String *func_call = buildClosFunctionCall(f.item, clos_name, chickenPrimitiveName(scmname));
+ Printf(clos_methods, "%s\n", func_call);
+ Delete(f.item);
+ Delete(func_call);
+ }
+ }
+
+ Delete(clos_name);
+ Delete(flist);
+ }
+ }
+
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(tmp);
+ Delete(wname);
+}
+
+int CHICKEN::isPointer(SwigType *t) {
+ return SwigType_ispointer(SwigType_typedef_resolve_all(t));
+}
+
+void CHICKEN::addMethod(String *scheme_name, String *function) {
+ String *sym = NewString("");
+ if (clos) {
+ Append(sym, "primitive:");
+ }
+ Append(sym, scheme_name);
+
+ /* add symbol to Chicken internal symbol table */
+ if (hide_primitive) {
+ Printv(f_init, "{\n",
+ " C_word *p0 = a;\n", " *(a++)=C_CLOSURE_TYPE|1;\n", " *(a++)=(C_word)", function, ";\n", " C_mutate(return_vec++, (C_word)p0);\n", "}\n", NIL);
+ } else {
+ Printf(f_sym_size, "+C_SIZEOF_INTERNED_SYMBOL(%d)", Len(sym));
+ Printf(f_init, "sym = C_intern (&a, %d, \"%s\");\n", Len(sym), sym);
+ Printv(f_init, "C_mutate ((C_word*)sym+1, (*a=C_CLOSURE_TYPE|1, a[1]=(C_word)", function, ", tmp=(C_word)a, a+=2, tmp));\n", NIL);
+ }
+
+ if (hide_primitive) {
+ Setattr(primitive_names, scheme_name, NewStringf("(vector-ref swig-init-return %i)", num_methods));
+ } else {
+ Setattr(primitive_names, scheme_name, Copy(sym));
+ }
+
+ num_methods++;
+
+ Delete(sym);
+}
+
+String *CHICKEN::chickenPrimitiveName(String *name) {
+ String *value = Getattr(primitive_names, name);
+ if (value)
+ return value;
+ else {
+ Swig_error(input_file, line_number, "Internal Error: attempting to reference non-existant primitive name %s\n", name);
+ return NewString("#f");
+ }
+}
+
+int CHICKEN::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;
+}
+
+ /* ------------------------------------------------------------
+ * closNameMapping()
+ * Maps the identifier from C++ to the CLOS based on command
+ * line parameters and such.
+ * If class_name = "" that means the mapping is for a function or
+ * variable not attached to any class.
+ * ------------------------------------------------------------ */
+String *CHICKEN::chickenNameMapping(String *name, const_String_or_char_ptr class_name) {
+ String *n = NewString("");
+
+ if (Strcmp(class_name, "") == 0) {
+ // not part of a class, so no class name to prefix
+ if (clossymnameprefix) {
+ Printf(n, "%s%s", clossymnameprefix, name);
+ } else {
+ Printf(n, "%s", name);
+ }
+ } else {
+ if (useclassprefix) {
+ Printf(n, "%s-%s", class_name, name);
+ } else {
+ if (clossymnameprefix) {
+ Printf(n, "%s%s", clossymnameprefix, name);
+ } else {
+ Printf(n, "%s", name);
+ }
+ }
+ }
+ return n;
+}
+
+String *CHICKEN::runtimeCode() {
+ String *s = Swig_include_sys("chickenrun.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'chickenrun.swg'\n");
+ s = NewString("");
+ }
+ return s;
+}
+
+String *CHICKEN::defaultExternalRuntimeFilename() {
+ return NewString("swigchickenrun.h");
+}
diff --git a/Source/Modules/clisp.cxx b/Source/Modules/clisp.cxx
new file mode 100644
index 0000000..665a8c2
--- /dev/null
+++ b/Source/Modules/clisp.cxx
@@ -0,0 +1,509 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * clisp.cxx
+ *
+ * clisp language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_clisp_cxx[] = "$Id: clisp.cxx 11380 2009-07-08 12:17:45Z wsfulton $";
+
+#include "swigmod.h"
+
+class CLISP:public Language {
+public:
+ File *f_cl;
+ String *module;
+ virtual void main(int argc, char *argv[]);
+ virtual int top(Node *n);
+ virtual int functionWrapper(Node *n);
+ virtual int variableWrapper(Node *n);
+ virtual int constantWrapper(Node *n);
+ virtual int classDeclaration(Node *n);
+ virtual int enumDeclaration(Node *n);
+ virtual int typedefHandler(Node *n);
+ List *entries;
+private:
+ String *get_ffi_type(Node *n, SwigType *ty);
+ String *convert_literal(String *num_param, String *type);
+ String *strip_parens(String *string);
+ int extern_all_flag;
+ int generate_typedef_flag;
+ int is_function;
+};
+
+void CLISP::main(int argc, char *argv[]) {
+ int i;
+
+ Preprocessor_define("SWIGCLISP 1", 0);
+ SWIG_library_directory("clisp");
+ SWIG_config_file("clisp.swg");
+ generate_typedef_flag = 0;
+ extern_all_flag = 0;
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-help")) {
+ Printf(stdout, "clisp Options (available with -clisp)\n");
+ Printf(stdout,
+ " -extern-all\n"
+ "\t If this option is given then clisp definitions for all the functions\n"
+ "and global variables will be created otherwise only definitions for \n"
+ "externed functions and variables are created.\n"
+ " -generate-typedef\n"
+ "\t If this option is given then def-c-type will be used to generate shortcuts\n"
+ "according to the typedefs in the input.\n");
+ } else if ((Strcmp(argv[i], "-extern-all") == 0)) {
+ extern_all_flag = 1;
+ Swig_mark_arg(i);
+ } else if ((Strcmp(argv[i], "-generate-typedef") == 0)) {
+ generate_typedef_flag = 1;
+ Swig_mark_arg(i);
+ }
+ }
+}
+
+int CLISP::top(Node *n) {
+
+ File *f_null = NewString("");
+ module = Getattr(n, "name");
+ String *output_filename;
+ entries = NewList();
+
+ /* Get the output file name */
+ String *outfile = Getattr(n, "outfile");
+
+ if (!outfile)
+ output_filename = outfile;
+ else {
+ output_filename = NewString("");
+ Printf(output_filename, "%s%s.lisp", SWIG_output_directory(), module);
+ }
+
+ f_cl = NewFile(output_filename, "w+", SWIG_output_files());
+ if (!f_cl) {
+ FileErrorDisplay(output_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Swig_register_filebyname("header", f_null);
+ Swig_register_filebyname("begin", f_null);
+ Swig_register_filebyname("runtime", f_null);
+ Swig_register_filebyname("wrapper", f_null);
+
+ String *header = NewString("");
+
+ Swig_banner_target_lang(header, ";;");
+
+ Printf(header, "\n(defpackage :%s\n (:use :common-lisp :ffi)", module);
+
+ Language::top(n);
+
+ Iterator i;
+
+ long len = Len(entries);
+ if (len > 0) {
+ Printf(header, "\n (:export");
+ }
+ //else nothing to export
+
+ for (i = First(entries); i.item; i = Next(i)) {
+ Printf(header, "\n\t:%s", i.item);
+ }
+
+ if (len > 0) {
+ Printf(header, ")");
+ }
+
+ Printf(header, ")\n");
+ Printf(header, "\n(in-package :%s)\n", module);
+ Printf(header, "\n(default-foreign-language :stdc)\n");
+
+ len = Tell(f_cl);
+
+ Printf(f_cl, "%s", header);
+
+ long end = Tell(f_cl);
+
+ for (len--; len >= 0; len--) {
+ end--;
+ Seek(f_cl, len, SEEK_SET);
+ int ch = Getc(f_cl);
+ Seek(f_cl, end, SEEK_SET);
+ Putc(ch, f_cl);
+ }
+
+ Seek(f_cl, 0, SEEK_SET);
+ Write(f_cl, Char(header), Len(header));
+
+ Close(f_cl);
+ Delete(f_cl); // Deletes the handle, not the file
+
+ return SWIG_OK;
+}
+
+
+int CLISP::functionWrapper(Node *n) {
+ is_function = 1;
+ String *storage = Getattr(n, "storage");
+ if (!extern_all_flag && (!storage || (Strcmp(storage, "extern") && Strcmp(storage, "externc"))))
+ return SWIG_OK;
+
+ String *func_name = Getattr(n, "sym:name");
+
+ ParmList *pl = Getattr(n, "parms");
+
+ int argnum = 0, first = 1;
+
+ Printf(f_cl, "\n(ffi:def-call-out %s\n\t(:name \"%s\")\n", func_name, func_name);
+
+ Append(entries, func_name);
+
+ if (ParmList_len(pl) != 0) {
+ Printf(f_cl, "\t(:arguments ");
+ }
+ for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
+
+ String *argname = Getattr(p, "name");
+ // SwigType *argtype;
+
+ String *ffitype = get_ffi_type(n, Getattr(p, "type"));
+
+ int tempargname = 0;
+
+ if (!argname) {
+ argname = NewStringf("arg%d", argnum);
+ tempargname = 1;
+ }
+
+ if (!first) {
+ Printf(f_cl, "\n\t\t");
+ }
+ Printf(f_cl, "(%s %s)", argname, ffitype);
+ first = 0;
+
+ Delete(ffitype);
+
+ if (tempargname)
+ Delete(argname);
+ }
+ if (ParmList_len(pl) != 0) {
+ Printf(f_cl, ")\n"); /* finish arg list */
+ }
+ String *ffitype = get_ffi_type(n, Getattr(n, "type"));
+ if (Strcmp(ffitype, "NIL")) { //when return type is not nil
+ Printf(f_cl, "\t(:return-type %s)\n", ffitype);
+ }
+ Printf(f_cl, "\t(:library +library-name+))\n");
+
+ return SWIG_OK;
+}
+
+
+int CLISP::constantWrapper(Node *n) {
+ is_function = 0;
+ String *type = Getattr(n, "type");
+ String *converted_value = convert_literal(Getattr(n, "value"), type);
+ String *name = Getattr(n, "sym:name");
+
+ Printf(f_cl, "\n(defconstant %s %s)\n", name, converted_value);
+ Append(entries, name);
+ Delete(converted_value);
+
+ return SWIG_OK;
+}
+
+int CLISP::variableWrapper(Node *n) {
+ is_function = 0;
+ // SwigType *type=;
+ String *storage = Getattr(n, "storage");
+
+ if (!extern_all_flag && (!storage || (Strcmp(storage, "extern") && Strcmp(storage, "externc"))))
+ return SWIG_OK;
+
+ String *var_name = Getattr(n, "sym:name");
+ String *lisp_type = get_ffi_type(n, Getattr(n, "type"));
+ Printf(f_cl, "\n(ffi:def-c-var %s\n (:name \"%s\")\n (:type %s)\n", var_name, var_name, lisp_type);
+ Printf(f_cl, "\t(:library +library-name+))\n");
+ Append(entries, var_name);
+
+ Delete(lisp_type);
+ return SWIG_OK;
+}
+
+int CLISP::typedefHandler(Node *n) {
+ if (generate_typedef_flag) {
+ is_function = 0;
+ Printf(f_cl, "\n(ffi:def-c-type %s %s)\n", Getattr(n, "name"), get_ffi_type(n, Getattr(n, "type")));
+ }
+
+ return Language::typedefHandler(n);
+}
+
+int CLISP::enumDeclaration(Node *n) {
+ is_function = 0;
+ String *name = Getattr(n, "sym:name");
+
+ Printf(f_cl, "\n(ffi:def-c-enum %s ", name);
+
+ for (Node *c = firstChild(n); c; c = nextSibling(c)) {
+
+ String *slot_name = Getattr(c, "name");
+ String *value = Getattr(c, "enumvalue");
+
+ Printf(f_cl, "(%s %s)", slot_name, value);
+
+ Append(entries, slot_name);
+
+ Delete(value);
+ }
+
+ Printf(f_cl, ")\n");
+ return SWIG_OK;
+}
+
+
+// Includes structs
+int CLISP::classDeclaration(Node *n) {
+ is_function = 0;
+ String *name = Getattr(n, "sym:name");
+ String *kind = Getattr(n, "kind");
+
+ if (Strcmp(kind, "struct")) {
+ Printf(stderr, "Don't know how to deal with %s kind of class yet.\n", kind);
+ Printf(stderr, " (name: %s)\n", name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+
+ Printf(f_cl, "\n(ffi:def-c-struct %s", name);
+
+ Append(entries, NewStringf("make-%s", name));
+
+ for (Node *c = firstChild(n); c; c = nextSibling(c)) {
+
+ if (Strcmp(nodeType(c), "cdecl")) {
+ Printf(stderr, "Structure %s has a slot that we can't deal with.\n", name);
+ Printf(stderr, "nodeType: %s, name: %s, type: %s\n", nodeType(c), Getattr(c, "name"), Getattr(c, "type"));
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ String *temp = Copy(Getattr(c, "decl"));
+ Append(temp, Getattr(c, "type")); //appending type to the end, otherwise wrong type
+ String *lisp_type = get_ffi_type(n, temp);
+ Delete(temp);
+
+ String *slot_name = Getattr(c, "sym:name");
+ Printf(f_cl, "\n\t(%s %s)", slot_name, lisp_type);
+
+ Append(entries, NewStringf("%s-%s", name, slot_name));
+
+ Delete(lisp_type);
+ }
+
+ Printf(f_cl, ")\n");
+
+ /* Add this structure to the known lisp types */
+ //Printf(stdout, "Adding %s foreign type\n", name);
+ // add_defined_foreign_type(name);
+
+ return SWIG_OK;
+}
+
+/* utilities */
+/* returns new string w/ parens stripped */
+String *CLISP::strip_parens(String *string) {
+ char *s = Char(string), *p;
+ int len = Len(string);
+ String *res;
+
+ if (len == 0 || s[0] != '(' || s[len - 1] != ')') {
+ return NewString(string);
+ }
+
+ p = (char *) malloc(len - 2 + 1);
+ if (!p) {
+ Printf(stderr, "Malloc failed\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ strncpy(p, s + 1, len - 1);
+ p[len - 2] = 0; /* null terminate */
+
+ res = NewString(p);
+ free(p);
+
+ return res;
+}
+
+String *CLISP::convert_literal(String *num_param, String *type) {
+ String *num = strip_parens(num_param), *res;
+ char *s = Char(num);
+
+ /* Make sure doubles use 'd' instead of 'e' */
+ if (!Strcmp(type, "double")) {
+ String *updated = Copy(num);
+ if (Replace(updated, "e", "d", DOH_REPLACE_ANY) > 1) {
+ Printf(stderr, "Weird!! number %s looks invalid.\n", num);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(num);
+ return updated;
+ }
+
+ if (SwigType_type(type) == T_CHAR) {
+ /* Use CL syntax for character literals */
+ return NewStringf("#\\%s", num_param);
+ } else if (SwigType_type(type) == T_STRING) {
+ /* Use CL syntax for string literals */
+ return NewStringf("\"%s\"", num_param);
+ }
+
+ if (Len(num) < 2 || s[0] != '0') {
+ return num;
+ }
+
+ /* octal or hex */
+
+ res = NewStringf("#%c%s", s[1] == 'x' ? 'x' : 'o', s + 2);
+ Delete(num);
+
+ return res;
+}
+
+String *CLISP::get_ffi_type(Node *n, SwigType *ty) {
+ Node *node = NewHash();
+ Setattr(node, "type", ty);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *tm = Swig_typemap_lookup("in", node, "", 0);
+ Delete(node);
+
+ if (tm) {
+ return NewString(tm);
+ } else if (SwigType_ispointer(ty)) {
+ SwigType *cp = Copy(ty);
+ SwigType_del_pointer(cp);
+ String *inner_type = get_ffi_type(n, cp);
+
+ if (SwigType_isfunction(cp)) {
+ return inner_type;
+ }
+
+ SwigType *base = SwigType_base(ty);
+ String *base_name = SwigType_str(base, 0);
+
+ String *str;
+ if (!Strcmp(base_name, "int") || !Strcmp(base_name, "float") || !Strcmp(base_name, "short")
+ || !Strcmp(base_name, "double") || !Strcmp(base_name, "long") || !Strcmp(base_name, "char")) {
+
+ str = NewStringf("(ffi:c-ptr %s)", inner_type);
+ } else {
+ str = NewStringf("(ffi:c-pointer %s)", inner_type);
+ }
+ Delete(base_name);
+ Delete(base);
+ Delete(cp);
+ Delete(inner_type);
+ return str;
+ } else if (SwigType_isarray(ty)) {
+ SwigType *cp = Copy(ty);
+ String *array_dim = SwigType_array_getdim(ty, 0);
+
+ if (!Strcmp(array_dim, "")) { //dimension less array convert to pointer
+ Delete(array_dim);
+ SwigType_del_array(cp);
+ SwigType_add_pointer(cp);
+ String *str = get_ffi_type(n, cp);
+ Delete(cp);
+ return str;
+ } else {
+ SwigType_pop_arrays(cp);
+ String *inner_type = get_ffi_type(n, cp);
+ Delete(cp);
+
+ int ndim = SwigType_array_ndim(ty);
+ String *dimension;
+ if (ndim == 1) {
+ dimension = array_dim;
+ } else {
+ dimension = array_dim;
+ for (int i = 1; i < ndim; i++) {
+ array_dim = SwigType_array_getdim(ty, i);
+ Append(dimension, " ");
+ Append(dimension, array_dim);
+ Delete(array_dim);
+ }
+ String *temp = dimension;
+ dimension = NewStringf("(%s)", dimension);
+ Delete(temp);
+ }
+ String *str;
+ if (is_function)
+ str = NewStringf("(ffi:c-ptr (ffi:c-array %s %s))", inner_type, dimension);
+ else
+ str = NewStringf("(ffi:c-array %s %s)", inner_type, dimension);
+
+ Delete(inner_type);
+ Delete(dimension);
+ return str;
+ }
+ } else if (SwigType_isfunction(ty)) {
+ SwigType *cp = Copy(ty);
+ SwigType *fn = SwigType_pop_function(cp);
+ String *args = NewString("");
+ ParmList *pl = SwigType_function_parms(fn);
+ if (ParmList_len(pl) != 0) {
+ Printf(args, "(:arguments ");
+ }
+ int argnum = 0, first = 1;
+ for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
+ String *argname = Getattr(p, "name");
+ SwigType *argtype = Getattr(p, "type");
+ String *ffitype = get_ffi_type(n, argtype);
+
+ int tempargname = 0;
+
+ if (!argname) {
+ argname = NewStringf("arg%d", argnum);
+ tempargname = 1;
+ }
+ if (!first) {
+ Printf(args, "\n\t\t");
+ }
+ Printf(args, "(%s %s)", argname, ffitype);
+ first = 0;
+ Delete(ffitype);
+ if (tempargname)
+ Delete(argname);
+ }
+ if (ParmList_len(pl) != 0) {
+ Printf(args, ")\n"); /* finish arg list */
+ }
+ String *ffitype = get_ffi_type(n, cp);
+ String *str = NewStringf("(ffi:c-function %s \t\t\t\t(:return-type %s))", args, ffitype);
+ Delete(fn);
+ Delete(args);
+ Delete(cp);
+ Delete(ffitype);
+ return str;
+ }
+ String *str = SwigType_str(ty, 0);
+ if (str) {
+ char *st = Strstr(str, "struct");
+ if (st) {
+ st += 7;
+ return NewString(st);
+ }
+ char *cl = Strstr(str, "class");
+ if (cl) {
+ cl += 6;
+ return NewString(cl);
+ }
+ }
+ return str;
+}
+
+extern "C" Language *swig_clisp(void) {
+ return new CLISP();
+}
diff --git a/Source/Modules/contract.cxx b/Source/Modules/contract.cxx
new file mode 100644
index 0000000..89e3150
--- /dev/null
+++ b/Source/Modules/contract.cxx
@@ -0,0 +1,354 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * contract.cxx
+ *
+ * Support for Wrap by Contract in SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_contract_cxx[] = "$Id: contract.cxx 11049 2009-01-10 01:15:03Z wsfulton $";
+
+#include "swigmod.h"
+
+/* Contract structure. This holds rules about the different kinds of contract sections
+ and their combination rules */
+
+struct contract {
+ const char *section;
+ const char *combiner;
+};
+/* Contract rules. This table defines what contract sections are recognized as well as
+ how contracts are to combined via inheritance */
+
+static contract Rules[] = {
+ {"require:", "&&"},
+ {"ensure:", "||"},
+ {NULL, NULL}
+};
+
+/* ----------------------------------------------------------------------------
+ * class Contracts:
+ *
+ * This class defines the functions that need to be used in
+ * "wrap by contract" module.
+ * ------------------------------------------------------------------------- */
+
+class Contracts:public Dispatcher {
+ String *make_expression(String *s, Node *n);
+ void substitute_parms(String *s, ParmList *p, int method);
+public:
+ Hash *ContractSplit(Node *n);
+ int emit_contract(Node *n, int method);
+ int cDeclaration(Node *n);
+ int constructorDeclaration(Node *n);
+ int externDeclaration(Node *n);
+ int extendDirective(Node *n);
+ int importDirective(Node *n);
+ int includeDirective(Node *n);
+ int namespaceDeclaration(Node *n);
+ int classDeclaration(Node *n);
+ virtual int top(Node *n);
+};
+
+static int Contract_Mode = 0; /* contract option */
+static int InClass = 0; /* Parsing C++ or not */
+static int InConstructor = 0;
+static Node *CurrentClass = 0;
+
+/* Set the contract mode, default is 0 (not open) */
+/* Normally set in main.cxx, when get the "-contracts" option */
+void Swig_contract_mode_set(int flag) {
+ Contract_Mode = flag;
+}
+
+/* Get the contract mode */
+int Swig_contract_mode_get() {
+ return Contract_Mode;
+}
+
+/* Apply contracts */
+void Swig_contracts(Node *n) {
+
+ Contracts *a = new Contracts;
+ a->top(n);
+ delete a;
+}
+
+/* Split the whole contract into preassertion, postassertion and others */
+Hash *Contracts::ContractSplit(Node *n) {
+
+ String *contract = Getattr(n, "feature:contract");
+ Hash *result;
+ if (!contract)
+ return NULL;
+
+ result = NewHash();
+ String *current_section = NewString("");
+ const char *current_section_name = Rules[0].section;
+ List *l = SplitLines(contract);
+
+ Iterator i;
+ for (i = First(l); i.item; i = Next(i)) {
+ int found = 0;
+ if (Strchr(i.item, '{'))
+ continue;
+ if (Strchr(i.item, '}'))
+ continue;
+ for (int j = 0; Rules[j].section; j++) {
+ if (Strstr(i.item, Rules[j].section)) {
+ if (Len(current_section)) {
+ Setattr(result, current_section_name, current_section);
+ current_section = Getattr(result, Rules[j].section);
+ if (!current_section)
+ current_section = NewString("");
+ }
+ current_section_name = Rules[j].section;
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ Append(current_section, i.item);
+ }
+ if (Len(current_section))
+ Setattr(result, current_section_name, current_section);
+ return result;
+}
+
+/* This function looks in base classes and collects contracts found */
+void inherit_contracts(Node *c, Node *n, Hash *contracts, Hash *messages) {
+
+ Node *b, *temp;
+ String *name, *type, *local_decl, *base_decl;
+ List *bases;
+ int found = 0;
+
+ bases = Getattr(c, "bases");
+ if (!bases)
+ return;
+
+ name = Getattr(n, "name");
+ type = Getattr(n, "type");
+ local_decl = Getattr(n, "decl");
+ if (local_decl) {
+ local_decl = SwigType_typedef_resolve_all(local_decl);
+ } else {
+ return;
+ }
+ /* Width first search */
+ for (int i = 0; i < Len(bases); i++) {
+ b = Getitem(bases, i);
+ temp = firstChild(b);
+ while (temp) {
+ base_decl = Getattr(temp, "decl");
+ if (base_decl) {
+ base_decl = SwigType_typedef_resolve_all(base_decl);
+ if ((checkAttribute(temp, "storage", "virtual")) &&
+ (checkAttribute(temp, "name", name)) && (checkAttribute(temp, "type", type)) && (!Strcmp(local_decl, base_decl))) {
+ /* Yes, match found. */
+ Hash *icontracts = Getattr(temp, "contract:rules");
+ Hash *imessages = Getattr(temp, "contract:messages");
+ found = 1;
+ if (icontracts && imessages) {
+ /* Add inherited contracts and messages to the contract rules above */
+ int j = 0;
+ for (j = 0; Rules[j].section; j++) {
+ String *t = Getattr(contracts, Rules[j].section);
+ String *s = Getattr(icontracts, Rules[j].section);
+ if (s) {
+ if (t) {
+ Insert(t, 0, "(");
+ Printf(t, ") %s (%s)", Rules[j].combiner, s);
+ String *m = Getattr(messages, Rules[j].section);
+ Printf(m, " %s [%s from %s]", Rules[j].combiner, Getattr(imessages, Rules[j].section), Getattr(b, "name"));
+ } else {
+ Setattr(contracts, Rules[j].section, NewString(s));
+ Setattr(messages, Rules[j].section, NewStringf("[%s from %s]", Getattr(imessages, Rules[j].section), Getattr(b, "name")));
+ }
+ }
+ }
+ }
+ }
+ Delete(base_decl);
+ }
+ temp = nextSibling(temp);
+ }
+ }
+ Delete(local_decl);
+ if (!found) {
+ for (int j = 0; j < Len(bases); j++) {
+ b = Getitem(bases, j);
+ inherit_contracts(b, n, contracts, messages);
+ }
+ }
+}
+
+/* This function cleans up the assertion string by removing some extraneous characters.
+ Splitting the assertion into pieces */
+
+String *Contracts::make_expression(String *s, Node *n) {
+ String *str_assert, *expr = 0;
+ List *list_assert;
+
+ str_assert = NewString(s);
+ /* Omit all useless characters and split by ; */
+ Replaceall(str_assert, "\n", "");
+ Replaceall(str_assert, "{", "");
+ Replaceall(str_assert, "}", "");
+ Replace(str_assert, " ", "", DOH_REPLACE_ANY | DOH_REPLACE_NOQUOTE);
+ Replace(str_assert, "\t", "", DOH_REPLACE_ANY | DOH_REPLACE_NOQUOTE);
+
+ list_assert = Split(str_assert, ';', -1);
+ Delete(str_assert);
+
+ /* build up new assertion */
+ str_assert = NewString("");
+ Iterator ei;
+
+ for (ei = First(list_assert); ei.item; ei = Next(ei)) {
+ expr = ei.item;
+ if (Len(expr)) {
+ Replaceid(expr, Getattr(n, "name"), "result");
+ if (Len(str_assert))
+ Append(str_assert, "&&");
+ Printf(str_assert, "(%s)", expr);
+ }
+ }
+ Delete(list_assert);
+ return str_assert;
+}
+
+/* This function substitutes parameter names for argument names in the
+ contract specification. Note: it is assumed that the wrapper code
+ uses arg1 for self and arg2..argn for arguments. */
+
+void Contracts::substitute_parms(String *s, ParmList *p, int method) {
+ int argnum = 1;
+ char argname[32];
+
+ if (method) {
+ Replaceid(s, "$self", "arg1");
+ argnum++;
+ }
+ while (p) {
+ sprintf(argname, "arg%d", argnum);
+ String *name = Getattr(p, "name");
+ if (name) {
+ Replaceid(s, name, argname);
+ }
+ argnum++;
+ p = nextSibling(p);
+ }
+}
+
+int Contracts::emit_contract(Node *n, int method) {
+ Hash *contracts;
+ Hash *messages;
+ String *c;
+
+ ParmList *cparms;
+
+ if (!Getattr(n, "feature:contract"))
+ return SWIG_ERROR;
+
+ /* Get contract parameters */
+ cparms = Getmeta(Getattr(n, "feature:contract"), "parms");
+
+ /* Split contract into preassert & postassert */
+ contracts = ContractSplit(n);
+ if (!contracts)
+ return SWIG_ERROR;
+
+ /* This messages hash is used to hold the error messages that will be displayed on
+ failed contract. */
+
+ messages = NewHash();
+
+ /* Take the different contract expressions and clean them up a bit */
+ Iterator i;
+ for (i = First(contracts); i.item; i = Next(i)) {
+ String *e = make_expression(i.item, n);
+ substitute_parms(e, cparms, method);
+ Setattr(contracts, i.key, e);
+
+ /* Make a string containing error messages */
+ Setattr(messages, i.key, NewString(e));
+ }
+
+ /* If we're in a class. We need to inherit other assertions. */
+ if (InClass) {
+ inherit_contracts(CurrentClass, n, contracts, messages);
+ }
+
+ /* Save information */
+ Setattr(n, "contract:rules", contracts);
+ Setattr(n, "contract:messages", messages);
+
+ /* Okay. Generate the contract runtime code. */
+
+ if ((c = Getattr(contracts, "require:"))) {
+ Setattr(n, "contract:preassert", NewStringf("SWIG_contract_assert(%s, \"Contract violation: require: %s\");\n", c, Getattr(messages, "require:")));
+ }
+ if ((c = Getattr(contracts, "ensure:"))) {
+ Setattr(n, "contract:postassert", NewStringf("SWIG_contract_assert(%s, \"Contract violation: ensure: %s\");\n", c, Getattr(messages, "ensure:")));
+ }
+ return SWIG_OK;
+}
+
+int Contracts::cDeclaration(Node *n) {
+ int ret = SWIG_OK;
+ String *decl = Getattr(n, "decl");
+
+ /* Not a function. Don't even bother with it (for now) */
+ if (!SwigType_isfunction(decl))
+ return SWIG_OK;
+
+ if (Getattr(n, "feature:contract"))
+ ret = emit_contract(n, (InClass && !checkAttribute(n, "storage", "static")));
+ return ret;
+}
+
+int Contracts::constructorDeclaration(Node *n) {
+ int ret = SWIG_OK;
+ InConstructor = 1;
+ if (Getattr(n, "feature:contract"))
+ ret = emit_contract(n, 0);
+ InConstructor = 0;
+ return ret;
+}
+
+int Contracts::externDeclaration(Node *n) {
+ return emit_children(n);
+}
+
+int Contracts::extendDirective(Node *n) {
+ return emit_children(n);
+}
+
+int Contracts::importDirective(Node *n) {
+ return emit_children(n);
+}
+
+int Contracts::includeDirective(Node *n) {
+ return emit_children(n);
+}
+
+int Contracts::namespaceDeclaration(Node *n) {
+ return emit_children(n);
+}
+
+int Contracts::classDeclaration(Node *n) {
+ int ret = SWIG_OK;
+ InClass = 1;
+ CurrentClass = n;
+ emit_children(n);
+ InClass = 0;
+ CurrentClass = 0;
+ return ret;
+}
+
+int Contracts::top(Node *n) {
+ emit_children(n);
+ return SWIG_OK;
+}
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
new file mode 100644
index 0000000..5713257
--- /dev/null
+++ b/Source/Modules/csharp.cxx
@@ -0,0 +1,3960 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * csharp.cxx
+ *
+ * C# language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_csharp_cxx[] = "$Id: csharp.cxx 11583 2009-08-15 23:22:20Z wsfulton $";
+
+#include "swigmod.h"
+#include <limits.h> // for INT_MAX
+#include "cparse.h"
+#include <ctype.h>
+
+/* Hash type used for upcalls from C/C++ */
+typedef DOH UpcallData;
+
+class CSHARP:public Language {
+ static const char *usage;
+ const String *empty_string;
+ const String *public_string;
+ const String *protected_string;
+
+ Hash *swig_types_hash;
+ File *f_begin;
+ File *f_runtime;
+ File *f_runtime_h;
+ File *f_header;
+ File *f_wrappers;
+ File *f_init;
+ File *f_directors;
+ File *f_directors_h;
+ List *filenames_list;
+
+ bool proxy_flag; // Flag for generating proxy classes
+ 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
+ bool old_variable_names; // Flag for old style variable names in the intermediary class
+ bool generate_property_declaration_flag; // Flag for generating properties
+
+ String *imclass_name; // intermediary class name
+ String *module_class_name; // module class name
+ String *imclass_class_code; // intermediary class code
+ String *proxy_class_def;
+ String *proxy_class_code;
+ String *module_class_code;
+ String *proxy_class_name;
+ String *variable_name; //Name of a variable being wrapped
+ String *proxy_class_constants_code;
+ String *module_class_constants_code;
+ String *enum_code;
+ String *dllimport; // DllImport attribute name
+ String *namespce; // Optional namespace name
+ String *imclass_imports; //intermediary class imports from %pragma
+ String *module_imports; //module imports from %pragma
+ String *imclass_baseclass; //inheritance for intermediary class class from %pragma
+ String *module_baseclass; //inheritance for module class from %pragma
+ String *imclass_interfaces; //interfaces for intermediary class class from %pragma
+ String *module_interfaces; //interfaces for module class from %pragma
+ String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma
+ String *module_class_modifiers; //class modifiers for module class overriden by %pragma
+ String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
+ String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
+ String *director_callback_typedefs; // Director function pointer typedefs for callbacks
+ String *director_callbacks; // Director callback function pointer member variables
+ String *director_delegate_callback; // Director callback method that delegates are set to call
+ String *director_delegate_definitions; // Director delegates definitions in proxy class
+ String *director_delegate_instances; // Director delegates member variables in proxy class
+ String *director_method_types; // Director method types
+ String *director_connect_parms; // Director delegates parameter list for director connect call
+ String *destructor_call; //C++ destructor call if any
+
+ // Director method stuff:
+ List *dmethods_seq;
+ Hash *dmethods_table;
+ int n_dmethods;
+ int n_directors;
+ int first_class_dmethod;
+ int curr_class_dmethod;
+
+ enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
+
+ static Parm *NewParmFromNode(SwigType *type, const_String_or_char_ptr name, Node *n) {
+ Parm *p = NewParm(type, name);
+ Setfile(p, Getfile(n));
+ Setline(p, Getline(n));
+ return p;
+ }
+
+public:
+
+ /* -----------------------------------------------------------------------------
+ * CSHARP()
+ * ----------------------------------------------------------------------------- */
+
+ CSHARP():empty_string(NewString("")),
+ public_string(NewString("public")),
+ protected_string(NewString("protected")),
+ swig_types_hash(NULL),
+ f_begin(NULL),
+ f_runtime(NULL),
+ f_runtime_h(NULL),
+ f_header(NULL),
+ f_wrappers(NULL),
+ f_init(NULL),
+ f_directors(NULL),
+ f_directors_h(NULL),
+ filenames_list(NULL),
+ proxy_flag(true),
+ native_function_flag(false),
+ enum_constant_flag(false),
+ static_flag(false),
+ variable_wrapper_flag(false),
+ wrapping_member_flag(false),
+ global_variable_flag(false),
+ old_variable_names(false),
+ generate_property_declaration_flag(false),
+ imclass_name(NULL),
+ module_class_name(NULL),
+ imclass_class_code(NULL),
+ proxy_class_def(NULL),
+ proxy_class_code(NULL),
+ module_class_code(NULL),
+ proxy_class_name(NULL),
+ variable_name(NULL),
+ proxy_class_constants_code(NULL),
+ module_class_constants_code(NULL),
+ enum_code(NULL),
+ dllimport(NULL),
+ namespce(NULL),
+ imclass_imports(NULL),
+ module_imports(NULL),
+ imclass_baseclass(NULL),
+ module_baseclass(NULL),
+ imclass_interfaces(NULL),
+ module_interfaces(NULL),
+ imclass_class_modifiers(NULL),
+ module_class_modifiers(NULL),
+ upcasts_code(NULL),
+ imclass_cppcasts_code(NULL),
+ director_callback_typedefs(NULL),
+ director_callbacks(NULL),
+ director_delegate_callback(NULL),
+ director_delegate_definitions(NULL),
+ director_delegate_instances(NULL),
+ director_method_types(NULL),
+ director_connect_parms(NULL),
+ destructor_call(NULL),
+ dmethods_seq(NULL),
+ dmethods_table(NULL),
+ n_dmethods(0),
+ n_directors(0) {
+ /* for now, multiple inheritance in directors is disabled, this
+ should be easy to implement though */
+ director_multiple_inheritance = 0;
+ director_language = 1;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getProxyName()
+ *
+ * Test to see if a type corresponds to something wrapped with a proxy class
+ * Return NULL if not otherwise the proxy class name
+ * ----------------------------------------------------------------------------- */
+
+ String *getProxyName(SwigType *t) {
+ if (proxy_flag) {
+ Node *n = classLookup(t);
+ if (n) {
+ return Getattr(n, "sym:name");
+ }
+ }
+ return NULL;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * directorClassName()
+ * ----------------------------------------------------------------------------- */
+
+ String *directorClassName(Node *n) {
+ String *dirclassname;
+ const char *attrib = "director:classname";
+
+ if (!(dirclassname = Getattr(n, attrib))) {
+ String *classname = Getattr(n, "sym:name");
+
+ dirclassname = NewStringf("SwigDirector_%s", classname);
+ Setattr(n, attrib, dirclassname);
+ }
+
+ return dirclassname;
+ }
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+
+ SWIG_library_directory("csharp");
+
+ // Look for certain command line options
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-dllimport") == 0) {
+ if (argv[i + 1]) {
+ dllimport = NewString("");
+ Printf(dllimport, argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-namespace") == 0) {
+ if (argv[i + 1]) {
+ namespce = NewString("");
+ Printf(namespce, argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if ((strcmp(argv[i], "-noproxy") == 0)) {
+ Swig_mark_arg(i);
+ proxy_flag = false;
+ } else if (strcmp(argv[i], "-oldvarnames") == 0) {
+ Swig_mark_arg(i);
+ old_variable_names = true;
+ } else if (strcmp(argv[i], "-help") == 0) {
+ Printf(stdout, "%s\n", usage);
+ }
+ }
+ }
+
+ // Add a symbol to the parser for conditional compilation
+ Preprocessor_define("SWIGCSHARP 1", 0);
+
+ // Add typemap definitions
+ SWIG_typemap_lang("csharp");
+ SWIG_config_file("csharp.swg");
+
+ allow_overloading();
+ }
+
+ /* ---------------------------------------------------------------------
+ * top()
+ * --------------------------------------------------------------------- */
+
+ virtual int top(Node *n) {
+
+ // Get any options set in the module directive
+ Node *optionsnode = Getattr(Getattr(n, "module"), "options");
+
+ if (optionsnode) {
+ if (Getattr(optionsnode, "imclassname"))
+ imclass_name = Copy(Getattr(optionsnode, "imclassname"));
+ /* check if directors are enabled for this module. note: this
+ * is a "master" switch, without which no director code will be
+ * emitted. %feature("director") statements are also required
+ * to enable directors for individual classes or methods.
+ *
+ * use %module(directors="1") modulename at the start of the
+ * interface file to enable director generation.
+ */
+ if (Getattr(optionsnode, "directors")) {
+ allow_directors();
+ }
+ if (Getattr(optionsnode, "dirprot")) {
+ allow_dirprot();
+ }
+ allow_allprotected(GetFlag(optionsnode, "allprotected"));
+ }
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+ String *outfile_h = Getattr(n, "outfile_h");
+
+ if (!outfile) {
+ Printf(stderr, "Unable to determine outfile\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ if (directorsEnabled()) {
+ if (!outfile_h) {
+ Printf(stderr, "Unable to determine outfile_h\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
+ if (!f_runtime_h) {
+ FileErrorDisplay(outfile_h);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+ f_directors_h = NewString("");
+ f_directors = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+ Swig_register_filebyname("director", f_directors);
+ Swig_register_filebyname("director_h", f_directors_h);
+
+ swig_types_hash = NewHash();
+ filenames_list = NewList();
+
+ // Make the intermediary class and module class names. The intermediary class name can be set in the module directive.
+ if (!imclass_name) {
+ imclass_name = NewStringf("%sPINVOKE", Getattr(n, "name"));
+ module_class_name = Copy(Getattr(n, "name"));
+ } else {
+ // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution
+ if (Cmp(imclass_name, Getattr(n, "name")) == 0)
+ module_class_name = NewStringf("%sModule", Getattr(n, "name"));
+ else
+ module_class_name = Copy(Getattr(n, "name"));
+ }
+
+ imclass_class_code = NewString("");
+ proxy_class_def = NewString("");
+ proxy_class_code = NewString("");
+ module_class_constants_code = NewString("");
+ imclass_baseclass = NewString("");
+ imclass_interfaces = NewString("");
+ imclass_class_modifiers = NewString("");
+ module_class_code = NewString("");
+ module_baseclass = NewString("");
+ module_interfaces = NewString("");
+ module_imports = NewString("");
+ module_class_modifiers = NewString("");
+ imclass_imports = NewString("");
+ imclass_cppcasts_code = NewString("");
+ director_connect_parms = NewString("");
+ upcasts_code = NewString("");
+ dmethods_seq = NewList();
+ dmethods_table = NewHash();
+ n_dmethods = 0;
+ n_directors = 0;
+ if (!namespce)
+ namespce = NewString("");
+ if (!dllimport)
+ dllimport = Copy(module_class_name);
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGCSHARP\n");
+
+ if (directorsEnabled()) {
+ Printf(f_runtime, "#define SWIG_DIRECTORS\n");
+
+ /* Emit initial director header and director code: */
+ Swig_banner(f_directors_h);
+ Printf(f_directors_h, "\n");
+ Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_class_name);
+ Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_class_name);
+
+ Printf(f_directors, "\n\n");
+ Printf(f_directors, "/* ---------------------------------------------------\n");
+ Printf(f_directors, " * C++ director class methods\n");
+ Printf(f_directors, " * --------------------------------------------------- */\n\n");
+ if (outfile_h)
+ Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h));
+ }
+
+ Printf(f_runtime, "\n");
+
+ Swig_name_register((char *) "wrapper", (char *) "CSharp_%f");
+ if (old_variable_names) {
+ Swig_name_register((char *) "set", (char *) "set_%v");
+ Swig_name_register((char *) "get", (char *) "get_%v");
+ }
+
+ Printf(f_wrappers, "\n#ifdef __cplusplus\n");
+ Printf(f_wrappers, "extern \"C\" {\n");
+ Printf(f_wrappers, "#endif\n\n");
+
+ /* Emit code */
+ Language::top(n);
+
+ if (directorsEnabled()) {
+ // Insert director runtime into the f_runtime file (make it occur before %header section)
+ Swig_insert_file("director.swg", f_runtime);
+ }
+ // Generate the intermediary class
+ {
+ String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), imclass_name);
+ File *f_im = NewFile(filen, "w", SWIG_output_files());
+ if (!f_im) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the intermediary class file
+ emitBanner(f_im);
+
+ addOpenNamespace(namespce, f_im);
+
+ if (imclass_imports)
+ Printf(f_im, "%s\n", imclass_imports);
+
+ if (Len(imclass_class_modifiers) > 0)
+ Printf(f_im, "%s ", imclass_class_modifiers);
+ Printf(f_im, "%s ", imclass_name);
+
+ if (imclass_baseclass && *Char(imclass_baseclass))
+ Printf(f_im, ": %s ", imclass_baseclass);
+ if (Len(imclass_interfaces) > 0)
+ Printv(f_im, "implements ", imclass_interfaces, " ", NIL);
+ Printf(f_im, "{\n");
+
+ // Add the intermediary class methods
+ Replaceall(imclass_class_code, "$module", module_class_name);
+ Replaceall(imclass_class_code, "$imclassname", imclass_name);
+ Replaceall(imclass_class_code, "$dllimport", dllimport);
+ Printv(f_im, imclass_class_code, NIL);
+ Printv(f_im, imclass_cppcasts_code, NIL);
+
+ // Finish off the class
+ Printf(f_im, "}\n");
+ addCloseNamespace(namespce, f_im);
+
+ Close(f_im);
+ }
+
+ // Generate the C# module class
+ {
+ String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), module_class_name);
+ File *f_module = NewFile(filen, "w", SWIG_output_files());
+ if (!f_module) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the module class file
+ emitBanner(f_module);
+
+ addOpenNamespace(namespce, f_module);
+
+ if (module_imports)
+ Printf(f_module, "%s\n", module_imports);
+
+ if (Len(module_class_modifiers) > 0)
+ Printf(f_module, "%s ", module_class_modifiers);
+ Printf(f_module, "%s ", module_class_name);
+
+ if (module_baseclass && *Char(module_baseclass))
+ Printf(f_module, ": %s ", module_baseclass);
+ if (Len(module_interfaces) > 0)
+ Printv(f_module, "implements ", module_interfaces, " ", NIL);
+ Printf(f_module, "{\n");
+
+ Replaceall(module_class_code, "$module", module_class_name);
+ Replaceall(module_class_constants_code, "$module", module_class_name);
+
+ Replaceall(module_class_code, "$imclassname", imclass_name);
+ Replaceall(module_class_constants_code, "$imclassname", imclass_name);
+
+ Replaceall(module_class_code, "$dllimport", dllimport);
+ Replaceall(module_class_constants_code, "$dllimport", dllimport);
+
+ // Add the wrapper methods
+ Printv(f_module, module_class_code, NIL);
+
+ // Write out all the global constants
+ Printv(f_module, module_class_constants_code, NIL);
+
+ // Finish off the class
+ Printf(f_module, "}\n");
+ addCloseNamespace(namespce, f_module);
+
+ Close(f_module);
+ }
+
+ if (upcasts_code)
+ Printv(f_wrappers, upcasts_code, NIL);
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n");
+ Printf(f_wrappers, "}\n");
+ Printf(f_wrappers, "#endif\n");
+
+ // Output a C# type wrapper class for each SWIG type
+ for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) {
+ emitTypeWrapperClass(swig_type.key, swig_type.item);
+ }
+
+ // Check for overwriting file problems on filesystems that are case insensitive
+ Iterator it1;
+ Iterator it2;
+ for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) {
+ String *item1_lower = Swig_string_lower(it1.item);
+ for (it2 = Next(it1); it2.item; it2 = Next(it2)) {
+ String *item2_lower = Swig_string_lower(it2.item);
+ if (it1.item && it2.item) {
+ if (Strcmp(item1_lower, item2_lower) == 0) {
+ Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number,
+ "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as "
+ "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item);
+ }
+ }
+ Delete(item2_lower);
+ }
+ Delete(item1_lower);
+ }
+
+ Delete(swig_types_hash);
+ swig_types_hash = NULL;
+ Delete(filenames_list);
+ filenames_list = NULL;
+ Delete(imclass_name);
+ imclass_name = NULL;
+ Delete(imclass_class_code);
+ imclass_class_code = NULL;
+ Delete(proxy_class_def);
+ proxy_class_def = NULL;
+ Delete(proxy_class_code);
+ proxy_class_code = NULL;
+ Delete(module_class_constants_code);
+ module_class_constants_code = NULL;
+ Delete(imclass_baseclass);
+ imclass_baseclass = NULL;
+ Delete(imclass_interfaces);
+ imclass_interfaces = NULL;
+ Delete(imclass_class_modifiers);
+ imclass_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(imclass_imports);
+ imclass_imports = NULL;
+ Delete(imclass_cppcasts_code);
+ imclass_cppcasts_code = NULL;
+ Delete(upcasts_code);
+ upcasts_code = NULL;
+ Delete(dmethods_seq);
+ dmethods_seq = NULL;
+ Delete(dmethods_table);
+ dmethods_table = NULL;
+ Delete(namespce);
+ namespce = NULL;
+ n_dmethods = 0;
+
+ /* Close all of the files */
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+
+ if (directorsEnabled()) {
+ Dump(f_directors, f_begin);
+ Dump(f_directors_h, f_runtime_h);
+
+ Printf(f_runtime_h, "\n");
+ Printf(f_runtime_h, "#endif\n");
+
+ Close(f_runtime_h);
+ Delete(f_runtime_h);
+ f_runtime_h = NULL;
+ Delete(f_directors);
+ f_directors = NULL;
+ Delete(f_directors_h);
+ f_directors_h = NULL;
+ }
+
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitBanner()
+ * ----------------------------------------------------------------------------- */
+
+ void emitBanner(File *f) {
+ Printf(f, "/* ----------------------------------------------------------------------------\n");
+ Swig_banner_target_lang(f, " *");
+ Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
+ }
+
+ /*-----------------------------------------------------------------------
+ * Add new director upcall signature
+ *----------------------------------------------------------------------*/
+
+ UpcallData *addUpcallMethod(String *imclass_method, String *class_method, String *decl, String *overloaded_name) {
+ UpcallData *udata;
+ String *imclass_methodidx;
+ String *class_methodidx;
+ Hash *new_udata;
+ String *key = NewStringf("%s|%s", imclass_method, decl);
+
+ ++curr_class_dmethod;
+
+ /* Do we know about this director class already? */
+ if ((udata = Getattr(dmethods_table, key))) {
+ Delete(key);
+ return Getattr(udata, "methodoff");
+ }
+
+ imclass_methodidx = NewStringf("%d", n_dmethods);
+ class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod);
+ n_dmethods++;
+
+ new_udata = NewHash();
+ Append(dmethods_seq, new_udata);
+ Setattr(dmethods_table, key, new_udata);
+
+ Setattr(new_udata, "method", Copy(class_method));
+ // TODO: remove fdesc
+// Setattr(new_udata, "fdesc", Copy(class_desc));
+// Setattr(new_udata, "imclass_method", Copy(imclass_method));
+// Setattr(new_udata, "imclass_methodidx", imclass_methodidx);
+ Setattr(new_udata, "class_methodidx", class_methodidx);
+ Setattr(new_udata, "decl", Copy(decl));
+ Setattr(new_udata, "overname", Copy(overloaded_name));
+
+ Delete(key);
+ return new_udata;
+ }
+
+ /*-----------------------------------------------------------------------
+ * Get director upcall signature
+ *----------------------------------------------------------------------*/
+
+ /*
+ UpcallData * getUpcallMethodData(String *director_class, String *decl) {
+ String *key = NewStringf("%s|%s", director_class, decl);
+ UpcallData *udata = Getattr(dmethods_table, key);
+
+ Delete(key);
+ return udata;
+ }
+ */
+
+ /* ----------------------------------------------------------------------
+ * nativeWrapper()
+ * ---------------------------------------------------------------------- */
+
+ virtual int nativeWrapper(Node *n) {
+ String *wrapname = Getattr(n, "wrap:name");
+
+ if (!addSymbol(wrapname, n))
+ return SWIG_ERROR;
+
+ if (Getattr(n, "type")) {
+ Swig_save("nativeWrapper", n, "name", NIL);
+ Setattr(n, "name", wrapname);
+ native_function_flag = true;
+ functionWrapper(n);
+ Swig_restore(n);
+ native_function_flag = false;
+ } else {
+ Printf(stderr, "%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n, "wrap:name"));
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * functionWrapper()
+ * ---------------------------------------------------------------------- */
+
+ virtual int functionWrapper(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *tm;
+ Parm *p;
+ int i;
+ String *c_return_type = NewString("");
+ String *im_return_type = NewString("");
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *body = NewString("");
+ String *im_outattributes = 0;
+ 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;
+ }
+
+ /*
+ The rest of this function deals with generating the intermediary class wrapper function (that wraps
+ a c/c++ function) and generating the PInvoke c code. Each C# wrapper function has a
+ matching PInvoke c function call.
+ */
+
+ // A new wrapper function object
+ Wrapper *f = NewWrapper();
+
+ // Make a wrapper name for this function
+ String *wname = Swig_name_wrapper(overloaded_name);
+
+ /* Attach the non-standard typemaps to the parameter list. */
+ Swig_typemap_attach_parms("ctype", l, f);
+ Swig_typemap_attach_parms("imtype", l, f);
+
+ /* Get return types */
+ if ((tm = Swig_typemap_lookup("ctype", n, "", 0))) {
+ String *ctypeout = Getattr(n, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap
+ if (ctypeout)
+ tm = ctypeout;
+ Printf(c_return_type, "%s", tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ if ((tm = Swig_typemap_lookup("imtype", n, "", 0))) {
+ String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
+ if (imtypeout)
+ tm = imtypeout;
+ Printf(im_return_type, "%s", tm);
+ im_outattributes = Getattr(n, "tmap:imtype:outattributes");
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ is_void_return = (Cmp(c_return_type, "void") == 0);
+ if (!is_void_return)
+ Wrapper_add_localv(f, "jresult", c_return_type, "jresult", NIL);
+
+ Printv(f->def, " SWIGEXPORT ", c_return_type, " SWIGSTDCALL ", wname, "(", NIL);
+
+ // Emit all of the local variables for holding arguments.
+ emit_parameter_variables(l, f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l, f);
+
+ // Parameter overloading
+ Setattr(n, "wrap:parms", l);
+ Setattr(n, "wrap:name", wname);
+
+ // Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
+ if (Getattr(n, "sym:overloaded")) {
+ // Emit warnings for the few cases that can't be overloaded in C# and give up on generating wrapper
+ Swig_overload_check(n);
+ if (Getattr(n, "overload:ignore"))
+ return SWIG_OK;
+ }
+
+ Printv(imclass_class_code, "\n [DllImport(\"", dllimport, "\", EntryPoint=\"CSharp_", overloaded_name, "\")]\n", NIL);
+
+ if (im_outattributes)
+ Printf(imclass_class_code, " %s\n", im_outattributes);
+
+ Printf(imclass_class_code, " public static extern %s %s(", im_return_type, overloaded_name);
+
+
+ /* 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 *im_param_type = NewString("");
+ String *c_param_type = NewString("");
+ String *arg = NewString("");
+
+ Printf(arg, "j%s", ln);
+
+ /* Get the ctype types of the parameter */
+ if ((tm = Getattr(p, "tmap:ctype"))) {
+ Printv(c_param_type, tm, NIL);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ /* Get the intermediary class parameter types of the parameter */
+ if ((tm = Getattr(p, "tmap:imtype"))) {
+ const String *inattributes = Getattr(p, "tmap:imtype:inattributes");
+ Printf(im_param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ /* Add parameter to intermediary class method */
+ if (gencomma)
+ Printf(imclass_class_code, ", ");
+ Printf(imclass_class_code, "%s %s", im_param_type, arg);
+
+ // Add parameter to C function
+ Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL);
+
+ gencomma = 1;
+
+ // Get typemap for this argument
+ if ((tm = Getattr(p, "tmap:in"))) {
+ canThrow(n, "in", p);
+ Replaceall(tm, "$source", arg); /* deprecated */
+ Replaceall(tm, "$target", ln); /* deprecated */
+ Replaceall(tm, "$arg", arg); /* deprecated? */
+ Replaceall(tm, "$input", arg);
+ Setattr(p, "emit:input", arg);
+ Printf(f->code, "%s\n", tm);
+ p = Getattr(p, "tmap:in:next");
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
+ p = nextSibling(p);
+ }
+ Delete(im_param_type);
+ Delete(c_param_type);
+ Delete(arg);
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ canThrow(n, "check", p);
+ Replaceall(tm, "$target", Getattr(p, "lname")); /* deprecated */
+ Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:freearg"))) {
+ canThrow(n, "freearg", p);
+ Replaceall(tm, "$source", Getattr(p, "emit:input")); /* deprecated */
+ Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(cleanup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+ canThrow(n, "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);
+ }
+ }
+
+ // Look for usage of throws typemap and the canthrow flag
+ ParmList *throw_parm_list = NULL;
+ if ((throw_parm_list = Getattr(n, "catchlist"))) {
+ Swig_typemap_attach_parms("throws", throw_parm_list, f);
+ for (p = throw_parm_list; p; p = nextSibling(p)) {
+ if ((tm = Getattr(p, "tmap:throws"))) {
+ canThrow(n, "throws", p);
+ }
+ }
+ }
+
+ String *null_attribute = 0;
+ // Now write code to make the function call
+ if (!native_function_flag) {
+ if (Cmp(nodeType(n), "constant") == 0) {
+ // Wrapping a constant hack
+ Swig_save("functionWrapper", n, "wrap:action", NIL);
+
+ // below based on Swig_VargetToFunction()
+ SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n));
+ Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value")));
+ }
+
+ Swig_director_emit_dynamic_cast(n, f);
+ String *actioncode = emit_action(n);
+
+ if (Cmp(nodeType(n), "constant") == 0)
+ Swig_restore(n);
+
+ /* Return value if necessary */
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ canThrow(n, "out", n);
+ Replaceall(tm, "$source", "result"); /* deprecated */
+ Replaceall(tm, "$target", "jresult"); /* deprecated */
+ Replaceall(tm, "$result", "jresult");
+
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "1");
+ else
+ Replaceall(tm, "$owner", "0");
+
+ Printf(f->code, "%s", tm);
+ null_attribute = Getattr(n, "tmap:out:null");
+ if (Len(tm))
+ Printf(f->code, "\n");
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name"));
+ }
+ emit_return_variable(n, t, f);
+ }
+
+ /* 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 (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
+ canThrow(n, "newfree", n);
+ Replaceall(tm, "$source", "result"); /* deprecated */
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ /* See if there is any return cleanup code */
+ if (!native_function_flag) {
+ if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
+ canThrow(n, "ret", n);
+ Replaceall(tm, "$source", "result"); /* deprecated */
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ /* Finish C function and intermediary class function definitions */
+ Printf(imclass_class_code, ")");
+ Printf(imclass_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);
+
+ /* Substitute the function name */
+ Replaceall(f->code, "$symname", symname);
+
+ /* Contract macro modification */
+ if (Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ") > 0) {
+ Setattr(n, "csharp:canthrow", "1");
+ }
+
+ if (!null_attribute)
+ Replaceall(f->code, "$null", "0");
+ else
+ Replaceall(f->code, "$null", null_attribute);
+
+ /* Dump the function out */
+ if (!native_function_flag) {
+ Wrapper_print(f, f_wrappers);
+
+ // Handle %csexception which sets the canthrow attribute
+ if (Getattr(n, "feature:except:canthrow"))
+ Setattr(n, "csharp:canthrow", "1");
+
+ // A very simple check (it is not foolproof) to help typemap/feature writers for
+ // throwing C# exceptions from unmanaged code. It checks for the common methods which
+ // set a pending C# exception... the 'canthrow' typemap/feature attribute must be set
+ // so that code which checks for pending exceptions is added in the C# proxy method.
+ if (!Getattr(n, "csharp:canthrow")) {
+ if (Strstr(f->code, "SWIG_exception")) {
+ Swig_warning(WARN_CSHARP_CANTHROW, input_file, line_number,
+ "Unmanaged code contains a call to SWIG_exception and C# code does not handle pending exceptions via the canthrow attribute.\n");
+ } else if (Strstr(f->code, "SWIG_CSharpSetPendingException")) {
+ Swig_warning(WARN_CSHARP_CANTHROW, input_file, line_number,
+ "Unmanaged code contains a call to a SWIG_CSharpSetPendingException method and C# code does not handle pending exceptions via the canthrow attribute.\n");
+ }
+ }
+ }
+
+ if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
+ moduleClassFunctionHandler(n);
+ }
+
+ /*
+ * Generate the proxy class properties for public member variables.
+ * Not for enums and constants.
+ */
+ if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
+ // Capitalize the first letter in the variable in the getter/setter function name
+ bool getter_flag = Cmp(symname, Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) != 0;
+
+ String *getter_setter_name = NewString("");
+ if (!getter_flag)
+ 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, "proxyfuncname", getter_setter_name);
+ Setattr(n, "imfuncname", symname);
+
+ proxyClassFunctionHandler(n);
+ Delete(getter_setter_name);
+ }
+
+ Delete(c_return_type);
+ Delete(im_return_type);
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(body);
+ Delete(overloaded_name);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * variableWrapper()
+ * ----------------------------------------------------------------------- */
+
+ virtual int variableWrapper(Node *n) {
+ Language::variableWrapper(n);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * globalvariableHandler()
+ * ------------------------------------------------------------------------ */
+
+ virtual int globalvariableHandler(Node *n) {
+
+ generate_property_declaration_flag = true;
+ variable_name = Getattr(n, "sym:name");
+ global_variable_flag = true;
+ int ret = Language::globalvariableHandler(n);
+ global_variable_flag = false;
+ generate_property_declaration_flag = false;
+
+ if (proxy_flag) {
+ Printf(module_class_code, "\n }\n\n");
+ }
+
+ return ret;
+ }
+
+ /* ----------------------------------------------------------------------
+ * enumDeclaration()
+ *
+ * C/C++ enums can be mapped in one of 4 ways, depending on the cs:enum feature specified:
+ * 1) Simple enums - simple constant within the proxy class or module class
+ * 2) Typeunsafe enums - simple constant in a C# class (class named after the c++ enum name)
+ * 3) Typesafe enum - typesafe enum pattern (class named after the c++ enum name)
+ * 4) Proper enums - proper C# enum
+ * Anonymous enums always default to 1)
+ * ---------------------------------------------------------------------- */
+
+ virtual int enumDeclaration(Node *n) {
+
+ if (!ImportMode) {
+ if (getCurrentClass() && (cplus_mode != PUBLIC))
+ return SWIG_NOWRAP;
+
+ enum_code = NewString("");
+ String *symname = Getattr(n, "sym:name");
+ String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code;
+ EnumFeature enum_feature = decodeEnumFeature(n);
+ String *typemap_lookup_type = Getattr(n, "name");
+
+ if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
+ // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
+
+ // Pure C# baseclass and interfaces
+ const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE);
+ const String *pure_interfaces = typemapLookup(n, "csinterfaces", typemap_lookup_type, WARN_NONE);
+
+ // Class attributes
+ const String *csattributes = typemapLookup(n, "csattributes", typemap_lookup_type, WARN_NONE);
+ if (csattributes && *Char(csattributes))
+ Printf(enum_code, "%s\n", csattributes);
+
+ // Emit the enum
+ Printv(enum_code, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers (enum modifiers really)
+ " ", symname, (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces
+ ", " : "", pure_interfaces, " {\n", NIL);
+ } else {
+ // Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
+ if (symname && !Getattr(n, "unnamedinstance"))
+ Printf(constants_code, " // %s \n", symname);
+ }
+
+ // Emit each enum item
+ Language::enumDeclaration(n);
+
+ if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
+ // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
+ // Finish the enum declaration
+ // Typemaps are used to generate the enum definition in a similar manner to proxy classes.
+ Printv(enum_code, (enum_feature == ProperEnum) ? "\n" : typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
+ typemapLookup(n, "cscode", typemap_lookup_type, WARN_NONE), // extra C# code
+ "}", NIL);
+
+ Replaceall(enum_code, "$csclassname", symname);
+
+ // Substitute $enumvalues - intended usage is for typesafe enums
+ if (Getattr(n, "enumvalues"))
+ Replaceall(enum_code, "$enumvalues", Getattr(n, "enumvalues"));
+ else
+ Replaceall(enum_code, "$enumvalues", "");
+
+ if (proxy_flag && is_wrapping_class()) {
+ // Enums defined within the C++ class are defined within the proxy class
+
+ // Add extra indentation
+ Replaceall(enum_code, "\n", "\n ");
+ Replaceall(enum_code, " \n", "\n");
+
+ Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL);
+ } else {
+ // Global enums are defined in their own file
+ String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), symname);
+ File *f_enum = NewFile(filen, "w", SWIG_output_files());
+ if (!f_enum) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the enum file
+ emitBanner(f_enum);
+
+ addOpenNamespace(namespce, f_enum);
+
+ Printv(f_enum, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
+ "\n", enum_code, "\n", NIL);
+
+ addCloseNamespace(namespce, f_enum);
+
+ Close(f_enum);
+ }
+ } else {
+ // Wrap C++ enum with simple constant
+ Printf(enum_code, "\n");
+ if (proxy_flag && is_wrapping_class())
+ Printv(proxy_class_constants_code, enum_code, NIL);
+ else
+ Printv(module_class_constants_code, enum_code, NIL);
+ }
+
+ Delete(enum_code);
+ enum_code = NULL;
+ }
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * enumvalueDeclaration()
+ * ---------------------------------------------------------------------- */
+
+ virtual int enumvalueDeclaration(Node *n) {
+ if (getCurrentClass() && (cplus_mode != PUBLIC))
+ return SWIG_NOWRAP;
+
+ Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
+ String *symname = Getattr(n, "sym:name");
+ String *value = Getattr(n, "value");
+ String *name = Getattr(n, "name");
+ String *tmpValue;
+
+ // Strange hack from parent method
+ if (value)
+ tmpValue = NewString(value);
+ else
+ tmpValue = NewString(name);
+ // Note that this is used in enumValue() amongst other places
+ Setattr(n, "value", tmpValue);
+
+ {
+ EnumFeature enum_feature = decodeEnumFeature(parentNode(n));
+
+ if ((enum_feature == ProperEnum) && Getattr(parentNode(n), "sym:name") && !Getattr(parentNode(n), "unnamedinstance")) {
+ // Wrap (non-anonymous) C/C++ enum with a proper C# enum
+ // Emit the enum item.
+ if (!GetFlag(n, "firstenumitem"))
+ Printf(enum_code, ",\n");
+ Printf(enum_code, " %s", symname);
+
+ // Check for the %csconstvalue feature
+ String *value = Getattr(n, "feature:cs:constvalue");
+
+ // Note that the enum value must be a true constant and cannot be set from a PINVOKE call, thus no support for %csconst(0)
+ value = value ? value : Getattr(n, "enumvalue");
+ if (value) {
+ Printf(enum_code, " = %s", value);
+ }
+ } else {
+ // Wrap C/C++ enums with constant integers or use the typesafe enum pattern
+ const String *parent_name = Getattr(parentNode(n), "name");
+ String *typemap_lookup_type = parent_name ? Copy(parent_name) : NewString("int");
+ const String *tm = typemapLookup(n, "cstype", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF);
+ String *return_type = Copy(tm);
+ Delete(typemap_lookup_type);
+ typemap_lookup_type = NULL;
+
+ // The %csconst feature determines how the constant value is obtained
+ int const_feature_flag = GetFlag(n, "feature:cs:const");
+
+ const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
+ methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
+
+ if ((enum_feature == TypesafeEnum) && Getattr(parentNode(n), "sym:name") && !Getattr(parentNode(n), "unnamedinstance")) {
+ // Wrap (non-anonymouse) enum using the typesafe enum pattern
+ if (Getattr(n, "enumvalue")) {
+ String *value = enumValue(n);
+ Printf(enum_code, " %s static readonly %s %s = new %s(\"%s\", %s);\n", methodmods, return_type, symname, return_type, symname, value);
+ Delete(value);
+ } else {
+ Printf(enum_code, " %s static readonly %s %s = new %s(\"%s\");\n", methodmods, return_type, symname, return_type, symname);
+ }
+ } else {
+ // Simple integer constants
+ // Note these are always generated for anonymous enums, no matter what enum_feature is specified
+ // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
+ const char *const_readonly = const_feature_flag ? "const" : "static readonly";
+ String *value = enumValue(n);
+ Printf(enum_code, " %s %s %s %s = %s;\n", methodmods, const_readonly, return_type, symname, value);
+ Delete(value);
+ }
+ }
+
+ // Add the enum value to the comma separated list being constructed in the enum declaration.
+ String *enumvalues = Getattr(parentNode(n), "enumvalues");
+ if (!enumvalues)
+ Setattr(parentNode(n), "enumvalues", Copy(symname));
+ else
+ Printv(enumvalues, ", ", symname, NIL);
+ }
+
+ Delete(tmpValue);
+ Swig_restore(n);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * constantWrapper()
+ * Used for wrapping constants - #define or %constant.
+ * Also for inline initialised const static primitive type member variables (short, int, double, enums etc).
+ * C# static const variables are generated for these.
+ * If the %csconst(1) feature is used then the C constant value is used to initialise the C# const variable.
+ * If not, a PINVOKE method is generated to get the C constant value for initialisation of the C# const variable.
+ * However, if the %csconstvalue feature is used, it overrides all other ways to generate the initialisation.
+ * Also note that this method might be called for wrapping enum items (when the enum is using %csconst(0)).
+ * ------------------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *tm;
+ String *return_type = NewString("");
+ String *constants_code = NewString("");
+
+ if (!addSymbol(symname, n))
+ return SWIG_ERROR;
+
+ bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
+
+ // The %csconst feature determines how the constant value is obtained
+ int const_feature_flag = GetFlag(n, "feature:cs:const");
+
+ /* Adjust the enum type for the Swig_typemap_lookup.
+ * We want the same jstype typemap for all the enum items so we use the enum type (parent node). */
+ if (is_enum_item) {
+ t = Getattr(parentNode(n), "enumtype");
+ Setattr(n, "type", t);
+ }
+
+ /* Attach the non-standard typemaps to the parameter list. */
+ Swig_typemap_attach_parms("cstype", l, NULL);
+
+ /* Get C# return types */
+ bool classname_substituted_flag = false;
+
+ if ((tm = Swig_typemap_lookup("cstype", n, "", 0))) {
+ String *cstypeout = Getattr(n, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
+ if (cstypeout)
+ tm = cstypeout;
+ classname_substituted_flag = substituteClassname(t, tm);
+ Printf(return_type, "%s", tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ // Add the stripped quotes back in
+ String *new_value = NewString("");
+ Swig_save("constantWrapper", 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);
+ }
+
+ const String *outattributes = Getattr(n, "tmap:cstype:outattributes");
+ if (outattributes)
+ Printf(constants_code, " %s\n", outattributes);
+ const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname;
+
+ const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
+ methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
+
+ Printf(constants_code, " %s %s %s %s = ", methodmods, (const_feature_flag ? "const" : "static readonly"), return_type, itemname);
+
+ // Check for the %csconstvalue feature
+ String *value = Getattr(n, "feature:cs:constvalue");
+
+ if (value) {
+ Printf(constants_code, "%s;\n", value);
+ } else if (!const_feature_flag) {
+ // Default enum and constant handling will work with any type of C constant and initialises the C# variable from C through a PINVOKE call.
+
+ if (classname_substituted_flag) {
+ if (SwigType_isenum(t)) {
+ // This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
+ Printf(constants_code, "(%s)%s.%s();\n", return_type, imclass_name, Swig_name_get(symname));
+ } else {
+ // This handles function pointers using the %constant directive
+ Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, imclass_name, Swig_name_get(symname));
+ }
+ } else
+ Printf(constants_code, "%s.%s();\n", imclass_name, Swig_name_get(symname));
+
+ // Each constant and enum value is wrapped with a separate PInvoke function call
+ SetFlag(n, "feature:immutable");
+ enum_constant_flag = true;
+ variableWrapper(n);
+ enum_constant_flag = false;
+ } else {
+ // Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code
+ Printf(constants_code, "%s;\n", Getattr(n, "value"));
+ }
+
+ // Emit the generated code to appropriate place
+ // Enums only emit the intermediate and PINVOKE methods, so no proxy or module class wrapper methods needed
+ if (!is_enum_item) {
+ if (proxy_flag && wrapping_member_flag)
+ Printv(proxy_class_constants_code, constants_code, NIL);
+ else
+ Printv(module_class_constants_code, constants_code, NIL);
+ }
+ // Cleanup
+ Swig_restore(n);
+ Delete(new_value);
+ Delete(return_type);
+ Delete(constants_code);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * insertDirective()
+ * ----------------------------------------------------------------------------- */
+
+ virtual int insertDirective(Node *n) {
+ String *code = Getattr(n, "code");
+ Replaceall(code, "$module", module_class_name);
+ Replaceall(code, "$imclassname", imclass_name);
+ Replaceall(code, "$dllimport", dllimport);
+ return Language::insertDirective(n);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * pragmaDirective()
+ *
+ * Valid Pragmas:
+ * imclassbase - base (extends) for the intermediary class
+ * imclassclassmodifiers - class modifiers for the intermediary class
+ * imclasscode - text (C# code) is copied verbatim to the intermediary class
+ * imclassimports - import statements for the intermediary class
+ * imclassinterfaces - interface (implements) for the intermediary class
+ *
+ * modulebase - base (extends) for the module class
+ * moduleclassmodifiers - class modifiers for the module class
+ * modulecode - text (C# 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, "csharp") == 0) {
+
+ String *strvalue = NewString(value);
+ Replaceall(strvalue, "\\\"", "\"");
+
+ if (Strcmp(code, "imclassbase") == 0) {
+ Delete(imclass_baseclass);
+ imclass_baseclass = Copy(strvalue);
+ } else if (Strcmp(code, "imclassclassmodifiers") == 0) {
+ Delete(imclass_class_modifiers);
+ imclass_class_modifiers = Copy(strvalue);
+ } else if (Strcmp(code, "imclasscode") == 0) {
+ Printf(imclass_class_code, "%s\n", strvalue);
+ } else if (Strcmp(code, "imclassimports") == 0) {
+ Delete(imclass_imports);
+ imclass_imports = Copy(strvalue);
+ } else if (Strcmp(code, "imclassinterfaces") == 0) {
+ Delete(imclass_interfaces);
+ imclass_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 {
+ Printf(stderr, "%s : Line %d. Unrecognized pragma.\n", input_file, line_number);
+ }
+ Delete(strvalue);
+ }
+ }
+ return Language::pragmaDirective(n);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitProxyClassDefAndCPPCasts()
+ * ----------------------------------------------------------------------------- */
+
+ void emitProxyClassDefAndCPPCasts(Node *n) {
+ String *c_classname = SwigType_namestr(Getattr(n, "name"));
+ String *c_baseclass = NULL;
+ String *baseclass = NULL;
+ String *c_baseclassname = NULL;
+ SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
+ bool feature_director = Swig_directorclass(n) ? true : false;
+
+ // Inheritance from pure C# classes
+ Node *attributes = NewHash();
+ const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE, attributes);
+ bool purebase_replace = GetFlag(attributes, "tmap:csbase:replace") ? true : false;
+ bool purebase_notderived = GetFlag(attributes, "tmap:csbase:notderived") ? true : false;
+ Delete(attributes);
+
+ // C++ inheritance
+ if (!purebase_replace) {
+ List *baselist = Getattr(n, "bases");
+ if (baselist) {
+ Iterator base = First(baselist);
+ while (base.item && GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ }
+ if (base.item) {
+ c_baseclassname = Getattr(base.item, "name");
+ baseclass = Copy(getProxyName(c_baseclassname));
+ if (baseclass)
+ c_baseclass = SwigType_namestr(Getattr(base.item, "name"));
+ base = Next(base);
+ /* Warn about multiple inheritance for additional base class(es) */
+ while (base.item) {
+ if (GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ continue;
+ }
+ String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
+ String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
+ Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number,
+ "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", proxyclassname, baseclassname);
+ base = Next(base);
+ }
+ }
+ }
+ }
+
+ bool derived = baseclass && getProxyName(c_baseclassname);
+ if (derived && purebase_notderived)
+ pure_baseclass = empty_string;
+ const String *wanted_base = baseclass ? baseclass : pure_baseclass;
+
+ if (purebase_replace) {
+ wanted_base = pure_baseclass;
+ derived = false;
+ Delete(baseclass);
+ baseclass = NULL;
+ if (purebase_notderived)
+ Swig_error(input_file, line_number, "The csbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
+ } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
+ Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number,
+ "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#. "
+ "Perhaps you need one of the 'replace' or 'notderived' attributes in the csbase typemap?\n", typemap_lookup_type, pure_baseclass);
+ }
+
+ // Pure C# interfaces
+ const String *pure_interfaces = typemapLookup(n, derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE);
+ // Start writing the proxy class
+ Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
+ "\n", NIL);
+
+ // Class attributes
+ const String *csattributes = typemapLookup(n, "csattributes", typemap_lookup_type, WARN_NONE);
+ if (csattributes && *Char(csattributes))
+ Printf(proxy_class_def, "%s\n", csattributes);
+
+ Printv(proxy_class_def, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
+ " $csclassname", // Class name and base class
+ (*Char(wanted_base) || *Char(pure_interfaces)) ? " : " : "", wanted_base, (*Char(wanted_base) && *Char(pure_interfaces)) ? // Interfaces
+ ", " : "", pure_interfaces, " {", derived ? typemapLookup(n, "csbody_derived", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF) : // main body of class
+ typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
+ NIL);
+
+ // C++ destructor is wrapped by the Dispose method
+ // Note that the method name is specified in a typemap attribute called methodname
+ String *destruct = NewString("");
+ const String *tm = NULL;
+ attributes = NewHash();
+ String *destruct_methodname = NULL;
+ String *destruct_methodmodifiers = NULL;
+ if (derived) {
+ tm = typemapLookup(n, "csdestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
+ destruct_methodname = Getattr(attributes, "tmap:csdestruct_derived:methodname");
+ destruct_methodmodifiers = Getattr(attributes, "tmap:csdestruct_derived:methodmodifiers");
+ } else {
+ tm = typemapLookup(n, "csdestruct", typemap_lookup_type, WARN_NONE, attributes);
+ destruct_methodname = Getattr(attributes, "tmap:csdestruct:methodname");
+ destruct_methodmodifiers = Getattr(attributes, "tmap:csdestruct:methodmodifiers");
+ }
+ if (tm && *Char(tm)) {
+ if (!destruct_methodname) {
+ Swig_error(input_file, line_number, "No methodname attribute defined in csdestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
+ }
+ if (!destruct_methodmodifiers) {
+ Swig_error(input_file, line_number,
+ "No methodmodifiers attribute defined in csdestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name);
+ }
+ }
+ // Emit the Finalize and Dispose methods
+ if (tm) {
+ // Finalize method
+ if (*Char(destructor_call)) {
+ Printv(proxy_class_def, typemapLookup(n, "csfinalize", typemap_lookup_type, WARN_NONE), NIL);
+ }
+ // Dispose method
+ Printv(destruct, tm, NIL);
+ if (*Char(destructor_call))
+ Replaceall(destruct, "$imcall", destructor_call);
+ else
+ Replaceall(destruct, "$imcall", "throw new MethodAccessException(\"C++ destructor does not have public access\")");
+ if (*Char(destruct))
+ Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n",
+ NIL);
+ }
+
+ if (feature_director) {
+ // Generate director connect method
+ // put this in classDirectorEnd ???
+ Printf(proxy_class_code, " private void SwigDirectorConnect() {\n");
+
+ int i;
+ for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
+ UpcallData *udata = Getitem(dmethods_seq, i);
+ String *method = Getattr(udata, "method");
+ String *methid = Getattr(udata, "class_methodidx");
+ String *overname = Getattr(udata, "overname");
+ Printf(proxy_class_code, " if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s))\n", method, methid);
+ Printf(proxy_class_code, " swigDelegate%s = new SwigDelegate%s_%s(SwigDirector%s);\n", methid, proxy_class_name, methid, overname);
+ }
+ Printf(proxy_class_code, " %s.%s_director_connect(swigCPtr", imclass_name, proxy_class_name);
+ for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
+ UpcallData *udata = Getitem(dmethods_seq, i);
+ String *methid = Getattr(udata, "class_methodidx");
+ Printf(proxy_class_code, ", swigDelegate%s", methid);
+ }
+ Printf(proxy_class_code, ");\n");
+ Printf(proxy_class_code, " }\n");
+
+ if (first_class_dmethod < curr_class_dmethod) {
+ // Only emit if there is at least one director method
+ Printf(proxy_class_code, "\n");
+ Printf(proxy_class_code, " private bool SwigDerivedClassHasMethod(string methodName, Type[] methodTypes) {\n");
+ Printf(proxy_class_code,
+ " System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, methodTypes, null);\n");
+ Printf(proxy_class_code, " bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(%s));\n", proxy_class_name);
+ /* Could add this code to cover corner case where the GetMethod() returns a method which allows type
+ * promotion, eg it will return foo(double), if looking for foo(int).
+ if (hasDerivedMethod) {
+ hasDerivedMethod = false;
+ if (methodInfo != null)
+ {
+ hasDerivedMethod = true;
+ ParameterInfo[] parameterArray1 = methodInfo.GetParameters();
+ for (int i=0; i<methodTypes.Length; i++)
+ {
+ if (parameterArray1[0].ParameterType != methodTypes[0])
+ {
+ hasDerivedMethod = false;
+ break;
+ }
+ }
+ }
+ }
+ */
+ Printf(proxy_class_code, " return hasDerivedMethod;\n");
+ Printf(proxy_class_code, " }\n");
+ }
+
+ if (Len(director_delegate_callback) > 0)
+ Printv(proxy_class_code, director_delegate_callback, NIL);
+ if (Len(director_delegate_definitions) > 0)
+ Printv(proxy_class_code, "\n", director_delegate_definitions, NIL);
+ if (Len(director_delegate_instances) > 0)
+ Printv(proxy_class_code, "\n", director_delegate_instances, NIL);
+ if (Len(director_method_types) > 0)
+ Printv(proxy_class_code, "\n", director_method_types, NIL);
+
+ Delete(director_callback_typedefs);
+ director_callback_typedefs = NULL;
+ Delete(director_callbacks);
+ director_callbacks = NULL;
+ Delete(director_delegate_callback);
+ director_delegate_callback = NULL;
+ Delete(director_delegate_definitions);
+ director_delegate_definitions = NULL;
+ Delete(director_delegate_instances);
+ director_delegate_instances = NULL;
+ Delete(director_method_types);
+ director_method_types = NULL;
+ Delete(director_connect_parms);
+ director_connect_parms = NULL;
+ }
+
+ Delete(attributes);
+ Delete(destruct);
+
+ // Emit extra user code
+ Printv(proxy_class_def, typemapLookup(n, "cscode", typemap_lookup_type, WARN_NONE), // extra C# code
+ "\n", NIL);
+
+ // Substitute various strings into the above template
+ Replaceall(proxy_class_code, "$csclassname", proxy_class_name);
+ Replaceall(proxy_class_def, "$csclassname", proxy_class_name);
+
+ Replaceall(proxy_class_def, "$module", module_class_name);
+ Replaceall(proxy_class_code, "$module", module_class_name);
+
+ Replaceall(proxy_class_def, "$imclassname", imclass_name);
+ Replaceall(proxy_class_code, "$imclassname", imclass_name);
+
+ Replaceall(proxy_class_def, "$dllimport", dllimport);
+ Replaceall(proxy_class_code, "$dllimport", dllimport);
+
+ // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
+ if (derived) {
+ Printv(imclass_cppcasts_code, "\n [DllImport(\"", dllimport, "\", EntryPoint=\"CSharp_", proxy_class_name, "Upcast", "\")]\n", NIL);
+ Printf(imclass_cppcasts_code, " public static extern IntPtr $csclassnameUpcast(IntPtr objectRef);\n");
+
+ Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
+
+ Printv(upcasts_code,
+ "SWIGEXPORT $cbaseclass * SWIGSTDCALL CSharp_$imclazznameUpcast",
+ "($cclass *objectRef) {\n", " return ($cbaseclass *)objectRef;\n" "}\n", "\n", NIL);
+
+ Replaceall(upcasts_code, "$cbaseclass", c_baseclass);
+ Replaceall(upcasts_code, "$imclazzname", proxy_class_name);
+ Replaceall(upcasts_code, "$cclass", c_classname);
+ }
+ Delete(baseclass);
+ }
+
+ /* ----------------------------------------------------------------------
+ * classHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int classHandler(Node *n) {
+
+ File *f_proxy = NULL;
+ if (proxy_flag) {
+ proxy_class_name = NewString(Getattr(n, "sym:name"));
+
+ if (!addSymbol(proxy_class_name, n))
+ return SWIG_ERROR;
+
+ if (Cmp(proxy_class_name, imclass_name) == 0) {
+ Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ if (Cmp(proxy_class_name, module_class_name) == 0) {
+ Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), proxy_class_name);
+ f_proxy = NewFile(filen, "w", SWIG_output_files());
+ if (!f_proxy) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the proxy class file
+ emitBanner(f_proxy);
+
+ addOpenNamespace(namespce, f_proxy);
+
+ Clear(proxy_class_def);
+ Clear(proxy_class_code);
+
+ destructor_call = NewString("");
+ proxy_class_constants_code = NewString("");
+ }
+
+ Language::classHandler(n);
+
+ if (proxy_flag) {
+
+ emitProxyClassDefAndCPPCasts(n);
+
+ Replaceall(proxy_class_def, "$module", module_class_name);
+ Replaceall(proxy_class_code, "$module", module_class_name);
+ Replaceall(proxy_class_constants_code, "$module", module_class_name);
+ Replaceall(proxy_class_def, "$imclassname", imclass_name);
+ Replaceall(proxy_class_code, "$imclassname", imclass_name);
+ Replaceall(proxy_class_constants_code, "$imclassname", imclass_name);
+ Replaceall(proxy_class_def, "$dllimport", dllimport);
+ Replaceall(proxy_class_code, "$dllimport", dllimport);
+ Replaceall(proxy_class_constants_code, "$dllimport", dllimport);
+
+ Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
+
+ // Write out all the constants
+ if (Len(proxy_class_constants_code) != 0)
+ Printv(f_proxy, proxy_class_constants_code, NIL);
+
+ Printf(f_proxy, "}\n");
+ addCloseNamespace(namespce, f_proxy);
+ Close(f_proxy);
+ f_proxy = NULL;
+
+ /* Output the downcast method, if necessary. Note: There's no other really
+ good place to put this code, since Abstract Base Classes (ABCs) can and should have
+ downcasts, making the constructorHandler() a bad place (because ABCs don't get to
+ have constructors emitted.) */
+ if (GetFlag(n, "feature:javadowncast")) {
+ String *norm_name = SwigType_namestr(Getattr(n, "name"));
+
+ Printf(imclass_class_code, " public final static native %s downcast%s(long cPtrBase, boolean cMemoryOwn);\n", proxy_class_name, proxy_class_name);
+
+ Wrapper *dcast_wrap = NewWrapper();
+
+ Printf(dcast_wrap->def, "SWIGEXPORT jobject SWIGSTDCALL CSharp_downcast%s(JNIEnv *jenv, jclass jcls, jlong jCPtrBase, jboolean cMemoryOwn) {",
+ proxy_class_name);
+ Printf(dcast_wrap->code, " Swig::Director *director = (Swig::Director *) 0;\n");
+ Printf(dcast_wrap->code, " jobject jresult = (jobject) 0;\n");
+ Printf(dcast_wrap->code, " %s *obj = *((%s **)&jCPtrBase);\n", norm_name, norm_name);
+ Printf(dcast_wrap->code, " if (obj) director = dynamic_cast<Swig::Director *>(obj);\n");
+ Printf(dcast_wrap->code, " if (director) jresult = director->swig_get_self(jenv);\n");
+ Printf(dcast_wrap->code, " return jresult;\n");
+ Printf(dcast_wrap->code, "}\n");
+
+ Wrapper_print(dcast_wrap, f_wrappers);
+ DelWrapper(dcast_wrap);
+ }
+
+ emitDirectorExtraMethods(n);
+
+ Delete(proxy_class_name);
+ proxy_class_name = NULL;
+ Delete(destructor_call);
+ destructor_call = NULL;
+ Delete(proxy_class_constants_code);
+ proxy_class_constants_code = NULL;
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int memberfunctionHandler(Node *n) {
+ Language::memberfunctionHandler(n);
+
+ if (proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
+ Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
+ Setattr(n, "imfuncname", intermediary_function_name);
+ proxyClassFunctionHandler(n);
+ Delete(overloaded_name);
+ }
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+
+ static_flag = true;
+ Language::staticmemberfunctionHandler(n);
+
+ if (proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
+ Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
+ Setattr(n, "imfuncname", intermediary_function_name);
+ proxyClassFunctionHandler(n);
+ Delete(overloaded_name);
+ }
+ static_flag = false;
+
+ return SWIG_OK;
+ }
+
+
+ /* -----------------------------------------------------------------------------
+ * proxyClassFunctionHandler()
+ *
+ * Function called for creating a C# wrapper function around a c++ function in the
+ * proxy class. Used for both static and non-static C++ class functions.
+ * C++ class static functions map to C# static functions.
+ * Two extra attributes in the Node must be available. These are "proxyfuncname" -
+ * the name of the C# class proxy function, which in turn will call "imfuncname" -
+ * the intermediary (PInvoke) function name in the intermediary class.
+ * ----------------------------------------------------------------------------- */
+
+ void proxyClassFunctionHandler(Node *n) {
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *intermediary_function_name = Getattr(n, "imfuncname");
+ String *proxy_function_name = Getattr(n, "proxyfuncname");
+ String *tm;
+ Parm *p;
+ Parm *last_parm = 0;
+ int i;
+ String *imcall = NewString("");
+ String *return_type = NewString("");
+ String *function_code = NewString("");
+ bool setter_flag = false;
+ String *pre_code = NewString("");
+ String *post_code = NewString("");
+ String *terminator_code = NewString("");
+
+ if (!proxy_flag)
+ return;
+
+ // Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
+ if (Getattr(n, "overload:ignore"))
+ return;
+
+ // Don't generate proxy method for additional explicitcall method used in directors
+ if (GetFlag(n, "explicitcall"))
+ 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("cstype", l, NULL);
+ Swig_typemap_attach_parms("csin", l, NULL);
+
+ /* Get return types */
+ if ((tm = Swig_typemap_lookup("cstype", n, "", 0))) {
+ // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type
+ SwigType *covariant = Getattr(n, "covariant");
+ String *cstypeout = Getattr(n, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
+ if (cstypeout)
+ tm = cstypeout;
+ substituteClassname(covariant ? covariant : t, tm);
+ Printf(return_type, "%s", tm);
+ if (covariant)
+ Swig_warning(WARN_CSHARP_COVARIANT_RET, input_file, line_number,
+ "Covariant return types not supported in C#. Proxy method will return %s.\n", SwigType_str(covariant, 0));
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ if (wrapping_member_flag && !enum_constant_flag) {
+ // Properties
+ setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) == 0);
+ if (setter_flag)
+ Swig_typemap_attach_parms("csvarin", l, NULL);
+ }
+
+ /* Start generating the proxy function */
+ const String *outattributes = Getattr(n, "tmap:cstype:outattributes");
+ if (outattributes)
+ Printf(function_code, " %s\n", outattributes);
+ const String *csattributes = Getattr(n, "feature:cs:attributes");
+ if (csattributes)
+ Printf(function_code, " %s\n", csattributes);
+ const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
+ if (methodmods) {
+ if (is_smart_pointer()) {
+ // Smart pointer classes do not mirror the inheritance hierarchy of the underlying pointer type, so no virtual/override/new required.
+ String *mmods = Copy(methodmods);
+ Replaceall(mmods, "override", "");
+ Replaceall(mmods, "virtual", "");
+ Replaceall(mmods, "new", "");
+ Chop(mmods); // remove trailing whitespace
+ Printf(function_code, " %s ", mmods);
+ Delete(mmods);
+ } else {
+ Printf(function_code, " %s ", methodmods);
+ }
+ } else {
+ methodmods = (is_public(n) ? public_string : protected_string);
+ Printf(function_code, " %s ", methodmods);
+ if (!is_smart_pointer()) {
+ // Smart pointer classes do not mirror the inheritance hierarchy of the underlying pointer type, so no virtual/override/new required.
+ if (Getattr(n, "override"))
+ Printf(function_code, "override ");
+ else if (checkAttribute(n, "storage", "virtual"))
+ Printf(function_code, "virtual ");
+ if (Getattr(n, "hides"))
+ Printf(function_code, "new ");
+ }
+ }
+ if (static_flag)
+ Printf(function_code, "static ");
+ Printf(function_code, "%s %s(", return_type, proxy_function_name);
+
+ Printv(imcall, imclass_name, ".$imfuncname(", NIL);
+ if (!static_flag)
+ Printf(imcall, "swigCPtr");
+
+ emit_mark_varargs(l);
+
+ int gencomma = !static_flag;
+
+ /* Output each parameter */
+ for (i = 0, p = l; p; i++) {
+
+ /* Ignored varargs */
+ if (checkAttribute(p, "varargs:ignore", "1")) {
+ p = nextSibling(p);
+ continue;
+ }
+
+ /* Ignored parameters */
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+
+ /* Ignore the 'this' argument for variable wrappers */
+ if (!(variable_wrapper_flag && i == 0)) {
+ SwigType *pt = Getattr(p, "type");
+ String *param_type = NewString("");
+ if (setter_flag)
+ last_parm = p;
+
+ /* Get the C# parameter type */
+ if ((tm = Getattr(p, "tmap:cstype"))) {
+ substituteClassname(pt, tm);
+ const String *inattributes = Getattr(p, "tmap:cstype:inattributes");
+ Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ if (gencomma)
+ Printf(imcall, ", ");
+
+ String *arg = makeParameterName(n, p, i, setter_flag);
+
+ // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
+ if ((tm = Getattr(p, "tmap:csin"))) {
+ substituteClassname(pt, tm);
+ Replaceall(tm, "$csinput", arg);
+ String *pre = Getattr(p, "tmap:csin:pre");
+ if (pre) {
+ substituteClassname(pt, pre);
+ Replaceall(pre, "$csinput", arg);
+ if (Len(pre_code) > 0)
+ Printf(pre_code, "\n");
+ Printv(pre_code, pre, NIL);
+ }
+ String *post = Getattr(p, "tmap:csin:post");
+ if (post) {
+ substituteClassname(pt, post);
+ Replaceall(post, "$csinput", arg);
+ if (Len(post_code) > 0)
+ Printf(post_code, "\n");
+ Printv(post_code, post, NIL);
+ }
+ String *terminator = Getattr(p, "tmap:csin:terminator");
+ if (terminator) {
+ substituteClassname(pt, terminator);
+ Replaceall(terminator, "$csinput", arg);
+ if (Len(terminator_code) > 0)
+ Insert(terminator_code, 0, "\n");
+ Insert(terminator_code, 0, terminator);
+ }
+ Printv(imcall, tm, NIL);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ /* Add parameter to proxy function */
+ if (gencomma >= 2)
+ Printf(function_code, ", ");
+ gencomma = 2;
+ Printf(function_code, "%s %s", param_type, arg);
+
+ Delete(arg);
+ Delete(param_type);
+ }
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ Printf(imcall, ")");
+ Printf(function_code, ")");
+
+ // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class)
+ if ((tm = Swig_typemap_lookup("csout", n, "", 0))) {
+ excodeSubstitute(n, tm, "csout", n);
+ bool is_pre_code = Len(pre_code) > 0;
+ bool is_post_code = Len(post_code) > 0;
+ bool is_terminator_code = Len(terminator_code) > 0;
+ if (is_pre_code || is_post_code || is_terminator_code) {
+ Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
+ if (is_post_code) {
+ Insert(tm, 0, "\n try ");
+ Printv(tm, " finally {\n", post_code, "\n }", NIL);
+ } else {
+ Insert(tm, 0, "\n ");
+ }
+ if (is_pre_code) {
+ Insert(tm, 0, pre_code);
+ Insert(tm, 0, "\n");
+ }
+ if (is_terminator_code) {
+ Printv(tm, "\n", terminator_code, NIL);
+ }
+ Insert(tm, 0, "{");
+ Printf(tm, "\n }");
+ }
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "true");
+ else
+ Replaceall(tm, "$owner", "false");
+ substituteClassname(t, tm);
+
+ // For director methods: generate code to selectively make a normal polymorphic call or
+ // an explicit method call - needed to prevent infinite recursion calls in director methods.
+ Node *explicit_n = Getattr(n, "explicitcallnode");
+ if (explicit_n) {
+ String *ex_overloaded_name = getOverloadedName(explicit_n);
+ String *ex_intermediary_function_name = Swig_name_member(proxy_class_name, ex_overloaded_name);
+
+ String *ex_imcall = Copy(imcall);
+ Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
+ Replaceall(imcall, "$imfuncname", intermediary_function_name);
+
+ String *excode = NewString("");
+ if (!Cmp(return_type, "void"))
+ Printf(excode, "if (this.GetType() == typeof(%s)) %s; else %s", proxy_class_name, imcall, ex_imcall);
+ else
+ Printf(excode, "((this.GetType() == typeof(%s)) ? %s : %s)", proxy_class_name, imcall, ex_imcall);
+
+ Clear(imcall);
+ Printv(imcall, excode, NIL);
+ Delete(ex_overloaded_name);
+ Delete(excode);
+ } else {
+ Replaceall(imcall, "$imfuncname", intermediary_function_name);
+ }
+ Replaceall(tm, "$imcall", imcall);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ if (wrapping_member_flag && !enum_constant_flag) {
+ // Properties
+ if (generate_property_declaration_flag) { // Ensure the declaration is generated just once should the property contain both a set and get
+ // Get the C# variable type - obtained differently depending on whether a setter is required.
+ String *variable_type = return_type;
+ if (setter_flag) {
+ p = last_parm; // (last parameter is the only parameter for properties)
+ SwigType *pt = Getattr(p, "type");
+ if ((tm = Getattr(p, "tmap:cstype"))) {
+ substituteClassname(pt, tm);
+ String *cstypeout = Getattr(p, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
+ variable_type = cstypeout ? cstypeout : tm;
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+ }
+ const String *csattributes = Getattr(n, "feature:cs:attributes");
+ if (csattributes)
+ Printf(proxy_class_code, " %s\n", csattributes);
+ const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
+ if (!methodmods)
+ methodmods = (is_public(n) ? public_string : protected_string);
+ Printf(proxy_class_code, " %s %s%s %s {", methodmods, static_flag ? "static " : "", variable_type, variable_name);
+ }
+ generate_property_declaration_flag = false;
+
+ if (setter_flag) {
+ // Setter method
+ p = last_parm; // (last parameter is the only parameter for properties)
+ SwigType *pt = Getattr(p, "type");
+ if ((tm = Getattr(p, "tmap:csvarin"))) {
+ substituteClassname(pt, tm);
+ Replaceall(tm, "$imcall", imcall);
+ excodeSubstitute(n, tm, "csvarin", p);
+ Printf(proxy_class_code, "%s", tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+ } else {
+ // Getter method
+ if ((tm = Swig_typemap_lookup("csvarout", n, "", 0))) {
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "true");
+ else
+ Replaceall(tm, "$owner", "false");
+ substituteClassname(t, tm);
+ Replaceall(tm, "$imcall", imcall);
+ excodeSubstitute(n, tm, "csvarout", n);
+ Printf(proxy_class_code, "%s", tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarout typemap defined for %s\n", SwigType_str(t, 0));
+ }
+ }
+ } else {
+ // Normal function call
+ Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
+ Printv(proxy_class_code, function_code, NIL);
+ }
+
+ Delete(pre_code);
+ Delete(post_code);
+ Delete(terminator_code);
+ Delete(function_code);
+ Delete(return_type);
+ Delete(imcall);
+ }
+
+ /* ----------------------------------------------------------------------
+ * constructorHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int constructorHandler(Node *n) {
+
+ ParmList *l = Getattr(n, "parms");
+ String *tm;
+ Parm *p;
+ int i;
+ String *function_code = NewString("");
+ String *helper_code = NewString(""); // Holds code for the constructor helper method generated only when the csin typemap has code in the pre or post attributes
+ String *helper_args = NewString("");
+ String *pre_code = NewString("");
+ String *post_code = NewString("");
+ String *terminator_code = NewString("");
+ String *im_return_type = NewString("");
+ bool feature_director = (parentNode(n) && Swig_directorclass(n));
+
+ Language::constructorHandler(n);
+
+ // Wrappers not wanted for some methods where the parameters cannot be overloaded in C#
+ if (Getattr(n, "overload:ignore"))
+ return SWIG_OK;
+
+ if (proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *mangled_overname = Swig_name_construct(overloaded_name);
+ String *imcall = NewString("");
+
+ const String *csattributes = Getattr(n, "feature:cs:attributes");
+ if (csattributes) {
+ Printf(function_code, " %s\n", csattributes);
+ Printf(helper_code, " %s\n", csattributes);
+ }
+ const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
+ methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
+
+ tm = Getattr(n, "tmap:imtype"); // typemaps were attached earlier to the node
+ String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
+ if (imtypeout)
+ tm = imtypeout;
+ Printf(im_return_type, "%s", tm);
+
+ Printf(function_code, " %s %s(", methodmods, proxy_class_name);
+ Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name);
+
+ Printv(imcall, imclass_name, ".", mangled_overname, "(", NIL);
+
+ /* Attach the non-standard typemaps to the parameter list */
+ Swig_typemap_attach_parms("in", l, NULL);
+ Swig_typemap_attach_parms("cstype", l, NULL);
+ Swig_typemap_attach_parms("csin", l, NULL);
+
+ emit_mark_varargs(l);
+
+ int gencomma = 0;
+
+ /* Output each parameter */
+ for (i = 0, p = l; p; i++) {
+
+ /* Ignored varargs */
+ if (checkAttribute(p, "varargs:ignore", "1")) {
+ p = nextSibling(p);
+ continue;
+ }
+
+ /* Ignored parameters */
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *param_type = NewString("");
+
+ /* Get the C# parameter type */
+ if ((tm = Getattr(p, "tmap:cstype"))) {
+ substituteClassname(pt, tm);
+ const String *inattributes = Getattr(p, "tmap:cstype:inattributes");
+ Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ if (gencomma)
+ Printf(imcall, ", ");
+
+ String *arg = makeParameterName(n, p, i, false);
+ String *cshin = 0;
+
+ // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
+ if ((tm = Getattr(p, "tmap:csin"))) {
+ substituteClassname(pt, tm);
+ Replaceall(tm, "$csinput", arg);
+ String *pre = Getattr(p, "tmap:csin:pre");
+ if (pre) {
+ substituteClassname(pt, pre);
+ Replaceall(pre, "$csinput", arg);
+ if (Len(pre_code) > 0)
+ Printf(pre_code, "\n");
+ Printv(pre_code, pre, NIL);
+ }
+ String *post = Getattr(p, "tmap:csin:post");
+ if (post) {
+ substituteClassname(pt, post);
+ Replaceall(post, "$csinput", arg);
+ if (Len(post_code) > 0)
+ Printf(post_code, "\n");
+ Printv(post_code, post, NIL);
+ }
+ String *terminator = Getattr(p, "tmap:csin:terminator");
+ if (terminator) {
+ substituteClassname(pt, terminator);
+ Replaceall(terminator, "$csinput", arg);
+ if (Len(terminator_code) > 0)
+ Insert(terminator_code, 0, "\n");
+ Insert(terminator_code, 0, terminator);
+ }
+ cshin = Getattr(p, "tmap:csin:cshin");
+ if (cshin)
+ Replaceall(cshin, "$csinput", arg);
+ Printv(imcall, tm, NIL);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ /* Add parameter to proxy function */
+ if (gencomma) {
+ Printf(function_code, ", ");
+ Printf(helper_code, ", ");
+ Printf(helper_args, ", ");
+ }
+ Printf(function_code, "%s %s", param_type, arg);
+ Printf(helper_code, "%s %s", param_type, arg);
+ Printf(helper_args, "%s", cshin ? cshin : arg);
+ ++gencomma;
+
+ Delete(cshin);
+ Delete(arg);
+ Delete(param_type);
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ Printf(imcall, ")");
+
+ Printf(function_code, ")");
+ Printf(helper_code, ")");
+
+ /* Insert the csconstruct typemap, doing the replacement for $directorconnect, as needed */
+ Hash *attributes = NewHash();
+ String *construct_tm = Copy(typemapLookup(n, "csconstruct", Getattr(n, "name"),
+ WARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF, attributes));
+ if (construct_tm) {
+ if (!feature_director) {
+ Replaceall(construct_tm, "$directorconnect", "");
+ } else {
+ String *connect_attr = Getattr(attributes, "tmap:csconstruct:directorconnect");
+
+ if (connect_attr) {
+ Replaceall(construct_tm, "$directorconnect", connect_attr);
+ } else {
+ Swig_warning(WARN_CSHARP_NO_DIRECTORCONNECT_ATTR, input_file, line_number, "\"directorconnect\" attribute missing in %s \"csconstruct\" typemap.\n",
+ Getattr(n, "name"));
+ Replaceall(construct_tm, "$directorconnect", "");
+ }
+ }
+
+ Printv(function_code, " ", construct_tm, NIL);
+ }
+
+ excodeSubstitute(n, function_code, "csconstruct", attributes);
+
+ bool is_pre_code = Len(pre_code) > 0;
+ bool is_post_code = Len(post_code) > 0;
+ bool is_terminator_code = Len(terminator_code) > 0;
+ if (is_pre_code || is_post_code || is_terminator_code) {
+ Printf(helper_code, " {\n");
+ if (is_pre_code) {
+ Printv(helper_code, pre_code, "\n", NIL);
+ }
+ if (is_post_code) {
+ Printf(helper_code, " try {\n");
+ Printv(helper_code, " return ", imcall, ";\n", NIL);
+ Printv(helper_code, " } finally {\n", post_code, "\n }", NIL);
+ } else {
+ Printv(helper_code, " return ", imcall, ";", NIL);
+ }
+ if (is_terminator_code) {
+ Printv(helper_code, "\n", terminator_code, NIL);
+ }
+ Printf(helper_code, "\n }\n");
+ String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args);
+ String *im_outattributes = Getattr(n, "tmap:imtype:outattributes");
+ if (im_outattributes)
+ Printf(proxy_class_code, " %s\n", im_outattributes);
+ Printv(proxy_class_code, helper_code, "\n", NIL);
+ Replaceall(function_code, "$imcall", helper_name);
+ Delete(helper_name);
+ } else {
+ Replaceall(function_code, "$imcall", imcall);
+ }
+
+ Printv(proxy_class_code, function_code, "\n", NIL);
+
+ Delete(helper_args);
+ Delete(im_return_type);
+ Delete(pre_code);
+ Delete(post_code);
+ Delete(terminator_code);
+ Delete(construct_tm);
+ Delete(attributes);
+ Delete(overloaded_name);
+ Delete(imcall);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * destructorHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int destructorHandler(Node *n) {
+ Language::destructorHandler(n);
+ String *symname = Getattr(n, "sym:name");
+
+ if (proxy_flag) {
+ Printv(destructor_call, imclass_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * membervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int membervariableHandler(Node *n) {
+
+ generate_property_declaration_flag = true;
+ 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;
+ generate_property_declaration_flag = false;
+
+ Printf(proxy_class_code, "\n }\n\n");
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * staticmembervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmembervariableHandler(Node *n) {
+
+ bool static_const_member_flag = (Getattr(n, "value") == 0);
+
+ generate_property_declaration_flag = true;
+ variable_name = Getattr(n, "sym:name");
+ wrapping_member_flag = true;
+ static_flag = true;
+ Language::staticmembervariableHandler(n);
+ wrapping_member_flag = false;
+ static_flag = false;
+ generate_property_declaration_flag = false;
+
+ if (static_const_member_flag)
+ Printf(proxy_class_code, "\n }\n\n");
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberconstantHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int memberconstantHandler(Node *n) {
+ variable_name = Getattr(n, "sym:name");
+ wrapping_member_flag = true;
+ Language::memberconstantHandler(n);
+ wrapping_member_flag = false;
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getOverloadedName()
+ * ----------------------------------------------------------------------------- */
+
+ String *getOverloadedName(Node *n) {
+
+ /* A C# HandleRef is used for all classes in the SWIG intermediary class.
+ * The intermediary class methods are thus mangled when overloaded to give
+ * a unique name. */
+ String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name"));
+
+ if (Getattr(n, "sym:overloaded")) {
+ Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
+ }
+
+ return overloaded_name;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * moduleClassFunctionHandler()
+ * ----------------------------------------------------------------------------- */
+
+ void moduleClassFunctionHandler(Node *n) {
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *tm;
+ Parm *p;
+ Parm *last_parm = 0;
+ int i;
+ String *imcall = NewString("");
+ String *return_type = NewString("");
+ String *function_code = NewString("");
+ int num_arguments = 0;
+ int num_required = 0;
+ String *overloaded_name = getOverloadedName(n);
+ String *func_name = NULL;
+ bool setter_flag = false;
+ String *pre_code = NewString("");
+ String *post_code = NewString("");
+ String *terminator_code = NewString("");
+
+ 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("cstype", l, NULL);
+ Swig_typemap_attach_parms("csin", l, NULL);
+
+ /* Get return types */
+ if ((tm = Swig_typemap_lookup("cstype", n, "", 0))) {
+ String *cstypeout = Getattr(n, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
+ if (cstypeout)
+ tm = cstypeout;
+ substituteClassname(t, tm);
+ Printf(return_type, "%s", tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ /* Change function name for global variables */
+ if (proxy_flag && global_variable_flag) {
+ // Capitalize the first letter in the variable to create the getter/setter function name
+ func_name = NewString("");
+ setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(variable_name)) == 0);
+ if (setter_flag)
+ 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);
+ if (setter_flag)
+ Swig_typemap_attach_parms("csvarin", l, NULL);
+ } else {
+ func_name = Copy(Getattr(n, "sym:name"));
+ }
+
+ /* Start generating the function */
+ const String *outattributes = Getattr(n, "tmap:cstype:outattributes");
+ if (outattributes)
+ Printf(function_code, " %s\n", outattributes);
+ const String *csattributes = Getattr(n, "feature:cs:attributes");
+ if (csattributes)
+ Printf(function_code, " %s\n", csattributes);
+ const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
+ methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
+ Printf(function_code, " %s static %s %s(", methodmods, return_type, func_name);
+ Printv(imcall, imclass_name, ".", overloaded_name, "(", NIL);
+
+ /* Get number of required and total arguments */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+
+ bool global_or_member_variable = global_variable_flag || (wrapping_member_flag && !enum_constant_flag);
+ int gencomma = 0;
+
+ /* Output each parameter */
+ for (i = 0, p = l; i < num_arguments; i++) {
+
+ /* Ignored parameters */
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *param_type = NewString("");
+ last_parm = p;
+
+ /* Get the C# parameter type */
+ if ((tm = Getattr(p, "tmap:cstype"))) {
+ substituteClassname(pt, tm);
+ const String *inattributes = Getattr(p, "tmap:cstype:inattributes");
+ Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ if (gencomma)
+ Printf(imcall, ", ");
+
+ String *arg = makeParameterName(n, p, i, global_or_member_variable);
+
+ // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
+ if ((tm = Getattr(p, "tmap:csin"))) {
+ substituteClassname(pt, tm);
+ Replaceall(tm, "$csinput", arg);
+ String *pre = Getattr(p, "tmap:csin:pre");
+ if (pre) {
+ substituteClassname(pt, pre);
+ Replaceall(pre, "$csinput", arg);
+ if (Len(pre_code) > 0)
+ Printf(pre_code, "\n");
+ Printv(pre_code, pre, NIL);
+ }
+ String *post = Getattr(p, "tmap:csin:post");
+ if (post) {
+ substituteClassname(pt, post);
+ Replaceall(post, "$csinput", arg);
+ if (Len(post_code) > 0)
+ Printf(post_code, "\n");
+ Printv(post_code, post, NIL);
+ }
+ String *terminator = Getattr(p, "tmap:csin:terminator");
+ if (terminator) {
+ substituteClassname(pt, terminator);
+ Replaceall(terminator, "$csinput", arg);
+ if (Len(terminator_code) > 0)
+ Insert(terminator_code, 0, "\n");
+ Insert(terminator_code, 0, terminator);
+ }
+ Printv(imcall, tm, NIL);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ /* Add parameter to module class function */
+ if (gencomma >= 2)
+ Printf(function_code, ", ");
+ gencomma = 2;
+ Printf(function_code, "%s %s", param_type, arg);
+
+ p = Getattr(p, "tmap:in:next");
+ Delete(arg);
+ Delete(param_type);
+ }
+
+ Printf(imcall, ")");
+ Printf(function_code, ")");
+
+ // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in module class)
+ if ((tm = Swig_typemap_lookup("csout", n, "", 0))) {
+ excodeSubstitute(n, tm, "csout", n);
+ bool is_pre_code = Len(pre_code) > 0;
+ bool is_post_code = Len(post_code) > 0;
+ bool is_terminator_code = Len(terminator_code) > 0;
+ if (is_pre_code || is_post_code || is_terminator_code) {
+ Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
+ if (is_post_code) {
+ Insert(tm, 0, "\n try ");
+ Printv(tm, " finally {\n", post_code, "\n }", NIL);
+ } else {
+ Insert(tm, 0, "\n ");
+ }
+ if (is_pre_code) {
+ Insert(tm, 0, pre_code);
+ Insert(tm, 0, "\n");
+ }
+ if (is_terminator_code) {
+ Printv(tm, "\n", terminator_code, NIL);
+ }
+ Insert(tm, 0, "{");
+ Printf(tm, "\n }");
+ }
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "true");
+ else
+ Replaceall(tm, "$owner", "false");
+ substituteClassname(t, tm);
+ Replaceall(tm, "$imcall", imcall);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ if (proxy_flag && global_variable_flag) {
+ // Properties
+ if (generate_property_declaration_flag) { // Ensure the declaration is generated just once should the property contain both a set and get
+ // Get the C# variable type - obtained differently depending on whether a setter is required.
+ String *variable_type = return_type;
+ if (setter_flag) {
+ p = last_parm; // (last parameter is the only parameter for properties)
+ SwigType *pt = Getattr(p, "type");
+ if ((tm = Getattr(p, "tmap:cstype"))) {
+ substituteClassname(pt, tm);
+ String *cstypeout = Getattr(p, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap
+ variable_type = cstypeout ? cstypeout : tm;
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+ }
+ const String *csattributes = Getattr(n, "feature:cs:attributes");
+ if (csattributes)
+ Printf(module_class_code, " %s\n", csattributes);
+ const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
+ if (!methodmods)
+ methodmods = (is_public(n) ? public_string : protected_string);
+ Printf(module_class_code, " %s static %s %s {", methodmods, variable_type, variable_name);
+ }
+ generate_property_declaration_flag = false;
+
+ if (setter_flag) {
+ // Setter method
+ p = last_parm; // (last parameter is the only parameter for properties)
+ SwigType *pt = Getattr(p, "type");
+ if ((tm = Getattr(p, "tmap:csvarin"))) {
+ substituteClassname(pt, tm);
+ Replaceall(tm, "$csinput", "value");
+ Replaceall(tm, "$imcall", imcall);
+ excodeSubstitute(n, tm, "csvarin", p);
+ Printf(module_class_code, "%s", tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+ } else {
+ // Getter method
+ if ((tm = Swig_typemap_lookup("csvarout", n, "", 0))) {
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "true");
+ else
+ Replaceall(tm, "$owner", "false");
+ substituteClassname(t, tm);
+ Replaceall(tm, "$imcall", imcall);
+ excodeSubstitute(n, tm, "csvarout", n);
+ Printf(module_class_code, "%s", tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarout typemap defined for %s\n", SwigType_str(t, 0));
+ }
+ }
+ } else {
+ // Normal function call
+ Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
+ Printv(module_class_code, function_code, NIL);
+ }
+
+ Delete(pre_code);
+ Delete(post_code);
+ Delete(terminator_code);
+ Delete(function_code);
+ Delete(return_type);
+ Delete(imcall);
+ Delete(func_name);
+ }
+
+ /*----------------------------------------------------------------------
+ * replaceSpecialVariables()
+ *--------------------------------------------------------------------*/
+
+ virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) {
+ (void)method;
+ SwigType *type = Getattr(parm, "type");
+ substituteClassname(type, tm);
+ }
+
+ /*----------------------------------------------------------------------
+ * decodeEnumFeature()
+ * Decode the possible enum features, which are one of:
+ * %csenum(simple)
+ * %csenum(typeunsafe) - default
+ * %csenum(typesafe)
+ * %csenum(proper)
+ *--------------------------------------------------------------------*/
+
+ EnumFeature decodeEnumFeature(Node *n) {
+ EnumFeature enum_feature = TypeunsafeEnum;
+ String *feature = Getattr(n, "feature:cs:enum");
+ if (feature) {
+ if (Cmp(feature, "simple") == 0)
+ enum_feature = SimpleEnum;
+ else if (Cmp(feature, "typesafe") == 0)
+ enum_feature = TypesafeEnum;
+ else if (Cmp(feature, "proper") == 0)
+ enum_feature = ProperEnum;
+ }
+ return enum_feature;
+ }
+
+ /* -----------------------------------------------------------------------
+ * enumValue()
+ * This method will return a string with an enum value to use in C# generated
+ * code. If the %csconst feature is not used, the string will contain the intermediary
+ * class call to obtain the enum value. The intermediary class and PINVOKE methods to obtain
+ * the enum value will be generated. Otherwise the C/C++ enum value will be used if there
+ * is one and hopefully it will compile as C# code - e.g. 20 as in: enum E{e=20};
+ * The %csconstvalue feature overrides all other ways to generate the constant value.
+ * The caller must delete memory allocated for the returned string.
+ * ------------------------------------------------------------------------ */
+
+ String *enumValue(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+
+ // Check for the %csconstvalue feature
+ String *value = Getattr(n, "feature:cs:constvalue");
+
+ if (!value) {
+ // The %csconst feature determines how the constant value is obtained
+ int const_feature_flag = GetFlag(n, "feature:cs:const");
+
+ if (const_feature_flag) {
+ // Use the C syntax to make a true C# constant and hope that it compiles as C# code
+ value = Getattr(n, "enumvalue") ? Copy(Getattr(n, "enumvalue")) : Copy(Getattr(n, "enumvalueex"));
+ } else {
+ // Get the enumvalue from a PINVOKE call
+ if (!getCurrentClass() || !cparse_cplusplus || !proxy_flag) {
+ // Strange hack to change the name
+ Setattr(n, "name", Getattr(n, "value")); /* for wrapping of enums in a namespace when emit_action is used */
+ constantWrapper(n);
+ value = NewStringf("%s.%s()", imclass_name, Swig_name_get(symname));
+ } else {
+ memberconstantHandler(n);
+ value = NewStringf("%s.%s()", imclass_name, Swig_name_get(Swig_name_member(proxy_class_name, symname)));
+ }
+ }
+ }
+ return value;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getEnumName()
+ * ----------------------------------------------------------------------------- */
+
+ String *getEnumName(SwigType *t) {
+ Node *enum_name = NULL;
+ Node *n = enumLookup(t);
+ if (n) {
+ String *symname = Getattr(n, "sym:name");
+ if (symname) {
+ // Add in class scope when referencing enum if not a global enum
+ String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name"));
+ String *proxyname = 0;
+ if (scopename_prefix) {
+ proxyname = getProxyName(scopename_prefix);
+ }
+ if (proxyname)
+ enum_name = NewStringf("%s.%s", proxyname, symname);
+ else
+ enum_name = NewStringf("%s", symname);
+ Delete(scopename_prefix);
+ }
+ }
+
+ return enum_name;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * substituteClassname()
+ *
+ * Substitute the special variable $csclassname with the proxy class name for classes/structs/unions
+ * that SWIG knows about. Also substitutes enums with enum name.
+ * Otherwise use the $descriptor name for the C# class name. Note that the $&csclassname substitution
+ * is the same as a $&descriptor substitution, ie one pointer added to descriptor name.
+ * Inputs:
+ * pt - parameter type
+ * tm - typemap contents that might contain the special variable to be replaced
+ * Outputs:
+ * tm - typemap contents complete with the special variable substitution
+ * Return:
+ * substitution_performed - flag indicating if a substitution was performed
+ * ----------------------------------------------------------------------------- */
+
+ bool substituteClassname(SwigType *pt, String *tm) {
+ bool substitution_performed = false;
+ SwigType *type = Copy(SwigType_typedef_resolve_all(pt));
+ SwigType *strippedtype = SwigType_strip_qualifiers(type);
+
+ if (Strstr(tm, "$csclassname")) {
+ SwigType *classnametype = Copy(strippedtype);
+ substituteClassnameSpecialVariable(classnametype, tm, "$csclassname");
+ substitution_performed = true;
+ Delete(classnametype);
+ }
+ if (Strstr(tm, "$*csclassname")) {
+ SwigType *classnametype = Copy(strippedtype);
+ Delete(SwigType_pop(classnametype));
+ substituteClassnameSpecialVariable(classnametype, tm, "$*csclassname");
+ substitution_performed = true;
+ Delete(classnametype);
+ }
+ if (Strstr(tm, "$&csclassname")) {
+ SwigType *classnametype = Copy(strippedtype);
+ SwigType_add_pointer(classnametype);
+ substituteClassnameSpecialVariable(classnametype, tm, "$&csclassname");
+ substitution_performed = true;
+ Delete(classnametype);
+ }
+
+ Delete(strippedtype);
+ Delete(type);
+
+ return substitution_performed;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * substituteClassnameSpecialVariable()
+ * ----------------------------------------------------------------------------- */
+
+ void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable) {
+ if (SwigType_isenum(classnametype)) {
+ String *enumname = getEnumName(classnametype);
+ if (enumname)
+ Replaceall(tm, classnamespecialvariable, enumname);
+ else
+ Replaceall(tm, classnamespecialvariable, NewStringf("int"));
+ } else {
+ String *classname = getProxyName(classnametype);
+ if (classname) {
+ Replaceall(tm, classnamespecialvariable, classname); // getProxyName() works for pointers to classes too
+ } else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
+ String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
+ Replaceall(tm, classnamespecialvariable, descriptor);
+
+ // Add to hash table so that the type wrapper classes can be created later
+ Setattr(swig_types_hash, descriptor, classnametype);
+ Delete(descriptor);
+ }
+ }
+ }
+
+ /* -----------------------------------------------------------------------------
+ * makeParameterName()
+ *
+ * Inputs:
+ * n - Node
+ * p - parameter node
+ * arg_num - parameter argument number
+ * setter - set this flag when wrapping variables
+ * Return:
+ * arg - a unique parameter name
+ * ----------------------------------------------------------------------------- */
+
+ String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter) {
+
+ String *arg = 0;
+ String *pn = Getattr(p, "name");
+
+ // Use C parameter name unless it is a duplicate or an empty parameter name
+ int count = 0;
+ ParmList *plist = Getattr(n, "parms");
+ while (plist) {
+ if ((Cmp(pn, Getattr(plist, "name")) == 0))
+ count++;
+ plist = nextSibling(plist);
+ }
+ String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0;
+ arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn);
+
+ if (setter && Cmp(arg, "self") != 0) {
+ // Note that in C# properties, the input variable name is always called 'value'
+ Delete(arg);
+ arg = NewString("value");
+ }
+
+ return arg;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitTypeWrapperClass()
+ * ----------------------------------------------------------------------------- */
+
+ void emitTypeWrapperClass(String *classname, SwigType *type) {
+ Node *n = NewHash();
+ Setfile(n, input_file);
+ Setline(n, line_number);
+
+ String *swigtype = NewString("");
+ String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), classname);
+ File *f_swigtype = NewFile(filen, "w", SWIG_output_files());
+ if (!f_swigtype) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the type wrapper class file
+ emitBanner(f_swigtype);
+
+ addOpenNamespace(namespce, f_swigtype);
+
+ // Pure C# baseclass and interfaces
+ const String *pure_baseclass = typemapLookup(n, "csbase", type, WARN_NONE);
+ const String *pure_interfaces = typemapLookup(n, "csinterfaces", type, WARN_NONE);
+
+ // Emit the class
+ Printv(swigtype, typemapLookup(n, "csimports", type, WARN_NONE), // Import statements
+ "\n", NIL);
+
+ // Class attributes
+ const String *csattributes = typemapLookup(n, "csattributes", type, WARN_NONE);
+ if (csattributes && *Char(csattributes))
+ Printf(swigtype, "%s\n", csattributes);
+
+ Printv(swigtype, typemapLookup(n, "csclassmodifiers", type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
+ " $csclassname", // Class name and base class
+ (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces
+ ", " : "", pure_interfaces, " {", typemapLookup(n, "csbody", type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class
+ typemapLookup(n, "cscode", type, WARN_NONE), // extra C# code
+ "}\n", NIL);
+
+ Replaceall(swigtype, "$csclassname", classname);
+ Replaceall(swigtype, "$module", module_class_name);
+ Replaceall(swigtype, "$imclassname", imclass_name);
+ Replaceall(swigtype, "$dllimport", dllimport);
+
+ Printv(f_swigtype, swigtype, NIL);
+
+ addCloseNamespace(namespce, f_swigtype);
+
+ Close(f_swigtype);
+ Delete(swigtype);
+ Delete(n);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * typemapLookup()
+ * n - for input only and must contain info for Getfile(n) and Getline(n) to work
+ * tmap_method - typemap method name
+ * type - typemap type to lookup
+ * warning - warning number to issue if no typemaps found
+ * typemap_attributes - the typemap attributes are attached to this node and will
+ * also be used for temporary storage if non null
+ * return is never NULL, unlike Swig_typemap_lookup()
+ * ----------------------------------------------------------------------------- */
+
+ const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0) {
+ Node *node = !typemap_attributes ? NewHash() : typemap_attributes;
+ Setattr(node, "type", type);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
+ if (!tm) {
+ tm = empty_string;
+ if (warning != WARN_NONE)
+ Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0));
+ }
+ if (!typemap_attributes)
+ Delete(node);
+ return tm;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * canThrow()
+ * Determine whether the code in the typemap can throw a C# exception.
+ * If so, note it for later when excodeSubstitute() is called.
+ * ----------------------------------------------------------------------------- */
+
+ void canThrow(Node *n, const String *typemap, Node *parameter) {
+ String *canthrow_attribute = NewStringf("tmap:%s:canthrow", typemap);
+ String *canthrow = Getattr(parameter, canthrow_attribute);
+ if (canthrow)
+ Setattr(n, "csharp:canthrow", "1");
+ Delete(canthrow_attribute);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * excodeSubstitute()
+ * If a method can throw a C# exception, additional exception code is added to
+ * check for the pending exception so that it can then throw the exception. The
+ * $excode special variable is replaced by the exception code in the excode
+ * typemap attribute.
+ * ----------------------------------------------------------------------------- */
+
+ void excodeSubstitute(Node *n, String *code, const String *typemap, Node *parameter) {
+ String *excode_attribute = NewStringf("tmap:%s:excode", typemap);
+ String *excode = Getattr(parameter, excode_attribute);
+ if (Getattr(n, "csharp:canthrow")) {
+ int count = Replaceall(code, "$excode", excode);
+ if (count < 1 || !excode) {
+ Swig_warning(WARN_CSHARP_EXCODE, input_file, line_number,
+ "C# exception may not be thrown - no $excode or excode attribute in '%s' typemap.\n", typemap);
+ }
+ } else {
+ Replaceall(code, "$excode", empty_string);
+ }
+ Delete(excode_attribute);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * addOpenNamespace()
+ * ----------------------------------------------------------------------------- */
+
+ void addOpenNamespace(String *namspace, File *file) {
+ if (namspace)
+ if (Len(namspace) > 0)
+ Printf(file, "namespace %s {\n", namspace);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * addCloseNamespace()
+ * ----------------------------------------------------------------------------- */
+
+ void addCloseNamespace(String *namspace, File *file) {
+ if (namspace)
+ if (Len(namspace) > 0)
+ Printf(file, "\n}\n");
+ }
+
+ /*----------------------------------------------------------------------
+ * Start of director methods
+ *--------------------------------------------------------------------*/
+
+#if 0
+ /*----------------------------------------------------------------------
+ * emitDirectorUpcalls()
+ *--------------------------------------------------------------------*/
+
+ void emitDirectorUpcalls() {
+ if (n_dmethods) {
+ Wrapper *w = NewWrapper();
+ String *dmethod_data = NewString("");
+ int n_methods = 0;
+ Iterator udata_iter;
+
+ udata_iter = First(dmethods_seq);
+ while (udata_iter.item) {
+ UpcallData *udata = udata_iter.item;
+ Printf(dmethod_data, " { \"%s\", \"%s\" }", Getattr(udata, "imclass_method"), Getattr(udata, "imclass_fdesc"));
+ ++n_methods;
+
+ udata_iter = Next(udata_iter);
+
+ if (udata_iter.item)
+ Putc(',', dmethod_data);
+ Putc('\n', dmethod_data);
+ }
+
+
+ Wrapper_print(w, f_wrappers);
+ Delete(dmethod_data);
+ Delete(swig_module_init);
+ DelWrapper(w);
+ }
+ }
+#endif
+
+ /*----------------------------------------------------------------------
+ * emitDirectorExtraMethods()
+ *
+ * This is where the director connect method is
+ * generated.
+ *--------------------------------------------------------------------*/
+ void emitDirectorExtraMethods(Node *n) {
+ if (!Swig_directorclass(n))
+ return;
+
+ // Output the director connect method:
+ String *norm_name = SwigType_namestr(Getattr(n, "name"));
+ String *swig_director_connect = NewStringf("%s_director_connect", proxy_class_name);
+ String *sym_name = Getattr(n, "sym:name");
+ Wrapper *code_wrap;
+
+ Printv(imclass_class_code, "\n [DllImport(\"", dllimport, "\", EntryPoint=\"CSharp_", swig_director_connect, "\")]\n", NIL);
+ Printf(imclass_class_code, " public static extern void %s(HandleRef jarg1", swig_director_connect);
+
+ code_wrap = NewWrapper();
+ Printf(code_wrap->def, "SWIGEXPORT void SWIGSTDCALL CSharp_%s(void *objarg", swig_director_connect);
+
+ Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name);
+ Printf(code_wrap->code, " SwigDirector_%s *director = dynamic_cast<SwigDirector_%s *>(obj);\n", sym_name, sym_name);
+ // TODO: if statement not needed?? - Java too
+ Printf(code_wrap->code, " if (director) {\n");
+ Printf(code_wrap->code, " director->swig_connect_director(");
+
+ for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
+ UpcallData *udata = Getitem(dmethods_seq, i);
+ String *methid = Getattr(udata, "class_methodidx");
+
+ Printf(code_wrap->def, ", ");
+ if (i != first_class_dmethod)
+ Printf(code_wrap->code, ", ");
+ Printf(code_wrap->def, "SwigDirector_%s::SWIG_Callback%s_t callback%s", sym_name, methid, methid);
+ Printf(code_wrap->code, "callback%s", methid);
+ Printf(imclass_class_code, ", %s.SwigDelegate%s_%s delegate%s", sym_name, sym_name, methid, methid);
+ }
+
+ Printf(code_wrap->def, ") {\n");
+ Printf(code_wrap->code, ");\n");
+ Printf(imclass_class_code, ");\n");
+ Printf(code_wrap->code, " }\n");
+ Printf(code_wrap->code, "}\n");
+
+ Wrapper_print(code_wrap, f_wrappers);
+ DelWrapper(code_wrap);
+
+ Delete(swig_director_connect);
+ }
+
+ /* ---------------------------------------------------------------
+ * classDirectorMethod()
+ *
+ * Emit a virtual director method to pass a method call on to the
+ * underlying Java object.
+ *
+ * --------------------------------------------------------------- */
+
+ int classDirectorMethod(Node *n, Node *parent, String *super) {
+ String *empty_str = NewString("");
+ String *classname = Getattr(parent, "sym:name");
+ String *c_classname = Getattr(parent, "name");
+ String *name = Getattr(n, "name");
+ String *symname = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ SwigType *returntype = Getattr(n, "returntype");
+ String *overloaded_name = getOverloadedName(n);
+ String *storage = Getattr(n, "storage");
+ String *value = Getattr(n, "value");
+ String *decl = Getattr(n, "decl");
+ String *declaration = NewString("");
+ String *tm;
+ Parm *p;
+ int i;
+ Wrapper *w = NewWrapper();
+ ParmList *l = Getattr(n, "parms");
+ bool is_void = !(Cmp(returntype, "void"));
+ String *qualified_return = NewString("");
+ bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0")));
+ int status = SWIG_OK;
+ bool output_director = true;
+ String *dirclassname = directorClassName(parent);
+ String *qualified_name = NewStringf("%s::%s", dirclassname, name);
+ SwigType *c_ret_type = NULL;
+ String *jupcall_args = NewString("");
+ String *imclass_dmethod;
+ String *callback_typedef_parms = NewString("");
+ String *delegate_parms = NewString("");
+ String *proxy_method_types = NewString("");
+ String *callback_def = NewString("");
+ String *callback_code = NewString("");
+ String *imcall_args = NewString("");
+ int gencomma = 0;
+ bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
+
+ // Kludge Alert: functionWrapper sets sym:overload properly, but it
+ // isn't at this point, so we have to manufacture it ourselves. At least
+ // we're consistent with the sym:overload name in functionWrapper. (?? when
+ // does the overloaded method name get set?)
+
+ imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(classname, overloaded_name));
+
+ if (returntype) {
+
+ qualified_return = SwigType_rcaststr(returntype, "c_result");
+
+ if (!is_void && !ignored_method) {
+ if (!SwigType_isclass(returntype)) {
+ if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
+ String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
+ Delete(construct_result);
+ } else {
+ String *base_typename = SwigType_base(returntype);
+ String *resolved_typename = SwigType_typedef_resolve_all(base_typename);
+ Symtab *symtab = Getattr(n, "sym:symtab");
+ Node *typenode = Swig_symbol_clookup(resolved_typename, symtab);
+
+ if (SwigType_ispointer(returntype) || (typenode && Getattr(typenode, "abstract"))) {
+ /* initialize pointers to something sane. Same for abstract
+ classes when a reference is returned. */
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
+ } else {
+ /* If returning a reference, initialize the pointer to a sane
+ default - if a C# exception occurs, then the pointer returns
+ something other than a NULL-initialized reference. */
+ String *non_ref_type = Copy(returntype);
+
+ /* Remove reference and const qualifiers */
+ Replaceall(non_ref_type, "r.", "");
+ Replaceall(non_ref_type, "q(const).", "");
+ Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
+
+ Delete(non_ref_type);
+ }
+
+ Delete(base_typename);
+ Delete(resolved_typename);
+ }
+ } else {
+ SwigType *vt;
+
+ vt = cplus_value_type(returntype);
+ if (!vt) {
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL);
+ } else {
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(vt, "c_result"), NIL);
+ Delete(vt);
+ }
+ }
+ }
+
+ /* Create the intermediate class wrapper */
+ Parm *tp = NewParmFromNode(returntype, empty_str, n);
+
+ tm = Swig_typemap_lookup("imtype", tp, "", 0);
+ if (tm) {
+ String *imtypeout = Getattr(tp, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
+ if (imtypeout)
+ tm = imtypeout;
+ const String *im_directoroutattributes = Getattr(tp, "tmap:imtype:directoroutattributes");
+ if (im_directoroutattributes) {
+ Printf(callback_def, " %s\n", im_directoroutattributes);
+ Printf(director_delegate_definitions, " %s\n", im_directoroutattributes);
+ }
+
+ Printf(callback_def, " private %s SwigDirector%s(", tm, overloaded_name);
+ if (!ignored_method)
+ Printf(director_delegate_definitions, " public delegate %s", tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0));
+ }
+
+ Parm *retpm = NewParmFromNode(returntype, empty_str, n);
+
+ if ((c_ret_type = Swig_typemap_lookup("ctype", retpm, "", 0))) {
+
+ if (!is_void && !ignored_method) {
+ String *jretval_decl = NewStringf("%s jresult", c_ret_type);
+ Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL);
+ Delete(jretval_decl);
+ }
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+
+ Delete(retpm);
+ }
+
+ /* Go through argument list, attach lnames for arguments */
+ for (i = 0, p = l; p; p = nextSibling(p), ++i) {
+ String *arg = Getattr(p, "name");
+ String *lname = NewString("");
+
+ if (!arg && Cmp(Getattr(p, "type"), "void")) {
+ lname = NewStringf("arg%d", i);
+ Setattr(p, "name", lname);
+ } else
+ lname = arg;
+
+ Setattr(p, "lname", lname);
+ }
+
+ /* Attach the standard typemaps */
+ Swig_typemap_attach_parms("out", l, 0);
+ Swig_typemap_attach_parms("ctype", l, 0);
+ Swig_typemap_attach_parms("imtype", l, 0);
+ Swig_typemap_attach_parms("cstype", l, 0);
+ Swig_typemap_attach_parms("directorin", l, 0);
+ Swig_typemap_attach_parms("csdirectorin", l, 0);
+
+ /* Preamble code */
+ if (!ignored_method)
+ Printf(w->code, "if (!swig_callback%s) {\n", overloaded_name);
+
+ if (!pure_virtual) {
+ String *super_call = Swig_method_call(super, l);
+ if (is_void) {
+ Printf(w->code, "%s;\n", super_call);
+ if (!ignored_method)
+ Printf(w->code, "return;\n");
+ } else {
+ Printf(w->code, "return %s;\n", super_call);
+ }
+ Delete(super_call);
+ } else {
+ Printf(w->code, " throw Swig::DirectorPureVirtualException(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name));
+ }
+
+ if (!ignored_method)
+ Printf(w->code, "} else {\n");
+
+ /* Go through argument list, convert from native to Java */
+ for (p = l; p; /* empty */ ) {
+ /* Is this superfluous? */
+ while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
+ p = Getattr(p, "tmap:directorin:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *ln = Copy(Getattr(p, "name"));
+ String *c_param_type = NULL;
+ String *c_decl = NewString("");
+ String *arg = NewString("");
+
+ Printf(arg, "j%s", ln);
+
+ /* And add to the upcall args */
+ if (gencomma > 0)
+ Printf(jupcall_args, ", ");
+ Printf(jupcall_args, "%s", arg);
+
+ /* Get parameter's intermediary C type */
+ if ((c_param_type = Getattr(p, "tmap:ctype"))) {
+ String *ctypeout = Getattr(p, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap
+ if (ctypeout)
+ c_param_type = ctypeout;
+
+ Parm *tp = NewParmFromNode(c_param_type, empty_str, n);
+ String *desc_tm = NULL;
+
+ /* Add to local variables */
+ Printf(c_decl, "%s %s", c_param_type, arg);
+ if (!ignored_method)
+ Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL);
+
+ /* Add input marshalling code */
+ if ((desc_tm = Swig_typemap_lookup("directorin", tp, "", 0))
+ && (tm = Getattr(p, "tmap:directorin"))) {
+
+ Replaceall(tm, "$input", arg);
+ Replaceall(tm, "$owner", "0");
+
+ if (Len(tm))
+ if (!ignored_method)
+ Printf(w->code, "%s\n", tm);
+
+ Delete(tm);
+
+ /* Add C type to callback typedef */
+ if (gencomma > 0)
+ Printf(callback_typedef_parms, ", ");
+ Printf(callback_typedef_parms, "%s", c_param_type);
+
+ /* Add parameter to the intermediate class code if generating the
+ * intermediate's upcall code */
+ if ((tm = Getattr(p, "tmap:imtype"))) {
+
+ String *imtypeout = Getattr(p, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap
+ if (imtypeout)
+ tm = imtypeout;
+ const String *im_directorinattributes = Getattr(p, "tmap:imtype:directorinattributes");
+
+ String *din = Copy(Getattr(p, "tmap:csdirectorin"));
+
+ if (din) {
+ Replaceall(din, "$module", module_class_name);
+ Replaceall(din, "$imclassname", imclass_name);
+ substituteClassname(pt, din);
+ Replaceall(din, "$iminput", ln);
+
+ if (gencomma > 0) {
+ Printf(delegate_parms, ", ");
+ Printf(proxy_method_types, ", ");
+ Printf(imcall_args, ", ");
+ }
+ Printf(delegate_parms, "%s%s %s", im_directorinattributes ? im_directorinattributes : empty_string, tm, ln);
+
+ if (Cmp(din, ln)) {
+ Printv(imcall_args, din, NIL);
+ } else
+ Printv(imcall_args, ln, NIL);
+
+ /* Get the C# parameter type */
+ if ((tm = Getattr(p, "tmap:cstype"))) {
+ substituteClassname(pt, tm);
+ Printf(proxy_method_types, "typeof(%s)", tm);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF, input_file, line_number, "No csdirectorin typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+
+ p = Getattr(p, "tmap:directorin:next");
+
+ Delete(desc_tm);
+ } else {
+ if (!desc_tm) {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF, input_file, line_number,
+ "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(c_param_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ p = nextSibling(p);
+ } else if (!tm) {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF, input_file, line_number,
+ "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ p = nextSibling(p);
+ }
+
+ output_director = false;
+ }
+
+ Delete(tp);
+ } else {
+ Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ p = nextSibling(p);
+ }
+
+ gencomma++;
+ Delete(arg);
+ Delete(c_decl);
+ Delete(c_param_type);
+ }
+
+ /* header declaration, start wrapper definition */
+ String *target;
+ SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type;
+ target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+ Printf(w->def, "%s", target);
+ Delete(qualified_name);
+ Delete(target);
+ target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+ Printf(declaration, " virtual %s", target);
+ Delete(target);
+
+ // Add any exception specifications to the methods in the director class
+ ParmList *throw_parm_list = NULL;
+ if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
+ int gencomma = 0;
+
+ Append(w->def, " throw(");
+ Append(declaration, " throw(");
+
+ if (throw_parm_list)
+ Swig_typemap_attach_parms("throws", throw_parm_list, 0);
+ for (p = throw_parm_list; p; p = nextSibling(p)) {
+ if ((tm = Getattr(p, "tmap:throws"))) {
+ if (gencomma++) {
+ Append(w->def, ", ");
+ Append(declaration, ", ");
+ }
+ Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0));
+ Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0));
+ }
+ }
+
+ Append(w->def, ")");
+ Append(declaration, ")");
+ }
+
+ Append(w->def, " {");
+ Append(declaration, ";\n");
+
+ /* Finish off the inherited upcall's definition */
+
+ Printf(callback_def, "%s)", delegate_parms);
+ Printf(callback_def, " {\n");
+
+ /* Emit the intermediate class's upcall to the actual class */
+
+ String *upcall = NewStringf("%s(%s)", symname, imcall_args);
+
+ if (!is_void) {
+ Parm *tp = NewParmFromNode(returntype, empty_str, n);
+
+ if ((tm = Swig_typemap_lookup("csdirectorout", tp, "", 0))) {
+ substituteClassname(returntype, tm);
+ Replaceall(tm, "$cscall", upcall);
+
+ Printf(callback_code, " return %s;\n", tm);
+ }
+
+ Delete(tm);
+ Delete(tp);
+ } else
+ Printf(callback_code, " %s;\n", upcall);
+
+ Printf(callback_code, " }\n");
+ Delete(upcall);
+
+ if (!ignored_method) {
+ if (!is_void)
+ Printf(w->code, "jresult = (%s) ", c_ret_type);
+
+ Printf(w->code, "swig_callback%s(%s);\n", overloaded_name, jupcall_args);
+
+ if (!is_void) {
+ String *jresult_str = NewString("jresult");
+ String *result_str = NewString("c_result");
+ Parm *tp = NewParmFromNode(returntype, result_str, n);
+
+ /* Copy jresult into c_result... */
+ if ((tm = Swig_typemap_lookup("directorout", tp, result_str, w))) {
+ Replaceall(tm, "$input", jresult_str);
+ Replaceall(tm, "$result", result_str);
+ Printf(w->code, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s used in %s::%s (skipping director method)\n",
+ SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+
+ Delete(tp);
+ Delete(jresult_str);
+ Delete(result_str);
+ }
+
+ /* Terminate wrapper code */
+ Printf(w->code, "}\n");
+ if (!is_void)
+ Printf(w->code, "return %s;", qualified_return);
+ }
+
+ Printf(w->code, "}");
+
+ // We expose virtual protected methods via an extra public inline method which makes a straight call to the wrapped class' method
+ String *inline_extra_method = NewString("");
+ if (dirprot_mode() && !is_public(n) && !pure_virtual) {
+ Printv(inline_extra_method, declaration, NIL);
+ String *extra_method_name = NewStringf("%sSwigPublic", name);
+ Replaceall(inline_extra_method, name, extra_method_name);
+ Replaceall(inline_extra_method, ";\n", " {\n ");
+ if (!is_void)
+ Printf(inline_extra_method, "return ");
+ String *methodcall = Swig_method_call(super, l);
+ Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
+ Delete(methodcall);
+ Delete(extra_method_name);
+ }
+
+ /* emit code */
+ if (status == SWIG_OK && output_director) {
+ if (!is_void) {
+ Replaceall(w->code, "$null", qualified_return);
+ } else {
+ Replaceall(w->code, "$null", "");
+ }
+ if (!ignored_method)
+ Printv(director_delegate_callback, "\n", callback_def, callback_code, NIL);
+ if (!Getattr(n, "defaultargs")) {
+ Wrapper_print(w, f_directors);
+ Printv(f_directors_h, declaration, NIL);
+ Printv(f_directors_h, inline_extra_method, NIL);
+ }
+ }
+
+ if (!ignored_method) {
+ /* Emit the actual upcall through */
+ UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name);
+ String *methid = Getattr(udata, "class_methodidx");
+
+ Printf(director_callback_typedefs, " typedef %s (SWIGSTDCALL* SWIG_Callback%s_t)(", c_ret_type, methid);
+ Printf(director_callback_typedefs, "%s);\n", callback_typedef_parms);
+ Printf(director_callbacks, " SWIG_Callback%s_t swig_callback%s;\n", methid, overloaded_name);
+
+ Printf(director_delegate_definitions, " SwigDelegate%s_%s(%s);\n", classname, methid, delegate_parms);
+ Printf(director_delegate_instances, " private SwigDelegate%s_%s swigDelegate%s;\n", classname, methid, methid);
+ Printf(director_method_types, " private static Type[] swigMethodTypes%s = new Type[] { %s };\n", methid, proxy_method_types);
+ Printf(director_connect_parms, "SwigDirector%s%s delegate%s", classname, methid, methid);
+ }
+
+ Delete(qualified_return);
+ Delete(c_ret_type);
+ Delete(declaration);
+ Delete(callback_typedef_parms);
+ Delete(delegate_parms);
+ Delete(proxy_method_types);
+ Delete(callback_def);
+ Delete(callback_code);
+ DelWrapper(w);
+
+ return status;
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorConstructor()
+ * ------------------------------------------------------------ */
+
+ int classDirectorConstructor(Node *n) {
+ Node *parent = parentNode(n);
+ String *decl = Getattr(n, "decl");;
+ String *supername = Swig_class_name(parent);
+ String *classname = directorClassName(parent);
+ String *sub = NewString("");
+ Parm *p;
+ ParmList *superparms = Getattr(n, "parms");
+ ParmList *parms;
+ int argidx = 0;
+
+ /* Assign arguments to superclass's parameters, if not already done */
+ for (p = superparms; p; p = nextSibling(p)) {
+ String *pname = Getattr(p, "name");
+
+ if (!pname) {
+ pname = NewStringf("arg%d", argidx++);
+ Setattr(p, "name", pname);
+ }
+ }
+
+ // TODO: Is this copy needed?
+ parms = CopyParmList(superparms);
+
+ if (!Getattr(n, "defaultargs")) {
+ /* constructor */
+ {
+ String *basetype = Getattr(parent, "classtype");
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+ String *call = Swig_csuperclass_call(0, basetype, superparms);
+ String *classtype = SwigType_namestr(Getattr(n, "name"));
+
+ Printf(f_directors, "%s::%s : %s, %s {\n", classname, target, call, Getattr(parent, "director:ctor"));
+ Printf(f_directors, " swig_init_callbacks();\n");
+ Printf(f_directors, "}\n\n");
+
+ Delete(classtype);
+ Delete(target);
+ Delete(call);
+ }
+
+ /* constructor header */
+ {
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+ Printf(f_directors_h, " %s;\n", target);
+ Delete(target);
+ }
+ }
+
+ Delete(sub);
+ Delete(supername);
+ Delete(parms);
+ return Language::classDirectorConstructor(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorDefaultConstructor()
+ * ------------------------------------------------------------ */
+
+ int classDirectorDefaultConstructor(Node *n) {
+ String *classname = Swig_class_name(n);
+ String *classtype = SwigType_namestr(Getattr(n, "name"));
+ Wrapper *w = NewWrapper();
+
+ Printf(w->def, "SwigDirector_%s::SwigDirector_%s() : %s {", classname, classname, Getattr(n, "director:ctor"));
+ Printf(w->code, "}\n");
+ Wrapper_print(w, f_directors);
+
+ Printf(f_directors_h, " SwigDirector_%s();\n", classname);
+ DelWrapper(w);
+ Delete(classtype);
+ Delete(classname);
+ return Language::classDirectorDefaultConstructor(n);
+ }
+
+
+ /* ------------------------------------------------------------
+ * classDirectorInit()
+ * ------------------------------------------------------------ */
+
+ int classDirectorInit(Node *n) {
+ Delete(none_comparison);
+ none_comparison = NewString(""); // not used
+
+ Delete(director_ctor_code);
+ director_ctor_code = NewString("$director_new");
+
+ Java_director_declaration(n);
+
+ Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl"));
+ Printf(f_directors_h, "\npublic:\n");
+
+ /* Keep track of the director methods for this class */
+ first_class_dmethod = curr_class_dmethod = n_dmethods;
+
+ director_callback_typedefs = NewString("");
+ director_callbacks = NewString("");
+ director_delegate_callback = NewString("");
+ director_delegate_definitions = NewString("");
+ director_delegate_instances = NewString("");
+ director_method_types = NewString("");
+ director_connect_parms = NewString("");
+
+ return Language::classDirectorInit(n);
+ }
+
+ /* ----------------------------------------------------------------------
+ * classDirectorDestructor()
+ * ---------------------------------------------------------------------- */
+
+ int classDirectorDestructor(Node *n) {
+ Node *current_class = getCurrentClass();
+ String *full_classname = Getattr(current_class, "name");
+ String *classname = Swig_class_name(current_class);
+ Wrapper *w = NewWrapper();
+
+ if (Getattr(n, "throw")) {
+ Printf(f_directors_h, " virtual ~SwigDirector_%s() throw ();\n", classname);
+ Printf(w->def, "SwigDirector_%s::~SwigDirector_%s() throw () {\n", classname, classname);
+ } else {
+ Printf(f_directors_h, " virtual ~SwigDirector_%s();\n", classname);
+ Printf(w->def, "SwigDirector_%s::~SwigDirector_%s() {\n", classname, classname);
+ }
+
+ /* Ensure that correct directordisconnect typemap's method name is called
+ * here: */
+
+ const String *disconn_tm = NULL;
+ Node *disconn_attr = NewHash();
+ String *disconn_methodname = NULL;
+
+ disconn_tm = typemapLookup(n, "directordisconnect", full_classname, WARN_NONE, disconn_attr);
+ disconn_methodname = Getattr(disconn_attr, "tmap:directordisconnect:methodname");
+
+ Printv(w->code, "}\n", NIL);
+
+ Wrapper_print(w, f_directors);
+
+ DelWrapper(w);
+ Delete(disconn_attr);
+ Delete(classname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorEnd()
+ * ------------------------------------------------------------ */
+
+ int classDirectorEnd(Node *n) {
+ int i;
+ String *director_classname = directorClassName(n);
+
+ Wrapper *w = NewWrapper();
+
+ if (Len(director_callback_typedefs) > 0) {
+ Printf(f_directors_h, "\n%s", director_callback_typedefs);
+ }
+
+ Printf(f_directors_h, " void swig_connect_director(");
+
+ Printf(w->def, "void %s::swig_connect_director(", director_classname);
+
+ for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
+ UpcallData *udata = Getitem(dmethods_seq, i);
+ String *methid = Getattr(udata, "class_methodidx");
+ String *overname = Getattr(udata, "overname");
+
+ Printf(f_directors_h, "SWIG_Callback%s_t callback%s", methid, overname);
+ Printf(w->def, "SWIG_Callback%s_t callback%s", methid, overname);
+ Printf(w->code, "swig_callback%s = callback%s;\n", overname, overname);
+ if (i != curr_class_dmethod - 1) {
+ Printf(f_directors_h, ", ");
+ Printf(w->def, ", ");
+ }
+ }
+
+ Printf(f_directors_h, ");\n");
+ Printf(w->def, ") {");
+
+
+ if (Len(director_callback_typedefs) > 0) {
+ Printf(f_directors_h, "\nprivate:\n%s", director_callbacks);
+ }
+ Printf(f_directors_h, " void swig_init_callbacks();\n");
+ Printf(f_directors_h, "};\n\n");
+ Printf(w->code, "}\n\n");
+
+ Printf(w->code, "void %s::swig_init_callbacks() {\n", director_classname);
+ for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
+ UpcallData *udata = Getitem(dmethods_seq, i);
+ String *overname = Getattr(udata, "overname");
+ Printf(w->code, "swig_callback%s = 0;\n", overname);
+ }
+ Printf(w->code, "}");
+
+ Wrapper_print(w, f_directors);
+
+ DelWrapper(w);
+
+ return Language::classDirectorEnd(n);
+ }
+
+ /* --------------------------------------------------------------------
+ * classDirectorDisown()
+ * ------------------------------------------------------------------*/
+ virtual int classDirectorDisown(Node *n) {
+ (void) n;
+ return SWIG_OK;
+ }
+
+ /*----------------------------------------------------------------------
+ * extraDirectorProtectedCPPMethodsRequired()
+ *--------------------------------------------------------------------*/
+
+ bool extraDirectorProtectedCPPMethodsRequired() const {
+ return false;
+ }
+
+ /*----------------------------------------------------------------------
+ * Java_director_declaration()
+ *
+ * Generate the director class's declaration
+ * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
+ *--------------------------------------------------------------------*/
+
+ void Java_director_declaration(Node *n) {
+
+ String *base = Getattr(n, "classtype");
+ String *class_ctor = NewString("Swig::Director()");
+
+ String *classname = Swig_class_name(n);
+ String *directorname = NewStringf("SwigDirector_%s", classname);
+ String *declaration = Swig_class_declaration(n, directorname);
+
+ Printf(declaration, " : public %s, public Swig::Director", base);
+
+ // Stash stuff for later.
+ Setattr(n, "director:decl", declaration);
+ Setattr(n, "director:ctor", class_ctor);
+ }
+
+}; /* class CSHARP */
+
+/* -----------------------------------------------------------------------------
+ * swig_csharp() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_csharp() {
+ return new CSHARP();
+}
+extern "C" Language *swig_csharp(void) {
+ return new_swig_csharp();
+}
+
+/* -----------------------------------------------------------------------------
+ * Static member variables
+ * ----------------------------------------------------------------------------- */
+
+const char *CSHARP::usage = (char *) "\
+C# Options (available with -csharp)\n\
+ -dllimport <dl> - Override DllImport attribute name to <dl>\n\
+ -namespace <nm> - Generate wrappers into C# namespace <nm>\n\
+ -noproxy - Generate the low-level functional interface instead\n\
+ of proxy classes\n\
+ -oldvarnames - old intermediary method names for variable wrappers\n\
+\n";
diff --git a/Source/Modules/directors.cxx b/Source/Modules/directors.cxx
new file mode 100644
index 0000000..158b535
--- /dev/null
+++ b/Source/Modules/directors.cxx
@@ -0,0 +1,288 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * directors.cxx
+ *
+ * Director support functions.
+ * Not all of these may be necessary, and some may duplicate existing functionality
+ * in SWIG. --MR
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_directors_cxx[] = "$Id";
+
+#include "swigmod.h"
+
+/* Swig_csuperclass_call()
+ *
+ * Generates a fully qualified method call, including the full parameter list.
+ * e.g. "base::method(i, j)"
+ *
+ */
+
+String *Swig_csuperclass_call(String *base, String *method, ParmList *l) {
+ String *call = NewString("");
+ int arg_idx = 0;
+ Parm *p;
+ if (base) {
+ Printf(call, "%s::", base);
+ }
+ Printf(call, "%s(", method);
+ for (p = l; p; p = nextSibling(p)) {
+ String *pname = Getattr(p, "name");
+ if (!pname && Cmp(Getattr(p, "type"), "void")) {
+ pname = NewString("");
+ Printf(pname, "arg%d", arg_idx++);
+ }
+ if (p != l)
+ Printf(call, ", ");
+ Printv(call, pname, NIL);
+ }
+ Printf(call, ")");
+ return call;
+}
+
+/* Swig_class_declaration()
+ *
+ * Generate the start of a class/struct declaration.
+ * e.g. "class myclass"
+ *
+ */
+
+String *Swig_class_declaration(Node *n, String *name) {
+ if (!name) {
+ name = Getattr(n, "sym:name");
+ }
+ String *result = NewString("");
+ String *kind = Getattr(n, "kind");
+ Printf(result, "%s %s", kind, name);
+ return result;
+}
+
+String *Swig_class_name(Node *n) {
+ String *name;
+ name = Copy(Getattr(n, "sym:name"));
+ return name;
+}
+
+/* Swig_director_declaration()
+ *
+ * Generate the full director class declaration, complete with base classes.
+ * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
+ *
+ */
+
+String *Swig_director_declaration(Node *n) {
+ String *classname = Swig_class_name(n);
+ String *directorname = NewStringf("SwigDirector_%s", classname);
+ String *base = Getattr(n, "classtype");
+ String *declaration = Swig_class_declaration(n, directorname);
+ Printf(declaration, " : public %s, public Swig::Director {\n", base);
+ Delete(classname);
+ Delete(directorname);
+ return declaration;
+}
+
+
+String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
+ String *func;
+ int i = 0;
+ int comma = 0;
+ Parm *p = parms;
+ SwigType *pt;
+ String *nname;
+
+ func = NewString("");
+ nname = SwigType_namestr(name);
+ Printf(func, "%s(", nname);
+ while (p) {
+ String *pname;
+ pt = Getattr(p, "type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ if (comma)
+ Printf(func, ",");
+ pname = Getattr(p, "name");
+ Printf(func, "%s", pname);
+ comma = 1;
+ i++;
+ }
+ p = nextSibling(p);
+ }
+ Printf(func, ")");
+ return func;
+}
+
+/* Swig_method_decl
+ *
+ * Misnamed and misappropriated! Taken from SWIG's type string manipulation utilities
+ * and modified to generate full (or partial) type qualifiers for method declarations,
+ * local variable declarations, and return value casting. More importantly, it merges
+ * parameter type information with actual parameter names to produce a complete method
+ * declaration that fully mirrors the original method declaration.
+ *
+ * There is almost certainly a saner way to do this.
+ *
+ * This function needs to be cleaned up and possibly split into several smaller
+ * functions. For instance, attaching default names to parameters should be done in a
+ * separate function.
+ *
+ */
+
+String *Swig_method_decl(SwigType *returntype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values) {
+ String *result;
+ List *elements;
+ String *element = 0, *nextelement;
+ int is_const = 0;
+ int nelements, i;
+ int is_func = 0;
+ int arg_idx = 0;
+
+ if (id) {
+ result = NewString(Char(id));
+ } else {
+ result = NewString("");
+ }
+
+ elements = SwigType_split(decl);
+ nelements = Len(elements);
+ if (nelements > 0) {
+ element = Getitem(elements, 0);
+ }
+ for (i = 0; i < nelements; i++) {
+ if (i < (nelements - 1)) {
+ nextelement = Getitem(elements, i + 1);
+ } else {
+ nextelement = 0;
+ }
+ if (SwigType_isqualifier(element)) {
+ int skip = 0;
+ DOH *q = 0;
+ if (!strip) {
+ q = SwigType_parm(element);
+ if (!Cmp(q, "const")) {
+ is_const = 1;
+ is_func = SwigType_isfunction(nextelement);
+ if (is_func)
+ skip = 1;
+ skip = 1;
+ }
+ if (!skip) {
+ Insert(result, 0, " ");
+ Insert(result, 0, q);
+ }
+ Delete(q);
+ }
+ } else if (SwigType_isfunction(element)) {
+ Parm *parm;
+ String *p;
+ Append(result, "(");
+ parm = args;
+ while (parm != 0) {
+ String *type = Getattr(parm, "type");
+ String *name = Getattr(parm, "name");
+ if (!name && Cmp(type, "void")) {
+ name = NewString("");
+ Printf(name, "arg%d", arg_idx++);
+ Setattr(parm, "name", name);
+ }
+ if (!name) {
+ name = NewString("");
+ }
+ p = SwigType_str(type, name);
+ Append(result, p);
+ String *value = Getattr(parm, "value");
+ if (values && (value != 0)) {
+ Printf(result, " = %s", value);
+ }
+ parm = nextSibling(parm);
+ if (parm != 0)
+ Append(result, ", ");
+ }
+ Append(result, ")");
+ } else if (returntype) { // This check is intended for conversion operators to a pointer/reference which needs the pointer/reference ignoring in the declaration
+ if (SwigType_ispointer(element)) {
+ Insert(result, 0, "*");
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result, 0, "(");
+ Append(result, ")");
+ }
+ } else if (SwigType_ismemberpointer(element)) {
+ String *q;
+ q = SwigType_parm(element);
+ Insert(result, 0, "::*");
+ Insert(result, 0, q);
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result, 0, "(");
+ Append(result, ")");
+ }
+ Delete(q);
+ } else if (SwigType_isreference(element)) {
+ Insert(result, 0, "&");
+ } else if (SwigType_isarray(element)) {
+ DOH *size;
+ Append(result, "[");
+ size = SwigType_parm(element);
+ Append(result, size);
+ Append(result, "]");
+ Delete(size);
+ } else {
+ if (Strcmp(element, "v(...)") == 0) {
+ Insert(result, 0, "...");
+ } else {
+ String *bs = SwigType_namestr(element);
+ Insert(result, 0, " ");
+ Insert(result, 0, bs);
+ Delete(bs);
+ }
+ }
+ }
+ element = nextelement;
+ }
+
+ Delete(elements);
+
+ if (is_const) {
+ if (is_func) {
+ Append(result, " ");
+ Append(result, "const");
+ } else {
+ Insert(result, 0, "const ");
+ }
+ }
+
+ Chop(result);
+
+ if (returntype) {
+ Insert(result, 0, " ");
+ String *rtype = SwigType_str(returntype, 0);
+ Insert(result, 0, rtype);
+ Delete(rtype);
+ }
+
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_director_emit_dynamic_cast()
+ *
+ * In order to call protected virtual director methods from the target language, we need
+ * to add an extra dynamic_cast to call the public C++ wrapper in the director class.
+ * Also for non-static protected members when the allprotected option is on.
+ * ----------------------------------------------------------------------------- */
+void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) {
+ // TODO: why is the storage element removed in staticmemberfunctionHandler ??
+ if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) ||
+ (is_non_virtual_protected_access(n) && !(checkAttribute(n, "staticmemberfunctionHandler:storage", "static") ||
+ checkAttribute(n, "storage", "static"))
+ && !Equal(nodeType(n), "constructor"))) {
+ Node *parent = Getattr(n, "parentNode");
+ String *symname = Getattr(parent, "sym:name");
+ String *dirname = NewStringf("SwigDirector_%s", symname);
+ String *dirdecl = NewStringf("%s *darg = 0", dirname);
+ Wrapper_add_local(f, "darg", dirdecl);
+ Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n", dirname);
+ Delete(dirname);
+ Delete(dirdecl);
+ }
+}
+
diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx
new file mode 100644
index 0000000..99631c1
--- /dev/null
+++ b/Source/Modules/emit.cxx
@@ -0,0 +1,512 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * emit.cxx
+ *
+ * Useful functions for emitting various pieces of code.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_emit_cxx[] = "$Id: emit.cxx 11471 2009-07-29 20:52:29Z wsfulton $";
+
+#include "swigmod.h"
+
+/* -----------------------------------------------------------------------------
+ * emit_return_variable()
+ *
+ * Emits a variable declaration for a function return value.
+ * The variable name is always called result.
+ * n => Node of the method being wrapped
+ * rt => the return type
+ * f => the wrapper to generate code into
+ * ----------------------------------------------------------------------------- */
+
+void emit_return_variable(Node *n, SwigType *rt, Wrapper *f) {
+
+ if (!GetFlag(n, "tmap:out:optimal")) {
+ if (rt && (SwigType_type(rt) != T_VOID)) {
+ SwigType *vt = cplus_value_type(rt);
+ SwigType *tt = vt ? vt : rt;
+ SwigType *lt = SwigType_ltype(tt);
+ String *lstr = SwigType_str(lt, "result");
+ if (SwigType_ispointer(lt)) {
+ Wrapper_add_localv(f, "result", lstr, "= 0", NULL);
+ } else {
+ Wrapper_add_local(f, "result", lstr);
+ }
+ if (vt) {
+ Delete(vt);
+ }
+ Delete(lt);
+ Delete(lstr);
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_parameter_variables()
+ *
+ * Emits a list of variable declarations for function parameters.
+ * The variable names are always called arg1, arg2, etc...
+ * l => the parameter list
+ * f => the wrapper to generate code into
+ * ----------------------------------------------------------------------------- */
+
+void emit_parameter_variables(ParmList *l, Wrapper *f) {
+
+ Parm *p;
+ String *tm;
+
+ /* Emit function arguments */
+ Swig_cargs(f, l);
+
+ /* Attach typemaps to parameters */
+ /* Swig_typemap_attach_parms("ignore",l,f); */
+
+ Swig_typemap_attach_parms("default", l, f);
+ Swig_typemap_attach_parms("arginit", l, f);
+
+ /* Apply the arginit and default */
+ p = l;
+ while (p) {
+ tm = Getattr(p, "tmap:arginit");
+ if (tm) {
+ Replace(tm, "$target", Getattr(p, "lname"), DOH_REPLACE_ANY);
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:arginit:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Apply the default typemap */
+ p = l;
+ while (p) {
+ tm = Getattr(p, "tmap:default");
+ if (tm) {
+ Replace(tm, "$target", Getattr(p, "lname"), DOH_REPLACE_ANY);
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:default:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_attach_parmmaps()
+ *
+ * Attach the standard parameter related typemaps.
+ * ----------------------------------------------------------------------------- */
+
+void emit_attach_parmmaps(ParmList *l, Wrapper *f) {
+ Swig_typemap_attach_parms("in", l, f);
+ Swig_typemap_attach_parms("typecheck", l, 0);
+ Swig_typemap_attach_parms("argout", l, f);
+ Swig_typemap_attach_parms("check", l, f);
+ Swig_typemap_attach_parms("freearg", l, f);
+
+ {
+ /* This is compatibility code to deal with the deprecated "ignore" typemap */
+ Parm *p = l;
+ Parm *np;
+ String *tm;
+ while (p) {
+ tm = Getattr(p, "tmap:in");
+ if (tm && checkAttribute(p, "tmap:in:numinputs", "0")) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(f->code, tm, "\n", NIL);
+ np = Getattr(p, "tmap:in:next");
+ while (p && (p != np)) {
+ /* Setattr(p,"ignore","1"); Deprecate */
+ p = nextSibling(p);
+ }
+ } else if (tm) {
+ p = Getattr(p, "tmap:in:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* Perform a sanity check on "in" and "freearg" typemaps. These
+ must exactly match to avoid chaos. If a mismatch occurs, we
+ nuke the freearg typemap */
+
+ {
+ Parm *p = l;
+ Parm *npin, *npfreearg;
+ while (p) {
+ npin = Getattr(p, "tmap:in:next");
+
+ /*
+ if (Getattr(p,"tmap:ignore")) {
+ npin = Getattr(p,"tmap:ignore:next");
+ } else if (Getattr(p,"tmap:in")) {
+ npin = Getattr(p,"tmap:in:next");
+ }
+ */
+
+ if (Getattr(p, "tmap:freearg")) {
+ npfreearg = Getattr(p, "tmap:freearg:next");
+ if (npin != npfreearg) {
+ while (p != npin) {
+ Delattr(p, "tmap:freearg");
+ Delattr(p, "tmap:freearg:next");
+ p = nextSibling(p);
+ }
+ }
+ }
+ p = npin;
+ }
+ }
+
+ /* Check for variable length arguments with no input typemap.
+ If no input is defined, we set this to ignore and print a
+ message.
+ */
+ {
+ Parm *p = l;
+ Parm *lp = 0;
+ while (p) {
+ if (!checkAttribute(p, "tmap:in:numinputs", "0")) {
+ lp = p;
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+ if (SwigType_isvarargs(Getattr(p, "type"))) {
+ Swig_warning(WARN_LANG_VARARGS, input_file, line_number, "Variable length arguments discarded.\n");
+ Setattr(p, "tmap:in", "");
+ }
+ lp = 0;
+ p = nextSibling(p);
+ }
+
+ /* Check if last input argument is variable length argument */
+ if (lp) {
+ p = lp;
+ while (p) {
+ if (SwigType_isvarargs(Getattr(p, "type"))) {
+ Setattr(l, "emit:varargs", lp);
+ break;
+ }
+ p = nextSibling(p);
+ }
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_num_arguments()
+ *
+ * Calculate the total number of arguments. This function is safe for use
+ * with multi-argument 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);
+ }
+ }
+
+ /* DB 04/02/2003: Not sure this is necessary with tmap:in:numinputs */
+ /*
+ if (parms && (p = Getattr(parms,"emit:varargs"))) {
+ if (!nextSibling(p)) {
+ nargs--;
+ }
+ }
+ */
+ return nargs;
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_num_required()
+ *
+ * Computes the number of required arguments. This function is safe for
+ * use with multi-argument typemaps and knows how to skip over everything
+ * properly. Note that parameters with default values are counted unless
+ * the compact default args option is on.
+ * ----------------------------------------------------------------------------- */
+
+int emit_num_required(ParmList *parms) {
+ Parm *p = parms;
+ int nargs = 0;
+ Parm *first_default_arg = 0;
+ int compactdefargs = ParmList_is_compactdefargs(p);
+
+ while (p) {
+ if (Getattr(p, "tmap:in") && checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ } else {
+ if (Getattr(p, "tmap:default"))
+ break;
+ if (Getattr(p, "value")) {
+ if (!first_default_arg)
+ first_default_arg = p;
+ if (compactdefargs)
+ break;
+ }
+ nargs += GetInt(p, "tmap:in:numinputs");
+ if (Getattr(p, "tmap:in")) {
+ p = Getattr(p, "tmap:in:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* Print error message for non-default arguments following default arguments */
+ /* The error message is printed more than once with most language modules, this ought to be fixed */
+ if (first_default_arg) {
+ p = first_default_arg;
+ 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), "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);
+ }
+ }
+ }
+ }
+
+ /* DB 04/02/2003: Not sure this is necessary with tmap:in:numinputs */
+ /*
+ if (parms && (p = Getattr(parms,"emit:varargs"))) {
+ if (!nextSibling(p)) {
+ nargs--;
+ }
+ }
+ */
+ return nargs;
+}
+
+/* -----------------------------------------------------------------------------
+ * emit_isvarargs()
+ *
+ * Checks if a function is a varargs function
+ * ----------------------------------------------------------------------------- */
+
+int emit_isvarargs(ParmList *p) {
+ if (!p)
+ return 0;
+ if (Getattr(p, "emit:varargs"))
+ return 1;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * void emit_mark_vararg_parms()
+ *
+ * Marks the vararg parameters which are to be ignored.
+ * Vararg parameters are marked as ignored if there is no 'in' varargs (...)
+ * typemap.
+ * ----------------------------------------------------------------------------- */
+
+void emit_mark_varargs(ParmList *l) {
+ Parm *p = l;
+ while (p) {
+ if (SwigType_isvarargs(Getattr(p, "type")))
+ if (!Getattr(p, "tmap:in"))
+ Setattr(p, "varargs:ignore", "1");
+ p = nextSibling(p);
+ }
+}
+
+#if 0
+/* replace_contract_args. This function replaces argument names in contract
+ specifications. Used in conjunction with the %contract directive. */
+
+static void replace_contract_args(Parm *cp, Parm *rp, String *s) {
+ while (cp && rp) {
+ String *n = Getattr(cp, "name");
+ if (n) {
+ Replace(s, n, Getattr(rp, "lname"), DOH_REPLACE_ID);
+ }
+ cp = nextSibling(cp);
+ rp = nextSibling(rp);
+ }
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ * int emit_action_code()
+ *
+ * Emits action code for a wrapper. Adds in exception handling code (%exception).
+ * eaction -> the action code to emit
+ * wrappercode -> the emitted code (output)
+ * ----------------------------------------------------------------------------- */
+int emit_action_code(Node *n, String *wrappercode, String *eaction) {
+ assert(Getattr(n, "wrap:name"));
+
+ /* Look for except feature (%exception) */
+ String *tm = GetFlagAttr(n, "feature:except");
+ if (tm)
+ tm = Copy(tm);
+ if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
+ if (Strstr(tm, "$")) {
+ Replaceall(tm, "$name", Getattr(n, "name"));
+ Replaceall(tm, "$symname", Getattr(n, "sym:name"));
+ Replaceall(tm, "$function", eaction); // deprecated
+ Replaceall(tm, "$action", eaction);
+ Replaceall(tm, "$wrapname", Getattr(n, "wrap:name"));
+ String *overloaded = Getattr(n, "sym:overloaded");
+ Replaceall(tm, "$overname", overloaded ? Char(Getattr(n, "sym:overname")) : "");
+
+ if (Strstr(tm, "$decl")) {
+ String *decl = Swig_name_decl(n);
+ Replaceall(tm, "$decl", decl);
+ Delete(decl);
+ }
+ if (Strstr(tm, "$fulldecl")) {
+ String *fulldecl = Swig_name_fulldecl(n);
+ Replaceall(tm, "$fulldecl", fulldecl);
+ Delete(fulldecl);
+ }
+ }
+ Printv(wrappercode, tm, "\n", NIL);
+ Delete(tm);
+ return 1;
+ } else {
+ Printv(wrappercode, eaction, "\n", NIL);
+ return 0;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * int emit_action()
+ *
+ * Emits the call to the wrapped function.
+ * Adds in exception specification exception handling and %exception code.
+ * ----------------------------------------------------------------------------- */
+String *emit_action(Node *n) {
+ String *actioncode = NewStringEmpty();
+ String *tm;
+ String *action;
+ String *wrap;
+ SwigType *rt;
+ ParmList *catchlist = Getattr(n, "catchlist");
+
+ /* Look for fragments */
+ {
+ String *fragment = Getattr(n, "feature:fragment");
+ if (fragment) {
+ char *c, *tok;
+ String *t = Copy(fragment);
+ c = Char(t);
+ tok = strtok(c, ",");
+ while (tok) {
+ String *fname = NewString(tok);
+ Setfile(fname, Getfile(n));
+ Setline(fname, Getline(n));
+ Swig_fragment_emit(fname);
+ Delete(fname);
+ tok = strtok(NULL, ",");
+ }
+ Delete(t);
+ }
+ }
+
+ /* Emit wrapper code (if any) */
+ wrap = Getattr(n, "wrap:code");
+ if (wrap && Swig_filebyname("header") != Getattr(n, "wrap:code:done")) {
+ File *f_code = Swig_filebyname("header");
+ if (f_code) {
+ Printv(f_code, wrap, NIL);
+ }
+ Setattr(n, "wrap:code:done", f_code);
+ }
+
+ action = Getattr(n, "feature:action");
+ if (!action)
+ action = Getattr(n, "wrap:action");
+ assert(action != 0);
+
+ /* Get the return type */
+ rt = Getattr(n, "type");
+
+ /* Emit contract code (if any) */
+ if (Swig_contract_mode_get()) {
+ /* Preassertion */
+ tm = Getattr(n, "contract:preassert");
+ if (Len(tm)) {
+ Printv(actioncode, tm, "\n", NIL);
+ }
+ }
+ /* Exception handling code */
+
+ /* saves action -> eaction for postcatching exception */
+ String *eaction = NewString("");
+
+ /* If we are in C++ mode and there is an exception specification. We're going to
+ enclose the block in a try block */
+ if (catchlist) {
+ Printf(eaction, "try {\n");
+ }
+
+ Printv(eaction, action, NIL);
+
+ if (catchlist) {
+ int unknown_catch = 0;
+ Printf(eaction, "}\n");
+ for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) {
+ String *em = Swig_typemap_lookup("throws", ep, "_e", 0);
+ if (em) {
+ SwigType *et = Getattr(ep, "type");
+ SwigType *etr = SwigType_typedef_resolve_all(et);
+ if (SwigType_isreference(etr) || SwigType_ispointer(etr) || SwigType_isarray(etr)) {
+ Printf(eaction, "catch(%s) {", SwigType_str(et, "_e"));
+ } else if (SwigType_isvarargs(etr)) {
+ Printf(eaction, "catch(...) {");
+ } else {
+ Printf(eaction, "catch(%s) {", SwigType_str(et, "&_e"));
+ }
+ Printv(eaction, em, "\n", NIL);
+ Printf(eaction, "}\n");
+ } else {
+ Swig_warning(WARN_TYPEMAP_THROW, Getfile(n), Getline(n), "No 'throws' typemap defined for exception type '%s'\n", SwigType_str(Getattr(ep, "type"), 0));
+ unknown_catch = 1;
+ }
+ }
+ if (unknown_catch) {
+ Printf(eaction, "catch(...) { throw; }\n");
+ }
+ }
+
+ /* Look for except typemap (Deprecated) */
+ tm = Swig_typemap_lookup("except", n, "result", 0);
+ if (tm) {
+ Setattr(n, "feature:except", tm);
+ tm = 0;
+ }
+
+ /* emit the except feature code */
+ emit_action_code(n, actioncode, eaction);
+
+ Delete(eaction);
+
+ /* Emit contract code (if any) */
+ if (Swig_contract_mode_get()) {
+ /* Postassertion */
+ tm = Getattr(n, "contract:postassert");
+ if (Len(tm)) {
+ Printv(actioncode, tm, "\n", NIL);
+ }
+ }
+
+ return actioncode;
+}
diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx
new file mode 100644
index 0000000..2520a07
--- /dev/null
+++ b/Source/Modules/guile.cxx
@@ -0,0 +1,1759 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * guile.cxx
+ *
+ * Guile language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_guile_cxx[] = "$Id: guile.cxx 11133 2009-02-20 07:52:24Z wsfulton $";
+
+#include "swigmod.h"
+
+#include <ctype.h>
+
+// Note string broken in half for compilers that can't handle long strings
+static const char *guile_usage = (char *) "\
+Guile Options (available with -guile)\n\
+ -prefix <name> - Use <name> as prefix [default \"gswig_\"]\n\
+ -package <name> - Set the path of the module to <name>\n\
+ (default NULL)\n\
+ -emitsetters - Emit procedures-with-setters for variables\n\
+ and structure slots.\n\
+ -onlysetters - Don't emit traditional getter and setter\n\
+ procedures for structure slots,\n\
+ only emit procedures-with-setters.\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\
+ -linkage <lstyle> - Use linkage protocol <lstyle> (default `simple')\n\
+ Use `module' for native Guile module linking\n\
+ (requires Guile >= 1.5.0). Use `passive' for\n\
+ passive linking (no C-level module-handling code),\n\
+ `ltdlmod' for Guile's old dynamic module\n\
+ convention (Guile <= 1.4), or `hobbit' for hobbit\n\
+ modules.\n\
+ -scmstub - Output Scheme file with module declaration and\n\
+ exports; only with `passive' and `simple' linkage\n\
+ -gh - Use the gh_ Guile API. (Guile <= 1.8) \n\
+ -scm - Use the scm Guile API. (Guile >= 1.6, default) \n\
+ -proxy - Export GOOPS class definitions\n\
+ -emitslotaccessors - Emit accessor methods for all GOOPS slots\n" "\
+ -primsuffix <suffix> - Name appended to primitive module when exporting\n\
+ GOOPS classes. (default = \"primitive\")\n\
+ -goopsprefix <prefix> - Prepend <prefix> to all goops identifiers\n\
+ -useclassprefix - Prepend the class name to all goops identifiers\n\
+ -exportprimitive - Add the (export ...) code from scmstub into the\n\
+ GOOPS file.\n";
+
+static File *f_begin = 0;
+static File *f_runtime = 0;
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+
+
+static char *prefix = (char *) "gswig_";
+static char *module = 0;
+static char *package = 0;
+static enum {
+ GUILE_LSTYLE_SIMPLE, // call `SWIG_init()'
+ GUILE_LSTYLE_PASSIVE, // passive linking (no module code)
+ GUILE_LSTYLE_MODULE, // native guile module linking (Guile >= 1.4.1)
+ GUILE_LSTYLE_LTDLMOD_1_4, // old (Guile <= 1.4) dynamic module convention
+ GUILE_LSTYLE_HOBBIT // use (hobbit4d link)
+} linkage = GUILE_LSTYLE_SIMPLE;
+
+static File *procdoc = 0;
+static bool scmstub = false;
+static String *scmtext;
+static bool goops = false;
+static String *goopstext;
+static String *goopscode;
+static String *goopsexport;
+
+static enum {
+ GUILE_1_4,
+ PLAIN,
+ TEXINFO
+} docformat = GUILE_1_4;
+
+static int emit_setters = 0;
+static int only_setters = 0;
+static int emit_slot_accessors = 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;
+
+static int use_scm_interface = 1;
+static int exporting_destructor = 0;
+static String *swigtype_ptr = 0;
+
+/* GOOPS stuff */
+static String *primsuffix = 0;
+static String *class_name = 0;
+static String *short_class_name = 0;
+static String *goops_class_methods;
+static int in_class = 0;
+static int have_constructor = 0;
+static int useclassprefix = 0; // -useclassprefix argument
+static String *goopsprefix = 0; // -goopsprefix argument
+static int primRenamer = 0; // if (use-modules ((...) :renamer ...) is exported to GOOPS file
+static int exportprimitive = 0; // -exportprimitive argument
+static String *memberfunction_name = 0;
+
+extern "C" {
+ static int has_classname(Node *class_node) {
+ return Getattr(class_node, "guile:goopsclassname") != NULL;
+ }
+}
+
+class GUILE:public Language {
+public:
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+ int i, orig_len;
+
+ SWIG_library_directory("guile");
+ SWIG_typemap_lang("guile");
+
+ // Look for certain command line options
+ for (i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-help") == 0) {
+ fputs(guile_usage, stdout);
+ SWIG_exit(EXIT_SUCCESS);
+ } else if (strcmp(argv[i], "-prefix") == 0) {
+ if (argv[i + 1]) {
+ prefix = new char[strlen(argv[i + 1]) + 2];
+ strcpy(prefix, argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-package") == 0) {
+ if (argv[i + 1]) {
+ package = new char[strlen(argv[i + 1]) + 2];
+ strcpy(package, argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-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], "w", SWIG_output_files());
+ if (!procdoc) {
+ FileErrorDisplay(argv[i + 1]);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-procdocformat") == 0) {
+ if (strcmp(argv[i + 1], "guile-1.4") == 0)
+ docformat = GUILE_1_4;
+ else if (strcmp(argv[i + 1], "plain") == 0)
+ docformat = PLAIN;
+ else if (strcmp(argv[i + 1], "texinfo") == 0)
+ docformat = TEXINFO;
+ else
+ Swig_arg_error();
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else if (strcmp(argv[i], "-emit-setters") == 0 || strcmp(argv[i], "-emitsetters") == 0) {
+ emit_setters = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-only-setters") == 0 || strcmp(argv[i], "-onlysetters") == 0) {
+ emit_setters = 1;
+ only_setters = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-emit-slot-accessors") == 0 || strcmp(argv[i], "-emitslotaccessors") == 0) {
+ emit_slot_accessors = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-scmstub") == 0) {
+ scmstub = true;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
+ goops = true;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-gh") == 0) {
+ use_scm_interface = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-scm") == 0) {
+ use_scm_interface = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-primsuffix") == 0) {
+ if (argv[i + 1]) {
+ primsuffix = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-goopsprefix") == 0) {
+ if (argv[i + 1]) {
+ goopsprefix = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-useclassprefix") == 0) {
+ useclassprefix = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-exportprimitive") == 0) {
+ exportprimitive = 1;
+ // should use Swig_warning() here?
+ Swig_mark_arg(i);
+ }
+ }
+ }
+
+ // set default value for primsuffix
+ if (primsuffix == NULL)
+ primsuffix = NewString("primitive");
+
+ //goops support can only be enabled if passive or module linkage is used
+ if (goops) {
+ if (linkage != GUILE_LSTYLE_PASSIVE && linkage != GUILE_LSTYLE_MODULE) {
+ Printf(stderr, "guile: GOOPS support requires passive or module linkage\n");
+ exit(1);
+ }
+ }
+
+ if (goops) {
+ // -proxy implies -emit-setters
+ emit_setters = 1;
+ }
+
+ if ((linkage == GUILE_LSTYLE_PASSIVE && scmstub) || linkage == GUILE_LSTYLE_MODULE)
+ primRenamer = 1;
+
+ if (exportprimitive && primRenamer) {
+ // should use Swig_warning() ?
+ Printf(stderr, "guile: Warning: -exportprimitive only makes sense with passive linkage without a scmstub.\n");
+ }
+ // Make sure `prefix' ends in an underscore
+
+ orig_len = strlen(prefix);
+ if (prefix[orig_len - 1] != '_') {
+ prefix[1 + orig_len] = 0;
+ prefix[orig_len] = '_';
+ }
+
+ /* Add a symbol for this module */
+ Preprocessor_define("SWIGGUILE 1", 0);
+ /* Read in default typemaps */
+ if (use_scm_interface)
+ SWIG_config_file("guile_scm.swg");
+ else
+ SWIG_config_file("guile_gh.swg");
+ allow_overloading();
+
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ 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("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+
+ scmtext = NewString("");
+ Swig_register_filebyname("scheme", scmtext);
+ exported_symbols = NewString("");
+ goopstext = NewString("");
+ Swig_register_filebyname("goops", goopstext);
+ goopscode = NewString("");
+ goopsexport = NewString("");
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGGUILE\n");
+
+ if (!use_scm_interface) {
+ if (SwigRuntime == 1)
+ Printf(f_runtime, "#define SWIG_GLOBAL\n");
+ if (SwigRuntime == 2)
+ Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
+ }
+
+ /* Write out directives and declarations */
+
+ module = Swig_copy_string(Char(Getattr(n, "name")));
+
+ 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, "#define SWIG_GUILE_INIT_STATIC extern\n");
+ break;
+ default:
+ /* Other linkage; we make the SWIG_init function static */
+ Printf(f_runtime, "#define SWIG_GUILE_INIT_STATIC static\n");
+ break;
+ }
+
+ if (CPlusPlus) {
+ Printf(f_runtime, "extern \"C\" {\n\n");
+ }
+ Printf(f_runtime, "SWIG_GUILE_INIT_STATIC void\nSWIG_init (void);\n");
+ if (CPlusPlus) {
+ Printf(f_runtime, "\n}\n");
+ }
+
+ Printf(f_runtime, "\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_init, "}\n\n");
+ Printf(f_init, "#ifdef __cplusplus\n}\n#endif\n");
+
+ String *module_name = NewString("");
+
+ if (!module)
+ Printv(module_name, "swig", NIL);
+ else {
+ if (package)
+ Printf(module_name, "%s/%s", package, module);
+ else
+ Printv(module_name, module, NIL);
+ }
+ emit_linkage(module_name);
+
+ Delete(module_name);
+
+ if (procdoc) {
+ Delete(procdoc);
+ procdoc = NULL;
+ }
+ Delete(goopscode);
+ Delete(goopsexport);
+ Delete(goopstext);
+
+ /* Close all of the files */
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+ return SWIG_OK;
+ }
+
+ void emit_linkage(String *module_name) {
+ String *module_func = NewString("");
+
+ if (CPlusPlus) {
+ Printf(f_init, "extern \"C\" {\n\n");
+ }
+
+ Printv(module_func, module_name, NIL);
+ Replaceall(module_func, "-", "_");
+
+ switch (linkage) {
+ case GUILE_LSTYLE_SIMPLE:
+ Printf(f_init, "\n/* Linkage: simple */\n");
+ break;
+ case GUILE_LSTYLE_PASSIVE:
+ Printf(f_init, "\n/* Linkage: passive */\n");
+ Replaceall(module_func, "/", "_");
+ Insert(module_func, 0, "scm_init_");
+ Append(module_func, "_module");
+
+ Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
+ Printf(f_init, " SWIG_init();\n");
+ Printf(f_init, " return SCM_UNSPECIFIED;\n");
+ Printf(f_init, "}\n");
+ break;
+ case GUILE_LSTYLE_LTDLMOD_1_4:
+ Printf(f_init, "\n/* Linkage: ltdlmod */\n");
+ Replaceall(module_func, "/", "_");
+ Insert(module_func, 0, "scm_init_");
+ Append(module_func, "_module");
+ Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
+ {
+ String *mod = NewString(module_name);
+ Replaceall(mod, "/", " ");
+ Printf(f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", mod);
+ Printf(f_init, " return SCM_UNSPECIFIED;\n");
+ Delete(mod);
+ }
+ Printf(f_init, "}\n");
+ break;
+ case GUILE_LSTYLE_MODULE:
+ Printf(f_init, "\n/* Linkage: module */\n");
+ Replaceall(module_func, "/", "_");
+ Insert(module_func, 0, "scm_init_");
+ Append(module_func, "_module");
+
+ Printf(f_init, "static void SWIG_init_helper(void *data)\n");
+ Printf(f_init, "{\n SWIG_init();\n");
+ if (Len(exported_symbols) > 0)
+ Printf(f_init, " scm_c_export(%sNULL);", exported_symbols);
+ Printf(f_init, "\n}\n\n");
+
+ Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
+ {
+ String *mod = NewString(module_name);
+ if (goops)
+ Printv(mod, "-", primsuffix, NIL);
+ Replaceall(mod, "/", " ");
+ Printf(f_init, " 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 *primitive_name = NewString(module_name);
+ if (goops)
+ Printv(primitive_name, "-", primsuffix, NIL);
+
+ String *mod = NewString(primitive_name);
+ Replaceall(mod, "/", " ");
+
+ String *fname = NewStringf("%s%s.scm",
+ SWIG_output_directory(),
+ primitive_name);
+ Delete(primitive_name);
+ File *scmstubfile = NewFile(fname, "w", SWIG_output_files());
+ if (!scmstubfile) {
+ FileErrorDisplay(fname);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(fname);
+
+ Swig_banner_target_lang(scmstubfile, ";;;");
+ Printf(scmstubfile, "\n");
+ if (linkage == GUILE_LSTYLE_SIMPLE || linkage == GUILE_LSTYLE_PASSIVE)
+ Printf(scmstubfile, "(define-module (%s))\n\n", mod);
+ Delete(mod);
+ Printf(scmstubfile, "%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(scmstubfile, "\n(export %s)\n", ex);
+ Delete(ex);
+ }
+ Delete(scmstubfile);
+ }
+
+ if (goops) {
+ String *mod = NewString(module_name);
+ Replaceall(mod, "/", " ");
+
+ String *fname = NewStringf("%s%s.scm", SWIG_output_directory(),
+ module_name);
+ File *goopsfile = NewFile(fname, "w", SWIG_output_files());
+ if (!goopsfile) {
+ FileErrorDisplay(fname);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(fname);
+ Swig_banner_target_lang(goopsfile, ";;;");
+ Printf(goopsfile, "\n");
+ Printf(goopsfile, "(define-module (%s))\n", mod);
+ Printf(goopsfile, "%s\n", goopstext);
+ Printf(goopsfile, "(use-modules (oop goops) (Swig common))\n");
+ if (primRenamer) {
+ Printf(goopsfile, "(use-modules ((%s-%s) :renamer (symbol-prefix-proc 'primitive:)))\n", mod, primsuffix);
+ }
+ Printf(goopsfile, "%s\n(export %s)", goopscode, goopsexport);
+ if (exportprimitive) {
+ String *ex = NewString(exported_symbols);
+ Replaceall(ex, ", ", "\n ");
+ Replaceall(ex, "\"", "");
+ Chop(ex);
+ Printf(goopsfile, "\n(export %s)", ex);
+ Delete(ex);
+ }
+ Delete(mod);
+ Delete(goopsfile);
+ }
+
+ Delete(module_func);
+ if (CPlusPlus) {
+ Printf(f_init, "\n}\n");
+ }
+ }
+
+ /* Return true iff T is a pointer type */
+
+ int is_a_pointer(SwigType *t) {
+ return SwigType_ispointer(SwigType_typedef_resolve_all(t));
+ }
+
+ /* Report an error handling the given type. */
+
+ void throw_unhandled_guile_type_error(SwigType *d) {
+ Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s.\n", SwigType_str(d, 0));
+ }
+
+ /* Write out procedure documentation */
+
+ void write_doc(const String *proc_name, const String *signature, const String *doc, const String *signature2 = NULL) {
+ switch (docformat) {
+ case GUILE_1_4:
+ Printv(procdoc, "\f\n", NIL);
+ Printv(procdoc, "(", signature, ")\n", NIL);
+ if (signature2)
+ Printv(procdoc, "(", signature2, ")\n", NIL);
+ Printv(procdoc, doc, "\n", NIL);
+ break;
+ case PLAIN:
+ Printv(procdoc, "\f", proc_name, "\n\n", NIL);
+ Printv(procdoc, "(", signature, ")\n", NIL);
+ if (signature2)
+ Printv(procdoc, "(", signature2, ")\n", NIL);
+ Printv(procdoc, doc, "\n\n", NIL);
+ break;
+ case TEXINFO:
+ Printv(procdoc, "\f", proc_name, "\n", NIL);
+ Printv(procdoc, "@deffn primitive ", signature, "\n", NIL);
+ if (signature2)
+ Printv(procdoc, "@deffnx primitive ", signature2, "\n", NIL);
+ Printv(procdoc, doc, "\n", NIL);
+ Printv(procdoc, "@end deffn\n\n", NIL);
+ break;
+ }
+ }
+
+ /* returns false if the typemap is an empty string */
+ bool handle_documentation_typemap(String *output,
+ const String *maybe_delimiter, Parm *p, const String *typemap, const String *default_doc, const String *name = NULL) {
+ 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);
+ }
+ const String *pn = (name == NULL) ? (const String *) Getattr(p, "name") : 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];
+ Wrapper *f = NewWrapper();;
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *signature = NewString("");
+ String *doc_body = NewString("");
+ String *returns = NewString("");
+ String *method_signature = NewString("");
+ String *primitive_args = NewString("");
+ Hash *scheme_arg_names = NewHash();
+ 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;
+ int scheme_argnum = 0;
+ bool any_specialized_arg = false;
+
+ // 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)) {
+ DelWrapper(f);
+ 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_parameter_variables(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", "SWIGUNUSED int gswig_list_p = 0");
+
+ /* Open prototype and signature */
+
+ Printv(f->def, "static SCM\n", wname, " (", NIL);
+ if (args_passed_as_array) {
+ Printv(f->def, "int argc, SCM *argv", NIL);
+ }
+ Printv(signature, proc_name, NIL);
+
+ /* Now write code to extract the parameters */
+
+ for (i = 0, p = l; i < numargs; i++) {
+
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ 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);
+ String *target = Getattr(p, "lname");
+
+ if (!args_passed_as_array) {
+ if (i != 0)
+ Printf(f->def, ", ");
+ Printf(f->def, "SCM s_%d", i);
+ }
+ if (opt_p) {
+ Printf(f->code, " if (%s != SCM_UNDEFINED) {\n", source);
+ }
+ if ((tm = Getattr(p, "tmap:in"))) {
+ Replaceall(tm, "$source", source);
+ Replaceall(tm, "$target", target);
+ Replaceall(tm, "$input", source);
+ Setattr(p, "emit:input", source);
+ Printv(f->code, tm, "\n", NIL);
+
+ SwigType *pb = SwigType_typedef_resolve_all(SwigType_base(pt));
+ SwigType *pn = Getattr(p, "name");
+ String *argname;
+ scheme_argnum++;
+ if (pn && !Getattr(scheme_arg_names, pn))
+ argname = pn;
+ else {
+ /* Anonymous arg or re-used argument name -- choose a name that cannot clash */
+ argname = NewStringf("%%arg%d", scheme_argnum);
+ }
+
+ if (procdoc) {
+ if (i == numreq) {
+ /* First optional argument */
+ Printf(signature, " #:optional");
+ }
+ /* Add to signature (arglist) */
+ handle_documentation_typemap(signature, " ", p, "tmap:in:arglist", "$name", argname);
+ /* Document the type of the arg in the documentation body */
+ handle_documentation_typemap(doc_body, ", ", p, "tmap:in:doc", "$NAME is of type <$type>", argname);
+ }
+
+ if (goops) {
+ if (i < numreq) {
+ if (strcmp("void", Char(pt)) != 0) {
+ Node *class_node = Swig_symbol_clookup_check(pb, Getattr(n, "sym:symtab"),
+ has_classname);
+ String *goopsclassname = (class_node == NULL) ? NULL : Getattr(class_node, "guile:goopsclassname");
+ /* do input conversion */
+ if (goopsclassname) {
+ Printv(method_signature, " (", argname, " ", goopsclassname, ")", NIL);
+ any_specialized_arg = true;
+ } else {
+ Printv(method_signature, " ", argname, NIL);
+ }
+ Printv(primitive_args, " ", argname, NIL);
+ Setattr(scheme_arg_names, argname, p);
+ }
+ }
+ }
+
+ if (!pn) {
+ Delete(argname);
+ }
+ p = Getattr(p, "tmap:in:next");
+ } else {
+ throw_unhandled_guile_type_error(pt);
+ p = nextSibling(p);
+ }
+ if (opt_p)
+ Printf(f->code, " }\n");
+ }
+ if (Len(doc_body) > 0)
+ Printf(doc_body, ".\n");
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ /* Pass output arguments back to the caller. */
+
+ /* Insert argument output code */
+ String *returns_argout = NewString("");
+ 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_argout, ", ", p, "tmap:argout:doc", "$NAME (of type $type)")) {
+ /* A documentation typemap that is not the empty string
+ indicates that a value is returned to Scheme. */
+ num_results++;
+ }
+ }
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:freearg"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(cleanup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ if (use_scm_interface && exporting_destructor) {
+ /* Mark the destructor's argument as destroyed. */
+ String *tm = NewString("SWIG_Guile_MarkPointerDestroyed($input);");
+ Replaceall(tm, "$input", Getattr(l, "emit:input"));
+ Printv(cleanup, tm, "\n", NIL);
+ Delete(tm);
+ }
+
+ /* 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
+ if (!use_scm_interface)
+ Printv(f->code, tab4, "gh_defer_ints();\n", NIL);
+
+ String *actioncode = emit_action(n);
+
+ if (!use_scm_interface)
+ Printv(actioncode, tab4, "gh_allow_ints();\n", NIL);
+
+ // Now have return value, figure out what to do with it.
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ Replaceall(tm, "$result", "gswig_result");
+ Replaceall(tm, "$target", "gswig_result");
+ Replaceall(tm, "$source", "result");
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "1");
+ else
+ Replaceall(tm, "$owner", "0");
+ Printv(f->code, tm, "\n", NIL);
+ } else {
+ throw_unhandled_guile_type_error(d);
+ }
+ emit_return_variable(n, d, f);
+
+ // Documentation
+ 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;
+ }
+ Append(returns, returns_argout);
+
+
+ // 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 (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("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("ret", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printv(f->code, tm, "\n", NIL);
+ }
+ // Wrap things up (in a manner of speaking)
+
+ if (beforereturn)
+ Printv(f->code, beforereturn, "\n", NIL);
+ Printv(f->code, "return gswig_result;\n", NIL);
+
+ /* Substitute the function name */
+ Replaceall(f->code, "$symname", iname);
+ // 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 */
+ if (use_scm_interface) {
+ Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, 0, 1, (swig_guile_proc) %s_rest);\n", proc_name, wname);
+ } else {
+ Printf(f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s_rest, 0, 0, 1);\n", proc_name, wname);
+ }
+ } 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 = ");
+ if (use_scm_interface) {
+ /* GOOPS support uses the MEMBER-set and MEMBER-get functions,
+ so ignore only_setters in this case. */
+ if (only_setters && !goops)
+ Printf(f_init, "scm_c_make_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
+ else
+ Printf(f_init, "scm_c_define_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
+ } else {
+ if (only_setters && !goops)
+ Printf(f_init, "scm_make_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
+ else
+ 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 */
+ if (use_scm_interface) {
+ Printf(f_init, "scm_c_define");
+ } else {
+ Printf(f_init, "gh_define");
+ }
+ Printf(f_init, "(\"%s\", " "scm_make_procedure_with_setter(getter, setter));\n", pws_name);
+ } else {
+ /* There was no setter, so make an alias to the getter */
+ if (use_scm_interface) {
+ Printf(f_init, "scm_c_define");
+ } else {
+ Printf(f_init, "gh_define");
+ }
+ Printf(f_init, "(\"%s\", getter);\n", pws_name);
+ }
+ Printf(exported_symbols, "\"%s\", ", pws_name);
+ free(pws_name);
+ }
+ } else {
+ /* Register the function */
+ if (use_scm_interface) {
+ if (exporting_destructor) {
+ Printf(f_init, "((swig_guile_clientdata *)(SWIGTYPE%s->clientdata))->destroy = (guile_destructor) %s;\n", swigtype_ptr, wname);
+ //Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname);
+ }
+ Printf(f_init, "scm_c_define_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname);
+ } else {
+ Printf(f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n", proc_name, wname, numreq, numargs - numreq);
+ }
+ }
+ } else { /* overloaded function; don't export the single methods */
+ if (!Getattr(n, "sym:nextSibling")) {
+ /* Emit overloading dispatch function */
+
+ int maxargs;
+ String *dispatch = Swig_overload_dispatch(n, "return %s(argc,argv);", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *df = NewWrapper();
+ String *dname = Swig_name_wrapper(iname);
+
+ Printv(df->def, "static SCM\n", dname, "(SCM rest)\n{\n", NIL);
+ Printf(df->code, "#define FUNC_NAME \"%s\"\n", proc_name);
+ 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);
+ Printf(df->code, "#undef FUNC_NAME\n");
+ Printv(df->code, "}\n", NIL);
+ Wrapper_print(df, f_wrappers);
+ if (use_scm_interface) {
+ Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, 0, 1, (swig_guile_proc) %s);\n", proc_name, dname);
+ } else {
+ 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 (!in_class || memberfunction_name) {
+ // export wrapper into goops file
+ String *method_def = NewString("");
+ String *goops_name;
+ if (in_class)
+ goops_name = NewString(memberfunction_name);
+ else
+ goops_name = goopsNameMapping(proc_name, (char *) "");
+ String *primitive_name = NewString("");
+ if (primRenamer)
+ Printv(primitive_name, "primitive:", proc_name, NIL);
+ else
+ Printv(primitive_name, proc_name, NIL);
+ Replaceall(method_signature, "_", "-");
+ Replaceall(primitive_args, "_", "-");
+ if (!any_specialized_arg) {
+ /* If there would not be any specialized argument in
+ the method declaration, we simply re-export the
+ function. This is a performance optimization. */
+ Printv(method_def, "(define ", goops_name, " ", primitive_name, ")\n", NIL);
+ } else if (numreq == numargs) {
+ Printv(method_def, "(define-method (", goops_name, method_signature, ")\n", NIL);
+ Printv(method_def, " (", primitive_name, primitive_args, "))\n", NIL);
+ } else {
+ /* Handle optional args. For the rest argument, use a name
+ that cannot clash. */
+ Printv(method_def, "(define-method (", goops_name, method_signature, " . %args)\n", NIL);
+ Printv(method_def, " (apply ", primitive_name, primitive_args, " %args))\n", NIL);
+ }
+ if (in_class) {
+ /* Defer method definition till end of class definition. */
+ Printv(goops_class_methods, method_def, NIL);
+ } else {
+ Printv(goopscode, method_def, NIL);
+ }
+ Printf(goopsexport, "%s ", goops_name);
+ Delete(primitive_name);
+ Delete(goops_name);
+ Delete(method_def);
+ }
+
+ if (procdoc) {
+ String *returns_text = NewString("");
+ if (num_results == 0)
+ Printv(returns_text, return_nothing_doc, NIL);
+ else if (num_results == 1)
+ Printv(returns_text, return_one_doc, NIL);
+ else
+ Printv(returns_text, return_multi_doc, NIL);
+ /* Substitute documentation variables */
+ static const char *numbers[] = { "zero", "one", "two", "three",
+ "four", "five", "six", "seven",
+ "eight", "nine", "ten", "eleven",
+ "twelve"
+ };
+ if (num_results <= 12)
+ Replaceall(returns_text, "$num_values", numbers[num_results]);
+ else {
+ String *num_results_str = NewStringf("%d", num_results);
+ Replaceall(returns_text, "$num_values", num_results_str);
+ Delete(num_results_str);
+ }
+ Replaceall(returns_text, "$values", returns);
+ Printf(doc_body, "\n%s", returns_text);
+ write_doc(proc_name, signature, doc_body);
+ Delete(returns_text);
+ }
+
+ Delete(proc_name);
+ Delete(outarg);
+ Delete(cleanup);
+ Delete(signature);
+ Delete(method_signature);
+ Delete(primitive_args);
+ Delete(doc_body);
+ Delete(returns_argout);
+ Delete(returns);
+ Delete(tmp);
+ Delete(scheme_arg_names);
+ 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;
+ Wrapper *f;
+ String *tm;
+
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+
+ f = NewWrapper();
+ // evaluation function names
+
+ String *var_name = Swig_name_wrapper(iname);
+
+ // Build the name for scheme.
+ proc_name = NewString(iname);
+ Replaceall(proc_name, "_", "-");
+ Setattr(n, "wrap:name", 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 (!GetFlag(n, "feature:immutable")) {
+ /* Check for a setting of the variable value */
+ Printf(f->code, "if (s_0 != SCM_UNDEFINED) {\n");
+ if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
+ Replaceall(tm, "$source", "s_0");
+ Replaceall(tm, "$input", "s_0");
+ Replaceall(tm, "$target", name);
+ /* Printv(f->code,tm,"\n",NIL); */
+ emit_action_code(n, f->code, tm);
+ } 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("varout", n, name, 0))) {
+ Replaceall(tm, "$source", name);
+ Replaceall(tm, "$target", "gswig_result");
+ Replaceall(tm, "$result", "gswig_result");
+ /* Printv(f->code,tm,"\n",NIL); */
+ emit_action_code(n, f->code, tm);
+ } 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 || GetFlag(n, "feature:immutable")) {
+ /* Read-only variables become a simple procedure returning the
+ value; read-write variables become a simple procedure with
+ an optional argument. */
+ if (use_scm_interface) {
+
+ if (!goops && GetFlag(n, "feature:constasvar")) {
+ /* need to export this function as a variable instead of a procedure */
+ if (scmstub) {
+ /* export the function in the wrapper, and (set!) it in scmstub */
+ Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, !GetFlag(n, "feature:immutable"), var_name);
+ Printf(scmtext, "(set! %s (%s))\n", proc_name, proc_name);
+ } else {
+ /* export the variable directly */
+ Printf(f_init, "scm_c_define(\"%s\", %s(SCM_UNDEFINED));\n", proc_name, var_name);
+ }
+
+ } else {
+ /* Export the function as normal */
+ Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, !GetFlag(n, "feature:immutable"), var_name);
+ }
+
+ } else {
+ Printf(f_init, "\t gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, %d, 0);\n", proc_name, var_name, !GetFlag(n, "feature:immutable"));
+ }
+ } else {
+ /* Read/write variables become a procedure with setter. */
+ if (use_scm_interface) {
+ Printf(f_init, "{ SCM p = scm_c_define_gsubr(\"%s\", 0, 1, 0, (swig_guile_proc) %s);\n", proc_name, var_name);
+ Printf(f_init, "scm_c_define");
+ } else {
+ 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, "gh_define");
+ }
+ Printf(f_init, "(\"%s\", " "scm_make_procedure_with_setter(p, p)); }\n", proc_name);
+ }
+ Printf(exported_symbols, "\"%s\", ", proc_name);
+
+ // export wrapper into goops file
+ if (!in_class) { // only if the variable is not part of a class
+ String *class_name = SwigType_typedef_resolve_all(SwigType_base(t));
+ String *goops_name = goopsNameMapping(proc_name, (char *) "");
+ String *primitive_name = NewString("");
+ if (primRenamer)
+ Printv(primitive_name, "primitive:", NIL);
+ Printv(primitive_name, proc_name, NIL);
+ /* Simply re-export the procedure */
+ if ((!emit_setters || GetFlag(n, "feature:immutable"))
+ && GetFlag(n, "feature:constasvar")) {
+ Printv(goopscode, "(define ", goops_name, " (", primitive_name, "))\n", NIL);
+ } else {
+ Printv(goopscode, "(define ", goops_name, " ", primitive_name, ")\n", NIL);
+ }
+ Printf(goopsexport, "%s ", goops_name);
+ Delete(primitive_name);
+ Delete(class_name);
+ Delete(goops_name);
+ }
+
+ if (procdoc) {
+ /* Compute documentation */
+ String *signature = NewString("");
+ String *signature2 = NULL;
+ String *doc = NewString("");
+
+ if (GetFlag(n, "feature:immutable")) {
+ Printv(signature, proc_name, NIL);
+ if (GetFlag(n, "feature:constasvar")) {
+ Printv(doc, "Is constant ", NIL);
+ } else {
+ Printv(doc, "Returns constant ", NIL);
+ }
+ if ((tm = Getattr(n, "tmap:varout:doc"))) {
+ Printv(doc, tm, NIL);
+ } else {
+ String *s = SwigType_str(t, 0);
+ Chop(s);
+ Printf(doc, "<%s>", s);
+ Delete(s);
+ }
+ } else if (emit_setters) {
+ Printv(signature, proc_name, NIL);
+ signature2 = NewString("");
+ Printv(signature2, "set! (", proc_name, ") ", NIL);
+ handle_documentation_typemap(signature2, NIL, n, "tmap:varin:arglist", "new-value");
+ Printv(doc, "Get or set the value of the C variable, \n", NIL);
+ Printv(doc, "which is of type ", NIL);
+ handle_documentation_typemap(doc, NIL, n, "tmap:varout:doc", "$1_type");
+ Printv(doc, ".");
+ } else {
+ Printv(signature, proc_name, " #:optional ", NIL);
+ if ((tm = Getattr(n, "tmap:varin:doc"))) {
+ Printv(signature, tm, NIL);
+ } else {
+ String *s = SwigType_str(t, 0);
+ Chop(s);
+ Printf(signature, "new-value <%s>", s);
+ Delete(s);
+ }
+
+ Printv(doc, "If NEW-VALUE is provided, " "set C variable to this value.\n", NIL);
+ Printv(doc, "Returns variable value ", NIL);
+ if ((tm = Getattr(n, "tmap:varout:doc"))) {
+ Printv(doc, tm, NIL);
+ } else {
+ String *s = SwigType_str(t, 0);
+ Chop(s);
+ Printf(doc, "<%s>", s);
+ Delete(s);
+ }
+ }
+ write_doc(proc_name, signature, doc, signature2);
+ Delete(signature);
+ if (signature2)
+ Delete(signature2);
+ Delete(doc);
+ }
+
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0));
+ }
+ Delete(var_name);
+ Delete(proc_name);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ *
+ * We create a read-only variable.
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ char *name = GetChar(n, "name");
+ char *iname = GetChar(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ String *value = Getattr(n, "value");
+ int constasvar = GetFlag(n, "feature:constasvar");
+
+
+ String *proc_name;
+ String *var_name;
+ String *rvalue;
+ Wrapper *f;
+ SwigType *nctype;
+ String *tm;
+
+ f = NewWrapper();
+
+ // Make a static variable;
+ var_name = NewStringf("%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");
+ Delete(var_name);
+ DelWrapper(f);
+ 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("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);
+ SetFlag(n, "feature:immutable");
+ if (constasvar) {
+ SetFlag(n, "feature:constasvar");
+ }
+ variableWrapper(n);
+ Delete(n);
+ }
+ Delete(var_name);
+ Delete(nctype);
+ Delete(proc_name);
+ Delete(rvalue);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+ virtual int classDeclaration(Node *n) {
+ String *class_name = NewStringf("<%s>", Getattr(n, "sym:name"));
+ Setattr(n, "guile:goopsclassname", class_name);
+ return Language::classDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+ virtual int classHandler(Node *n) {
+ /* Create new strings for building up a wrapper function */
+ have_constructor = 0;
+
+ class_name = NewString("");
+ short_class_name = NewString("");
+ Printv(class_name, "<", Getattr(n, "sym:name"), ">", NIL);
+ Printv(short_class_name, Getattr(n, "sym:name"), NIL);
+ Replaceall(class_name, "_", "-");
+ Replaceall(short_class_name, "_", "-");
+
+ if (!addSymbol(class_name, n))
+ return SWIG_ERROR;
+
+ /* Handle inheritance */
+ String *base_class = NewString("<");
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator i = First(baselist);
+ while (i.item) {
+ Printv(base_class, Getattr(i.item, "sym:name"), NIL);
+ i = Next(i);
+ if (i.item) {
+ Printf(base_class, "> <");
+ }
+ }
+ }
+ Printf(base_class, ">");
+ Replaceall(base_class, "_", "-");
+
+ Printv(goopscode, "(define-class ", class_name, " ", NIL);
+ Printf(goopsexport, "%s ", class_name);
+
+ if (Len(base_class) > 2) {
+ Printv(goopscode, "(", base_class, ")\n", NIL);
+ } else {
+ Printv(goopscode, "(<swig>)\n", NIL);
+ }
+ SwigType *ct = NewStringf("p.%s", Getattr(n, "name"));
+ swigtype_ptr = SwigType_manglestr(ct);
+
+ String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name"));
+ /* Export clientdata structure */
+ if (use_scm_interface) {
+ Printf(f_runtime, "static swig_guile_clientdata _swig_guile_clientdata%s = { NULL, SCM_EOL };\n", mangled_classname);
+
+ Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", swigtype_ptr, ", (void *) &_swig_guile_clientdata", mangled_classname, ");\n", NIL);
+ SwigType_remember(ct);
+ }
+ Delete(ct);
+
+ /* Emit all of the members */
+ goops_class_methods = NewString("");
+
+ in_class = 1;
+ Language::classHandler(n);
+ in_class = 0;
+
+ Printv(goopscode, " #:metaclass <swig-metaclass>\n", NIL);
+
+ if (have_constructor)
+ Printv(goopscode, " #:new-function ", primRenamer ? "primitive:" : "", "new-", short_class_name, "\n", NIL);
+
+ Printf(goopscode, ")\n%s\n", goops_class_methods);
+ Delete(goops_class_methods);
+ goops_class_methods = 0;
+
+
+ /* export class initialization function */
+ if (goops) {
+ /* export the wrapper function */
+ String *funcName = NewString(mangled_classname);
+ Printf(funcName, "_swig_guile_setgoopsclass");
+ String *guileFuncName = NewString(funcName);
+ Replaceall(guileFuncName, "_", "-");
+
+ Printv(f_wrappers, "static SCM ", funcName, "(SCM cl) \n", NIL);
+ Printf(f_wrappers, "#define FUNC_NAME %s\n{\n", guileFuncName);
+ Printv(f_wrappers, " ((swig_guile_clientdata *)(SWIGTYPE", swigtype_ptr, "->clientdata))->goops_class = cl;\n", NIL);
+ Printf(f_wrappers, " return SCM_UNSPECIFIED;\n");
+ Printf(f_wrappers, "}\n#undef FUNC_NAME\n\n");
+
+ Printf(f_init, "scm_c_define_gsubr(\"%s\", 1, 0, 0, (swig_guile_proc) %s);\n", guileFuncName, funcName);
+ Printf(exported_symbols, "\"%s\", ", guileFuncName);
+
+ /* export the call to the wrapper function */
+ Printf(goopscode, "(%s%s %s)\n\n", primRenamer ? "primitive:" : "", guileFuncName, class_name);
+
+ Delete(guileFuncName);
+ Delete(funcName);
+ }
+
+ Delete(mangled_classname);
+
+ Delete(swigtype_ptr);
+ swigtype_ptr = 0;
+
+ Delete(class_name);
+ Delete(short_class_name);
+ class_name = 0;
+ short_class_name = 0;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
+ int memberfunctionHandler(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+ String *proc = NewString(iname);
+ Replaceall(proc, "_", "-");
+
+ memberfunction_name = goopsNameMapping(proc, short_class_name);
+ Language::memberfunctionHandler(n);
+ Delete(memberfunction_name);
+ memberfunction_name = NULL;
+ Delete(proc);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+ int membervariableHandler(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+
+ if (emit_setters) {
+ struct_member = 1;
+ Printf(f_init, "{\n");
+ }
+
+ Language::membervariableHandler(n);
+
+ if (emit_setters) {
+ Printf(f_init, "}\n");
+ struct_member = 0;
+ }
+
+ String *proc = NewString(iname);
+ Replaceall(proc, "_", "-");
+ String *goops_name = goopsNameMapping(proc, short_class_name);
+
+ /* The slot name is never qualified with the class,
+ even if useclassprefix is true. */
+ Printv(goopscode, " (", proc, " #:allocation #:virtual", NIL);
+ /* GOOPS (at least in Guile 1.6.3) only accepts closures, not
+ primitive procedures for slot-ref and slot-set. */
+ Printv(goopscode, "\n #:slot-ref (lambda (obj) (", primRenamer ? "primitive:" : "", short_class_name, "-", proc, "-get", " obj))", NIL);
+ if (!GetFlag(n, "feature:immutable")) {
+ Printv(goopscode, "\n #:slot-set! (lambda (obj value) (", primRenamer ? "primitive:" : "", short_class_name, "-", proc, "-set", " obj value))", NIL);
+ } else {
+ Printf(goopscode, "\n #:slot-set! (lambda (obj value) (error \"Immutable slot\"))");
+ }
+ if (emit_slot_accessors) {
+ if (GetFlag(n, "feature:immutable")) {
+ Printv(goopscode, "\n #:getter ", goops_name, NIL);
+ } else {
+ Printv(goopscode, "\n #:accessor ", goops_name, NIL);
+ }
+ Printf(goopsexport, "%s ", goops_name);
+ }
+ Printv(goopscode, ")\n", NIL);
+ Delete(proc);
+ Delete(goops_name);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorHandler()
+ * ------------------------------------------------------------ */
+ int constructorHandler(Node *n) {
+ Language::constructorHandler(n);
+ have_constructor = 1;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+ virtual int destructorHandler(Node *n) {
+ exporting_destructor = true;
+ Language::destructorHandler(n);
+ exporting_destructor = false;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * pragmaDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int pragmaDirective(Node *n) {
+ if (!ImportMode) {
+ String *lang = Getattr(n, "lang");
+ String *cmd = Getattr(n, "name");
+ String *value = Getattr(n, "value");
+
+# define store_pragma(PRAGMANAME) \
+ if (Strcmp(cmd, #PRAGMANAME) == 0) { \
+ if (PRAGMANAME) Delete(PRAGMANAME); \
+ PRAGMANAME = value ? NewString(value) : NULL; \
+ }
+
+ if (Strcmp(lang, "guile") == 0) {
+ store_pragma(beforereturn)
+ store_pragma(return_nothing_doc)
+ store_pragma(return_one_doc)
+ store_pragma(return_multi_doc);
+# undef store_pragma
+ }
+ }
+ return Language::pragmaDirective(n);
+ }
+
+
+ /* ------------------------------------------------------------
+ * goopsNameMapping()
+ * Maps the identifier from C++ to the GOOPS based * on command
+ * line parameters and such.
+ * If class_name = "" that means the mapping is for a function or
+ * variable not attached to any class.
+ * ------------------------------------------------------------ */
+ String *goopsNameMapping(String *name, const_String_or_char_ptr class_name) {
+ String *n = NewString("");
+
+ if (Strcmp(class_name, "") == 0) {
+ // not part of a class, so no class name to prefix
+ if (goopsprefix) {
+ Printf(n, "%s%s", goopsprefix, name);
+ } else {
+ Printf(n, "%s", name);
+ }
+ } else {
+ if (useclassprefix) {
+ Printf(n, "%s-%s", class_name, name);
+ } else {
+ if (goopsprefix) {
+ Printf(n, "%s%s", goopsprefix, name);
+ } else {
+ Printf(n, "%s", name);
+ }
+ }
+ }
+ return n;
+ }
+
+
+ /* ------------------------------------------------------------
+ * validIdentifier()
+ * ------------------------------------------------------------ */
+
+ virtual int validIdentifier(String *s) {
+ char *c = Char(s);
+ /* Check whether we have an R5RS identifier. Guile supports a
+ superset of R5RS identifiers, but it's probably a bad idea to use
+ those. */
+ /* <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;
+ }
+
+ String *runtimeCode() {
+ String *s;
+ if (use_scm_interface) {
+ s = Swig_include_sys("guile_scm_run.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'guile_scm_run.swg");
+ s = NewString("");
+ }
+ } else {
+ s = Swig_include_sys("guile_gh_run.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'guile_gh_run.swg");
+ s = NewString("");
+ }
+ }
+ return s;
+ }
+
+ String *defaultExternalRuntimeFilename() {
+ if (use_scm_interface) {
+ return NewString("swigguilerun.h");
+ } else {
+ return NewString("swigguileghrun.h");
+ }
+ }
+};
+
+/* -----------------------------------------------------------------------------
+ * swig_guile() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_guile() {
+ return new GUILE();
+}
+extern "C" Language *swig_guile(void) {
+ return new_swig_guile();
+}
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
new file mode 100644
index 0000000..469f899
--- /dev/null
+++ b/Source/Modules/java.cxx
@@ -0,0 +1,4166 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * java.cxx
+ *
+ * Java language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_java_cxx[] = "$Id: java.cxx 11584 2009-08-16 00:04:29Z wsfulton $";
+
+#include "swigmod.h"
+#include <limits.h> // for INT_MAX
+#include "cparse.h"
+#include <ctype.h>
+
+/* Hash type used for upcalls from C/C++ */
+typedef DOH UpcallData;
+
+class JAVA:public Language {
+ static const char *usage;
+ const String *empty_string;
+ const String *public_string;
+ const String *protected_string;
+
+ Hash *swig_types_hash;
+ File *f_begin;
+ File *f_runtime;
+ File *f_runtime_h;
+ File *f_header;
+ File *f_wrappers;
+ File *f_init;
+ File *f_directors;
+ File *f_directors_h;
+ List *filenames_list;
+
+ bool proxy_flag; // Flag for generating proxy classes
+ bool nopgcpp_flag; // Flag for suppressing the premature garbage collection prevention parameter
+ 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
+ bool old_variable_names; // Flag for old style variable names in the intermediary class
+ bool member_func_flag; // flag set when wrapping a member function
+
+ String *imclass_name; // intermediary class name
+ String *module_class_name; // module class name
+ String *imclass_class_code; // intermediary class code
+ String *proxy_class_def;
+ String *proxy_class_code;
+ String *module_class_code;
+ String *proxy_class_name;
+ String *variable_name; //Name of a variable being wrapped
+ String *proxy_class_constants_code;
+ String *module_class_constants_code;
+ String *enum_code;
+ String *package; // Optional package name
+ String *jnipackage; // Package name used in the JNI code
+ String *package_path; // Package name used internally by JNI (slashes)
+ String *imclass_imports; //intermediary class imports from %pragma
+ String *module_imports; //module imports from %pragma
+ String *imclass_baseclass; //inheritance for intermediary class class from %pragma
+ String *module_baseclass; //inheritance for module class from %pragma
+ String *imclass_interfaces; //interfaces for intermediary class class from %pragma
+ String *module_interfaces; //interfaces for module class from %pragma
+ String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma
+ String *module_class_modifiers; //class modifiers for module class overriden by %pragma
+ String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
+ String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
+ String *imclass_directors; // Intermediate class director code
+ String *destructor_call; //C++ destructor call if any
+ String *destructor_throws_clause; //C++ destructor throws clause if any
+
+ // Director method stuff:
+ List *dmethods_seq;
+ Hash *dmethods_table;
+ int n_dmethods;
+ int n_directors;
+ int first_class_dmethod;
+ int curr_class_dmethod;
+
+ enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
+
+ static Parm *NewParmFromNode(SwigType *type, const_String_or_char_ptr name, Node *n) {
+ Parm *p = NewParm(type, name);
+ Setfile(p, Getfile(n));
+ Setline(p, Getline(n));
+ return p;
+ }
+
+public:
+
+ /* -----------------------------------------------------------------------------
+ * JAVA()
+ * ----------------------------------------------------------------------------- */
+
+ JAVA():empty_string(NewString("")),
+ public_string(NewString("public")),
+ protected_string(NewString("protected")),
+ swig_types_hash(NULL),
+ f_begin(NULL),
+ f_runtime(NULL),
+ f_runtime_h(NULL),
+ f_header(NULL),
+ f_wrappers(NULL),
+ f_init(NULL),
+ f_directors(NULL),
+ f_directors_h(NULL),
+ filenames_list(NULL),
+ proxy_flag(true),
+ nopgcpp_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),
+ old_variable_names(false),
+ member_func_flag(false),
+ imclass_name(NULL),
+ module_class_name(NULL),
+ imclass_class_code(NULL),
+ proxy_class_def(NULL),
+ proxy_class_code(NULL),
+ module_class_code(NULL),
+ proxy_class_name(NULL),
+ variable_name(NULL),
+ proxy_class_constants_code(NULL),
+ module_class_constants_code(NULL),
+ package(NULL),
+ jnipackage(NULL),
+ package_path(NULL),
+ imclass_imports(NULL),
+ module_imports(NULL),
+ imclass_baseclass(NULL),
+ module_baseclass(NULL),
+ imclass_interfaces(NULL),
+ module_interfaces(NULL),
+ imclass_class_modifiers(NULL),
+ module_class_modifiers(NULL),
+ upcasts_code(NULL),
+ imclass_cppcasts_code(NULL),
+ imclass_directors(NULL),
+ destructor_call(NULL),
+ destructor_throws_clause(NULL),
+ dmethods_seq(NULL),
+ dmethods_table(NULL),
+ n_dmethods(0),
+ n_directors(0) {
+ /* for now, multiple inheritance in directors is disabled, this
+ should be easy to implement though */
+ director_multiple_inheritance = 0;
+ director_language = 1;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getProxyName()
+ *
+ * Test to see if a type corresponds to something wrapped with a proxy class
+ * Return NULL if not otherwise the proxy class name
+ * ----------------------------------------------------------------------------- */
+
+ String *getProxyName(SwigType *t) {
+ if (proxy_flag) {
+ Node *n = classLookup(t);
+ if (n) {
+ return Getattr(n, "sym:name");
+ }
+ }
+ return NULL;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * makeValidJniName()
+ * ----------------------------------------------------------------------------- */
+
+ String *makeValidJniName(const String *name) {
+ String *valid_jni_name = NewString(name);
+ Replaceall(valid_jni_name, "_", "_1");
+ return valid_jni_name;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * directorClassName()
+ * ----------------------------------------------------------------------------- */
+
+ String *directorClassName(Node *n) {
+ String *dirclassname;
+ const char *attrib = "director:classname";
+
+ if (!(dirclassname = Getattr(n, attrib))) {
+ String *classname = Getattr(n, "sym:name");
+
+ dirclassname = NewStringf("SwigDirector_%s", classname);
+ Setattr(n, attrib, dirclassname);
+ }
+
+ return dirclassname;
+ }
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+
+ SWIG_library_directory("java");
+
+ // Look for certain command line options
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-package") == 0) {
+ if (argv[i + 1]) {
+ package = NewString("");
+ Printf(package, argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
+ Printf(stderr, "Deprecated command line option: %s. Proxy classes are now generated by default.\n", argv[i]);
+ Swig_mark_arg(i);
+ proxy_flag = true;
+ } else if ((strcmp(argv[i], "-noproxy") == 0)) {
+ Swig_mark_arg(i);
+ proxy_flag = false;
+ } else if (strcmp(argv[i], "-nopgcpp") == 0) {
+ Swig_mark_arg(i);
+ nopgcpp_flag = true;
+ } else if (strcmp(argv[i], "-oldvarnames") == 0) {
+ Swig_mark_arg(i);
+ old_variable_names = true;
+ } 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 typemap 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(stdout, "%s\n", usage);
+ }
+ }
+ }
+
+ // Add a symbol to the parser for conditional compilation
+ Preprocessor_define("SWIGJAVA 1", 0);
+
+ // Add typemap definitions
+ SWIG_typemap_lang("java");
+ SWIG_config_file("java.swg");
+
+ allow_overloading();
+ }
+
+ /* ---------------------------------------------------------------------
+ * top()
+ * --------------------------------------------------------------------- */
+
+ virtual int top(Node *n) {
+
+ // Get any options set in the module directive
+ Node *optionsnode = Getattr(Getattr(n, "module"), "options");
+
+ if (optionsnode) {
+ if (Getattr(optionsnode, "jniclassname"))
+ imclass_name = Copy(Getattr(optionsnode, "jniclassname"));
+ /* check if directors are enabled for this module. note: this
+ * is a "master" switch, without which no director code will be
+ * emitted. %feature("director") statements are also required
+ * to enable directors for individual classes or methods.
+ *
+ * use %module(directors="1") modulename at the start of the
+ * interface file to enable director generation.
+ */
+ if (Getattr(optionsnode, "directors")) {
+ allow_directors();
+ }
+ if (Getattr(optionsnode, "dirprot")) {
+ allow_dirprot();
+ }
+ allow_allprotected(GetFlag(optionsnode, "allprotected"));
+ }
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+ String *outfile_h = Getattr(n, "outfile_h");
+
+ if (!outfile) {
+ Printf(stderr, "Unable to determine outfile\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ if (directorsEnabled()) {
+ if (!outfile_h) {
+ Printf(stderr, "Unable to determine outfile_h\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
+ if (!f_runtime_h) {
+ FileErrorDisplay(outfile_h);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+ f_directors_h = NewString("");
+ f_directors = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("begin", f_begin);
+ 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_register_filebyname("director", f_directors);
+ Swig_register_filebyname("director_h", f_directors_h);
+
+ swig_types_hash = NewHash();
+ filenames_list = NewList();
+
+ // Make the intermediary class and module class names. The intermediary class name can be set in the module directive.
+ if (!imclass_name) {
+ imclass_name = NewStringf("%sJNI", Getattr(n, "name"));
+ module_class_name = Copy(Getattr(n, "name"));
+ } else {
+ // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution
+ if (Cmp(imclass_name, Getattr(n, "name")) == 0)
+ module_class_name = NewStringf("%sModule", Getattr(n, "name"));
+ else
+ module_class_name = Copy(Getattr(n, "name"));
+ }
+
+ imclass_class_code = NewString("");
+ proxy_class_def = NewString("");
+ proxy_class_code = NewString("");
+ module_class_constants_code = NewString("");
+ imclass_baseclass = NewString("");
+ imclass_interfaces = NewString("");
+ imclass_class_modifiers = NewString("");
+ module_class_code = NewString("");
+ module_baseclass = NewString("");
+ module_interfaces = NewString("");
+ module_imports = NewString("");
+ module_class_modifiers = NewString("");
+ imclass_imports = NewString("");
+ imclass_cppcasts_code = NewString("");
+ imclass_directors = NewString("");
+ upcasts_code = NewString("");
+ dmethods_seq = NewList();
+ dmethods_table = NewHash();
+ n_dmethods = 0;
+ n_directors = 0;
+ if (!package)
+ package = NewString("");
+ jnipackage = NewString("");
+ package_path = NewString("");
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n#define SWIGJAVA\n");
+
+ if (directorsEnabled()) {
+ Printf(f_runtime, "#define SWIG_DIRECTORS\n");
+
+ /* Emit initial director header and director code: */
+ Swig_banner(f_directors_h);
+ Printf(f_directors_h, "\n");
+ Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_class_name);
+ Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_class_name);
+
+ Printf(f_directors, "\n\n");
+ Printf(f_directors, "/* ---------------------------------------------------\n");
+ Printf(f_directors, " * C++ director class methods\n");
+ Printf(f_directors, " * --------------------------------------------------- */\n\n");
+ if (outfile_h)
+ Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h));
+ }
+
+ Printf(f_runtime, "\n");
+
+ String *wrapper_name = NewString("");
+
+ if (Len(package)) {
+ String *jniname = makeValidJniName(package);
+ Printv(jnipackage, jniname, NIL);
+ Delete(jniname);
+ Replaceall(jnipackage, ".", "_");
+ Append(jnipackage, "_");
+ Printv(package_path, package, NIL);
+ Replaceall(package_path, ".", "/");
+ }
+ String *jniname = makeValidJniName(imclass_name);
+ Printf(wrapper_name, "Java_%s%s_%%f", Char(jnipackage), jniname);
+ Delete(jniname);
+
+ Swig_name_register((char *) "wrapper", Char(wrapper_name));
+ if (old_variable_names) {
+ Swig_name_register((char *) "set", (char *) "set_%v");
+ Swig_name_register((char *) "get", (char *) "get_%v");
+ }
+
+ Delete(wrapper_name);
+
+ Printf(f_wrappers, "\n#ifdef __cplusplus\n");
+ Printf(f_wrappers, "extern \"C\" {\n");
+ Printf(f_wrappers, "#endif\n\n");
+
+ /* Emit code */
+ Language::top(n);
+
+ if (directorsEnabled()) {
+ // Insert director runtime into the f_runtime file (make it occur before %header section)
+ Swig_insert_file("director.swg", f_runtime);
+ }
+ // Generate the intermediary class
+ {
+ String *filen = NewStringf("%s%s.java", SWIG_output_directory(), imclass_name);
+ File *f_im = NewFile(filen, "w", SWIG_output_files());
+ if (!f_im) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the intermediary class file
+ emitBanner(f_im);
+
+ if (Len(package) > 0)
+ Printf(f_im, "package %s;\n", package);
+
+ if (imclass_imports)
+ Printf(f_im, "%s\n", imclass_imports);
+
+ if (Len(imclass_class_modifiers) > 0)
+ Printf(f_im, "%s ", imclass_class_modifiers);
+ Printf(f_im, "%s ", imclass_name);
+
+ if (imclass_baseclass && *Char(imclass_baseclass))
+ Printf(f_im, "extends %s ", imclass_baseclass);
+ if (Len(imclass_interfaces) > 0)
+ Printv(f_im, "implements ", imclass_interfaces, " ", NIL);
+ Printf(f_im, "{\n");
+
+ // Add the intermediary class methods
+ Replaceall(imclass_class_code, "$module", module_class_name);
+ Replaceall(imclass_class_code, "$imclassname", imclass_name);
+ Printv(f_im, imclass_class_code, NIL);
+ Printv(f_im, imclass_cppcasts_code, NIL);
+ if (Len(imclass_directors) > 0)
+ Printv(f_im, "\n", imclass_directors, NIL);
+
+ if (n_dmethods > 0) {
+ Putc('\n', f_im);
+ Printf(f_im, " private final static native void swig_module_init();\n");
+ Printf(f_im, " static {\n");
+ Printf(f_im, " swig_module_init();\n");
+ Printf(f_im, " }\n");
+ }
+ // Finish off the class
+ Printf(f_im, "}\n");
+ Close(f_im);
+ }
+
+ // Generate the Java module class
+ {
+ String *filen = NewStringf("%s%s.java", SWIG_output_directory(), module_class_name);
+ File *f_module = NewFile(filen, "w", SWIG_output_files());
+ if (!f_module) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the module class file
+ emitBanner(f_module);
+
+ if (Len(package) > 0)
+ Printf(f_module, "package %s;\n", package);
+
+ if (module_imports)
+ Printf(f_module, "%s\n", module_imports);
+
+ if (Len(module_class_modifiers) > 0)
+ Printf(f_module, "%s ", module_class_modifiers);
+ Printf(f_module, "%s ", module_class_name);
+
+ if (module_baseclass && *Char(module_baseclass))
+ Printf(f_module, "extends %s ", module_baseclass);
+ if (Len(module_interfaces) > 0) {
+ if (Len(module_class_constants_code) != 0)
+ Printv(f_module, "implements ", Getattr(n, "name"), "Constants, ", module_interfaces, " ", NIL);
+ else
+ Printv(f_module, "implements ", module_interfaces, " ", NIL);
+ } else {
+ if (Len(module_class_constants_code) != 0)
+ Printv(f_module, "implements ", Getattr(n, "name"), "Constants ", NIL);
+ }
+ Printf(f_module, "{\n");
+
+ Replaceall(module_class_code, "$module", module_class_name);
+ Replaceall(module_class_constants_code, "$module", module_class_name);
+
+ Replaceall(module_class_code, "$imclassname", imclass_name);
+ Replaceall(module_class_constants_code, "$imclassname", imclass_name);
+
+ // Add the wrapper methods
+ Printv(f_module, module_class_code, NIL);
+
+ // Finish off the class
+ Printf(f_module, "}\n");
+ Close(f_module);
+ }
+
+ // Generate the Java constants interface
+ if (Len(module_class_constants_code) != 0) {
+ String *filen = NewStringf("%s%sConstants.java", SWIG_output_directory(), module_class_name);
+ File *f_module = NewFile(filen, "w", SWIG_output_files());
+ if (!f_module) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the Java constants interface file
+ emitBanner(f_module);
+
+ if (Len(package) > 0)
+ Printf(f_module, "package %s;\n", package);
+
+ if (module_imports)
+ Printf(f_module, "%s\n", module_imports);
+
+ Printf(f_module, "public interface %sConstants {\n", module_class_name);
+
+ // Write out all the global constants
+ Printv(f_module, module_class_constants_code, NIL);
+
+ // Finish off the Java interface
+ Printf(f_module, "}\n");
+ Close(f_module);
+ }
+
+ if (upcasts_code)
+ Printv(f_wrappers, upcasts_code, NIL);
+
+ emitDirectorUpcalls();
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n");
+ Printf(f_wrappers, "}\n");
+ Printf(f_wrappers, "#endif\n");
+
+ // Output a Java type wrapper class for each SWIG type
+ for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) {
+ emitTypeWrapperClass(swig_type.key, swig_type.item);
+ }
+
+ // Check for overwriting file problems on filesystems that are case insensitive
+ Iterator it1;
+ Iterator it2;
+ for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) {
+ String *item1_lower = Swig_string_lower(it1.item);
+ for (it2 = Next(it1); it2.item; it2 = Next(it2)) {
+ String *item2_lower = Swig_string_lower(it2.item);
+ if (it1.item && it2.item) {
+ if (Strcmp(item1_lower, item2_lower) == 0) {
+ Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number,
+ "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as "
+ "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item);
+ }
+ }
+ Delete(item2_lower);
+ }
+ Delete(item1_lower);
+ }
+
+ Delete(swig_types_hash);
+ swig_types_hash = NULL;
+ Delete(filenames_list);
+ filenames_list = NULL;
+ Delete(imclass_name);
+ imclass_name = NULL;
+ Delete(imclass_class_code);
+ imclass_class_code = NULL;
+ Delete(proxy_class_def);
+ proxy_class_def = NULL;
+ Delete(proxy_class_code);
+ proxy_class_code = NULL;
+ Delete(module_class_constants_code);
+ module_class_constants_code = NULL;
+ Delete(imclass_baseclass);
+ imclass_baseclass = NULL;
+ Delete(imclass_interfaces);
+ imclass_interfaces = NULL;
+ Delete(imclass_class_modifiers);
+ imclass_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(imclass_imports);
+ imclass_imports = NULL;
+ Delete(imclass_cppcasts_code);
+ imclass_cppcasts_code = NULL;
+ Delete(imclass_directors);
+ imclass_directors = NULL;
+ Delete(upcasts_code);
+ upcasts_code = NULL;
+ Delete(package);
+ package = NULL;
+ Delete(jnipackage);
+ jnipackage = NULL;
+ Delete(package_path);
+ package_path = NULL;
+ Delete(dmethods_seq);
+ dmethods_seq = NULL;
+ Delete(dmethods_table);
+ dmethods_table = NULL;
+ n_dmethods = 0;
+
+ /* Close all of the files */
+ Dump(f_header, f_runtime);
+
+ if (directorsEnabled()) {
+ Dump(f_directors, f_runtime);
+ Dump(f_directors_h, f_runtime_h);
+
+ Printf(f_runtime_h, "\n");
+ Printf(f_runtime_h, "#endif\n");
+
+ Close(f_runtime_h);
+ Delete(f_runtime_h);
+ f_runtime_h = NULL;
+ Delete(f_directors);
+ f_directors = NULL;
+ Delete(f_directors_h);
+ f_directors_h = NULL;
+ }
+
+ Dump(f_wrappers, f_runtime);
+ Wrapper_pretty_print(f_init, f_runtime);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Dump(f_runtime, f_begin);
+ Delete(f_runtime);
+ Close(f_begin);
+ Delete(f_begin);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitBanner()
+ * ----------------------------------------------------------------------------- */
+
+ void emitBanner(File *f) {
+ Printf(f, "/* ----------------------------------------------------------------------------\n");
+ Swig_banner_target_lang(f, " *");
+ Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
+ }
+
+ /*-----------------------------------------------------------------------
+ * Add new director upcall signature
+ *----------------------------------------------------------------------*/
+
+ UpcallData *addUpcallMethod(String *imclass_method, String *class_method, String *imclass_desc, String *class_desc, String *decl) {
+ UpcallData *udata;
+ String *imclass_methodidx;
+ String *class_methodidx;
+ Hash *new_udata;
+ String *key = NewStringf("%s|%s", imclass_method, decl);
+
+ ++curr_class_dmethod;
+
+ /* Do we know about this director class already? */
+ if ((udata = Getattr(dmethods_table, key))) {
+ Delete(key);
+ return Getattr(udata, "methodoff");
+ }
+
+ imclass_methodidx = NewStringf("%d", n_dmethods);
+ class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod);
+ n_dmethods++;
+
+ new_udata = NewHash();
+ Append(dmethods_seq, new_udata);
+ Setattr(dmethods_table, key, new_udata);
+
+ Setattr(new_udata, "method", Copy(class_method));
+ Setattr(new_udata, "fdesc", Copy(class_desc));
+ Setattr(new_udata, "imclass_method", Copy(imclass_method));
+ Setattr(new_udata, "imclass_fdesc", Copy(imclass_desc));
+ Setattr(new_udata, "imclass_methodidx", imclass_methodidx);
+ Setattr(new_udata, "class_methodidx", class_methodidx);
+ Setattr(new_udata, "decl", Copy(decl));
+
+ Delete(key);
+ return new_udata;
+ }
+
+ /*-----------------------------------------------------------------------
+ * Get director upcall signature
+ *----------------------------------------------------------------------*/
+
+ UpcallData *getUpcallMethodData(String *director_class, String *decl) {
+ String *key = NewStringf("%s|%s", director_class, decl);
+ UpcallData *udata = Getattr(dmethods_table, key);
+
+ Delete(key);
+ return udata;
+ }
+
+ /* ----------------------------------------------------------------------
+ * nativeWrapper()
+ * ---------------------------------------------------------------------- */
+
+ virtual int nativeWrapper(Node *n) {
+ String *wrapname = Getattr(n, "wrap:name");
+
+ if (!addSymbol(wrapname, n))
+ return SWIG_ERROR;
+
+ if (Getattr(n, "type")) {
+ Swig_save("nativeWrapper", n, "name", NIL);
+ Setattr(n, "name", wrapname);
+ native_function_flag = true;
+ functionWrapper(n);
+ Swig_restore(n);
+ native_function_flag = false;
+ } else {
+ Printf(stderr, "%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n, "wrap:name"));
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * functionWrapper()
+ * ---------------------------------------------------------------------- */
+
+ virtual int functionWrapper(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *tm;
+ Parm *p;
+ int i;
+ String *c_return_type = NewString("");
+ String *im_return_type = NewString("");
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *body = NewString("");
+ int num_arguments = 0;
+ int num_required = 0;
+ int gencomma = 0;
+ bool is_void_return;
+ String *overloaded_name = getOverloadedName(n);
+ String *nondir_args = NewString("");
+ bool is_destructor = (Cmp(Getattr(n, "nodeType"), "destructor") == 0);
+
+ if (!Getattr(n, "sym:overloaded")) {
+ if (!addSymbol(Getattr(n, "sym:name"), n))
+ return SWIG_ERROR;
+ }
+
+ /*
+ The rest of this function deals with generating the intermediary class wrapper function (that wraps
+ a c/c++ function) and generating the JNI c code. Each Java wrapper function has a
+ matching JNI c function call.
+ */
+
+ // A new wrapper function object
+ Wrapper *f = NewWrapper();
+
+ // Make a wrapper name for this function
+ String *jniname = makeValidJniName(overloaded_name);
+ String *wname = Swig_name_wrapper(jniname);
+
+ Delete(jniname);
+
+ /* Attach the non-standard typemaps to the parameter list. */
+ Swig_typemap_attach_parms("jni", l, f);
+ Swig_typemap_attach_parms("jtype", l, f);
+ Swig_typemap_attach_parms("jstype", l, f);
+
+ /* Get return types */
+ if ((tm = Swig_typemap_lookup("jni", n, "", 0))) {
+ Printf(c_return_type, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ if ((tm = Swig_typemap_lookup("jtype", n, "", 0))) {
+ Printf(im_return_type, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ is_void_return = (Cmp(c_return_type, "void") == 0);
+ if (!is_void_return)
+ Wrapper_add_localv(f, "jresult", c_return_type, "jresult = 0", NIL);
+
+ Printv(f->def, "SWIGEXPORT ", c_return_type, " 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_parameter_variables(l, f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l, f);
+
+ // Parameter overloading
+ Setattr(n, "wrap:parms", l);
+ Setattr(n, "wrap:name", wname);
+
+ // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java
+ if (Getattr(n, "sym:overloaded")) {
+ // Emit warnings for the few cases that can't be overloaded in Java and give up on generating wrapper
+ Swig_overload_check(n);
+ if (Getattr(n, "overload:ignore"))
+ return SWIG_OK;
+ }
+
+ Printf(imclass_class_code, " public final static native %s %s(", im_return_type, overloaded_name);
+
+ /* Get number of required and total arguments */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+
+ // 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 *im_param_type = NewString("");
+ String *c_param_type = NewString("");
+ String *arg = NewString("");
+
+ Printf(arg, "j%s", ln);
+
+ /* Get the JNI C types of the parameter */
+ if ((tm = Getattr(p, "tmap:jni"))) {
+ Printv(c_param_type, tm, NIL);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ /* Get the intermediary class parameter types of the parameter */
+ if ((tm = Getattr(p, "tmap:jtype"))) {
+ Printv(im_param_type, 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 parameter to intermediary class method */
+ if (gencomma)
+ Printf(imclass_class_code, ", ");
+ Printf(imclass_class_code, "%s %s", im_param_type, arg);
+
+ // Add parameter to C function
+ Printv(f->def, ", ", c_param_type, " ", arg, NIL);
+
+ ++gencomma;
+
+ // Premature garbage collection prevention parameter
+ if (!is_destructor) {
+ String *pgc_parameter = prematureGarbageCollectionPreventionParameter(pt, p);
+ if (pgc_parameter) {
+ Printf(imclass_class_code, ", %s %s_", pgc_parameter, arg);
+ Printf(f->def, ", jobject %s_", arg);
+ Printf(f->code, " (void)%s_;\n", arg);
+ }
+ }
+ // Get typemap for this argument
+ if ((tm = Getattr(p, "tmap:in"))) {
+ addThrows(n, "tmap:in", p);
+ Replaceall(tm, "$source", arg); /* deprecated */
+ Replaceall(tm, "$target", ln); /* deprecated */
+ Replaceall(tm, "$arg", arg); /* deprecated? */
+ Replaceall(tm, "$input", arg);
+ Setattr(p, "emit:input", arg);
+
+ Printf(nondir_args, "%s\n", tm);
+
+ p = Getattr(p, "tmap:in:next");
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
+ p = nextSibling(p);
+ }
+
+ Delete(im_param_type);
+ Delete(c_param_type);
+ Delete(arg);
+ }
+
+ Printv(f->code, nondir_args, NIL);
+ Delete(nondir_args);
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ addThrows(n, "tmap:check", p);
+ Replaceall(tm, "$target", Getattr(p, "lname")); /* deprecated */
+ Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:freearg"))) {
+ addThrows(n, "tmap:freearg", p);
+ Replaceall(tm, "$source", Getattr(p, "emit:input")); /* deprecated */
+ Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(cleanup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+ addThrows(n, "tmap:argout", p);
+ Replaceall(tm, "$source", Getattr(p, "emit:input")); /* deprecated */
+ Replaceall(tm, "$target", Getattr(p, "lname")); /* deprecated */
+ Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
+ Replaceall(tm, "$result", "jresult");
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(outarg, tm, "\n", NIL);
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Get any Java exception classes in the throws typemap
+ ParmList *throw_parm_list = NULL;
+ if ((throw_parm_list = Getattr(n, "catchlist"))) {
+ 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_function_flag) {
+ if (Cmp(nodeType(n), "constant") == 0) {
+ // Wrapping a constant hack
+ Swig_save("functionWrapper", n, "wrap:action", NIL);
+
+ // below based on Swig_VargetToFunction()
+ SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n));
+ Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value")));
+ }
+
+ // Now write code to make the function call
+ Swig_director_emit_dynamic_cast(n, f);
+ String *actioncode = emit_action(n);
+
+ // Handle exception classes specified in the "except" feature's "throws" attribute
+ addThrows(n, "feature:except", n);
+
+ if (Cmp(nodeType(n), "constant") == 0)
+ Swig_restore(n);
+
+ /* Return value if necessary */
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ addThrows(n, "tmap:out", n);
+ Replaceall(tm, "$source", "result"); /* deprecated */
+ Replaceall(tm, "$target", "jresult"); /* deprecated */
+ Replaceall(tm, "$result", "jresult");
+
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "1");
+ else
+ Replaceall(tm, "$owner", "0");
+
+ Printf(f->code, "%s", tm);
+ if (Len(tm))
+ Printf(f->code, "\n");
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name"));
+ }
+ emit_return_variable(n, t, f);
+ }
+
+ /* 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 (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
+ addThrows(n, "tmap:newfree", n);
+ Replaceall(tm, "$source", "result"); /* deprecated */
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ /* See if there is any return cleanup code */
+ if (!native_function_flag) {
+ if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
+ addThrows(n, "tmap:ret", n);
+ Replaceall(tm, "$source", "result"); /* deprecated */
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ /* Finish C function and intermediary class function definitions */
+ Printf(imclass_class_code, ")");
+ generateThrowsClause(n, imclass_class_code);
+ Printf(imclass_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);
+
+ /* Substitute the function name */
+ Replaceall(f->code, "$symname", symname);
+
+ /* Contract macro modification */
+ Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ");
+
+ 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);
+
+ if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
+ moduleClassFunctionHandler(n);
+ }
+
+ /*
+ * Generate the proxy class getters/setters for public 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
+ bool getter_flag = Cmp(symname, Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) != 0;
+
+ String *getter_setter_name = NewString("");
+ if (!getter_flag)
+ 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, "proxyfuncname", getter_setter_name);
+ Setattr(n, "imfuncname", symname);
+
+ proxyClassFunctionHandler(n);
+ Delete(getter_setter_name);
+ }
+
+ Delete(c_return_type);
+ Delete(im_return_type);
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(body);
+ Delete(overloaded_name);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * variableWrapper()
+ * ----------------------------------------------------------------------- */
+
+ virtual int variableWrapper(Node *n) {
+ variable_wrapper_flag = true;
+ Language::variableWrapper(n); /* Default to functions */
+ variable_wrapper_flag = false;
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * globalvariableHandler()
+ * ------------------------------------------------------------------------ */
+
+ virtual int globalvariableHandler(Node *n) {
+
+ variable_name = Getattr(n, "sym:name");
+ global_variable_flag = true;
+ int ret = Language::globalvariableHandler(n);
+ global_variable_flag = false;
+ return ret;
+ }
+
+ /* ----------------------------------------------------------------------
+ * enumDeclaration()
+ *
+ * C/C++ enums can be mapped in one of 4 ways, depending on the java:enum feature specified:
+ * 1) Simple enums - simple constant within the proxy class or module class
+ * 2) Typeunsafe enums - simple constant in a Java class (class named after the c++ enum name)
+ * 3) Typesafe enum - typesafe enum pattern (class named after the c++ enum name)
+ * 4) Proper enums - proper Java enum
+ * Anonymous enums always default to 1)
+ * ---------------------------------------------------------------------- */
+
+ virtual int enumDeclaration(Node *n) {
+
+ if (!ImportMode) {
+ if (getCurrentClass() && (cplus_mode != PUBLIC))
+ return SWIG_NOWRAP;
+
+ enum_code = NewString("");
+ String *symname = Getattr(n, "sym:name");
+ String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code;
+ EnumFeature enum_feature = decodeEnumFeature(n);
+ String *typemap_lookup_type = Getattr(n, "name");
+
+ if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
+ // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
+
+ // Pure Java baseclass and interfaces
+ const String *pure_baseclass = typemapLookup(n, "javabase", typemap_lookup_type, WARN_NONE);
+ const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
+
+ // Emit the enum
+ Printv(enum_code, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers (enum modifiers really)
+ " ", symname, *Char(pure_baseclass) ? // Bases
+ " extends " : "", pure_baseclass, *Char(pure_interfaces) ? // Interfaces
+ " implements " : "", pure_interfaces, " {\n", NIL);
+ if (proxy_flag && is_wrapping_class())
+ Replaceall(enum_code, "$static ", "static ");
+ else
+ Replaceall(enum_code, "$static ", "");
+ } else {
+ // Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
+ if (symname && !Getattr(n, "unnamedinstance"))
+ Printf(constants_code, " // %s \n", symname);
+ }
+
+ // Emit each enum item
+ Language::enumDeclaration(n);
+
+ if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
+ // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
+ // Finish the enum declaration
+ // Typemaps are used to generate the enum definition in a similar manner to proxy classes.
+ Printv(enum_code, (enum_feature == ProperEnum) ? ";\n" : "", typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
+ typemapLookup(n, "javacode", typemap_lookup_type, WARN_NONE), // extra Java code
+ "}", NIL);
+
+ Replaceall(enum_code, "$javaclassname", symname);
+
+ // Substitute $enumvalues - intended usage is for typesafe enums
+ if (Getattr(n, "enumvalues"))
+ Replaceall(enum_code, "$enumvalues", Getattr(n, "enumvalues"));
+ else
+ Replaceall(enum_code, "$enumvalues", "");
+
+ if (proxy_flag && is_wrapping_class()) {
+ // Enums defined within the C++ class are defined within the proxy class
+
+ // Add extra indentation
+ Replaceall(enum_code, "\n", "\n ");
+ Replaceall(enum_code, " \n", "\n");
+
+ Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL);
+ } else {
+ // Global enums are defined in their own file
+ String *filen = NewStringf("%s%s.java", SWIG_output_directory(), symname);
+ File *f_enum = NewFile(filen, "w", SWIG_output_files());
+ if (!f_enum) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the enum file
+ emitBanner(f_enum);
+
+ if (Len(package) > 0)
+ Printf(f_enum, "package %s;\n", package);
+
+ Printv(f_enum, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements
+ "\n", enum_code, "\n", NIL);
+
+ Printf(f_enum, "\n");
+ Close(f_enum);
+ }
+ } else {
+ // Wrap C++ enum with simple constant
+ Printf(enum_code, "\n");
+ if (proxy_flag && is_wrapping_class())
+ Printv(proxy_class_constants_code, enum_code, NIL);
+ else
+ Printv(module_class_constants_code, enum_code, NIL);
+ }
+
+ Delete(enum_code);
+ enum_code = NULL;
+ }
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * enumvalueDeclaration()
+ * ---------------------------------------------------------------------- */
+
+ virtual int enumvalueDeclaration(Node *n) {
+ if (getCurrentClass() && (cplus_mode != PUBLIC))
+ return SWIG_NOWRAP;
+
+ Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
+ String *symname = Getattr(n, "sym:name");
+ String *value = Getattr(n, "value");
+ String *name = Getattr(n, "name");
+ String *tmpValue;
+
+ // Strange hack from parent method
+ if (value)
+ tmpValue = NewString(value);
+ else
+ tmpValue = NewString(name);
+ // Note that this is used in enumValue() amongst other places
+ Setattr(n, "value", tmpValue);
+
+ {
+ EnumFeature enum_feature = decodeEnumFeature(parentNode(n));
+
+ if ((enum_feature == ProperEnum) && Getattr(parentNode(n), "sym:name") && !Getattr(parentNode(n), "unnamedinstance")) {
+ // Wrap (non-anonymous) C/C++ enum with a proper Java enum
+ // Emit the enum item.
+ if (!GetFlag(n, "firstenumitem"))
+ Printf(enum_code, ",\n");
+ Printf(enum_code, " %s", symname);
+ if (Getattr(n, "enumvalue")) {
+ String *value = enumValue(n);
+ Printf(enum_code, "(%s)", value);
+ Delete(value);
+ }
+ } else {
+ // Wrap C/C++ enums with constant integers or use the typesafe enum pattern
+ const String *parent_name = Getattr(parentNode(n), "name");
+ String *typemap_lookup_type = parent_name ? Copy(parent_name) : NewString("int");
+ const String *tm = typemapLookup(n, "jstype", typemap_lookup_type, WARN_JAVA_TYPEMAP_JSTYPE_UNDEF);
+ String *return_type = Copy(tm);
+ Delete(typemap_lookup_type);
+ typemap_lookup_type = NULL;
+
+ const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
+ methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
+
+ if ((enum_feature == TypesafeEnum) && Getattr(parentNode(n), "sym:name") && !Getattr(parentNode(n), "unnamedinstance")) {
+ // Wrap (non-anonymouse) enum using the typesafe enum pattern
+ if (Getattr(n, "enumvalue")) {
+ String *value = enumValue(n);
+ Printf(enum_code, " %s final static %s %s = new %s(\"%s\", %s);\n", methodmods, return_type, symname, return_type, symname, value);
+ Delete(value);
+ } else {
+ Printf(enum_code, " %s final static %s %s = new %s(\"%s\");\n", methodmods, return_type, symname, return_type, symname);
+ }
+ } else {
+ // Simple integer constants
+ // Note these are always generated for anonymous enums, no matter what enum_feature is specified
+ // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
+ String *value = enumValue(n);
+ Printf(enum_code, " %s final static %s %s = %s;\n", methodmods, return_type, symname, value);
+ Delete(value);
+ }
+ }
+
+ // Add the enum value to the comma separated list being constructed in the enum declaration.
+ String *enumvalues = Getattr(parentNode(n), "enumvalues");
+ if (!enumvalues)
+ Setattr(parentNode(n), "enumvalues", Copy(symname));
+ else
+ Printv(enumvalues, ", ", symname, NIL);
+ }
+
+ Delete(tmpValue);
+ Swig_restore(n);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * constantWrapper()
+ * Used for wrapping constants - #define or %constant.
+ * Also for inline initialised const static primitive type member variables (short, int, double, enums etc).
+ * Java static final variables are generated for these.
+ * If the %javaconst(1) feature is used then the C constant value is used to initialise the Java final variable.
+ * If not, a JNI method is generated to get the C constant value for initialisation of the Java final variable.
+ * However, if the %javaconstvalue feature is used, it overrides all other ways to generate the initialisation.
+ * Also note that this method might be called for wrapping enum items (when the enum is using %javaconst(0)).
+ * ------------------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *tm;
+ String *return_type = NewString("");
+ String *constants_code = NewString("");
+
+ if (!addSymbol(symname, n))
+ return SWIG_ERROR;
+
+ bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
+
+ // The %javaconst feature determines how the constant value is obtained
+ int const_feature_flag = GetFlag(n, "feature:java:const");
+
+ /* Adjust the enum type for the Swig_typemap_lookup.
+ * We want the same jstype typemap for all the enum items so we use the enum type (parent node). */
+ if (is_enum_item) {
+ t = Getattr(parentNode(n), "enumtype");
+ Setattr(n, "type", t);
+ }
+
+ /* Attach the non-standard typemaps to the parameter list. */
+ Swig_typemap_attach_parms("jstype", l, NULL);
+
+ /* Get Java return types */
+ bool classname_substituted_flag = false;
+
+ if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) {
+ classname_substituted_flag = substituteClassname(t, tm);
+ Printf(return_type, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ // Add the stripped quotes back in
+ String *new_value = NewString("");
+ Swig_save("constantWrapper", 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);
+ }
+
+ const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname;
+ const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
+ methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
+
+ Printf(constants_code, " %s final static %s %s = ", methodmods, return_type, itemname);
+
+ // Check for the %javaconstvalue feature
+ String *value = Getattr(n, "feature:java:constvalue");
+
+ if (value) {
+ Printf(constants_code, "%s;\n", value);
+ } else if (!const_feature_flag) {
+ // Default enum and constant handling will work with any type of C constant and initialises the Java variable from C through a JNI call.
+
+ if (classname_substituted_flag) {
+ if (SwigType_isenum(t)) {
+ // This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
+ Printf(constants_code, "%s.swigToEnum(%s.%s());\n", return_type, imclass_name, Swig_name_get(symname));
+ } else {
+ // This handles function pointers using the %constant directive
+ Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, imclass_name, Swig_name_get(symname));
+ }
+ } else
+ Printf(constants_code, "%s.%s();\n", imclass_name, Swig_name_get(symname));
+
+ // Each constant and enum value is wrapped with a separate JNI function call
+ SetFlag(n, "feature:immutable");
+ enum_constant_flag = true;
+ variableWrapper(n);
+ enum_constant_flag = false;
+ } else {
+ // Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code
+ Printf(constants_code, "%s;\n", Getattr(n, "value"));
+ }
+
+ // Emit the generated code to appropriate place
+ // Enums only emit the intermediate and JNI methods, so no proxy or module class wrapper methods needed
+ if (!is_enum_item) {
+ if (proxy_flag && wrapping_member_flag)
+ Printv(proxy_class_constants_code, constants_code, NIL);
+ else
+ Printv(module_class_constants_code, constants_code, NIL);
+ }
+ // Cleanup
+ Swig_restore(n);
+ Delete(new_value);
+ Delete(return_type);
+ Delete(constants_code);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * insertDirective()
+ * ----------------------------------------------------------------------------- */
+
+ virtual int insertDirective(Node *n) {
+ String *code = Getattr(n, "code");
+ Replaceall(code, "$module", module_class_name);
+ Replaceall(code, "$imclassname", imclass_name);
+ return Language::insertDirective(n);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * pragmaDirective()
+ *
+ * Valid Pragmas:
+ * jniclassbase - base (extends) for the intermediary class
+ * jniclassclassmodifiers - class modifiers for the intermediary class
+ * jniclasscode - text (java code) is copied verbatim to the intermediary class
+ * jniclassimports - import statements for the intermediary class
+ * jniclassinterfaces - interface (implements) for the intermediary 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(imclass_baseclass);
+ imclass_baseclass = Copy(strvalue);
+ } else if (Strcmp(code, "jniclassclassmodifiers") == 0) {
+ Delete(imclass_class_modifiers);
+ imclass_class_modifiers = Copy(strvalue);
+ } else if (Strcmp(code, "jniclasscode") == 0) {
+ Printf(imclass_class_code, "%s\n", strvalue);
+ } else if (Strcmp(code, "jniclassimports") == 0) {
+ Delete(imclass_imports);
+ imclass_imports = Copy(strvalue);
+ } else if (Strcmp(code, "jniclassinterfaces") == 0) {
+ Delete(imclass_interfaces);
+ imclass_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);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitProxyClassDefAndCPPCasts()
+ * ----------------------------------------------------------------------------- */
+
+ void emitProxyClassDefAndCPPCasts(Node *n) {
+ String *c_classname = SwigType_namestr(Getattr(n, "name"));
+ String *c_baseclass = NULL;
+ String *baseclass = NULL;
+ String *c_baseclassname = NULL;
+ SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
+ bool feature_director = Swig_directorclass(n) ? true : false;
+
+ // Inheritance from pure Java classes
+ Node *attributes = NewHash();
+ const String *pure_baseclass = typemapLookup(n, "javabase", typemap_lookup_type, WARN_NONE, attributes);
+ bool purebase_replace = GetFlag(attributes, "tmap:javabase:replace") ? true : false;
+ bool purebase_notderived = GetFlag(attributes, "tmap:javabase:notderived") ? true : false;
+ Delete(attributes);
+
+ // C++ inheritance
+ if (!purebase_replace) {
+ List *baselist = Getattr(n, "bases");
+ if (baselist) {
+ Iterator base = First(baselist);
+ while (base.item && GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ }
+ if (base.item) {
+ c_baseclassname = Getattr(base.item, "name");
+ baseclass = Copy(getProxyName(c_baseclassname));
+ if (baseclass)
+ c_baseclass = SwigType_namestr(Getattr(base.item, "name"));
+ base = Next(base);
+ /* Warn about multiple inheritance for additional base class(es) */
+ while (base.item) {
+ if (GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ continue;
+ }
+ String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
+ String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
+ Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number,
+ "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", proxyclassname, baseclassname);
+ base = Next(base);
+ }
+ }
+ }
+ }
+
+ bool derived = baseclass && getProxyName(c_baseclassname);
+ if (derived && purebase_notderived)
+ pure_baseclass = empty_string;
+ const String *wanted_base = baseclass ? baseclass : pure_baseclass;
+
+ if (purebase_replace) {
+ wanted_base = pure_baseclass;
+ derived = false;
+ Delete(baseclass);
+ baseclass = NULL;
+ if (purebase_notderived)
+ Swig_error(input_file, line_number, "The javabase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
+ } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
+ Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number,
+ "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java. "
+ "Perhaps you need one of the 'replace' or 'notderived' attributes in the csbase typemap?\n", typemap_lookup_type, pure_baseclass);
+ }
+
+ // Pure Java interfaces
+ const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
+
+ // Start writing the proxy class
+ Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements
+ "\n", typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
+ " $javaclassname", // Class name and bases
+ (*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(pure_interfaces) ? // Pure Java interfaces
+ " implements " : "", pure_interfaces, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class
+ typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
+ NIL);
+
+ // C++ destructor is wrapped by the delete method
+ // Note that the method name is specified in a typemap attribute called methodname
+ String *destruct = NewString("");
+ const String *tm = NULL;
+ attributes = NewHash();
+ String *destruct_methodname = NULL;
+ String *destruct_methodmodifiers = NULL;
+ if (derived) {
+ tm = typemapLookup(n, "javadestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
+ destruct_methodname = Getattr(attributes, "tmap:javadestruct_derived:methodname");
+ destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct_derived:methodmodifiers");
+ } else {
+ tm = typemapLookup(n, "javadestruct", typemap_lookup_type, WARN_NONE, attributes);
+ destruct_methodname = Getattr(attributes, "tmap:javadestruct:methodname");
+ destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct:methodmodifiers");
+ }
+ if (tm && *Char(tm)) {
+ if (!destruct_methodname) {
+ Swig_error(input_file, line_number,
+ "No methodname attribute defined in javadestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
+ }
+ if (!destruct_methodmodifiers) {
+ Swig_error(input_file, line_number,
+ "No methodmodifiers attribute defined in javadestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name);
+ }
+ }
+ // Emit the finalize and delete methods
+ if (tm) {
+ // Finalize method
+ if (*Char(destructor_call)) {
+ Printv(proxy_class_def, typemapLookup(n, "javafinalize", typemap_lookup_type, WARN_NONE), NIL);
+ }
+ // delete method
+ Printv(destruct, tm, NIL);
+ if (*Char(destructor_call))
+ Replaceall(destruct, "$jnicall", destructor_call);
+ else
+ Replaceall(destruct, "$jnicall", "throw new UnsupportedOperationException(\"C++ destructor does not have public access\")");
+ if (*Char(destruct))
+ Printv(proxy_class_def, "\n ", destruct_methodmodifiers, " void ", destruct_methodname, "()", destructor_throws_clause, " ", destruct, "\n", NIL);
+ }
+
+ /* Insert directordisconnect typemap, if this class has directors enabled */
+ /* Also insert the swigTakeOwnership and swigReleaseOwnership methods */
+ if (feature_director) {
+ String *destruct_jnicall, *release_jnicall, *take_jnicall;
+
+ destruct_jnicall = NewStringf("%s()", destruct_methodname);
+ release_jnicall = NewStringf("%s.%s_change_ownership(this, swigCPtr, false)", imclass_name, proxy_class_name);
+ take_jnicall = NewStringf("%s.%s_change_ownership(this, swigCPtr, true)", imclass_name, proxy_class_name);
+
+ emitCodeTypemap(n, false, typemap_lookup_type, "directordisconnect", "methodname", destruct_jnicall);
+ emitCodeTypemap(n, false, typemap_lookup_type, "directorowner_release", "methodname", release_jnicall);
+ emitCodeTypemap(n, false, typemap_lookup_type, "directorowner_take", "methodname", take_jnicall);
+
+ Delete(destruct_jnicall);
+ Delete(release_jnicall);
+ Delete(take_jnicall);
+ }
+
+ Delete(attributes);
+ Delete(destruct);
+
+ // Emit extra user code
+ Printv(proxy_class_def, typemapLookup(n, "javacode", typemap_lookup_type, WARN_NONE), // extra Java code
+ "\n", NIL);
+
+ // Substitute various strings into the above template
+ Replaceall(proxy_class_code, "$javaclassname", proxy_class_name);
+ Replaceall(proxy_class_def, "$javaclassname", proxy_class_name);
+
+ Replaceall(proxy_class_def, "$module", module_class_name);
+ Replaceall(proxy_class_code, "$module", module_class_name);
+
+ Replaceall(proxy_class_def, "$imclassname", imclass_name);
+ Replaceall(proxy_class_code, "$imclassname", imclass_name);
+
+ // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
+ if (derived) {
+ Printv(imclass_cppcasts_code, " public final static native long SWIG$javaclassnameUpcast(long jarg1);\n", NIL);
+
+ Replaceall(imclass_cppcasts_code, "$javaclassname", proxy_class_name);
+
+ Printv(upcasts_code,
+ "SWIGEXPORT jlong JNICALL Java_$jnipackage$imimclass_SWIG$imclazznameUpcast",
+ "(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 *imimclass = makeValidJniName(imclass_name);
+ String *imclazzname = makeValidJniName(proxy_class_name);
+ Replaceall(upcasts_code, "$cbaseclass", c_baseclass);
+ Replaceall(upcasts_code, "$imclazzname", imclazzname);
+ Replaceall(upcasts_code, "$cclass", c_classname);
+ Replaceall(upcasts_code, "$jnipackage", jnipackage);
+ Replaceall(upcasts_code, "$imimclass", imimclass);
+
+ Delete(imclazzname);
+ Delete(imimclass);
+ }
+ Delete(baseclass);
+ }
+
+ /* ----------------------------------------------------------------------
+ * classHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int classHandler(Node *n) {
+
+ File *f_proxy = NULL;
+ if (proxy_flag) {
+ proxy_class_name = NewString(Getattr(n, "sym:name"));
+
+ if (!addSymbol(proxy_class_name, n))
+ return SWIG_ERROR;
+
+ if (Cmp(proxy_class_name, imclass_name) == 0) {
+ Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ if (Cmp(proxy_class_name, module_class_name) == 0) {
+ Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ String *filen = NewStringf("%s%s.java", SWIG_output_directory(), proxy_class_name);
+ f_proxy = NewFile(filen, "w", SWIG_output_files());
+ if (!f_proxy) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the proxy class file
+ emitBanner(f_proxy);
+
+ if (Len(package) > 0)
+ Printf(f_proxy, "package %s;\n", package);
+
+ Clear(proxy_class_def);
+ Clear(proxy_class_code);
+
+ destructor_call = NewString("");
+ destructor_throws_clause = NewString("");
+ proxy_class_constants_code = NewString("");
+ }
+
+ Language::classHandler(n);
+
+ if (proxy_flag) {
+
+ emitProxyClassDefAndCPPCasts(n);
+
+ Replaceall(proxy_class_def, "$module", module_class_name);
+ Replaceall(proxy_class_code, "$module", module_class_name);
+ Replaceall(proxy_class_constants_code, "$module", module_class_name);
+ Replaceall(proxy_class_def, "$imclassname", imclass_name);
+ Replaceall(proxy_class_code, "$imclassname", imclass_name);
+ Replaceall(proxy_class_constants_code, "$imclassname", imclass_name);
+ Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
+
+ // Write out all the constants
+ if (Len(proxy_class_constants_code) != 0)
+ Printv(f_proxy, proxy_class_constants_code, NIL);
+
+ Printf(f_proxy, "}\n");
+ Close(f_proxy);
+ f_proxy = NULL;
+
+ /* Output the downcast method, if necessary. Note: There's no other really
+ good place to put this code, since Abstract Base Classes (ABCs) can and should have
+ downcasts, making the constructorHandler() a bad place (because ABCs don't get to
+ have constructors emitted.) */
+ if (GetFlag(n, "feature:javadowncast")) {
+ String *jni_imclass_name = makeValidJniName(imclass_name);
+ String *jni_class_name = makeValidJniName(proxy_class_name);
+ String *norm_name = SwigType_namestr(Getattr(n, "name"));
+
+ Printf(imclass_class_code, " public final static native %s downcast%s(long cPtrBase, boolean cMemoryOwn);\n", proxy_class_name, proxy_class_name);
+
+ Wrapper *dcast_wrap = NewWrapper();
+
+ Printf(dcast_wrap->def, "SWIGEXPORT jobject JNICALL Java_%s%s_downcast%s(JNIEnv *jenv, jclass jcls, jlong jCPtrBase, jboolean cMemoryOwn) {",
+ jnipackage, jni_imclass_name, jni_class_name);
+ Printf(dcast_wrap->code, " Swig::Director *director = (Swig::Director *) 0;\n");
+ Printf(dcast_wrap->code, " jobject jresult = (jobject) 0;\n");
+ Printf(dcast_wrap->code, " %s *obj = *((%s **)&jCPtrBase);\n", norm_name, norm_name);
+ Printf(dcast_wrap->code, " if (obj) director = dynamic_cast<Swig::Director *>(obj);\n");
+ Printf(dcast_wrap->code, " if (director) jresult = director->swig_get_self(jenv);\n");
+ Printf(dcast_wrap->code, " return jresult;\n");
+ Printf(dcast_wrap->code, "}\n");
+
+ Wrapper_print(dcast_wrap, f_wrappers);
+ DelWrapper(dcast_wrap);
+ }
+
+ emitDirectorExtraMethods(n);
+
+ Delete(proxy_class_name);
+ proxy_class_name = NULL;
+ Delete(destructor_call);
+ destructor_call = NULL;
+ Delete(destructor_throws_clause);
+ destructor_throws_clause = NULL;
+ Delete(proxy_class_constants_code);
+ proxy_class_constants_code = NULL;
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int memberfunctionHandler(Node *n) {
+ member_func_flag = true;
+ Language::memberfunctionHandler(n);
+
+ if (proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
+ Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
+ Setattr(n, "imfuncname", intermediary_function_name);
+ proxyClassFunctionHandler(n);
+ Delete(overloaded_name);
+ }
+ member_func_flag = false;
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+
+ static_flag = true;
+ member_func_flag = true;
+ Language::staticmemberfunctionHandler(n);
+
+ if (proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
+ Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
+ Setattr(n, "imfuncname", intermediary_function_name);
+ proxyClassFunctionHandler(n);
+ Delete(overloaded_name);
+ }
+ static_flag = false;
+ member_func_flag = false;
+
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * proxyClassFunctionHandler()
+ *
+ * Function called for creating a Java wrapper function around a c++ function in the
+ * proxy class. Used for both static and non-static C++ class functions.
+ * C++ class static functions map to Java static functions.
+ * Two extra attributes in the Node must be available. These are "proxyfuncname" -
+ * the name of the Java class proxy function, which in turn will call "imfuncname" -
+ * the intermediary (JNI) function name in the intermediary class.
+ * ----------------------------------------------------------------------------- */
+
+ void proxyClassFunctionHandler(Node *n) {
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *intermediary_function_name = Getattr(n, "imfuncname");
+ String *proxy_function_name = Getattr(n, "proxyfuncname");
+ String *tm;
+ Parm *p;
+ int i;
+ String *imcall = NewString("");
+ String *return_type = NewString("");
+ String *function_code = NewString("");
+ bool setter_flag = false;
+ String *pre_code = NewString("");
+ String *post_code = NewString("");
+
+ if (!proxy_flag)
+ return;
+
+ // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java
+ if (Getattr(n, "overload:ignore"))
+ return;
+
+ // Don't generate proxy method for additional explicitcall method used in directors
+ if (GetFlag(n, "explicitcall"))
+ 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("jtype", l, NULL);
+ Swig_typemap_attach_parms("jstype", l, NULL);
+ Swig_typemap_attach_parms("javain", l, NULL);
+
+ /* Get return types */
+ if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) {
+ // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type
+ SwigType *covariant = Getattr(n, "covariant");
+ substituteClassname(covariant ? covariant : t, tm);
+ Printf(return_type, "%s", tm);
+ if (covariant)
+ Swig_warning(WARN_JAVA_COVARIANT_RET, input_file, line_number,
+ "Covariant return types not supported in Java. Proxy method will return %s.\n", SwigType_str(covariant, 0));
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ if (wrapping_member_flag && !enum_constant_flag) {
+ // For wrapping member variables (Javabean setter)
+ setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) == 0);
+ }
+
+ /* Start generating the proxy function */
+ const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
+ methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
+ Printf(function_code, " %s ", methodmods);
+ if (static_flag)
+ Printf(function_code, "static ");
+ Printf(function_code, "%s %s(", return_type, proxy_function_name);
+
+ Printv(imcall, imclass_name, ".$imfuncname(", NIL);
+ if (!static_flag) {
+ Printf(imcall, "swigCPtr");
+
+ String *this_type = Copy(getClassType());
+ String *name = NewString("self");
+ String *qualifier = Getattr(n, "qualifier");
+ if (qualifier)
+ SwigType_push(this_type, qualifier);
+ SwigType_add_pointer(this_type);
+ Parm *this_parm = NewParm(this_type, name);
+ Swig_typemap_attach_parms("jtype", this_parm, NULL);
+ Swig_typemap_attach_parms("jstype", this_parm, NULL);
+
+ if (prematureGarbageCollectionPreventionParameter(this_type, this_parm))
+ Printf(imcall, ", this");
+
+ Delete(this_parm);
+ Delete(name);
+ Delete(this_type);
+ }
+
+ emit_mark_varargs(l);
+
+ int gencomma = !static_flag;
+
+ /* Output each parameter */
+ for (i = 0, p = l; p; i++) {
+
+ /* Ignored varargs */
+ if (checkAttribute(p, "varargs:ignore", "1")) {
+ p = nextSibling(p);
+ continue;
+ }
+
+ /* Ignored parameters */
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+
+ /* Ignore the 'this' argument for variable wrappers */
+ if (!(variable_wrapper_flag && i == 0) || static_flag) {
+ SwigType *pt = Getattr(p, "type");
+ String *param_type = NewString("");
+
+ /* Get the Java parameter type */
+ if ((tm = Getattr(p, "tmap:jstype"))) {
+ substituteClassname(pt, tm);
+ Printf(param_type, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ if (gencomma)
+ Printf(imcall, ", ");
+
+ String *arg = makeParameterName(n, p, i, setter_flag);
+
+ // Use typemaps to transform type used in Java proxy wrapper (in proxy class) to type used in JNI function (in intermediary class)
+ if ((tm = Getattr(p, "tmap:javain"))) {
+ addThrows(n, "tmap:javain", p);
+ substituteClassname(pt, tm);
+ Replaceall(tm, "$javainput", arg);
+ String *pre = Getattr(p, "tmap:javain:pre");
+ if (pre) {
+ substituteClassname(pt, pre);
+ Replaceall(pre, "$javainput", arg);
+ if (Len(pre_code) > 0)
+ Printf(pre_code, "\n");
+ Printv(pre_code, pre, NIL);
+ }
+ String *post = Getattr(p, "tmap:javain:post");
+ if (post) {
+ substituteClassname(pt, post);
+ Replaceall(post, "$javainput", arg);
+ if (Len(post_code) > 0)
+ Printf(post_code, "\n");
+ Printv(post_code, post, NIL);
+ }
+ Printv(imcall, tm, NIL);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ /* Add parameter to proxy function */
+ if (gencomma >= 2)
+ Printf(function_code, ", ");
+ gencomma = 2;
+ Printf(function_code, "%s %s", param_type, arg);
+
+ if (prematureGarbageCollectionPreventionParameter(pt, p)) {
+ String *pgcppname = Getattr(p, "tmap:javain:pgcppname");
+ if (pgcppname) {
+ String *argname = Copy(pgcppname);
+ Replaceall(argname, "$javainput", arg);
+ Printf(imcall, ", %s", argname);
+ Delete(argname);
+ } else {
+ Printf(imcall, ", %s", arg);
+ }
+ }
+
+ Delete(arg);
+ Delete(param_type);
+ }
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ Printf(imcall, ")");
+ Printf(function_code, ")");
+
+ // Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in proxy class)
+ if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) {
+ addThrows(n, "tmap:javaout", n);
+ bool is_pre_code = Len(pre_code) > 0;
+ bool is_post_code = Len(post_code) > 0;
+ if (is_pre_code || is_post_code) {
+ Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
+ if (is_post_code) {
+ Insert(tm, 0, "\n try ");
+ Printv(tm, " finally {\n", post_code, "\n }", NIL);
+ } else {
+ Insert(tm, 0, "\n ");
+ }
+ if (is_pre_code) {
+ Insert(tm, 0, pre_code);
+ Insert(tm, 0, "\n");
+ }
+ Insert(tm, 0, "{");
+ Printf(tm, "\n }");
+ }
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "true");
+ else
+ Replaceall(tm, "$owner", "false");
+ substituteClassname(t, tm);
+
+ // For director methods: generate code to selectively make a normal polymorphic call or
+ // an explicit method call - needed to prevent infinite recursion calls in director methods.
+ Node *explicit_n = Getattr(n, "explicitcallnode");
+ if (explicit_n) {
+ String *ex_overloaded_name = getOverloadedName(explicit_n);
+ String *ex_intermediary_function_name = Swig_name_member(proxy_class_name, ex_overloaded_name);
+
+ String *ex_imcall = Copy(imcall);
+ Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
+ Replaceall(imcall, "$imfuncname", intermediary_function_name);
+
+ String *excode = NewString("");
+ if (!Cmp(return_type, "void"))
+ Printf(excode, "if (getClass() == %s.class) %s; else %s", proxy_class_name, imcall, ex_imcall);
+ else
+ Printf(excode, "(getClass() == %s.class) ? %s : %s", proxy_class_name, imcall, ex_imcall);
+
+ Clear(imcall);
+ Printv(imcall, excode, NIL);
+ Delete(ex_overloaded_name);
+ Delete(excode);
+ } else {
+ Replaceall(imcall, "$imfuncname", intermediary_function_name);
+ }
+
+ Replaceall(tm, "$jnicall", imcall);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ generateThrowsClause(n, function_code);
+ Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
+ Printv(proxy_class_code, function_code, NIL);
+
+ Delete(pre_code);
+ Delete(post_code);
+ Delete(function_code);
+ Delete(return_type);
+ Delete(imcall);
+ }
+
+ /* ----------------------------------------------------------------------
+ * constructorHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int constructorHandler(Node *n) {
+
+ ParmList *l = Getattr(n, "parms");
+ String *tm;
+ Parm *p;
+ int i;
+ String *function_code = NewString("");
+ String *helper_code = NewString(""); // Holds code for the constructor helper method generated only when the javain typemap has code in the pre or post attributes
+ String *helper_args = NewString("");
+ String *pre_code = NewString("");
+ String *post_code = NewString("");
+ String *im_return_type = NewString("");
+ bool feature_director = (parentNode(n) && Swig_directorclass(n));
+
+ Language::constructorHandler(n);
+
+ // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java
+ if (Getattr(n, "overload:ignore"))
+ return SWIG_OK;
+
+ if (proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *mangled_overname = Swig_name_construct(overloaded_name);
+ String *imcall = NewString("");
+
+ const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
+ methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
+
+ tm = Getattr(n, "tmap:jtype"); // typemaps were attached earlier to the node
+ Printf(im_return_type, "%s", tm);
+
+ Printf(function_code, " %s %s(", methodmods, proxy_class_name);
+ Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name);
+
+ Printv(imcall, imclass_name, ".", mangled_overname, "(", NIL);
+
+ /* Attach the non-standard typemaps to the parameter list */
+ Swig_typemap_attach_parms("in", l, NULL);
+ Swig_typemap_attach_parms("jtype", l, NULL);
+ Swig_typemap_attach_parms("jstype", l, NULL);
+ Swig_typemap_attach_parms("javain", l, NULL);
+
+ emit_mark_varargs(l);
+
+ int gencomma = 0;
+
+ /* Output each parameter */
+ for (i = 0, p = l; p; i++) {
+
+ /* Ignored varargs */
+ if (checkAttribute(p, "varargs:ignore", "1")) {
+ p = nextSibling(p);
+ continue;
+ }
+
+ /* Ignored parameters */
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *param_type = NewString("");
+
+ /* Get the Java parameter type */
+ if ((tm = Getattr(p, "tmap:jstype"))) {
+ substituteClassname(pt, tm);
+ Printf(param_type, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ if (gencomma)
+ Printf(imcall, ", ");
+
+ String *arg = makeParameterName(n, p, i, false);
+
+ // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in JNI function (in intermediary class)
+ if ((tm = Getattr(p, "tmap:javain"))) {
+ addThrows(n, "tmap:javain", p);
+ substituteClassname(pt, tm);
+ Replaceall(tm, "$javainput", arg);
+ String *pre = Getattr(p, "tmap:javain:pre");
+ if (pre) {
+ substituteClassname(pt, pre);
+ Replaceall(pre, "$javainput", arg);
+ if (Len(pre_code) > 0)
+ Printf(pre_code, "\n");
+ Printv(pre_code, pre, NIL);
+ }
+ String *post = Getattr(p, "tmap:javain:post");
+ if (post) {
+ substituteClassname(pt, post);
+ Replaceall(post, "$javainput", arg);
+ if (Len(post_code) > 0)
+ Printf(post_code, "\n");
+ Printv(post_code, post, NIL);
+ }
+ Printv(imcall, tm, NIL);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ /* Add parameter to proxy function */
+ if (gencomma) {
+ Printf(function_code, ", ");
+ Printf(helper_code, ", ");
+ Printf(helper_args, ", ");
+ }
+ Printf(function_code, "%s %s", param_type, arg);
+ Printf(helper_code, "%s %s", param_type, arg);
+ Printf(helper_args, "%s", arg);
+ ++gencomma;
+
+ if (prematureGarbageCollectionPreventionParameter(pt, p)) {
+ String *pgcppname = Getattr(p, "tmap:javain:pgcppname");
+ if (pgcppname) {
+ String *argname = Copy(pgcppname);
+ Replaceall(argname, "$javainput", arg);
+ Printf(imcall, ", %s", argname);
+ Delete(argname);
+ } else {
+ Printf(imcall, ", %s", arg);
+ }
+ }
+
+ Delete(arg);
+ Delete(param_type);
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ Printf(imcall, ")");
+
+ Printf(function_code, ")");
+ Printf(helper_code, ")");
+ generateThrowsClause(n, function_code);
+
+ /* Insert the javaconstruct typemap, doing the replacement for $directorconnect, as needed */
+ Hash *attributes = NewHash();
+ String *construct_tm = Copy(typemapLookup(n, "javaconstruct", Getattr(n, "name"),
+ WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF, attributes));
+ if (construct_tm) {
+ if (!feature_director) {
+ Replaceall(construct_tm, "$directorconnect", "");
+ } else {
+ String *connect_attr = Getattr(attributes, "tmap:javaconstruct:directorconnect");
+
+ if (connect_attr) {
+ Replaceall(construct_tm, "$directorconnect", connect_attr);
+ } else {
+ Swig_warning(WARN_JAVA_NO_DIRECTORCONNECT_ATTR, input_file, line_number, "\"directorconnect\" attribute missing in %s \"javaconstruct\" typemap.\n",
+ Getattr(n, "name"));
+ Replaceall(construct_tm, "$directorconnect", "");
+ }
+ }
+
+ Printv(function_code, " ", construct_tm, "\n", NIL);
+ }
+
+ bool is_pre_code = Len(pre_code) > 0;
+ bool is_post_code = Len(post_code) > 0;
+ if (is_pre_code || is_post_code) {
+ generateThrowsClause(n, helper_code);
+ Printf(helper_code, " {\n");
+ if (is_pre_code) {
+ Printv(helper_code, pre_code, "\n", NIL);
+ }
+ if (is_post_code) {
+ Printf(helper_code, " try {\n");
+ Printv(helper_code, " return ", imcall, ";\n", NIL);
+ Printv(helper_code, " } finally {\n", post_code, "\n }", NIL);
+ } else {
+ Printv(helper_code, " return ", imcall, ";", NIL);
+ }
+ Printf(helper_code, "\n }\n");
+ String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args);
+ Printv(proxy_class_code, helper_code, "\n", NIL);
+ Replaceall(function_code, "$imcall", helper_name);
+ Delete(helper_name);
+ } else {
+ Replaceall(function_code, "$imcall", imcall);
+ }
+
+ Printv(proxy_class_code, function_code, "\n", NIL);
+
+ Delete(helper_args);
+ Delete(im_return_type);
+ Delete(pre_code);
+ Delete(post_code);
+ Delete(construct_tm);
+ Delete(attributes);
+ Delete(overloaded_name);
+ Delete(imcall);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * destructorHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int destructorHandler(Node *n) {
+ Language::destructorHandler(n);
+ String *symname = Getattr(n, "sym:name");
+
+ if (proxy_flag) {
+ Printv(destructor_call, imclass_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL);
+ generateThrowsClause(n, destructor_throws_clause);
+ }
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * membervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int membervariableHandler(Node *n) {
+ variable_name = Getattr(n, "sym:name");
+ wrapping_member_flag = true;
+ variable_wrapper_flag = true;
+ Language::membervariableHandler(n);
+ wrapping_member_flag = false;
+ variable_wrapper_flag = false;
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * staticmembervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ variable_name = Getattr(n, "sym:name");
+ wrapping_member_flag = true;
+ static_flag = true;
+ Language::staticmembervariableHandler(n);
+ wrapping_member_flag = false;
+ static_flag = false;
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberconstantHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int memberconstantHandler(Node *n) {
+ variable_name = Getattr(n, "sym:name");
+ wrapping_member_flag = true;
+ Language::memberconstantHandler(n);
+ wrapping_member_flag = false;
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getOverloadedName()
+ * ----------------------------------------------------------------------------- */
+
+ String *getOverloadedName(Node *n) {
+
+ /* Although JNI functions are designed to handle overloaded Java functions,
+ * a Java long is used for all classes in the SWIG intermediary class.
+ * The intermediary class methods are thus mangled when overloaded to give
+ * a unique name. */
+ String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name"));
+
+ if (Getattr(n, "sym:overloaded")) {
+ Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
+ }
+
+ return overloaded_name;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * moduleClassFunctionHandler()
+ * ----------------------------------------------------------------------------- */
+
+ void moduleClassFunctionHandler(Node *n) {
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *tm;
+ Parm *p;
+ int i;
+ String *imcall = NewString("");
+ String *return_type = NewString("");
+ String *function_code = NewString("");
+ int num_arguments = 0;
+ int num_required = 0;
+ String *overloaded_name = getOverloadedName(n);
+ String *func_name = NULL;
+ bool setter_flag = false;
+ String *pre_code = NewString("");
+ String *post_code = NewString("");
+
+ if (l) {
+ if (SwigType_type(Getattr(l, "type")) == T_VOID) {
+ l = nextSibling(l);
+ }
+ }
+
+ /* Attach the non-standard typemaps to the parameter list */
+ Swig_typemap_attach_parms("jstype", l, NULL);
+ Swig_typemap_attach_parms("javain", l, NULL);
+
+ /* Get return types */
+ if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) {
+ substituteClassname(t, tm);
+ Printf(return_type, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ /* Change function name for global variables */
+ if (proxy_flag && global_variable_flag) {
+ // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name
+ func_name = NewString("");
+ setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(variable_name)) == 0);
+ if (setter_flag)
+ Printf(func_name, "set");
+ else
+ Printf(func_name, "get");
+ Putc(toupper((int) *Char(variable_name)), func_name);
+ Printf(func_name, "%s", Char(variable_name) + 1);
+ } else {
+ func_name = Copy(Getattr(n, "sym:name"));
+ }
+
+ /* Start generating the function */
+ const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
+ methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
+ Printf(function_code, " %s static %s %s(", methodmods, return_type, func_name);
+ Printv(imcall, imclass_name, ".", overloaded_name, "(", NIL);
+
+ /* Get number of required and total arguments */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+
+ bool global_or_member_variable = global_variable_flag || (wrapping_member_flag && !enum_constant_flag);
+ int gencomma = 0;
+
+ /* Output each parameter */
+ for (i = 0, p = l; i < num_arguments; i++) {
+
+ /* Ignored parameters */
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *param_type = NewString("");
+
+ /* Get the Java parameter type */
+ if ((tm = Getattr(p, "tmap:jstype"))) {
+ substituteClassname(pt, tm);
+ Printf(param_type, "%s", tm);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ if (gencomma)
+ Printf(imcall, ", ");
+
+ String *arg = makeParameterName(n, p, i, global_or_member_variable);
+
+ // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in JNI function (in intermediary class)
+ if ((tm = Getattr(p, "tmap:javain"))) {
+ addThrows(n, "tmap:javain", p);
+ substituteClassname(pt, tm);
+ Replaceall(tm, "$javainput", arg);
+ String *pre = Getattr(p, "tmap:javain:pre");
+ if (pre) {
+ substituteClassname(pt, pre);
+ Replaceall(pre, "$javainput", arg);
+ if (Len(pre_code) > 0)
+ Printf(pre_code, "\n");
+ Printv(pre_code, pre, NIL);
+ }
+ String *post = Getattr(p, "tmap:javain:post");
+ if (post) {
+ substituteClassname(pt, post);
+ Replaceall(post, "$javainput", arg);
+ if (Len(post_code) > 0)
+ Printf(post_code, "\n");
+ Printv(post_code, post, NIL);
+ }
+ Printv(imcall, tm, NIL);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt, 0));
+ }
+
+ /* Add parameter to module class function */
+ if (gencomma >= 2)
+ Printf(function_code, ", ");
+ gencomma = 2;
+ Printf(function_code, "%s %s", param_type, arg);
+
+ if (prematureGarbageCollectionPreventionParameter(pt, p)) {
+ String *pgcppname = Getattr(p, "tmap:javain:pgcppname");
+ if (pgcppname) {
+ String *argname = Copy(pgcppname);
+ Replaceall(argname, "$javainput", arg);
+ Printf(imcall, ", %s", argname);
+ Delete(argname);
+ } else {
+ Printf(imcall, ", %s", arg);
+ }
+ }
+
+ p = Getattr(p, "tmap:in:next");
+ Delete(arg);
+ Delete(param_type);
+ }
+
+ Printf(imcall, ")");
+ Printf(function_code, ")");
+
+ // Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in module class)
+ if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) {
+ addThrows(n, "tmap:javaout", n);
+ bool is_pre_code = Len(pre_code) > 0;
+ bool is_post_code = Len(post_code) > 0;
+ if (is_pre_code || is_post_code) {
+ Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap
+ if (is_post_code) {
+ Insert(tm, 0, "\n try ");
+ Printv(tm, " finally {\n", post_code, "\n }", NIL);
+ } else {
+ Insert(tm, 0, "\n ");
+ }
+ if (is_pre_code) {
+ Insert(tm, 0, pre_code);
+ Insert(tm, 0, "\n");
+ }
+ Insert(tm, 0, "{");
+ Printf(tm, "\n }");
+ }
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "true");
+ else
+ Replaceall(tm, "$owner", "false");
+ substituteClassname(t, tm);
+ Replaceall(tm, "$jnicall", imcall);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
+ }
+
+ generateThrowsClause(n, function_code);
+ Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
+ Printv(module_class_code, function_code, NIL);
+
+ Delete(pre_code);
+ Delete(post_code);
+ Delete(function_code);
+ Delete(return_type);
+ Delete(imcall);
+ Delete(func_name);
+ }
+
+ /*----------------------------------------------------------------------
+ * replaceSpecialVariables()
+ *--------------------------------------------------------------------*/
+
+ virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) {
+ (void)method;
+ SwigType *type = Getattr(parm, "type");
+ substituteClassname(type, tm);
+ }
+
+ /*----------------------------------------------------------------------
+ * decodeEnumFeature()
+ * Decode the possible enum features, which are one of:
+ * %javaenum(simple)
+ * %javaenum(typeunsafe) - default
+ * %javaenum(typesafe)
+ * %javaenum(proper)
+ *--------------------------------------------------------------------*/
+
+ EnumFeature decodeEnumFeature(Node *n) {
+ EnumFeature enum_feature = TypeunsafeEnum;
+ String *feature = Getattr(n, "feature:java:enum");
+ if (feature) {
+ if (Cmp(feature, "simple") == 0)
+ enum_feature = SimpleEnum;
+ else if (Cmp(feature, "typesafe") == 0)
+ enum_feature = TypesafeEnum;
+ else if (Cmp(feature, "proper") == 0)
+ enum_feature = ProperEnum;
+ }
+ return enum_feature;
+ }
+
+ /* -----------------------------------------------------------------------
+ * enumValue()
+ * This method will return a string with an enum value to use in Java generated
+ * code. If the %javaconst feature is not used, the string will contain the intermediary
+ * class call to obtain the enum value. The intermediary class and JNI methods to obtain
+ * the enum value will be generated. Otherwise the C/C++ enum value will be used if there
+ * is one and hopefully it will compile as Java code - e.g. 20 as in: enum E{e=20};
+ * The %javaconstvalue feature overrides all other ways to generate the constant value.
+ * The caller must delete memory allocated for the returned string.
+ * ------------------------------------------------------------------------ */
+
+ String *enumValue(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+
+ // Check for the %javaconstvalue feature
+ String *value = Getattr(n, "feature:java:constvalue");
+
+ if (!value) {
+ // The %javaconst feature determines how the constant value is obtained
+ int const_feature_flag = GetFlag(n, "feature:java:const");
+
+ if (const_feature_flag) {
+ // Use the C syntax to make a true Java constant and hope that it compiles as Java code
+ value = Getattr(n, "enumvalue") ? Copy(Getattr(n, "enumvalue")) : Copy(Getattr(n, "enumvalueex"));
+ } else {
+ // Get the enumvalue from a JNI call
+ if (!getCurrentClass() || !cparse_cplusplus || !proxy_flag) {
+ // Strange hack to change the name
+ Setattr(n, "name", Getattr(n, "value")); /* for wrapping of enums in a namespace when emit_action is used */
+ constantWrapper(n);
+ value = NewStringf("%s.%s()", imclass_name, Swig_name_get(symname));
+ } else {
+ memberconstantHandler(n);
+ value = NewStringf("%s.%s()", imclass_name, Swig_name_get(Swig_name_member(proxy_class_name, symname)));
+ }
+ }
+ }
+ return value;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getEnumName()
+ *
+ * If jnidescriptor is set, inner class names are separated with '$' otherwise a '.'
+ * ----------------------------------------------------------------------------- */
+
+ String *getEnumName(SwigType *t, bool jnidescriptor) {
+ Node *enum_name = NULL;
+ Node *n = enumLookup(t);
+ if (n) {
+ String *symname = Getattr(n, "sym:name");
+ if (symname) {
+ // Add in class scope when referencing enum if not a global enum
+ String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name"));
+ String *proxyname = 0;
+ if (scopename_prefix) {
+ proxyname = getProxyName(scopename_prefix);
+ }
+ if (proxyname) {
+ const char *class_separator = jnidescriptor ? "$" : ".";
+ enum_name = NewStringf("%s%s%s", proxyname, class_separator, symname);
+ } else {
+ enum_name = NewStringf("%s", symname);
+ }
+ Delete(scopename_prefix);
+ }
+ }
+
+ return enum_name;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * substituteClassname()
+ *
+ * Substitute the special variable $javaclassname with the proxy class name for classes/structs/unions
+ * that SWIG knows about. Also substitutes enums with enum name.
+ * 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 - typemap contents that might contain the special variable to be replaced
+ * jnidescriptor - if set, inner class names are separated with '$' otherwise a '.'
+ * Outputs:
+ * tm - typemap contents complete with the special variable substitution
+ * Return:
+ * substitution_performed - flag indicating if a substitution was performed
+ * ----------------------------------------------------------------------------- */
+
+ bool substituteClassname(SwigType *pt, String *tm, bool jnidescriptor = false) {
+ bool substitution_performed = false;
+ SwigType *type = Copy(SwigType_typedef_resolve_all(pt));
+ SwigType *strippedtype = SwigType_strip_qualifiers(type);
+
+ if (Strstr(tm, "$javaclassname")) {
+ SwigType *classnametype = Copy(strippedtype);
+ substituteClassnameSpecialVariable(classnametype, tm, "$javaclassname", jnidescriptor);
+ substitution_performed = true;
+ Delete(classnametype);
+ }
+ if (Strstr(tm, "$*javaclassname")) {
+ SwigType *classnametype = Copy(strippedtype);
+ Delete(SwigType_pop(classnametype));
+ substituteClassnameSpecialVariable(classnametype, tm, "$*javaclassname", jnidescriptor);
+ substitution_performed = true;
+ Delete(classnametype);
+ }
+ if (Strstr(tm, "$&javaclassname")) {
+ SwigType *classnametype = Copy(strippedtype);
+ SwigType_add_pointer(classnametype);
+ substituteClassnameSpecialVariable(classnametype, tm, "$&javaclassname", jnidescriptor);
+ substitution_performed = true;
+ Delete(classnametype);
+ }
+
+ Delete(strippedtype);
+ Delete(type);
+
+ return substitution_performed;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * substituteClassnameSpecialVariable()
+ * ----------------------------------------------------------------------------- */
+
+ void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable, bool jnidescriptor) {
+ if (SwigType_isenum(classnametype)) {
+ String *enumname = getEnumName(classnametype, jnidescriptor);
+ if (enumname)
+ Replaceall(tm, classnamespecialvariable, enumname);
+ else
+ Replaceall(tm, classnamespecialvariable, NewStringf("int"));
+ } else {
+ String *classname = getProxyName(classnametype);
+ if (classname) {
+ Replaceall(tm, classnamespecialvariable, classname); // getProxyName() works for pointers to classes too
+ } else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
+ String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype));
+ Replaceall(tm, classnamespecialvariable, descriptor);
+
+ // Add to hash table so that the type wrapper classes can be created later
+ Setattr(swig_types_hash, descriptor, classnametype);
+ Delete(descriptor);
+ }
+ }
+ }
+
+ /* -----------------------------------------------------------------------------
+ * makeParameterName()
+ *
+ * Inputs:
+ * n - Node
+ * p - parameter node
+ * arg_num - parameter argument number
+ * setter - set this flag when wrapping variables
+ * Return:
+ * arg - a unique parameter name
+ * ----------------------------------------------------------------------------- */
+
+ String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter) {
+
+ String *arg = 0;
+ String *pn = Getattr(p, "name");
+
+ // Use C parameter name unless it is a duplicate or an empty parameter name
+ int count = 0;
+ ParmList *plist = Getattr(n, "parms");
+ while (plist) {
+ if ((Cmp(pn, Getattr(plist, "name")) == 0))
+ count++;
+ plist = nextSibling(plist);
+ }
+ String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0;
+ arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn);
+
+ if (setter && Cmp(arg, "self") != 0) {
+ // Note that for setters the parameter name is always set but sometimes includes C++
+ // scope resolution, so we need to strip off the scope resolution to make a valid name.
+ Delete(arg);
+ arg = NewString("value"); //Swig_scopename_last(pn);
+ }
+
+ return arg;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitTypeWrapperClass()
+ * ----------------------------------------------------------------------------- */
+
+ void emitTypeWrapperClass(String *classname, SwigType *type) {
+ Node *n = NewHash();
+ Setfile(n, input_file);
+ Setline(n, line_number);
+
+ String *swigtype = NewString("");
+ String *filen = NewStringf("%s%s.java", SWIG_output_directory(), classname);
+ File *f_swigtype = NewFile(filen, "w", SWIG_output_files());
+ if (!f_swigtype) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Append(filenames_list, Copy(filen));
+ Delete(filen);
+ filen = NULL;
+
+ // Start writing out the type wrapper class file
+ emitBanner(f_swigtype);
+
+ if (Len(package) > 0)
+ Printf(f_swigtype, "package %s;\n", package);
+
+ // Pure Java baseclass and interfaces
+ const String *pure_baseclass = typemapLookup(n, "javabase", type, WARN_NONE);
+ const String *pure_interfaces = typemapLookup(n, "javainterfaces", type, WARN_NONE);
+
+ // Emit the class
+ Printv(swigtype, typemapLookup(n, "javaimports", type, WARN_NONE), // Import statements
+ "\n", typemapLookup(n, "javaclassmodifiers", type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
+ " $javaclassname", // Class name and bases
+ *Char(pure_baseclass) ? " extends " : "", pure_baseclass, *Char(pure_interfaces) ? // Interfaces
+ " implements " : "", pure_interfaces, " {", typemapLookup(n, "javabody", type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
+ typemapLookup(n, "javacode", type, WARN_NONE), // extra Java code
+ "}\n", "\n", NIL);
+
+ Replaceall(swigtype, "$javaclassname", classname);
+ Replaceall(swigtype, "$module", module_class_name);
+ Replaceall(swigtype, "$imclassname", imclass_name);
+ Printv(f_swigtype, swigtype, NIL);
+
+ Close(f_swigtype);
+ Delete(swigtype);
+ Delete(n);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * typemapLookup()
+ * n - for input only and must contain info for Getfile(n) and Getline(n) to work
+ * tmap_method - typemap method name
+ * type - typemap type to lookup
+ * warning - warning number to issue if no typemaps found
+ * typemap_attributes - the typemap attributes are attached to this node and will
+ * also be used for temporary storage if non null
+ * return is never NULL, unlike Swig_typemap_lookup()
+ * ----------------------------------------------------------------------------- */
+
+ const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0) {
+ Node *node = !typemap_attributes ? NewHash() : typemap_attributes;
+ Setattr(node, "type", type);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
+ if (!tm) {
+ tm = empty_string;
+ if (warning != WARN_NONE)
+ Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0));
+ }
+ if (!typemap_attributes)
+ Delete(node);
+ return tm;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * addThrows()
+ *
+ * Adds exception classes to a throws list. The throws list is the list of classes
+ * that will form the Java throws clause. Mainly for checked exceptions.
+ * ----------------------------------------------------------------------------- */
+
+ void addThrows(Node *n, const String *attribute, Node *parameter) {
+ // Get the comma separated exception classes for the throws clause - held in typemap/feature's "throws" attribute
+ String *throws_attribute = NewStringf("%s:throws", attribute);
+ String *throws = Getattr(parameter, throws_attribute);
+
+ if (throws && Len(throws) > 0) {
+ String *throws_list = Getattr(n, "java:throwslist");
+ if (!throws_list) {
+ throws_list = NewList();
+ Setattr(n, "java:throwslist", throws_list);
+ }
+ // Put the exception classes in the throws clause into a temporary List
+ List *temp_classes_list = Split(throws, ',', INT_MAX);
+
+ // Add the exception classes to the node throws list, but don't duplicate if already in list
+ if (temp_classes_list && Len(temp_classes_list) > 0) {
+ for (Iterator cls = First(temp_classes_list); cls.item; cls = Next(cls)) {
+ String *exception_class = NewString(cls.item);
+ Replaceall(exception_class, " ", ""); // remove spaces
+ Replaceall(exception_class, "\t", ""); // remove tabs
+ if (Len(exception_class) > 0) {
+ // $javaclassname substitution
+ SwigType *pt = Getattr(parameter, "type");
+ substituteClassname(pt, exception_class);
+
+ // Don't duplicate the Java exception class in the throws clause
+ bool found_flag = false;
+ for (Iterator item = First(throws_list); item.item; item = Next(item)) {
+ if (Strcmp(item.item, exception_class) == 0)
+ found_flag = true;
+ }
+ if (!found_flag)
+ Append(throws_list, exception_class);
+ }
+ Delete(exception_class);
+ }
+ }
+ Delete(temp_classes_list);
+ }
+ Delete(throws_attribute);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * generateThrowsClause()
+ *
+ * Generates throws clause for checked exception
+ * ----------------------------------------------------------------------------- */
+
+ void generateThrowsClause(Node *n, String *code) {
+ // Add the throws clause into code
+ List *throws_list = Getattr(n, "java:throwslist");
+ if (throws_list) {
+ Iterator cls = First(throws_list);
+ Printf(code, " throws %s", cls.item);
+ while ((cls = Next(cls)).item)
+ Printf(code, ", %s", cls.item);
+ }
+ }
+
+ /* -----------------------------------------------------------------------------
+ * prematureGarbageCollectionPreventionParameter()
+ *
+ * Get the proxy class name for use in an additional generated parameter. The
+ * additional parameter is added to a native method call purely to prevent
+ * premature garbage collection of proxy classes which pass their C++ class pointer
+ * in a Java long to the JNI layer.
+ * ----------------------------------------------------------------------------- */
+
+ String *prematureGarbageCollectionPreventionParameter(SwigType *t, Parm *p) {
+ String *proxyClassName = 0;
+ String *jtype = NewString(Getattr(p, "tmap:jtype"));
+
+ // Strip C comments
+ String *stripped_jtype = Swig_strip_c_comments(jtype);
+ if (stripped_jtype) {
+ Delete(jtype);
+ jtype = stripped_jtype;
+ }
+
+ // Remove whitespace
+ Replaceall(jtype, " ", "");
+ Replaceall(jtype, "\t", "");
+
+ if (Cmp(jtype, "long") == 0) {
+ if (proxy_flag) {
+ if (!GetFlag(p, "tmap:jtype:nopgcpp") && !nopgcpp_flag) {
+ Node *n = classLookup(t);
+ if (n) {
+ // Found a struct/class parameter passed by value, reference, pointer, or pointer reference
+ proxyClassName = Getattr(n, "sym:name");
+ } else {
+ // Look for proxy class parameters passed to C++ layer using non-default typemaps, ie not one of above types
+ String *jstype = NewString(Getattr(p, "tmap:jstype"));
+ if (jstype) {
+ Hash *classes = getClassHash();
+ if (classes) {
+ // Strip C comments
+ String *stripped_jstype = Swig_strip_c_comments(jstype);
+ if (stripped_jstype) {
+ Delete(jstype);
+ jstype = stripped_jstype;
+ }
+ // Remove whitespace
+ Replaceall(jstype, " ", "");
+ Replaceall(jstype, "\t", "");
+
+ Iterator ki;
+ for (ki = First(classes); ki.key; ki = Next(ki)) {
+ Node *cls = ki.item;
+ if (cls && !Getattr(cls, "feature:ignore")) {
+ String *symname = Getattr(cls, "sym:name");
+ if (symname && Strcmp(symname, jstype) == 0) {
+ proxyClassName = symname;
+ }
+ }
+ }
+ }
+ }
+ Delete(jstype);
+ }
+ }
+ }
+ }
+ Delete(jtype);
+ return proxyClassName;
+ }
+
+ /*----------------------------------------------------------------------
+ * Start of director methods
+ *--------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------
+ * getUpcallJNIMethod()
+ *--------------------------------------------------------------------*/
+
+ String *getUpcallJNIMethod(String *descrip) {
+ static struct {
+ char code;
+ const char *method;
+ } upcall_methods[] = {
+ {
+ 'B', "CallStaticByteMethod"}, {
+ 'C', "CallStaticCharMethod"}, {
+ 'D', "CallStaticDoubleMethod"}, {
+ 'F', "CallStaticFloatMethod"}, {
+ 'I', "CallStaticIntMethod"}, {
+ 'J', "CallStaticLongMethod"}, {
+ 'L', "CallStaticObjectMethod"}, {
+ 'S', "CallStaticShortMethod"}, {
+ 'V', "CallStaticVoidMethod"}, {
+ 'Z', "CallStaticBooleanMethod"}, {
+ '[', "CallStaticObjectMethod"}
+ };
+
+ char code;
+ int i;
+
+ code = *Char(descrip);
+ for (i = 0; i < (int) (sizeof(upcall_methods) / sizeof(upcall_methods[0])); ++i)
+ if (code == upcall_methods[i].code)
+ return NewString(upcall_methods[i].method);
+ return NULL;
+ }
+
+ /*----------------------------------------------------------------------
+ * emitDirectorUpcalls()
+ *--------------------------------------------------------------------*/
+
+ void emitDirectorUpcalls() {
+ if (n_dmethods) {
+ Wrapper *w = NewWrapper();
+ String *jni_imclass_name = makeValidJniName(imclass_name);
+ String *swig_module_init = NewString("swig_module_init");
+ String *swig_module_init_jni = makeValidJniName(swig_module_init);
+ String *dmethod_data = NewString("");
+ int n_methods = 0;
+ Iterator udata_iter;
+
+ udata_iter = First(dmethods_seq);
+ while (udata_iter.item) {
+ UpcallData *udata = udata_iter.item;
+ Printf(dmethod_data, " { \"%s\", \"%s\" }", Getattr(udata, "imclass_method"), Getattr(udata, "imclass_fdesc"));
+ ++n_methods;
+
+ udata_iter = Next(udata_iter);
+
+ if (udata_iter.item)
+ Putc(',', dmethod_data);
+ Putc('\n', dmethod_data);
+ }
+
+ Printf(f_runtime, "namespace Swig {\n");
+ Printf(f_runtime, " static jclass jclass_%s = NULL;\n", imclass_name);
+ Printf(f_runtime, " static jmethodID director_methids[%d];\n", n_methods);
+ Printf(f_runtime, "}\n");
+
+ Printf(w->def, "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls) {", jnipackage, jni_imclass_name, swig_module_init_jni);
+ Printf(w->code, "static struct {\n");
+ Printf(w->code, " const char *method;\n");
+ Printf(w->code, " const char *signature;\n");
+ Printf(w->code, "} methods[%d] = {\n", n_methods);
+ Printv(w->code, dmethod_data, NIL);
+ Printf(w->code, "};\n");
+
+ Wrapper_add_local(w, "i", "int i");
+
+ Printf(w->code, "Swig::jclass_%s = (jclass) jenv->NewGlobalRef(jcls);\n", imclass_name);
+ Printf(w->code, "if (!Swig::jclass_%s) return;\n", imclass_name);
+ Printf(w->code, "for (i = 0; i < (int) (sizeof(methods)/sizeof(methods[0])); ++i) {\n");
+ Printf(w->code, " Swig::director_methids[i] = jenv->GetStaticMethodID(jcls, methods[i].method, methods[i].signature);\n");
+ Printf(w->code, " if (!Swig::director_methids[i]) return;\n");
+ Printf(w->code, "}\n");
+
+ Printf(w->code, "}\n");
+
+ Wrapper_print(w, f_wrappers);
+ Delete(dmethod_data);
+ Delete(swig_module_init_jni);
+ Delete(swig_module_init);
+ Delete(jni_imclass_name);
+ DelWrapper(w);
+ }
+ }
+
+ /*----------------------------------------------------------------------
+ * emitDirectorExtraMethods()
+ *
+ * This is where the $javaclassname_director_connect is
+ * generated.
+ *--------------------------------------------------------------------*/
+ void emitDirectorExtraMethods(Node *n) {
+ if (!Swig_directorclass(n))
+ return;
+
+ // Output the director connect method:
+ String *jni_imclass_name = makeValidJniName(imclass_name);
+ String *norm_name = SwigType_namestr(Getattr(n, "name"));
+ String *swig_director_connect = NewStringf("%s_director_connect", proxy_class_name);
+ String *swig_director_connect_jni = makeValidJniName(swig_director_connect);
+ String *sym_name = Getattr(n, "sym:name");
+ Wrapper *code_wrap;
+
+ Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr, boolean mem_own, boolean weak_global);\n",
+ swig_director_connect, proxy_class_name);
+
+ code_wrap = NewWrapper();
+ Printf(code_wrap->def,
+ "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jswig_mem_own, "
+ "jboolean jweak_global) {\n", jnipackage, jni_imclass_name, swig_director_connect_jni);
+ Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name);
+ Printf(code_wrap->code, " (void)jcls;\n");
+ Printf(code_wrap->code, " SwigDirector_%s *director = dynamic_cast<SwigDirector_%s *>(obj);\n", sym_name, sym_name);
+ Printf(code_wrap->code, " if (director) {\n");
+ Printf(code_wrap->code, " director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), "
+ "(jswig_mem_own == JNI_TRUE), (jweak_global == JNI_TRUE));\n");
+ Printf(code_wrap->code, " }\n");
+ Printf(code_wrap->code, "}\n");
+
+ Wrapper_print(code_wrap, f_wrappers);
+ DelWrapper(code_wrap);
+
+ Delete(swig_director_connect_jni);
+ Delete(swig_director_connect);
+
+ // Output the swigReleaseOwnership, swigTakeOwnership methods:
+ String *changeown_method_name = NewStringf("%s_change_ownership", proxy_class_name);
+ String *changeown_jnimethod_name = makeValidJniName(changeown_method_name);
+
+ Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr, boolean take_or_release);\n", changeown_method_name, proxy_class_name);
+
+ code_wrap = NewWrapper();
+ Printf(code_wrap->def,
+ "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) {\n",
+ jnipackage, jni_imclass_name, changeown_jnimethod_name);
+ Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name);
+ Printf(code_wrap->code, " SwigDirector_%s *director = dynamic_cast<SwigDirector_%s *>(obj);\n", sym_name, sym_name);
+ Printf(code_wrap->code, " (void)jcls;\n");
+ Printf(code_wrap->code, " if (director) {\n");
+ Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\n");
+ Printf(code_wrap->code, " }\n");
+ Printf(code_wrap->code, "}\n");
+
+ Wrapper_print(code_wrap, f_wrappers);
+ DelWrapper(code_wrap);
+
+ Delete(changeown_method_name);
+ Delete(changeown_jnimethod_name);
+ Delete(norm_name);
+ Delete(jni_imclass_name);
+ }
+
+ /*----------------------------------------------------------------------
+ * emitCodeTypemap()
+ *
+ * Output a code typemap that uses $methodname and $jnicall, as used
+ * in the directordisconnect, director_release and director_take
+ * typemaps.
+ *--------------------------------------------------------------------*/
+
+ void emitCodeTypemap(Node *n, bool derived, SwigType *lookup_type, const String *typemap, const String *methodname, const String *jnicall) {
+ const String *tm = NULL;
+ Node *tmattrs = NewHash();
+ String *lookup_tmname = NewString(typemap);
+ String *method_attr_name;
+ String *method_attr;
+
+ if (derived) {
+ Append(lookup_tmname, "_derived");
+ }
+
+ tm = typemapLookup(n, lookup_tmname, lookup_type, WARN_NONE, tmattrs);
+ method_attr_name = NewStringf("tmap:%s:%s", lookup_tmname, methodname);
+ method_attr = Getattr(tmattrs, method_attr_name);
+
+ if (*Char(tm)) {
+ if (method_attr) {
+ String *codebody = Copy(tm);
+ Replaceall(codebody, "$methodname", method_attr);
+ Replaceall(codebody, "$jnicall", jnicall);
+ Append(proxy_class_def, codebody);
+ Delete(codebody);
+ } else {
+ Swig_error(input_file, line_number, "No %s method name attribute for %s\n", lookup_tmname, proxy_class_name);
+ }
+ } else {
+ Swig_error(input_file, line_number, "No %s typemap for %s\n", lookup_tmname, proxy_class_name);
+ }
+
+ Delete(tmattrs);
+ Delete(lookup_tmname);
+ // Delete(method_attr);
+ }
+
+ /* ---------------------------------------------------------------
+ * Canonicalize the JNI field descriptor
+ *
+ * Replace the $javapackage and $javaclassname family of special
+ * variables with the desired package and Java proxy name as
+ * required in the JNI field descriptors.
+ *
+ * !!SFM!! If $packagepath occurs in the field descriptor, but
+ * package_path isn't set (length == 0), then strip it and the
+ * optional trailing '/' from the resulting name.
+ *
+ * --------------------------------------------------------------- */
+
+ String *canonicalizeJNIDescriptor(String *descriptor_in, Parm *p) {
+ String *pkg_path = Swig_typemap_lookup("javapackage", p, "", 0);
+ SwigType *type = Getattr(p, "type");
+
+ if (pkg_path && Len(pkg_path) != 0) {
+ Replaceall(pkg_path, ".", "/");
+ } else
+ pkg_path = package_path;
+
+ String *descriptor_out = Copy(descriptor_in);
+
+ if (Len(pkg_path) > 0) {
+ Replaceall(descriptor_out, "$packagepath", pkg_path);
+ } else {
+ Replaceall(descriptor_out, "$packagepath/", empty_string);
+ Replaceall(descriptor_out, "$packagepath", empty_string);
+ }
+
+ substituteClassname(type, descriptor_out, true);
+
+ if (pkg_path != package_path)
+ Delete(pkg_path);
+
+ return descriptor_out;
+ }
+
+ /* ---------------------------------------------------------------
+ * classDirectorMethod()
+ *
+ * Emit a virtual director method to pass a method call on to the
+ * underlying Java object.
+ *
+ * --------------------------------------------------------------- */
+
+ int classDirectorMethod(Node *n, Node *parent, String *super) {
+ String *empty_str = NewString("");
+ String *classname = Getattr(parent, "sym:name");
+ String *c_classname = Getattr(parent, "name");
+ String *name = Getattr(n, "name");
+ String *symname = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ SwigType *returntype = Getattr(n, "returntype");
+ String *overloaded_name = getOverloadedName(n);
+ String *storage = Getattr(n, "storage");
+ String *value = Getattr(n, "value");
+ String *decl = Getattr(n, "decl");
+ String *declaration = NewString("");
+ String *tm;
+ Parm *p;
+ int i;
+ Wrapper *w = NewWrapper();
+ ParmList *l = Getattr(n, "parms");
+ bool is_void = !(Cmp(returntype, "void"));
+ String *qualified_return = NewString("");
+ bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0")));
+ int status = SWIG_OK;
+ bool output_director = true;
+ String *dirclassname = directorClassName(parent);
+ String *qualified_name = NewStringf("%s::%s", dirclassname, name);
+ String *jnidesc = NewString("");
+ String *classdesc = NewString("");
+ String *jniret_desc = NewString("");
+ String *classret_desc = NewString("");
+ SwigType *c_ret_type = NULL;
+ String *jupcall_args = NewString("swigjobj");
+ String *imclass_dmethod;
+ String *callback_def = NewString("");
+ String *callback_code = NewString("");
+ String *imcall_args = NewString("");
+ int gencomma = 0;
+ int classmeth_off = curr_class_dmethod - first_class_dmethod;
+ bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
+
+ // Kludge Alert: functionWrapper sets sym:overload properly, but it
+ // isn't at this point, so we have to manufacture it ourselves. At least
+ // we're consistent with the sym:overload name in functionWrapper. (?? when
+ // does the overloaded method name get set?)
+
+ imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(classname, overloaded_name));
+
+ if (returntype) {
+
+ qualified_return = SwigType_rcaststr(returntype, "c_result");
+
+ if (!is_void && (!ignored_method || pure_virtual)) {
+ if (!SwigType_isclass(returntype)) {
+ if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
+ String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
+ Delete(construct_result);
+ } else {
+ String *base_typename = SwigType_base(returntype);
+ String *resolved_typename = SwigType_typedef_resolve_all(base_typename);
+ Symtab *symtab = Getattr(n, "sym:symtab");
+ Node *typenode = Swig_symbol_clookup(resolved_typename, symtab);
+
+ if (SwigType_ispointer(returntype) || (typenode && Getattr(typenode, "abstract"))) {
+ /* initialize pointers to something sane. Same for abstract
+ classes when a reference is returned. */
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
+ } else {
+ /* If returning a reference, initialize the pointer to a sane
+ default - if a Java exception occurs, then the pointer returns
+ something other than a NULL-initialized reference. */
+ String *non_ref_type = Copy(returntype);
+
+ /* Remove reference and const qualifiers */
+ Replaceall(non_ref_type, "r.", "");
+ Replaceall(non_ref_type, "q(const).", "");
+ Wrapper_add_localv(w, "result_default", "static", SwigType_str(non_ref_type, "result_default"), "=", SwigType_str(non_ref_type, "()"), NIL);
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= &result_default", NIL);
+
+ Delete(non_ref_type);
+ }
+
+ Delete(base_typename);
+ Delete(resolved_typename);
+ }
+ } else {
+ SwigType *vt;
+
+ vt = cplus_value_type(returntype);
+ if (!vt) {
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL);
+ } else {
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(vt, "c_result"), NIL);
+ Delete(vt);
+ }
+ }
+ }
+
+ /* Create the intermediate class wrapper */
+ Parm *tp = NewParmFromNode(returntype, empty_str, n);
+
+ tm = Swig_typemap_lookup("jtype", tp, "", 0);
+ if (tm) {
+ Printf(callback_def, " public static %s %s(%s self", tm, imclass_dmethod, classname);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(returntype, 0));
+ }
+
+ String *cdesc = NULL;
+ SwigType *covariant = Getattr(n, "covariant");
+ SwigType *adjustedreturntype = covariant ? covariant : returntype;
+ Parm *adjustedreturntypeparm = NewParmFromNode(adjustedreturntype, empty_str, n);
+
+ if ((tm = Swig_typemap_lookup("directorin", adjustedreturntypeparm, "", 0))
+ && (cdesc = Getattr(adjustedreturntypeparm, "tmap:directorin:descriptor"))) {
+
+ // Note that in the case of polymorphic (covariant) return types, the
+ // method's return type is changed to be the base of the C++ return
+ // type
+ String *jnidesc_canon = canonicalizeJNIDescriptor(cdesc, adjustedreturntypeparm);
+ Append(classret_desc, jnidesc_canon);
+ Delete(jnidesc_canon);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+
+ /* Get the JNI field descriptor for this return type, add the JNI field descriptor
+ to jniret_desc */
+
+ Parm *retpm = NewParmFromNode(returntype, empty_str, n);
+
+ if ((c_ret_type = Swig_typemap_lookup("jni", retpm, "", 0))) {
+ Parm *tp = NewParmFromNode(c_ret_type, empty_str, n);
+
+ if (!is_void && !ignored_method) {
+ String *jretval_decl = NewStringf("%s jresult", c_ret_type);
+ Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL);
+ Delete(jretval_decl);
+ }
+
+ String *jdesc = NULL;
+ if ((tm = Swig_typemap_lookup("directorin", tp, "", 0))
+ && (jdesc = Getattr(tp, "tmap:directorin:descriptor"))) {
+
+ // Objects marshalled passing a Java class across JNI boundary use jobject - the nouse flag indicates this
+ // We need the specific Java class name instead of the generic 'Ljava/lang/Object;'
+ if (GetFlag(tp, "tmap:directorin:nouse"))
+ jdesc = cdesc;
+ String *jnidesc_canon = canonicalizeJNIDescriptor(jdesc, tp);
+ Append(jniret_desc, jnidesc_canon);
+ Delete(jnidesc_canon);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
+ "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(c_ret_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+
+ Delete(tp);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+
+ Delete(adjustedreturntypeparm);
+ Delete(retpm);
+ }
+
+ /* Go through argument list, attach lnames for arguments */
+ for (i = 0, p = l; p; p = nextSibling(p), ++i) {
+ String *arg = Getattr(p, "name");
+ String *lname = NewString("");
+
+ if (!arg && Cmp(Getattr(p, "type"), "void")) {
+ lname = NewStringf("arg%d", i);
+ Setattr(p, "name", lname);
+ } else
+ lname = arg;
+
+ Setattr(p, "lname", lname);
+ }
+
+ /* Attach the standard typemaps */
+ Swig_typemap_attach_parms("out", l, 0);
+ Swig_typemap_attach_parms("jni", l, 0);
+ Swig_typemap_attach_parms("jtype", l, 0);
+ Swig_typemap_attach_parms("directorin", l, 0);
+ Swig_typemap_attach_parms("javadirectorin", l, 0);
+
+ if (!ignored_method) {
+ /* Add Java environment pointer to wrapper */
+ String *jenvstr = NewString("jenv");
+ String *jobjstr = NewString("swigjobj");
+
+ Wrapper_add_localv(w, "swigjnienv", "JNIEnvWrapper", "swigjnienv(this)", NIL, NIL);
+ Wrapper_add_localv(w, jenvstr, "JNIEnv *", jenvstr, "= swigjnienv.getJNIEnv()", NIL);
+ Wrapper_add_localv(w, jobjstr, "jobject", jobjstr, "= (jobject) NULL", NIL);
+ Delete(jenvstr);
+ Delete(jobjstr);
+
+ /* Preamble code */
+ Printf(w->code, "if (!swig_override[%d]) {\n", classmeth_off);
+ }
+
+ if (!pure_virtual) {
+ String *super_call = Swig_method_call(super, l);
+ if (is_void) {
+ Printf(w->code, "%s;\n", super_call);
+ if (!ignored_method)
+ Printf(w->code, "return;\n");
+ } else {
+ Printf(w->code, "return %s;\n", super_call);
+ }
+ Delete(super_call);
+ } else {
+ Printf(w->code, "SWIG_JavaThrowException(JNIEnvWrapper(this).getJNIEnv(), SWIG_JavaDirectorPureVirtual, ");
+ Printf(w->code, "\"Attempted to invoke pure virtual method %s::%s.\");\n", SwigType_namestr(c_classname), SwigType_namestr(name));
+
+ /* Make sure that we return something in the case of a pure
+ * virtual method call for syntactical reasons. */
+ if (!is_void)
+ Printf(w->code, "return %s;", qualified_return);
+ else if (!ignored_method)
+ Printf(w->code, "return;\n");
+ }
+
+ if (!ignored_method) {
+ Printf(w->code, "}\n");
+ Printf(w->code, "swigjobj = swig_get_self(jenv);\n");
+ Printf(w->code, "if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) {\n");
+ }
+
+ /* Start the Java field descriptor for the intermediate class's upcall (insert self object) */
+ Parm *tp = NewParmFromNode(c_classname, empty_str, n);
+ String *jdesc;
+
+ if ((tm = Swig_typemap_lookup("directorin", tp, "", 0))
+ && (jdesc = Getattr(tp, "tmap:directorin:descriptor"))) {
+ String *jni_canon = canonicalizeJNIDescriptor(jdesc, tp);
+ Append(jnidesc, jni_canon);
+ Delete(jni_canon);
+ Delete(tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
+ "No or improper directorin typemap for type %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(type, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+
+ Delete(tp);
+
+ /* Go through argument list, convert from native to Java */
+ for (p = l; p; /* empty */ ) {
+ /* Is this superfluous? */
+ while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
+ p = Getattr(p, "tmap:directorin:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *ln = Copy(Getattr(p, "name"));
+ String *c_param_type = NULL;
+ String *c_decl = NewString("");
+ String *arg = NewString("");
+
+ Printf(arg, "j%s", ln);
+
+ /* Add various typemap's 'throws' clauses */
+ addThrows(n, "tmap:directorin", p);
+ addThrows(n, "tmap:out", p);
+
+ /* And add to the upcall args */
+ Printf(jupcall_args, ", %s", arg);
+
+ /* Get parameter's intermediary C type */
+ if ((c_param_type = Getattr(p, "tmap:jni"))) {
+ Parm *tp = NewParmFromNode(c_param_type, empty_str, n);
+ String *desc_tm = NULL, *jdesc = NULL, *cdesc = NULL;
+
+ /* Add to local variables */
+ Printf(c_decl, "%s %s", c_param_type, arg);
+ if (!ignored_method)
+ Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL);
+
+ /* Add input marshalling code and update JNI field descriptor */
+ if ((desc_tm = Swig_typemap_lookup("directorin", tp, "", 0))
+ && (jdesc = Getattr(tp, "tmap:directorin:descriptor"))
+ && (tm = Getattr(p, "tmap:directorin"))
+ && (cdesc = Getattr(p, "tmap:directorin:descriptor"))) {
+
+ // Objects marshalled by passing a Java class across the JNI boundary use jobject as the JNI type -
+ // the nouse flag indicates this. We need the specific Java class name instead of the generic 'Ljava/lang/Object;'
+ if (GetFlag(tp, "tmap:directorin:nouse"))
+ jdesc = cdesc;
+ String *jni_canon = canonicalizeJNIDescriptor(jdesc, tp);
+ Append(jnidesc, jni_canon);
+ Delete(jni_canon);
+
+ Replaceall(tm, "$input", arg);
+ Replaceall(tm, "$owner", "0");
+
+ if (Len(tm))
+ if (!ignored_method)
+ Printf(w->code, "%s\n", tm);
+
+ Delete(tm);
+
+ /* Add parameter to the intermediate class code if generating the
+ * intermediate's upcall code */
+ if ((tm = Getattr(p, "tmap:jtype"))) {
+ String *din = Copy(Getattr(p, "tmap:javadirectorin"));
+ addThrows(n, "tmap:javadirectorin", p);
+
+ if (din) {
+ Replaceall(din, "$module", module_class_name);
+ Replaceall(din, "$imclassname", imclass_name);
+ substituteClassname(pt, din);
+ Replaceall(din, "$jniinput", ln);
+
+ if (++gencomma > 1)
+ Printf(imcall_args, ", ");
+ Printf(callback_def, ", %s %s", tm, ln);
+
+ if (Cmp(din, ln)) {
+ Printv(imcall_args, din, NIL);
+ } else
+ Printv(imcall_args, ln, NIL);
+
+ jni_canon = canonicalizeJNIDescriptor(cdesc, p);
+ Append(classdesc, jni_canon);
+ Delete(jni_canon);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF, input_file, line_number, "No javadirectorin typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+
+ p = Getattr(p, "tmap:directorin:next");
+
+ Delete(desc_tm);
+ } else {
+ if (!desc_tm) {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF, input_file, line_number,
+ "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(c_param_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ p = nextSibling(p);
+ } else if (!jdesc) {
+ Swig_warning(WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC, input_file, line_number,
+ "Missing JNI descriptor in directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(c_param_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ p = Getattr(p, "tmap:directorin:next");
+ } else if (!tm) {
+ Swig_warning(WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF, input_file, line_number,
+ "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ p = nextSibling(p);
+ } else if (!cdesc) {
+ Swig_warning(WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC, input_file, line_number,
+ "Missing JNI descriptor in directorin typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ p = Getattr(p, "tmap:directorin:next");
+ }
+
+ output_director = false;
+ }
+
+ Delete(tp);
+ } else {
+ Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s for use in %s::%s (skipping director method)\n",
+ SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ p = nextSibling(p);
+ }
+
+ Delete(arg);
+ Delete(c_decl);
+ Delete(c_param_type);
+ }
+
+ /* header declaration, start wrapper definition */
+ String *target;
+ SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type;
+ target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+ Printf(w->def, "%s", target);
+ Delete(qualified_name);
+ Delete(target);
+ target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+ Printf(declaration, " virtual %s", target);
+ Delete(target);
+
+ // Add any exception specifications to the methods in the director class
+ // Get any Java exception classes in the throws typemap
+ ParmList *throw_parm_list = NULL;
+
+ if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
+ int gencomma = 0;
+
+ Append(w->def, " throw(");
+ Append(declaration, " throw(");
+
+ if (throw_parm_list)
+ Swig_typemap_attach_parms("throws", throw_parm_list, 0);
+ for (p = throw_parm_list; p; p = nextSibling(p)) {
+ if ((tm = Getattr(p, "tmap:throws"))) {
+ addThrows(n, "tmap:throws", p);
+
+ if (gencomma++) {
+ Append(w->def, ", ");
+ Append(declaration, ", ");
+ }
+
+ Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0));
+ Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0));
+ }
+ }
+
+ Append(w->def, ")");
+ Append(declaration, ")");
+ }
+
+ Append(w->def, " {");
+ Append(declaration, ";\n");
+
+ /* Emit the intermediate class's upcall to the actual class */
+
+ String *upcall = NewStringf("self.%s(%s)", symname, imcall_args);
+
+ if (!is_void) {
+ Parm *tp = NewParmFromNode(returntype, empty_str, n);
+
+ if ((tm = Swig_typemap_lookup("javadirectorout", tp, "", 0))) {
+ addThrows(n, "tmap:javadirectorout", tp);
+ substituteClassname(returntype, tm);
+ Replaceall(tm, "$javacall", upcall);
+
+ Printf(callback_code, " return %s;\n", tm);
+ }
+
+ if ((tm = Swig_typemap_lookup("out", tp, "", 0)))
+ addThrows(n, "tmap:out", tp);
+
+ Delete(tm);
+ Delete(tp);
+ } else
+ Printf(callback_code, " %s;\n", upcall);
+
+ Printf(callback_code, " }\n");
+ Delete(upcall);
+
+ /* Finish off the inherited upcall's definition */
+ Putc(')', callback_def);
+ generateThrowsClause(n, callback_def);
+ Printf(callback_def, " {\n");
+
+ if (!ignored_method) {
+ /* Emit the actual upcall through */
+ String *imclass_desc = NewStringf("(%s)%s", jnidesc, jniret_desc);
+ String *class_desc = NewStringf("(%s)%s", classdesc, classret_desc);
+ UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, imclass_desc, class_desc, decl);
+ String *methid = Getattr(udata, "imclass_methodidx");
+ String *methop = getUpcallJNIMethod(jniret_desc);
+
+ if (!is_void)
+ Printf(w->code, "jresult = (%s) ", c_ret_type);
+
+ Printf(w->code, "jenv->%s(Swig::jclass_%s, Swig::director_methids[%s], %s);\n", methop, imclass_name, methid, jupcall_args);
+
+ Printf(w->code, "if (jenv->ExceptionOccurred()) return $null;\n");
+
+ if (!is_void) {
+ String *jresult_str = NewString("jresult");
+ String *result_str = NewString("c_result");
+ Parm *tp = NewParmFromNode(returntype, result_str, n);
+
+ /* Copy jresult into c_result... */
+ if ((tm = Swig_typemap_lookup("directorout", tp, result_str, w))) {
+ addThrows(n, "tmap:directorout", tp);
+ Replaceall(tm, "$input", jresult_str);
+ Replaceall(tm, "$result", result_str);
+ Printf(w->code, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s used in %s::%s (skipping director method)\n",
+ SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ output_director = false;
+ }
+
+ Delete(tp);
+ Delete(jresult_str);
+ Delete(result_str);
+ }
+
+ Delete(imclass_desc);
+ Delete(class_desc);
+
+ /* Terminate wrapper code */
+ Printf(w->code, "} else {\n");
+ Printf(w->code, "SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, \"null upcall object\");\n");
+ Printf(w->code, "}\n");
+
+ Printf(w->code, "if (swigjobj) jenv->DeleteLocalRef(swigjobj);\n");
+
+ if (!is_void)
+ Printf(w->code, "return %s;", qualified_return);
+ }
+
+ Printf(w->code, "}");
+
+ // We expose virtual protected methods via an extra public inline method which makes a straight call to the wrapped class' method
+ String *inline_extra_method = NewString("");
+ if (dirprot_mode() && !is_public(n) && !pure_virtual) {
+ Printv(inline_extra_method, declaration, NIL);
+ String *extra_method_name = NewStringf("%sSwigPublic", name);
+ Replaceall(inline_extra_method, name, extra_method_name);
+ Replaceall(inline_extra_method, ";\n", " {\n ");
+ if (!is_void)
+ Printf(inline_extra_method, "return ");
+ String *methodcall = Swig_method_call(super, l);
+ Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
+ Delete(methodcall);
+ Delete(extra_method_name);
+ }
+
+ /* emit code */
+ if (status == SWIG_OK && output_director) {
+ if (!is_void) {
+ Replaceall(w->code, "$null", qualified_return);
+ } else {
+ Replaceall(w->code, "$null", "");
+ }
+ if (!GetFlag(n, "feature:ignore"))
+ Printv(imclass_directors, callback_def, callback_code, NIL);
+ if (!Getattr(n, "defaultargs")) {
+ Wrapper_print(w, f_directors);
+ Printv(f_directors_h, declaration, NIL);
+ Printv(f_directors_h, inline_extra_method, NIL);
+ }
+ }
+
+ Delete(inline_extra_method);
+ Delete(qualified_return);
+ Delete(jnidesc);
+ Delete(c_ret_type);
+ Delete(jniret_desc);
+ Delete(declaration);
+ Delete(callback_def);
+ Delete(callback_code);
+ DelWrapper(w);
+
+ return status;
+ }
+
+ /* ------------------------------------------------------------
+ * directorPrefixArgs()
+ * ------------------------------------------------------------ */
+
+ void directorPrefixArgs(Node *n) {
+ Parm *p;
+
+ /* Need to prepend 'jenv' to the director constructor's argument list */
+
+ String *jenv_type = NewString("JNIEnv");
+
+ SwigType_add_pointer(jenv_type);
+
+ p = NewParmFromNode(jenv_type, NewString("jenv"), n);
+ Setattr(p, "arg:byname", "1");
+ set_nextSibling(p, NULL);
+
+ Setattr(n, "director:prefix_args", p);
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorConstructor()
+ * ------------------------------------------------------------ */
+
+ int classDirectorConstructor(Node *n) {
+ Node *parent = parentNode(n);
+ String *decl = Getattr(n, "decl");;
+ String *supername = Swig_class_name(parent);
+ String *classname = directorClassName(parent);
+ String *sub = NewString("");
+ Parm *p;
+ ParmList *superparms = Getattr(n, "parms");
+ ParmList *parms;
+ int argidx = 0;
+
+ /* Assign arguments to superclass's parameters, if not already done */
+ for (p = superparms; p; p = nextSibling(p)) {
+ String *pname = Getattr(p, "name");
+
+ if (!pname) {
+ pname = NewStringf("arg%d", argidx++);
+ Setattr(p, "name", pname);
+ }
+ }
+
+ /* insert jenv prefix argument */
+ parms = CopyParmList(superparms);
+
+ String *jenv_type = NewString("JNIEnv");
+ SwigType_add_pointer(jenv_type);
+ p = NewParmFromNode(jenv_type, NewString("jenv"), n);
+ set_nextSibling(p, parms);
+ parms = p;
+
+ directorPrefixArgs(n);
+
+ if (!Getattr(n, "defaultargs")) {
+ /* constructor */
+ {
+ String *basetype = Getattr(parent, "classtype");
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+ String *call = Swig_csuperclass_call(0, basetype, superparms);
+ String *classtype = SwigType_namestr(Getattr(n, "name"));
+
+ Printf(f_directors, "%s::%s : %s, %s {\n", classname, target, call, Getattr(parent, "director:ctor"));
+ Printf(f_directors, "}\n\n");
+
+ Delete(classtype);
+ Delete(target);
+ Delete(call);
+ }
+
+ /* constructor header */
+ {
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+ Printf(f_directors_h, " %s;\n", target);
+ Delete(target);
+ }
+ }
+
+ Delete(sub);
+ Delete(supername);
+ Delete(jenv_type);
+ Delete(parms);
+ return Language::classDirectorConstructor(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorDefaultConstructor()
+ * ------------------------------------------------------------ */
+
+ int classDirectorDefaultConstructor(Node *n) {
+ String *classname = Swig_class_name(n);
+ String *classtype = SwigType_namestr(Getattr(n, "name"));
+ Wrapper *w = NewWrapper();
+
+ Printf(w->def, "SwigDirector_%s::SwigDirector_%s(JNIEnv *jenv) : %s {", classname, classname, Getattr(n, "director:ctor"));
+ Printf(w->code, "}\n");
+ Wrapper_print(w, f_directors);
+
+ Printf(f_directors_h, " SwigDirector_%s(JNIEnv *jenv);\n", classname);
+ DelWrapper(w);
+ Delete(classtype);
+ Delete(classname);
+ directorPrefixArgs(n);
+ return Language::classDirectorDefaultConstructor(n);
+ }
+
+
+ /* ------------------------------------------------------------
+ * classDirectorInit()
+ * ------------------------------------------------------------ */
+
+ int classDirectorInit(Node *n) {
+ Delete(none_comparison);
+ none_comparison = NewString(""); // not used
+
+ Delete(director_ctor_code);
+ director_ctor_code = NewString("$director_new");
+
+ Java_director_declaration(n);
+
+ Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl"));
+ Printf(f_directors_h, "\npublic:\n");
+ Printf(f_directors_h, " void swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global);\n");
+
+ /* Keep track of the director methods for this class */
+ first_class_dmethod = curr_class_dmethod = n_dmethods;
+
+ return Language::classDirectorInit(n);
+ }
+
+ /* ----------------------------------------------------------------------
+ * classDirectorDestructor()
+ * ---------------------------------------------------------------------- */
+
+ int classDirectorDestructor(Node *n) {
+ Node *current_class = getCurrentClass();
+ String *full_classname = Getattr(current_class, "name");
+ String *classname = Swig_class_name(current_class);
+ Wrapper *w = NewWrapper();
+
+ if (Getattr(n, "throw")) {
+ Printf(f_directors_h, " virtual ~SwigDirector_%s() throw ();\n", classname);
+ Printf(w->def, "SwigDirector_%s::~SwigDirector_%s() throw () {\n", classname, classname);
+ } else {
+ Printf(f_directors_h, " virtual ~SwigDirector_%s();\n", classname);
+ Printf(w->def, "SwigDirector_%s::~SwigDirector_%s() {\n", classname, classname);
+ }
+
+ /* Ensure that correct directordisconnect typemap's method name is called
+ * here: */
+
+ const String *disconn_tm = NULL;
+ Node *disconn_attr = NewHash();
+ String *disconn_methodname = NULL;
+
+ disconn_tm = typemapLookup(n, "directordisconnect", full_classname, WARN_NONE, disconn_attr);
+ disconn_methodname = Getattr(disconn_attr, "tmap:directordisconnect:methodname");
+
+ Printv(w->code, " swig_disconnect_director_self(\"", disconn_methodname, "\");\n", "}\n", NIL);
+
+ Wrapper_print(w, f_directors);
+
+ DelWrapper(w);
+ Delete(disconn_attr);
+ Delete(classname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorEnd()
+ * ------------------------------------------------------------ */
+
+ int classDirectorEnd(Node *n) {
+ String *classname = Getattr(n, "sym:name");
+ String *director_classname = directorClassName(n);
+ String *internal_classname;
+
+ Wrapper *w = NewWrapper();
+
+ if (Len(package_path) > 0)
+ internal_classname = NewStringf("%s/%s", package_path, classname);
+ else
+ internal_classname = NewStringf("%s", classname);
+
+ Wrapper_add_localv(w, "baseclass", "static jclass baseclass", "= 0", NIL);
+ Printf(w->def, "void %s::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) {", director_classname);
+
+ if (first_class_dmethod != curr_class_dmethod) {
+ Printf(w->def, "static struct {\n");
+ Printf(w->def, "const char *mname;\n");
+ Printf(w->def, "const char *mdesc;\n");
+ Printf(w->def, "jmethodID base_methid;\n");
+ Printf(w->def, "} methods[] = {\n");
+
+ for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
+ UpcallData *udata = Getitem(dmethods_seq, i);
+
+ Printf(w->def, "{ \"%s\", \"%s\", NULL }", Getattr(udata, "method"), Getattr(udata, "fdesc"));
+ if (i != curr_class_dmethod - 1)
+ Putc(',', w->def);
+ Putc('\n', w->def);
+ }
+
+ Printf(w->def, "};\n");
+ }
+
+ Printf(w->code, "if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) {\n");
+ Printf(w->code, "if (!baseclass) {\n");
+ Printf(w->code, "baseclass = jenv->FindClass(\"%s\");\n", internal_classname);
+ Printf(w->code, "if (!baseclass) return;\n");
+ Printf(w->code, "baseclass = (jclass) jenv->NewGlobalRef(baseclass);\n");
+ Printf(w->code, "}\n");
+
+ int n_methods = curr_class_dmethod - first_class_dmethod;
+
+ if (n_methods) {
+ /* Emit the swig_overrides() method and the swig_override array */
+ Printf(f_directors_h, "public:\n");
+ Printf(f_directors_h, " bool swig_overrides(int n) {\n");
+ Printf(f_directors_h, " return (n < %d ? swig_override[n] : false);\n", n_methods);
+ Printf(f_directors_h, " }\n");
+ Printf(f_directors_h, "protected:\n");
+ Printf(f_directors_h, " bool swig_override[%d];\n", n_methods);
+
+ /* Emit the code to look up the class's methods, initialize the override array */
+
+ Printf(w->code, "bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true);\n");
+ Printf(w->code, "for (int i = 0; i < %d; ++i) {\n", n_methods);
+ Printf(w->code, " if (!methods[i].base_methid) {\n");
+ Printf(w->code, " methods[i].base_methid = jenv->GetMethodID(baseclass, methods[i].mname, methods[i].mdesc);\n");
+ Printf(w->code, " if (!methods[i].base_methid) return;\n");
+ Printf(w->code, " }\n");
+ Printf(w->code, " swig_override[i] = false;\n");
+ Printf(w->code, " if (derived) {\n");
+ Printf(w->code, " jmethodID methid = jenv->GetMethodID(jcls, methods[i].mname, methods[i].mdesc);\n");
+ Printf(w->code, " swig_override[i] = (methid != methods[i].base_methid);\n");
+ Printf(w->code, " jenv->ExceptionClear();\n");
+ Printf(w->code, " }\n");
+ Printf(w->code, "}\n");
+ } else {
+ Printf(f_directors_h, "public:\n");
+ Printf(f_directors_h, " bool swig_overrides(int n) {\n");
+ Printf(f_directors_h, " return false;\n");
+ Printf(f_directors_h, " }\n");
+ }
+
+ Printf(f_directors_h, "};\n\n");
+ Printf(w->code, "}\n");
+ Printf(w->code, "}\n");
+
+ Wrapper_print(w, f_directors);
+
+ DelWrapper(w);
+ Delete(internal_classname);
+
+ return Language::classDirectorEnd(n);
+ }
+
+ /* --------------------------------------------------------------------
+ * classDirectorDisown()
+ * ------------------------------------------------------------------*/
+
+ virtual int classDirectorDisown(Node *n) {
+ (void) n;
+ return SWIG_OK;
+ }
+
+ /*----------------------------------------------------------------------
+ * extraDirectorProtectedCPPMethodsRequired()
+ *--------------------------------------------------------------------*/
+ bool extraDirectorProtectedCPPMethodsRequired() const {
+ return false;
+ }
+
+ /*----------------------------------------------------------------------
+ * Java_director_declaration()
+ *
+ * Generate the director class's declaration
+ * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
+ *--------------------------------------------------------------------*/
+
+ void Java_director_declaration(Node *n) {
+ String *base = Getattr(n, "classtype");
+ String *class_ctor = NewString("Swig::Director(jenv)");
+
+ String *classname = Swig_class_name(n);
+ String *directorname = NewStringf("SwigDirector_%s", classname);
+ String *declaration = Swig_class_declaration(n, directorname);
+
+ Printf(declaration, " : public %s, public Swig::Director", base);
+
+ // Stash stuff for later.
+ Setattr(n, "director:decl", declaration);
+ Setattr(n, "director:ctor", class_ctor);
+ }
+
+}; /* class JAVA */
+
+/* -----------------------------------------------------------------------------
+ * swig_java() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_java() {
+ return new JAVA();
+}
+extern "C" Language *swig_java(void) {
+ return new_swig_java();
+}
+
+/* -----------------------------------------------------------------------------
+ * Static member variables
+ * ----------------------------------------------------------------------------- */
+
+const char *JAVA::usage = (char *) "\
+Java Options (available with -java)\n\
+ -nopgcpp - Suppress premature garbage collection prevention parameter\n\
+ -noproxy - Generate the low-level functional interface instead\n\
+ of proxy classes\n\
+ -oldvarnames - old intermediary method names for variable wrappers\n\
+ -package <name> - set name of the Java package to <name>\n\
+\n";
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx
new file mode 100644
index 0000000..d4715ee
--- /dev/null
+++ b/Source/Modules/lang.cxx
@@ -0,0 +1,3431 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * lang.cxx
+ *
+ * Language base class functions. Default C++ handling is also implemented here.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_lang_cxx[] = "$Id: lang.cxx 11482 2009-07-30 18:48:14Z wsfulton $";
+
+#include "swigmod.h"
+#include "cparse.h"
+#include <ctype.h>
+
+/* default mode settings */
+static int director_mode = 0;
+static int director_protected_mode = 1;
+static int all_protected_mode = 0;
+static int naturalvar_mode = 0;
+Language* Language::this_ = 0;
+
+/* Set director_protected_mode */
+void Wrapper_director_mode_set(int flag) {
+ director_mode = flag;
+}
+
+void Wrapper_director_protected_mode_set(int flag) {
+ director_protected_mode = flag;
+}
+
+void Wrapper_all_protected_mode_set(int flag) {
+ all_protected_mode = flag;
+}
+
+void Wrapper_naturalvar_mode_set(int flag) {
+ naturalvar_mode = flag;
+}
+
+extern "C" {
+ int Swig_director_mode() {
+ return director_mode;
+ }
+ int Swig_director_protected_mode() {
+ return director_protected_mode;
+ }
+ int Swig_all_protected_mode() {
+ return all_protected_mode;
+ }
+ void Language_replace_special_variables(String *method, String *tm, Parm *parm) {
+ Language::instance()->replaceSpecialVariables(method, tm, parm);
+ }
+}
+
+/* Some status variables used during parsing */
+static int InClass = 0; /* Parsing C++ or not */
+static String *ClassName = 0; /* This is the real name of the current class */
+static String *ClassPrefix = 0; /* Class prefix */
+static String *ClassType = 0; /* Fully qualified type name to use */
+static String *DirectorClassName = 0; /* Director name of the current class */
+int Abstract = 0;
+int ImportMode = 0;
+int IsVirtual = 0;
+static String *AttributeFunctionGet = 0;
+static String *AttributeFunctionSet = 0;
+static Node *CurrentClass = 0;
+int line_number = 0;
+String *input_file = 0;
+int SmartPointer = 0;
+static Hash *classhash;
+
+extern int GenerateDefault;
+extern int ForceExtern;
+extern int AddExtern;
+
+/* import modes */
+
+#define IMPORT_MODE 1
+#define IMPORT_MODULE 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_OK;
+ }
+
+ /* 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, "enumforward") == 0) {
+ ret = enumforwardDeclaration(n);
+ } else if (strcmp(tag, "class") == 0) {
+ ret = classDeclaration(n);
+ } else if (strcmp(tag, "classforward") == 0) {
+ ret = classforwardDeclaration(n);
+ } else if (strcmp(tag, "constructor") == 0) {
+ ret = constructorDeclaration(n);
+ } else if (strcmp(tag, "destructor") == 0) {
+ ret = destructorDeclaration(n);
+ } else if (strcmp(tag, "access") == 0) {
+ ret = accessDeclaration(n);
+ } else if (strcmp(tag, "using") == 0) {
+ ret = usingDeclaration(n);
+ } else if (strcmp(tag, "namespace") == 0) {
+ ret = namespaceDeclaration(n);
+ } else if (strcmp(tag, "template") == 0) {
+ ret = templateDeclaration(n);
+ }
+
+ /* ===============================================================
+ * SWIG directives
+ * =============================================================== */
+
+ else if (strcmp(tag, "top") == 0) {
+ ret = top(n);
+ } else if (strcmp(tag, "extend") == 0) {
+ ret = extendDirective(n);
+ } else if (strcmp(tag, "apply") == 0) {
+ ret = applyDirective(n);
+ } else if (strcmp(tag, "clear") == 0) {
+ ret = clearDirective(n);
+ } else if (strcmp(tag, "constant") == 0) {
+ ret = constantDirective(n);
+ } else if (strcmp(tag, "fragment") == 0) {
+ ret = fragmentDirective(n);
+ } else if (strcmp(tag, "import") == 0) {
+ ret = importDirective(n);
+ } else if (strcmp(tag, "include") == 0) {
+ ret = includeDirective(n);
+ } else if (strcmp(tag, "insert") == 0) {
+ ret = insertDirective(n);
+ } else if (strcmp(tag, "module") == 0) {
+ ret = moduleDirective(n);
+ } else if (strcmp(tag, "native") == 0) {
+ ret = nativeDirective(n);
+ } else if (strcmp(tag, "pragma") == 0) {
+ ret = pragmaDirective(n);
+ } else if (strcmp(tag, "typemap") == 0) {
+ ret = typemapDirective(n);
+ } else if (strcmp(tag, "typemapcopy") == 0) {
+ ret = typemapcopyDirective(n);
+ } else if (strcmp(tag, "typemapitem") == 0) {
+ ret = typemapitemDirective(n);
+ } else if (strcmp(tag, "types") == 0) {
+ ret = typesDirective(n);
+ } else {
+ Printf(stderr, "%s:%d. Unrecognized parse tree node type '%s'\n", input_file, line_number, tag);
+ ret = SWIG_ERROR;
+ }
+ if (wrn) {
+ Swig_warnfilter(wrn, 0);
+ }
+ return ret;
+}
+
+/* ----------------------------------------------------------------------
+ * Dispatcher::emit_children()
+ *
+ * Emit all children that match the given type. type = 0 means all types.
+ * ---------------------------------------------------------------------- */
+
+int Dispatcher::emit_children(Node *n) {
+ Node *c;
+ char *eo = Char(Getattr(n, "feature:emitonlychildren"));
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ if (eo) {
+ const char *tag = Char(nodeType(c));
+ if (strcmp(tag, "cdecl") == 0) {
+ if (checkAttribute(c, "storage", "typedef"))
+ tag = "typedef";
+ }
+ if (strstr(eo, tag) == 0) {
+ continue;
+ }
+ }
+ 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::enumforwardDeclaration(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():
+none_comparison(NewString("$arg != 0")),
+director_ctor_code(NewString("")),
+director_prot_ctor_code(0),
+symbols(NewHash()),
+classtypes(NewHash()),
+enumtypes(NewHash()),
+overloading(0),
+multiinput(0),
+cplus_runtime(0),
+directors(0) {
+ argc_template_string = NewString("argc");
+ argv_template_string = NewString("argv[%d]");
+
+ /* Default director constructor code, passed to Swig_ConstructorToFunction */
+ Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL);
+
+ /*
+ Default director 'protected' constructor code, disabled by
+ default. Each language that needs it, has to define it.
+ */
+ director_prot_ctor_code = 0;
+ director_multiple_inheritance = 1;
+ director_language = 0;
+ assert(!this_);
+ this_ = this;
+}
+
+Language::~Language() {
+ Delete(symbols);
+ Delete(classtypes);
+ Delete(enumtypes);
+ Delete(director_ctor_code);
+ Delete(none_comparison);
+ this_ = 0;
+}
+
+/* ----------------------------------------------------------------------
+ emit_one()
+ ---------------------------------------------------------------------- */
+
+int Language::emit_one(Node *n) {
+ int ret;
+ int oldext;
+ if (!n)
+ return SWIG_OK;
+
+ if (GetFlag(n, "feature:ignore")
+ && !Getattr(n, "feature:onlychildren"))
+ return SWIG_OK;
+
+ oldext = Extend;
+ if (Getattr(n, "feature:extend"))
+ Extend = 1;
+
+ line_number = Getline(n);
+ input_file = Getfile(n);
+
+ /*
+ symtab = Getattr(n,"symtab");
+ if (symtab) {
+ symtab = Swig_symbol_setscope(symtab);
+ }
+ */
+ ret = Dispatcher::emit_one(n);
+ /*
+ if (symtab) {
+ Swig_symbol_setscope(symtab);
+ }
+ */
+ Extend = oldext;
+ return ret;
+}
+
+
+static Parm *nonvoid_parms(Parm *p) {
+ if (p) {
+ SwigType *t = Getattr(p, "type");
+ if (SwigType_type(t) == T_VOID)
+ return 0;
+ }
+ return p;
+}
+
+/* -----------------------------------------------------------------------------
+ * cplus_value_type()
+ *
+ * Returns the alternative value type needed in C++ for class value
+ * types. When swig is not sure about using a plain $ltype value,
+ * since the class doesn't have a default constructor, or it can't be
+ * assigned, you will get back 'SwigValueWrapper<type >'.
+ *
+ * ----------------------------------------------------------------------------- */
+
+SwigType *cplus_value_type(SwigType *t) {
+ return SwigType_alttype(t, 0);
+}
+
+static Node *first_nontemplate(Node *n) {
+ while (n) {
+ if (Strcmp(nodeType(n), "template") != 0)
+ return n;
+ n = Getattr(n, "sym:nextSibling");
+ }
+ return n;
+}
+
+
+
+/* --------------------------------------------------------------------------
+ * swig_pragma()
+ *
+ * Handle swig pragma directives.
+ * -------------------------------------------------------------------------- */
+
+void swig_pragma(char *lang, char *name, char *value) {
+ if (strcmp(lang, "swig") == 0) {
+ if ((strcmp(name, "make_default") == 0) || ((strcmp(name, "makedefault") == 0))) {
+ GenerateDefault = 1;
+ } else if ((strcmp(name, "no_default") == 0) || ((strcmp(name, "nodefault") == 0))) {
+ Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use %%nodefaultctor, %%nodefaultdtor instead.\n");
+ 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;
+ }
+ }
+}
+
+/* --------------------------------------------------------------------------
+ * use_naturalvar_mode()
+ * -------------------------------------------------------------------------- */
+int use_naturalvar_mode(Node *n) {
+ if (Getattr(n, "unnamed"))
+ return 0;
+ int nvar = naturalvar_mode || GetFlag(n, "feature:naturalvar");
+ if (!nvar) {
+ /* look for feature in the class */
+ SwigType *ty = Getattr(n, "type");
+ SwigType *fullty = SwigType_typedef_resolve_all(ty);
+ if (SwigType_isclass(fullty)) {
+ Node *m = Copy(n);
+ SwigType *tys = SwigType_strip_qualifiers(fullty);
+ Swig_features_get(Swig_cparse_features(), 0, tys, 0, m);
+ nvar = GetFlag(m, "feature:naturalvar");
+ Delete(tys);
+ Delete(m);
+ }
+ Delete(fullty);
+ }
+ return nvar ? CWRAP_NATURAL_VAR : 0;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::top() - Top of parsing tree
+ * ---------------------------------------------------------------------- */
+
+int Language::top(Node *n) {
+ Node *mod = Getattr(n, "module");
+ if (mod) {
+ Node *options = Getattr(mod, "options");
+ if (options) {
+ if (Getattr(options, "naturalvar")) {
+ naturalvar_mode = 1;
+ }
+ if (Getattr(options, "nonaturalvar")) {
+ naturalvar_mode = 0;
+ }
+ }
+ }
+ classhash = Getattr(n, "classes");
+ return emit_children(n);
+}
+
+/* ----------------------------------------------------------------------
+ * Language::extendDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::extendDirective(Node *n) {
+ int oldam = Extend;
+ AccessMode oldmode = cplus_mode;
+ Extend = CWRAP_EXTEND;
+ cplus_mode = PUBLIC;
+
+ emit_children(n);
+
+ Extend = oldam;
+ cplus_mode = oldmode;
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::applyDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::applyDirective(Node *n) {
+
+ Parm *pattern = Getattr(n, "pattern");
+ Node *c = firstChild(n);
+ while (c) {
+ Parm *apattern = Getattr(c, "pattern");
+ if (ParmList_len(pattern) != ParmList_len(apattern)) {
+ Swig_error(input_file, line_number, "Can't apply (%s) to (%s). Number of arguments don't match.\n", ParmList_str(pattern), ParmList_str(apattern));
+ } else {
+ if (!Swig_typemap_apply(pattern, apattern)) {
+ Swig_warning(WARN_TYPEMAP_APPLY_UNDEF, input_file, line_number, "Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern));
+ }
+ }
+ c = nextSibling(c);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::clearDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::clearDirective(Node *n) {
+ Node *p;
+ for (p = firstChild(n); p; p = nextSibling(p)) {
+ ParmList *pattern = Getattr(p, "pattern");
+ Swig_typemap_clear_apply(pattern);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::constantDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::constantDirective(Node *n) {
+
+ if (CurrentClass && (cplus_mode != PUBLIC))
+ return SWIG_NOWRAP;
+
+ if (!GetFlag(n, "feature:allowexcept")) {
+ UnsetFlag(n, "feature:except");
+ }
+ if (Getattr(n, "feature:exceptvar")) {
+ Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
+ }
+
+ if (!ImportMode) {
+ Swig_require("constantDirective", n, "name", "?value", NIL);
+ String *name = Getattr(n, "name");
+ String *value = Getattr(n, "value");
+ if (!value) {
+ value = Copy(name);
+ } else {
+ /* if (checkAttribute(n,"type","char")) {
+ value = NewString(value);
+ } else {
+ value = NewStringf("%(escape)s", value);
+ }
+ */
+ Setattr(n, "rawvalue", value);
+ value = NewStringf("%(escape)s", value);
+ if (!Len(value))
+ Append(value, "\\0");
+ /* Printf(stdout,"'%s' = '%s'\n", name, value); */
+ }
+ Setattr(n, "value", value);
+ this->constantWrapper(n);
+ Swig_restore(n);
+ return SWIG_OK;
+ }
+ return SWIG_NOWRAP;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::fragmentDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::fragmentDirective(Node *n) {
+ Swig_fragment_register(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::importDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::importDirective(Node *n) {
+ int oldim = ImportMode;
+ ImportMode = IMPORT_MODE;
+ emit_children(n);
+ ImportMode = oldim;
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::includeDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::includeDirective(Node *n) {
+ emit_children(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::insertDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::insertDirective(Node *n) {
+ /* %insert directive */
+ if ((!ImportMode) || Getattr(n, "generated")) {
+ String *code = Getattr(n, "code");
+ String *section = Getattr(n, "section");
+ File *f = 0;
+ if (!section) { /* %{ ... %} */
+ f = Swig_filebyname("header");
+ } else {
+ f = Swig_filebyname(section);
+ }
+ if (f) {
+ Printf(f, "%s\n", code);
+ } else {
+ Swig_error(input_file, line_number, "Unknown target '%s' for %%insert directive.\n", section);
+ }
+ return SWIG_OK;
+ } else {
+ return SWIG_NOWRAP;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ * Language::moduleDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::moduleDirective(Node *n) {
+ (void) n;
+ /* %module directive */
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::nativeDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::nativeDirective(Node *n) {
+ if (!ImportMode) {
+ return nativeWrapper(n);
+ } else {
+ return SWIG_NOWRAP;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ * Language::pragmaDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::pragmaDirective(Node *n) {
+ /* %pragma directive */
+ if (!ImportMode) {
+ String *lan = Getattr(n, "lang");
+ String *name = Getattr(n, "name");
+ String *value = Getattr(n, "value");
+ swig_pragma(Char(lan), Char(name), Char(value));
+ /* pragma(Char(lan),Char(name),Char(value)); */
+ return SWIG_OK;
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::typemapDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::typemapDirective(Node *n) {
+ /* %typemap directive */
+ String *method = Getattr(n, "method");
+ String *code = Getattr(n, "code");
+ Parm *kwargs = Getattr(n, "kwargs");
+ Node *items = firstChild(n);
+ static int namewarn = 0;
+
+
+ if (code && (Strstr(code, "$source") || (Strstr(code, "$target")))) {
+ Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "Deprecated typemap feature ($source/$target).\n");
+ if (!namewarn) {
+ Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is deprecated.\n\
+For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\
+$source by $input and $target by $1. For typemaps related to return values (out,\n\
+argout,ret,except), replace $source by $1 and $target by $result. See the file\n\
+Doc/Manual/Typemaps.html for complete details.\n");
+ namewarn = 1;
+ }
+ }
+
+ if (Strcmp(method, "except") == 0) {
+ Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n), "%%typemap(except) is deprecated. Use the %%exception directive.\n");
+ }
+
+ if (Strcmp(method, "in") == 0) {
+ Hash *k;
+ k = kwargs;
+ while (k) {
+ if (checkAttribute(k, "name", "numinputs")) {
+ if (!multiinput && (GetInt(k, "value") > 1)) {
+ Swig_error(Getfile(n), Getline(n), "Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n");
+ return SWIG_ERROR;
+ }
+ break;
+ }
+ k = nextSibling(k);
+ }
+ if (!k) {
+ k = NewHash();
+ Setattr(k, "name", "numinputs");
+ Setattr(k, "value", "1");
+ set_nextSibling(k, kwargs);
+ Setattr(n, "kwargs", k);
+ kwargs = k;
+ }
+ }
+
+ if (Strcmp(method, "ignore") == 0) {
+ Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n), "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n");
+
+ Clear(method);
+ Append(method, "in");
+ Hash *k = NewHash();
+ Setattr(k, "name", "numinputs");
+ Setattr(k, "value", "0");
+ set_nextSibling(k, kwargs);
+ Setattr(n, "kwargs", k);
+ kwargs = k;
+ }
+
+ /* Replace $descriptor() macros */
+
+ if (code) {
+ Setfile(code, Getfile(n));
+ Setline(code, Getline(n));
+ Swig_cparse_replace_descriptor(code);
+ }
+
+ while (items) {
+ Parm *pattern = Getattr(items, "pattern");
+ Parm *parms = Getattr(items, "parms");
+
+ if (code) {
+ Swig_typemap_register(method, pattern, code, parms, kwargs);
+ } else {
+ Swig_typemap_clear(method, pattern);
+ }
+ items = nextSibling(items);
+ }
+ return SWIG_OK;
+
+}
+
+/* ----------------------------------------------------------------------
+ * Language::typemapcopyDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::typemapcopyDirective(Node *n) {
+ String *method = Getattr(n, "method");
+ Parm *pattern = Getattr(n, "pattern");
+ Node *items = firstChild(n);
+ int nsrc = 0;
+ nsrc = ParmList_len(pattern);
+ while (items) {
+ ParmList *npattern = Getattr(items, "pattern");
+ if (nsrc != ParmList_len(npattern)) {
+ Swig_error(input_file, line_number, "Can't copy typemap. Number of types differ.\n");
+ } else {
+ if (Swig_typemap_copy(method, pattern, npattern) < 0) {
+ Swig_error(input_file, line_number, "Can't copy typemap.\n");
+ }
+ }
+ items = nextSibling(items);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::typesDirective()
+ * ---------------------------------------------------------------------- */
+
+int Language::typesDirective(Node *n) {
+ Parm *parms = Getattr(n, "parms");
+ String *convcode = Getattr(n, "convcode"); /* optional user supplied conversion code for custom casting */
+ 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, convcode);
+ }
+ }
+ 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;
+
+ /* discards nodes following the access control rules */
+ if (cplus_mode != PUBLIC || !is_public(n)) {
+ /* except for friends, they are not affected by access control */
+ int isfriend = storage && (Cmp(storage, "friend") == 0);
+ if (!isfriend) {
+ /* Check what the director needs. If the method is pure virtual, it is always needed.
+ * Also wrap non-virtual protected members if asked for (allprotected mode). */
+ if (!(directorsEnabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || is_non_virtual_protected_access(n)))) {
+ return SWIG_NOWRAP;
+ }
+ // Prevent wrapping protected overloaded director methods more than once -
+ // This bit of code is only needed due to the cDeclaration call in classHandler()
+ String *wrapname = NewStringf("nonpublic_%s%s", symname, Getattr(n, "sym:overname"));
+ if (Getattr(CurrentClass, wrapname)) {
+ Delete(wrapname);
+ return SWIG_NOWRAP;
+ }
+ SetFlag(CurrentClass, wrapname);
+ Delete(wrapname);
+ }
+ }
+
+ if (Cmp(storage, "typedef") == 0) {
+ Swig_save("cDeclaration", 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;
+ }
+
+ /* If in import mode, we proceed no further */
+ if (ImportMode)
+ return SWIG_NOWRAP;
+
+ /* If we're in extend mode and there is code, replace the $descriptor macros */
+ if (Extend) {
+ String *code = Getattr(n, "code");
+ if (code) {
+ Setfile(code, Getfile(n));
+ Setline(code, Getline(n));
+ Swig_cparse_replace_descriptor(code);
+ }
+ }
+
+ /* Overloaded symbol check */
+ over = Swig_symbol_isoverloaded(n);
+ if (!overloading) {
+ if (over)
+ over = first_nontemplate(over);
+ if (over && (over != n)) {
+ Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", Swig_name_decl(n));
+ Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over), "Previous declaration is %s\n", Swig_name_decl(over));
+ 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 (AddExtern) {
+ if (f_header) {
+ if ((Cmp(storage, "extern") == 0) || (ForceExtern && !storage)) {
+ /* we don't need the 'extern' part in the C/C++ declaration,
+ and it produces some problems when namespace and SUN
+ Studio is used.
+
+ Printf(f_header,"extern %s", SwigType_str(ty,name));
+
+ In fact generating extern declarations is quite error prone and is
+ no longer the default. Getting it right seems impossible with namespaces
+ and default arguments and when a method is declared with the various Windows
+ calling conventions - SWIG doesn't understand Windows (non standard) calling
+ conventions in the first place, so can't regenerate them.
+ */
+ String *str = SwigType_str(ty, name);
+ Printf(f_header, "%s", str);
+ Delete(str);
+ {
+ DOH *t = Getattr(n, "throws");
+ if (t) {
+ Printf(f_header, " throw(");
+ while (t) {
+ Printf(f_header, "%s", Getattr(t, "type"));
+ t = nextSibling(t);
+ if (t)
+ Printf(f_header, ",");
+ }
+ Printf(f_header, ")");
+ }
+ }
+ Printf(f_header, ";\n");
+ } else if (Cmp(storage, "externc") == 0) {
+ /* here 'extern "C"' is needed */
+ String *str = SwigType_str(ty, name);
+ Printf(f_header, "extern \"C\" %s;\n", str);
+ Delete(str);
+ }
+ }
+ }
+ }
+ /* This needs to check qualifiers */
+ if (SwigType_isqualifier(ty)) {
+ SwigType *qual = SwigType_pop(ty);
+ Setattr(n, "qualifier", qual);
+ Delete(qual);
+ }
+ Delete(SwigType_pop_function(ty));
+ DohIncref(type);
+ Setattr(n, "type", ty);
+ if (GetFlag(n, "feature:onlychildren") && !GetFlag(n, "feature:ignore")) {
+ // Found an unignored templated method that has a an empty template instantiation (%template())
+ // Ignore it unless it has been %rename'd
+ if (Strncmp(symname, "__dummy_", 8) == 0) {
+ SetFlag(n, "feature:ignore");
+ Swig_warning(WARN_LANG_TEMPLATE_METHOD_IGNORE, input_file, line_number,
+ "%%template() contains no name. Template method ignored: %s\n", Swig_name_decl(n));
+ }
+ }
+ if (!GetFlag(n, "feature:ignore"))
+ functionHandler(n);
+ Setattr(n, "type", type);
+ Delete(ty);
+ Delete(type);
+ return SWIG_OK;
+ } else {
+ /* Some kind of variable declaration */
+ String *declaration = Copy(decl);
+ Delattr(n, "decl");
+ if (Getattr(n, "nested"))
+ SetFlag(n, "feature:immutable");
+ if (!CurrentClass) {
+ if ((Cmp(storage, "extern") == 0) || ForceExtern) {
+ f_header = Swig_filebyname("header");
+ if (AddExtern) {
+ if (f_header) {
+ String *str = SwigType_str(ty, name);
+ Printf(f_header, "extern %s;\n", str);
+ Delete(str);
+ }
+ }
+ }
+ }
+ if (!SwigType_ismutable(ty)) {
+ SetFlag(n, "feature:immutable");
+ }
+ /* If an array and elements are const, then read-only */
+ if (SwigType_isarray(ty)) {
+ SwigType *tya = SwigType_array_type(ty);
+ if (SwigType_isconst(tya)) {
+ SetFlag(n, "feature:immutable");
+ }
+ Delete(tya);
+ }
+ DohIncref(type);
+ Setattr(n, "type", ty);
+ variableHandler(n);
+ Setattr(n, "type", type);
+ Setattr(n, "decl", declaration);
+ Delete(ty);
+ Delete(type);
+ Delete(fullty);
+ return SWIG_OK;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ * Language::functionHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::functionHandler(Node *n) {
+ String *storage = Getattr(n, "storage");
+ int isfriend = CurrentClass && Cmp(storage, "friend") == 0;
+ int isstatic = CurrentClass && Cmp(storage, "static") == 0 && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"));
+ Parm *p = Getattr(n, "parms");
+ if (GetFlag(n, "feature:del")) {
+ /* the method acts like a delete operator, ie, we need to disown the parameter */
+ if (CurrentClass && !isstatic && !isfriend) {
+ SetFlag(n, "feature:self:disown");
+ } else {
+ if (p)
+ SetFlag(p, "wrap:disown");
+ }
+ }
+ if (!CurrentClass) {
+ globalfunctionHandler(n);
+ } else {
+ if (isstatic) {
+ staticmemberfunctionHandler(n);
+ } else if (isfriend) {
+ globalfunctionHandler(n);
+ } else {
+ Node *explicit_n = 0;
+ if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
+ bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
+ if (virtual_but_not_pure_virtual) {
+ // Add additional wrapper which makes an explicit call to the virtual method (ie not a virtual call)
+ explicit_n = Copy(n);
+ String *new_symname = Copy(Getattr(n, "sym:name"));
+ String *suffix = Getattr(parentNode(n), "sym:name");
+ Printv(new_symname, "SwigExplicit", suffix, NIL);
+ Setattr(explicit_n, "sym:name", new_symname);
+ Delattr(explicit_n, "storage");
+ Delattr(explicit_n, "override");
+ Delattr(explicit_n, "hides");
+ SetFlag(explicit_n, "explicitcall");
+ Setattr(n, "explicitcallnode", explicit_n);
+ }
+ }
+
+ memberfunctionHandler(n);
+
+ if (explicit_n) {
+ memberfunctionHandler(explicit_n);
+ Delattr(explicit_n, "explicitcall");
+ Delete(explicit_n);
+ }
+ }
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::globalfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::globalfunctionHandler(Node *n) {
+
+ Swig_require("globalfunctionHandler", n, "name", "sym:name", "type", "?parms", NIL);
+
+ String *name = Getattr(n, "name");
+ String *symname = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ ParmList *parms = Getattr(n, "parms");
+
+ /* Check for callback mode */
+ String *cb = GetFlagAttr(n, "feature:callback");
+ if (cb) {
+ String *cbname = Getattr(n, "feature:callback:name");
+ if (!cbname) {
+ cbname = NewStringf(cb, symname);
+ Setattr(n, "feature:callback:name", cbname);
+ }
+
+ callbackfunctionHandler(n);
+ if (Cmp(cbname, symname) == 0) {
+ Delete(cbname);
+ Swig_restore(n);
+ return SWIG_NOWRAP;
+ }
+ Delete(cbname);
+ }
+ Setattr(n, "parms", nonvoid_parms(parms));
+ String *call = Swig_cfunction_call(name, parms);
+ String *cres = Swig_cresult(type, "result", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(cres);
+ Delete(call);
+ functionWrapper(n);
+
+ Swig_restore(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::callbackfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::callbackfunctionHandler(Node *n) {
+ Swig_require("callbackfunctionHandler", 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 = GetFlagAttr(n, "feature:callback");
+ String *cbname = Getattr(n, "feature:callback:name");
+ String *calltype = NewStringf("(%s (*)(%s))(%s)", SwigType_str(type, 0), ParmList_str(parms), SwigType_namestr(name));
+ SwigType *cbty = Copy(type);
+ SwigType_add_function(cbty, parms);
+ SwigType_add_pointer(cbty);
+
+ if (!cbname) {
+ cbname = NewStringf(cb, symname);
+ Setattr(n, "feature:callback:name", cbname);
+ }
+
+ Setattr(n, "sym:name", cbname);
+ Setattr(n, "type", cbty);
+ Setattr(n, "value", calltype);
+
+ Node *ns = Getattr(symbols, cbname);
+ if (!ns)
+ constantWrapper(n);
+
+ Delete(cbname);
+ Delete(cbty);
+
+ Swig_restore(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::memberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::memberfunctionHandler(Node *n) {
+
+ Swig_require("memberfunctionHandler", 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 = GetFlagAttr(n, "feature:callback");
+
+ if (Cmp(storage, "virtual") == 0) {
+ if (Cmp(value, "0") == 0) {
+ IsVirtual = PURE_VIRTUAL;
+ } else {
+ IsVirtual = PLAIN_VIRTUAL;
+ }
+ } else {
+ IsVirtual = 0;
+ }
+ if (cb) {
+ Node *cbn = NewHash();
+ String *cbname = Getattr(n, "feature:callback:name");
+ if (!cbname) {
+ cbname = NewStringf(cb, symname);
+ }
+
+ SwigType *cbty = Copy(type);
+ SwigType_add_function(cbty, parms);
+ SwigType_add_memberpointer(cbty, ClassName);
+ String *cbvalue = NewStringf("&%s::%s", ClassName, name);
+ Setattr(cbn, "sym:name", cbname);
+ Setattr(cbn, "type", cbty);
+ Setattr(cbn, "value", cbvalue);
+ Setattr(cbn, "name", name);
+
+ memberconstantHandler(cbn);
+ Setattr(n, "feature:callback:name", Swig_name_member(ClassPrefix, cbname));
+
+ Delete(cb);
+ Delete(cbn);
+ Delete(cbvalue);
+ Delete(cbty);
+ Delete(cbname);
+ if (Cmp(cbname, symname) == 0) {
+ Swig_restore(n);
+ return SWIG_NOWRAP;
+ }
+ }
+
+ String *fname = Swig_name_member(ClassPrefix, symname);
+ if (Extend && SmartPointer) {
+ if (!Getattr(n, "classname")) {
+ Setattr(n, "classname", Getattr(CurrentClass, "allocate:smartpointerbase"));
+ }
+ }
+ // Set up the type for the cast to this class for use when wrapping const director (virtual) methods.
+ // Note: protected director methods or when allprotected mode turned on.
+ String *director_type = 0;
+ if (!is_public(n) && (is_member_director(CurrentClass, n) || GetFlag(n, "explicitcall") || is_non_virtual_protected_access(n))) {
+ director_type = Copy(DirectorClassName);
+ String *qualifier = Getattr(n, "qualifier");
+ if (qualifier)
+ SwigType_push(director_type, qualifier);
+ SwigType_add_pointer(director_type);
+ }
+
+ int DirectorExtraCall = 0;
+ if (directorsEnabled() && is_member_director(CurrentClass, n) && !SmartPointer)
+ if (extraDirectorProtectedCPPMethodsRequired())
+ DirectorExtraCall = CWRAP_DIRECTOR_TWO_CALLS;
+
+ if (GetFlag(n, "explicitcall"))
+ DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL;
+
+ Swig_MethodToFunction(n, ClassType, Getattr(n, "template") ? SmartPointer : Extend | SmartPointer | DirectorExtraCall, director_type,
+ is_member_director(CurrentClass, n));
+ Setattr(n, "sym:name", fname);
+
+ functionWrapper(n);
+
+ Delete(director_type);
+ Delete(fname);
+ Swig_restore(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::staticmemberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::staticmemberfunctionHandler(Node *n) {
+
+ Swig_require("staticmemberfunctionHandler", n, "*name", "*sym:name", "*type", NIL);
+ Swig_save("staticmemberfunctionHandler", 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 *cb = GetFlagAttr(n, "feature:callback");
+ String *cname, *mrename;
+
+ if (!Extend) {
+ Node *sb = Getattr(n, "cplus:staticbase");
+ String *sname = Getattr(sb, "name");
+ if (is_non_virtual_protected_access(n))
+ cname = NewStringf("%s::%s", DirectorClassName, name);
+ else
+ cname = NewStringf("%s::%s", sname, name);
+ } else {
+ String *mname = Swig_name_mangle(ClassName);
+ cname = Swig_name_member(mname, name);
+ Delete(mname);
+ }
+ mrename = Swig_name_member(ClassPrefix, symname);
+
+ if (Extend) {
+ String *code = Getattr(n, "code");
+ String *defaultargs = Getattr(n, "defaultargs");
+ String *mangled = Swig_name_mangle(mrename);
+ Delete(mrename);
+ mrename = mangled;
+
+ if (Getattr(n, "sym:overloaded") && code) {
+ Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
+ }
+
+ if (!defaultargs && code) {
+ /* Hmmm. An added static member. We have to create a little wrapper for this */
+ Swig_add_extension_code(n, cname, parms, type, code, CPlusPlus, 0);
+ }
+ }
+
+ Setattr(n, "name", cname);
+ Setattr(n, "sym:name", mrename);
+
+ if (cb) {
+ String *cbname = NewStringf(cb, symname);
+ Setattr(n, "feature:callback:name", Swig_name_member(ClassPrefix, cbname));
+ Setattr(n, "feature:callback:staticname", name);
+ }
+ Delattr(n, "storage");
+
+ globalfunctionHandler(n);
+
+ Delete(cname);
+ Delete(mrename);
+ Swig_restore(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::variableHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::variableHandler(Node *n) {
+
+ /* 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.
+
+ Caveat: Some compilers seem to route attribute access through
+ methods which can generate exceptions. The feature:allowexcept
+ allows this. Also, the feature:exceptvar can be used to match
+ only variables.
+ */
+ if (!(Extend | SmartPointer)) {
+ if (!GetFlag(n, "feature:allowexcept")) {
+ UnsetFlag(n, "feature:except");
+ }
+ if (Getattr(n, "feature:exceptvar")) {
+ Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
+ }
+ }
+
+ if (!CurrentClass) {
+ globalvariableHandler(n);
+ } else {
+ String *storage = Getattr(n, "storage");
+ Swig_save("variableHandler", n, "feature:immutable", NIL);
+ if (SmartPointer) {
+ /* If a smart-pointer and it's a constant access, we have to set immutable */
+ if (Getattr(CurrentClass, "allocate:smartpointerconst")) {
+ SetFlag(n, "feature:immutable");
+ }
+ }
+ if ((Cmp(storage, "static") == 0) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"))) {
+ staticmembervariableHandler(n);
+ } else {
+ membervariableHandler(n);
+ }
+ Swig_restore(n);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::globalvariableHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::globalvariableHandler(Node *n) {
+ variableWrapper(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::membervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::membervariableHandler(Node *n) {
+
+ Swig_require("membervariableHandler", n, "*name", "*sym:name", "*type", NIL);
+ Swig_save("membervariableHandler", n, "parms", NIL);
+
+ String *name = Getattr(n, "name");
+ String *symname = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+
+ if (!AttributeFunctionGet) {
+ String *mname = Swig_name_member(ClassPrefix, symname);
+ String *mrename_get = Swig_name_get(mname);
+ String *mrename_set = Swig_name_set(mname);
+ Delete(mname);
+
+ /* Create a function to set the value of the variable */
+
+ int assignable = is_assignable(n);
+
+ if (SmartPointer) {
+ if (Getattr(CurrentClass, "allocate:smartpointerconst")) {
+ assignable = 0;
+ }
+ }
+
+ if (assignable) {
+ int make_set_wrapper = 1;
+ String *tm = 0;
+ String *target = 0;
+ if (!Extend) {
+ if (SmartPointer) {
+ if (checkAttribute(n, "storage", "static")) {
+ Node *sn = Getattr(n, "cplus:staticbase");
+ String *base = Getattr(sn, "name");
+ target = NewStringf("%s::%s", base, name);
+ } else {
+ String *pname = Swig_cparm_name(0, 0);
+ target = NewStringf("(*%s)->%s", pname, name);
+ Delete(pname);
+ }
+ } else {
+ String *pname = is_non_virtual_protected_access(n) ? NewString("darg") : Swig_cparm_name(0, 0);
+ target = NewStringf("%s->%s", pname, name);
+ Delete(pname);
+ }
+ } else {
+ target = NewStringf("$extendgetcall"); // member variable access expanded later
+ }
+ tm = Swig_typemap_lookup("memberin", n, target, 0);
+ int flags = Extend | SmartPointer | use_naturalvar_mode(n);
+ if (is_non_virtual_protected_access(n))
+ flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
+
+ String *call = 0;
+ Swig_MembersetToFunction(n, ClassType, flags, &call);
+ Setattr(n, "memberset", "1");
+
+ if (!tm) {
+ if (SwigType_isarray(type)) {
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
+ make_set_wrapper = 0;
+ }
+ } else {
+ String *pname0 = Swig_cparm_name(0, 0);
+ String *pname1 = Swig_cparm_name(0, 1);
+ Replace(tm, "$source", pname1, DOH_REPLACE_ANY);
+ Replace(tm, "$target", target, DOH_REPLACE_ANY);
+ Replace(tm, "$input", pname1, DOH_REPLACE_ANY);
+ Replace(tm, "$self", pname0, DOH_REPLACE_ANY);
+ Replace(tm, "$extendgetcall", call, DOH_REPLACE_ANY);
+ Setattr(n, "wrap:action", tm);
+ Delete(tm);
+ Delete(pname0);
+ Delete(pname1);
+ }
+ Delete(call);
+ Delete(target);
+
+ if (make_set_wrapper) {
+ Setattr(n, "sym:name", mrename_set);
+ functionWrapper(n);
+ } else {
+ SetFlag(n, "feature:immutable");
+ }
+ /* Restore parameters */
+ Setattr(n, "type", type);
+ Setattr(n, "name", name);
+ Setattr(n, "sym:name", symname);
+
+ /* Delete all attached typemaps and typemap attributes */
+ Iterator ki;
+ for (ki = First(n); ki.key; ki = Next(ki)) {
+ if (Strncmp(ki.key, "tmap:", 5) == 0)
+ Delattr(n, ki.key);
+ }
+ }
+ /* Emit get function */
+ {
+ int flags = Extend | SmartPointer | use_naturalvar_mode(n);
+ if (is_non_virtual_protected_access(n))
+ flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
+ Swig_MembergetToFunction(n, ClassType, flags);
+ Setattr(n, "sym:name", mrename_get);
+ Setattr(n, "memberget", "1");
+ functionWrapper(n);
+ }
+ Delete(mrename_get);
+ Delete(mrename_set);
+
+ } else {
+
+ /* This code is used to support the attributefunction directive
+ where member variables are converted automagically to
+ accessor functions */
+
+#if 0
+ Parm *p;
+ String *gname;
+ SwigType *vty;
+ p = NewParm(type, 0);
+ gname = NewStringf(AttributeFunctionGet, symname);
+ if (!Extend) {
+ ActionFunc = Copy(Swig_cmemberget_call(name, type));
+ cpp_member_func(Char(gname), Char(gname), type, 0);
+ Delete(ActionFunc);
+ } else {
+ String *cname = Swig_name_get(name);
+ cpp_member_func(Char(cname), Char(gname), type, 0);
+ Delete(cname);
+ }
+ Delete(gname);
+ if (!GetFlag(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 = 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("staticmembervariableHandler", n, "*name", "*sym:name", "*type", "?value", NIL);
+ String *value = Getattr(n, "value");
+ String *classname = !SmartPointer ? (is_non_virtual_protected_access(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerbase");
+
+ if (!value || !Getattr(n, "hasconsttype")) {
+ 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 {
+
+ /* This is a C++ static member declaration with an initializer and it's const.
+ Certain C++ compilers optimize this out so that there is no linkage to a
+ memory address. Example:
+
+ class Foo {
+ public:
+ static const int x = 3;
+ };
+
+ Some discussion of this in section 9.4 of the C++ draft standard.
+
+ Also, we have to manage the case:
+
+ class Foo {
+ public:
+ %extend {
+ static const int x = 3;
+ }
+ };
+
+ in which there's no actual Foo::x variable to refer to. In this case,
+ the best we can do is to wrap the given value verbatim.
+ */
+
+
+ String *name = Getattr(n, "name");
+ String *cname = NewStringf("%s::%s", classname, name);
+ if (Extend) {
+ /* the variable is a synthesized one.
+ There's nothing we can do; we just keep the given value */
+ } else {
+ /* we refer to the value as Foo::x */
+ 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);
+ SetFlag(n, "wrappedasconstant");
+ 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 != PUBLIC))
+ return SWIG_NOWRAP;
+
+ Swig_require("enumvalueDeclaration", 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 || !cparse_cplusplus) {
+ 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::enumforwardDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::enumforwardDeclaration(Node *n) {
+ (void) n;
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::memberconstantHandler()
+ * ----------------------------------------------------------------------------- */
+
+int Language::memberconstantHandler(Node *n) {
+
+ Swig_require("memberconstantHandler", n, "*name", "*sym:name", "value", NIL);
+
+ if (!GetFlag(n, "feature:allowexcept")) {
+ UnsetFlag(n, "feature:except");
+ }
+ if (Getattr(n, "feature:exceptvar")) {
+ Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
+ }
+
+ String *name = Getattr(n, "name");
+ String *symname = Getattr(n, "sym:name");
+ String *value = Getattr(n, "value");
+
+ String *mrename = Swig_name_member(ClassPrefix, symname);
+ Setattr(n, "sym:name", mrename);
+
+ String *new_name = 0;
+ if (Extend)
+ new_name = Copy(value);
+ else
+ new_name = NewStringf("%s::%s", is_non_virtual_protected_access(n) ? DirectorClassName : ClassName, name);
+ Setattr(n, "name", new_name);
+
+ constantWrapper(n);
+ Delete(mrename);
+ Delete(new_name);
+ Swig_restore(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::typedefHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::typedefHandler(Node *n) {
+ /* since this is a recurring issue, we are going to remember the
+ typedef pointer, if already it is not a pointer or reference, as
+ in
+
+ typedef void NT;
+ int func(NT *p);
+
+ see director_basic.i for example.
+ */
+ SwigType *name = Getattr(n, "name");
+ SwigType *decl = Getattr(n, "decl");
+ if (!SwigType_ispointer(decl) && !SwigType_isreference(decl)) {
+ SwigType *pname = Copy(name);
+ SwigType_add_pointer(pname);
+ SwigType_remember(pname);
+ Delete(pname);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDirectorMethod()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDirectorMethod(Node *n, Node *parent, String *super) {
+ (void) n;
+ (void) parent;
+ (void) super;
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDirectorConstructor()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDirectorConstructor(Node *n) {
+ (void) n;
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDirectorDefaultConstructor()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDirectorDefaultConstructor(Node *n) {
+ (void) n;
+ return SWIG_OK;
+}
+
+static String *vtable_method_id(Node *n) {
+ String *nodeType = Getattr(n, "nodeType");
+ int is_destructor = (Cmp(nodeType, "destructor") == 0);
+ if (is_destructor)
+ return 0;
+ String *name = Getattr(n, "name");
+ String *decl = Getattr(n, "decl");
+ String *local_decl = SwigType_typedef_resolve_all(decl);
+ String *tmp = SwigType_pop_function(local_decl);
+ Delete(local_decl);
+ local_decl = tmp;
+ Node *method_id = NewStringf("%s|%s", name, local_decl);
+ Delete(local_decl);
+ return method_id;
+}
+
+
+/* ----------------------------------------------------------------------
+ * Language::unrollVirtualMethods()
+ * ---------------------------------------------------------------------- */
+int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase) {
+ Node *ni;
+ String *nodeType;
+ String *classname;
+ String *decl;
+ bool first_base = false;
+ // recurse through all base classes to build the vtable
+ List *bl = Getattr(n, "bases");
+ if (bl) {
+ Iterator bi;
+ for (bi = First(bl); bi.item; bi = Next(bi)) {
+ if (first_base && !director_multiple_inheritance)
+ break;
+ unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor);
+ first_base = true;
+ }
+ }
+ // recurse through all protected base classes to build the vtable, as needed
+ bl = Getattr(n, "protectedbases");
+ if (bl) {
+ Iterator bi;
+ for (bi = First(bl); bi.item; bi = Next(bi)) {
+ if (first_base && !director_multiple_inheritance)
+ break;
+ unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor, 1);
+ first_base = true;
+ }
+ }
+ // find the methods that need directors
+ classname = Getattr(n, "name");
+ for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
+ /* we only need to check the virtual members */
+ if (!checkAttribute(ni, "storage", "virtual"))
+ continue;
+ nodeType = Getattr(ni, "nodeType");
+ /* we need to add methods(cdecl) and destructor (to check for throw decl) */
+ int is_destructor = (Cmp(nodeType, "destructor") == 0);
+ if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
+ decl = Getattr(ni, "decl");
+ /* extra check for function type and proper access */
+ if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(ni)) || need_nonpublic_member(ni))) {
+ String *name = Getattr(ni, "name");
+ Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(ni);
+ /* Make sure that the new method overwrites the existing: */
+ int len = Len(vm);
+ const int DO_NOT_REPLACE = -1;
+ int replace = DO_NOT_REPLACE;
+ for (int i = 0; i < len; i++) {
+ Node *item = Getitem(vm, i);
+ String *check_vmid = Getattr(item, "vmid");
+
+ if (Strcmp(method_id, check_vmid) == 0) {
+ replace = i;
+ break;
+ }
+ }
+ /* filling a new method item */
+ String *fqdname = NewStringf("%s::%s", classname, name);
+ Hash *item = NewHash();
+ Setattr(item, "fqdname", fqdname);
+ Node *m = Copy(ni);
+
+ /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */
+ SwigType *ty = NewString(Getattr(m, "type"));
+ SwigType_push(ty, decl);
+ if (SwigType_isqualifier(ty)) {
+ Delete(SwigType_pop(ty));
+ }
+ Delete(SwigType_pop_function(ty));
+ Setattr(m, "returntype", ty);
+
+ String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name);
+ /* apply the features of the original method found in the base class */
+ Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m);
+ Setattr(item, "methodNode", m);
+ Setattr(item, "vmid", method_id);
+ if (replace == DO_NOT_REPLACE)
+ Append(vm, item);
+ else
+ Setitem(vm, replace, item);
+
+ Delete(mname);
+ }
+ if (is_destructor) {
+ virtual_destructor = 1;
+ }
+ }
+ }
+
+ /*
+ We delete all the nodirector methods. This prevents the
+ generation of 'empty' director classes.
+
+ But this has to be done outside the previous 'for'
+ an the recursive loop!.
+ */
+ if (n == parent) {
+ int len = Len(vm);
+ for (int i = 0; i < len; i++) {
+ Node *item = Getitem(vm, i);
+ Node *m = Getattr(item, "methodNode");
+ /* retrieve the director features */
+ int mdir = GetFlag(m, "feature:director");
+ int mndir = GetFlag(m, "feature:nodirector");
+ /* 'nodirector' has precedence over 'director' */
+ int dir = (mdir || mndir) ? (mdir && !mndir) : 1;
+ /* check if the method was found only in a base class */
+ Node *p = Getattr(m, "parentNode");
+ if (p != n) {
+ Node *c = Copy(m);
+ Setattr(c, "parentNode", n);
+ int cdir = GetFlag(c, "feature:director");
+ int cndir = GetFlag(c, "feature:nodirector");
+ dir = (cdir || cndir) ? (cdir && !cndir) : dir;
+ Delete(c);
+ }
+ if (dir) {
+ /* be sure the 'nodirector' feature is disabled */
+ if (mndir)
+ Delattr(m, "feature:nodirector");
+ } else {
+ /* or just delete from the vm, since is not a director method */
+ Delitem(vm, i);
+ len--;
+ i--;
+ }
+ }
+ }
+
+ return SWIG_OK;
+}
+
+
+/* ----------------------------------------------------------------------
+ * Language::classDirectorDisown()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDirectorDisown(Node *n) {
+ Node *disown = NewHash();
+ String *mrename;
+ String *symname = Getattr(n, "sym:name");
+ mrename = Swig_name_disown(symname); //Getattr(n, "name"));
+ String *type = NewString(ClassType);
+ String *name = NewString("self");
+ SwigType_add_pointer(type);
+ Parm *p = NewParm(type, name);
+ Delete(name);
+ Delete(type);
+ type = NewString("void");
+ String *action = NewString("");
+ Printv(action, "{\n", "Swig::Director *director = dynamic_cast<Swig::Director *>(arg1);\n", "if (director) director->swig_disown();\n", "}\n", NULL);
+ Setattr(disown, "wrap:action", action);
+ Setattr(disown, "name", mrename);
+ Setattr(disown, "sym:name", mrename);
+ Setattr(disown, "type", type);
+ Setattr(disown, "parms", p);
+ Delete(action);
+ Delete(mrename);
+ Delete(type);
+ Delete(p);
+
+ functionWrapper(disown);
+ Delete(disown);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDirectorConstructors()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDirectorConstructors(Node *n) {
+ Node *ni;
+ String *nodeType;
+ Node *parent = Swig_methodclass(n);
+ int default_ctor = Getattr(parent, "allocate:default_constructor") ? 1 : 0;
+ int protected_ctor = 0;
+ int constructor = 0;
+
+ /* emit constructors */
+ for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
+ nodeType = Getattr(ni, "nodeType");
+ if (Cmp(nodeType, "constructor") == 0) {
+ Parm *parms = Getattr(ni, "parms");
+ if (is_public(ni)) {
+ /* emit public constructor */
+ classDirectorConstructor(ni);
+ constructor = 1;
+ if (default_ctor)
+ default_ctor = !ParmList_numrequired(parms);
+ } else {
+ /* emit protected constructor if needed */
+ if (need_nonpublic_ctor(ni)) {
+ classDirectorConstructor(ni);
+ constructor = 1;
+ protected_ctor = 1;
+ if (default_ctor)
+ default_ctor = !ParmList_numrequired(parms);
+ }
+ }
+ }
+ }
+ /* emit default constructor if needed */
+ if (!constructor) {
+ if (!default_ctor) {
+ /* we get here because the class has no public, protected or
+ default constructor, therefore, the director class can't be
+ created, ie, is kind of abstract. */
+ Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n), "Director class '%s' can't be constructed\n", SwigType_namestr(Getattr(n, "name")));
+ return SWIG_OK;
+ }
+ classDirectorDefaultConstructor(n);
+ default_ctor = 1;
+ }
+ /* this is just to support old java behavior, ie, the default
+ constructor is always emitted, even when protected, and not
+ needed, since there is a public constructor already defined.
+
+ (scottm) This code is needed here to make the director_abstract +
+ test generate compileable code (Example2 in director_abastract.i).
+
+ (mmatus) This is very strange, since swig compiled with gcc3.2.3
+ doesn't need it here....
+ */
+ if (!default_ctor && !protected_ctor) {
+ if (Getattr(parent, "allocate:default_base_constructor")) {
+ classDirectorDefaultConstructor(n);
+ }
+ }
+
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDirectorMethods()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDirectorMethods(Node *n) {
+ Node *vtable = Getattr(n, "vtable");
+
+ int len = Len(vtable);
+ for (int i = 0; i < len; i++) {
+ Node *item = Getitem(vtable, i);
+ String *method = Getattr(item, "methodNode");
+ String *fqdname = Getattr(item, "fqdname");
+ if (GetFlag(method, "feature:nodirector"))
+ continue;
+
+ String *type = Getattr(method, "nodeType");
+ if (!Cmp(type, "destructor")) {
+ classDirectorDestructor(method);
+ } else {
+ if (classDirectorMethod(method, n, fqdname) == SWIG_OK) {
+ Setattr(item, "director", "1");
+ }
+ }
+ }
+
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDirectorInit()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDirectorInit(Node *n) {
+ (void) n;
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDirectorDestructor()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDirectorDestructor(Node *n) {
+ /*
+ Always emit the virtual destructor in the declaration and in the
+ compilation unit. Been explicit here can't make any damage, and
+ can solve some nasty C++ compiler problems.
+ */
+ File *f_directors = Swig_filebyname("director");
+ File *f_directors_h = Swig_filebyname("director_h");
+ if (Getattr(n, "throw")) {
+ Printf(f_directors_h, " virtual ~%s() throw ();\n", DirectorClassName);
+ Printf(f_directors, "%s::~%s() throw () {\n}\n\n", DirectorClassName, DirectorClassName);
+ } else {
+ Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName);
+ Printf(f_directors, "%s::~%s() {\n}\n\n", DirectorClassName, DirectorClassName);
+ }
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDirectorEnd()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDirectorEnd(Node *n) {
+ (void) n;
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDirector()
+ * ---------------------------------------------------------------------- */
+
+int Language::classDirector(Node *n) {
+ Node *module = Getattr(n, "module");
+ String *classtype = Getattr(n, "classtype");
+ Hash *directormap = 0;
+ if (module) {
+ directormap = Getattr(module, "wrap:directormap");
+ if (directormap == 0) {
+ directormap = NewHash();
+ Setattr(module, "wrap:directormap", directormap);
+ }
+ }
+ List *vtable = NewList();
+ int virtual_destructor = 0;
+ unrollVirtualMethods(n, n, vtable, 0, virtual_destructor);
+
+ // Emit all the using base::member statements for non virtual members (allprotected mode)
+ Node *ni;
+ String *using_protected_members_code = NewString("");
+ for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
+ Node *nodeType = Getattr(ni, "nodeType");
+ bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
+ if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
+ if (is_non_virtual_protected_access(ni)) {
+ Node *overloaded = Getattr(ni, "sym:overloaded");
+ // emit the using base::member statement (but only once if the method is overloaded)
+ if (!overloaded || (overloaded && (overloaded == ni)))
+ Printf(using_protected_members_code, " using %s::%s;\n", SwigType_namestr(ClassName), Getattr(ni, "name"));
+ }
+ }
+ }
+
+ if (virtual_destructor || Len(vtable) > 0) {
+ if (!virtual_destructor) {
+ String *classtype = Getattr(n, "classtype");
+ Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number, "Director base class %s has no virtual destructor.\n", classtype);
+ }
+
+ Setattr(n, "vtable", vtable);
+ if (directormap != 0) {
+ Setattr(directormap, classtype, n);
+ }
+ classDirectorInit(n);
+ classDirectorConstructors(n);
+ classDirectorMethods(n);
+
+ File *f_directors_h = Swig_filebyname("director_h");
+ Printv(f_directors_h, using_protected_members_code, NIL);
+
+ classDirectorEnd(n);
+ }
+ Delete(vtable);
+ Delete(using_protected_members_code);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classDeclaration()
+ * ---------------------------------------------------------------------- */
+
+static void addCopyConstructor(Node *n) {
+ Node *cn = NewHash();
+ set_nodeType(cn, "constructor");
+ Setattr(cn, "access", "public");
+ Setfile(cn, Getfile(n));
+ Setline(cn, Getline(n));
+
+ String *cname = Getattr(n, "name");
+ SwigType *type = Copy(cname);
+ String *last = Swig_scopename_last(cname);
+ String *name = NewStringf("%s::%s", cname, last);
+ String *cc = NewStringf("r.q(const).%s", type);
+ String *decl = NewStringf("f(%s).", cc);
+ String *csymname = Getattr(n, "sym:name");
+ String *oldname = csymname;
+
+ if (Getattr(n, "allocate:has_constructor")) {
+ // to work properly with '%rename Class', we must look
+ // for any other constructor in the class, which has not been
+ // renamed, and use its name as oldname.
+ Node *c;
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ const char *tag = Char(nodeType(c));
+ if (strcmp(tag, "constructor") == 0) {
+ String *cname = Getattr(c, "name");
+ String *csname = Getattr(c, "sym:name");
+ String *clast = Swig_scopename_last(cname);
+ if (Equal(csname, clast)) {
+ oldname = csname;
+ break;
+ }
+ }
+ }
+ }
+
+ String *symname = Swig_name_make(cn, cname, last, decl, oldname);
+ if (Strcmp(symname, "$ignore") != 0) {
+ if (!symname) {
+ symname = Copy(csymname);
+ }
+ Parm *p = NewParm(cc, "other");
+
+ Setattr(cn, "name", name);
+ Setattr(cn, "sym:name", symname);
+ SetFlag(cn, "feature:new");
+ Setattr(cn, "decl", decl);
+ Setattr(cn, "parentNode", n);
+ Setattr(cn, "parms", p);
+ Setattr(cn, "copy_constructor", "1");
+
+ Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
+ Node *on = Swig_symbol_add(symname, cn);
+ Swig_symbol_setscope(oldscope);
+ Swig_features_get(Swig_cparse_features(), 0, name, decl, cn);
+
+ if (on == cn) {
+ Node *access = NewHash();
+ set_nodeType(access, "access");
+ Setattr(access, "kind", "public");
+ appendChild(n, access);
+ appendChild(n, cn);
+ Setattr(n, "has_copy_constructor", "1");
+ Setattr(n, "copy_constructor_decl", decl);
+ Setattr(n, "allocate:copy_constructor", "1");
+ Delete(access);
+ }
+ }
+ Delete(cn);
+ Delete(last);
+ Delete(name);
+ Delete(decl);
+ Delete(symname);
+}
+
+static void addDefaultConstructor(Node *n) {
+ Node *cn = NewHash();
+ set_nodeType(cn, "constructor");
+ Setattr(cn, "access", "public");
+ Setfile(cn, Getfile(n));
+ Setline(cn, Getline(n));
+
+ String *cname = Getattr(n, "name");
+ String *last = Swig_scopename_last(cname);
+ String *name = NewStringf("%s::%s", cname, last);
+ String *decl = NewString("f().");
+ String *csymname = Getattr(n, "sym:name");
+ String *oldname = csymname;
+ String *symname = Swig_name_make(cn, cname, last, decl, oldname);
+ if (Strcmp(symname, "$ignore") != 0) {
+ if (!symname) {
+ symname = Copy(csymname);
+ }
+
+ Setattr(cn, "name", name);
+ Setattr(cn, "sym:name", symname);
+ SetFlag(cn, "feature:new");
+ Setattr(cn, "decl", decl);
+ Setattr(cn, "parentNode", n);
+ Setattr(cn, "default_constructor", "1");
+
+ Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
+ Node *on = Swig_symbol_add(symname, cn);
+ Swig_symbol_setscope(oldscope);
+ Swig_features_get(Swig_cparse_features(), 0, name, decl, cn);
+
+ if (on == cn) {
+ Node *access = NewHash();
+ set_nodeType(access, "access");
+ Setattr(access, "kind", "public");
+ appendChild(n, access);
+ appendChild(n, cn);
+ Setattr(n, "has_default_constructor", "1");
+ Setattr(n, "allocate:default_constructor", "1");
+ Delete(access);
+ }
+ }
+ Delete(cn);
+ Delete(last);
+ Delete(name);
+ Delete(decl);
+ Delete(symname);
+}
+
+static void addDestructor(Node *n) {
+ Node *cn = NewHash();
+ set_nodeType(cn, "destructor");
+ Setattr(cn, "access", "public");
+ Setfile(cn, Getfile(n));
+ Setline(cn, Getline(n));
+
+ String *cname = Getattr(n, "name");
+ String *last = Swig_scopename_last(cname);
+ Insert(last, 0, "~");
+ String *name = NewStringf("%s::%s", cname, last);
+ String *decl = NewString("f().");
+ String *symname = Swig_name_make(cn, cname, last, decl, 0);
+ if (Strcmp(symname, "$ignore") != 0) {
+ if (!symname) {
+ symname = NewStringf("~%s", Getattr(n, "sym:name"));
+ }
+
+ Setattr(cn, "name", name);
+ Setattr(cn, "sym:name", symname);
+ Setattr(cn, "decl", "f().");
+ Setattr(cn, "parentNode", n);
+
+ Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
+ Node *on = Swig_symbol_add(symname, cn);
+ Swig_symbol_setscope(oldscope);
+ Swig_features_get(Swig_cparse_features(), 0, name, decl, cn);
+
+ if (on == cn) {
+ Node *access = NewHash();
+ set_nodeType(access, "access");
+ Setattr(access, "kind", "public");
+ appendChild(n, access);
+ appendChild(n, cn);
+ Setattr(n, "has_destructor", "1");
+ Setattr(n, "allocate:destructor", "1");
+ Delete(access);
+ }
+ }
+ Delete(cn);
+ Delete(last);
+ Delete(name);
+ Delete(decl);
+ Delete(symname);
+}
+
+int Language::classDeclaration(Node *n) {
+ String *ochildren = Getattr(n, "feature:onlychildren");
+ if (ochildren) {
+ Setattr(n, "feature:emitonlychildren", ochildren);
+ emit_children(n);
+ Delattr(n, "feature:emitonlychildren");
+ SetFlag(n, "feature:ignore");
+ return SWIG_NOWRAP;
+ }
+
+ 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 */
+ 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("classDeclaration", n, "name", NIL);
+ Setattr(n, "name", classname);
+
+ if (Cmp(kind, "class") == 0) {
+ cplus_mode = PRIVATE;
+ } else {
+ cplus_mode = PUBLIC;
+ }
+
+ ClassName = NewString(classname);
+ ClassPrefix = NewString(iname);
+ if (strip) {
+ ClassType = NewString(classname);
+ } else {
+ ClassType = NewStringf("%s %s", kind, classname);
+ }
+ Setattr(n, "classtypeobj", Copy(ClassType));
+ Setattr(n, "classtype", SwigType_namestr(ClassType));
+
+ InClass = 1;
+ CurrentClass = n;
+
+
+ /* Call classHandler() here */
+ if (!ImportMode) {
+ int dir = 0;
+ if (directorsEnabled()) {
+ int ndir = GetFlag(n, "feature:director");
+ int nndir = GetFlag(n, "feature:nodirector");
+ /* 'nodirector' has precedence over 'director' */
+ dir = (ndir || nndir) ? (ndir && !nndir) : 0;
+ }
+ int abstract = !dir && abstractClassTest(n);
+ int odefault = (GenerateDefault && !GetFlag(n, "feature:nodefault"));
+
+ /* default constructor */
+ if (!abstract && !GetFlag(n, "feature:nodefaultctor") && odefault) {
+ if (!Getattr(n, "has_constructor") && !Getattr(n, "allocate:has_constructor") && (Getattr(n, "allocate:default_constructor"))) {
+ addDefaultConstructor(n);
+ }
+ }
+ /* copy constructor */
+ if (CPlusPlus && !abstract && GetFlag(n, "feature:copyctor")) {
+ if (!Getattr(n, "has_copy_constructor") && !Getattr(n, "allocate:has_copy_constructor")
+ && (Getattr(n, "allocate:copy_constructor"))
+ && (!GetFlag(n, "feature:ignore"))) {
+ addCopyConstructor(n);
+ }
+ }
+ /* default destructor */
+ if (!GetFlag(n, "feature:nodefaultdtor") && odefault) {
+ if (!Getattr(n, "has_destructor") && (!Getattr(n, "allocate:has_destructor"))
+ && (Getattr(n, "allocate:default_destructor"))
+ && (!GetFlag(n, "feature:ignore"))) {
+ addDestructor(n);
+ }
+ }
+
+ if (dir) {
+ DirectorClassName = NewStringf("SwigDirector_%s", symname);
+ classDirector(n);
+ }
+ /* check for abstract after resolving directors */
+ Abstract = abstractClassTest(n);
+
+ classHandler(n);
+ } else {
+ Abstract = abstractClassTest(n);
+ Language::classHandler(n);
+ }
+
+ InClass = 0;
+ CurrentClass = 0;
+ Delete(ClassType);
+ ClassType = 0;
+ Delete(ClassPrefix);
+ ClassPrefix = 0;
+ Delete(ClassName);
+ ClassName = 0;
+ Delete(DirectorClassName);
+ DirectorClassName = 0;
+ Swig_restore(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::classHandler(Node *n) {
+
+ bool hasDirector = Swig_directorclass(n) ? true : false;
+
+ /* 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 = PUBLIC;
+ SmartPointer = CWRAP_SMART_POINTER;
+ Iterator c;
+ for (c = First(methods); c.item; c = Next(c)) {
+ emit_one(c.item);
+ }
+ SmartPointer = 0;
+ }
+
+ cplus_mode = PUBLIC;
+
+ /* emit director disown method */
+ if (hasDirector) {
+ classDirectorDisown(n);
+
+ /* Emit additional protected virtual methods - only needed if the language module
+ * codes logic in the C++ layer instead of the director proxy class method - primarily
+ * to catch public use of protected methods by the scripting languages. */
+ if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) {
+ Node *vtable = Getattr(n, "vtable");
+ String *symname = Getattr(n, "sym:name");
+ AccessMode old_mode = cplus_mode;
+ cplus_mode = PROTECTED;
+ int len = Len(vtable);
+ for (int i = 0; i < len; i++) {
+ Node *item = Getitem(vtable, i);
+ Node *method = Getattr(item, "methodNode");
+ SwigType *type = Getattr(method, "nodeType");
+ if (Strcmp(type, "cdecl") != 0)
+ continue;
+ if (GetFlag(method, "feature:ignore"))
+ continue;
+ String *methodname = Getattr(method, "sym:name");
+ String *wrapname = NewStringf("%s_%s", symname, methodname);
+ if (!Getattr(symbols, wrapname) && (!is_public(method))) {
+ Node *m = Copy(method);
+ Setattr(m, "director", "1");
+ Setattr(m, "parentNode", n);
+ /*
+ * There is a bug that needs fixing still...
+ * This area of code is creating methods which have not been overidden in a derived class (director methods that are protected in the base)
+ * If the method is overloaded, then Swig_overload_dispatch() incorrectly generates a call to the base wrapper, _wrap_xxx method
+ * See director_protected_overloaded.i - Possibly sym:overname needs correcting here.
+ Printf(stdout, "new method: %s::%s(%s)\n", Getattr(parentNode(m), "name"), Getattr(m, "name"), ParmList_str_defaultargs(Getattr(m, "parms")));
+ */
+ cDeclaration(m);
+ Delete(m);
+ }
+ Delete(wrapname);
+ }
+ cplus_mode = old_mode;
+ }
+ }
+
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::classforwardDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::classforwardDeclaration(Node *n) {
+ (void) n;
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::constructorDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::constructorDeclaration(Node *n) {
+ String *name = Getattr(n, "name");
+ String *symname = Getattr(n, "sym:name");
+
+ if (!symname)
+ return SWIG_NOWRAP;
+ if (!CurrentClass)
+ return SWIG_NOWRAP;
+ if (ImportMode)
+ return SWIG_NOWRAP;
+
+ if (Extend) {
+ /* extend default constructor can be safely ignored if there is already one */
+ int num_required = ParmList_numrequired(Getattr(n, "parms"));
+ if ((num_required == 0) && Getattr(CurrentClass, "has_default_constructor")) {
+ return SWIG_NOWRAP;
+ }
+ if ((num_required == 1) && Getattr(CurrentClass, "has_copy_constructor")) {
+ String *ccdecl = Getattr(CurrentClass, "copy_constructor_decl");
+ if (ccdecl && (Strcmp(ccdecl, Getattr(n, "decl")) == 0)) {
+ return SWIG_NOWRAP;
+ }
+ }
+ }
+
+ /* clean protected overloaded constructors, in case they are not needed anymore */
+ Node *over = Swig_symbol_isoverloaded(n);
+ if (over && !Getattr(CurrentClass, "sym:cleanconstructor")) {
+ int dirclass = Swig_directorclass(CurrentClass);
+ Node *nn = over;
+ while (nn) {
+ if (!is_public(nn)) {
+ if (!dirclass || !need_nonpublic_ctor(nn)) {
+ SetFlag(nn, "feature:ignore");
+ }
+ }
+ nn = Getattr(nn, "sym:nextSibling");
+ }
+ clean_overloaded(over);
+ Setattr(CurrentClass, "sym:cleanconstructor", "1");
+ }
+
+ if ((cplus_mode != PUBLIC)) {
+ /* check only for director classes */
+ if (!Swig_directorclass(CurrentClass) || !need_nonpublic_ctor(n))
+ return SWIG_NOWRAP;
+ }
+
+ /* Name adjustment for %name */
+ Swig_save("constructorDeclaration", 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) {
+ Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, input_file, line_number,
+ "Overloaded constructor ignored. %s\n", Swig_name_decl(n));
+ Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, Getfile(over), Getline(over),
+ "Previous declaration is %s\n", Swig_name_decl(over));
+ } else {
+ constructorHandler(n);
+ }
+ }
+ } else {
+ if (name && (Cmp(Swig_scopename_last(name), Swig_scopename_last(ClassName))) && !(Getattr(n, "template"))) {
+ Swig_warning(WARN_LANG_RETURN_TYPE, input_file, line_number, "Function %s must have a return type.\n", SwigType_namestr(name));
+ Swig_restore(n);
+ return SWIG_NOWRAP;
+ }
+ constructorHandler(n);
+ }
+ }
+ Setattr(CurrentClass, "has_constructor", "1");
+
+ Swig_restore(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * get_director_ctor_code()
+ * ---------------------------------------------------------------------- */
+
+static String *get_director_ctor_code(Node *n, String *director_ctor_code, String *director_prot_ctor_code, List *&abstract) {
+ String *director_ctor = director_ctor_code;
+ int use_director = Swig_directorclass(n);
+ if (use_director) {
+ Node *pn = Swig_methodclass(n);
+ abstract = Getattr(pn, "abstract");
+ if (director_prot_ctor_code) {
+ int is_notabstract = GetFlag(pn, "feature:notabstract");
+ int is_abstract = abstract && !is_notabstract;
+ if (is_protected(n) || is_abstract) {
+ director_ctor = director_prot_ctor_code;
+ Delattr(pn, "abstract");
+ } else {
+ if (is_notabstract) {
+ Delattr(pn, "abstract");
+ } else {
+ abstract = 0;
+ }
+ }
+ }
+ }
+ return director_ctor;
+}
+
+
+/* ----------------------------------------------------------------------
+ * Language::constructorHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::constructorHandler(Node *n) {
+ Swig_require("constructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
+ String *symname = Getattr(n, "sym:name");
+ String *mrename = Swig_name_construct(symname);
+ String *nodeType = Getattr(n, "nodeType");
+ int constructor = (!Cmp(nodeType, "constructor"));
+ List *abstract = 0;
+ String *director_ctor = get_director_ctor_code(n, director_ctor_code,
+ director_prot_ctor_code,
+ abstract);
+ if (!constructor) {
+ /* if not originally a constructor, still handle it as one */
+ Setattr(n, "handled_as_constructor", "1");
+ }
+
+ Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend);
+ Setattr(n, "sym:name", mrename);
+ functionWrapper(n);
+ Delete(mrename);
+ Swig_restore(n);
+ if (abstract)
+ Setattr(Swig_methodclass(n), "abstract", abstract);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::copyconstructorHandler()
+ * ---------------------------------------------------------------------- */
+
+int Language::copyconstructorHandler(Node *n) {
+ Swig_require("copyconstructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL);
+ String *symname = Getattr(n, "sym:name");
+ String *mrename = Swig_name_copyconstructor(symname);
+ List *abstract = 0;
+ String *director_ctor = get_director_ctor_code(n, director_ctor_code,
+ director_prot_ctor_code,
+ abstract);
+ Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend);
+ Setattr(n, "sym:name", mrename);
+ functionWrapper(n);
+ Delete(mrename);
+ Swig_restore(n);
+ if (abstract)
+ Setattr(Swig_methodclass(n), "abstract", abstract);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::destructorDeclaration()
+ * ---------------------------------------------------------------------- */
+
+int Language::destructorDeclaration(Node *n) {
+
+ if (!CurrentClass)
+ return SWIG_NOWRAP;
+ if (cplus_mode != PUBLIC)
+ return SWIG_NOWRAP;
+ if (ImportMode)
+ return SWIG_NOWRAP;
+
+ if (Extend) {
+ /* extend destructor can be safetly ignored if there is already one */
+ if (Getattr(CurrentClass, "has_destructor")) {
+ return SWIG_NOWRAP;
+ }
+ }
+
+ Swig_save("destructorDeclaration", 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("destructorHandler", n, "?name", "*sym:name", NIL);
+ Swig_save("destructorHandler", 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 = PUBLIC;
+ } else if (Cmp(kind, "private") == 0) {
+ cplus_mode = PRIVATE;
+ } else if (Cmp(kind, "protected") == 0) {
+ cplus_mode = PROTECTED;
+ }
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::namespaceDeclaration()
+ * ----------------------------------------------------------------------------- */
+
+int Language::namespaceDeclaration(Node *n) {
+ if (Getattr(n, "alias"))
+ return SWIG_OK;
+ if (Getattr(n, "unnamed"))
+ return SWIG_OK;
+ emit_children(n);
+ return SWIG_OK;
+}
+
+int Language::validIdentifier(String *s) {
+ char *c = Char(s);
+ while (*c) {
+ if (!(isalnum(*c) || (*c == '_')))
+ return 0;
+ c++;
+ }
+ return 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::usingDeclaration()
+ * ----------------------------------------------------------------------------- */
+
+int Language::usingDeclaration(Node *n) {
+ if ((cplus_mode == PUBLIC)) {
+ Node *np = Copy(n);
+ Node *c;
+ for (c = firstChild(np); c; c = nextSibling(c)) {
+ /* it seems for some cases this is needed, like A* A::boo() */
+ if (CurrentClass)
+ Setattr(c, "parentNode", CurrentClass);
+ emit_one(c);
+ }
+ Delete(np);
+ }
+ 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");
+ String *str = SwigType_str(type, name);
+ Printf(stdout, "constantWrapper : %s = %s\n", str, value);
+ Delete(str);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::variableWrapper()
+ * ---------------------------------------------------------------------- */
+
+int Language::variableWrapper(Node *n) {
+ Swig_require("variableWrapper", 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 */
+ int assignable = is_assignable(n);
+ int flags = use_naturalvar_mode(n);
+ if (!GetFlag(n, "wrappedasconstant"))
+ flags = flags | Extend;
+
+ if (assignable) {
+ int make_set_wrapper = 1;
+ String *tm = Swig_typemap_lookup("globalin", n, name, 0);
+
+ Swig_VarsetToFunction(n, flags);
+ String *sname = Swig_name_set(symname);
+ Setattr(n, "sym:name", sname);
+ Delete(sname);
+
+ if (!tm) {
+ if (SwigType_isarray(type)) {
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
+ make_set_wrapper = 0;
+ }
+ } else {
+ String *pname0 = Swig_cparm_name(0, 0);
+ Replace(tm, "$source", pname0, DOH_REPLACE_ANY);
+ Replace(tm, "$target", name, DOH_REPLACE_ANY);
+ Replace(tm, "$input", pname0, DOH_REPLACE_ANY);
+ Setattr(n, "wrap:action", tm);
+ Delete(tm);
+ Delete(pname0);
+ }
+ if (make_set_wrapper) {
+ functionWrapper(n);
+ }
+ /* Restore parameters */
+ Setattr(n, "sym:name", symname);
+ Setattr(n, "type", type);
+ Setattr(n, "name", name);
+
+ /* Delete all attached typemaps and typemap attributes */
+ Iterator ki;
+ for (ki = First(n); ki.key; ki = Next(ki)) {
+ if (Strncmp(ki.key, "tmap:", 5) == 0)
+ Delattr(n, ki.key);
+ }
+ }
+
+ Swig_VargetToFunction(n, flags);
+ String *gname = Swig_name_get(symname);
+ Setattr(n, "sym:name", gname);
+ Delete(gname);
+ functionWrapper(n);
+ Swig_restore(n);
+ return SWIG_OK;
+}
+
+/* ----------------------------------------------------------------------
+ * Language::functionWrapper()
+ * ---------------------------------------------------------------------- */
+
+int Language::functionWrapper(Node *n) {
+ String *name = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ ParmList *parms = Getattr(n, "parms");
+
+ Printf(stdout, "functionWrapper : %s\n", SwigType_str(type, NewStringf("%s(%s)", name, ParmList_str_defaultargs(parms))));
+ Printf(stdout, " action : %s\n", Getattr(n, "wrap:action"));
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::nativeWrapper()
+ * ----------------------------------------------------------------------------- */
+
+int Language::nativeWrapper(Node *n) {
+ (void) n;
+ return SWIG_OK;
+}
+
+void Language::main(int argc, char *argv[]) {
+ (void) argc;
+ (void) argv;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::addSymbol()
+ *
+ * Adds a symbol entry. Returns 1 if the symbol is added successfully.
+ * Prints an error message and returns 0 if a conflict occurs.
+ * ----------------------------------------------------------------------------- */
+
+int
+Language::addSymbol(const String *s, const Node *n) {
+ Node *c = Getattr(symbols, s);
+ if (c && (c != n)) {
+ Swig_error(input_file, line_number, "'%s' is multiply defined in the generated module.\n", s);
+ Swig_error(Getfile(c), Getline(c), "Previous declaration of '%s'\n", s);
+ return 0;
+ }
+ Setattr(symbols, s, n);
+ return 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::symbolLookup()
+ * ----------------------------------------------------------------------------- */
+
+Node *Language::symbolLookup(String *s) {
+ return Getattr(symbols, s);
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::classLookup()
+ *
+ * Tries to locate a class from a type definition
+ * ----------------------------------------------------------------------------- */
+
+Node *Language::classLookup(SwigType *s) {
+ Node *n = 0;
+
+ /* Look in hash of cached values */
+ n = Getattr(classtypes, s);
+ if (!n) {
+ Symtab *stab = 0;
+ SwigType *ty1 = SwigType_typedef_resolve_all(s);
+ SwigType *ty2 = SwigType_strip_qualifiers(ty1);
+ Delete(ty1);
+ ty1 = 0;
+
+ String *base = SwigType_base(ty2);
+
+ Replaceall(base, "class ", "");
+ Replaceall(base, "struct ", "");
+ Replaceall(base, "union ", "");
+
+ if (strncmp(Char(base), "::", 2) == 0) {
+ String *oldbase = base;
+ base = NewString(Char(base) + 2);
+ Delete(oldbase);
+ }
+
+ String *prefix = SwigType_prefix(ty2);
+
+ /* Do a symbol table search on the base type */
+ 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;
+ }
+ if (n) {
+ /* Found a match. Look at the prefix. We only allow
+ the cases where where we want a proxy class for the particular type */
+ if ((Len(prefix) == 0) || // simple type (pass by value)
+ (Strcmp(prefix, "p.") == 0) || // pointer
+ (Strcmp(prefix, "r.") == 0) || // reference
+ (Strcmp(prefix, "r.p.") == 0) || // pointer by reference
+ SwigType_prefix_is_simple_1D_array(prefix)) { // Simple 1D array (not arrays of pointers/references)
+ SwigType *cs = Copy(s);
+ Setattr(classtypes, cs, n);
+ Delete(cs);
+ } else {
+ n = 0;
+ }
+ }
+ Delete(ty2);
+ Delete(base);
+ Delete(prefix);
+ }
+ if (n && (GetFlag(n, "feature:ignore") || Getattr(n, "feature:onlychildren"))) {
+ n = 0;
+ }
+
+ return n;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::enumLookup()
+ *
+ * Finds and returns the Node containing the enum declaration for the (enum)
+ * type passed in.
+ * ----------------------------------------------------------------------------- */
+
+Node *Language::enumLookup(SwigType *s) {
+ Node *n = 0;
+
+ /* Look in hash of cached values */
+ n = Getattr(enumtypes, s);
+ if (!n) {
+ Symtab *stab = 0;
+ SwigType *lt = SwigType_ltype(s);
+ SwigType *ty1 = SwigType_typedef_resolve_all(lt);
+ SwigType *ty2 = SwigType_strip_qualifiers(ty1);
+ Delete(lt);
+ Delete(ty1);
+ lt = 0;
+ ty1 = 0;
+
+ String *base = SwigType_base(ty2);
+
+ Replaceall(base, "enum ", "");
+ String *prefix = SwigType_prefix(ty2);
+
+ if (strncmp(Char(base), "::", 2) == 0) {
+ String *oldbase = base;
+ base = NewString(Char(base) + 2);
+ Delete(oldbase);
+ }
+
+ /* Look for type in symbol table */
+ while (!n) {
+ Hash *nstab;
+ n = Swig_symbol_clookup(base, stab);
+ if (!n)
+ break;
+ if (Strcmp(nodeType(n), "enum") == 0)
+ break;
+ n = parentNode(n);
+ if (!n)
+ break;
+ nstab = Getattr(n, "sym:symtab");
+ n = 0;
+ if ((!nstab) || (nstab == stab)) {
+ break;
+ }
+ stab = nstab;
+ }
+ if (n) {
+ /* Found a match. Look at the prefix. We only allow simple types. */
+ if (Len(prefix) == 0) { /* Simple type */
+ Setattr(enumtypes, Copy(s), n);
+ } else {
+ n = 0;
+ }
+ }
+ Delete(ty2);
+ Delete(base);
+ Delete(prefix);
+ }
+ if (n && (GetFlag(n, "feature:ignore"))) {
+ n = 0;
+ }
+
+ return n;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::allow_overloading()
+ * ----------------------------------------------------------------------------- */
+
+void Language::allow_overloading(int val) {
+ overloading = val;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::allow_multiple_input()
+ * ----------------------------------------------------------------------------- */
+
+void Language::allow_multiple_input(int val) {
+ multiinput = val;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::enable_cplus_runtime_mode()
+ * ----------------------------------------------------------------------------- */
+
+void Language::enable_cplus_runtime_mode() {
+ cplus_runtime = 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::cplus_runtime_mode()
+ * ----------------------------------------------------------------------------- */
+
+int Language::cplus_runtime_mode() {
+ return cplus_runtime;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::allow_directors()
+ * ----------------------------------------------------------------------------- */
+
+void Language::allow_directors(int val) {
+ directors = val;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::directorsEnabled()
+ * ----------------------------------------------------------------------------- */
+
+int Language::directorsEnabled() const {
+ return director_language && CPlusPlus && (directors || director_mode);
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::allow_dirprot()
+ * ----------------------------------------------------------------------------- */
+
+void Language::allow_dirprot(int val) {
+ director_protected_mode = val;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::allow_allprotected()
+ * ----------------------------------------------------------------------------- */
+
+void Language::allow_allprotected(int val) {
+ all_protected_mode = val;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::dirprot_mode()
+ * ----------------------------------------------------------------------------- */
+
+int Language::dirprot_mode() const {
+ return directorsEnabled() ? director_protected_mode : 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::need_nonpublic_ctor()
+ * ----------------------------------------------------------------------------- */
+
+int Language::need_nonpublic_ctor(Node *n) {
+ /*
+ detects when a protected constructor is needed, which is always
+ the case if 'dirprot' mode is used. However, if that is not the
+ case, we will try to strictly emit what is minimal to don't break
+ the generated, while preserving compatibility with java, which
+ always try to emit the default constructor.
+
+ rules:
+
+ - when dirprot mode is used, the protected constructors are
+ always needed.
+
+ - the protected default constructor is always needed.
+
+ - if dirprot mode is not used, the protected constructors will be
+ needed only if:
+
+ - there is no any public constructor in the class, and
+ - there is no protected default constructor
+
+ In that case, all the declared protected constructors are
+ needed since we don't know which one to pick up.
+
+ Note: given all the complications here, I am always in favor to
+ always enable 'dirprot', since is the C++ idea of protected
+ members, and use %ignore for the method you don't whan to add in
+ the director class.
+ */
+ if (directorsEnabled()) {
+ if (is_protected(n)) {
+ if (dirprot_mode()) {
+ /* when using dirprot mode, the protected constructors are
+ always needed */
+ return 1;
+ } else {
+ int is_default_ctor = !ParmList_numrequired(Getattr(n, "parms"));
+ if (is_default_ctor) {
+ /* the default protected constructor is always needed, for java compatibility */
+ return 1;
+ } else {
+ /* check if there is a public constructor */
+ Node *parent = Swig_methodclass(n);
+ int public_ctor = Getattr(parent, "allocate:default_constructor")
+ || Getattr(parent, "allocate:public_constructor");
+ if (!public_ctor) {
+ /* if not, the protected constructor will be needed only
+ if there is no protected default constructor declared */
+ int no_prot_default_ctor = !Getattr(parent, "allocate:default_base_constructor");
+ return no_prot_default_ctor;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::need_nonpublic_member()
+ * ----------------------------------------------------------------------------- */
+int Language::need_nonpublic_member(Node *n) {
+ if (directorsEnabled()) {
+ if (is_protected(n)) {
+ if (dirprot_mode()) {
+ /* when using dirprot mode, the protected members are always needed. */
+ return 1;
+ } else {
+ /* if the method is pure virtual, we need it. */
+ int pure_virtual = (Cmp(Getattr(n, "value"), "0") == 0);
+ return pure_virtual;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Language::is_smart_pointer()
+ * ----------------------------------------------------------------------------- */
+
+int Language::is_smart_pointer() const {
+ return SmartPointer;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::extraDirectorProtectedCPPMethodsRequired()
+ * ----------------------------------------------------------------------------- */
+
+bool Language::extraDirectorProtectedCPPMethodsRequired() const {
+ return true;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::is_wrapping_class()
+ * ----------------------------------------------------------------------------- */
+
+int Language::is_wrapping_class() {
+ return InClass;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::getCurrentClass()
+ * ----------------------------------------------------------------------------- */
+
+Node *Language::getCurrentClass() const {
+ return CurrentClass;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::getClassName()
+ * ----------------------------------------------------------------------------- */
+
+String *Language::getClassName() const {
+ return ClassName;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::getClassPrefix()
+ * ----------------------------------------------------------------------------- */
+
+String *Language::getClassPrefix() const {
+ return ClassPrefix;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::getClassType()
+ * ----------------------------------------------------------------------------- */
+
+String *Language::getClassType() const {
+ return ClassType;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::abstractClassTest()
+ * ----------------------------------------------------------------------------- */
+//#define SWIG_DEBUG
+int Language::abstractClassTest(Node *n) {
+ /* check for non public operator new */
+ if (GetFlag(n, "feature:notabstract"))
+ return 0;
+ if (Getattr(n, "allocate:nonew"))
+ return 1;
+ /* now check for the rest */
+ List *abstract = Getattr(n, "abstract");
+ if (!abstract)
+ return 0;
+ int labs = Len(abstract);
+#ifdef SWIG_DEBUG
+ List *bases = Getattr(n, "allbases");
+ Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(bases));
+#endif
+ if (!labs)
+ return 0; /*strange, but need to be fixed */
+ if (abstract && !directorsEnabled())
+ return 1;
+ if (!GetFlag(n, "feature:director"))
+ return 1;
+
+ Node *dirabstract = 0;
+ Node *vtable = Getattr(n, "vtable");
+ if (vtable) {
+#ifdef SWIG_DEBUG
+ Printf(stderr, "vtable %s %d %d\n", Getattr(n, "name"), Len(vtable), labs);
+#endif
+ for (int i = 0; i < labs; i++) {
+ Node *ni = Getitem(abstract, i);
+ Node *method_id = vtable_method_id(ni);
+ if (!method_id)
+ continue;
+ bool exists_item = false;
+ int len = Len(vtable);
+ for (int i = 0; i < len; i++) {
+ Node *item = Getitem(vtable, i);
+ String *check_item = Getattr(item, "vmid");
+ if (Strcmp(method_id, check_item) == 0) {
+ exists_item = true;
+ break;
+ }
+ }
+#ifdef SWIG_DEBUG
+ Printf(stderr, "method %s %d\n", method_id, exists_item ? 1 : 0);
+#endif
+ Delete(method_id);
+ if (!exists_item) {
+ dirabstract = ni;
+ break;
+ }
+ }
+ if (dirabstract) {
+ if (is_public(dirabstract)) {
+ Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
+ "Director class '%s' is abstract, abstract method '%s' is not accesible, maybe due to multiple inheritance or 'nodirector' feature\n",
+ SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
+ } else {
+ Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n),
+ "Director class '%s' is abstract, abstract method '%s' is private\n", SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name"));
+ }
+ return 1;
+ }
+ } else {
+ return 1;
+ }
+ return dirabstract ? 1 : 0;
+}
+
+void Language::setSubclassInstanceCheck(String *nc) {
+ none_comparison = nc;
+}
+
+void Language::setOverloadResolutionTemplates(String *argc, String *argv) {
+ Delete(argc_template_string);
+ argc_template_string = Copy(argc);
+ Delete(argv_template_string);
+ argv_template_string = Copy(argv);
+}
+
+int Language::is_assignable(Node *n) {
+ if (GetFlag(n, "feature:immutable"))
+ return 0;
+ SwigType *type = Getattr(n, "type");
+ Node *cn = 0;
+ SwigType *ftd = SwigType_typedef_resolve_all(type);
+ SwigType *td = SwigType_strip_qualifiers(ftd);
+ if (SwigType_type(td) == T_USER) {
+ cn = Swig_symbol_clookup(td, 0);
+ if (cn) {
+ if ((Strcmp(nodeType(cn), "class") == 0)) {
+ if (Getattr(cn, "allocate:noassign")) {
+ SetFlag(n, "feature:immutable");
+ Delete(ftd);
+ Delete(td);
+ return 0;
+ }
+ }
+ }
+ }
+ Delete(ftd);
+ Delete(td);
+ return 1;
+}
+
+String *Language::runtimeCode() {
+ return NewString("");
+}
+
+String *Language::defaultExternalRuntimeFilename() {
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language::replaceSpecialVariables()
+ * Language modules should implement this if special variables are to be handled
+ * correctly in the $typemap(...) special variable macro.
+ * method - typemap method name
+ * tm - string containing typemap contents
+ * parm - a parameter describing the typemap type to be handled
+ * ----------------------------------------------------------------------------- */
+void Language::replaceSpecialVariables(String *method, String *tm, Parm *parm) {
+ (void)method;
+ (void)tm;
+ (void)parm;
+}
+
+Language *Language::instance() {
+ return this_;
+}
+
+Hash *Language::getClassHash() const {
+ return classhash;
+}
diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx
new file mode 100644
index 0000000..8835667
--- /dev/null
+++ b/Source/Modules/lua.cxx
@@ -0,0 +1,1226 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * lua.cxx
+ *
+ * Lua language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+/* NEW LANGUAGE NOTE:
+ * ver001
+ this is simply a copy of tcl8.cxx, which has been renamed
+ * ver002
+ all non essential code commented out, program now does virtually nothing
+ it prints to stderr the list of functions to wrap, but does not create
+ the XXX_wrap.c file
+ * ver003
+ added back top(), still prints the list of fns to stderr
+ but now creates a rather empty XXX_wrap.c with some basic boilerplate code
+ * ver004
+ very basic version of functionWrapper()
+ also uncommented usage_string() to keep compiler happy
+ this will start producing proper looking code soon (I hope)
+ produced the wrapper code, but without any type conversion (in or out)
+ generates a few warning because of no wrappering
+ does not generate SWIG_init()
+ reason for this is that lua.swg is empty
+ we will need to add code into this to make it work
+ * ver005/6
+ massive rework, basing work on the pike module instead of tcl
+ (pike module it only 1/3 of the size)(though not as complete)
+ * ver007
+ added simple type checking
+ * ver008
+ INPUT, OUTPUT, INOUT typemaps handled (though not all types yet)
+ * ver009
+ class support: ok for basic types, but methods still TDB
+ (code is VERY messed up & needs to be cleaned)
+
+
+*/
+
+char cvsroot_lua_cxx[] = "$Id: lua.cxx 11133 2009-02-20 07:52:24Z wsfulton $";
+
+#include "swigmod.h"
+
+/**** Diagnostics:
+ With the #define REPORT(), you can change the amount of diagnostics given
+ This helps me search the parse tree & figure out what is going on inside SWIG
+ (because its not clear or documented)
+*/
+#define REPORT(T,D) // no info:
+//#define REPORT(T,D) {Printf(stdout,T"\n");} // only title
+//#define REPORT(T,D) {Printf(stdout,T" %p\n",n);} // title & pointer
+//#define REPORT(T,D) {Printf(stdout,T"\n");display_mapping(D);} // the works
+//#define REPORT(T,D) {Printf(stdout,T"\n");if(D)Swig_print_node(D);} // the works
+
+void display_mapping(DOH *d) {
+ if (d == 0 || !DohIsMapping(d))
+ return;
+ for (DohIterator it = DohFirst(d); it.item; it = DohNext(it)) {
+ if (DohIsString(it.item))
+ Printf(stdout, " %s = %s\n", it.key, it.item);
+ else if (DohIsMapping(it.item))
+ Printf(stdout, " %s = <mapping>\n", it.key);
+ else if (DohIsSequence(it.item))
+ Printf(stdout, " %s = <sequence>\n", it.key);
+ else
+ Printf(stdout, " %s = <unknown>\n", it.key);
+ }
+}
+
+
+
+/* NEW LANGUAGE NOTE:***********************************************
+ most of the default options are handled by SWIG
+ you can add new ones here
+ (though for now I have not bothered)
+NEW LANGUAGE NOTE:END ************************************************/
+static const char *usage = (char *) "\
+ Lua Options (available with -lua)\n\
+ (coming soon.)\n\n";
+
+
+
+/* NEW LANGUAGE NOTE:***********************************************
+ To add a new language, you need to derive your class from
+ Language and the overload various virtual functions
+ (more on this as I figure it out)
+NEW LANGUAGE NOTE:END ************************************************/
+
+class LUA:public Language {
+private:
+
+ File *f_begin;
+ File *f_runtime;
+ File *f_header;
+ File *f_wrappers;
+ File *f_init;
+ File *f_initbeforefunc;
+ String *PrefixPlusUnderscore;
+ String *s_cmd_tab; // table of command names
+ String *s_var_tab; // table of global variables
+ String *s_const_tab; // table of global constants
+ String *s_methods_tab; // table of class methods
+ String *s_attr_tab; // table of class atributes
+ String *s_luacode; // luacode to be called during init
+
+ int have_constructor;
+ int have_destructor;
+ String *destructor_action;
+ String *class_name;
+ String *constructor_name;
+
+ enum {
+ NO_CPP,
+ VARIABLE,
+ MEMBER_FUNC,
+ CONSTRUCTOR,
+ DESTRUCTOR,
+ MEMBER_VAR,
+ CLASS_CONST,
+ STATIC_FUNC,
+ STATIC_VAR
+ }current;
+
+public:
+
+ /* ---------------------------------------------------------------------
+ * LUA()
+ *
+ * Initialize member data
+ * --------------------------------------------------------------------- */
+
+ LUA() {
+ f_begin = 0;
+ f_runtime = 0;
+ f_header = 0;
+ f_wrappers = 0;
+ f_init = 0;
+ f_initbeforefunc = 0;
+ PrefixPlusUnderscore = 0;
+
+ s_cmd_tab = s_var_tab = s_const_tab = s_luacode = 0;
+ current=NO_CPP;
+ }
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ This is called to initalise the system & read any command line args
+ most of this is boilerplate code, except the command line args
+ which depends upon what args your code supports
+ NEW LANGUAGE NOTE:END ************************************************/
+
+ /* ---------------------------------------------------------------------
+ * main()
+ *
+ * Parse command line options and initializes variables.
+ * --------------------------------------------------------------------- */
+
+ virtual void main(int argc, char *argv[]) {
+
+ /* Set location of SWIG library */
+ SWIG_library_directory("lua");
+
+ /* Look for certain command line options */
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-help") == 0) { // usage flags
+ fputs(usage, stderr);
+ }
+ }
+ }
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ This is the boilerplate code, setting a few #defines
+ and which lib directory to use
+ the SWIG_library_directory() is also boilerplate code
+ but it always seems to be the first line of code
+ NEW LANGUAGE NOTE:END ************************************************/
+ /* Add a symbol to the parser for conditional compilation */
+ Preprocessor_define("SWIGLUA 1", 0);
+
+ /* Set language-specific configuration file */
+ SWIG_config_file("lua.swg");
+
+ /* Set typemap language */
+ SWIG_typemap_lang("lua");
+
+ /* Enable overloaded methods support */
+ allow_overloading();
+ }
+
+
+
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ After calling main, SWIG parses the code to wrap (I believe)
+ then calls top()
+ in this is more boilerplate code to set everything up
+ and a call to Language::top()
+ which begins the code generations by calling the member fns
+ after all that is more boilerplate code to close all down
+ (overall there is virtually nothing here that needs to be edited
+ just use as is)
+ NEW LANGUAGE NOTE:END ************************************************/
+ /* ---------------------------------------------------------------------
+ * 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_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+ f_initbeforefunc = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+ Swig_register_filebyname("initbeforefunc", f_initbeforefunc);
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ s_cmd_tab,s_var_tab & s_const_tab hold the names of the fns for
+ registering with SWIG.
+ These will be filled in when the functions/variables are wrapped &
+ then added to the end of the wrappering code
+ just before it is written to file
+ NEW LANGUAGE NOTE:END ************************************************/
+ // Initialize some variables for the object interface
+ s_cmd_tab = NewString("");
+ s_var_tab = NewString("");
+ // s_methods_tab = NewString("");
+ s_const_tab = NewString("");
+
+ s_luacode = NewString("");
+ Swig_register_filebyname("luacode", s_luacode);
+
+ current=NO_CPP;
+
+ /* Standard stuff for the SWIG runtime section */
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGLUA\n");
+
+ // if (NoInclude) {
+ // Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
+ // }
+
+ Printf(f_runtime, "\n");
+
+ //String *init_name = NewStringf("%(title)s_Init", module);
+ //Printf(f_header, "#define SWIG_init %s\n", init_name);
+ //Printf(f_header, "#define SWIG_name \"%s\"\n", module);
+ /* SWIG_import is a special function name for importing within Lua5.1 */
+ //Printf(f_header, "#define SWIG_import luaopen_%s\n\n", module);
+ Printf(f_header, "#define SWIG_name \"%s\"\n", module);
+ Printf(f_header, "#define SWIG_init luaopen_%s\n", module);
+ Printf(f_header, "#define SWIG_init_user luaopen_%s_user\n\n", module);
+ Printf(f_header, "#define SWIG_LUACODE luaopen_%s_luacode\n\n", module);
+
+ Printf(s_cmd_tab, "\nstatic const struct luaL_reg swig_commands[] = {\n");
+ Printf(s_var_tab, "\nstatic swig_lua_var_info swig_variables[] = {\n");
+ Printf(s_const_tab, "\nstatic swig_lua_const_info swig_constants[] = {\n");
+ Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
+
+ /* %init code inclusion, effectively in the SWIG_init function */
+ Printf(f_init, "void SWIG_init_user(lua_State* L)\n{\n");
+ Language::top(n);
+ Printf(f_init,"/* exec Lua code if applicable */\nSWIG_Lua_dostring(L,SWIG_LUACODE);\n");
+ Printf(f_init, "}\n");
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n");
+
+ // Done. Close up the module & write to the wrappers
+ Printv(s_cmd_tab, tab4, "{0,0}\n", "};\n", NIL);
+ Printv(s_var_tab, tab4, "{0,0,0}\n", "};\n", NIL);
+ Printv(s_const_tab, tab4, "{0,0,0,0,0,0}\n", "};\n", NIL);
+ Printv(f_wrappers, s_cmd_tab, s_var_tab, s_const_tab, NIL);
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ this basically combines several of the strings together
+ and then writes it all to a file
+ NEW LANGUAGE NOTE:END ************************************************/
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_wrappers, f_begin);
+ Dump(f_initbeforefunc, f_begin);
+ /* for the Lua code it needs to be properly excaped to be added into the C/C++ code */
+ EscapeCode(s_luacode);
+ Printf(f_begin, "const char* SWIG_LUACODE=\n \"%s\";\n\n",s_luacode);
+ Wrapper_pretty_print(f_init, f_begin);
+ /* Close all of the files */
+ Delete(s_luacode);
+ Delete(s_cmd_tab);
+ Delete(s_var_tab);
+ Delete(s_const_tab);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Delete(f_initbeforefunc);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+
+ /* Done */
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * importDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int importDirective(Node *n) {
+ return Language::importDirective(n);
+ }
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ This is it!
+ you get this one right, and most of your work is done
+ but its going to take soem file to get it working right
+ quite a bit of this is generally boilerplate code
+ (or stuff I dont understand)
+ that which matters will have extra added comments
+ NEW LANGUAGE NOTE:END ************************************************/
+ /* ---------------------------------------------------------------------
+ * functionWrapper()
+ *
+ * Create a function declaration and register it with the interpreter.
+ * --------------------------------------------------------------------- */
+
+ virtual int functionWrapper(Node *n) {
+ REPORT("functionWrapper",n);
+
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *d = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ //Printf(stdout,"functionWrapper %s %s\n",name,iname);
+ Parm *p;
+ String *tm;
+ int i;
+ //Printf(stdout,"functionWrapper %s %s %d\n",name,iname,current);
+ // int returnval=0; // number of arguments returned
+
+ String *overname = 0;
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n)) {
+ Printf(stderr,"addSymbol(%s) failed\n",iname);
+ return SWIG_ERROR;
+ }
+ }
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ the wrapper object holds all the wrappering code
+ we need to add a couple of local variables
+ NEW LANGUAGE NOTE:END ************************************************/
+ Wrapper *f = NewWrapper();
+ Wrapper_add_local(f, "SWIG_arg", "int SWIG_arg = 0");
+
+
+ String *wname = Swig_name_wrapper(iname);
+ if (overname) {
+ Append(wname, overname);
+ }
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ the format of a lua fn is:
+ static int wrap_XXX(lua_State* L){...}
+ this line adds this into the wrappering code
+ NEW LANGUAGE NOTE:END ************************************************/
+ Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL);
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ this prints the list of args, eg for a C fn
+ int gcd(int x,int y);
+ it will print
+ int arg1;
+ int arg2;
+ NEW LANGUAGE NOTE:END ************************************************/
+ /* Write code to extract function parameters. */
+ emit_parameter_variables(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 num_required = emit_num_required(l);
+ int varargs = emit_isvarargs(l);
+
+ // Check if we have to ignore arguments that are passed by LUA.
+ // Needed for unary minus, where lua passes two arguments and
+ // we have to ignore the second.
+
+ int args_to_ignore = 0;
+ if (Getattr(n, "lua:ignore_args")) {
+ args_to_ignore = GetInt(n, "lua:ignore_args");
+ }
+
+
+ /* 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;
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ from here on in, it gets rather hairy
+ this is the code to convert from the scripting language to C/C++
+ some of the stuff will refer to the typemaps code written in your swig file
+ (lua.swg), and some is done in the code here
+ I suppose you could do all the conversion on C, but it would be a nightmare to do
+ NEW LANGUAGE NOTE:END ************************************************/
+ /* Generate code for argument marshalling */
+ // String *description = NewString("");
+ /* NEW LANGUAGE NOTE:***********************************************
+ argument_check is a new feature I added to check types of arguments:
+ eg for int gcd(int,int)
+ I want to check that arg1 & arg2 really are integers
+ NEW LANGUAGE NOTE:END ************************************************/
+ String *argument_check = NewString("");
+ String *argument_parse = NewString("");
+ String *checkfn = NULL;
+ // String *numoutputs=NULL;
+ char source[64];
+ //Printf(argument_check, "SWIG_check_num_args(\"%s\",%d,%d)\n",name,num_required,num_arguments);
+ Printf(argument_check, "SWIG_check_num_args(\"%s\",%d,%d)\n",name,num_required+args_to_ignore,num_arguments+args_to_ignore);
+
+ 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");
+
+ /* Look for an input typemap */
+ sprintf(source, "%d", i + 1);
+ if ((tm = Getattr(p, "tmap:in"))) {
+ Replaceall(tm, "$source", source);
+ Replaceall(tm, "$target", ln);
+ 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");
+ }
+ /* NEW LANGUAGE NOTE:***********************************************
+ look for a 'checkfn' typemap
+ this an additional parameter added to the in typemap
+ if found the type will be tested for
+ this will result in code either in the
+ argument_check or argument_parse string
+ NEW LANGUAGE NOTE:END ************************************************/
+ if ((checkfn = Getattr(p, "tmap:in:checkfn"))) {
+ if (i < num_required) {
+ Printf(argument_check, "if(!%s(L,%s))", checkfn, source);
+ } else {
+ Printf(argument_check, "if(lua_gettop(L)>=%s && !%s(L,%s))", source, checkfn, source);
+ }
+ Printf(argument_check, " SWIG_fail_arg(\"%s\",%s,\"%s\");\n", name, source, SwigType_str(pt, 0));
+ }
+ /* NEW LANGUAGE NOTE:***********************************************
+ lua states the number of arguments passed to a function using the fn
+ lua_gettop()
+ we can use this to deal with default arguments
+ NEW LANGUAGE NOTE:END ************************************************/
+ if (i < num_required) {
+ Printf(argument_parse, "%s\n", tm);
+ } else {
+ Printf(argument_parse, "if(lua_gettop(L)>=%s){%s}\n", source, tm);
+ }
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ } else {
+ /* NEW LANGUAGE NOTE:***********************************************
+ // why is this code not called when I dont have a typemap?
+ // instead of giving a warning, no code is generated
+ NEW LANGUAGE NOTE:END ************************************************/
+ 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;
+ }
+ }
+
+ // add all argcheck code
+ Printv(f->code, argument_check, argument_parse, 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 */
+ 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"))) {
+ // // managing the number of returning variables
+ // if (numoutputs=Getattr(p,"tmap:argout:numoutputs")){
+ // int i=GetInt(p,"tmap:argout:numoutputs");
+ // printf("got argout:numoutputs of %d\n",i);
+ // returnval+=GetInt(p,"tmap:argout:numoutputs");
+ // }
+ // else returnval++;
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Replaceall(tm, "$target", "result");
+ 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);
+ }
+ }
+
+ Setattr(n, "wrap:name", wname);
+
+ /* Emit the function call */
+ String *actioncode = emit_action(n);
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ FIXME:
+ returns 1 if there is a void return type
+ this is because there is a typemap for void
+ NEW LANGUAGE NOTE:END ************************************************/
+ // Return value if necessary
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ // managing the number of returning variables
+ // if (numoutputs=Getattr(tm,"numoutputs")){
+ // int i=GetInt(tm,"numoutputs");
+ // printf("return numoutputs %d\n",i);
+ // returnval+=GetInt(tm,"numoutputs");
+ // }
+ // else returnval++;
+ Replaceall(tm, "$source", "result");
+ if (GetFlag(n, "feature:new")) {
+ Replaceall(tm, "$owner", "1");
+ } else {
+ Replaceall(tm, "$owner", "0");
+ }
+ Printf(f->code, "%s\n", tm);
+ // returnval++;
+ } 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);
+ }
+ emit_return_variable(n, d, f);
+
+ /* 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 (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("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("ret", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+
+
+ /* Close the function */
+ Printv(f->code, "return SWIG_arg;\n", NIL);
+ // add the failure cleanup code:
+ Printv(f->code, "\nif(0) SWIG_fail;\n", NIL);
+ Printv(f->code, "\nfail:\n", NIL);
+ Printv(f->code, "$cleanup", "lua_error(L);\n", NIL);
+ Printv(f->code, "return SWIG_arg;\n", NIL);
+ 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", "result");
+
+ /* Dump the function out */
+ /* in Lua we will not emit the destructor as a wrappered function,
+ Lua will automatically call the destructor when the object is free'd
+ However: you cannot just skip this function as it will not emit
+ any custom destructor (using %extend), as you need to call emit_action()
+ Therefore we go though the whole function,
+ but do not write the code into the wrapper
+ */
+ if(current!=DESTRUCTOR) {
+ Wrapper_print(f, f_wrappers);
+ }
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ register the function in SWIG
+ different language mappings seem to use different ideas
+ NEW LANGUAGE NOTE:END ************************************************/
+ /* Now register the function with the interpreter. */
+ if (!Getattr(n, "sym:overloaded")) {
+ // add_method(n, iname, wname, description);
+ if (current==NO_CPP || current==STATIC_FUNC) // emit normal fns & static fns
+ Printv(s_cmd_tab, tab4, "{ \"", iname, "\", ", Swig_name_wrapper(iname), "},\n", NIL);
+ // Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", Swig_name_wrapper(iname), "},\n", NIL);
+ } else {
+ if (!Getattr(n, "sym:nextSibling")) {
+ dispatchFunction(n);
+ }
+ }
+
+ Delete(argument_check);
+ Delete(argument_parse);
+
+ Delete(cleanup);
+ Delete(outarg);
+ // Delete(description);
+ Delete(wname);
+ DelWrapper(f);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * dispatchFunction()
+ *
+ * Emit overloading dispatch function
+ * ------------------------------------------------------------ */
+
+ /* NEW LANGUAGE NOTE:***********************************************
+ This is an extra function used for overloading of functions
+ it checks the args & then calls the relevant fn
+ nost of the real work in again typemaps:
+ look for %typecheck(SWIG_TYPECHECK_*) in the .swg file
+ NEW LANGUAGE NOTE:END ************************************************/
+ void dispatchFunction(Node *n) {
+ /* Last node in overloaded chain */
+
+ int maxargs;
+ String *tmp = NewString("");
+ String *dispatch = Swig_overload_dispatch(n, "return %s(L);", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *f = NewWrapper();
+ String *symname = Getattr(n, "sym:name");
+ String *wname = Swig_name_wrapper(symname);
+
+ //Printf(stdout,"Swig_overload_dispatch %s %s '%s' %d\n",symname,wname,dispatch,maxargs);
+
+ Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL);
+ Wrapper_add_local(f, "argc", "int argc");
+ Printf(tmp, "int argv[%d]={1", maxargs + 1);
+ for (int i = 1; i <= maxargs; i++) {
+ Printf(tmp, ",%d", i + 1);
+ }
+ Printf(tmp, "}");
+ Wrapper_add_local(f, "argv", tmp);
+ Printf(f->code, "argc = lua_gettop(L);\n");
+
+ Replaceall(dispatch, "$args", "self,args");
+ Printv(f->code, dispatch, "\n", NIL);
+
+ Node *sibl = n;
+ while (Getattr(sibl, "sym:previousSibling"))
+ sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up
+ String *protoTypes = NewString("");
+ do {
+ Printf(protoTypes, "\n\" %s(%s)\\n\"", SwigType_str(Getattr(sibl, "name"), 0), ParmList_protostr(Getattr(sibl, "wrap:parms")));
+ } while ((sibl = Getattr(sibl, "sym:nextSibling")));
+ Printf(f->code, "lua_pushstring(L,\"Wrong arguments for overloaded function '%s'\\n\"\n"
+ "\" Possible C/C++ prototypes are:\\n\"%s);\n",symname,protoTypes);
+ Delete(protoTypes);
+
+ Printf(f->code, "lua_error(L);return 0;\n");
+ Printv(f->code, "}\n", NIL);
+ Wrapper_print(f, f_wrappers);
+ //add_method(symname,wname,0);
+ if (current==NO_CPP || current==STATIC_FUNC) // emit normal fns & static fns
+ Printv(s_cmd_tab, tab4, "{ \"", symname, "\",", wname, "},\n", NIL);
+
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(tmp);
+ Delete(wname);
+ }
+
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+ /* NEW LANGUAGE NOTE:***********************************************
+ Language::variableWrapper(n) will generate two wrapper fns
+ Foo_get & Foo_set by calling functionWrapper()
+ so we will just add these into the variable lists
+ ideally we should not have registered these as functions,
+ only WRT this variable will look into this later.
+ NEW LANGUAGE NOTE:END ************************************************/
+ // REPORT("variableWrapper", n);
+ String *iname = Getattr(n, "sym:name");
+ current=VARIABLE;
+ // let SWIG generate the wrappers
+ int result = Language::variableWrapper(n);
+ current=NO_CPP;
+ // normally SWIG will generate 2 wrappers, a get and a set
+ // but in certain scenarios (immutable, or if its arrays), it will not
+ String *getName = Swig_name_wrapper(Swig_name_get(iname));
+ String *setName = 0;
+ // checking whether it can be set to or not appears to be a very error prone issue
+ // I refered to the Language::variableWrapper() to find this out
+ bool assignable=is_assignable(n) ? true : false;
+ SwigType *type = Getattr(n, "type");
+ String *tm = Swig_typemap_lookup("globalin", n, iname, 0);
+ if (!tm && SwigType_isarray(type))
+ assignable=false;
+ Delete(tm);
+
+ if (assignable) {
+ setName = Swig_name_wrapper(Swig_name_set(iname));
+ } else {
+ // how about calling a 'this is not settable' error message?
+ setName = NewString("SWIG_Lua_set_immutable"); // error message
+ //setName = NewString("0");
+ }
+ // register the variable
+ Printf(s_var_tab, "%s{ \"%s\", %s, %s },\n", tab4, iname, getName, setName);
+ Delete(getName);
+ Delete(setName);
+ return result;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+ virtual int constantWrapper(Node *n) {
+ // REPORT("constantWrapper", n);
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ //String *nsname = !nspace ? Copy(iname) : NewStringf("%s::%s",ns_name,iname);
+ String *nsname = Copy(iname);
+ SwigType *type = Getattr(n, "type");
+ String *rawval = Getattr(n, "rawval");
+ String *value = rawval ? rawval : Getattr(n, "value");
+ String *tm;
+
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ //if (nspace) Setattr(n,"sym:name",nsname);
+
+ /* 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("consttab", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ Replaceall(tm, "$nsname", nsname);
+ Printf(s_const_tab, "%s,\n", tm);
+ } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ Replaceall(tm, "$nsname", nsname);
+ Printf(f_init, "%s\n", tm);
+ } else {
+ Delete(nsname);
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+ Delete(nsname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int nativeWrapper(Node *n) {
+ // REPORT("nativeWrapper", n);
+ String *symname = Getattr(n, "sym:name");
+ String *wrapname = Getattr(n, "wrap:name");
+ if (!addSymbol(wrapname, n))
+ return SWIG_ERROR;
+
+ Printv(s_cmd_tab, tab4, "{ \"", symname, "\",", wrapname, "},\n", NIL);
+ // return Language::nativeWrapper(n); // this does nothing...
+ 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) {
+ //REPORT("classHandler", n);
+
+ String *mangled_classname = 0;
+ String *real_classname = 0;
+
+ constructor_name = 0;
+ have_constructor = 0;
+ have_destructor = 0;
+ destructor_action = 0;
+
+ class_name = Getattr(n, "sym:name");
+ if (!addSymbol(class_name, n))
+ return SWIG_ERROR;
+
+ real_classname = Getattr(n, "name");
+ mangled_classname = Swig_name_mangle(real_classname);
+
+ // not sure exactly how this workswhat this works,
+ // but tcl has a static hashtable of all classes emitted and then only emits code for them once.
+ // this fixes issues in test suites: template_default2 & template_specialization
+
+ // * if i understand correctly, this is a bug.
+ // * consider effect on template_specialization_defarg
+
+ static Hash *emitted = NewHash();
+ if (Getattr(emitted, mangled_classname))
+ return SWIG_NOWRAP;
+ Setattr(emitted, mangled_classname, "1");
+
+ s_attr_tab = NewString("");
+ Printf(s_attr_tab, "static swig_lua_attribute swig_");
+ Printv(s_attr_tab, mangled_classname, "_attributes[] = {\n", NIL);
+
+ s_methods_tab = NewString("");
+ Printf(s_methods_tab, "static swig_lua_method swig_");
+ Printv(s_methods_tab, mangled_classname, "_methods[] = {\n", NIL);
+
+ // Generate normal wrappers
+ Language::classHandler(n);
+
+ SwigType *t = Copy(Getattr(n, "name"));
+ SwigType_add_pointer(t);
+
+ // Catch all: eg. a class with only static functions and/or variables will not have 'remembered'
+ String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname);
+ SwigType_remember_clientdata(t, wrap_class);
+
+ String *rt = Copy(Getattr(n, "classtype"));
+ SwigType_add_pointer(rt);
+
+ // Register the class structure with the type checker
+ // Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname);
+
+ // emit a function to be called to delete the object
+ 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, "\n", NIL);
+ } else {
+ if (CPlusPlus) {
+ Printv(f_wrappers, " delete (", SwigType_str(rt, 0), ") obj;\n", NIL);
+ } else {
+ Printv(f_wrappers, " free((char *) obj);\n", NIL);
+ }
+ }
+ Printf(f_wrappers, "}\n");
+ }
+
+ Printf(s_methods_tab, " {0,0}\n};\n");
+ Printv(f_wrappers, s_methods_tab, NIL);
+
+ Printf(s_attr_tab, " {0,0,0}\n};\n");
+ Printv(f_wrappers, s_attr_tab, NIL);
+
+ Delete(s_methods_tab);
+ Delete(s_attr_tab);
+
+ // Handle inheritance
+ // note: with the idea of class hireachied spread over multiple modules
+ // cf test-suite: imports.i
+ // it is not possible to just add the pointers to the base classes to the code
+ // (as sometimes these classes are not present)
+ // therefore we instead hold the name of the base class and a null pointer
+ // at runtime: we can query the swig type manager & see if the class exists
+ // if so, we can get the pointer to the base class & replace the null pointer
+ // if the type does not exist, then we cannot...
+ String *base_class = NewString("");
+ String *base_class_names = NewString("");
+
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator b;
+ int index = 0;
+ b = First(baselist);
+ while (b.item) {
+ String *bname = Getattr(b.item, "name");
+ if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
+ b = Next(b);
+ continue;
+ }
+ // old code: (used the pointer to the base class)
+ //String *bmangle = Swig_name_mangle(bname);
+ //Printf(base_class, "&_wrap_class_%s", bmangle);
+ //Putc(',', base_class);
+ //Delete(bmangle);
+ // new code: stores a null pointer & the name
+ Printf(base_class, "0,");
+ Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
+
+ b = Next(b);
+ index++;
+ }
+ }
+
+ Printv(f_wrappers, "static swig_lua_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL);
+ Delete(base_class);
+ Printv(f_wrappers, "static const char *swig_", mangled_classname, "_base_names[] = {", base_class_names, "0};\n", NIL);
+ Delete(base_class_names);
+
+ Printv(f_wrappers, "static swig_lua_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(constructor_name)));
+ Delete(constructor_name);
+ constructor_name = 0;
+ } else {
+ Printf(f_wrappers, "0");
+ }
+
+ if (have_destructor) {
+ Printv(f_wrappers, ", swig_delete_", class_name, NIL);
+ } else {
+ Printf(f_wrappers, ",0");
+ }
+ Printf(f_wrappers, ", swig_%s_methods, swig_%s_attributes, swig_%s_bases, swig_%s_base_names };\n\n", mangled_classname, mangled_classname, mangled_classname, mangled_classname);
+
+ // Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases };\n\n", NIL);
+ // Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_classname, "},\n", NIL);
+ Delete(t);
+ Delete(mangled_classname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberfunctionHandler(Node *n) {
+ String *name = Getattr(n, "name");
+ String *iname = GetChar(n, "sym:name");
+ //Printf(stdout,"memberfunctionHandler %s %s\n",name,iname);
+
+ // Special case unary minus: LUA passes two parameters for the
+ // wrapper function while we want only one. Tell our
+ // functionWrapper to ignore a parameter.
+
+ if (Cmp(Getattr(n, "sym:name"), "__unm") == 0) {
+ //Printf(stdout, "unary minus: ignore one argument\n");
+ SetInt(n, "lua:ignore_args", 1);
+ }
+
+ String *realname, *rname;
+
+ current = MEMBER_FUNC;
+ Language::memberfunctionHandler(n);
+ current = NO_CPP;
+
+ realname = iname ? iname : name;
+ rname = Swig_name_wrapper(Swig_name_member(class_name, realname));
+ if (!Getattr(n, "sym:nextSibling")) {
+ Printv(s_methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL);
+ }
+ Delete(rname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int membervariableHandler(Node *n) {
+ // REPORT("membervariableHandler",n);
+ String *symname = Getattr(n, "sym:name");
+ String *gname, *sname;
+
+ current = MEMBER_VAR;
+ Language::membervariableHandler(n);
+ current = NO_CPP;
+ gname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname)));
+ if (!GetFlag(n, "feature:immutable")) {
+ sname = Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name, symname)));
+ } else {
+ //sname = NewString("0");
+ sname = NewString("SWIG_Lua_set_immutable"); // error message
+ }
+ Printf(s_attr_tab,"%s{ \"%s\", %s, %s},\n",tab4,symname,gname,sname);
+ Delete(gname);
+ Delete(sname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorHandler()
+ *
+ * Method for adding C++ member constructor
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+ // REPORT("constructorHandler", n);
+ current = CONSTRUCTOR;
+ Language::constructorHandler(n);
+ current = NO_CPP;
+ constructor_name = NewString(Getattr(n, "sym:name"));
+ have_constructor = 1;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorHandler(Node *n) {
+ REPORT("destructorHandler", n);
+ current = DESTRUCTOR;
+ Language::destructorHandler(n);
+ current = NO_CPP;
+ have_destructor = 1;
+ destructor_action = Getattr(n, "wrap:action");
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ *
+ * Wrap a static C++ function
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ current = STATIC_FUNC;
+ return Language::staticmemberfunctionHandler(n);
+ }
+
+ /* ------------------------------------------------------------
+ * memberconstantHandler()
+ *
+ * Create a C++ constant
+ * ------------------------------------------------------------ */
+
+ virtual int memberconstantHandler(Node *n) {
+ // REPORT("memberconstantHandler",n);
+ return Language::memberconstantHandler(n);
+ }
+
+ /* ---------------------------------------------------------------------
+ * staticmembervariableHandler()
+ * --------------------------------------------------------------------- */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ // REPORT("staticmembervariableHandler",n);
+ current = STATIC_VAR;
+ return Language::staticmembervariableHandler(n);
+ }
+
+ /* ---------------------------------------------------------------------
+ * external runtime generation
+ * --------------------------------------------------------------------- */
+
+ /* This is to support the usage
+ SWIG -external-runtime <filename>
+ The code consists of two functions:
+ String *runtimeCode() // returns a large string with all the runtimes in
+ String *defaultExternalRuntimeFilename() // returns the default filename
+ I am writing a generic solution, even though SWIG-Lua only has one file right now...
+ */
+ String *runtimeCode() {
+ String *s = NewString("");
+ const char *filenames[] = { "luarun.swg", 0
+ }
+ ; // must be 0 termiated
+ String *sfile;
+ for (int i = 0; filenames[i] != 0; i++) {
+ sfile = Swig_include_sys(filenames[i]);
+ if (!sfile) {
+ Printf(stderr, "*** Unable to open '%s'\n", filenames[i]);
+ } else {
+ Append(s, sfile);
+ Delete(sfile);
+ }
+ }
+
+ return s;
+ }
+
+ String *defaultExternalRuntimeFilename() {
+ return NewString("swigluarun.h");
+ }
+
+ /* ---------------------------------------------------------------------
+ * helpers
+ * --------------------------------------------------------------------- */
+
+ /* This is to convert the string of Lua code into a proper string, which can then be
+ emitted into the C/C++ code.
+ Basically is is a lot of search & replacing of odd sequences
+ */
+ void EscapeCode(String* str)
+ {
+ //Printf(f_runtime,"/* original luacode:[[[\n%s\n]]]\n*/\n",str);
+ Chop(str); // trim
+ Replace(str,"\\","\\\\",DOH_REPLACE_ANY); // \ to \\ (this must be done first)
+ Replace(str,"\"","\\\"",DOH_REPLACE_ANY); // " to \"
+ Replace(str,"\n","\\n\"\n \"",DOH_REPLACE_ANY); // \n to \n"\n" (ie quoting every line)
+ //Printf(f_runtime,"/* hacked luacode:[[[\n%s\n]]]\n*/\n",str);
+ }
+};
+
+/* NEW LANGUAGE NOTE:***********************************************
+ in order to add you language into swig, you need to make the following changes:
+ - write this file (obviously)
+ - add into the makefile (not 100% clear on how to do this)
+ - edit swigmain.cxx to add your module
+
+near the top of swigmain.cxx, look for this code & add you own codes
+======= begin change ==========
+extern "C" {
+ Language *swig_tcl(void);
+ Language *swig_python(void);
+ //etc,etc,etc...
+ Language *swig_lua(void); // this is my code
+}
+
+ //etc,etc,etc...
+
+swig_module modules[] = {
+ {"-guile", swig_guile, "Guile"},
+ {"-java", swig_java, "Java"},
+ //etc,etc,etc...
+ {"-lua", swig_lua, "Lua"}, // this is my code
+ {NULL, NULL, NULL} // this must come at the end of the list
+};
+======= end change ==========
+
+This is all that is needed
+
+NEW LANGUAGE NOTE:END ************************************************/
+
+/* -----------------------------------------------------------------------------
+ * swig_lua() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+extern "C" Language *swig_lua(void) {
+ return new LUA();
+}
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
new file mode 100644
index 0000000..477d83b
--- /dev/null
+++ b/Source/Modules/main.cxx
@@ -0,0 +1,1251 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * main.cxx
+ *
+ * Main entry point to the SWIG core.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_main_cxx[] = "$Id: main.cxx 11135 2009-02-20 20:55:16Z wsfulton $";
+
+#include "swigconfig.h"
+
+#if defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#include "swigmod.h"
+
+#include "swigwarn.h"
+#include "cparse.h"
+#include <ctype.h>
+#include <limits.h> // for INT_MAX
+
+// Global variables
+
+Language *lang; // Language method
+int CPlusPlus = 0;
+int Extend = 0; // Extend flag
+int ForceExtern = 0; // Force extern mode
+int GenerateDefault = 1; // Generate default constructors
+int Verbose = 0;
+int AddExtern = 0;
+int NoExcept = 0;
+int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime
+
+/* Suppress warning messages for private inheritance, preprocessor evaluation etc...
+ WARN_PP_EVALUATION 202
+ WARN_PARSE_PRIVATE_INHERIT 309
+ WARN_TYPE_ABSTRACT 403
+ WARN_LANG_OVERLOAD_CONST 512
+ WARN_PARSE_BUILTIN_NAME 321
+ WARN_PARSE_REDUNDANT 322
+ */
+#define EXTRA_WARNINGS "202,309,403,512,321,322"
+
+extern "C" {
+ extern String *ModuleName;
+}
+
+/* usage string split into multiple parts otherwise string is too big for some compilers */
+/* naming conventions for commandline options - no underscores, no capital letters, join words together
+ * except when using a common prefix, then use '-' to separate, eg the debug-xxx options */
+static const char *usage1 = (const char *) "\
+\nGeneral Options\n\
+ -addextern - Add extra extern declarations\n\
+ -c++ - Enable C++ processing\n\
+ -co <file> - Check <file> out of the SWIG library\n\
+ -copyctor - Automatically generate copy constructors wherever possible\n\
+ -cpperraswarn - Treat the preprocessor #error statement as #warning (default)\n\
+ -copyright - Display copyright notices\n\
+ -debug-classes - Display information about the classes found in the interface\n\
+ -debug-module <n>- Display module parse tree at stages 1-4, <n> is a csv list of stages\n\
+ -debug-tags - Display information about the tags found in the interface\n\
+ -debug-template - Display information for debugging templates\n\
+ -debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages\n\
+ -debug-typedef - Display information about the types and typedefs in the interface\n\
+ -debug-typemap - Display information for debugging typemaps\n\
+ -directors - Turn on director mode for all the classes, mainly for testing\n\
+ -dirprot - Turn on wrapping of protected members for director classes (default)\n\
+ -D<symbol> - Define a symbol <symbol> (for conditional compilation)\n\
+ -E - Preprocess only, does not generate wrapper code\n\
+ -external-runtime [file] - Export the SWIG runtime stack\n\
+ -fakeversion <v>- Make SWIG fake the program version number to <v>\n\
+ -fcompact - Compile in compact mode\n\
+ -features <list>- Set global features, where <list> is a comma separated list of\n\
+ features, eg -features directors,autodoc=1\n\
+ If no explicit value is given to the feature, a default of 1 is used\n\
+";
+
+static const char *usage2 = (const char *) "\
+ -fastdispatch - Enable fast dispatch mode to produce faster overload dispatcher code\n\
+ -Fmicrosoft - Display error/warning messages in Microsoft format\n\
+ -Fstandard - Display error/warning messages in commonly used format\n\
+ -fvirtual - Compile in virtual elimination mode\n\
+ -help - This output\n\
+ -I- - Don't search the current directory\n\
+ -I<dir> - Look for SWIG files in directory <dir>\n\
+ -ignoremissing - Ignore missing include files\n\
+ -importall - Follow all #include statements as imports\n\
+ -includeall - Follow all #include statements\n\
+ -l<ifile> - Include SWIG library file <ifile>\n\
+ -macroerrors - Report errors inside macros\n\
+ -makedefault - Create default constructors/destructors (the default)\n\
+ -M - List all dependencies\n\
+ -MD - Is equivalent to `-M -MF <file>', except `-E' is not implied\n\
+ -MF <file> - Generate dependencies into <file> and continue generating wrappers\n\
+ -MM - List dependencies, but omit files in SWIG library\n\
+ -MMD - Like `-MD', but omit files in SWIG library\n\
+ -module <name> - Set module name to <name>\n\
+ -MT <target> - Set the target of the rule emitted by dependency generation\n\
+ -nocontract - Turn off contract checking\n\
+ -nocpperraswarn - Do not treat the preprocessor #error statement as #warning\n\
+ -nodefault - Do not generate default constructors nor default destructors\n\
+ -nodefaultctor - Do not generate implicit default constructors\n\
+ -nodefaultdtor - Do not generate implicit default destructors\n\
+ -nodirprot - Do not wrap director protected members\n\
+ -noexcept - Do not wrap exception specifiers\n\
+ -nofastdispatch - Disable fast dispatch mode (default)\n\
+ -nopreprocess - Skip the preprocessor step\n\
+";
+
+static const char *usage3 = (const char *) "\
+ -notemplatereduce - Disable reduction of the typedefs in templates\n\
+ -O - Enable the optimization options: \n\
+ -fastdispatch -fvirtual \n\
+ -o <outfile> - Set name of the output file to <outfile>\n\
+ -oh <headfile> - Set name of the output header file to <headfile>\n\
+ -outcurrentdir - Set default output dir to current dir instead of input file's path\n\
+ -outdir <dir> - Set language specific files output directory to <dir>\n\
+ -small - Compile in virtual elimination & compact mode\n\
+ -swiglib - Report location of SWIG library and exit\n\
+ -templatereduce - Reduce all the typedefs in templates\n\
+ -v - Run in verbose mode\n\
+ -version - Display SWIG version number\n\
+ -Wall - Remove all warning suppression, also implies -Wextra\n\
+ -Wallkw - Enable keyword warnings for all the supported languages\n\
+ -Werror - Treat warnings as errors\n\
+ -Wextra - Adds the following additional warnings: " EXTRA_WARNINGS "\n\
+ -w<list> - Suppress/add warning messages, eg -w401,+321 - see Warnings.html\n\
+ -xmlout <file> - Write XML version of the parse tree to <file> after normal processing\n\
+\n\
+Options can also be defined using the SWIG_FEATURES environment variable, for example:\n\
+\n\
+ $ SWIG_FEATURES=\"-Wall\"\n\
+ $ export SWIG_FEATURES\n\
+ $ swig -python interface.i\n\
+\n\
+is equivalent to: \n\
+\n\
+ $ swig -Wall -python interface.i \n\
+\n\
+\n";
+
+// Local variables
+static String *LangSubDir = 0; // Target language library subdirectory
+static char *SwigLib = 0; // Library directory
+static String *SwigLibWin = 0; // Extra Library directory for Windows
+static int freeze = 0;
+static String *lang_config = 0;
+static char *hpp_extension = (char *) "h";
+static char *cpp_extension = (char *) "cxx";
+static char *depends_extension = (char *) "d";
+static String *outdir = 0;
+static String *xmlout = 0;
+static int outcurrentdir = 0;
+static int help = 0;
+static int checkout = 0;
+static int cpp_only = 0;
+static int no_cpp = 0;
+static char *outfile_name = 0;
+static char *outfile_name_h = 0;
+static int tm_debug = 0;
+static int dump_tags = 0;
+static int dump_module = 0;
+static int dump_top = 0;
+static int dump_xml = 0;
+static int browse = 0;
+static int dump_typedef = 0;
+static int dump_classes = 0;
+static int werror = 0;
+static int depend = 0;
+static int depend_only = 0;
+static int memory_debug = 0;
+static int allkw = 0;
+static DOH *libfiles = 0;
+static DOH *cpps = 0;
+static String *dependencies_file = 0;
+static File *f_dependencies_file = 0;
+static String *dependencies_target = 0;
+static int external_runtime = 0;
+static String *external_runtime_name = 0;
+enum { STAGE1=1, STAGE2=2, STAGE3=4, STAGE4=8, STAGEOVERFLOW=16 };
+static List *all_output_files = 0;
+
+// -----------------------------------------------------------------------------
+// check_suffix()
+//
+// Checks the suffix of a file to see if we should emit extern declarations.
+// -----------------------------------------------------------------------------
+
+static int check_suffix(String *filename) {
+ const char *name = Char(filename);
+ const char *c;
+ if (!name)
+ return 0;
+ c = Swig_file_suffix(name);
+ if ((strcmp(c, ".c") == 0) ||
+ (strcmp(c, ".C") == 0) || (strcmp(c, ".cc") == 0) || (strcmp(c, ".cxx") == 0) || (strcmp(c, ".c++") == 0) || (strcmp(c, ".cpp") == 0)) {
+ return 1;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+// install_opts(int argc, char *argv[])
+// Install all command line options as preprocessor symbols
+// -----------------------------------------------------------------------------
+
+static void install_opts(int argc, char *argv[]) {
+ int i;
+ int noopt = 0;
+ char *c;
+ for (i = 1; i < (argc - 1); i++) {
+ if (argv[i]) {
+ if ((*argv[i] == '-') && (!isupper(*(argv[i] + 1)))) {
+ String *opt = NewStringf("SWIGOPT%(upper)s", argv[i]);
+ Replaceall(opt, "-", "_");
+ c = Char(opt);
+ noopt = 0;
+ while (*c) {
+ if (!(isalnum(*c) || (*c == '_'))) {
+ noopt = 1;
+ break;
+ }
+ c++;
+ }
+ if (((i + 1) < (argc - 1)) && (argv[i + 1]) && (*argv[i + 1] != '-')) {
+ Printf(opt, " %s", argv[i + 1]);
+ i++;
+ } else {
+ Printf(opt, " 1");
+ }
+ if (!noopt) {
+ /* Printf(stdout,"%s\n", opt); */
+ Preprocessor_define(opt, 0);
+ }
+ Delete(opt);
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// decode_numbers_list(String *numlist)
+// Decode comma separated list into a binary number of the inputs or'd together
+// eg list="1,4" will return (2^0 || 2^3) = 0x1001
+// -----------------------------------------------------------------------------
+
+static unsigned int decode_numbers_list(String *numlist) {
+ unsigned int decoded_number = 0;
+ if (numlist) {
+ List *numbers = Split(numlist, ',', INT_MAX);
+ if (numbers && Len(numbers) > 0) {
+ for (Iterator it = First(numbers); it.item; it = Next(it)) {
+ String *numstring = it.item;
+ // TODO: check that it is a number
+ int number = atoi(Char(numstring));
+ if (number > 0 && number <= 16) {
+ decoded_number |= (1 << (number-1));
+ }
+ }
+ }
+ }
+ return decoded_number;
+}
+
+// -----------------------------------------------------------------------------
+// Sets the output directory for language specific (proxy) files if not set and
+// adds trailing file separator if necessary.
+// -----------------------------------------------------------------------------
+
+static void set_outdir(const String *c_wrapper_file_dir) {
+
+ // Add file delimiter if not present in output directory name
+ if (outdir && Len(outdir) != 0) {
+ const char *outd = Char(outdir);
+ if (strcmp(outd + strlen(outd) - strlen(SWIG_FILE_DELIMITER), SWIG_FILE_DELIMITER) != 0)
+ Printv(outdir, SWIG_FILE_DELIMITER, NIL);
+ }
+ // Use the C wrapper file's directory if the output directory has not been set by user
+ if (!outdir)
+ outdir = NewString(c_wrapper_file_dir);
+}
+
+/* This function sets the name of the configuration file */
+void SWIG_config_file(const_String_or_char_ptr filename) {
+ lang_config = NewString(filename);
+}
+
+/* Sets the target language subdirectory name */
+void SWIG_library_directory(const char *subdirectory) {
+ LangSubDir = NewString(subdirectory);
+}
+
+// Returns the directory for generating language specific files (non C/C++ files)
+const String *SWIG_output_directory() {
+ assert(outdir);
+ return outdir;
+}
+
+void SWIG_config_cppext(const char *ext) {
+ cpp_extension = (char *) ext;
+}
+
+List *SWIG_output_files() {
+ assert(all_output_files);
+ return all_output_files;
+}
+
+void SWIG_setfeature(const char *cfeature, const char *cvalue) {
+ Hash *features_hash = Swig_cparse_features();
+ String *name = NewString("");
+ String *fname = NewString(cfeature);
+ String *fvalue = NewString(cvalue);
+ Swig_feature_set(features_hash, name, 0, fname, fvalue, 0);
+ Delete(name);
+ Delete(fname);
+ Delete(fvalue);
+}
+
+
+void SWIG_setfeatures(const char *c) {
+ char feature[64];
+ char *fb = feature;
+ char *fe = fb + 63;
+ Hash *features_hash = Swig_cparse_features();
+ String *name = NewString("");
+ /* Printf(stderr,"all features %s\n", c); */
+ while (*c) {
+ char *f = fb;
+ String *fname = NewString("feature:");
+ String *fvalue = NewString("");
+ while ((f != fe) && *c != '=' && *c != ',' && *c) {
+ *(f++) = *(c++);
+ }
+ *f = 0;
+ Printf(fname, "%s", feature);
+ if (*c && *(c++) == '=') {
+ char value[64];
+ char *v = value;
+ char *ve = v + 63;
+ while ((v != ve) && *c != ',' && *c && !isspace(*c)) {
+ *(v++) = *(c++);
+ }
+ *v = 0;
+ Printf(fvalue, "%s", value);
+ } else {
+ Printf(fvalue, "1");
+ }
+ /* Printf(stderr,"%s %s\n", fname, fvalue); */
+ Swig_feature_set(features_hash, name, 0, fname, fvalue, 0);
+ Delete(fname);
+ Delete(fvalue);
+ }
+ Delete(name);
+}
+
+/* This function handles the -external-runtime command option */
+static void SWIG_dump_runtime() {
+ String *outfile;
+ File *runtime;
+ String *s;
+
+ outfile = external_runtime_name;
+ if (!outfile) {
+ outfile = lang->defaultExternalRuntimeFilename();
+ if (!outfile) {
+ Printf(stderr, "*** Please provide a filename for the external runtime\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+
+ runtime = NewFile(outfile, "w", SWIG_output_files());
+ if (!runtime) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Swig_banner(runtime);
+ Printf(runtime, "\n");
+
+ s = Swig_include_sys("swiglabels.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'swiglabels.swg'\n");
+ Close(runtime);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Printf(runtime, "%s", s);
+ Delete(s);
+
+ s = Swig_include_sys("swigerrors.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'swigerrors.swg'\n");
+ Close(runtime);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Printf(runtime, "%s", s);
+ Delete(s);
+
+ s = Swig_include_sys("swigerrors.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'swigerrors.swg'\n");
+ Close(runtime);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Printf(runtime, "%s", s);
+ s = Swig_include_sys("swigrun.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'swigrun.swg'\n");
+ Close(runtime);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Printf(runtime, "%s", s);
+ Delete(s);
+
+ s = lang->runtimeCode();
+ Printf(runtime, "%s", s);
+ Delete(s);
+
+ s = Swig_include_sys("runtime.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'runtime.swg'\n");
+ Close(runtime);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Printf(runtime, "%s", s);
+ Delete(s);
+
+ Close(runtime);
+ Delete(runtime);
+ SWIG_exit(EXIT_SUCCESS);
+}
+
+void SWIG_getoptions(int argc, char *argv[]) {
+ int i;
+ // Get options
+ for (i = 1; i < argc; i++) {
+ if (argv[i] && !Swig_check_marked(i)) {
+ if (strncmp(argv[i], "-I-", 3) == 0) {
+ // Don't push/pop directories
+ Swig_set_push_dir(0);
+ Swig_mark_arg(i);
+ } else if (strncmp(argv[i], "-I", 2) == 0) {
+ // Add a new directory search path
+ char *a = Swig_copy_string(argv[i] + 2);
+ Swig_add_directory((DOH *) a);
+ free(a);
+ Swig_mark_arg(i);
+ } else if (strncmp(argv[i], "-D", 2) == 0) {
+ String *d = NewString(argv[i] + 2);
+ Replace(d, (char *) "=", (char *) " ", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
+ Preprocessor_define((DOH *) d, 0);
+ Delete(d);
+ // 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], "-nopreprocess") == 0) {
+ no_cpp = 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 __cplusplus", 0);
+ Swig_cparse_cplusplus(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-fcompact") == 0) {
+ Wrapper_compact_print_mode_set(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-fvirtual") == 0) {
+ Wrapper_virtual_elimination_mode_set(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-fastdispatch") == 0) {
+ Wrapper_fast_dispatch_mode_set(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nofastdispatch") == 0) {
+ Wrapper_fast_dispatch_mode_set(0);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-naturalvar") == 0) {
+ Wrapper_naturalvar_mode_set(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nonaturalvar") == 0) {
+ Wrapper_naturalvar_mode_set(0);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-directors") == 0) {
+ SWIG_setfeature("feature:director", "1");
+ Wrapper_director_mode_set(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-dirprot") == 0) {
+ Wrapper_director_protected_mode_set(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nodirprot") == 0) {
+ Wrapper_director_protected_mode_set(0);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-small") == 0) {
+ Wrapper_compact_print_mode_set(1);
+ Wrapper_virtual_elimination_mode_set(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-runtime") == 0) { // Used to also accept -c. removed in swig-1.3.36
+ Swig_mark_arg(i);
+ Swig_warning(WARN_DEPRECATED_OPTC, "SWIG", 1, "-runtime, -noruntime command line options are deprecated.\n");
+ SwigRuntime = 1;
+ } else if (strcmp(argv[i], "-noruntime") == 0) {
+ Swig_mark_arg(i);
+ Swig_warning(WARN_DEPRECATED_OPTC, "SWIG", 1, "-runtime, -noruntime command line options are deprecated.\n");
+ SwigRuntime = 2;
+ } else if (strcmp(argv[i], "-external-runtime") == 0) {
+ external_runtime = 1;
+ Swig_mark_arg(i);
+ if (argv[i + 1]) {
+ external_runtime_name = NewString(argv[i + 1]);
+ Swig_mark_arg(i + 1);
+ 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_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use -nodefaultctor, -nodefaultdtor instead.\n");
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-nodefaultctor") == 0)) {
+ SWIG_setfeature("feature:nodefaultctor", "1");
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-nodefaultdtor") == 0)) {
+ SWIG_setfeature("feature:nodefaultdtor", "1");
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-copyctor") == 0)) {
+ SWIG_setfeature("feature:copyctor", "1");
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noexcept") == 0) {
+ NoExcept = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noextern") == 0) {
+ Swig_warning(WARN_DEPRECATED_NOEXTERN, "SWIG", 1, "-noextern command line option is deprecated; extern is no longer generated by default.\n");
+ AddExtern = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-addextern") == 0) {
+ AddExtern = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-debug-template") == 0) || (strcmp(argv[i], "-debug_template") == 0) || (strcmp(argv[i], "-show_templates") == 0)) {
+ Swig_cparse_debug_templates(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-templatereduce") == 0) {
+ SWIG_cparse_template_reduce(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-notemplatereduce") == 0) {
+ SWIG_cparse_template_reduce(0);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-macroerrors") == 0) {
+ Swig_cparse_follow_locators(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-swiglib") == 0) {
+ if (SwigLibWin)
+ printf("%s\n", Char(SwigLibWin));
+ printf("%s\n", SwigLib);
+ 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]);
+ if (!outfile_name_h || !dependencies_file) {
+ char *ext = strrchr(outfile_name, '.');
+ String *basename = ext ? NewStringWithSize(outfile_name, ext - outfile_name) : NewString(outfile_name);
+ if (!dependencies_file) {
+ dependencies_file = NewStringf("%s.%s", basename, depends_extension);
+ }
+ if (!outfile_name_h) {
+ Printf(basename, ".%s", hpp_extension);
+ outfile_name_h = Swig_copy_string(Char(basename));
+ }
+ Delete(basename);
+ }
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-oh") == 0) {
+ Swig_mark_arg(i);
+ if (argv[i + 1]) {
+ outfile_name_h = Swig_copy_string(argv[i + 1]);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-fakeversion") == 0) {
+ Swig_mark_arg(i);
+ if (argv[i + 1]) {
+ Swig_set_fakeversion(argv[i + 1]);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-version") == 0) {
+ fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version());
+ fprintf(stdout, "\nCompiled with %s [%s]\n", SWIG_CXX, SWIG_PLATFORM);
+ fprintf(stdout, "Please see %s for reporting bugs and further information\n", PACKAGE_BUGREPORT);
+ SWIG_exit(EXIT_SUCCESS);
+ } else if (strcmp(argv[i], "-copyright") == 0) {
+ fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version());
+ fprintf(stdout, "Copyright (c) 1995-1998\n");
+ fprintf(stdout, "University of Utah and the Regents of the University of California\n");
+ fprintf(stdout, "Copyright (c) 1998-2005\n");
+ fprintf(stdout, "University of Chicago\n");
+ fprintf(stdout, "Copyright (c) 2005-2006\n");
+ fprintf(stdout, "Arizona Board of Regents (University of Arizona)\n");
+ 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], "-features") == 0) {
+ Swig_mark_arg(i);
+ if (argv[i + 1]) {
+ SWIG_setfeatures(argv[i + 1]);
+ Swig_mark_arg(i + 1);
+ } else {
+ Swig_arg_error();
+ }
+ } 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], "-cpperraswarn") == 0) {
+ Preprocessor_error_as_warning(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nocpperraswarn") == 0) {
+ Preprocessor_error_as_warning(0);
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-debug-typemap") == 0) || (strcmp(argv[i], "-debug_typemap") == 0) || (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;
+ depend_only = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-MM") == 0) {
+ depend = 2;
+ depend_only = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-MF") == 0) {
+ Swig_mark_arg(i);
+ if (argv[i + 1]) {
+ dependencies_file = NewString(argv[i + 1]);
+ Swig_mark_arg(i + 1);
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-MD") == 0) {
+ depend = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-MMD") == 0) {
+ depend = 2;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-MT") == 0) {
+ Swig_mark_arg(i);
+ if (argv[i + 1]) {
+ if (!dependencies_target)
+ dependencies_target = NewString(argv[i + 1]);
+ else
+ Printf(dependencies_target, " %s", argv[i + 1]);
+ Swig_mark_arg(i + 1);
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-outdir") == 0) {
+ Swig_mark_arg(i);
+ if (argv[i + 1]) {
+ outdir = NewString(argv[i + 1]);
+ Swig_mark_arg(i + 1);
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-outcurrentdir") == 0) {
+ Swig_mark_arg(i);
+ outcurrentdir = 1;
+ } else if (strcmp(argv[i], "-Wall") == 0) {
+ Swig_mark_arg(i);
+ Swig_warnall();
+ } else if (strcmp(argv[i], "-Wallkw") == 0) {
+ allkw = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-Werror") == 0) {
+ werror = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-Wextra") == 0) {
+ Swig_mark_arg(i);
+ Swig_warnfilter(EXTRA_WARNINGS, 0);
+ } else if (strncmp(argv[i], "-w", 2) == 0) {
+ Swig_mark_arg(i);
+ Swig_warnfilter(argv[i] + 2, 1);
+ } else if ((strcmp(argv[i], "-debug-tags") == 0) || (strcmp(argv[i], "-dump_tags") == 0)) {
+ dump_tags = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-debug-top") == 0) {
+ Swig_mark_arg(i);
+ if (argv[i + 1]) {
+ String *dump_list = NewString(argv[i + 1]);
+ dump_top = decode_numbers_list(dump_list);
+ if (dump_top < STAGE1 || dump_top >= STAGEOVERFLOW)
+ Swig_arg_error();
+ else
+ Swig_mark_arg(i + 1);
+ Delete(dump_list);
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-debug-module") == 0) {
+ Swig_mark_arg(i);
+ if (argv[i + 1]) {
+ String *dump_list = NewString(argv[i + 1]);
+ dump_module = decode_numbers_list(dump_list);
+ if (dump_module < STAGE1 || dump_module >= STAGEOVERFLOW)
+ Swig_arg_error();
+ else
+ Swig_mark_arg(i + 1);
+ Delete(dump_list);
+ } else {
+ Swig_arg_error();
+ }
+ } else if ((strcmp(argv[i], "-dump_tree") == 0) || (strcmp(argv[i], "-dump_top") == 0)) {
+ dump_top |= STAGE4;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-dump_module") == 0) {
+ dump_module |= STAGE4;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-dump_parse_module") == 0) {
+ dump_module |= STAGE1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-dump_parse_top") == 0) {
+ dump_top |= STAGE1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-dump_xml") == 0) {
+ dump_xml = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-xmlout") == 0) {
+ dump_xml = 1;
+ Swig_mark_arg(i);
+ if (argv[i + 1]) {
+ xmlout = NewString(argv[i + 1]);
+ Swig_mark_arg(i + 1);
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-nocontract") == 0) {
+ Swig_mark_arg(i);
+ Swig_contract_mode_set(0);
+ } else if (strcmp(argv[i], "-browse") == 0) {
+ browse = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-debug-typedef") == 0) || (strcmp(argv[i], "-dump_typedef") == 0)) {
+ dump_typedef = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-debug-classes") == 0) || (strcmp(argv[i], "-dump_classes") == 0)) {
+ dump_classes = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-debug-memory") == 0) || (strcmp(argv[i], "-dump_memory") == 0)) {
+ memory_debug = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-Fstandard") == 0) {
+ Swig_error_msg_format(EMF_STANDARD);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-Fmicrosoft") == 0) {
+ Swig_error_msg_format(EMF_MICROSOFT);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-O") == 0) {
+ Wrapper_virtual_elimination_mode_set(1);
+ Wrapper_fast_dispatch_mode_set(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-help") == 0) {
+ fputs(usage1, stdout);
+ fputs(usage2, stdout);
+ fputs(usage3, stdout);
+ Swig_mark_arg(i);
+ help = 1;
+ }
+ }
+ }
+}
+
+
+
+
+
+int SWIG_main(int argc, char *argv[], Language *l) {
+ char *c;
+ extern void Swig_print_xml(Node *obj, String *filename);
+
+ /* Initialize the SWIG core */
+ Swig_init();
+
+ // Default warning suppression
+ Swig_warnfilter(EXTRA_WARNINGS, 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 in format 0xAABBCC from package version expected to be in format A.B.C
+ String *package_version = NewString(PACKAGE_VERSION); /* Note that the fakeversion has not been set at this point */
+ char *token = strtok(Char(package_version), ".");
+ String *vers = NewString("SWIG_VERSION 0x");
+ int count = 0;
+ while (token) {
+ int len = strlen(token);
+ assert(len == 1 || len == 2);
+ Printf(vers, "%s%s", (len == 1) ? "0" : "", token);
+ token = strtok(NULL, ".");
+ count++;
+ }
+ Delete(package_version);
+ assert(count == 3); // Check version format is correct
+
+ /* Turn on contracts */
+
+ Swig_contract_mode_set(1);
+ Preprocessor_define(vers, 0);
+
+ /* Turn off directors mode */
+ Wrapper_director_mode_set(0);
+ Wrapper_director_protected_mode_set(1);
+
+ // Create Library search directories
+
+ // 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)) {
+ *(p + 1) = '\0';
+ SwigLibWin = NewStringf("%sLib", buf); // Native windows installation path
+ }
+ SwigLib = Swig_copy_string(SWIG_LIB_WIN_UNIX); // Unix installation path using a drive letter (for msys/mingw)
+#else
+ SwigLib = Swig_copy_string(SWIG_LIB);
+#endif
+ } else {
+ SwigLib = Swig_copy_string(c);
+ }
+
+ libfiles = NewList();
+ all_output_files = NewList();
+
+ /* Check for SWIG_FEATURES environment variable */
+
+ SWIG_getoptions(argc, argv);
+
+ // Define the __cplusplus symbol
+ if (CPlusPlus)
+ Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0);
+
+ // Parse language dependent options
+ lang->main(argc, argv);
+
+ if (help) {
+ Printf(stdout, "\nNote: 'swig -<lang> -help' displays options for a specific target language.\n\n");
+ SWIG_exit(EXIT_SUCCESS); // Exit if we're in help mode
+ }
+ // Check all of the options to make sure we're cool.
+ // Don't check for an input file if -external-runtime is passed
+ Swig_check_options(external_runtime ? 0 : 1);
+
+ install_opts(argc, argv);
+
+ // Add language dependent directory to the search path
+ {
+ String *rl = NewString("");
+ Printf(rl, ".%sswig_lib%s%s", SWIG_FILE_DELIMITER, SWIG_FILE_DELIMITER, LangSubDir);
+ Swig_add_directory(rl);
+ if (SwigLibWin) {
+ rl = NewString("");
+ Printf(rl, "%s%s%s", SwigLibWin, SWIG_FILE_DELIMITER, LangSubDir);
+ Swig_add_directory(rl);
+ }
+ rl = NewString("");
+ Printf(rl, "%s%s%s", SwigLib, SWIG_FILE_DELIMITER, LangSubDir);
+ Swig_add_directory(rl);
+ }
+
+ Swig_add_directory((String *) "." SWIG_FILE_DELIMITER "swig_lib");
+ if (SwigLibWin)
+ Swig_add_directory((String *) SwigLibWin);
+ Swig_add_directory((String *) SwigLib);
+
+ if (Verbose) {
+ printf("LangSubDir: %s\n", Char(LangSubDir));
+ printf("Search paths:\n");
+ List *sp = Swig_search_path();
+ Iterator s;
+ for (s = First(sp); s.item; s = Next(s)) {
+ Printf(stdout, " %s\n", s.item);
+ }
+ }
+ // handle the -external-runtime argument
+ if (external_runtime)
+ SWIG_dump_runtime();
+
+ // If we made it this far, looks good. go for it....
+
+ input_file = NewString(argv[argc - 1]);
+ Swig_filename_correct(input_file);
+
+ // If the user has requested to check out a file, handle that
+ if (checkout) {
+ DOH *s;
+ char *outfile = Char(input_file);
+ if (outfile_name)
+ outfile = outfile_name;
+
+ if (Verbose)
+ printf("Handling checkout...\n");
+
+ s = Swig_include(input_file);
+ if (!s) {
+ Printf(stderr, "Unable to locate '%s' in the SWIG library.\n", input_file);
+ } else {
+ FILE *f = Swig_open(outfile);
+ if (f) {
+ fclose(f);
+ Printf(stderr, "File '%s' already exists. Checkout aborted.\n", outfile);
+ } else {
+ File *f_outfile = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_outfile) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ } else {
+ if (Verbose)
+ Printf(stdout, "'%s' checked out from the SWIG library.\n", outfile);
+ Printv(f_outfile, s, NIL);
+ Close(f_outfile);
+ }
+ }
+ }
+ } else {
+ // Run the preprocessor
+ if (Verbose)
+ printf("Preprocessing...\n");
+
+ {
+ int i;
+ String *fs = NewString("");
+ FILE *df = Swig_open(input_file);
+ if (!df) {
+ df = Swig_include_open(input_file);
+ if (!df) {
+ char *cfile = Char(input_file);
+ if (cfile && cfile[0] == '-') {
+ Printf(stderr, "Unable to find option or file '%s', ", input_file);
+ Printf(stderr, "use 'swig -help' for more information.\n");
+ } else {
+ Printf(stderr, "Unable to find file '%s'.\n", input_file);
+ }
+ SWIG_exit(EXIT_FAILURE);
+ } else {
+ Swig_warning(WARN_DEPRECATED_INPUT_FILE, "SWIG", 1, "Use of the include path to find the input file is deprecated and will not work with ccache. Please include the path when specifying the input file.\n"); // so that behaviour is like c/c++ compilers
+ }
+ }
+ if (!no_cpp) {
+ fclose(df);
+ Printf(fs, "%%include <swig.swg>\n");
+ if (allkw) {
+ Printf(fs, "%%include <allkw.swg>\n");
+ }
+ if (lang_config) {
+ Printf(fs, "\n%%include <%s>\n", lang_config);
+ }
+ Printf(fs, "%%include(maininput=\"%s\") \"%s\"\n", Swig_filename_escape(input_file), 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);
+ Delete(fs);
+ } else {
+ cpps = Swig_read_file(df);
+ fclose(df);
+ }
+ if (Swig_error_count()) {
+ SWIG_exit(EXIT_FAILURE);
+ }
+ if (cpp_only) {
+ Printf(stdout, "%s", cpps);
+ SWIG_exit(EXIT_SUCCESS);
+ }
+ if (depend) {
+ if (!no_cpp) {
+ String *outfile;
+
+ char *basename = Swig_file_basename(outcurrentdir ? Swig_file_filename(input_file): Char(input_file));
+ if (!outfile_name) {
+ if (CPlusPlus || lang->cplus_runtime_mode()) {
+ outfile = NewStringf("%s_wrap.%s", basename, cpp_extension);
+ } else {
+ outfile = NewStringf("%s_wrap.c", basename);
+ }
+ } else {
+ outfile = NewString(outfile_name);
+ }
+ if (dependencies_file && Len(dependencies_file) != 0) {
+ f_dependencies_file = NewFile(dependencies_file, "w", SWIG_output_files());
+ if (!f_dependencies_file) {
+ FileErrorDisplay(dependencies_file);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ } else if (!depend_only) {
+ String *filename = NewStringf("%s_wrap.%s", basename, depends_extension);
+ f_dependencies_file = NewFile(filename, "w", SWIG_output_files());
+ if (!f_dependencies_file) {
+ FileErrorDisplay(filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ } else
+ f_dependencies_file = stdout;
+ if (dependencies_target) {
+ Printf(f_dependencies_file, "%s: ", dependencies_target);
+ } else {
+ Printf(f_dependencies_file, "%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(f_dependencies_file, "\\\n %s ", Getitem(files, i));
+ }
+ }
+ Printf(f_dependencies_file, "\n");
+ if (f_dependencies_file != stdout)
+ Close(f_dependencies_file);
+ if (depend_only)
+ SWIG_exit(EXIT_SUCCESS);
+ } else {
+ Printf(stderr, "Cannot generate dependencies with -nopreprocess\n");
+ // Actually we could but it would be inefficient when just generating dependencies, as it would be done after Swig_cparse
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+ Seek(cpps, 0, SEEK_SET);
+ }
+
+ /* Register a null file with the file handler */
+ Swig_register_filebyname("null", NewString(""));
+
+ // Pass control over to the specific language interpreter
+ if (Verbose) {
+ fprintf(stdout, "Starting language-specific parse...\n");
+ fflush(stdout);
+ }
+
+ Node *top = Swig_cparse(cpps);
+
+ if (dump_top & STAGE1) {
+ Printf(stdout, "debug-top stage 1\n");
+ Swig_print_tree(top);
+ }
+ if (dump_module & STAGE1) {
+ Printf(stdout, "debug-module stage 1\n");
+ Swig_print_tree(Getattr(top, "module"));
+ }
+
+ if (Verbose) {
+ Printf(stdout, "Processing types...\n");
+ }
+ Swig_process_types(top);
+
+ if (dump_top & STAGE2) {
+ Printf(stdout, "debug-top stage 2\n");
+ Swig_print_tree(top);
+ }
+ if (dump_module & STAGE2) {
+ Printf(stdout, "debug-module stage 2\n");
+ Swig_print_tree(Getattr(top, "module"));
+ }
+
+ if (Verbose) {
+ Printf(stdout, "C++ analysis...\n");
+ }
+ Swig_default_allocators(top);
+
+ if (dump_top & STAGE3) {
+ Printf(stdout, "debug-top stage 3\n");
+ Swig_print_tree(top);
+ }
+ if (dump_module & STAGE3) {
+ Printf(stdout, "debug-module stage 3\n");
+ Swig_print_tree(Getattr(top, "module"));
+ }
+
+ if (Verbose) {
+ Printf(stdout, "Generating wrappers...\n");
+ }
+
+ if (dump_classes) {
+ Hash *classes = Getattr(top, "classes");
+ if (classes) {
+ Printf(stdout, "Classes\n");
+ Printf(stdout, "------------\n");
+ Iterator ki;
+ for (ki = First(classes); ki.key; ki = Next(ki)) {
+ Printf(stdout, "%s\n", ki.key);
+ }
+ }
+ }
+
+ if (dump_typedef) {
+ SwigType_print_scope(0);
+ }
+
+ if (dump_tags) {
+ Swig_print_tags(top, 0);
+ }
+ 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 */
+ String *infile = scanner_get_main_input_file();
+ if (!infile) {
+ Printf(stderr, "Missing input file in preprocessed output.\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Setattr(top, "infile", infile); // Note: if nopreprocess then infile is the original input file, otherwise input_file
+ Setattr(top, "inputfile", input_file);
+
+ char *basename = Swig_file_basename(outcurrentdir ? Swig_file_filename(infile): Char(infile));
+ if (!outfile_name) {
+ if (CPlusPlus || lang->cplus_runtime_mode()) {
+ Setattr(top, "outfile", NewStringf("%s_wrap.%s", basename, cpp_extension));
+ } else {
+ Setattr(top, "outfile", NewStringf("%s_wrap.c", basename));
+ }
+ } else {
+ Setattr(top, "outfile", outfile_name);
+ }
+ if (!outfile_name_h) {
+ Setattr(top, "outfile_h", NewStringf("%s_wrap.%s", basename, hpp_extension));
+ } else {
+ Setattr(top, "outfile_h", outfile_name_h);
+ }
+ set_outdir(Swig_file_dirname(Getattr(top, "outfile")));
+ if (Swig_contract_mode_get()) {
+ Swig_contracts(top);
+ }
+
+ // Check the suffix for a c/c++ file. If so, we're going to declare everything we see as "extern"
+ ForceExtern = check_suffix(input_file);
+
+ lang->top(top);
+
+ if (browse) {
+ Swig_browser(top, 0);
+ }
+ }
+ }
+ if (dump_top & STAGE4) {
+ Printf(stdout, "debug-top stage 4\n");
+ Swig_print_tree(top);
+ }
+ if (dump_module & STAGE4) {
+ Printf(stdout, "debug-module stage 4\n");
+ Swig_print_tree(Getattr(top, "module"));
+ }
+ if (dump_xml && top) {
+ Swig_print_xml(top, xmlout);
+ }
+ Delete(top);
+ }
+ if (tm_debug)
+ Swig_typemap_debug();
+ if (memory_debug)
+ DohMemoryDebug();
+
+ char *outfiles = getenv("CCACHE_OUTFILES");
+ if (outfiles) {
+ File *f_outfiles = NewFile(outfiles, "w", 0);
+ if (!f_outfiles) {
+ Printf(stderr, "Failed to write list of output files to the filename '%s' specified in CCACHE_OUTFILES environment variable - ", outfiles);
+ FileErrorDisplay(outfiles);
+ SWIG_exit(EXIT_FAILURE);
+ } else {
+ int i;
+ for (i = 0; i < Len(all_output_files); i++)
+ Printf(f_outfiles, "%s\n", Getitem(all_output_files, i));
+ Close(f_outfiles);
+ }
+ }
+
+ // Deletes
+ Delete(libfiles);
+ Preprocessor_delete();
+
+ while (freeze) {
+ }
+
+ if ((werror) && (Swig_warn_count())) {
+ return Swig_warn_count();
+ }
+ return Swig_error_count();
+}
+
+// --------------------------------------------------------------------------
+// SWIG_exit(int exit_code)
+//
+// Cleanup and either freeze or exit
+// --------------------------------------------------------------------------
+
+void SWIG_exit(int exit_code) {
+ while (freeze) {
+ }
+ exit(exit_code);
+}
diff --git a/Source/Modules/modula3.cxx b/Source/Modules/modula3.cxx
new file mode 100644
index 0000000..40f275a
--- /dev/null
+++ b/Source/Modules/modula3.cxx
@@ -0,0 +1,3987 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * modula3.cxx
+ *
+ * Modula3 language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_modula3_cxx[] = "$Id: modula3.cxx 11584 2009-08-16 00:04:29Z wsfulton $";
+
+/*
+ Text formatted with
+ indent -sob -br -ce -nut -npsl
+*/
+
+/*
+ Report:
+ - It's not a good concept to use member variables or global variables
+ for passing parameters to functions.
+ It's not a good concept to use functions of superclasses for specific services.
+ E.g. For SWIG this means: Generating accessor functions for member variables
+ is the most common but no general task to be processed in membervariableHandler.
+ Better provide a service function which generates accessor function code
+ and equip this service function with all parameters needed for input (parse node)
+ and output (generated code).
+ - How can I make globalvariableHandler not to generate
+ interface functions to two accessor functions
+ (that don't exist) ?
+ - How can I generate a typemap that turns every C reference argument into
+ its Modula 3 counterpart, that is
+ void test(Complex &z);
+ PROCEDURE test(VAR z:Complex);
+ - neither $*n_mangle nor $*n_type nor $*n_ltype return the type without
+ pointer converted to Modula3 equivalent,
+ $*n_mangle is the variant closest to what I expect
+ - using a typemap like
+ typemap(m3wrapintype) int * %{VAR $1_name: INTEGER%}
+ has the advantages:
+ - one C parameter can be turned into multiple M3 parameters
+ - the argument can be renamed
+ - using typemaps like
+ typemap(m3wrapinmode) int * "VAR"
+ typemap(m3wrapintype) int * "INTEGER"
+ has the advantages:
+ - multiple parameters with same type and default value can be bundled
+ - more conform to the other language modules
+ - Where takes the reduction of multi-typemaps place?
+ How can I preserve all parameters for functions of the intermediary class?
+ The answer is Getattrs(n,"tmap:m3rawintype:next")
+ - Char() can be used to transform a String to (char *)
+ which can be used for output with printf
+ - What is the while (checkAttribute()) loop in functionWrapper good for?
+ Appearently for skipping (numinputs=0) typemaps.
+ - SWIGTYPE const * - typemap is ignored, whereas
+ SWIGTYPE * - typemap is invoked, why?
+ Had it been (const SWIGTYPE *) instead?
+ - enumeration items should definitely be equipped
+ with its plain numerical value
+ One could add tag 'numvalue' in CParse/parser.y,
+ but it is still possible that someone declares an
+ enumeration using a symbolic constant.
+ I have quickly hacked
+ that the successive number is assigned
+ if "enumvalue" has suffix "+1".
+ The ultimate solution would be to generate a C program
+ which includes the header and outputs all constants.
+ This program might be compiled and run
+ by 'make' or by SWIG and the resulting output is fed back to SWIG.
+ - It's a bad idea to interpret feature value ""
+ 'disable feature' because the value ""
+ might be sensible in case of feature:modula3:oldprefix.
+ - What's the difference between "sym:name" and "name" ?
+ "name" is the original name and
+ "sym:name" is probably modified by the user using %rename
+ - Is it possible for 'configure' to find out if m3pp is installed
+ and to invoke it for generated Modula3 files?
+ - It would be better to separate an arguments purpose and its name,
+ because an output variable with name "OUTPUT" is not very descriptive.
+ In case of PLPlot this could be solved by typedefs
+ that assign special purposes to the array types.
+ - Can one interpret $n_basetype as the identifier matched with SWIGTYPE ?
+
+ Swig's odds:
+ - arguments of type (Node *) for SWIG functions
+ should be most often better (const Node *):
+ Swig_symbol_qualified, Getattr, nodeType, parentNode
+ - unique identifier style instead of
+ NewString, Getattr, firstChild
+ - 'class'.name is qualified,
+ 'enum'.name and 'enumitem'.name is not
+ - Swig_symbol_qualified() returns NIL for enumeration nodes
+
+ - Is there a function that creates a C representation of a SWIG type string?
+
+ ToDo:
+ - create WeakRefs only for resources returned by function marked with %newobject
+ -> part of output conversion
+ - clean typemap conception
+ - should a multi-typemap for m3wrapouttype skip the corresponding input parameters?
+ when yes - How to handle inout-arguments? In this case like in-argument.
+ - C++ classes
+ - C++ exceptions
+ - allow for moving RECORD and OBJECT definitions
+ to separate files, with the main type called T
+ - call-back functions
+ - special option: fast access to class members by pointer arithmetic,
+ member offsets can be determined by a C++ program that print them.
+ - emit enumeration definitions when its first item is declared,
+ currently enumerations are emitted at the beginning of the file
+
+ Done:
+ - addThrow should convert the typemap by itself
+ - not possible because routine for attaching mapped types to parameter nodes
+ won't work for the function node
+ - turning error codes into exceptions
+ -> part of output value checking
+ - create WeakRefs for resources allocated by the library
+ -> part of output conversion
+ - TRY..FINALLY..END; can be omitted
+ - if there is no m3wrapfreearg
+ - no exception can be raised in the body (empty RAISES) list
+*/
+
+#include "swigmod.h"
+
+#include <limits.h> // for INT_MAX
+#include <ctype.h>
+
+#define USAGE_ARG_DIR "m3wrapargdir typemap expect values: in, out, inout\n"
+
+class MODULA3:public Language {
+public:
+ enum block_type { no_block, constant, variable, blocktype, revelation };
+
+private:
+ struct M3File {
+ String *f;
+ Hash *import;
+ block_type bt;
+ /* VC++ 6 doesn't allow the access to 'no_block'
+ if it is a private member of MODULA3 class */
+ M3File():f(NewString("")), import(NewHash()), bt(no_block) {
+ }
+ ~M3File() {
+ Delete(f);
+ Delete(import);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * enterBlock()
+ *
+ * Make sure that a given declaration is written to the right declaration block,
+ * that is constants are written after "CONST" and so on ...
+ * ----------------------------------------------------------------------------- */
+ void enterBlock(block_type newbt) {
+ static const char *ident[] = { "", "\nCONST\n", "\nVAR\n", "\nTYPE\n", "\nREVEAL\n" };
+#ifdef DEBUG
+ if ((bt < 0) || (4 < bt)) {
+ printf("bt %d out of range\n", bt);
+ }
+#endif
+ if (newbt != bt) {
+ Append(f, ident[newbt]);
+ bt = newbt;
+ }
+ }
+
+ };
+
+ static const char *usage;
+ const String *empty_string;
+
+ Hash *swig_types_hash;
+ File *f_begin;
+ File *f_runtime;
+ File *f_header;
+ File *f_wrappers;
+ File *f_init;
+
+ bool proxy_flag; // Flag for generating proxy 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
+ bool old_variable_names; // Flag for old style variable names in the intermediary class
+ bool unsafe_module;
+
+ String *m3raw_name; // raw interface name
+ M3File m3raw_intf; // raw interface
+ M3File m3raw_impl; // raw implementation (usually empty)
+ String *m3wrap_name; // wrapper module
+ M3File m3wrap_intf;
+ M3File m3wrap_impl;
+ String *m3makefile;
+ String *targetlibrary;
+ String *proxy_class_def;
+ String *proxy_class_code;
+ String *proxy_class_name;
+ String *variable_name; //Name of a variable being wrapped
+ String *variable_type; //Type of this variable
+ String *enumeration_name; //Name of the current enumeration type
+ Hash *enumeration_items; //and its members
+ int enumeration_max;
+ Hash *enumeration_coll; //Collection of all enumerations.
+ /* The items are nodes with members:
+ "items" - hash of with key 'itemname' and content 'itemvalue'
+ "max" - maximum value in item list
+ */
+ String *constant_values;
+ String *constantfilename;
+ String *renamefilename;
+ String *typemapfilename;
+ String *m3raw_imports; //intermediary class imports from %pragma
+ String *module_imports; //module imports from %pragma
+ String *m3raw_baseclass; //inheritance for intermediary class class from %pragma
+ String *module_baseclass; //inheritance for module class from %pragma
+ String *m3raw_interfaces; //interfaces for intermediary class class from %pragma
+ String *module_interfaces; //interfaces for module class from %pragma
+ String *m3raw_class_modifiers; //class modifiers for intermediary class overriden by %pragma
+ String *m3wrap_modifiers; //class modifiers for module class overriden by %pragma
+ String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
+ String *m3raw_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
+ String *destructor_call; //C++ destructor call if any
+ String *outfile;
+
+ enum type_additions { none, pointer, reference };
+
+public:
+
+ /* -----------------------------------------------------------------------------
+ * MODULA3()
+ * ----------------------------------------------------------------------------- */
+
+MODULA3():
+ empty_string(NewString("")),
+ swig_types_hash(NULL),
+ f_begin(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),
+ old_variable_names(false),
+ unsafe_module(false),
+ m3raw_name(NULL),
+ m3raw_intf(),
+ m3raw_impl(),
+ m3wrap_name(NULL),
+ m3wrap_intf(),
+ m3wrap_impl(),
+ m3makefile(NULL),
+ targetlibrary(NULL),
+ proxy_class_def(NULL),
+ proxy_class_code(NULL),
+ proxy_class_name(NULL),
+ variable_name(NULL),
+ variable_type(NULL),
+ enumeration_name(NULL),
+ enumeration_items(NULL),
+ enumeration_max(0),
+ enumeration_coll(NULL),
+ constant_values(NULL),
+ constantfilename(NULL),
+ renamefilename(NULL),
+ typemapfilename(NULL),
+ m3raw_imports(NULL),
+ module_imports(NULL),
+ m3raw_baseclass(NULL),
+ module_baseclass(NULL),
+ m3raw_interfaces(NULL),
+ module_interfaces(NULL),
+ m3raw_class_modifiers(NULL),
+ m3wrap_modifiers(NULL),
+ upcasts_code(NULL),
+ m3raw_cppcasts_code(NULL),
+ destructor_call(NULL),
+ outfile(NULL) {
+ }
+
+ /************** some utility functions ***************/
+
+ /* -----------------------------------------------------------------------------
+ * getMappedType()
+ *
+ * Return the type of 'p' mapped by 'map'.
+ * Print a standard warning if 'p' can't be mapped.
+ * ----------------------------------------------------------------------------- */
+
+ String *getMappedType(Node *p, const char *map) {
+ String *mapattr = NewString("tmap:");
+ Append(mapattr, map);
+
+ String *tm = Getattr(p, mapattr);
+ if (tm == NIL) {
+ Swig_warning(WARN_MODULA3_TYPEMAP_TYPE_UNDEF, input_file, line_number,
+ "No '%s' typemap defined for type '%s'\n", map, SwigType_str(Getattr(p, "type"), 0));
+ }
+ Delete(mapattr);
+ return tm;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getMappedTypeNew()
+ *
+ * Similar to getMappedType but uses Swig_type_lookup_new.
+ * ----------------------------------------------------------------------------- */
+
+ String *getMappedTypeNew(Node *n, const char *map, const char *lname = "", bool warn = true) {
+ String *tm = Swig_typemap_lookup(map, n, lname, 0);
+ if ((tm == NIL) && warn) {
+ Swig_warning(WARN_MODULA3_TYPEMAP_TYPE_UNDEF, input_file, line_number,
+ "No '%s' typemap defined for type '%s'\n", map, SwigType_str(Getattr(n, "type"), 0));
+ }
+ return tm;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * attachMappedType()
+ *
+ * Obtain the type mapped by 'map' and attach it to the node
+ * ----------------------------------------------------------------------------- */
+
+ void attachMappedType(Node *n, const char *map, const char *lname = "") {
+ String *tm = Swig_typemap_lookup(map, n, lname, 0);
+ if (tm != NIL) {
+ String *attr = NewStringf("tmap:%s", map);
+ Setattr(n, attr, tm);
+ Delete(attr);
+ }
+ }
+
+ /* -----------------------------------------------------------------------------
+ * skipIgnored()
+ *
+ * Skip all parameters that have 'numinputs=0'
+ * with respect to a given typemap.
+ * ----------------------------------------------------------------------------- */
+
+ Node *skipIgnored(Node *p, const char *map) {
+ String *niattr = NewStringf("tmap:%s:numinputs", map);
+ String *nextattr = NewStringf("tmap:%s:next", map);
+
+ while ((p != NIL) && checkAttribute(p, niattr, "0")) {
+ p = Getattr(p, nextattr);
+ }
+
+ Delete(nextattr);
+ Delete(niattr);
+ return p;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * isInParam()
+ * isOutParam()
+ *
+ * Check if the parameter is intended for input or for output.
+ * ----------------------------------------------------------------------------- */
+
+ bool isInParam(Node *p) {
+ String *dir = Getattr(p, "tmap:m3wrapargdir");
+//printf("dir for %s: %s\n", Char(Getattr(p,"name")), Char(dir));
+ if ((dir == NIL) || (Strcmp(dir, "in") == 0)
+ || (Strcmp(dir, "inout") == 0)) {
+ return true;
+ } else if (Strcmp(dir, "out") == 0) {
+ return false;
+ } else {
+ printf("%s", USAGE_ARG_DIR);
+ return false;
+ }
+ }
+
+ bool isOutParam(Node *p) {
+ String *dir = Getattr(p, "tmap:m3wrapargdir");
+ if ((dir == NIL) || (Strcmp(dir, "in") == 0)) {
+ return false;
+ } else if ((Strcmp(dir, "out") == 0) || (Strcmp(dir, "inout") == 0)) {
+ return true;
+ } else {
+ printf("%s", USAGE_ARG_DIR);
+ return false;
+ }
+ }
+
+ /* -----------------------------------------------------------------------------
+ * printAttrs()
+ *
+ * For debugging: Show all attributes of a node and their values.
+ * ----------------------------------------------------------------------------- */
+ void printAttrs(Node *n) {
+ Iterator it;
+ for (it = First(n); it.key != NIL; it = Next(it)) {
+ printf("%s = %s\n", Char(it.key), Char(Getattr(n, it.key)));
+ }
+ }
+
+ /* -----------------------------------------------------------------------------
+ * hasPrefix()
+ *
+ * Check if a string have a given prefix.
+ * ----------------------------------------------------------------------------- */
+ bool hasPrefix(const String *str, const String *prefix) {
+ int len_prefix = Len(prefix);
+ return (Len(str) > len_prefix)
+ && (Strncmp(str, prefix, len_prefix) == 0);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getQualifiedName()
+ *
+ * Return fully qualified identifier of n.
+ * ----------------------------------------------------------------------------- */
+#if 0
+ // Swig_symbol_qualified returns NIL for enumeration nodes
+ String *getQualifiedName(Node *n) {
+ String *qual = Swig_symbol_qualified(n);
+ String *name = Getattr(n, "name");
+ if (hasContent(qual)) {
+ return NewStringf("%s::%s", qual, name);
+ } else {
+ return name;
+ }
+ }
+#else
+ String *getQualifiedName(Node *n) {
+ String *name = Copy(Getattr(n, "name"));
+ n = parentNode(n);
+ while (n != NIL) {
+ const String *type = nodeType(n);
+ if ((Strcmp(type, "class") == 0) || (Strcmp(type, "struct") == 0) || (Strcmp(type, "namespace") == 0)) {
+ String *newname = NewStringf("%s::%s", Getattr(n, "name"), name);
+ Delete(name);
+ //name = newname;
+ // Hmpf, the class name is already qualified.
+ return newname;
+ }
+ n = parentNode(n);
+ }
+ //printf("qualified name: %s\n", Char(name));
+ return name;
+ }
+#endif
+
+ /* -----------------------------------------------------------------------------
+ * nameToModula3()
+ *
+ * Turn usual C identifiers like "this_is_an_identifier"
+ * into usual Modula 3 identifier like "thisIsAnIdentifier"
+ * ----------------------------------------------------------------------------- */
+ String *nameToModula3(const String *sym, bool leadingCap) {
+ int len_sym = Len(sym);
+ char *csym = Char(sym);
+ char *m3sym = new char[len_sym + 1];
+ int i, j;
+ bool cap = leadingCap;
+ for (i = 0, j = 0; j < len_sym; j++) {
+ char c = csym[j];
+ if ((c == '_') || (c == ':')) {
+ cap = true;
+ } else {
+ if (isdigit(c)) {
+ m3sym[i] = c;
+ cap = true;
+ } else {
+ if (cap) {
+ m3sym[i] = (char)toupper(c);
+ } else {
+ m3sym[i] = (char)tolower(c);
+ }
+ cap = false;
+ }
+ i++;
+ }
+ }
+ m3sym[i] = 0;
+ String *result = NewString(m3sym);
+ delete[]m3sym;
+ return result;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * capitalizeFirst()
+ *
+ * Make the first character upper case.
+ * ----------------------------------------------------------------------------- */
+ String *capitalizeFirst(const String *str) {
+ return NewStringf("%c%s", toupper(*Char(str)), Char(str) + 1);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * prefixedNameToModula3()
+ *
+ * If feature modula3:oldprefix and modula3:newprefix is present
+ * and the C identifier has leading 'oldprefix'
+ * then it is replaced by the 'newprefix'.
+ * The rest is converted to Modula style.
+ * ----------------------------------------------------------------------------- */
+ String *prefixedNameToModula3(Node *n, const String *sym, bool leadingCap) {
+ String *oldPrefix = Getattr(n, "feature:modula3:oldprefix");
+ String *newPrefix = Getattr(n, "feature:modula3:newprefix");
+ String *result = NewString("");
+ char *short_sym = Char(sym);
+ // if at least one prefix feature is present
+ // the replacement takes place
+ if ((oldPrefix != NIL) || (newPrefix != NIL)) {
+ if ((oldPrefix == NIL) || hasPrefix(sym, oldPrefix)) {
+ short_sym += Len(oldPrefix);
+ if (newPrefix != NIL) {
+ Append(result, newPrefix);
+ }
+ }
+ }
+ String *suffix = nameToModula3(short_sym, leadingCap || hasContent(newPrefix));
+ Append(result, suffix);
+ Delete(suffix);
+ return result;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * hasContent()
+ *
+ * Check if the string exists and contains something.
+ * ----------------------------------------------------------------------------- */
+ bool hasContent(const String *str) {
+ return (str != NIL) && (Strcmp(str, "") != 0);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * openWriteFile()
+ *
+ * Caution: The file must be freshly allocated and will be destroyed
+ * by this routine.
+ * ----------------------------------------------------------------------------- */
+
+ File *openWriteFile(String *name) {
+ File *file = NewFile(name, "w", SWIG_output_files());
+ if (!file) {
+ FileErrorDisplay(name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(name);
+ return file;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * aToL()
+ *
+ * like atol but with additional user warning
+ * ----------------------------------------------------------------------------- */
+
+ long aToL(const String *value) {
+ char *endptr;
+ long numvalue = strtol(Char(value), &endptr, 0);
+ if (*endptr != 0) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "The string <%s> does not denote a numeric value.\n", value);
+ }
+ return numvalue;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * strToL()
+ *
+ * like strtol but returns if the conversion was successful
+ * ----------------------------------------------------------------------------- */
+
+ bool strToL(const String *value, long &numvalue) {
+ char *endptr;
+ numvalue = strtol(Char(value), &endptr, 0);
+ return (*endptr == 0);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * evalExpr()
+ *
+ * Evaluate simple expression as they may occur in "enumvalue" attributes.
+ * ----------------------------------------------------------------------------- */
+
+ bool evalExpr(String *value, long &numvalue) {
+ // Split changes file status of String and thus cannot receive 'const' strings
+//printf("evaluate <%s>\n", Char(value));
+ List *summands = Split(value, '+', INT_MAX);
+ Iterator sm = First(summands);
+ numvalue = 0;
+ for (; sm.item != NIL; sm = Next(sm)) {
+ String *smvalue = Getattr(constant_values, sm.item);
+ long smnumvalue;
+ if (smvalue != NIL) {
+ if (!strToL(smvalue, smnumvalue)) {
+//printf("evaluation: abort 0 <%s>\n", Char(smvalue));
+ return false;
+ }
+ } else {
+ if (!strToL(sm.item, smnumvalue)) {
+//printf("evaluation: abort 1 <%s>\n", Char(sm));
+ return false;
+ }
+ }
+ numvalue += smnumvalue;
+ }
+//printf("evaluation: return %ld\n", numvalue);
+ return true;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * log2()
+ *
+ * Determine the position of the single bit of a power of two.
+ * Returns true if the given number is a power of two.
+ * ----------------------------------------------------------------------------- */
+
+ bool log2(long n, long &exp) {
+ exp = 0;
+ while (n > 0) {
+ if ((n & 1) != 0) {
+ return n == 1;
+ }
+ exp++;
+ n >>= 1;
+ }
+ return false;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * writeArg
+ *
+ * Write a function argument or RECORD entry definition.
+ * Bundles arguments of same type and default value.
+ * 'name.next==NIL' denotes the end of the entry or argument list.
+ * ----------------------------------------------------------------------------- */
+
+ bool equalNilStr(const String *str0, const String *str1) {
+ if (str0 == NIL) {
+ return (str1 == NIL);
+ //return (str0==NIL) == (str1==NIL);
+ } else {
+ return (str1 != NIL) && (Cmp(str0, str1) == 0);
+ //return Cmp(str0,str1)==0;
+ }
+ }
+
+ struct writeArgState {
+ String *mode, *name, *type, *value;
+ bool hold;
+ writeArgState():mode(NIL), name(NIL), type(NIL), value(NIL), hold(false) {
+ }
+ };
+
+ void writeArg(File *f, writeArgState & state, String *mode, String *name, String *type, String *value) {
+ /* skip the first argument,
+ only store the information for the next call in this case */
+ if (state.name != NIL) {
+ if ((!state.hold) && (state.mode != NIL)) {
+ Printf(f, "%s ", state.mode);
+ }
+ if ((name != NIL) && equalNilStr(state.mode, mode) && equalNilStr(state.type, type) && (state.value == NIL) && (value == NIL)
+ /* the same expression may have different values
+ due to side effects of the called function */
+ /*equalNilStr(state.value,value) */
+ ) {
+ Printf(f, "%s, ", state.name);
+ state.hold = true;
+ } else {
+ Append(f, state.name);
+ if (state.type != NIL) {
+ Printf(f, ": %s", state.type);
+ }
+ if (state.value != NIL) {
+ Printf(f, ":= %s", state.value);
+ }
+ Append(f, ";\n");
+ state.hold = false;
+ }
+ }
+ /* at the next call the current argument will be the previous one */
+ state.mode = mode;
+ state.name = name;
+ state.type = type;
+ state.value = value;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getProxyName()
+ *
+ * Test to see if a type corresponds to something wrapped with a proxy class
+ * Return NULL if not otherwise the proxy class name
+ * ----------------------------------------------------------------------------- */
+
+ String *getProxyName(SwigType *t) {
+ if (proxy_flag) {
+ Node *n = classLookup(t);
+ if (n) {
+ return Getattr(n, "sym:name");
+ }
+ }
+ return NULL;
+ }
+
+ /*************** language processing ********************/
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+
+ SWIG_library_directory("modula3");
+
+ // Look for certain command line options
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-generateconst") == 0) {
+ if (argv[i + 1]) {
+ constantfilename = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-generaterename") == 0) {
+ if (argv[i + 1]) {
+ renamefilename = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-generatetypemap") == 0) {
+ if (argv[i + 1]) {
+ typemapfilename = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-noproxy") == 0) {
+ Swig_mark_arg(i);
+ proxy_flag = false;
+ } else if (strcmp(argv[i], "-oldvarnames") == 0) {
+ Swig_mark_arg(i);
+ old_variable_names = true;
+ } else if (strcmp(argv[i], "-help") == 0) {
+ Printf(stdout, "%s\n", usage);
+ }
+ }
+ }
+
+ // Add a symbol to the parser for conditional compilation
+ Preprocessor_define("SWIGMODULA3 1", 0);
+
+ // Add typemap definitions
+ SWIG_typemap_lang("modula3");
+ SWIG_config_file("modula3.swg");
+
+ allow_overloading();
+ }
+
+ /* ---------------------------------------------------------------------
+ * top()
+ * --------------------------------------------------------------------- */
+
+ virtual int top(Node *n) {
+ if (hasContent(constantfilename) || hasContent(renamefilename) || hasContent(typemapfilename)) {
+ int result = SWIG_OK;
+ if (hasContent(constantfilename)) {
+ result = generateConstantTop(n) && result;
+ }
+ if (hasContent(renamefilename)) {
+ result = generateRenameTop(n) && result;
+ }
+ if (hasContent(typemapfilename)) {
+ result = generateTypemapTop(n) && result;
+ }
+ return result;
+ } else {
+ return generateM3Top(n);
+ }
+ }
+
+ void scanConstant(File *file, Node *n) {
+ Node *child = firstChild(n);
+ while (child != NIL) {
+ String *constname = NIL;
+ String *type = nodeType(child);
+ if ((Strcmp(type, "enumitem") == 0)
+ || (Strcmp(type, "constant") == 0)) {
+#if 1
+ constname = getQualifiedName(child);
+#else
+ constname = Getattr(child, "value");
+ if ((!hasContent(constname))
+ || (('0' <= *Char(constname)) && (*Char(constname) <= '9'))) {
+ constname = Getattr(child, "name");
+ }
+#endif
+ }
+ if (constname != NIL) {
+ Printf(file, " printf(\"%%%%constnumeric(%%Lg) %s;\\n\", (long double)%s);\n", constname, constname);
+ }
+ scanConstant(file, child);
+ child = nextSibling(child);
+ }
+ }
+
+ int generateConstantTop(Node *n) {
+ File *file = openWriteFile(NewStringf("%s.c", constantfilename));
+ if (CPlusPlus) {
+ Printf(file, "#include <cstdio>\n");
+ } else {
+ Printf(file, "#include <stdio.h>\n");
+ }
+ Printf(file, "#include \"%s\"\n", input_file);
+ Printf(file, "\n");
+ Printf(file, "int main (int argc, char *argv[]) {\n");
+ Printf(file, "\
+/*This progam must work for floating point numbers and integers.\n\
+ Thus all numbers are converted to double precision floating point format.*/\n");
+ scanConstant(file, n);
+ Printf(file, " return 0;\n");
+ Printf(file, "}\n");
+ Close(file);
+ return SWIG_OK;
+ }
+
+ void scanRename(File *file, Node *n) {
+ Node *child = firstChild(n);
+ while (child != NIL) {
+ String *type = nodeType(child);
+ if (Strcmp(type, "cdecl") == 0) {
+ ParmList *p = Getattr(child, "parms");
+ if (p != NIL) {
+ String *name = getQualifiedName(child);
+ String *m3name = nameToModula3(name, true);
+ /*don't know how to get the original C type identifiers */
+ //String *arguments = createCSignature (child);
+ Printf(file, "%%rename(\"%s\") %s;\n", m3name, name);
+ /*Printf(file, "%%rename(\"%s\") %s %s(%s);\n",
+ m3name, Getattr(n,"type"), name, arguments); */
+ Delete(name);
+ Delete(m3name);
+ //Delete (arguments);
+ }
+ }
+ scanRename(file, child);
+ child = nextSibling(child);
+ }
+ }
+
+ int generateRenameTop(Node *n) {
+ File *file = openWriteFile(NewStringf("%s.i", renamefilename));
+ Printf(file, "\
+/* This file was generated from %s\n\
+ by SWIG with option -generaterename. */\n\
+\n", input_file);
+ scanRename(file, n);
+ Close(file);
+ return SWIG_OK;
+ }
+
+ void scanTypemap(File *file, Node *n) {
+ Node *child = firstChild(n);
+ while (child != NIL) {
+ String *type = nodeType(child);
+ //printf("nodetype %s\n", Char(type));
+ String *storage = Getattr(child, "storage");
+ if ((Strcmp(type, "class") == 0) || ((Strcmp(type, "cdecl") == 0) && (storage != NIL)
+ && (Strcmp(storage, "typedef") == 0))) {
+ String *name = getQualifiedName(child);
+ String *m3name = nameToModula3(name, true);
+ Printf(file, "%%typemap(\"m3wrapintype\") %s %%{%s%%}\n", name, m3name);
+ Printf(file, "%%typemap(\"m3rawintype\") %s %%{%s%%}\n", name, m3name);
+ Printf(file, "\n");
+ }
+ scanTypemap(file, child);
+ child = nextSibling(child);
+ }
+ }
+
+ int generateTypemapTop(Node *n) {
+ File *file = openWriteFile(NewStringf("%s.i", typemapfilename));
+ Printf(file, "\
+/* This file was generated from %s\n\
+ by SWIG with option -generatetypemap. */\n\
+\n", input_file);
+ scanTypemap(file, n);
+ Close(file);
+ return SWIG_OK;
+ }
+
+ int generateM3Top(Node *n) {
+ /* Initialize all of the output files */
+ outfile = Getattr(n, "outfile");
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+
+ m3makefile = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+
+ Swig_register_filebyname("m3rawintf", m3raw_intf.f);
+ Swig_register_filebyname("m3rawimpl", m3raw_impl.f);
+ Swig_register_filebyname("m3wrapintf", m3wrap_intf.f);
+ Swig_register_filebyname("m3wrapimpl", m3wrap_impl.f);
+ Swig_register_filebyname("m3makefile", m3makefile);
+
+ swig_types_hash = NewHash();
+
+ String *name = Getattr(n, "name");
+ // Make the intermediary class and module class names. The intermediary class name can be set in the module directive.
+ Node *optionsnode = Getattr(Getattr(n, "module"), "options");
+ if (optionsnode != NIL) {
+ String *m3raw_name_tmp = Getattr(optionsnode, "m3rawname");
+ if (m3raw_name_tmp != NIL) {
+ m3raw_name = Copy(m3raw_name_tmp);
+ }
+ }
+ if (m3raw_name == NIL) {
+ m3raw_name = NewStringf("%sRaw", name);
+ }
+ Setattr(m3wrap_impl.import, m3raw_name, "");
+
+ m3wrap_name = Copy(name);
+
+ proxy_class_def = NewString("");
+ proxy_class_code = NewString("");
+ m3raw_baseclass = NewString("");
+ m3raw_interfaces = NewString("");
+ m3raw_class_modifiers = NewString(""); // package access only to the intermediary class by default
+ m3raw_imports = NewString("");
+ m3raw_cppcasts_code = NewString("");
+ m3wrap_modifiers = NewString("public");
+ module_baseclass = NewString("");
+ module_interfaces = NewString("");
+ module_imports = NewString("");
+ upcasts_code = NewString("");
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGMODULA3\n");
+ Printf(f_runtime, "\n");
+
+ Swig_name_register((char *) "wrapper", (char *) "Modula3_%f");
+ if (old_variable_names) {
+ Swig_name_register((char *) "set", (char *) "set_%v");
+ Swig_name_register((char *) "get", (char *) "get_%v");
+ }
+
+ Printf(f_wrappers, "\n#ifdef __cplusplus\n");
+ Printf(f_wrappers, "extern \"C\" {\n");
+ Printf(f_wrappers, "#endif\n\n");
+
+ constant_values = NewHash();
+ scanForConstPragmas(n);
+ enumeration_coll = NewHash();
+ collectEnumerations(enumeration_coll, n);
+
+ /* Emit code */
+ Language::top(n);
+
+ // Generate m3makefile
+ // This will be unnecessary if SWIG is invoked from Quake.
+ {
+ File *file = openWriteFile(NewStringf("%sm3makefile", Swig_file_dirname(outfile)));
+
+ Printf(file, "%% automatically generated quake file for %s\n\n", name);
+
+ /* Write the fragments written by '%insert'
+ collected while 'top' processed the parse tree */
+ Printv(file, m3makefile, NIL);
+
+ Printf(file, "import(\"libm3\")\n");
+ //Printf(file, "import_lib(\"%s\",\"/usr/lib\")\n", name);
+ Printf(file, "module(\"%s\")\n", m3raw_name);
+ Printf(file, "module(\"%s\")\n\n", m3wrap_name);
+
+ if (targetlibrary != NIL) {
+ Printf(file, "library(\"%s\")\n", targetlibrary);
+ } else {
+ Printf(file, "library(\"m3%s\")\n", name);
+ }
+ Close(file);
+ }
+
+ // Generate the raw interface
+ {
+ File *file = openWriteFile(NewStringf("%s%s.i3", Swig_file_dirname(outfile), m3raw_name));
+
+ emitBanner(file);
+
+ Printf(file, "INTERFACE %s;\n\n", m3raw_name);
+
+ emitImportStatements(m3raw_intf.import, file);
+ Printf(file, "\n");
+
+ // Write the interface generated within 'top'
+ Printv(file, m3raw_intf.f, NIL);
+
+ Printf(file, "\nEND %s.\n", m3raw_name);
+ Close(file);
+ }
+
+ // Generate the raw module
+ {
+ File *file = openWriteFile(NewStringf("%s%s.m3", Swig_file_dirname(outfile), m3raw_name));
+
+ emitBanner(file);
+
+ Printf(file, "MODULE %s;\n\n", m3raw_name);
+
+ emitImportStatements(m3raw_impl.import, file);
+ Printf(file, "\n");
+
+ // will be empty usually
+ Printv(file, m3raw_impl.f, NIL);
+
+ Printf(file, "BEGIN\nEND %s.\n", m3raw_name);
+ Close(file);
+ }
+
+ // Generate the interface for the comfort wrappers
+ {
+ File *file = openWriteFile(NewStringf("%s%s.i3", Swig_file_dirname(outfile), m3wrap_name));
+
+ emitBanner(file);
+
+ Printf(file, "INTERFACE %s;\n", m3wrap_name);
+
+ emitImportStatements(m3wrap_intf.import, file);
+ Printf(file, "\n");
+
+ {
+ Iterator it = First(enumeration_coll);
+ if (it.key != NIL) {
+ Printf(file, "TYPE\n");
+ }
+ for (; it.key != NIL; it = Next(it)) {
+ Printf(file, "\n");
+ emitEnumeration(file, it.key, it.item);
+ }
+ }
+
+ // Add the wrapper methods
+ Printv(file, m3wrap_intf.f, NIL);
+
+ // Finish off the class
+ Printf(file, "\nEND %s.\n", m3wrap_name);
+ Close(file);
+ }
+
+ // Generate the wrapper routines implemented in Modula 3
+ {
+ File *file = openWriteFile(NewStringf("%s%s.m3", Swig_file_dirname(outfile), m3wrap_name));
+
+ emitBanner(file);
+
+ if (unsafe_module) {
+ Printf(file, "UNSAFE ");
+ }
+ Printf(file, "MODULE %s;\n\n", m3wrap_name);
+
+ emitImportStatements(m3wrap_impl.import, file);
+ Printf(file, "\n");
+
+ // Add the wrapper methods
+ Printv(file, m3wrap_impl.f, NIL);
+
+ Printf(file, "\nBEGIN\nEND %s.\n", m3wrap_name);
+ Close(file);
+ }
+
+ if (upcasts_code)
+ Printv(f_wrappers, upcasts_code, NIL);
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n");
+ Printf(f_wrappers, "}\n");
+ Printf(f_wrappers, "#endif\n");
+
+ // Output a Modula 3 type wrapper class for each SWIG type
+ for (Iterator swig_type = First(swig_types_hash); swig_type.item != NIL; swig_type = Next(swig_type)) {
+ emitTypeWrapperClass(swig_type.key, swig_type.item);
+ }
+
+ Delete(swig_types_hash);
+ swig_types_hash = NULL;
+ Delete(constant_values);
+ constant_values = NULL;
+ Delete(enumeration_coll);
+ enumeration_coll = NULL;
+ Delete(m3raw_name);
+ m3raw_name = NULL;
+ Delete(m3raw_baseclass);
+ m3raw_baseclass = NULL;
+ Delete(m3raw_interfaces);
+ m3raw_interfaces = NULL;
+ Delete(m3raw_class_modifiers);
+ m3raw_class_modifiers = NULL;
+ Delete(m3raw_imports);
+ m3raw_imports = NULL;
+ Delete(m3raw_cppcasts_code);
+ m3raw_cppcasts_code = NULL;
+ Delete(proxy_class_def);
+ proxy_class_def = NULL;
+ Delete(proxy_class_code);
+ proxy_class_code = NULL;
+ Delete(m3wrap_name);
+ m3wrap_name = NULL;
+ Delete(m3wrap_modifiers);
+ m3wrap_modifiers = NULL;
+ Delete(targetlibrary);
+ targetlibrary = NULL;
+ Delete(module_baseclass);
+ module_baseclass = NULL;
+ Delete(module_interfaces);
+ module_interfaces = NULL;
+ Delete(module_imports);
+ module_imports = NULL;
+ Delete(upcasts_code);
+ upcasts_code = NULL;
+ Delete(constantfilename);
+ constantfilename = NULL;
+ Delete(renamefilename);
+ renamefilename = NULL;
+ Delete(typemapfilename);
+ typemapfilename = NULL;
+
+ /* Close all of the files */
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitBanner()
+ * ----------------------------------------------------------------------------- */
+
+ void emitBanner(File *f) {
+ Printf(f, "(*******************************************************************************\n");
+ Swig_banner_target_lang(f, " *");
+ Printf(f, "*******************************************************************************)\n\n");
+ }
+
+ /* ----------------------------------------------------------------------
+ * nativeWrapper()
+ * ---------------------------------------------------------------------- */
+
+ virtual int nativeWrapper(Node *n) {
+ String *wrapname = Getattr(n, "wrap:name");
+
+ if (!addSymbol(wrapname, n))
+ return SWIG_ERROR;
+
+ if (Getattr(n, "type")) {
+ Swig_save("nativeWrapper", n, "name", NIL);
+ Setattr(n, "name", wrapname);
+ native_function_flag = true;
+ functionWrapper(n);
+ Swig_restore(n);
+ native_function_flag = false;
+ } else {
+ Printf(stderr, "%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n, "wrap:name"));
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * functionWrapper()
+ * ---------------------------------------------------------------------- */
+
+ virtual int functionWrapper(Node *n) {
+ String *type = nodeType(n);
+ String *funcType = Getattr(n, "modula3:functype");
+ String *rawname = Getattr(n, "name");
+ String *symname = Getattr(n, "sym:name");
+ String *capname = capitalizeFirst(symname);
+ //String *wname = Swig_name_wrapper(symname);
+
+ //printf("function: %s\n", Char(symname));
+ //printf(" purpose: %s\n", Char(funcType));
+
+ if (Strcmp(type, "cdecl") == 0) {
+ if (funcType == NIL) {
+ // no wrapper needed for plain functions
+ emitM3RawPrototype(n, rawname, symname);
+ emitM3Wrapper(n, symname);
+ } else if (Strcmp(funcType, "method") == 0) {
+ Setattr(n, "modula3:funcname", capname);
+ emitCWrapper(n, capname);
+ emitM3RawPrototype(n, capname, capname);
+ emitM3Wrapper(n, capname);
+ } else if (Strcmp(funcType, "accessor") == 0) {
+ /*
+ * Generate the proxy class properties for public member variables.
+ * Not for enums and constants.
+ */
+ if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
+ // Capitalize the first letter in the function name
+ Setattr(n, "proxyfuncname", capname);
+ Setattr(n, "imfuncname", symname);
+ if (hasPrefix(capname, "Set")) {
+ Setattr(n, "modula3:setname", capname);
+ } else {
+ Setattr(n, "modula3:getname", capname);
+ }
+
+ emitCWrapper(n, capname);
+ emitM3RawPrototype(n, capname, capname);
+ emitM3Wrapper(n, capname);
+ //proxyClassFunctionHandler(n);
+ }
+#ifdef DEBUG
+ } else {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Function type <%s> unknown.\n", Char(funcType));
+#endif
+ }
+ } else if ((Strcmp(type, "constructor") == 0) || (Strcmp(type, "destructor") == 0)) {
+ emitCWrapper(n, capname);
+ emitM3RawPrototype(n, capname, capname);
+ emitM3Wrapper(n, capname);
+ }
+// a Java relict
+#if 0
+ if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
+ emitM3Wrapper(n, capname);
+ }
+#endif
+
+ Delete(capname);
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * emitCWrapper()
+ *
+ * Generate the wrapper in C which calls C++ methods.
+ * ---------------------------------------------------------------------- */
+
+ virtual int emitCWrapper(Node *n, const String *wname) {
+ String *rawname = Getattr(n, "name");
+ String *c_return_type = NewString("");
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *body = NewString("");
+ Hash *throws_hash = NewHash();
+ ParmList *l = Getattr(n, "parms");
+ SwigType *t = Getattr(n, "type");
+ String *symname = Getattr(n, "sym:name");
+
+ if (!Getattr(n, "sym:overloaded")) {
+ if (!addSymbol(wname, n)) {
+ return SWIG_ERROR;
+ }
+ }
+ // A new wrapper function object
+ Wrapper *f = NewWrapper();
+
+ /* Attach the non-standard typemaps to the parameter list. */
+ Swig_typemap_attach_parms("ctype", l, f);
+
+ /* Get return types */
+ {
+ String *tm = getMappedTypeNew(n, "ctype", "");
+ if (tm != NIL) {
+ Printf(c_return_type, "%s", tm);
+ }
+ }
+
+ bool is_void_return = (Cmp(c_return_type, "void") == 0);
+ if (!is_void_return) {
+ Wrapper_add_localv(f, "cresult", c_return_type, "cresult = 0", NIL);
+ }
+
+ Printv(f->def, " SWIGEXPORT ", c_return_type, " ", wname, "(", NIL);
+
+ // Emit all of the local variables for holding arguments.
+ emit_parameter_variables(l, f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l, f);
+ Setattr(n, "wrap:parms", l);
+
+ // Generate signature and argument conversion for C wrapper
+ {
+ Parm *p;
+ attachParameterNames(n, "tmap:name", "c:wrapname", "m3arg%d");
+ bool gencomma = false;
+ for (p = skipIgnored(l, "in"); p != NULL; p = skipIgnored(p, "in")) {
+
+ String *arg = Getattr(p, "c:wrapname");
+ {
+ /* Get the ctype types of the parameter */
+ String *c_param_type = getMappedType(p, "ctype");
+ // Add parameter to C function
+ Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL);
+ Delete(c_param_type);
+ gencomma = true;
+ }
+
+ // Get typemap for this argument
+ String *tm = getMappedType(p, "in");
+ if (tm != NIL) {
+ addThrows(throws_hash, "in", p);
+ Replaceall(tm, "$input", arg);
+ Setattr(p, "emit:input", arg); /*??? */
+ Printf(f->code, "%s\n", tm);
+ p = Getattr(p, "tmap:in:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* Insert constraint checking code */
+ {
+ Parm *p;
+ for (p = l; p;) {
+ String *tm = Getattr(p, "tmap:check");
+ if (tm != NIL) {
+ addThrows(throws_hash, "check", p);
+ Replaceall(tm, "$target", Getattr(p, "lname")); /* deprecated */
+ Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* Insert cleanup code */
+ {
+ Parm *p;
+ for (p = l; p;) {
+ String *tm = Getattr(p, "tmap:freearg");
+ if (tm != NIL) {
+ addThrows(throws_hash, "freearg", p);
+ Replaceall(tm, "$source", Getattr(p, "emit:input")); /* deprecated */
+ Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(cleanup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* Insert argument output code */
+ {
+ Parm *p;
+ for (p = l; p;) {
+ String *tm = Getattr(p, "tmap:argout");
+ if (tm != NIL) {
+ addThrows(throws_hash, "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", "cresult");
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(outarg, tm, "\n", NIL);
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ // Get any Modula 3 exception classes in the throws typemap
+ ParmList *throw_parm_list = NULL;
+ if ((throw_parm_list = Getattr(n, "catchlist"))) {
+ Swig_typemap_attach_parms("throws", throw_parm_list, f);
+ Parm *p;
+ for (p = throw_parm_list; p; p = nextSibling(p)) {
+ addThrows(throws_hash, "throws", p);
+ }
+ }
+
+ if (Cmp(nodeType(n), "constant") == 0) {
+ // Wrapping a constant hack
+ Swig_save("functionWrapper", n, "wrap:action", NIL);
+
+ // below based on Swig_VargetToFunction()
+ SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n));
+ Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value")));
+ }
+
+ Setattr(n, "wrap:name", wname);
+
+ // Now write code to make the function call
+ if (!native_function_flag) {
+ String *actioncode = emit_action(n);
+
+ if (Cmp(nodeType(n), "constant") == 0) {
+ Swig_restore(n);
+ }
+
+ /* Return value if necessary */
+ String *tm;
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ addThrows(throws_hash, "out", n);
+ Replaceall(tm, "$source", "result"); /* deprecated */
+ Replaceall(tm, "$target", "cresult"); /* deprecated */
+ Replaceall(tm, "$result", "cresult");
+ Printf(f->code, "%s", tm);
+ if (hasContent(tm))
+ Printf(f->code, "\n");
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), rawname);
+ }
+ emit_return_variable(n, t, f);
+ }
+
+ /* 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 (GetFlag(n, "feature:new")) {
+ String *tm = Swig_typemap_lookup("newfree", n, "result", 0);
+ if (tm != NIL) {
+ addThrows(throws_hash, "newfree", n);
+ Replaceall(tm, "$source", "result"); /* deprecated */
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ /* See if there is any return cleanup code */
+ if (!native_function_flag) {
+ String *tm = Swig_typemap_lookup("ret", n, "result", 0);
+ if (tm != NIL) {
+ Replaceall(tm, "$source", "result"); /* deprecated */
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ /* Finish C wrapper */
+ Printf(f->def, ") {");
+
+ if (!is_void_return)
+ Printv(f->code, " return cresult;\n", NIL);
+ Printf(f->code, "}\n");
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code, "$cleanup", cleanup);
+
+ /* Substitute the function name */
+ Replaceall(f->code, "$symname", symname);
+
+ 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);
+ }
+
+ Delete(c_return_type);
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(body);
+ Delete(throws_hash);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * emitM3RawPrototype()
+ *
+ * Generate an EXTERNAL procedure declaration in Modula 3
+ * which is the interface to an existing C routine or a C wrapper.
+ * ---------------------------------------------------------------------- */
+
+ virtual int emitM3RawPrototype(Node *n, const String *cname, const String *m3name) {
+ String *im_return_type = NewString("");
+ //String *symname = Getattr(n,"sym:name");
+ ParmList *l = Getattr(n, "parms");
+
+ /* Attach the non-standard typemaps to the parameter list. */
+ Swig_typemap_attach_parms("m3rawinmode", l, NULL);
+ Swig_typemap_attach_parms("m3rawintype", l, NULL);
+
+ /* Get return types */
+ bool has_return;
+ {
+ String *tm = getMappedTypeNew(n, "m3rawrettype", "");
+ if (tm != NIL) {
+ Printf(im_return_type, "%s", tm);
+ }
+ has_return = hasContent(tm);
+ }
+
+ /* cname is the original name if 'n' denotes a C function
+ and it is the relabeled name (sym:name) if 'n' denotes a C++ method or similar */
+ m3raw_intf.enterBlock(no_block);
+ Printf(m3raw_intf.f, "\n<* EXTERNAL %s *>\nPROCEDURE %s (", cname, m3name);
+
+ // Generate signature for raw interface
+ {
+ Parm *p;
+ writeArgState state;
+ attachParameterNames(n, "tmap:rawinname", "modula3:rawname", "arg%d");
+ for (p = skipIgnored(l, "m3rawintype"); p != NULL; p = skipIgnored(p, "m3rawintype")) {
+
+ /* Get argument passing mode, should be one of VALUE, VAR, READONLY */
+ String *mode = Getattr(p, "tmap:m3rawinmode");
+ String *argname = Getattr(p, "modula3:rawname");
+ String *im_param_type = getMappedType(p, "m3rawintype");
+ addImports(m3raw_intf.import, "m3rawintype", p);
+
+ writeArg(m3raw_intf.f, state, mode, argname, im_param_type, NIL);
+ if (im_param_type != NIL) {
+ p = Getattr(p, "tmap:m3rawintype:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ writeArg(m3raw_intf.f, state, NIL, NIL, NIL, NIL);
+ }
+
+ /* Finish M3 raw prototype */
+ Printf(m3raw_intf.f, ")");
+ // neither a C wrapper nor a plain C function may throw an exception
+ //generateThrowsClause(throws_hash, m3raw_intf.f);
+ if (has_return) {
+ Printf(m3raw_intf.f, ": %s", im_return_type);
+ }
+ Printf(m3raw_intf.f, ";\n");
+
+ Delete(im_return_type);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * variableWrapper()
+ * ----------------------------------------------------------------------- */
+
+ virtual int variableWrapper(Node *n) {
+ Language::variableWrapper(n);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * globalvariableHandler()
+ * ----------------------------------------------------------------------- */
+
+ virtual int globalvariableHandler(Node *n) {
+ SwigType *t = Getattr(n, "type");
+ String *tm;
+
+ // Get the variable type
+ if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
+ substituteClassname(t, tm);
+ }
+
+ variable_name = Getattr(n, "sym:name");
+ variable_type = Copy(tm);
+
+ // Get the variable type expressed in terms of Modula 3 equivalents of C types
+ if ((tm = getMappedTypeNew(n, "m3rawtype", ""))) {
+ m3raw_intf.enterBlock(no_block);
+ Printf(m3raw_intf.f, "\n<* EXTERNAL *> VAR %s: %s;\n", variable_name, tm);
+ }
+ // Output the property's accessor methods
+ /*
+ global_variable_flag = true;
+ int ret = Language::globalvariableHandler(n);
+ global_variable_flag = false;
+ */
+
+ Printf(m3wrap_impl.f, "\n\n");
+
+ //return ret;
+ return 1;
+ }
+
+ long getConstNumeric(Node *n) {
+ String *constnumeric = Getfeature(n, "constnumeric");
+ String *name = Getattr(n, "name");
+ long numvalue;
+ if (constnumeric == NIL) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Feature 'constnumeric' is necessary to obtain value of %s.\n", name);
+ return 0;
+ } else if (!strToL(constnumeric, numvalue)) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number,
+ "The feature 'constnumeric' of %s specifies value <%s> which is not an integer constant.\n", name, constnumeric);
+ return 0;
+ } else {
+ return numvalue;
+ }
+ }
+
+ /* ------------------------------------------------------------------------
+ * generateIntConstant()
+ *
+ * Considers node as an integer constant definition
+ * and generate a Modula 3 constant definition.
+ * ------------------------------------------------------------------------ */
+ void generateIntConstant(Node *n, String *name) {
+ String *value = Getattr(n, "value");
+ String *type = Getfeature(n, "modula3:constint:type");
+ String *conv = Getfeature(n, "modula3:constint:conv");
+
+ if (name == NIL) {
+ name = Getattr(n, "sym:name");
+ }
+
+ long numvalue;
+ bool isSimpleNum = strToL(value, numvalue);
+ if (!isSimpleNum) {
+ numvalue = getConstNumeric(n);
+ }
+
+ String *m3value;
+ if ((conv == NIL) || ((Strcmp(conv, "set:int") != 0) && (Strcmp(conv, "int:set") != 0))) {
+ /* The original value of the constant has precedence over
+ 'constnumeric' feature since we like to keep
+ the style (that is the base) of simple numeric constants */
+ if (isSimpleNum) {
+ if (hasPrefix(value, "0x")) {
+ m3value = NewStringf("16_%s", Char(value) + 2);
+ } else if ((Len(value) > 1) && (*Char(value) == '0')) {
+ m3value = NewStringf("8_%s", Char(value) + 1);
+ } else {
+ m3value = Copy(value);
+ }
+ /* If we cannot easily obtain the value of a numeric constant,
+ we use the results given by a C compiler. */
+ } else {
+ m3value = Copy(Getfeature(n, "constnumeric"));
+ }
+ } else {
+ // if the value can't be converted, it is ignored
+ if (convertInt(numvalue, numvalue, conv)) {
+ m3value = NewStringf("%d", numvalue);
+ } else {
+ m3value = NIL;
+ }
+ }
+
+ if (m3value != NIL) {
+ m3wrap_intf.enterBlock(constant);
+ Printf(m3wrap_intf.f, "%s", name);
+ if (hasContent(type)) {
+ Printf(m3wrap_intf.f, ": %s", type);
+ }
+ Printf(m3wrap_intf.f, " = %s;\n", m3value);
+ Delete(m3value);
+ }
+ }
+
+ /* -----------------------------------------------------------------------
+ * generateSetConstant()
+ *
+ * Considers node as a set constant definition
+ * and generate a Modula 3 constant definition.
+ * ------------------------------------------------------------------------ */
+ void generateSetConstant(Node *n, String *name) {
+ String *value = Getattr(n, "value");
+ String *type = Getfeature(n, "modula3:constset:type");
+ String *setname = Getfeature(n, "modula3:constset:set");
+ String *basename = Getfeature(n, "modula3:constset:base");
+ String *conv = Getfeature(n, "modula3:constset:conv");
+
+ m3wrap_intf.enterBlock(constant);
+
+ Printf(m3wrap_intf.f, "%s", name);
+ if (type != NIL) {
+ Printf(m3wrap_intf.f, ":%s ", type);
+ }
+ Printf(m3wrap_intf.f, " = %s{", setname);
+
+ long numvalue = 0;
+ if (!strToL(value, numvalue)) {
+ numvalue = getConstNumeric(n);
+ }
+ convertInt(numvalue, numvalue, conv);
+
+ bool isIntType = Strcmp(basename, "CARDINAL") == 0;
+ Hash *items = NIL;
+ if (!isIntType) {
+ Hash *enumeration = Getattr(enumeration_coll, basename);
+ if (enumeration == NIL) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "There is no enumeration <%s> as needed for the set.\n", setname);
+ isIntType = true;
+ } else {
+ items = Getattr(enumeration, "items");
+ }
+ }
+
+ bool gencomma = false;
+ int bitpos = 0;
+ while (numvalue > 0) {
+ if ((numvalue & 1) != 0) {
+ if (isIntType) {
+ if (gencomma) {
+ Printv(m3wrap_intf.f, ",", NIL);
+ }
+ gencomma = true;
+ Printf(m3wrap_intf.f, "%d", bitpos);
+ } else {
+ char bitval[15];
+ sprintf(bitval, "%d", bitpos);
+ String *bitname = Getattr(items, bitval);
+ if (bitname == NIL) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Enumeration <%s> has no value <%s>.\n", setname, bitval);
+ } else {
+ if (gencomma) {
+ Printv(m3wrap_intf.f, ",", NIL);
+ }
+ gencomma = true;
+ Printf(m3wrap_intf.f, "%s.%s", basename, bitname);
+ }
+ }
+ }
+ numvalue >>= 1;
+ bitpos++;
+ }
+ Printf(m3wrap_intf.f, "};\n");
+ }
+
+ void generateConstant(Node *n) {
+ // any of the special interpretation disables the default behaviour
+ String *enumitem = Getfeature(n, "modula3:enumitem:name");
+ String *constset = Getfeature(n, "modula3:constset:name");
+ String *constint = Getfeature(n, "modula3:constint:name");
+ if (hasContent(enumitem) || hasContent(constset) || hasContent(constint)) {
+ if (hasContent(constset)) {
+ generateSetConstant(n, constset);
+ }
+ if (hasContent(constint)) {
+ generateIntConstant(n, constint);
+ }
+ } else {
+ String *value = Getattr(n, "value");
+ String *name = Getattr(n, "sym:name");
+ if (name == NIL) {
+ name = Getattr(n, "name");
+ }
+ m3wrap_intf.enterBlock(constant);
+ Printf(m3wrap_intf.f, "%s = %s;\n", name, value);
+ }
+ }
+
+#if 0
+ void generateEnumerationItem(const String *name, const String *value, int numvalue) {
+ String *oldsymname = Getattr(enumeration_items, value);
+ if (oldsymname != NIL) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "The value <%s> is already assigned to <%s>.\n", value, oldsymname);
+ }
+ Setattr(enumeration_items, value, name);
+ if (enumeration_max < numvalue) {
+ enumeration_max = numvalue;
+ }
+ }
+#endif
+
+ void emitEnumeration(File *file, String *name, Node *n) {
+ Printf(file, "%s = {", name);
+ int i;
+ bool gencomma = false;
+ int max = aToL(Getattr(n, "max"));
+ Hash *items = Getattr(n, "items");
+ for (i = 0; i <= max; i++) {
+ if (gencomma) {
+ Printf(file, ",");
+ }
+ Printf(file, "\n");
+ gencomma = true;
+ char numstr[15];
+ sprintf(numstr, "%d", i);
+ String *name = Getattr(items, numstr);
+ if (name != NIL) {
+ Printv(file, name, NIL);
+ } else {
+ Printf(file, "Dummy%d", i);
+ }
+ }
+ Printf(file, "\n};\n");
+ }
+
+ /* -----------------------------------------------------------------------
+ * constantWrapper()
+ *
+ * Handles constants and enumeration items.
+ * ------------------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ generateConstant(n);
+ return SWIG_OK;
+ }
+
+#if 0
+// enumerations are handled like constant definitions
+ /* -----------------------------------------------------------------------------
+ * enumDeclaration()
+ * ----------------------------------------------------------------------------- */
+
+ virtual int enumDeclaration(Node *n) {
+ String *symname = nameToModula3(Getattr(n, "sym:name"), true);
+ enumerationStart(symname);
+ int result = Language::enumDeclaration(n);
+ enumerationStop();
+ Delete(symname);
+ return result;
+ }
+#endif
+
+ /* -----------------------------------------------------------------------------
+ * enumvalueDeclaration()
+ * ----------------------------------------------------------------------------- */
+
+ virtual int enumvalueDeclaration(Node *n) {
+ generateConstant(n);
+ /*
+ This call would continue processing in the constantWrapper
+ which cannot handle values like "RED+1".
+ return Language::enumvalueDeclaration(n);
+ */
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * pragmaDirective()
+ *
+ * Valid Pragmas:
+ * imclassbase - base (extends) for the intermediary class
+ * imclassclassmodifiers - class modifiers for the intermediary class
+ * imclasscode - text (Modula 3 code) is copied verbatim to the intermediary class
+ * imclassimports - import statements for the intermediary class
+ * imclassinterfaces - interface (implements) for the intermediary class
+ *
+ * modulebase - base (extends) for the module class
+ * moduleclassmodifiers - class modifiers for the module class
+ * modulecode - text (Modula 3 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, "modula3") == 0) {
+
+ String *strvalue = NewString(value);
+ Replaceall(strvalue, "\\\"", "\"");
+/*
+ bool isEnumItem = Strcmp(code, "enumitem") == 0;
+ bool isSetItem = Strcmp(code, "setitem") == 0;
+*/
+ if (Strcmp(code, "imclassbase") == 0) {
+ Delete(m3raw_baseclass);
+ m3raw_baseclass = Copy(strvalue);
+ } else if (Strcmp(code, "imclassclassmodifiers") == 0) {
+ Delete(m3raw_class_modifiers);
+ m3raw_class_modifiers = Copy(strvalue);
+ } else if (Strcmp(code, "imclasscode") == 0) {
+ Printf(m3raw_intf.f, "%s\n", strvalue);
+ } else if (Strcmp(code, "imclassimports") == 0) {
+ Delete(m3raw_imports);
+ m3raw_imports = Copy(strvalue);
+ } else if (Strcmp(code, "imclassinterfaces") == 0) {
+ Delete(m3raw_interfaces);
+ m3raw_interfaces = Copy(strvalue);
+ } else if (Strcmp(code, "modulebase") == 0) {
+ Delete(module_baseclass);
+ module_baseclass = Copy(strvalue);
+ } else if (Strcmp(code, "moduleclassmodifiers") == 0) {
+ Delete(m3wrap_modifiers);
+ m3wrap_modifiers = Copy(strvalue);
+ } else if (Strcmp(code, "modulecode") == 0) {
+ Printf(m3wrap_impl.f, "%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, "unsafe") == 0) {
+ unsafe_module = true;
+ } else if (Strcmp(code, "library") == 0) {
+ if (targetlibrary != NULL) {
+ Delete(targetlibrary);
+ }
+ targetlibrary = Copy(strvalue);
+ } else if (Strcmp(code, "enumitem") == 0) {
+ } else if (Strcmp(code, "constset") == 0) {
+ } else if (Strcmp(code, "constint") == 0) {
+ } else if (Strcmp(code, "makesetofenum") == 0) {
+ m3wrap_intf.enterBlock(blocktype);
+ Printf(m3wrap_intf.f, "%sSet = SET OF %s;\n", value, value);
+ } else {
+ Swig_warning(WARN_MODULA3_UNKNOWN_PRAGMA, input_file, line_number, "Unrecognized pragma <%s>.\n", code);
+ }
+ Delete(strvalue);
+ }
+ }
+ return Language::pragmaDirective(n);
+ }
+
+ void Setfeature(Node *n, const char *feature, const String *value, bool warn = false) {
+ //printf("tag feature <%s> with value <%s>\n", feature, Char(value));
+ String *attr = NewStringf("feature:%s", feature);
+ if ((Setattr(n, attr, value) != 0) && warn) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Feature <%s> of %s did already exist.\n", feature, Getattr(n, "name"));
+ }
+ Delete(attr);
+ }
+
+ String *Getfeature(Node *n, const char *feature) {
+ //printf("retrieve feature <%s> with value <%s>\n", feature, Char(value));
+ String *attr = NewStringf("feature:%s", feature);
+ String *result = Getattr(n, attr);
+ Delete(attr);
+ return result;
+ }
+
+ bool convertInt(long in, long &out, const String *mode) {
+ if ((mode == NIL) || (Strcmp(mode, "int:int") == 0) || (Strcmp(mode, "set:set") == 0)) {
+ out = in;
+ return true;
+ } else if (Strcmp(mode, "set:int") == 0) {
+ return log2(in, out);
+ } else if (Strcmp(mode, "int:set") == 0) {
+ out = 1L << in;
+ return unsigned (in) < (sizeof(out) * 8);
+ } else {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown integer conversion method <%s>.\n", mode);
+ return false;
+ }
+ }
+
+ void collectEnumerations(Hash *enums, Node *n) {
+ Node *child = firstChild(n);
+ while (child != NIL) {
+ String *name = Getattr(child, "name");
+ const bool isConstant = Strcmp(nodeType(child), "constant") == 0;
+ const bool isEnumItem = Strcmp(nodeType(child), "enumitem") == 0;
+ if (isConstant || isEnumItem) {
+//printf("%s%s name %s\n", isConstant?"constant":"", isEnumItem?"enumitem":"", Char(name));
+ {
+ String *m3name = Getfeature(child, "modula3:enumitem:name");
+ String *m3enum = Getfeature(child, "modula3:enumitem:enum");
+ String *conv = Getfeature(child, "modula3:enumitem:conv");
+
+ if (m3enum != NIL) {
+//printf("m3enum %s\n", Char(m3enum));
+ if (m3name == NIL) {
+ m3name = name;
+ }
+
+ long max = -1;
+ Hash *items;
+ Hash *enumnode = Getattr(enums, m3enum);
+ if (enumnode == NIL) {
+ enumnode = NewHash();
+ items = NewHash();
+ Setattr(enumnode, "items", items);
+ Setattr(enums, m3enum, enumnode);
+ } else {
+ String *maxstr = Getattr(enumnode, "max");
+ if (maxstr != NIL) {
+ max = aToL(maxstr);
+ }
+ items = Getattr(enumnode, "items");
+ }
+ long numvalue;
+ String *value = Getattr(child, "value");
+//printf("value: %s\n", Char(value));
+ if ((value == NIL) || (!strToL(value, numvalue))) {
+ value = Getattr(child, "enumvalue");
+ if ((value == NIL) || (!evalExpr(value, numvalue))) {
+ numvalue = getConstNumeric(child);
+ }
+//printf("constnumeric: %s\n", Char(value));
+ }
+ Setattr(constant_values, name, NewStringf("%d", numvalue));
+ if (convertInt(numvalue, numvalue, conv)) {
+ String *newvalue = NewStringf("%d", numvalue);
+ String *oldname = Getattr(items, newvalue);
+ if (oldname != NIL) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "The value <%s> is already assigned to <%s>.\n", value, oldname);
+ }
+//printf("items %lx, set %s = %s\n", (long) items, Char(newvalue), Char(m3name));
+ Setattr(items, newvalue, m3name);
+ if (max < numvalue) {
+ max = numvalue;
+ }
+ Setattr(enumnode, "max", NewStringf("%d", max));
+ }
+ }
+ }
+ }
+
+ collectEnumerations(enums, child);
+ child = nextSibling(child);
+ }
+ }
+
+ enum const_pragma_type { cpt_none, cpt_constint, cpt_constset, cpt_enumitem };
+
+ struct const_id_pattern {
+ String *prefix, *parentEnum;
+ };
+
+ void tagConstants(Node *first, String *parentEnum, const const_id_pattern & pat, const String *pragma, List *convdesc) {
+ Node *n = first;
+ while (n != NIL) {
+ String *name = getQualifiedName(n);
+ bool isConstant = Strcmp(nodeType(n), "constant") == 0;
+ bool isEnumItem = Strcmp(nodeType(n), "enumitem") == 0;
+ if ((isConstant || isEnumItem) && ((pat.prefix == NIL) || (hasPrefix(name, pat.prefix))) && ((pat.parentEnum == NIL) || ((parentEnum != NIL)
+ &&
+ (Strcmp
+ (pat.parentEnum, parentEnum)
+ == 0)))) {
+ //printf("tag %s\n", Char(name));
+ String *srctype = Getitem(convdesc, 1);
+ String *relationstr = Getitem(convdesc, 3);
+ List *relationdesc = Split(relationstr, ',', 2);
+
+ // transform name from C to Modula3 style
+ String *srcstyle = NIL;
+ String *newprefix = NIL;
+ {
+ //printf("name conversion <%s>\n", Char(Getitem(convdesc,2)));
+ List *namedesc = Split(Getitem(convdesc, 2), ',', INT_MAX);
+ Iterator nameit = First(namedesc);
+ for (; nameit.item != NIL; nameit = Next(nameit)) {
+ List *nameassign = Split(nameit.item, '=', 2);
+ String *tag = Getitem(nameassign, 0);
+ String *data = Getitem(nameassign, 1);
+ //printf("name conv <%s> = <%s>\n", Char(tag), Char(data));
+ if (Strcmp(tag, "srcstyle") == 0) {
+ srcstyle = Copy(data);
+ } else if (Strcmp(tag, "prefix") == 0) {
+ newprefix = Copy(data);
+ } else {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown name conversion tag <%s> with value <%s>.\n", tag, data);
+ }
+ Delete(nameassign);
+ }
+ Delete(namedesc);
+ }
+ const char *stem = Char(name);
+ if (pat.prefix != NIL) {
+ //printf("pat.prefix %s for %s\n", Char(pat.prefix), Char(name));
+ stem += Len(pat.prefix);
+ }
+ String *newname;
+ if (Strcmp(srcstyle, "underscore") == 0) {
+ if (newprefix != NIL) {
+ String *newstem = nameToModula3(stem, true);
+ newname = NewStringf("%s%s", newprefix, newstem);
+ Delete(newstem);
+ } else {
+ newname = nameToModula3(stem, true);
+ }
+ } else {
+ if (srcstyle != NIL) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown C identifier style <%s>.\n", srcstyle);
+ }
+ newname = Copy(name);
+ }
+
+ if (Strcmp(pragma, "enumitem") == 0) {
+ if (Len(relationdesc) != 1) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Expected <enumeration>, got <%s>.\n", relationstr);
+ }
+ Setfeature(n, "modula3:enumitem:name", newname, true);
+ Setfeature(n, "modula3:enumitem:enum", relationstr, true);
+ Setfeature(n, "modula3:enumitem:conv", NewStringf("%s:int", srctype), true);
+ } else if (Strcmp(pragma, "constint") == 0) {
+ if (Len(relationdesc) != 1) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Expected <ordinal type>, got <%s>.\n", relationstr);
+ }
+ Setfeature(n, "modula3:constint:name", newname, true);
+ Setfeature(n, "modula3:constint:type", Getitem(relationdesc, 0), true);
+ Setfeature(n, "modula3:constint:conv", NewStringf("%s:int", srctype), true);
+ } else if (Strcmp(pragma, "constset") == 0) {
+ if (Len(relationdesc) != 2) {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Expected <set type,base type>, got <%s>.\n", relationstr);
+ }
+ String *settype = Getitem(relationdesc, 0);
+ Setfeature(n, "modula3:constset:name", newname, true);
+ //Setfeature(n,"modula3:constset:type",settype,true);
+ Setfeature(n, "modula3:constset:set", settype, true);
+ Setfeature(n, "modula3:constset:base", Getitem(relationdesc, 1), true);
+ Setfeature(n, "modula3:constset:conv", NewStringf("%s:set", srctype), true);
+ }
+
+ Delete(newname);
+ Delete(relationdesc);
+ }
+
+ if (Strcmp(nodeType(n), "enum") == 0) {
+ //printf("explore enum %s, qualification %s\n", Char(name), Char(Swig_symbol_qualified(n)));
+ tagConstants(firstChild(n), name, pat, pragma, convdesc);
+ } else {
+ tagConstants(firstChild(n), NIL, pat, pragma, convdesc);
+ }
+ n = nextSibling(n);
+ }
+ }
+
+ void scanForConstPragmas(Node *n) {
+ Node *child = firstChild(n);
+ while (child != NIL) {
+ const String *type = nodeType(child);
+ if (Strcmp(type, "pragma") == 0) {
+ const String *lang = Getattr(child, "lang");
+ const String *code = Getattr(child, "name");
+ String *value = Getattr(child, "value");
+
+ if (Strcmp(lang, "modula3") == 0) {
+ const_pragma_type cpt = cpt_none;
+ if (Strcmp(code, "constint") == 0) {
+ cpt = cpt_constint;
+ } else if (Strcmp(code, "constset") == 0) {
+ cpt = cpt_constset;
+ } else if (Strcmp(code, "enumitem") == 0) {
+ cpt = cpt_enumitem;
+ }
+ if (cpt != cpt_none) {
+ const_id_pattern pat = { NIL, NIL };
+
+ List *convdesc = Split(value, ';', 4);
+ List *patterndesc = Split(Getitem(convdesc, 0), ',', INT_MAX);
+ Iterator patternit;
+ for (patternit = First(patterndesc); patternit.item != NIL; patternit = Next(patternit)) {
+ List *patternassign = Split(patternit.item, '=', 2);
+ String *tag = Getitem(patternassign, 0);
+ String *data = Getitem(patternassign, 1);
+ if (Strcmp(tag, "prefix") == 0) {
+ pat.prefix = Copy(data);
+ } else if (Strcmp(tag, "enum") == 0) {
+ pat.parentEnum = Copy(data);
+ } else {
+ Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown identification tag <%s> with value <%s>.\n", tag, data);
+ }
+ Delete(patternassign);
+ }
+ tagConstants(child, NIL, pat, code, convdesc);
+
+ Delete(patterndesc);
+ }
+ }
+ }
+ scanForConstPragmas(child);
+ child = nextSibling(child);
+ }
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitProxyClassDefAndCPPCasts()
+ * ----------------------------------------------------------------------------- */
+
+ void emitProxyClassDefAndCPPCasts(Node *n) {
+ String *c_classname = SwigType_namestr(Getattr(n, "name"));
+ String *c_baseclass = NULL;
+ String *baseclass = NULL;
+ String *c_baseclassname = NULL;
+ String *classDeclarationName = Getattr(n, "classDeclaration:name");
+
+ /* Deal with inheritance */
+ List *baselist = Getattr(n, "bases");
+ if (baselist != NIL) {
+ Iterator base = First(baselist);
+ c_baseclassname = Getattr(base.item, "name");
+ baseclass = Copy(getProxyName(c_baseclassname));
+ if (baseclass) {
+ c_baseclass = SwigType_namestr(Getattr(base.item, "name"));
+ }
+ base = Next(base);
+ if (base.item != NIL) {
+ Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file,
+ line_number,
+ "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n",
+ classDeclarationName, Getattr(base.item, "name"));
+ }
+ }
+
+ bool derived = baseclass && getProxyName(c_baseclassname);
+ if (!baseclass)
+ baseclass = NewString("");
+
+ // Inheritance from pure Modula 3 classes
+ const String *pure_baseclass = typemapLookup(n, "m3base", classDeclarationName, WARN_NONE);
+ if (hasContent(pure_baseclass) && hasContent(baseclass)) {
+ Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file,
+ line_number,
+ "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", classDeclarationName, pure_baseclass);
+ }
+ // Pure Modula 3 interfaces
+ const String *pure_interfaces = typemapLookup(n, derived ? "m3interfaces_derived" : "m3interfaces",
+ classDeclarationName, WARN_NONE);
+
+ // Start writing the proxy class
+ Printv(proxy_class_def, typemapLookup(n, "m3imports", classDeclarationName, WARN_NONE), // Import statements
+ "\n", typemapLookup(n, "m3classmodifiers", classDeclarationName, WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
+ " class $m3classname", // Class name and bases
+ (derived || *Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", baseclass, pure_baseclass, ((derived || *Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces
+ ", " : "", pure_interfaces, " {\n", " private IntPtr swigCPtr;\n", // Member variables for memory handling
+ derived ? "" : " protected bool swigCMemOwn;\n", "\n", " ", typemapLookup(n, "m3ptrconstructormodifiers", classDeclarationName, WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers
+ " $m3classname(IntPtr cPtr, bool cMemoryOwn) ", // Constructor used for wrapping pointers
+ derived ?
+ ": base($imclassname.$m3classnameTo$baseclass(cPtr), cMemoryOwn) {\n"
+ : "{\n swigCMemOwn = cMemoryOwn;\n", " swigCPtr = cPtr;\n", " }\n", NIL);
+
+ if (!have_default_constructor_flag) { // All proxy classes need a constructor
+ Printv(proxy_class_def, "\n", " protected $m3classname() : this(IntPtr.Zero, false) {\n", " }\n", NIL);
+ }
+ // C++ destructor is wrapped by the Dispose method
+ // Note that the method name is specified in a typemap attribute called methodname
+ String *destruct = NewString("");
+ const String *tm = NULL;
+ Node *attributes = NewHash();
+ String *destruct_methodname = NULL;
+ if (derived) {
+ tm = typemapLookup(n, "m3destruct_derived", classDeclarationName, WARN_NONE, attributes);
+ destruct_methodname = Getattr(attributes, "tmap:m3destruct_derived:methodname");
+ } else {
+ tm = typemapLookup(n, "m3destruct", classDeclarationName, WARN_NONE, attributes);
+ destruct_methodname = Getattr(attributes, "tmap:m3destruct:methodname");
+ }
+ if (!destruct_methodname) {
+ Swig_error(input_file, line_number, "No methodname attribute defined in m3destruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
+ }
+ // Emit the Finalize and Dispose methods
+ if (tm) {
+ // Finalize method
+ if (*Char(destructor_call)) {
+ Printv(proxy_class_def, typemapLookup(n, "m3finalize", classDeclarationName, WARN_NONE), NIL);
+ }
+ // Dispose method
+ Printv(destruct, tm, NIL);
+ if (*Char(destructor_call))
+ Replaceall(destruct, "$imcall", destructor_call);
+ else
+ Replaceall(destruct, "$imcall", "throw new MethodAccessException(\"C++ destructor does not have public access\")");
+ if (*Char(destruct))
+ Printv(proxy_class_def, "\n public ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n", NIL);
+ }
+ Delete(attributes);
+ Delete(destruct);
+
+ // Emit various other methods
+ Printv(proxy_class_def, typemapLookup(n, "m3getcptr", classDeclarationName, WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF), // getCPtr method
+ typemapLookup(n, "m3code", classDeclarationName, WARN_NONE), // extra Modula 3 code
+ "\n", NIL);
+
+ // Substitute various strings into the above template
+ Replaceall(proxy_class_def, "$m3classname", proxy_class_name);
+ Replaceall(proxy_class_code, "$m3classname", proxy_class_name);
+
+ Replaceall(proxy_class_def, "$baseclass", baseclass);
+ Replaceall(proxy_class_code, "$baseclass", baseclass);
+
+ Replaceall(proxy_class_def, "$imclassname", m3raw_name);
+ Replaceall(proxy_class_code, "$imclassname", m3raw_name);
+
+ // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
+ if (derived) {
+ Printv(m3raw_cppcasts_code, "\n [DllImport(\"", m3wrap_name, "\", EntryPoint=\"Modula3_", proxy_class_name, "To", baseclass, "\")]\n", NIL);
+ Printv(m3raw_cppcasts_code, " public static extern IntPtr ", "$m3classnameTo$baseclass(IntPtr objectRef);\n", NIL);
+
+ Replaceall(m3raw_cppcasts_code, "$m3classname", proxy_class_name);
+ Replaceall(m3raw_cppcasts_code, "$baseclass", baseclass);
+
+ Printv(upcasts_code,
+ "SWIGEXPORT long Modula3_$imclazznameTo$imbaseclass",
+ "(long objectRef) {\n",
+ " long baseptr = 0;\n" " *($cbaseclass **)&baseptr = *($cclass **)&objectRef;\n" " return baseptr;\n" "}\n", "\n", NIL);
+
+ Replaceall(upcasts_code, "$imbaseclass", baseclass);
+ Replaceall(upcasts_code, "$cbaseclass", c_baseclass);
+ Replaceall(upcasts_code, "$imclazzname", proxy_class_name);
+ Replaceall(upcasts_code, "$cclass", c_classname);
+ }
+ Delete(baseclass);
+ }
+
+ /* ----------------------------------------------------------------------
+ * getAttrString()
+ *
+ * If necessary create and return the string
+ * associated with a certain attribute of 'n'.
+ * ---------------------------------------------------------------------- */
+
+ String *getAttrString(Node *n, const char *attr) {
+ String *str = Getattr(n, attr);
+ if (str == NIL) {
+ str = NewString("");
+ Setattr(n, attr, str);
+ }
+ return str;
+ }
+
+ /* ----------------------------------------------------------------------
+ * getMethodDeclarations()
+ *
+ * If necessary create and return the handle
+ * where the methods of the current access can be written to.
+ * 'n' must be a member of a struct or a class.
+ * ---------------------------------------------------------------------- */
+
+ String *getMethodDeclarations(Node *n) {
+ String *acc_str = Getattr(n, "access");
+ String *methodattr;
+ if (acc_str == NIL) {
+ methodattr = NewString("modula3:method:public");
+ } else {
+ methodattr = NewStringf("modula3:method:%s", acc_str);
+ }
+ String *methods = getAttrString(parentNode(n), Char(methodattr));
+ Delete(methodattr);
+ return methods;
+ }
+
+ /* ----------------------------------------------------------------------
+ * classHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int classHandler(Node *n) {
+
+ File *f_proxy = NULL;
+ proxy_class_name = Copy(Getattr(n, "sym:name"));
+ //String *rawname = Getattr(n,"name");
+
+ if (proxy_flag) {
+ if (!addSymbol(proxy_class_name, n))
+ return SWIG_ERROR;
+
+ if (Cmp(proxy_class_name, m3raw_name) == 0) {
+ Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ if (Cmp(proxy_class_name, m3wrap_name) == 0) {
+ Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ String *filen = NewStringf("%s%s.m3", Swig_file_dirname(outfile), proxy_class_name);
+ f_proxy = NewFile(filen, "w", SWIG_output_files());
+ if (!f_proxy) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(filen);
+ filen = NULL;
+
+ emitBanner(f_proxy);
+
+ Clear(proxy_class_def);
+ Clear(proxy_class_code);
+
+ have_default_constructor_flag = false;
+ destructor_call = NewString("");
+ }
+
+ /* This will invoke memberfunctionHandler, membervariableHandler ...
+ and finally it may invoke functionWrapper
+ for wrappers and member variable accessors.
+ It will invoke Language:constructorDeclaration
+ which decides whether to call MODULA3::constructorHandler */
+ Language::classHandler(n);
+
+ {
+ String *kind = Getattr(n, "kind");
+ if (Cmp(kind, "struct") == 0) {
+ String *entries = NewString("");
+ Node *child;
+ writeArgState state;
+ for (child = firstChild(n); child != NIL; child = nextSibling(child)) {
+ String *childType = nodeType(child);
+ if (Strcmp(childType, "cdecl") == 0) {
+ String *member = Getattr(child, "sym:name");
+ ParmList *pl = Getattr(child, "parms");
+ if (pl == NIL) {
+ // Get the variable type in Modula 3 type equivalents
+ String *m3ct = getMappedTypeNew(child, "m3rawtype", "");
+
+ writeArg(entries, state, NIL, member, m3ct, NIL);
+ }
+ }
+ }
+ writeArg(entries, state, NIL, NIL, NIL, NIL);
+
+ m3raw_intf.enterBlock(blocktype);
+ Printf(m3raw_intf.f, "%s =\nRECORD\n%sEND;\n", proxy_class_name, entries);
+
+ Delete(entries);
+
+ } else if (Cmp(kind, "class") == 0) {
+ enum access_privilege { acc_public, acc_protected, acc_private };
+ int max_acc = acc_public;
+
+ const char *acc_name[3] = { "public", "protected", "private" };
+ String *methods[3];
+ int acc;
+ for (acc = acc_public; acc <= acc_private; acc++) {
+ String *methodattr = NewStringf("modula3:method:%s", acc_name[acc]);
+ methods[acc] = Getattr(n, methodattr);
+ Delete(methodattr);
+ max_acc = max_acc > acc ? max_acc : acc;
+ }
+
+ /* Determine the name of the base class */
+ String *baseclassname = NewString("");
+ {
+ List *baselist = Getattr(n, "bases");
+ if (baselist) {
+ /* Look for the first (principal?) base class -
+ Modula 3 does not support multiple inheritance */
+ Iterator base = First(baselist);
+ Append(baseclassname, Getattr(base.item, "sym:name"));
+ base = Next(base);
+ if (base.item != NIL) {
+ Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, input_file,
+ line_number,
+ "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n",
+ proxy_class_name, Getattr(base.item, "name"));
+ }
+ }
+ }
+
+ /* the private class of the base class and only this
+ need a pointer to the C++ object */
+ bool need_private = !hasContent(baseclassname);
+ max_acc = need_private ? acc_private : max_acc;
+
+ /* Declare C++ object as abstract pointer in Modula 3 */
+ /* The revelation system does not allow us
+ to imitate the whole class hierarchy of the C++ library,
+ but at least we can distinguish between classes of different roots. */
+ if (hasContent(baseclassname)) {
+ m3raw_intf.enterBlock(blocktype);
+ Printf(m3raw_intf.f, "%s = %s;\n", proxy_class_name, baseclassname);
+ } else {
+ m3raw_intf.enterBlock(blocktype);
+ Printf(m3raw_intf.f, "%s <: ADDRESS;\n", proxy_class_name);
+ m3raw_impl.enterBlock(revelation);
+ Printf(m3raw_impl.f, "%s = UNTRACED BRANDED REF RECORD (*Dummy*) END;\n", proxy_class_name);
+ }
+
+ String *superclass;
+ m3wrap_intf.enterBlock(blocktype);
+ if (hasContent(methods[acc_public])) {
+ superclass = NewStringf("%sPublic", proxy_class_name);
+ } else if (hasContent(baseclassname)) {
+ superclass = Copy(baseclassname);
+ } else {
+ superclass = NewString("ROOT");
+ }
+ Printf(m3wrap_intf.f, "%s <: %s;\n", proxy_class_name, superclass);
+ Delete(superclass);
+
+ {
+ static const char *acc_m3suffix[] = { "Public", "Protected", "Private" };
+ int acc;
+ for (acc = acc_public; acc <= acc_private; acc++) {
+ bool process_private = (acc == acc_private) && need_private;
+ if (hasContent(methods[acc]) || process_private) {
+ String *subclass = NewStringf("%s%s", proxy_class_name, acc_m3suffix[acc]);
+ /*
+ m3wrap_intf.enterBlock(revelation);
+ Printf(m3wrap_intf.f, "%s <: %s;\n", proxy_class_name, subclass);
+ */
+ if (acc == max_acc) {
+ m3wrap_intf.enterBlock(revelation);
+ Printf(m3wrap_intf.f, "%s =\n", proxy_class_name);
+ } else {
+ m3wrap_intf.enterBlock(blocktype);
+ Printf(m3wrap_intf.f, "%s =\n", subclass);
+ }
+ Printf(m3wrap_intf.f, "%s BRANDED OBJECT\n", baseclassname);
+ if (process_private) {
+ Setattr(m3wrap_intf.import, m3raw_name, "");
+ Printf(m3wrap_intf.f, "cxxObj:%s.%s;\n", m3raw_name, proxy_class_name);
+ }
+ if (hasContent(methods[acc])) {
+ Printf(m3wrap_intf.f, "METHODS\n%s", methods[acc]);
+ }
+ if (acc == max_acc) {
+ String *overrides = Getattr(n, "modula3:override");
+ Printf(m3wrap_intf.f, "OVERRIDES\n%s", overrides);
+ }
+ Printf(m3wrap_intf.f, "END;\n");
+ Delete(baseclassname);
+ baseclassname = subclass;
+ }
+ }
+ }
+
+ Delete(methods[acc_public]);
+ Delete(methods[acc_protected]);
+ Delete(methods[acc_private]);
+
+ } else {
+ Swig_warning(WARN_MODULA3_TYPECONSTRUCTOR_UNKNOWN, input_file, line_number, "Unknown type constructor %s\n", kind);
+ }
+ }
+
+ if (proxy_flag) {
+
+ emitProxyClassDefAndCPPCasts(n);
+
+ Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
+
+ Printf(f_proxy, "}\n");
+ Close(f_proxy);
+ f_proxy = NULL;
+
+ Delete(proxy_class_name);
+ proxy_class_name = NULL;
+ Delete(destructor_call);
+ destructor_call = NULL;
+ }
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int memberfunctionHandler(Node *n) {
+ //printf("begin memberfunctionHandler(%s)\n", Char(Getattr(n,"name")));
+ Setattr(n, "modula3:functype", "method");
+ Language::memberfunctionHandler(n);
+
+ {
+ /* Language::memberfunctionHandler will remove the mapped types
+ that emitM3Wrapper may attach */
+ ParmList *pl = Getattr(n, "parms");
+ Swig_typemap_attach_parms("m3wrapinmode", pl, NULL);
+ Swig_typemap_attach_parms("m3wrapinname", pl, NULL);
+ Swig_typemap_attach_parms("m3wrapintype", pl, NULL);
+ Swig_typemap_attach_parms("m3wrapindefault", pl, NULL);
+ attachParameterNames(n, "tmap:m3wrapinname", "autoname", "arg%d");
+ String *rettype = getMappedTypeNew(n, "m3wrapouttype", "");
+
+ String *methodname = Getattr(n, "sym:name");
+/*
+ if (methodname==NIL) {
+ methodname = Getattr(n,"name");
+ }
+*/
+ String *arguments = createM3Signature(n);
+ String *storage = Getattr(n, "storage");
+ String *overridden = Getattr(n, "override");
+ bool isVirtual = (storage != NIL) && (Strcmp(storage, "virtual") == 0);
+ bool isOverridden = (overridden != NIL)
+ && (Strcmp(overridden, "1") == 0);
+ if ((!isVirtual) || (!isOverridden)) {
+ {
+ String *methods = getMethodDeclarations(n);
+ Printf(methods, "%s(%s)%s%s;%s\n",
+ methodname, arguments,
+ hasContent(rettype) ? ": " : "", hasContent(rettype) ? (const String *) rettype : "", isVirtual ? " (* base method *)" : "");
+ }
+ {
+ /* this was attached by functionWrapper
+ invoked by Language::memberfunctionHandler */
+ String *fname = Getattr(n, "modula3:funcname");
+ String *overrides = getAttrString(parentNode(n), "modula3:override");
+ Printf(overrides, "%s := %s;\n", methodname, fname);
+ }
+ }
+ }
+
+ if (proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
+ Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
+ Setattr(n, "imfuncname", intermediary_function_name);
+ proxyClassFunctionHandler(n);
+ Delete(overloaded_name);
+ }
+ //printf("end memberfunctionHandler(%s)\n", Char(Getattr(n,"name")));
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+
+ static_flag = true;
+ Language::staticmemberfunctionHandler(n);
+
+ if (proxy_flag) {
+ String *overloaded_name = getOverloadedName(n);
+ String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name);
+ Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
+ Setattr(n, "imfuncname", intermediary_function_name);
+ proxyClassFunctionHandler(n);
+ Delete(overloaded_name);
+ }
+ static_flag = false;
+
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * proxyClassFunctionHandler()
+ *
+ * Function called for creating a Modula 3 wrapper function around a c++ function in the
+ * proxy class. Used for both static and non-static C++ class functions.
+ * C++ class static functions map to Modula 3 static functions.
+ * Two extra attributes in the Node must be available. These are "proxyfuncname" -
+ * the name of the Modula 3 class proxy function, which in turn will call "imfuncname" -
+ * the intermediary (PInvoke) function name in the intermediary class.
+ * ----------------------------------------------------------------------------- */
+
+ void proxyClassFunctionHandler(Node *n) {
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ Hash *throws_hash = NewHash();
+ String *intermediary_function_name = Getattr(n, "imfuncname");
+ String *proxy_function_name = Getattr(n, "proxyfuncname");
+ String *tm;
+ Parm *p;
+ int i;
+ String *imcall = NewString("");
+ String *return_type = NewString("");
+ String *function_code = NewString("");
+ bool setter_flag = false;
+
+ 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("m3wraptype", l, NULL);
+ Swig_typemap_attach_parms("m3in", l, NULL);
+
+ /* Get return types */
+ if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
+ substituteClassname(t, tm);
+ Printf(return_type, "%s", tm);
+ }
+
+ if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
+ // Properties
+ setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(Swig_name_member(proxy_class_name, variable_name)))
+ == 0);
+ }
+
+ /* Start generating the proxy function */
+ Printf(function_code, " %s ", Getattr(n, "feature:modula3:methodmodifiers"));
+ if (static_flag)
+ Printf(function_code, "static ");
+ if (Getattr(n, "override"))
+ Printf(function_code, "override ");
+ else if (checkAttribute(n, "storage", "virtual"))
+ Printf(function_code, "virtual ");
+
+ Printf(function_code, "%s %s(", return_type, proxy_function_name);
+
+ Printv(imcall, m3raw_name, ".", intermediary_function_name, "(", NIL);
+ if (!static_flag)
+ Printv(imcall, "swigCPtr", NIL);
+
+ emit_mark_varargs(l);
+
+ int gencomma = !static_flag;
+
+ /* Output each parameter */
+ for (i = 0, p = l; p; i++) {
+
+ /* Ignored varargs */
+ if (checkAttribute(p, "varargs:ignore", "1")) {
+ p = nextSibling(p);
+ continue;
+ }
+
+ /* Ignored parameters */
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+
+ /* Ignore the 'this' argument for variable wrappers */
+ if (!(variable_wrapper_flag && i == 0)) {
+ SwigType *pt = Getattr(p, "type");
+ String *param_type = NewString("");
+
+ /* Get the Modula 3 parameter type */
+ if ((tm = getMappedType(p, "m3wraptype"))) {
+ substituteClassname(pt, tm);
+ Printf(param_type, "%s", tm);
+ }
+
+ if (gencomma)
+ Printf(imcall, ", ");
+
+ String *arg = variable_wrapper_flag ? NewString("value") : makeParameterName(n,
+ p,
+ i);
+
+ // Use typemaps to transform type used in Modula 3 wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
+ if ((tm = getMappedType(p, "in"))) {
+ addThrows(throws_hash, "in", p);
+ substituteClassname(pt, tm);
+ Replaceall(tm, "$input", arg);
+ Printv(imcall, tm, NIL);
+ }
+
+ /* Add parameter to proxy function */
+ if (gencomma >= 2)
+ Printf(function_code, ", ");
+ gencomma = 2;
+ Printf(function_code, "%s %s", param_type, arg);
+
+ Delete(arg);
+ Delete(param_type);
+ }
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ Printf(imcall, ")");
+ Printf(function_code, ")");
+
+ // Transform return type used in PInvoke function (in intermediary class) to type used in Modula 3 wrapper function (in proxy class)
+ if ((tm = getMappedTypeNew(n, "m3out", ""))) {
+ addThrows(throws_hash, "m3out", n);
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "true");
+ else
+ Replaceall(tm, "$owner", "false");
+ substituteClassname(t, tm);
+ Replaceall(tm, "$imcall", imcall);
+ }
+
+ generateThrowsClause(throws_hash, function_code);
+ Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
+
+ if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
+ // Properties
+ if (setter_flag) {
+ // Setter method
+ if ((tm = getMappedTypeNew(n, "m3varin", ""))) {
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "true");
+ else
+ Replaceall(tm, "$owner", "false");
+ substituteClassname(t, tm);
+ Replaceall(tm, "$imcall", imcall);
+ Printf(proxy_class_code, "%s", tm);
+ }
+ } else {
+ // Getter method
+ if ((tm = getMappedTypeNew(n, "m3varout", ""))) {
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "true");
+ else
+ Replaceall(tm, "$owner", "false");
+ substituteClassname(t, tm);
+ Replaceall(tm, "$imcall", imcall);
+ Printf(proxy_class_code, "%s", tm);
+ }
+ }
+ } else {
+ // Normal function call
+ Printv(proxy_class_code, function_code, NIL);
+ }
+
+ Delete(function_code);
+ Delete(return_type);
+ Delete(imcall);
+ Delete(throws_hash);
+ }
+
+ /* ----------------------------------------------------------------------
+ * constructorHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int constructorHandler(Node *n) {
+ // this invokes functionWrapper
+ Language::constructorHandler(n);
+
+ if (proxy_flag) {
+ ParmList *l = Getattr(n, "parms");
+
+ Hash *throws_hash = NewHash();
+ String *overloaded_name = getOverloadedName(n);
+ String *imcall = NewString("");
+
+ Printf(proxy_class_code, " %s %s(", Getattr(n, "feature:modula3:methodmodifiers"), proxy_class_name);
+ Printv(imcall, " : this(", m3raw_name, ".", Swig_name_construct(overloaded_name), "(", NIL);
+
+ /* Attach the non-standard typemaps to the parameter list */
+ Swig_typemap_attach_parms("in", l, NULL);
+ Swig_typemap_attach_parms("m3wraptype", l, NULL);
+ Swig_typemap_attach_parms("m3in", l, NULL);
+
+ emit_mark_varargs(l);
+
+ int gencomma = 0;
+
+ String *tm;
+ Parm *p = l;
+ int i;
+
+ /* Output each parameter */
+ for (i = 0; p; i++) {
+
+ /* Ignored varargs */
+ if (checkAttribute(p, "varargs:ignore", "1")) {
+ p = nextSibling(p);
+ continue;
+ }
+
+ /* Ignored parameters */
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *param_type = NewString("");
+
+ /* Get the Modula 3 parameter type */
+ if ((tm = getMappedType(p, "m3wraptype"))) {
+ substituteClassname(pt, tm);
+ Printf(param_type, "%s", tm);
+ }
+
+ if (gencomma)
+ Printf(imcall, ", ");
+
+ String *arg = makeParameterName(n, p, i);
+
+ // Use typemaps to transform type used in Modula 3 wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
+ if ((tm = getMappedType(p, "in"))) {
+ addThrows(throws_hash, "in", p);
+ substituteClassname(pt, tm);
+ Replaceall(tm, "$input", arg);
+ Printv(imcall, tm, NIL);
+ }
+
+ /* Add parameter to proxy function */
+ if (gencomma)
+ Printf(proxy_class_code, ", ");
+ Printf(proxy_class_code, "%s %s", param_type, arg);
+ gencomma = 1;
+
+ Delete(arg);
+ Delete(param_type);
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ Printf(imcall, "), true)");
+
+ Printf(proxy_class_code, ")");
+ Printf(proxy_class_code, "%s", imcall);
+ generateThrowsClause(throws_hash, proxy_class_code);
+ Printf(proxy_class_code, " {\n");
+ Printf(proxy_class_code, " }\n\n");
+
+ if (!gencomma) // We must have a default constructor
+ have_default_constructor_flag = true;
+
+ Delete(overloaded_name);
+ Delete(imcall);
+ Delete(throws_hash);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * destructorHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int destructorHandler(Node *n) {
+ Language::destructorHandler(n);
+ String *symname = Getattr(n, "sym:name");
+
+ if (proxy_flag) {
+ Printv(destructor_call, m3raw_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * membervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int membervariableHandler(Node *n) {
+ //printf("begin membervariableHandler(%s)\n", Char(Getattr(n,"name")));
+ SwigType *t = Getattr(n, "type");
+ String *tm;
+
+ // Get the variable type
+ if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
+ substituteClassname(t, tm);
+ }
+
+ variable_name = Getattr(n, "sym:name");
+ //printf("member variable: %s\n", Char(variable_name));
+
+ // Output the property's field declaration and accessor methods
+ Printf(proxy_class_code, " public %s %s {", tm, variable_name);
+
+ Setattr(n, "modula3:functype", "accessor");
+ wrapping_member_flag = true;
+ variable_wrapper_flag = true;
+ Language::membervariableHandler(n);
+ wrapping_member_flag = false;
+ variable_wrapper_flag = false;
+
+ Printf(proxy_class_code, "\n }\n\n");
+
+ {
+ String *methods = getMethodDeclarations(n);
+ String *overrides = getAttrString(parentNode(n), "modula3:override");
+ SwigType *type = Getattr(n, "type");
+ String *m3name = capitalizeFirst(variable_name);
+ //String *m3name = nameToModula3(variable_name,true);
+ if (!SwigType_isconst(type)) {
+ {
+ String *inmode = getMappedTypeNew(n, "m3wrapinmode", "", false);
+ String *intype = getMappedTypeNew(n, "m3wrapintype", "");
+ Printf(methods, "set%s(%s val:%s);\n", m3name, (inmode != NIL) ? (const String *) inmode : "", intype);
+ }
+ {
+ /* this was attached by functionWrapper
+ invoked by Language::memberfunctionHandler */
+ String *fname = Getattr(n, "modula3:setname");
+ Printf(overrides, "set%s := %s;\n", m3name, fname);
+ }
+ }
+ {
+ {
+ String *outtype = getMappedTypeNew(n, "m3wrapouttype", "");
+ Printf(methods, "get%s():%s;\n", m3name, outtype);
+ }
+ {
+ /* this was attached by functionWrapper
+ invoked by Language::memberfunctionHandler */
+ String *fname = Getattr(n, "modula3:getname");
+ Printf(overrides, "get%s := %s;\n", m3name, fname);
+ }
+ }
+ Delete(m3name);
+ }
+ //printf("end membervariableHandler(%s)\n", Char(Getattr(n,"name")));
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * staticmembervariableHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmembervariableHandler(Node *n) {
+
+ bool static_const_member_flag = (Getattr(n, "value") == 0);
+ if (static_const_member_flag) {
+ SwigType *t = Getattr(n, "type");
+ String *tm;
+
+ // Get the variable type
+ if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
+ substituteClassname(t, tm);
+ }
+ // Output the property's field declaration and accessor methods
+ Printf(proxy_class_code, " public static %s %s {", tm, Getattr(n, "sym:name"));
+ }
+
+ variable_name = Getattr(n, "sym:name");
+ wrapping_member_flag = true;
+ static_flag = true;
+ Language::staticmembervariableHandler(n);
+ wrapping_member_flag = false;
+ static_flag = false;
+
+ if (static_const_member_flag)
+ Printf(proxy_class_code, "\n }\n\n");
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberconstantHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int memberconstantHandler(Node *n) {
+ variable_name = Getattr(n, "sym:name");
+ wrapping_member_flag = true;
+ Language::memberconstantHandler(n);
+ wrapping_member_flag = false;
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * getOverloadedName()
+ * ----------------------------------------------------------------------------- */
+
+ String *getOverloadedName(Node *n) {
+ String *overloaded_name = Copy(Getattr(n, "sym:name"));
+
+ if (Getattr(n, "sym:overloaded")) {
+ Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
+ }
+
+ return overloaded_name;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitM3Wrapper()
+ * It is also used for set and get methods of global variables.
+ * ----------------------------------------------------------------------------- */
+
+ void emitM3Wrapper(Node *n, const String *func_name) {
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ Hash *throws_hash = NewHash();
+ int num_exceptions = 0;
+ int num_returns = 0;
+ String *rawcall = NewString("");
+ String *reccall = NewString("");
+ String *local_variables = NewString("");
+ String *local_constants = NewString("");
+ String *incheck = NewString("");
+ String *outcheck = NewString("");
+ String *setup = NewString("");
+ String *cleanup = NewString("");
+ String *outarg = NewString(""); /* don't mix up with 'autark' :-] */
+ String *storeout = NewString("");
+ String *result_name = NewString("");
+ String *return_variables = NewString("");
+ const char *result_return = "ret";
+ String *function_code = NewString("");
+ /*several names for the same function */
+ String *raw_name = Getattr(n, "name"); /*original C function name */
+ //String *func_name = Getattr(n,"sym:name"); /*final Modula3 name chosen by the user*/
+ bool setter_flag = false;
+ int multiretval = GetFlag(n, "feature:modula3:multiretval");
+
+ 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("m3wrapargvar", l, NULL);
+ Swig_typemap_attach_parms("m3wrapargconst", l, NULL);
+ Swig_typemap_attach_parms("m3wrapargraw", l, NULL);
+ Swig_typemap_attach_parms("m3wrapargdir", l, NULL);
+ Swig_typemap_attach_parms("m3wrapinmode", l, NULL);
+ Swig_typemap_attach_parms("m3wrapinname", l, NULL);
+ Swig_typemap_attach_parms("m3wrapintype", l, NULL);
+ Swig_typemap_attach_parms("m3wrapindefault", l, NULL);
+ Swig_typemap_attach_parms("m3wrapinconv", l, NULL);
+ Swig_typemap_attach_parms("m3wrapincheck", l, NULL);
+ Swig_typemap_attach_parms("m3wrapoutname", l, NULL);
+ Swig_typemap_attach_parms("m3wrapouttype", l, NULL);
+ Swig_typemap_attach_parms("m3wrapoutconv", l, NULL);
+ Swig_typemap_attach_parms("m3wrapoutcheck", l, NULL);
+
+ attachMappedType(n, "m3wrapretraw");
+ attachMappedType(n, "m3wrapretname");
+ attachMappedType(n, "m3wraprettype");
+ attachMappedType(n, "m3wrapretvar");
+ attachMappedType(n, "m3wrapretconv");
+ attachMappedType(n, "m3wrapretcheck");
+
+ Swig_typemap_attach_parms("m3wrapfreearg", l, NULL);
+
+/*
+ Swig_typemap_attach_parms("m3wrapargvar:throws", l, NULL);
+ Swig_typemap_attach_parms("m3wrapargraw:throws", l, NULL);
+ Swig_typemap_attach_parms("m3wrapinconv:throws", l, NULL);
+ Swig_typemap_attach_parms("m3wrapincheck:throws", l, NULL);
+ Swig_typemap_attach_parms("m3wrapoutconv:throws", l, NULL);
+ Swig_typemap_attach_parms("m3wrapoutcheck:throws", l, NULL);
+
+ attachMappedType(n, "m3wrapretvar:throws");
+ attachMappedType(n, "m3wrapretconv:throws");
+ attachMappedType(n, "m3wrapretcheck:throws");
+
+ Swig_typemap_attach_parms("m3wrapfreearg:throws", l, NULL);
+*/
+
+ /* Attach argument names to the parameter list */
+ /* should be a separate procedure making use of hashes */
+ attachParameterNames(n, "tmap:m3wrapinname", "autoname", "arg%d");
+
+ /* Get return types */
+ String *result_m3rawtype = Copy(getMappedTypeNew(n, "m3rawrettype", ""));
+ String *result_m3wraptype = Copy(getMappedTypeNew(n, "m3wraprettype", ""));
+ bool has_return_raw = hasContent(result_m3rawtype);
+ bool has_return_m3 = hasContent(result_m3wraptype);
+ if (has_return_m3) {
+ num_returns++;
+ //printf("%s: %s\n", Char(func_name),Char(result_m3wraptype));
+ }
+
+ String *arguments = createM3Signature(n);
+
+ /* Create local variables or RECORD fields for return values
+ and determine return type that might result from a converted VAR argument. */
+ {
+ writeArgState state;
+ if (multiretval && has_return_m3) {
+ writeArg(return_variables, state, NIL, NewString(result_return), result_m3wraptype, NIL);
+ }
+
+ Parm *p = skipIgnored(l, "m3wrapouttype");
+ while (p != NIL) {
+
+ String *arg = Getattr(p, "tmap:m3wrapoutname");
+ if (arg == NIL) {
+ arg = Getattr(p, "name");
+ }
+
+ String *tm = Getattr(p, "tmap:m3wrapouttype");
+ if (tm != NIL) {
+ if (isOutParam(p)) {
+ if (!multiretval) {
+ if (num_returns == 0) {
+ Printv(result_name, arg, NIL);
+ Clear(result_m3wraptype);
+ Printv(result_m3wraptype, tm, NIL);
+ } else {
+ Swig_warning(WARN_MODULA3_TYPEMAP_MULTIPLE_RETURN, input_file, line_number,
+ "Typemap m3wrapargdir set to 'out' for %s implies a RETURN value, but the routine %s has already one.\nUse %%multiretval feature.\n",
+ SwigType_str(Getattr(p, "type"), 0), raw_name);
+ }
+ }
+ num_returns++;
+ addImports(m3wrap_intf.import, "m3wrapouttype", p);
+ writeArg(return_variables, state, NIL, arg, tm, NIL);
+ }
+ p = skipIgnored(Getattr(p, "tmap:m3wrapouttype:next"), "m3wrapouttype");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ writeArg(return_variables, state, NIL, NIL, NIL, NIL);
+
+ if (multiretval) {
+ Printv(result_name, "result", NIL);
+ Printf(result_m3wraptype, "%sResult", func_name);
+ m3wrap_intf.enterBlock(blocktype);
+ Printf(m3wrap_intf.f, "%s =\nRECORD\n%sEND;\n", result_m3wraptype, return_variables);
+ Printf(local_variables, "%s: %s;\n", result_name, result_m3wraptype);
+ } else {
+ Append(local_variables, return_variables);
+ }
+ }
+
+ /* Declare local constants e.g. for storing argument names. */
+ {
+ Parm *p = l;
+ while (p != NIL) {
+
+ String *arg = Getattr(p, "autoname");
+
+ String *tm = Getattr(p, "tmap:m3wrapargconst");
+ if (tm != NIL) {
+ addImports(m3wrap_impl.import, "m3wrapargconst", p);
+ Replaceall(tm, "$input", arg);
+ Printv(local_constants, tm, "\n", NIL);
+ p = Getattr(p, "tmap:m3wrapargconst:next");
+ } else {
+ p = nextSibling(p);
+ }
+
+ }
+ }
+
+ /* Declare local variables e.g. for converted input values. */
+ {
+ String *tm = getMappedTypeNew(n, "m3wrapretvar", "", false);
+ if (tm != NIL) {
+ addImports(m3wrap_impl.import, "m3wrapretvar", n);
+ addThrows(throws_hash, "m3wrapretvar", n);
+ Printv(local_variables, tm, "\n", NIL);
+ }
+
+ Parm *p = l;
+ while (p != NIL) {
+
+ String *arg = Getattr(p, "autoname");
+
+ tm = Getattr(p, "tmap:m3wrapargvar");
+ if (tm != NIL) {
+ /* exceptions that may be raised but can't be catched,
+ thus we won't count them in num_exceptions */
+ addImports(m3wrap_impl.import, "m3wrapargvar", p);
+ addThrows(throws_hash, "m3wrapargvar", p);
+ Replaceall(tm, "$input", arg);
+ Printv(local_variables, tm, "\n", NIL);
+ p = Getattr(p, "tmap:m3wrapargvar:next");
+ } else {
+ p = nextSibling(p);
+ }
+
+ }
+ }
+
+ /* Convert input values from Modula 3 to C. */
+ {
+ Parm *p = l;
+ while (p != NIL) {
+
+ String *arg = Getattr(p, "autoname");
+
+ String *tm = Getattr(p, "tmap:m3wrapinconv");
+ if (tm != NIL) {
+ addImports(m3wrap_impl.import, "m3wrapinconv", p);
+ num_exceptions += addThrows(throws_hash, "m3wrapinconv", p);
+ Replaceall(tm, "$input", arg);
+ Printv(setup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:m3wrapinconv:next");
+ } else {
+ p = nextSibling(p);
+ }
+
+ }
+ }
+
+ /* Generate checks for input value integrity. */
+ {
+ Parm *p = l;
+ while (p != NIL) {
+
+ String *arg = Getattr(p, "autoname");
+
+ String *tm = Getattr(p, "tmap:m3wrapincheck");
+ if (tm != NIL) {
+ addImports(m3wrap_impl.import, "m3wrapincheck", p);
+ num_exceptions += addThrows(throws_hash, "m3wrapincheck", p);
+ Replaceall(tm, "$input", arg);
+ Printv(incheck, tm, "\n", NIL);
+ p = Getattr(p, "tmap:m3wrapincheck:next");
+ } else {
+ p = nextSibling(p);
+ }
+
+ }
+ }
+
+ Printv(rawcall, m3raw_name, ".", func_name, "(", NIL);
+ /* Arguments to the raw C function */
+ {
+ bool gencomma = false;
+ Parm *p = l;
+ while (p != NIL) {
+ if (gencomma) {
+ Printf(rawcall, ", ");
+ }
+ gencomma = true;
+ addImports(m3wrap_impl.import, "m3wrapargraw", p);
+ num_exceptions += addThrows(throws_hash, "m3wrapargraw", p);
+
+ String *arg = Getattr(p, "autoname");
+ String *qualarg = NewString("");
+ if (!isInParam(p)) {
+ String *tmparg = Getattr(p, "tmap:m3wrapoutname");
+ if (tmparg != NIL) {
+ arg = tmparg;
+ }
+ if (multiretval /*&& isOutParam(p) - automatically fulfilled */ ) {
+ Printf(qualarg, "%s.", result_name);
+ }
+ }
+ Append(qualarg, arg);
+ Setattr(p, "m3outarg", qualarg);
+
+ String *tm = Getattr(p, "tmap:m3wrapargraw");
+ if (tm != NIL) {
+ Replaceall(tm, "$input", arg);
+ Replaceall(tm, "$output", qualarg);
+ Printv(rawcall, tm, NIL);
+ p = Getattr(p, "tmap:m3wrapargraw:next");
+ } else {
+ //Printv(rawcall, Getattr(p,"lname"), NIL);
+ Printv(rawcall, qualarg, NIL);
+ p = nextSibling(p);
+ }
+ Delete(qualarg);
+ }
+ }
+ Printf(rawcall, ")");
+
+ /* Check for error codes and integrity of results */
+ {
+ String *tm = getMappedTypeNew(n, "m3wrapretcheck", "", false);
+ if (tm != NIL) {
+ addImports(m3wrap_impl.import, "m3wrapretcheck", n);
+ num_exceptions += addThrows(throws_hash, "m3wrapretcheck", n);
+ Printv(outcheck, tm, "\n", NIL);
+ }
+
+ Parm *p = l;
+ while (p != NIL) {
+ tm = Getattr(p, "tmap:m3wrapoutcheck");
+ if (tm != NIL) {
+ String *arg = Getattr(p, "autoname");
+ String *outarg = Getattr(p, "m3outarg");
+ addImports(m3wrap_impl.import, "m3wrapoutcheck", p);
+ num_exceptions += addThrows(throws_hash, "m3wrapoutcheck", p);
+ //substituteClassname(Getattr(p,"type"), tm);
+ Replaceall(tm, "$input", arg);
+ Replaceall(tm, "$output", outarg);
+ Printv(outcheck, tm, "\n", NIL);
+ p = Getattr(p, "tmap:m3wrapoutcheck:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* Convert the results to Modula 3 data structures and
+ put them in the record prepared for returning */
+ {
+ /* m3wrapretconv is processed
+ when it is clear if there is some output conversion and checking code */
+ Parm *p = l;
+ while (p != NIL) {
+ String *tm = Getattr(p, "tmap:m3wrapoutconv");
+ if (tm != NIL) {
+ String *arg = Getattr(p, "autoname");
+ String *outarg = Getattr(p, "m3outarg");
+ addImports(m3wrap_impl.import, "m3wrapoutconv", n);
+ num_exceptions += addThrows(throws_hash, "m3wrapoutconv", p);
+ //substituteClassname(Getattr(p,"type"), tm);
+ Replaceall(tm, "$input", arg);
+ Replaceall(tm, "$output", outarg);
+ Printf(storeout, "%s := %s;\n", outarg, tm);
+ p = Getattr(p, "tmap:m3wrapoutconv:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* Generate cleanup code */
+ {
+ Parm *p = l;
+ while (p != NIL) {
+ String *tm = Getattr(p, "tmap:m3wrapfreearg");
+ if (tm != NIL) {
+ String *arg = Getattr(p, "autoname");
+ String *outarg = Getattr(p, "m3outarg");
+ addImports(m3wrap_impl.import, "m3wrapfreearg", p);
+ num_exceptions += addThrows(throws_hash, "m3wrapfreearg", p);
+ //substituteClassname(Getattr(p,"type"), tm);
+ Replaceall(tm, "$input", arg);
+ Replaceall(tm, "$output", outarg);
+ Printv(cleanup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:m3wrapfreearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ {
+ /* Currently I don't know how a typemap similar to the original 'out' typemap
+ could help returning the return value. */
+ /* Receive result from call to raw library function */
+ if (!has_return_raw) {
+ /*
+ rawcall(arg1);
+ result.val := arg1;
+ RETURN result;
+ */
+ /*
+ rawcall(arg1);
+ RETURN arg1;
+ */
+ Printf(reccall, "%s;\n", rawcall);
+
+ if (hasContent(result_name)) {
+ Printf(outarg, "RETURN %s;\n", result_name);
+ }
+ } else {
+ /*
+ arg0 := rawcall(arg1);
+ result.ret := Convert(arg0);
+ result.val := arg1;
+ RETURN result;
+ */
+ /*
+ arg0 := rawcall();
+ RETURN Convert(arg0);
+ */
+ /*
+ RETURN rawcall();
+ */
+ String *return_raw = getMappedTypeNew(n, "m3wrapretraw", "", false);
+ String *return_conv = getMappedTypeNew(n, "m3wrapretconv", "", false);
+
+ /* immediate RETURN would skip result checking */
+ if ((hasContent(outcheck) || hasContent(storeout)
+ || hasContent(cleanup)) && (!hasContent(result_name))
+ && (return_raw == NIL)) {
+ Printv(result_name, "result", NIL);
+ Printf(local_variables, "%s: %s;\n", result_name, result_m3wraptype);
+ }
+
+ String *result_lvalue = Copy(result_name);
+ if (multiretval) {
+ Printf(result_lvalue, ".%s", result_return);
+ }
+ if (return_raw != NIL) {
+ Printf(reccall, "%s := %s;\n", return_raw, rawcall);
+ } else if (hasContent(result_name)) {
+ Printf(reccall, "%s := %s;\n", result_lvalue, rawcall);
+ } else {
+ Printf(outarg, "RETURN %s;\n", rawcall);
+ }
+ if (return_conv != NIL) {
+ addImports(m3wrap_impl.import, "m3wrapretconv", n);
+ num_exceptions += addThrows(throws_hash, "m3wrapretconv", n);
+ if (hasContent(result_name)) {
+ Printf(reccall, "%s := %s;\n", result_lvalue, return_conv);
+ Printf(outarg, "RETURN %s;\n", result_name);
+ } else {
+ Printf(outarg, "RETURN %s;\n", return_conv);
+ }
+ } else {
+ if (hasContent(result_name)) {
+ Printf(outarg, "RETURN %s;\n", result_name);
+ }
+ }
+ }
+ }
+
+ /* Create procedure header */
+ {
+ String *header = NewStringf("PROCEDURE %s (%s)",
+ func_name, arguments);
+
+ if ((num_returns > 0) || multiretval) {
+ Printf(header, ": %s", result_m3wraptype);
+ }
+ generateThrowsClause(throws_hash, header);
+
+ Append(function_code, header);
+
+ m3wrap_intf.enterBlock(no_block);
+ Printf(m3wrap_intf.f, "%s;\n\n", header);
+ }
+
+ {
+ String *body = NewStringf("%s%s%s%s%s",
+ incheck,
+ setup,
+ reccall,
+ outcheck,
+ storeout);
+
+ String *exc_handler;
+ if (hasContent(cleanup) && (num_exceptions > 0)) {
+ exc_handler = NewStringf("TRY\n%sFINALLY\n%sEND;\n", body, cleanup);
+ } else {
+ exc_handler = NewStringf("%s%s", body, cleanup);
+ }
+
+ Printf(function_code, " =\n%s%s%s%sBEGIN\n%s%sEND %s;\n\n",
+ hasContent(local_constants) ? "CONST\n" : "", local_constants,
+ hasContent(local_variables) ? "VAR\n" : "", local_variables, exc_handler, outarg, func_name);
+
+ Delete(exc_handler);
+ Delete(body);
+ }
+
+ m3wrap_impl.enterBlock(no_block);
+ if (proxy_flag && global_variable_flag) {
+ // Properties
+ if (setter_flag) {
+ // Setter method
+ String *tm = getMappedTypeNew(n, "m3varin", "");
+ if (tm != NIL) {
+ if (GetFlag(n, "feature:new")) {
+ Replaceall(tm, "$owner", "true");
+ } else {
+ Replaceall(tm, "$owner", "false");
+ }
+ substituteClassname(t, tm);
+ Replaceall(tm, "$rawcall", rawcall);
+ Replaceall(tm, "$vartype", variable_type); /* $type is already replaced by some super class */
+ Replaceall(tm, "$var", variable_name);
+ Printf(m3wrap_impl.f, "%s", tm);
+ }
+ } else {
+ // Getter method
+ String *tm = getMappedTypeNew(n, "m3varout", "");
+ if (tm != NIL) {
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "true");
+ else
+ Replaceall(tm, "$owner", "false");
+ substituteClassname(t, tm);
+ Replaceall(tm, "$rawcall", rawcall);
+ Replaceall(tm, "$vartype", variable_type);
+ Replaceall(tm, "$var", variable_name);
+ Printf(m3wrap_impl.f, "%s", tm);
+ }
+ }
+ } else {
+ // Normal function call
+ Printv(m3wrap_impl.f, function_code, NIL);
+ }
+
+ Delete(arguments);
+ Delete(return_variables);
+ Delete(local_variables);
+ Delete(local_constants);
+ Delete(outarg);
+ Delete(incheck);
+ Delete(outcheck);
+ Delete(setup);
+ Delete(cleanup);
+ Delete(storeout);
+ Delete(function_code);
+ Delete(result_name);
+ Delete(result_m3wraptype);
+ Delete(reccall);
+ Delete(rawcall);
+ Delete(throws_hash);
+ }
+
+ /*----------------------------------------------------------------------
+ * replaceSpecialVariables()
+ *--------------------------------------------------------------------*/
+
+ virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) {
+ (void)method;
+ SwigType *type = Getattr(parm, "type");
+ substituteClassname(type, tm);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * substituteClassname()
+ *
+ * Substitute the special variable $m3classname with the proxy class name for classes/structs/unions
+ * that SWIG knows about.
+ * Otherwise use the $descriptor name for the Modula 3 class name. Note that the $&m3classname substitution
+ * is the same as a $&descriptor substitution, ie one pointer added to descriptor name.
+ * Inputs:
+ * pt - parameter type
+ * tm - typemap contents that might contain the special variable to be replaced
+ * Outputs:
+ * tm - typemap contents complete with the special variable substitution
+ * Return:
+ * substitution_performed - flag indicating if a substitution was performed
+ * ----------------------------------------------------------------------------- */
+
+ bool substituteClassname(SwigType *pt, String *tm) {
+ bool substitution_performed = false;
+ if (Strstr(tm, "$m3classname") || Strstr(tm, "$&m3classname")) {
+ String *classname = getProxyName(pt);
+ if (classname) {
+ Replaceall(tm, "$&m3classname", classname); // getProxyName() works for pointers to classes too
+ Replaceall(tm, "$m3classname", classname);
+ } 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, "$&m3classname")) {
+ SwigType_add_pointer(type);
+ descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
+ Replaceall(tm, "$&m3classname", descriptor);
+ } else { // $m3classname
+ descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
+ Replaceall(tm, "$m3classname", descriptor);
+ }
+
+ // Add to hash table so that the type wrapper classes can be created later
+ Setattr(swig_types_hash, descriptor, type);
+ Delete(descriptor);
+ Delete(type);
+ }
+ substitution_performed = true;
+ }
+ return substitution_performed;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * makeParameterName()
+ *
+ * Inputs:
+ * n - Node
+ * p - parameter node
+ * arg_num - parameter argument number
+ * Return:
+ * arg - a unique parameter name
+ * ----------------------------------------------------------------------------- */
+
+ String *makeParameterName(Node *n, Parm *p, int arg_num) {
+
+ // Use C parameter name unless it is a duplicate or an empty parameter name
+ String *pn = Getattr(p, "name");
+ int count = 0;
+ ParmList *plist = Getattr(n, "parms");
+ while (plist) {
+ if ((Cmp(pn, Getattr(plist, "name")) == 0))
+ count++;
+ plist = nextSibling(plist);
+ }
+ String *arg = (!pn || (count > 1)) ? NewStringf("arg%d",
+ arg_num) : Copy(Getattr(p,
+ "name"));
+
+ return arg;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * attachParameterNames()
+ *
+ * Inputs:
+ * n - Node of a function declaration
+ * tmid - attribute name for overriding C argument names,
+ * e.g. "tmap:m3wrapinname",
+ * don't forget to attach the mapped types before
+ * nameid - attribute for attaching the names,
+ * e.g. "modula3:inname"
+ * fmt - format for the argument name containing %d
+ * e.g. "arg%d"
+ * ----------------------------------------------------------------------------- */
+
+ void attachParameterNames(Node *n, const char *tmid, const char *nameid, const char *fmt) {
+ /* Use C parameter name if present and unique,
+ otherwise create an 'arg%d' name */
+ Hash *hash = NewHash();
+ Parm *p = Getattr(n, "parms");
+ int count = 0;
+ while (p != NIL) {
+ String *name = Getattr(p, tmid);
+ if (name == NIL) {
+ name = Getattr(p, "name");
+ }
+ String *newname;
+ if ((!hasContent(name)) || (Getattr(hash, name) != NIL)) {
+ newname = NewStringf(fmt, count);
+ } else {
+ newname = Copy(name);
+ }
+ if (1 == Setattr(hash, newname, "1")) {
+ Swig_warning(WARN_MODULA3_DOUBLE_ID, input_file, line_number, "Argument '%s' twice.\n", newname);
+ }
+ Setattr(p, nameid, newname);
+// Delete(newname);
+ p = nextSibling(p);
+ count++;
+ }
+ Delete(hash);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * createM3Signature()
+ *
+ * Create signature of M3 wrapper procedure
+ * Call attachParameterNames and attach mapped types before!
+ * m3wrapintype, m3wrapinmode, m3wrapindefault
+ * ----------------------------------------------------------------------------- */
+
+ String *createM3Signature(Node *n) {
+ String *arguments = NewString("");
+ Parm *p = skipIgnored(Getattr(n, "parms"), "m3wrapintype");
+ writeArgState state;
+ while (p != NIL) {
+
+ /* Get the M3 parameter type */
+ String *tm = getMappedType(p, "m3wrapintype");
+ if (tm != NIL) {
+ if (isInParam(p)) {
+ addImports(m3wrap_intf.import, "m3wrapintype", p);
+ addImports(m3wrap_impl.import, "m3wrapintype", p);
+ String *mode = Getattr(p, "tmap:m3wrapinmode");
+ String *deflt = Getattr(p, "tmap:m3wrapindefault");
+ String *arg = Getattr(p, "autoname");
+ SwigType *pt = Getattr(p, "type");
+ substituteClassname(pt, tm); /* do we need this ? */
+
+ writeArg(arguments, state, mode, arg, tm, deflt);
+ }
+ p = skipIgnored(Getattr(p, "tmap:m3wrapintype:next"), "m3wrapintype");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ writeArg(arguments, state, NIL, NIL, NIL, NIL);
+ return (arguments);
+ }
+
+/* not used any longer
+ - try SwigType_str if required again */
+#if 0
+ /* -----------------------------------------------------------------------------
+ * createCSignature()
+ *
+ * Create signature of C function
+ * ----------------------------------------------------------------------------- */
+
+ String *createCSignature(Node *n) {
+ String *arguments = NewString("");
+ bool gencomma = false;
+ Node *p;
+ for (p = Getattr(n, "parms"); p != NIL; p = nextSibling(p)) {
+ if (gencomma) {
+ Append(arguments, ",");
+ }
+ gencomma = true;
+ String *type = Getattr(p, "type");
+ String *ctype = getMappedTypeNew(type, "ctype");
+ Append(arguments, ctype);
+ }
+ return arguments;
+ }
+#endif
+
+ /* -----------------------------------------------------------------------------
+ * emitTypeWrapperClass()
+ * ----------------------------------------------------------------------------- */
+
+ void emitTypeWrapperClass(String *classname, SwigType *type) {
+ Node *n = NewHash();
+ Setfile(n, input_file);
+ Setline(n, line_number);
+
+ String *filen = NewStringf("%s%s.m3", Swig_file_dirname(outfile), classname);
+ File *f_swigtype = NewFile(filen, "w", SWIG_output_files());
+ if (!f_swigtype) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ String *swigtype = NewString("");
+
+ // Emit banner name
+ emitBanner(f_swigtype);
+
+ // Pure Modula 3 baseclass and interfaces
+ const String *pure_baseclass = typemapLookup(n, "m3base", type, WARN_NONE);
+ const String *pure_interfaces = typemapLookup(n, "m3interfaces", type, WARN_NONE);
+
+ // Emit the class
+ Printv(swigtype, typemapLookup(n, "m3imports", type, WARN_NONE), // Import statements
+ "\n", typemapLookup(n, "m3classmodifiers", type, WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
+ " class $m3classname", // Class name and bases
+ *Char(pure_baseclass) ? " : " : "", pure_baseclass, *Char(pure_interfaces) ? // Interfaces
+ " : " : "", pure_interfaces, " {\n", " private IntPtr swigCPtr;\n", "\n", " ", typemapLookup(n, "m3ptrconstructormodifiers", type, WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers
+ " $m3classname(IntPtr cPtr, bool bFutureUse) {\n", // Constructor used for wrapping pointers
+ " swigCPtr = cPtr;\n", " }\n", "\n", " protected $m3classname() {\n", // Default constructor
+ " swigCPtr = IntPtr.Zero;\n", " }\n", typemapLookup(n, "m3getcptr", type, WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF), // getCPtr method
+ typemapLookup(n, "m3code", type, WARN_NONE), // extra Modula 3 code
+ "}\n", "\n", NIL);
+
+ Replaceall(swigtype, "$m3classname", classname);
+ Printv(f_swigtype, swigtype, NIL);
+
+ Close(f_swigtype);
+ Delete(filen);
+ Delete(swigtype);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * typemapLookup()
+ * n - for input only and must contain info for Getfile(n) and Getline(n) to work
+ * tmap_method - typemap method name
+ * type - typemap type to lookup
+ * warning - warning number to issue if no typemaps found
+ * typemap_attributes - the typemap attributes are attached to this node and will
+ * also be used for temporary storage if non null
+ * return is never NULL, unlike Swig_typemap_lookup()
+ * ----------------------------------------------------------------------------- */
+
+ const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0) {
+ Node *node = !typemap_attributes ? NewHash() : typemap_attributes;
+ Setattr(node, "type", type);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
+ if (!tm) {
+ tm = empty_string;
+ if (warning != WARN_NONE)
+ Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0));
+ }
+ if (!typemap_attributes)
+ Delete(node);
+ return tm;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * addThrows()
+ *
+ * Add all exceptions to a hash that are associated with the 'typemap'.
+ * Return number the number of these exceptions.
+ * ----------------------------------------------------------------------------- */
+
+ int addThrows(Hash *throws_hash, const String *typemap, Node *parameter) {
+ // Get the comma separated throws clause - held in "throws" attribute in the typemap passed in
+ int len = 0;
+ String *throws_attribute = NewStringf("%s:throws", typemap);
+
+ addImports(m3wrap_intf.import, throws_attribute, parameter);
+ addImports(m3wrap_impl.import, throws_attribute, parameter);
+
+ String *throws = getMappedTypeNew(parameter, Char(throws_attribute), "", false);
+ //printf("got exceptions %s for %s\n", Char(throws), Char(throws_attribute));
+
+ if (throws) {
+ // Put the exception classes in the throws clause into a temporary List
+ List *temp_classes_list = Split(throws, ',', INT_MAX);
+ len = Len(temp_classes_list);
+
+ // Add the exception classes to the node throws list, but don't duplicate if already in list
+ if (temp_classes_list /*&& hasContent(temp_classes_list) */ ) {
+ for (Iterator cls = First(temp_classes_list); cls.item != NIL; cls = Next(cls)) {
+ String *exception_class = NewString(cls.item);
+ Replaceall(exception_class, " ", ""); // remove spaces
+ Replaceall(exception_class, "\t", ""); // remove tabs
+ if (hasContent(exception_class)) {
+ // $m3classname substitution
+ SwigType *pt = Getattr(parameter, "type");
+ substituteClassname(pt, exception_class);
+ // Don't duplicate the exception class in the throws clause
+ //printf("add exception %s\n", Char(exception_class));
+ Setattr(throws_hash, exception_class, "1");
+ }
+ Delete(exception_class);
+ }
+ }
+ Delete(temp_classes_list);
+ }
+ Delete(throws_attribute);
+ return len;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * generateThrowsClause()
+ * ----------------------------------------------------------------------------- */
+
+ void generateThrowsClause(Hash *throws_hash, String *code) {
+ // Add the throws clause into code
+ if (Len(throws_hash) > 0) {
+ Iterator cls = First(throws_hash);
+ Printf(code, " RAISES {%s", cls.key);
+ for (cls = Next(cls); cls.key != NIL; cls = Next(cls)) {
+ Printf(code, ", %s", cls.key);
+ }
+ Printf(code, "}");
+ }
+ }
+
+ /* -----------------------------------------------------------------------------
+ * addImports()
+ *
+ * Add all imports that are needed for contents of 'typemap'.
+ * ----------------------------------------------------------------------------- */
+
+ void addImports(Hash *imports_hash, const String *typemap, Node *node) {
+ // Get the comma separated throws clause - held in "throws" attribute in the typemap passed in
+ String *imports_attribute = NewStringf("%s:import", typemap);
+ String *imports = getMappedTypeNew(node, Char(imports_attribute), "", false);
+ //printf("got imports %s for %s\n", Char(imports), Char(imports_attribute));
+
+ if (imports != NIL) {
+ List *import_list = Split(imports, ',', INT_MAX);
+
+ // Add the exception classes to the node imports list, but don't duplicate if already in list
+ if (import_list != NIL) {
+ for (Iterator imp = First(import_list); imp.item != NIL; imp = Next(imp)) {
+ List *import_pair = Split(imp.item, ' ', 3);
+ if (Len(import_pair) == 1) {
+ Setattr(imports_hash, Getitem(import_pair, 0), "");
+ } else if ((Len(import_pair) == 3)
+ && Strcmp(Getitem(import_pair, 1), "AS") == 0) {
+ Setattr(imports_hash, Getitem(import_pair, 0), Getitem(import_pair, 2));
+ } else {
+ Swig_warning(WARN_MODULA3_BAD_IMPORT, input_file, line_number,
+ "Malformed import '%s' for typemap '%s' defined for type '%s'\n", imp, typemap, SwigType_str(Getattr(node, "type"), 0));
+ }
+ Delete(import_pair);
+ }
+ }
+ Delete(import_list);
+ }
+ Delete(imports_attribute);
+ }
+
+ /* -----------------------------------------------------------------------------
+ * emitImportStatements()
+ * ----------------------------------------------------------------------------- */
+
+ void emitImportStatements(Hash *imports_hash, String *code) {
+ // Add the imports statements into code
+ Iterator imp = First(imports_hash);
+ while (imp.key != NIL) {
+ Printf(code, "IMPORT %s", imp.key);
+ String *imp_as = imp.item;
+ if (hasContent(imp_as)) {
+ Printf(code, " AS %s", imp_as);
+ }
+ Printf(code, ";\n");
+ imp = Next(imp);
+ }
+ }
+
+}; /* class MODULA3 */
+
+/* -----------------------------------------------------------------------------
+ * swig_modula3() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+extern "C" Language *swig_modula3(void) {
+ return new MODULA3();
+}
+
+/* -----------------------------------------------------------------------------
+ * Static member variables
+ * ----------------------------------------------------------------------------- */
+
+const char *MODULA3::usage = (char *) "\
+Modula 3 Options (available with -modula3)\n\
+ -generateconst <file> - generate code for computing numeric values of constants\n\
+ -generaterename <file> - generate suggestions for %rename\n\
+ -generatetypemap <file> - generate templates for some basic typemaps\n\
+ -oldvarnames - old intermediary method names for variable wrappers\n\
+\n";
+
+/*
+ -generateconst <file> - stem of the .c source file for computing the numeric values of constants\n\
+ -generaterename <file> - stem of the .i source file containing %rename suggestions\n\
+ -generatetypemap <file> - stem of the .i source file containing typemap patterns\n\
+*/
diff --git a/Source/Modules/module.cxx b/Source/Modules/module.cxx
new file mode 100644
index 0000000..bd82b9e
--- /dev/null
+++ b/Source/Modules/module.cxx
@@ -0,0 +1,57 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * module.cxx
+ *
+ * This file is responsible for the module system.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_module_cxx[] = "$Id: module.cxx 10003 2007-10-17 21:42:11Z wsfulton $";
+
+#include "swigmod.h"
+
+struct Module {
+ ModuleFactory fac;
+ char *name;
+ Module *next;
+ Module(const char *n, ModuleFactory f) {
+ fac = f;
+ name = new char[strlen(n) + 1];
+ strcpy(name, n);
+ next = 0;
+ } ~Module() {
+ delete[]name;
+ }
+};
+
+static Module *modules = 0;
+
+/* -----------------------------------------------------------------------------
+ * void Swig_register_module()
+ *
+ * Register a module.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_register_module(const char *n, ModuleFactory f) {
+ Module *m = new Module(n, f);
+ m->next = modules;
+ modules = m;
+}
+
+/* -----------------------------------------------------------------------------
+ * Language *Swig_find_module()
+ *
+ * Given a command line option, locates the factory function.
+ * ----------------------------------------------------------------------------- */
+
+ModuleFactory Swig_find_module(const char *name) {
+ Module *m = modules;
+ while (m) {
+ if (strcmp(m->name, name) == 0) {
+ return m->fac;
+ }
+ m = m->next;
+ }
+ return 0;
+}
diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx
new file mode 100644
index 0000000..a40f00d
--- /dev/null
+++ b/Source/Modules/mzscheme.cxx
@@ -0,0 +1,834 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * mzscheme.cxx
+ *
+ * Mzscheme language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_mzscheme_cxx[] = "$Id: mzscheme.cxx 11133 2009-02-20 07:52:24Z wsfulton $";
+
+#include "swigmod.h"
+
+#include <ctype.h>
+
+static const char *usage = (char *) "\
+Mzscheme Options (available with -mzscheme)\n\
+ -prefix <name> - Set a prefix <name> to be prepended to all names\n\
+ -declaremodule - Create extension that declares a module\n\
+ -noinit - Do not emit scheme_initialize, scheme_reload,\n\
+ scheme_module_name functions\n\
+ -dynamic-load <library>,[library,...] - Do not link with these libraries, dynamic load\n\
+ them\n\
+";
+
+static String *fieldnames_tab = 0;
+static String *convert_tab = 0;
+static String *convert_proto_tab = 0;
+static String *struct_name = 0;
+static String *mangled_struct_name = 0;
+
+static char *prefix = 0;
+static bool declaremodule = false;
+static bool noinit = false;
+//DLOPEN PATCH
+static char *load_libraries = NULL;
+//DLOPEN PATCH
+static String *module = 0;
+static char *mzscheme_path = (char *) "mzscheme";
+static String *init_func_def = 0;
+
+static File *f_begin = 0;
+static File *f_runtime = 0;
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+
+// Used for garbage collection
+static int exporting_destructor = 0;
+static String *swigtype_ptr = 0;
+static String *cls_swigtype = 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(usage, stdout);
+ SWIG_exit(0);
+ } else if (strcmp(argv[i], "-prefix") == 0) {
+ if (argv[i + 1]) {
+ prefix = new char[strlen(argv[i + 1]) + 2];
+ strcpy(prefix, argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-declaremodule") == 0) {
+ declaremodule = true;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noinit") == 0) {
+ noinit = true;
+ Swig_mark_arg(i);
+ }
+// DLOPEN PATCH
+ else if (strcmp(argv[i], "-dynamic-load") == 0) {
+ load_libraries = new char[strlen(argv[i + 1]) + 2];
+ strcpy(load_libraries, argv[i + 1]);
+ Swig_mark_arg(i++);
+ Swig_mark_arg(i);
+ }
+// DLOPEN PATCH
+ }
+ }
+
+ // 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.swg");
+ allow_overloading();
+
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ 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("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+
+ init_func_def = NewString("");
+ Swig_register_filebyname("init", init_func_def);
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGMZSCHEME\n");
+ Printf(f_runtime, "\n");
+
+ module = Getattr(n, "name");
+
+ Language::top(n);
+
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+ if (!noinit) {
+ if (declaremodule) {
+ Printf(f_init, "#define SWIG_MZSCHEME_CREATE_MENV(env) scheme_primitive_module(scheme_intern_symbol(\"%s\"), env)\n", module);
+ } else {
+ Printf(f_init, "#define SWIG_MZSCHEME_CREATE_MENV(env) (env)\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");
+
+ // DLOPEN PATCH
+ if (load_libraries) {
+ Printf(f_init, "mz_set_dlopen_libraries(\"%s\");\n", load_libraries);
+ }
+ // DLOPEN PATCH
+
+ 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_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * Create a function declaration and register it with the interpreter.
+ * ------------------------------------------------------------ */
+
+ void throw_unhandled_mzscheme_type_error(SwigType *d) {
+ Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s.\n", SwigType_str(d, 0));
+ }
+
+ /* Return true iff T is a pointer type */
+
+ int
+ is_a_pointer(SwigType *t) {
+ return SwigType_ispointer(SwigType_typedef_resolve_all(t));
+ }
+
+ virtual int functionWrapper(Node *n) {
+ char *iname = GetChar(n, "sym:name");
+ SwigType *d = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ Parm *p;
+
+ Wrapper *f = NewWrapper();
+ String *proc_name = NewString("");
+ String *source = NewString("");
+ String *target = NewString("");
+ String *arg = NewString("");
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *build = NewString("");
+ String *tm;
+ int argout_set = 0;
+ int i = 0;
+ int numargs;
+ int numreq;
+ String *overname = 0;
+
+ // PATCH DLOPEN
+ if (load_libraries) {
+ ParmList *parms = Getattr(n, "parms");
+ SwigType *type = Getattr(n, "type");
+ String *name = NewString("caller");
+ Setattr(n, "wrap:action", Swig_cresult(type, "result", Swig_cfunction_call(name, parms)));
+ }
+ // PATCH DLOPEN
+
+ // 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)) {
+ DelWrapper(f);
+ return SWIG_ERROR;
+ }
+ }
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n, "wrap:name", wname);
+
+ // Build the name for Scheme.
+ Printv(proc_name, iname, NIL);
+ Replaceall(proc_name, "_", "-");
+
+ // writing the function wrapper function
+ Printv(f->def, "static Scheme_Object *", wname, " (", NIL);
+ Printv(f->def, "int argc, Scheme_Object **argv", NIL);
+ Printv(f->def, ")\n{", NIL);
+
+ /* Define the scheme name in C. This define is used by several
+ macros. */
+ Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
+
+ // Emit all of the local variables for holding arguments.
+ emit_parameter_variables(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);
+
+ // DLOPEN PATCH
+ /* Add the holder for the pointer to the function to be opened */
+ if (load_libraries) {
+ Wrapper_add_local(f, "_function_loaded", "static int _function_loaded=(1==0)");
+ Wrapper_add_local(f, "_the_function", "static void *_the_function=NULL");
+ {
+ String *parms = ParmList_protostr(l);
+ String *func = NewStringf("(*caller)(%s)", parms);
+ Wrapper_add_local(f, "caller", SwigType_lstr(d, func)); /*"(*caller)()")); */
+ }
+ }
+ // DLOPEN PATCH
+
+ // adds local variables
+ Wrapper_add_local(f, "lenv", "int lenv = 1");
+ Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]");
+
+ // DLOPEN PATCH
+ if (load_libraries) {
+ Printf(f->code, "if (!_function_loaded) { _the_function=mz_load_function(\"%s\");_function_loaded=(1==1); }\n", iname);
+ Printf(f->code, "if (!_the_function) { scheme_signal_error(\"Cannot load C function '%s'\"); }\n", iname);
+ Printf(f->code, "caller=_the_function;\n");
+ }
+ // DLOPEN PATCH
+
+ // Now write code to extract the parameters (this is super ugly)
+
+ for (i = 0, p = l; i < numargs; i++) {
+ /* Skip ignored arguments */
+
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *ln = Getattr(p, "lname");
+
+ // Produce names of source and target
+ Clear(source);
+ Clear(target);
+ Clear(arg);
+ Printf(source, "argv[%d]", i);
+ Printf(target, "%s", ln);
+ Printv(arg, Getattr(p, "name"), NIL);
+
+ if (i >= numreq) {
+ Printf(f->code, "if (argc > %d) {\n", i);
+ }
+ // Handle parameter types.
+ if ((tm = Getattr(p, "tmap:in"))) {
+ Replaceall(tm, "$source", source);
+ Replaceall(tm, "$target", target);
+ Replaceall(tm, "$input", source);
+ Setattr(p, "emit:input", source);
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:in:next");
+ } else {
+ // no typemap found
+ // check if typedef and resolve
+ throw_unhandled_mzscheme_type_error(pt);
+ p = nextSibling(p);
+ }
+ if (i >= numreq) {
+ Printf(f->code, "}\n");
+ }
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Pass output arguments back to the caller.
+
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+ Replaceall(tm, "$source", Getattr(p, "emit:input")); /* Deprecated */
+ Replaceall(tm, "$target", Getattr(p, "lname")); /* Deprecated */
+ Replaceall(tm, "$arg", Getattr(p, "emit:input"));
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(outarg, tm, "\n", NIL);
+ p = Getattr(p, "tmap:argout:next");
+ argout_set = 1;
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Free up any memory allocated for the arguments.
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:freearg"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(cleanup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ // Now write code to make the function call
+
+ String *actioncode = emit_action(n);
+
+ // Now have return value, figure out what to do with it.
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$target", "values[0]");
+ Replaceall(tm, "$result", "values[0]");
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "1");
+ else
+ Replaceall(tm, "$owner", "0");
+ Printv(f->code, tm, "\n", NIL);
+ } else {
+ throw_unhandled_mzscheme_type_error(d);
+ }
+ emit_return_variable(n, d, f);
+
+ // 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 (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("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("ret", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printv(f->code, tm, "\n", NIL);
+ }
+ // Wrap things up (in a manner of speaking)
+
+ Printv(f->code, tab4, "return SWIG_MzScheme_PackageValues(lenv, values);\n", NIL);
+ Printf(f->code, "#undef FUNC_NAME\n");
+ Printv(f->code, "}\n", NIL);
+
+ /* Substitute the function name */
+ Replaceall(f->code, "$symname", iname);
+
+ Wrapper_print(f, f_wrappers);
+
+ if (!Getattr(n, "sym:overloaded")) {
+
+ // Now register the function
+ char temp[256];
+ sprintf(temp, "%d", numargs);
+ if (exporting_destructor) {
+ Printf(init_func_def, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname);
+ } else {
+ Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, wname, proc_name, numreq, numargs);
+ }
+ } else {
+ if (!Getattr(n, "sym:nextSibling")) {
+ /* Emit overloading dispatch function */
+
+ int maxargs;
+ String *dispatch = Swig_overload_dispatch(n, "return %s(argc,argv);", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *df = NewWrapper();
+ String *dname = Swig_name_wrapper(iname);
+
+ Printv(df->def, "static Scheme_Object *\n", dname, "(int argc, Scheme_Object **argv) {", NIL);
+ Printv(df->code, dispatch, "\n", NIL);
+ Printf(df->code, "scheme_signal_error(\"No matching function for overloaded '%s'\");\n", iname);
+ Printv(df->code, "}\n", NIL);
+ Wrapper_print(df, f_wrappers);
+ Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, dname, proc_name, 0, maxargs);
+ DelWrapper(df);
+ Delete(dispatch);
+ Delete(dname);
+ }
+ }
+
+ Delete(proc_name);
+ Delete(source);
+ Delete(target);
+ Delete(arg);
+ Delete(outarg);
+ Delete(cleanup);
+ Delete(build);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ *
+ * Create a link to a C variable.
+ * This creates a single function _wrap_swig_var_varname().
+ * This function takes a single optional argument. If supplied, it means
+ * we are setting this variable to some value. If omitted, it means we are
+ * simply evaluating this variable. Either way, we return the variables
+ * value.
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+
+ char *name = GetChar(n, "name");
+ char *iname = GetChar(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+
+ String *proc_name = NewString("");
+ 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
+ String *var_name = Swig_name_wrapper(iname);
+
+ // Build the name for scheme.
+ Printv(proc_name, iname, NIL);
+ Replaceall(proc_name, "_", "-");
+ Setattr(n, "wrap:name", 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 (!GetFlag(n, "feature:immutable")) {
+ /* Check for a setting of the variable value */
+ Printf(f->code, "if (argc) {\n");
+ if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
+ Replaceall(tm, "$source", "argv[0]");
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$input", "argv[0]");
+ /* Printv(f->code, tm, "\n",NIL); */
+ emit_action_code(n, f->code, tm);
+ } else {
+ throw_unhandled_mzscheme_type_error(t);
+ }
+ Printf(f->code, "}\n");
+ }
+ // Now return the value of the variable (regardless
+ // of evaluating or setting)
+
+ if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
+ Replaceall(tm, "$source", name);
+ Replaceall(tm, "$target", "swig_result");
+ Replaceall(tm, "$result", "swig_result");
+ /* Printf (f->code, "%s\n", tm); */
+ emit_action_code(n, f->code, tm);
+ } else {
+ throw_unhandled_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(var_name);
+ Delete(proc_name);
+ Delete(argnum);
+ Delete(arg);
+ Delete(tm2);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ char *name = GetChar(n, "name");
+ char *iname = GetChar(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ String *value = Getattr(n, "value");
+
+ String *var_name = NewString("");
+ String *proc_name = NewString("");
+ String *rvalue = NewString("");
+ String *temp = NewString("");
+ String *tm;
+
+ // Make a static variable;
+
+ Printf(var_name, "_wrap_const_%s", Swig_name_mangle(Getattr(n, "sym:name")));
+
+ // 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("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);
+ SetFlag(n, "feature:immutable");
+ variableWrapper(n);
+ Delete(n);
+ }
+ }
+ Delete(proc_name);
+ Delete(rvalue);
+ Delete(temp);
+ return SWIG_OK;
+ }
+
+ virtual int destructorHandler(Node *n) {
+ exporting_destructor = true;
+ Language::destructorHandler(n);
+ exporting_destructor = false;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+ virtual int classHandler(Node *n) {
+ String *mangled_classname = 0;
+ String *real_classname = 0;
+ String *scm_structname = NewString("");
+ SwigType *ctype_ptr = NewStringf("p.%s", Getattr(n, "classtype"));
+
+ SwigType *t = NewStringf("p.%s", Getattr(n, "name"));
+ swigtype_ptr = SwigType_manglestr(t);
+ Delete(t);
+
+ cls_swigtype = SwigType_manglestr(Getattr(n, "name"));
+
+
+ fieldnames_tab = NewString("");
+ convert_tab = NewString("");
+ convert_proto_tab = NewString("");
+
+ struct_name = Getattr(n, "sym:name");
+ mangled_struct_name = Swig_name_mangle(Getattr(n, "sym:name"));
+
+ Printv(scm_structname, struct_name, NIL);
+ Replaceall(scm_structname, "_", "-");
+
+ real_classname = Getattr(n, "name");
+ mangled_classname = Swig_name_mangle(real_classname);
+
+ Printv(fieldnames_tab, "static const char *_swig_struct_", cls_swigtype, "_field_names[] = { \n", NIL);
+
+ Printv(convert_proto_tab, "static Scheme_Object *_swig_convert_struct_", cls_swigtype, "(", SwigType_str(ctype_ptr, "ptr"), ");\n", NIL);
+
+ Printv(convert_tab, "static Scheme_Object *_swig_convert_struct_", cls_swigtype, "(", SwigType_str(ctype_ptr, "ptr"), ")\n {\n", NIL);
+
+ Printv(convert_tab,
+ tab4, "Scheme_Object *obj;\n", tab4, "Scheme_Object *fields[_swig_struct_", cls_swigtype, "_field_names_cnt];\n", tab4, "int i = 0;\n\n", NIL);
+
+ /* Generate normal wrappers */
+ Language::classHandler(n);
+
+ Printv(convert_tab, tab4, "obj = scheme_make_struct_instance(", "_swig_struct_type_", cls_swigtype, ", i, fields);\n", NIL);
+ Printv(convert_tab, tab4, "return obj;\n}\n\n", NIL);
+
+ Printv(fieldnames_tab, "};\n", NIL);
+
+ Printv(f_header, "static Scheme_Object *_swig_struct_type_", cls_swigtype, ";\n", NIL);
+
+ Printv(f_header, fieldnames_tab, NIL);
+ Printv(f_header, "#define _swig_struct_", cls_swigtype, "_field_names_cnt (sizeof(_swig_struct_", cls_swigtype, "_field_names)/sizeof(char*))\n", NIL);
+
+ Printv(f_header, convert_proto_tab, NIL);
+ Printv(f_wrappers, convert_tab, NIL);
+
+ Printv(init_func_def, "_swig_struct_type_", cls_swigtype,
+ " = SWIG_MzScheme_new_scheme_struct(menv, \"", scm_structname, "\", ",
+ "_swig_struct_", cls_swigtype, "_field_names_cnt,", "(char**) _swig_struct_", cls_swigtype, "_field_names);\n", NIL);
+
+ Delete(mangled_classname);
+ Delete(swigtype_ptr);
+ swigtype_ptr = 0;
+ Delete(fieldnames_tab);
+ Delete(convert_tab);
+ Delete(ctype_ptr);
+ Delete(convert_proto_tab);
+ struct_name = 0;
+ mangled_struct_name = 0;
+ Delete(cls_swigtype);
+ cls_swigtype = 0;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int membervariableHandler(Node *n) {
+ Language::membervariableHandler(n);
+
+ if (!is_smart_pointer()) {
+ String *symname = Getattr(n, "sym:name");
+ String *name = Getattr(n, "name");
+ SwigType *type = Getattr(n, "type");
+ String *swigtype = SwigType_manglestr(Getattr(n, "type"));
+ String *tm = 0;
+ String *access_mem = NewString("");
+ SwigType *ctype_ptr = NewStringf("p.%s", Getattr(n, "type"));
+
+ Printv(fieldnames_tab, tab4, "\"", symname, "\",\n", NIL);
+ Printv(access_mem, "(ptr)->", name, NIL);
+ if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) {
+ Printv(convert_tab, tab4, "fields[i++] = ", NIL);
+ Printv(convert_tab, "_swig_convert_struct_", swigtype, "((", SwigType_str(ctype_ptr, ""), ")&((ptr)->", name, "));\n", NIL);
+ } else if ((tm = Swig_typemap_lookup("varout", n, access_mem, 0))) {
+ Replaceall(tm, "$result", "fields[i++]");
+ Printv(convert_tab, tm, "\n", NIL);
+ } else
+ Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported member variable type %s (ignored).\n", SwigType_str(type, 0));
+
+ Delete(access_mem);
+ }
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * 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;
+ }
+
+ String *runtimeCode() {
+ String *s = Swig_include_sys("mzrun.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'mzrun.swg'\n");
+ s = NewString("");
+ }
+ return s;
+ }
+
+ String *defaultExternalRuntimeFilename() {
+ return NewString("swigmzrun.h");
+ }
+};
+
+/* -----------------------------------------------------------------------------
+ * swig_mzscheme() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_mzscheme() {
+ return new MZSCHEME();
+}
+extern "C" Language *swig_mzscheme(void) {
+ return new_swig_mzscheme();
+}
diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx
new file mode 100644
index 0000000..5b0e78a
--- /dev/null
+++ b/Source/Modules/ocaml.cxx
@@ -0,0 +1,1866 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * ocaml.cxx
+ *
+ * Ocaml language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_ocaml_cxx[] = "$Id: ocaml.cxx 11246 2009-06-05 17:19:29Z wsfulton $";
+
+#include "swigmod.h"
+
+#include <ctype.h>
+
+static const char *usage = (char *)
+ ("Ocaml Options (available with -ocaml)\n"
+ "-prefix <name> - Set a prefix <name> to be prepended to all names\n"
+ "-where - Emit library location\n"
+ "-suffix <name> - Change .cxx to something else\n" "-oldvarnames - old intermediary method names for variable wrappers\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 int generate_sizeof = 0;
+static char *prefix = 0;
+static char *ocaml_path = (char *) "ocaml";
+static bool old_variable_names = false;
+static String *classname = 0;
+static String *module = 0;
+static String *init_func_def = 0;
+static String *f_classtemplate = 0;
+static String *name_qualifier = 0;
+
+static Hash *seen_enums = 0;
+static Hash *seen_enumvalues = 0;
+static Hash *seen_constructors = 0;
+
+static File *f_header = 0;
+static File *f_begin = 0;
+static File *f_runtime = 0;
+static File *f_wrappers = 0;
+static File *f_directors = 0;
+static File *f_directors_h = 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_mltail = 0;
+static File *f_mlitail = 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:
+
+ OCAML() {
+ director_prot_ctor_code = NewString("");
+ Printv(director_prot_ctor_code,
+ "if ( $comparison ) { /* subclassed */\n",
+ " $director_new \n", "} else {\n", " failwith(\"accessing abstract class or protected constructor\"); \n", "}\n", NIL);
+ director_multiple_inheritance = 1;
+ director_language = 1;
+ }
+
+ String *Swig_class_name(Node *n) {
+ String *name;
+ name = Copy(Getattr(n, "sym:name"));
+ return name;
+ }
+
+ void PrintIncludeArg() {
+ Printv(stdout, SWIG_LIB, SWIG_FILE_DELIMITER, ocaml_path, "\n", NIL);
+ }
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+ int i;
+
+ prefix = 0;
+
+ 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(usage, stdout);
+ SWIG_exit(0);
+ } else if (strcmp(argv[i], "-where") == 0) {
+ PrintIncludeArg();
+ SWIG_exit(0);
+ } else if (strcmp(argv[i], "-prefix") == 0) {
+ if (argv[i + 1]) {
+ prefix = new char[strlen(argv[i + 1]) + 2];
+ strcpy(prefix, argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-suffix") == 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], "-oldvarnames") == 0) {
+ Swig_mark_arg(i);
+ old_variable_names = true;
+ }
+ }
+ }
+
+ // 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();
+
+ }
+
+ /* Swig_director_declaration()
+ *
+ * Generate the full director class declaration, complete with base classes.
+ * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {"
+ *
+ */
+
+ String *Swig_director_declaration(Node *n) {
+ String *classname = Swig_class_name(n);
+ String *directorname = NewStringf("SwigDirector_%s", classname);
+ String *base = Getattr(n, "classtype");
+ String *declaration = Swig_class_declaration(n, directorname);
+ Printf(declaration, " : public %s, public Swig::Director {\n", base);
+ Delete(classname);
+ Delete(directorname);
+ return declaration;
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ *
+ * Recognize the %module, and capture the module name.
+ * Create the default enum cases.
+ * Set up the named outputs:
+ *
+ * init
+ * ml
+ * mli
+ * wrapper
+ * header
+ * runtime
+ * directors
+ * directors_h
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+ /* Set comparison with none for ConstructorToFunction */
+ setSubclassInstanceCheck(NewString("caml_list_nth(args,0) != Val_unit"));
+
+ /* check if directors are enabled for this module. note: this
+ * is a "master" switch, without which no director code will be
+ * emitted. %feature("director") statements are also required
+ * to enable directors for individual classes or methods.
+ *
+ * use %module(directors="1") modulename at the start of the
+ * interface file to enable director generation.
+ */
+ {
+ Node *module = Getattr(n, "module");
+ if (module) {
+ Node *options = Getattr(module, "options");
+ if (options) {
+ if (Getattr(options, "directors")) {
+ allow_directors();
+ }
+ if (Getattr(options, "dirprot")) {
+ allow_dirprot();
+ }
+ if (Getattr(options, "sizeof")) {
+ generate_sizeof = 1;
+ }
+ }
+ }
+ }
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+ f_directors = NewString("");
+ f_directors_h = NewString("");
+ f_enumtypes_type = NewString("");
+ f_enumtypes_value = NewString("");
+ init_func_def = NewString("");
+ f_mlbody = NewString("");
+ f_mlibody = NewString("");
+ f_mltail = NewString("");
+ f_mlitail = NewString("");
+ f_class_ctors = NewString("");
+ f_class_ctors_end = NewString("");
+ f_enum_to_int = NewString("");
+ f_int_to_enum = NewString("");
+ f_classtemplate = 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("init", init_func_def);
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("mli", f_mlibody);
+ Swig_register_filebyname("ml", f_mlbody);
+ Swig_register_filebyname("mlitail", f_mlitail);
+ Swig_register_filebyname("mltail", f_mltail);
+ Swig_register_filebyname("director", f_directors);
+ Swig_register_filebyname("director_h", f_directors_h);
+ Swig_register_filebyname("classtemplate", f_classtemplate);
+ Swig_register_filebyname("class_ctors", f_class_ctors);
+
+ if (old_variable_names) {
+ Swig_name_register("set", "%v__set__");
+ Swig_name_register("get", "%v__get__");
+ }
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGOCAML\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 : c_obj) =\n"
+ " match v with\n"
+ " C_enum _y ->\n"
+ " (let y = _y in match (x : c_enum_type) with\n"
+ " `unknown -> " " (match y with\n" " `Int x -> (Swig.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");
+
+ if (directorsEnabled()) {
+ Printf(f_runtime, "#define SWIG_DIRECTORS\n");
+ }
+
+ Printf(f_runtime, "\n");
+
+ /* Produce the enum_to_int and int_to_enum functions */
+
+ Printf(f_enumtypes_type, "open Swig\n" "type c_enum_type = [ \n `unknown\n");
+ Printf(f_enumtypes_value, "type c_enum_value = [ \n `Int of int\n");
+ String *mlfile = NewString("");
+ String *mlifile = NewString("");
+
+ Printv(mlfile, module, ".ml", NIL);
+ Printv(mlifile, module, ".mli", NIL);
+
+ String *mlfilen = NewStringf("%s%s", SWIG_output_directory(), mlfile);
+ if ((f_mlout = NewFile(mlfilen, "w", SWIG_output_files())) == 0) {
+ FileErrorDisplay(mlfilen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ String *mlifilen = NewStringf("%s%s", SWIG_output_directory(), mlifile);
+ if ((f_mliout = NewFile(mlifilen, "w", SWIG_output_files())) == 0) {
+ FileErrorDisplay(mlifilen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ 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 -> Swig.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_init, "#define SWIG_init f_%s_init\n" "%s" "}\n", module, init_func_def);
+ Printf(f_mlbody, "external f_init : unit -> unit = \"f_%s_init\" ;;\n" "let _ = f_init ()\n", module);
+ Printf(f_enumtypes_type, "]\n");
+ Printf(f_enumtypes_value, "]\n\n" "type c_obj = c_enum_value c_obj_t\n");
+
+ if (directorsEnabled()) {
+ // Insert director runtime into the f_runtime file (make it occur before %header section)
+ Swig_insert_file("director.swg", f_runtime);
+ }
+
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+ /* Close all of the files */
+ Dump(f_runtime, f_begin);
+ Dump(f_directors_h, f_header);
+ Dump(f_header, f_begin);
+ Dump(f_directors, f_wrappers);
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+
+ 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);
+ Dump(f_mltail, 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);
+ Dump(f_mlitail, f_mliout);
+ Close(f_mliout);
+ Delete(f_mliout);
+
+ return SWIG_OK;
+ }
+
+ /* Produce an error for the given type */
+ void throw_unhandled_ocaml_type_error(SwigType *d, const char *types) {
+ Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s (%s).\n", SwigType_str(d, 0), types);
+ }
+
+ /* Return true iff T is a pointer type */
+ int
+ is_a_pointer(SwigType *t) {
+ return SwigType_ispointer(SwigType_typedef_resolve_all(t));
+ }
+
+ /*
+ * Delete one reference from a given type.
+ */
+
+ void oc_SwigType_del_reference(SwigType *t) {
+ char *c = Char(t);
+ if (strncmp(c, "q(", 2) == 0) {
+ Delete(SwigType_pop(t));
+ c = Char(t);
+ }
+ if (strncmp(c, "r.", 2)) {
+ printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n");
+ abort();
+ }
+ Replace(t, "r.", "", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
+ }
+
+ void oc_SwigType_del_array(SwigType *t) {
+ char *c = Char(t);
+ if (strncmp(c, "q(", 2) == 0) {
+ Delete(SwigType_pop(t));
+ c = Char(t);
+ }
+ if (strncmp(c, "a(", 2) == 0) {
+ Delete(SwigType_pop(t));
+ }
+ }
+
+ /*
+ * Return true iff T is a reference type
+ */
+
+ int
+ is_a_reference(SwigType *t) {
+ return SwigType_isreference(SwigType_typedef_resolve_all(t));
+ }
+
+ int
+ is_an_array(SwigType *t) {
+ return SwigType_isarray(SwigType_typedef_resolve_all(t));
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * Create a function declaration and register it with the interpreter.
+ * ------------------------------------------------------------ */
+
+ virtual int functionWrapper(Node *n) {
+ char *iname = GetChar(n, "sym:name");
+ SwigType *d = Getattr(n, "type");
+ String *return_type_normalized = normalizeTemplatedClassName(d);
+ ParmList *l = Getattr(n, "parms");
+ int director_method = 0;
+ 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 = GetFlag(n, "feature:new");
+ String *nodeType = Getattr(n, "nodeType");
+ int destructor = (!Cmp(nodeType, "destructor"));
+ String *overname = 0;
+ bool isOverloaded = Getattr(n, "sym:overloaded") ? true : false;
+
+ // Make a wrapper name for this
+ String *wname = Swig_name_wrapper(iname);
+ if (isOverloaded) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n)) {
+ DelWrapper(f);
+ return SWIG_ERROR;
+ }
+ }
+ if (overname) {
+ Append(wname, overname);
+ }
+ /* Do this to disambiguate functions emitted from different modules */
+ Append(wname, module);
+
+ 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, "memberfunctionHandler:sym:name"));
+
+ Replaceall(opname, "operator ", "");
+
+ if (strstr(Char(mangled_name), "__get__")) {
+ String *set_name = Copy(mangled_name);
+ if (!GetFlag(n, "feature:immutable")) {
+ Replaceall(set_name, "__get__", "__set__");
+ Printf(f_class_ctors, " \"%s\", (fun args -> " "if args = (C_list [ raw_ptr ]) then %s args else %s args) ;\n", opname, mangled_name, set_name);
+ Delete(set_name);
+ } else {
+ Printf(f_class_ctors, " \"%s\", (fun args -> " "if args = (C_list [ raw_ptr ]) then %s args else C_void) ;\n", opname, mangled_name);
+ }
+ } else if (strstr(Char(mangled_name), "__set__")) {
+ ; /* Nothing ... handled by the case above */
+ } else {
+ Printf(f_class_ctors, " \"%s\", %s ;\n", opname, mangled_name);
+ }
+
+ Delete(opname);
+ }
+
+ if (classmode && in_constructor) {
+ Setattr(seen_constructors, mangled_name, "true");
+ }
+ // writing the function wrapper function
+ Printv(f->def, "SWIGEXT CAML_VALUE ", wname, " (", NIL);
+ Printv(f->def, "CAML_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", "SWIG_CAMLlocal2(swig_result,rv)");
+ Wrapper_add_local(f, "_v", "int _v = 0");
+ if (isOverloaded) {
+ Wrapper_add_local(f, "i", "int i");
+ Wrapper_add_local(f, "argc", "int argc = caml_list_length(args)");
+ Wrapper_add_local(f, "argv", "CAML_VALUE *argv");
+
+ Printv(f->code,
+ "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
+ "for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
+ }
+ d = SwigType_typedef_qualified(d);
+ emit_parameter_variables(l, f);
+
+ /* 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");
+ pt = SwigType_typedef_qualified(pt);
+
+ // Produce names of source and target
+ Clear(source);
+ Clear(target);
+ Clear(arg);
+ Printf(source, "caml_list_nth(args,%d)", i);
+ 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, "in");
+ 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"));
+ Replaceall(tm, "$ntype", normalizeTemplatedClassName(Getattr(p, "type")));
+ 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);
+ }
+ }
+
+ /* if the object is a director, and the method call originated from its
+ * underlying python object, resolve the call by going up the c++
+ * inheritance chain. otherwise try to resolve the method in python.
+ * without this check an infinite loop is set up between the director and
+ * shadow class method calls.
+ */
+
+ // NOTE: this code should only be inserted if this class is the
+ // base class of a director class. however, in general we haven't
+ // yet analyzed all classes derived from this one to see if they are
+ // directors. furthermore, this class may be used as the base of
+ // a director class defined in a completely different module at a
+ // later time, so this test must be included whether or not directorbase
+ // is true. we do skip this code if directors have not been enabled
+ // at the command line to preserve source-level compatibility with
+ // non-polymorphic swig. also, if this wrapper is for a smart-pointer
+ // method, there is no need to perform the test since the calling object
+ // (the smart-pointer) and the director object (the "pointee") are
+ // distinct.
+
+ director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
+ if (director_method) {
+ Wrapper_add_local(f, "director", "Swig::Director *director = 0");
+ Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
+ Wrapper_add_local(f, "upcall", "bool upcall = false");
+ Append(f->code, "upcall = (director);\n");
+ }
+
+ // Now write code to make the function call
+ Swig_director_emit_dynamic_cast(n, f);
+ String *actioncode = emit_action(n);
+
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ Replaceall(tm, "$source", "swig_result");
+ Replaceall(tm, "$target", "rv");
+ Replaceall(tm, "$result", "rv");
+ Replaceall(tm, "$ntype", return_type_normalized);
+ Printv(f->code, tm, "\n", NIL);
+ } else {
+ throw_unhandled_ocaml_type_error(d, "out");
+ }
+ emit_return_variable(n, d, f);
+
+ // 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 (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
+ Replaceall(tm, "$source", "swig_result");
+ Printv(f->code, tm, "\n", NIL);
+ }
+ }
+ // Free any memory allocated by the function being wrapped..
+
+ if ((tm = Swig_typemap_lookup("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", NIL);
+ if (isOverloaded)
+ Printv(f->code, "free(argv);\n", NIL);
+ Printv(f->code, tab4, "CAMLreturn(swig_result);\n", NIL);
+ Printv(f->code, "}\n", NIL);
+
+ /* Substitute the function name */
+ Replaceall(f->code, "$symname", iname);
+
+ Wrapper_print(f, f_wrappers);
+
+ if (isOverloaded) {
+ if (!Getattr(n, "sym:nextSibling")) {
+ int maxargs;
+ Wrapper *df = NewWrapper();
+ String *dispatch = Swig_overload_dispatch(n,
+ "free(argv);\n" "CAMLreturn(%s(args));\n",
+ &maxargs);
+
+ Wrapper_add_local(df, "_v", "int _v = 0");
+ Wrapper_add_local(df, "argv", "CAML_VALUE *argv");
+
+ /* Undifferentiate name .. this is the dispatch function */
+ wname = Swig_name_wrapper(iname);
+ /* Do this to disambiguate functions emitted from different
+ * modules */
+ Append(wname, module);
+
+ Printv(df->def,
+ "SWIGEXT CAML_VALUE ", wname, "(CAML_VALUE args) {\n" " CAMLparam1(args);\n" " int i;\n" " int argc = caml_list_length(args);\n", NIL);
+ Printv(df->code,
+ "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
+ "for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
+ Printv(df->code, dispatch, "\n", NIL);
+ Printf(df->code, "failwith(\"No matching function for overloaded '%s'\");\n", iname);
+ Printv(df->code, "}\n", NIL);
+ Wrapper_print(df, f_wrappers);
+
+ DelWrapper(df);
+ Delete(dispatch);
+ }
+ }
+
+ Printf(f_mlbody,
+ "external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n"
+ "let %s arg = match %s_f (fnhelper arg) with\n"
+ " [] -> C_void\n"
+ "| [x] -> (if %s then Gc.finalise \n"
+ " (fun x -> ignore ((invoke x) \"~\" C_void)) x) ; x\n"
+ "| lst -> C_list lst ;;\n", mangled_name, wname, mangled_name, mangled_name, newobj ? "true" : "false");
+
+ if (!classmode || in_constructor || in_destructor || static_member_function)
+ Printf(f_mlibody, "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. In the set case we return C_void.
+ *
+ * symname is the name of the variable with respect to C. This
+ * may need to differ from the original name in the case of enums.
+ * enumvname is the name of the variable with respect to ocaml. This
+ * will vary if the variable has been renamed.
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+ char *name = GetChar(n, "feature:symname");
+ String *iname = Getattr(n, "feature:enumvname");
+ String *mname = mangleNameForCaml(iname);
+ SwigType *t = Getattr(n, "type");
+
+ String *proc_name = NewString("");
+ String *tm;
+ String *tm2 = NewString("");;
+ String *argnum = NewString("0");
+ String *arg = NewString("SWIG_Field(args,0)");
+ Wrapper *f;
+
+ if (!name) {
+ name = GetChar(n, "name");
+ }
+
+ if (!iname) {
+ iname = Getattr(n, "sym:name");
+ mname = mangleNameForCaml(NewString(iname));
+ }
+
+ if (!iname || !addSymbol(iname, n))
+ return SWIG_ERROR;
+
+ f = NewWrapper();
+
+ // evaluation function names
+ String *var_name = Swig_name_wrapper(iname);
+
+ // Build the name for scheme.
+ Printv(proc_name, iname, NIL);
+ Setattr(n, "wrap:name", proc_name);
+
+ Printf(f->def, "SWIGEXT CAML_VALUE %s(CAML_VALUE args) {\n", var_name);
+ // Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
+
+ Wrapper_add_local(f, "swig_result", "CAML_VALUE swig_result");
+
+ if (!GetFlag(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("varin", n, name, 0))) {
+ Replaceall(tm, "$source", "args");
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$input", "args");
+ /* Printv(f->code, tm, "\n",NIL); */
+ emit_action_code(n, f->code, tm);
+ } else if ((tm = Swig_typemap_lookup("in", n, name, 0))) {
+ Replaceall(tm, "$source", "args");
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$input", "args");
+ Printv(f->code, tm, "\n", NIL);
+ } else {
+ throw_unhandled_ocaml_type_error(t, "varin/in");
+ }
+ Printf(f->code, "}\n");
+ }
+ // Now return the value of the variable (regardless
+ // of evaluating or setting)
+
+ if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
+ Replaceall(tm, "$source", name);
+ Replaceall(tm, "$target", "swig_result");
+ Replaceall(tm, "$result", "swig_result");
+ emit_action_code(n, f->code, tm);
+ } else if ((tm = Swig_typemap_lookup("out", 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, "varout/out");
+ }
+
+ Printf(f->code, "\nreturn swig_result;\n");
+ Printf(f->code, "}\n");
+
+ Wrapper_print(f, f_wrappers);
+
+ // Now add symbol to the Ocaml interpreter
+
+ if (GetFlag(n, "feature:immutable")) {
+ Printf(f_mlbody, "external _%s : c_obj -> Swig.c_obj = \"%s\" \n", mname, var_name);
+ Printf(f_mlibody, "val _%s : c_obj -> Swig.c_obj\n", iname);
+ if (const_enum) {
+ Printf(f_enum_to_int, " | `%s -> _%s C_void\n", mname, mname);
+ Printf(f_int_to_enum, " if y = (get_int (_%s C_void)) 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);
+ }
+
+ Delete(var_name);
+ 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()
+ *
+ * The one trick here is that we have to make sure we rename the
+ * constant to something useful that doesn't collide with the
+ * original if any exists.
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *name = Getattr(n, "feature:symname");
+ SwigType *type = Getattr(n, "type");
+ String *value = Getattr(n, "value");
+ String *qvalue = Getattr(n, "qualified:value");
+ String *rvalue = NewString("");
+ String *temp = 0;
+
+ if (qvalue)
+ value = qvalue;
+
+ if (!name) {
+ name = mangleNameForCaml(Getattr(n, "name"));
+ Insert(name, 0, "_swig_wrap_");
+ Setattr(n, "feature:symname", name);
+ }
+ // See if there's a typemap
+
+ Printv(rvalue, value, NIL);
+ if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) {
+ temp = Copy(rvalue);
+ Clear(rvalue);
+ Printv(rvalue, "\"", temp, "\"", NIL);
+ Delete(temp);
+ }
+ if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
+ temp = Copy(rvalue);
+ Clear(rvalue);
+ Printv(rvalue, "'", temp, "'", NIL);
+ Delete(temp);
+ }
+ // Create variable and assign it a value
+
+ Printf(f_header, "static %s = ", SwigType_lstr(type, name));
+ 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);
+ }
+
+ SetFlag(n, "feature:immutable");
+ variableWrapper(n);
+ return SWIG_OK;
+ }
+
+ int constructorHandler(Node *n) {
+ int ret;
+
+ in_constructor = 1;
+ ret = Language::constructorHandler(n);
+ in_constructor = 0;
+
+ return ret;
+ }
+
+ /* destructorHandler:
+ * Turn on destructor flag to inform decisions in functionWrapper
+ */
+
+ int destructorHandler(Node *n) {
+ int ret;
+
+ in_destructor = 1;
+ ret = Language::destructorHandler(n);
+ in_destructor = 0;
+
+ return ret;
+ }
+
+ /* copyconstructorHandler:
+ * Turn on constructor and copyconstructor flags for functionWrapper
+ */
+
+ int copyconstructorHandler(Node *n) {
+ int ret;
+
+ in_copyconst = 1;
+ in_constructor = 1;
+ ret = Language::copyconstructorHandler(n);
+ in_constructor = 0;
+ in_copyconst = 0;
+
+ return ret;
+ }
+
+ /**
+ * A simple, somewhat general purpose function for writing to multiple
+ * streams from a source template. This allows the user to define the
+ * class definition in ways different from the one I have here if they
+ * want to. It will also make the class definition system easier to
+ * fiddle with when I want to change methods, etc.
+ */
+
+ void Multiwrite(String *s) {
+ char *find_marker = strstr(Char(s), "(*Stream:");
+ while (find_marker) {
+ char *next = strstr(find_marker, "*)");
+ find_marker += strlen("(*Stream:");
+
+ if (next) {
+ int num_chars = next - find_marker;
+ String *stream_name = NewString(find_marker);
+ Delslice(stream_name, num_chars, Len(stream_name));
+ File *fout = Swig_filebyname(stream_name);
+ if (fout) {
+ next += strlen("*)");
+ char *following = strstr(next, "(*Stream:");
+ find_marker = following;
+ if (!following)
+ following = next + strlen(next);
+ String *chunk = NewString(next);
+ Delslice(chunk, following - next, Len(chunk));
+ Printv(fout, chunk, NIL);
+ }
+ }
+ }
+ }
+
+ bool isSimpleType(String *name) {
+ char *ch = Char(name);
+
+ return !(strchr(ch, '(') || strchr(ch, '<') || strchr(ch, ')') || strchr(ch, '>'));
+ }
+
+ /* We accept all chars in identifiers because we use strings to index
+ * them. */
+ int validIdentifier(String *name) {
+ return Len(name) > 0 ? 1 : 0;
+ }
+
+ /* classHandler
+ *
+ * Create a "class" definition for ocaml. I thought quite a bit about
+ * how I should do this part of it, and arrived here, using a function
+ * invocation to select a method, and dispatch. This can obviously be
+ * done better, but I can't see how, given that I want to support
+ * overloaded methods, out parameters, and operators.
+ *
+ * I needed a system that would do this:
+ *
+ * a Be able to call these methods:
+ * int foo( int x );
+ * float foo( int x, int &out );
+ *
+ * b Be typeable, even in the presence of mutually dependent classes.
+ *
+ * c Support some form of operator invocation.
+ *
+ * (c) I chose strings for the method names so that "+=" would be a
+ * valid method name, and the somewhat natural << (invoke x) "+=" y >>
+ * would work.
+ *
+ * (a) (b) Since the c_obj type exists, it's easy to return C_int in one
+ * case and C_list [ C_float ; C_int ] in the other. This makes tricky
+ * problems with out parameters disappear; they're simply appended to the
+ * return list.
+ *
+ * (b) Since every item that comes from C++ is the same type, there is no
+ * problem with the following:
+ *
+ * class Foo;
+ * class Bar { Foo *toFoo(); }
+ * class Foo { Bar *toBar(); }
+ *
+ * Since the Objective caml types of Foo and Bar are the same. Now that
+ * I correctly incorporate SWIG's typechecking, this isn't a big deal.
+ *
+ * The class is in the form of a function returning a c_obj. The c_obj
+ * is a C_obj containing a function which invokes a method on the
+ * underlying object given its type.
+ *
+ * The name emitted here is normalized before being sent to
+ * Callback.register, because we need this string to look up properly
+ * when the typemap passes the descriptor string. I've been considering
+ * some, possibly more forgiving method that would do some transformations
+ * on the $descriptor in order to find a potential match. This is for
+ * later.
+ *
+ * Important things to note:
+ *
+ * We rely on exception handling (BadMethodName) in order to call an
+ * ancestor. This can be improved.
+ *
+ * The method used to get :classof could be improved to look at the type
+ * info that the base pointer contains. It's really an error to have a
+ * SWIG-generated object that does not contain type info, since the
+ * existence of the object means that SWIG knows the type.
+ *
+ * :parents could use :classof to tell what class it is and make a better
+ * decision. This could be nice, (i.e. provide a run-time graph of C++
+ * classes represented);.
+ *
+ * I can't think of a more elegant way of converting a C_obj fun to a
+ * pointer than "operator &"...
+ *
+ * Added a 'sizeof' that will allow you to do the expected thing.
+ * This should help users to fill buffer structs and the like (as is
+ * typical in windows-styled code). It's only enabled if you give
+ * %feature(sizeof) and then, only for simple types.
+ *
+ * Overall, carrying the list of methods and base classes has worked well.
+ * It allows me to give the Ocaml user introspection over their objects.
+ */
+
+ int classHandler(Node *n) {
+ String *name = Getattr(n, "name");
+
+ if (!name)
+ return SWIG_OK;
+
+ String *mangled_sym_name = mangleNameForCaml(name);
+ String *this_class_def = NewString(f_classtemplate);
+ String *name_normalized = normalizeTemplatedClassName(name);
+ String *old_class_ctors = f_class_ctors;
+ String *base_classes = NewString("");
+ f_class_ctors = NewString("");
+ bool sizeof_feature = generate_sizeof && isSimpleType(name);
+
+
+ classname = mangled_sym_name;
+ classmode = true;
+ int rv = Language::classHandler(n);
+ classmode = false;
+
+ if (sizeof_feature) {
+ Printf(f_wrappers,
+ "SWIGEXT CAML_VALUE _wrap_%s_sizeof( CAML_VALUE args ) {\n"
+ " CAMLparam1(args);\n" " CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_sym_name, name_normalized);
+
+ Printf(f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", classname, mangled_sym_name);
+ }
+
+
+ /* Insert sizeof operator for concrete classes */
+ if (sizeof_feature) {
+ Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__", classname, "_sizeof ())) ;\n", NIL);
+ }
+ /* Handle up-casts in a nice way */
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator b;
+ b = First(baselist);
+ while (b.item) {
+ String *bname = Getattr(b.item, "name");
+ if (bname) {
+ String *base_create = NewString("");
+ Printv(base_create, "(create_class \"", bname, "\")", NIL);
+ Printv(f_class_ctors, " \"::", bname, "\", (fun args -> ", base_create, " args) ;\n", NIL);
+ Printv(base_classes, base_create, " ;\n", NIL);
+ }
+ b = Next(b);
+ }
+ }
+
+ Replaceall(this_class_def, "$classname", classname);
+ Replaceall(this_class_def, "$normalized", name_normalized);
+ Replaceall(this_class_def, "$realname", name);
+ Replaceall(this_class_def, "$baselist", base_classes);
+ Replaceall(this_class_def, "$classbody", f_class_ctors);
+
+ Delete(f_class_ctors);
+ f_class_ctors = old_class_ctors;
+
+ // Actually write out the class definition
+
+ Multiwrite(this_class_def);
+
+ Setattr(n, "ocaml:ctor", classname);
+
+ return rv;
+ }
+
+ String *normalizeTemplatedClassName(String *name) {
+ String *name_normalized = SwigType_typedef_resolve_all(name);
+ bool took_action;
+
+ do {
+ took_action = false;
+
+ if (is_a_pointer(name_normalized)) {
+ SwigType_del_pointer(name_normalized);
+ took_action = true;
+ }
+
+ if (is_a_reference(name_normalized)) {
+ oc_SwigType_del_reference(name_normalized);
+ took_action = true;
+ }
+
+ if (is_an_array(name_normalized)) {
+ oc_SwigType_del_array(name_normalized);
+ took_action = true;
+ }
+ } while (took_action);
+
+ return SwigType_str(name_normalized, 0);
+ }
+
+ /*
+ * Produce the symbol name that ocaml will use when referring to the
+ * target item. I wonder if there's a better way to do this:
+ *
+ * I shudder to think about doing it with a hash lookup, but that would
+ * make a couple of things easier:
+ */
+
+ String *mangleNameForCaml(String *s) {
+ String *out = Copy(s);
+ Replaceall(out, " ", "_xx");
+ Replaceall(out, "::", "_xx");
+ Replaceall(out, ",", "_x");
+ Replaceall(out, "+", "_xx_plus");
+ Replaceall(out, "-", "_xx_minus");
+ Replaceall(out, "<", "_xx_ldbrace");
+ Replaceall(out, ">", "_xx_rdbrace");
+ Replaceall(out, "!", "_xx_not");
+ Replaceall(out, "%", "_xx_mod");
+ Replaceall(out, "^", "_xx_xor");
+ Replaceall(out, "*", "_xx_star");
+ Replaceall(out, "&", "_xx_amp");
+ Replaceall(out, "|", "_xx_or");
+ Replaceall(out, "(", "_xx_lparen");
+ Replaceall(out, ")", "_xx_rparen");
+ Replaceall(out, "[", "_xx_lbrace");
+ Replaceall(out, "]", "_xx_rbrace");
+ Replaceall(out, "~", "_xx_bnot");
+ Replaceall(out, "=", "_xx_equals");
+ Replaceall(out, "/", "_xx_slash");
+ Replaceall(out, ".", "_xx_dot");
+ return out;
+ }
+
+ String *fully_qualify_enum_name(Node *n, String *name) {
+ Node *parent = 0;
+ String *qualification = NewString("");
+ String *fully_qualified_name = NewString("");
+ String *parent_type = 0;
+ String *normalized_name;
+
+ parent = parentNode(n);
+ while (parent) {
+ parent_type = nodeType(parent);
+ if (Getattr(parent, "name")) {
+ String *parent_copy = NewStringf("%s::", Getattr(parent, "name"));
+ if (!Cmp(parent_type, "class") || !Cmp(parent_type, "namespace"))
+ Insert(qualification, 0, parent_copy);
+ Delete(parent_copy);
+ }
+ if (!Cmp(parent_type, "class"))
+ break;
+ parent = parentNode(parent);
+ }
+
+ Printf(fully_qualified_name, "%s%s", qualification, name);
+
+ normalized_name = normalizeTemplatedClassName(fully_qualified_name);
+ if (!strncmp(Char(normalized_name), "enum ", 5)) {
+ Insert(normalized_name, 5, qualification);
+ }
+
+ return normalized_name;
+ }
+
+ /* Benedikt Grundmann inspired --> Enum wrap styles */
+
+ int enumvalueDeclaration(Node *n) {
+ String *name = Getattr(n, "name");
+ String *qvalue = 0;
+
+ if (name_qualifier) {
+ qvalue = Copy(name_qualifier);
+ Printv(qvalue, name, NIL);
+ }
+
+ if (const_enum && name && !Getattr(seen_enumvalues, name)) {
+ Setattr(seen_enumvalues, name, "true");
+ SetFlag(n, "feature:immutable");
+ Setattr(n, "feature:enumvalue", "1"); // this does not appear to be used
+
+ if (qvalue)
+ Setattr(n, "qualified:value", qvalue);
+
+ String *evname = SwigType_manglestr(qvalue);
+ Insert(evname, 0, "SWIG_ENUM_");
+
+ Setattr(n, "feature:enumvname", name);
+ Setattr(n, "feature:symname", evname);
+ Delete(evname);
+ Printf(f_enumtypes_value, "| `%s\n", name);
+
+ return Language::enumvalueDeclaration(n);
+ } else
+ return SWIG_OK;
+ }
+
+ /* -------------------------------------------------------------------
+ * This function is a bit uglier than it deserves.
+ *
+ * I used to direct lookup the name of the enum. Now that certain fixes
+ * have been made in other places, the names of enums are now fully
+ * qualified, which is a good thing, overall, but requires me to do
+ * some legwork.
+ *
+ * The other thing that uglifies this function is the varying way that
+ * typedef enum and enum are handled. I need to produce consistent names,
+ * which means looking up and registering by typedef and enum name. */
+ int enumDeclaration(Node *n) {
+ String *name = Getattr(n, "name");
+ if (name) {
+ String *oname = NewString(name);
+ /* name is now fully qualified */
+ String *fully_qualified_name = NewString(name);
+ bool seen_enum = false;
+ if (name_qualifier)
+ Delete(name_qualifier);
+ char *strip_position;
+ name_qualifier = fully_qualify_enum_name(n, NewString(""));
+
+ strip_position = strstr(Char(oname), "::");
+
+ while (strip_position) {
+ strip_position += 2;
+ oname = NewString(strip_position);
+ strip_position = strstr(Char(oname), "::");
+ }
+
+ seen_enum = (Getattr(seen_enums, fully_qualified_name) ? true : false);
+
+ if (!seen_enum) {
+ const_enum = true;
+ Printf(f_enum_to_int, "| `%s -> (match y with\n", oname);
+ Printf(f_int_to_enum, "| `%s -> C_enum (\n", oname);
+ /* * * * A note about enum name resolution * * * *
+ * This code should now work, but I think we can do a bit better.
+ * The problem I'm having is that swig isn't very precise about
+ * typedef name resolution. My opinion is that SwigType_typedef
+ * resolve_all should *always* return the enum tag if one exists,
+ * rather than the admittedly friendlier enclosing typedef.
+ *
+ * This would make one of the cases below unnecessary.
+ * * * */
+ Printf(f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", fully_qualified_name, oname);
+ if (!strncmp(Char(fully_qualified_name), "enum ", 5)) {
+ String *fq_noenum = NewString(Char(fully_qualified_name) + 5);
+ Printf(f_mlbody,
+ "let _ = Callback.register \"%s_marker\" (`%s)\n" "let _ = Callback.register \"%s_marker\" (`%s)\n", fq_noenum, oname, fq_noenum, name);
+ }
+
+ Printf(f_enumtypes_type, "| `%s\n", oname);
+ Insert(fully_qualified_name, 0, "enum ");
+ Setattr(seen_enums, fully_qualified_name, n);
+ }
+ }
+
+ int ret = Language::enumDeclaration(n);
+
+ if (const_enum) {
+ Printf(f_int_to_enum, "`Int y)\n");
+ Printf(f_enum_to_int, "| `Int x -> Swig.C_int x\n" "| _ -> raise (LabelNotFromThisEnum v))\n");
+ }
+
+ const_enum = false;
+
+ return ret;
+ }
+
+ /* ----------------------------------------------------------------------------
+ * BEGIN C++ Director Class modifications
+ * ------------------------------------------------------------------------- */
+
+ /*
+ * Modified polymorphism code for Ocaml language module.
+ * Original:
+ * C++/Python polymorphism demo code, copyright (C) 2002 Mark Rose
+ * <mrose@stm.lbl.gov>
+ *
+ * TODO
+ *
+ * Move some boilerplate code generation to Swig_...() functions.
+ *
+ */
+
+ /* ---------------------------------------------------------------
+ * classDirectorMethod()
+ *
+ * Emit a virtual director method to pass a method call on to the
+ * underlying Python object.
+ *
+ * --------------------------------------------------------------- */
+
+ int classDirectorMethod(Node *n, Node *parent, String *super) {
+ int is_void = 0;
+ int is_pointer = 0;
+ String *storage;
+ String *value;
+ String *decl;
+ String *type;
+ String *name;
+ String *classname;
+ String *c_classname = Getattr(parent, "name");
+ String *declaration;
+ ParmList *l;
+ Wrapper *w;
+ String *tm;
+ String *wrap_args = NewString("");
+ String *return_type;
+ int status = SWIG_OK;
+ int idx;
+ bool pure_virtual = false;
+ bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
+
+ storage = Getattr(n, "storage");
+ value = Getattr(n, "value");
+ classname = Getattr(parent, "sym:name");
+ type = Getattr(n, "type");
+ name = Getattr(n, "name");
+
+ if (Cmp(storage, "virtual") == 0) {
+ if (Cmp(value, "0") == 0) {
+ pure_virtual = true;
+ }
+ }
+
+ w = NewWrapper();
+ declaration = NewString("");
+ Wrapper_add_local(w, "swig_result", "CAMLparam0();\n" "SWIG_CAMLlocal2(swig_result,args)");
+
+ /* determine if the method returns a pointer */
+ decl = Getattr(n, "decl");
+ is_pointer = SwigType_ispointer_return(decl);
+ is_void = (!Cmp(type, "void") && !is_pointer);
+
+ /* form complete return type */
+ return_type = Copy(type);
+ {
+ SwigType *t = Copy(decl);
+ SwigType *f = 0;
+ f = SwigType_pop_function(t);
+ SwigType_push(return_type, t);
+ Delete(f);
+ Delete(t);
+ }
+
+ /* virtual method definition */
+ l = Getattr(n, "parms");
+ String *target;
+ String *pclassname = NewStringf("SwigDirector_%s", classname);
+ String *qualified_name = NewStringf("%s::%s", pclassname, name);
+ SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type;
+ target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+ Printf(w->def, "%s {", target);
+ Delete(qualified_name);
+ Delete(target);
+ /* header declaration */
+ target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+ Printf(declaration, " virtual %s;", target);
+ Delete(target);
+
+ /* declare method return value
+ * if the return value is a reference or const reference, a specialized typemap must
+ * handle it, including declaration of c_result ($result).
+ */
+ if (!is_void) {
+ if (!(ignored_method && !pure_virtual)) {
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL);
+ }
+ }
+
+ if (ignored_method) {
+ if (!pure_virtual) {
+ if (!is_void)
+ Printf(w->code, "return ");
+ String *super_call = Swig_method_call(super, l);
+ Printf(w->code, "%s;\n", super_call);
+ Delete(super_call);
+ } else {
+ Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
+ SwigType_namestr(name));
+ }
+ } else {
+ /* attach typemaps to arguments (C/C++ -> Ocaml) */
+ String *arglist = NewString("");
+
+ Swig_typemap_attach_parms("in", l, 0);
+ Swig_typemap_attach_parms("directorin", l, 0);
+ Swig_typemap_attach_parms("directorargout", l, w);
+
+ Parm *p;
+ int num_arguments = emit_num_arguments(l);
+ int i;
+ char source[256];
+
+ int outputs = 0;
+ if (!is_void)
+ outputs++;
+
+ /* build argument list and type conversion string */
+ for (i = 0, idx = 0, p = l; i < num_arguments; i++) {
+
+ while (Getattr(p, "tmap:ignore")) {
+ p = Getattr(p, "tmap:ignore:next");
+ }
+
+ if (Getattr(p, "tmap:directorargout") != 0)
+ outputs++;
+
+ String *pname = Getattr(p, "name");
+ String *ptype = Getattr(p, "type");
+
+ Putc(',', arglist);
+ if ((tm = Getattr(p, "tmap:directorin")) != 0) {
+ Replaceall(tm, "$input", pname);
+ Replaceall(tm, "$owner", "0");
+ if (Len(tm) == 0)
+ Append(tm, pname);
+ Printv(wrap_args, tm, "\n", NIL);
+ p = Getattr(p, "tmap:directorin:next");
+ continue;
+ } else if (Cmp(ptype, "void")) {
+ /* special handling for pointers to other C++ director classes.
+ * ideally this would be left to a typemap, but there is currently no
+ * way to selectively apply the dynamic_cast<> to classes that have
+ * directors. in other words, the type "SwigDirector_$1_lname" only exists
+ * for classes with directors. we avoid the problem here by checking
+ * module.wrap::directormap, but it's not clear how to get a typemap to
+ * do something similar. perhaps a new default typemap (in addition
+ * to SWIGTYPE) called DIRECTORTYPE?
+ */
+ if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
+ Node *module = Getattr(parent, "module");
+ Node *target = Swig_directormap(module, ptype);
+ sprintf(source, "obj%d", idx++);
+ String *nonconst = 0;
+ /* strip pointer/reference --- should move to Swig/stype.c */
+ String *nptype = NewString(Char(ptype) + 2);
+ /* name as pointer */
+ String *ppname = Copy(pname);
+ if (SwigType_isreference(ptype)) {
+ Insert(ppname, 0, "&");
+ }
+ /* if necessary, cast away const since Python doesn't support it! */
+ if (SwigType_isconst(nptype)) {
+ nonconst = NewStringf("nc_tmp_%s", pname);
+ String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(ptype, 0), ppname);
+ Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
+ Delete(nonconst_i);
+ Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
+ "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(ptype, pname),
+ SwigType_namestr(c_classname), SwigType_namestr(name));
+ } else {
+ nonconst = Copy(ppname);
+ }
+ Delete(nptype);
+ Delete(ppname);
+ String *mangle = SwigType_manglestr(ptype);
+ if (target) {
+ String *director = NewStringf("director_%s", mangle);
+ Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
+ Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
+ Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
+ Printf(wrap_args, "if (!%s) {\n", director);
+ Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
+ Printf(wrap_args, "} else {\n");
+ Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
+ Printf(wrap_args, "}\n");
+ Delete(director);
+ Printv(arglist, source, NIL);
+ } else {
+ Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
+ Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
+ //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
+ // source, nonconst, base);
+ Printv(arglist, source, NIL);
+ }
+ Delete(mangle);
+ Delete(nonconst);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
+ SwigType_namestr(c_classname), SwigType_namestr(name));
+ status = SWIG_NOWRAP;
+ break;
+ }
+ }
+ p = nextSibling(p);
+ }
+
+ Printv(w->code, "swig_result = Val_unit;\n", 0);
+ Printf(w->code, "args = Val_unit;\n");
+
+ /* wrap complex arguments to values */
+ Printv(w->code, wrap_args, NIL);
+
+ /* pass the method call on to the Python object */
+ Printv(w->code,
+ "swig_result = caml_swig_alloc(1,C_list);\n" "SWIG_Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0);
+ Printf(w->code, "swig_result = " "callback3(*caml_named_value(\"swig_runmethod\")," "swig_get_self(),copy_string(\"%s\"),args);\n", Getattr(n, "name"));
+ /* exception handling */
+ tm = Swig_typemap_lookup("director:except", n, "result", 0);
+ if (!tm) {
+ tm = Getattr(n, "feature:director:except");
+ }
+ if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
+ Printf(w->code, "if (result == NULL) {\n");
+ Printf(w->code, " CAML_VALUE error = *caml_named_value(\"director_except\");\n");
+ Replaceall(tm, "$error", "error");
+ Printv(w->code, Str(tm), "\n", NIL);
+ Printf(w->code, "}\n");
+ }
+
+ /*
+ * Python method may return a simple object, or a tuple.
+ * for in/out aruments, we have to extract the appropriate values from the
+ * argument list, then marshal everything back to C/C++ (return value and
+ * output arguments).
+ */
+
+ /* marshal return value and other outputs (if any) from value to C/C++
+ * type */
+
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+
+ idx = 0;
+
+ /* this seems really silly. the node's type excludes
+ * qualifier/pointer/reference markers, which have to be retrieved
+ * from the decl field to construct return_type. but the typemap
+ * lookup routine uses the node's type, so we have to swap in and
+ * out the correct type. it's not just me, similar silliness also
+ * occurs in Language::cDeclaration().
+ */
+ Setattr(n, "type", return_type);
+ tm = Swig_typemap_lookup("directorout", n, "c_result", w);
+ Setattr(n, "type", type);
+ if (tm != 0) {
+ Replaceall(tm, "$input", "swig_result");
+ /* TODO check this */
+ if (Getattr(n, "wrap:disown")) {
+ Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm, "$disown", "0");
+ }
+ Replaceall(tm, "$result", "c_result");
+ Printv(w->code, tm, "\n", NIL);
+ }
+
+ /* marshal outputs */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
+ Replaceall(tm, "$input", "swig_result");
+ Replaceall(tm, "$result", Getattr(p, "name"));
+ Printv(w->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:directorargout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ Delete(arglist);
+ Delete(cleanup);
+ Delete(outarg);
+ }
+
+ /* any existing helper functions to handle this? */
+ if (!is_void) {
+ if (!(ignored_method && !pure_virtual)) {
+ /* A little explanation:
+ * The director_enum test case makes a method whose return type
+ * is an enum type. return_type here is "int". gcc complains
+ * about an implicit enum conversion, and although i don't strictly
+ * agree with it, I'm working on fixing the error:
+ *
+ * Below is what I came up with. It's not great but it should
+ * always essentially work.
+ */
+ if (!SwigType_isreference(return_type)) {
+ Printf(w->code, "CAMLreturn_type((%s)c_result);\n", SwigType_lstr(return_type, ""));
+ } else {
+ Printf(w->code, "CAMLreturn_type(*c_result);\n");
+ }
+ }
+ }
+
+ Printf(w->code, "}\n");
+
+ // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
+ String *inline_extra_method = NewString("");
+ if (dirprot_mode() && !is_public(n) && !pure_virtual) {
+ Printv(inline_extra_method, declaration, NIL);
+ String *extra_method_name = NewStringf("%sSwigPublic", name);
+ Replaceall(inline_extra_method, name, extra_method_name);
+ Replaceall(inline_extra_method, ";\n", " {\n ");
+ if (!is_void)
+ Printf(inline_extra_method, "return ");
+ String *methodcall = Swig_method_call(super, l);
+ Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
+ Delete(methodcall);
+ Delete(extra_method_name);
+ }
+
+ /* emit the director method */
+ if (status == SWIG_OK) {
+ if (!Getattr(n, "defaultargs")) {
+ Wrapper_print(w, f_directors);
+ Printv(f_directors_h, declaration, NIL);
+ Printv(f_directors_h, inline_extra_method, NIL);
+ }
+ }
+
+ /* clean up */
+ Delete(wrap_args);
+ Delete(return_type);
+ Delete(pclassname);
+ DelWrapper(w);
+ return status;
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorConstructor()
+ * ------------------------------------------------------------ */
+
+ int classDirectorConstructor(Node *n) {
+ Node *parent = Getattr(n, "parentNode");
+ String *sub = NewString("");
+ String *decl = Getattr(n, "decl");
+ String *supername = Swig_class_name(parent);
+ String *classname = NewString("");
+ Printf(classname, "SwigDirector_%s", supername);
+
+ /* insert self parameter */
+ Parm *p, *q;
+ ParmList *superparms = Getattr(n, "parms");
+ ParmList *parms = CopyParmList(superparms);
+ String *type = NewString("CAML_VALUE");
+ p = NewParm(type, NewString("self"));
+ q = Copy(p);
+ set_nextSibling(q, superparms);
+ set_nextSibling(p, parms);
+ parms = p;
+
+ if (!Getattr(n, "defaultargs")) {
+ /* constructor */
+ {
+ Wrapper *w = NewWrapper();
+ String *call;
+ String *basetype = Getattr(parent, "classtype");
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+ call = Swig_csuperclass_call(0, basetype, superparms);
+ Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
+ Delete(target);
+ Wrapper_print(w, f_directors);
+ Delete(call);
+ DelWrapper(w);
+ }
+
+ /* constructor header */
+ {
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+ Printf(f_directors_h, " %s;\n", target);
+ Delete(target);
+ }
+ }
+
+ Setattr(n, "parms", q);
+ Language::classDirectorConstructor(n);
+
+ Delete(sub);
+ Delete(classname);
+ Delete(supername);
+ //Delete(parms);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorDefaultConstructor()
+ * ------------------------------------------------------------ */
+
+ int classDirectorDefaultConstructor(Node *n) {
+ String *classname;
+ classname = Swig_class_name(n);
+
+ /* insert self parameter */
+ Parm *p, *q;
+ ParmList *superparms = Getattr(n, "parms");
+ ParmList *parms = CopyParmList(superparms);
+ String *type = NewString("CAML_VALUE");
+ p = NewParm(type, NewString("self"));
+ q = Copy(p);
+ set_nextSibling(p, parms);
+ parms = p;
+
+ {
+ Wrapper *w = NewWrapper();
+ Printf(w->def, "SwigDirector_%s::SwigDirector_%s(CAML_VALUE self) : Swig::Director(self) { }", classname, classname);
+ Wrapper_print(w, f_directors);
+ DelWrapper(w);
+ }
+ Printf(f_directors_h, " SwigDirector_%s(CAML_VALUE self);\n", classname);
+ Delete(classname);
+ Setattr(n, "parms", q);
+ return Language::classDirectorDefaultConstructor(n);
+ }
+
+ int classDirectorInit(Node *n) {
+ String *declaration = Swig_director_declaration(n);
+ Printf(f_directors_h, "\n" "%s\n" "public:\n", declaration);
+ Delete(declaration);
+ return Language::classDirectorInit(n);
+ }
+
+ int classDirectorEnd(Node *n) {
+ Printf(f_directors_h, "};\n\n");
+ return Language::classDirectorEnd(n);
+ }
+
+ /* ---------------------------------------------------------------------
+ * typedefHandler
+ *
+ * This is here in order to maintain the correct association between
+ * typedef names and enum names.
+ *
+ * Since I implement enums as polymorphic variant tags, I need to call
+ * back into ocaml to evaluate them. This requires a string that can
+ * be generated in the typemaps, and also at SWIG time to be the same
+ * string. The problem that arises is that SWIG variously generates
+ * enum e_name_tag
+ * e_name_tag
+ * e_typedef_name
+ * for
+ * typedef enum e_name_tag { ... } e_typedef_name;
+ *
+ * Since I need these strings to be consistent, I must maintain a correct
+ * association list between typedef and enum names.
+ * --------------------------------------------------------------------- */
+ int typedefHandler(Node *n) {
+ String *type = Getattr(n, "type");
+ Node *enum_node = type ? Getattr(seen_enums, type) : 0;
+ if (enum_node) {
+ String *name = Getattr(enum_node, "name");
+
+ Printf(f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", Getattr(n, "name"), name);
+
+ }
+ return SWIG_OK;
+ }
+
+ String *runtimeCode() {
+ String *s = Swig_include_sys("ocaml.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'ocaml.swg'\n");
+ s = NewString("");
+ }
+ return s;
+ }
+
+ String *defaultExternalRuntimeFilename() {
+ return NewString("swigocamlrun.h");
+ }
+};
+
+/* -------------------------------------------------------------------------
+ * swig_ocaml() - Instantiate module
+ * ------------------------------------------------------------------------- */
+
+static Language *new_swig_ocaml() {
+ return new OCAML();
+}
+extern "C" Language *swig_ocaml(void) {
+ return new_swig_ocaml();
+}
diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx
new file mode 100644
index 0000000..aeb72f7
--- /dev/null
+++ b/Source/Modules/octave.cxx
@@ -0,0 +1,1425 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * octave.cxx
+ *
+ * Octave language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_octave_cxx[] = "$Id$";
+
+#include "swigmod.h"
+
+static const char *usage = (char *) "\
+Octave Options (available with -octave)\n\
+ -api <N> - Generate code that assumes Octave API N [default: 37]\n\
+ \n";
+
+
+class OCTAVE:public Language {
+private:
+ File *f_begin;
+ File *f_runtime;
+ File *f_header;
+ File *f_doc;
+ File *f_wrappers;
+ File *f_init;
+ File *f_initbeforefunc;
+ File *f_directors;
+ File *f_directors_h;
+ String *s_global_tab;
+ String *s_members_tab;
+ String *class_name;
+
+ int have_constructor;
+ int have_destructor;
+ String *constructor_name;
+
+ int api_version;
+
+ Hash *docs;
+
+public:
+ OCTAVE():f_begin(0), f_runtime(0), f_header(0), f_doc(0), f_wrappers(0),
+ f_init(0), f_initbeforefunc(0), f_directors(0), f_directors_h(0),
+ s_global_tab(0), s_members_tab(0), class_name(0) {
+ /* Add code to manage protected constructors and directors */
+ director_prot_ctor_code = NewString("");
+ Printv(director_prot_ctor_code,
+ "if ( $comparison ) { /* subclassed */\n",
+ " $director_new \n",
+ "} else {\n", " error(\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL);
+
+ enable_cplus_runtime_mode();
+ allow_overloading();
+ director_multiple_inheritance = 1;
+ director_language = 1;
+ docs = NewHash();
+ api_version = 0;
+ }
+
+ virtual void main(int argc, char *argv[]) {
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-help") == 0) {
+ fputs(usage, stderr);
+ } else if (strcmp(argv[i], "-api") == 0) {
+ if (argv[i + 1]) {
+ api_version = atoi(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ }
+ }
+ }
+
+ SWIG_library_directory("octave");
+ Preprocessor_define("SWIGOCTAVE 1", 0);
+ SWIG_config_file("octave.swg");
+ SWIG_typemap_lang("octave");
+ allow_overloading();
+ }
+
+ virtual int top(Node *n) {
+ {
+ Node *mod = Getattr(n, "module");
+ if (mod) {
+ Node *options = Getattr(mod, "options");
+ if (options) {
+ int dirprot = 0;
+ if (Getattr(options, "dirprot")) {
+ dirprot = 1;
+ }
+ if (Getattr(options, "nodirprot")) {
+ dirprot = 0;
+ }
+ if (Getattr(options, "directors")) {
+ allow_directors();
+ if (dirprot)
+ allow_dirprot();
+ }
+ }
+ }
+ }
+
+ String *module = Getattr(n, "name");
+ String *outfile = Getattr(n, "outfile");
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ f_header = NewString("");
+ f_doc = NewString("");
+ f_wrappers = NewString("");
+ f_init = NewString("");
+ f_initbeforefunc = NewString("");
+ f_directors_h = NewString("");
+ f_directors = NewString("");
+ s_global_tab = NewString("");
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("doc", f_doc);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("init", f_init);
+ Swig_register_filebyname("initbeforefunc", f_initbeforefunc);
+ Swig_register_filebyname("director", f_directors);
+ Swig_register_filebyname("director_h", f_directors_h);
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGOCTAVE\n");
+ Printf(f_runtime, "#define SWIG_name_d \"%s\"\n", module);
+ Printf(f_runtime, "#define SWIG_name %s\n", module);
+ Printf(f_runtime, "#define OCTAVE_API_VERSION_OPTION %i\n", api_version);
+
+ if (directorsEnabled()) {
+ Printf(f_runtime, "#define SWIG_DIRECTORS\n");
+ Swig_banner(f_directors_h);
+ if (dirprot_mode()) {
+ // Printf(f_directors_h, "#include <map>\n");
+ // Printf(f_directors_h, "#include <string>\n\n");
+ }
+ }
+
+ Printf(f_runtime, "\n");
+
+ Printf(s_global_tab, "\nstatic const struct swig_octave_member swig_globals[] = {\n");
+ Printf(f_init, "static void SWIG_init_user(octave_swig_type* module_ns)\n{\n");
+
+ if (!CPlusPlus)
+ Printf(f_header,"extern \"C\" {\n");
+
+ Language::top(n);
+
+ if (!CPlusPlus)
+ Printf(f_header,"}\n");
+
+ if (Len(docs))
+ emit_doc_texinfo();
+
+ if (directorsEnabled())
+ Swig_insert_file("director.swg", f_runtime);
+
+ Printf(f_init, "}\n");
+ Printf(s_global_tab, "{0,0,0,0,0}\n};\n");
+
+ Printv(f_wrappers, s_global_tab, NIL);
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_doc, f_begin);
+ if (directorsEnabled()) {
+ Dump(f_directors_h, f_begin);
+ Dump(f_directors, f_begin);
+ }
+ Dump(f_wrappers, f_begin);
+ Dump(f_initbeforefunc, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+
+ Delete(s_global_tab);
+ Delete(f_initbeforefunc);
+ Delete(f_init);
+ Delete(f_wrappers);
+ Delete(f_doc);
+ Delete(f_header);
+ Delete(f_directors);
+ Delete(f_directors_h);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+
+ return SWIG_OK;
+ }
+
+ String *texinfo_escape(String *_s) {
+ const char* s=(const char*)Data(_s);
+ while (*s&&(*s=='\t'||*s=='\r'||*s=='\n'||*s==' '))
+ ++s;
+ String *r = NewString("");
+ for (int j=0;s[j];++j) {
+ if (s[j] == '\n') {
+ Append(r, "\\n\\\n");
+ } else if (s[j] == '\r') {
+ Append(r, "\\r");
+ } else if (s[j] == '\t') {
+ Append(r, "\\t");
+ } else if (s[j] == '\\') {
+ Append(r, "\\\\");
+ } else if (s[j] == '\'') {
+ Append(r, "\\\'");
+ } else if (s[j] == '\"') {
+ Append(r, "\\\"");
+ } else
+ Putc(s[j], r);
+ }
+ return r;
+ }
+ void emit_doc_texinfo() {
+ for (Iterator it = First(docs); it.key; it = Next(it)) {
+ String *wrap_name = it.key;
+
+ String *synopsis = Getattr(it.item, "synopsis");
+ String *decl_info = Getattr(it.item, "decl_info");
+ String *cdecl_info = Getattr(it.item, "cdecl_info");
+ String *args_info = Getattr(it.item, "args_info");
+
+ String *doc_str = NewString("");
+ Printv(doc_str, synopsis, decl_info, cdecl_info, args_info, NIL);
+ String *escaped_doc_str = texinfo_escape(doc_str);
+
+ if (Len(doc_str)>0) {
+ Printf(f_doc,"const char* %s_texinfo = ",wrap_name);
+ Printf(f_doc,"\"-*- texinfo -*-\\n\\\n%s", escaped_doc_str);
+ if (Len(decl_info))
+ Printf(f_doc,"\\n\\\n@end deftypefn");
+ Printf(f_doc,"\";\n");
+ }
+
+ Delete(escaped_doc_str);
+ Delete(doc_str);
+ Delete(wrap_name);
+ }
+ Printf(f_doc,"\n");
+ }
+ bool is_empty_doc_node(Node* n) {
+ if (!n)
+ return true;
+ String *synopsis = Getattr(n, "synopsis");
+ String *decl_info = Getattr(n, "decl_info");
+ String *cdecl_info = Getattr(n, "cdecl_info");
+ String *args_info = Getattr(n, "args_info");
+ return !Len(synopsis) && !Len(decl_info) &&
+ !Len(cdecl_info) && !Len(args_info);
+ }
+ String *texinfo_name(Node* n) {
+ String *tname = NewString("");
+ String *iname = Getattr(n, "sym:name");
+ String *wname = Swig_name_wrapper(iname);
+ Node* d = Getattr(docs, wname);
+
+ if (is_empty_doc_node(d))
+ Printf(tname, "0");
+ else
+ Printf(tname, "%s_texinfo", wname);
+
+ return tname;
+ }
+ void process_autodoc(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+ String *name = Getattr(n, "name");
+ String *wname = Swig_name_wrapper(iname);
+ String *str = Getattr(n, "feature:docstring");
+ bool autodoc_enabled = !Cmp(Getattr(n, "feature:autodoc"), "1");
+ Node* d = Getattr(docs, wname);
+ if (!d) {
+ d = NewHash();
+ Setattr(d, "synopsis", NewString(""));
+ Setattr(d, "decl_info", NewString(""));
+ Setattr(d, "cdecl_info", NewString(""));
+ Setattr(d, "args_info", NewString(""));
+ Setattr(docs, wname, d);
+ }
+
+ String *synopsis = Getattr(d, "synopsis");
+ String *decl_info = Getattr(d, "decl_info");
+ // String *cdecl_info = Getattr(d, "cdecl_info");
+ String *args_info = Getattr(d, "args_info");
+
+ // * couldn't we just emit the docs here?
+
+ if (autodoc_enabled) {
+ String *decl_str = NewString("");
+ String *args_str = NewString("");
+ make_autodocParmList(n, decl_str, args_str);
+ Append(decl_info, "@deftypefn {Loadable Function} ");
+
+ SwigType *type = Getattr(n, "type");
+ if (type && Strcmp(type, "void")) {
+ type = SwigType_base(type);
+ Node *lookup = Swig_symbol_clookup(type, 0);
+ if (lookup)
+ type = Getattr(lookup, "sym:name");
+ Append(decl_info, "@var{retval} = ");
+ String *type_str = NewString("");
+ Printf(type_str, "@var{retval} is of type %s. ", type);
+ Append(args_str, type_str);
+ Delete(type_str);
+ }
+
+ Append(decl_info, name);
+ Append(decl_info, " (");
+ Append(decl_info, decl_str);
+ Append(decl_info, ")\n");
+ Append(args_info, args_str);
+ Delete(decl_str);
+ Delete(args_str);
+ }
+
+ if (str && Len(str) > 0) {
+ // strip off {} if necessary
+ char *t = Char(str);
+ if (*t == '{') {
+ Delitem(str, 0);
+ Delitem(str, DOH_END);
+ }
+
+ // emit into synopsis section
+ Append(synopsis, str);
+ }
+ }
+
+ virtual int importDirective(Node *n) {
+ String *modname = Getattr(n, "module");
+ if (modname)
+ Printf(f_init, "feval(\"%s\",octave_value_list(),0);\n", modname);
+ return Language::importDirective(n);
+ }
+
+ const char *get_implicitconv_flag(Node *n) {
+ int conv = 0;
+ if (n && GetFlag(n, "feature:implicitconv")) {
+ conv = 1;
+ }
+ return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "0";
+ }
+
+ void make_autodocParmList(Node *n, String *decl_str, String *args_str) {
+ String *pdocs = Copy(Getattr(n, "feature:pdocs"));
+ ParmList *plist = CopyParmList(Getattr(n, "parms"));
+ Parm *p;
+ Parm *pnext;
+ Node *lookup;
+
+ if (pdocs)
+ Append(pdocs, "\n");
+
+ Swig_typemap_attach_parms("in", plist, 0);
+ Swig_typemap_attach_parms("doc", plist, 0);
+
+ for (p = plist; p; p = pnext) {
+ String *name = 0;
+ String *type = 0;
+ String *value = 0;
+ String *ptype = 0;
+ String *pdoc = Getattr(p, "tmap:doc");
+ if (pdoc) {
+ name = Getattr(p, "tmap:doc:name");
+ type = Getattr(p, "tmap:doc:type");
+ value = Getattr(p, "tmap:doc:value");
+ ptype = Getattr(p, "tmap:doc:pytype");
+ }
+
+ name = name ? name : Getattr(p, "name");
+ type = type ? type : Getattr(p, "type");
+ value = value ? value : Getattr(p, "value");
+
+ String *tex_name = NewString("");
+ if (name)
+ Printf(tex_name, "@var{%s}", name);
+ else
+ Printf(tex_name, "@var{?}");
+
+ String *tm = Getattr(p, "tmap:in");
+ if (tm) {
+ pnext = Getattr(p, "tmap:in:next");
+ } else {
+ pnext = nextSibling(p);
+ }
+
+ if (Len(decl_str))
+ Append(decl_str, ", ");
+ Append(decl_str, tex_name);
+
+ if (value) {
+ if (Strcmp(value, "NULL") == 0)
+ value = NewString("nil");
+ else if (Strcmp(value, "true") == 0 || Strcmp(value, "TRUE") == 0)
+ value = NewString("true");
+ else if (Strcmp(value, "false") == 0 || Strcmp(value, "FALSE") == 0)
+ value = NewString("false");
+ else {
+ lookup = Swig_symbol_clookup(value, 0);
+ if (lookup)
+ value = Getattr(lookup, "sym:name");
+ }
+ Printf(decl_str, " = %s", value);
+ }
+
+ if (type) {
+ String *type_str = NewString("");
+ type = SwigType_base(type);
+ lookup = Swig_symbol_clookup(type, 0);
+ if (lookup)
+ type = Getattr(lookup, "sym:name");
+ Printf(type_str, "%s is of type %s. ", tex_name, type);
+ Append(args_str, type_str);
+ Delete(type_str);
+ }
+
+ Delete(tex_name);
+ }
+ if (pdocs)
+ Setattr(n, "feature:pdocs", pdocs);
+ Delete(plist);
+ }
+
+ virtual int functionWrapper(Node *n) {
+ Wrapper *f = NewWrapper();
+ Parm *p;
+ String *tm;
+ int j;
+
+ String *nodeType = Getattr(n, "nodeType");
+ int constructor = (!Cmp(nodeType, "constructor"));
+ int destructor = (!Cmp(nodeType, "destructor"));
+ String *storage = Getattr(n, "storage");
+
+ bool overloaded = !!Getattr(n, "sym:overloaded");
+ bool last_overload = overloaded && !Getattr(n, "sym:nextSibling");
+ String *iname = Getattr(n, "sym:name");
+ String *wname = Swig_name_wrapper(iname);
+ String *overname = Copy(wname);
+ SwigType *d = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+
+ if (!overloaded && !addSymbol(iname, n))
+ return SWIG_ERROR;
+
+ if (overloaded)
+ Append(overname, Getattr(n, "sym:overname"));
+
+ Printv(f->def, "static octave_value_list ", overname, " (const octave_value_list& args, int nargout) {", NIL);
+
+ emit_parameter_variables(l, f);
+ emit_attach_parmmaps(l, f);
+ Setattr(n, "wrap:parms", l);
+
+ int num_arguments = emit_num_arguments(l);
+ int num_required = emit_num_required(l);
+ int varargs = emit_isvarargs(l);
+ char source[64];
+
+ Printf(f->code, "if (!SWIG_check_num_args(\"%s\",args.length(),%i,%i,%i)) "
+ "{\n SWIG_fail;\n }\n", iname, num_arguments, num_required, varargs);
+
+ if (constructor && num_arguments == 1 && num_required == 1) {
+ if (Cmp(storage, "explicit") == 0) {
+ Node *parent = Swig_methodclass(n);
+ if (GetFlag(parent, "feature:implicitconv")) {
+ String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type")));
+ Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc);
+ Delete(desc);
+ }
+ }
+ }
+
+ for (j = 0, p = l; j < num_arguments; ++j) {
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+
+ String *tm = Getattr(p, "tmap:in");
+ if (tm) {
+ if (!tm || checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = nextSibling(p);
+ continue;
+ }
+
+ sprintf(source, "args(%d)", j);
+ Setattr(p, "emit:input", source);
+
+ Replaceall(tm, "$source", Getattr(p, "emit:input"));
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+
+ if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
+ Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm, "$disown", "0");
+ }
+
+ if (Getattr(p, "tmap:in:implicitconv")) {
+ const char *convflag = "0";
+ if (!Getattr(p, "hidden")) {
+ SwigType *ptype = Getattr(p, "type");
+ convflag = get_implicitconv_flag(classLookup(ptype));
+ }
+ Replaceall(tm, "$implicitconv", convflag);
+ Setattr(p, "implicitconv", convflag);
+ }
+
+ String *getargs = NewString("");
+ if (j >= num_required)
+ Printf(getargs, "if (%d<args.length()) {\n%s\n}", j, tm);
+ else
+ Printv(getargs, tm, NIL);
+ Printv(f->code, getargs, "\n", NIL);
+ Delete(getargs);
+
+ 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;
+ }
+ }
+
+ // 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"))) {
+ if (Getattr(p, "tmap:freearg:implicitconv")) {
+ const char *convflag = "0";
+ if (!Getattr(p, "hidden")) {
+ SwigType *ptype = Getattr(p, "type");
+ convflag = get_implicitconv_flag(classLookup(ptype));
+ }
+ if (strcmp(convflag, "0") == 0) {
+ tm = 0;
+ }
+ }
+ if (tm && (Len(tm) != 0)) {
+ 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", "_outp");
+ Replaceall(tm, "$result", "_outp");
+ 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);
+ }
+ }
+
+ int director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
+ if (director_method) {
+ Wrapper_add_local(f, "upcall", "bool upcall = false");
+ Append(f->code, "upcall = !!dynamic_cast<Swig::Director*>(arg1);\n");
+ }
+
+ Setattr(n, "wrap:name", overname);
+
+ Swig_director_emit_dynamic_cast(n, f);
+ String *actioncode = emit_action(n);
+
+ Wrapper_add_local(f, "_out", "octave_value_list _out");
+ Wrapper_add_local(f, "_outp", "octave_value_list *_outp=&_out");
+ Wrapper_add_local(f, "_outv", "octave_value _outv");
+
+ // Return the function value
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$target", "_outv");
+ Replaceall(tm, "$result", "_outv");
+
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "1");
+ else
+ Replaceall(tm, "$owner", "0");
+
+ Printf(f->code, "%s\n", tm);
+ Printf(f->code, "if (_outv.is_defined()) _outp = " "SWIG_Octave_AppendOutput(_outp, _outv);\n");
+ Delete(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), iname);
+ }
+ emit_return_variable(n, d, f);
+
+ Printv(f->code, outarg, NIL);
+ Printv(f->code, cleanup, NIL);
+
+ if (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$result", "_outv");
+ Printf(f->code, "%s\n", tm);
+ Delete(tm);
+ }
+
+ Printf(f->code, "fail:\n"); // we should free locals etc if this happens
+ Printf(f->code, "return _out;\n");
+ Printf(f->code, "}\n");
+
+ Replaceall(f->code, "$symname", iname);
+ Wrapper_print(f, f_wrappers);
+ DelWrapper(f);
+
+ if (last_overload)
+ dispatchFunction(n);
+
+ if (!overloaded || last_overload) {
+ process_autodoc(n);
+ String *tname = texinfo_name(n);
+ Printf(s_global_tab, "{\"%s\",%s,0,0,2,%s},\n", iname, wname, tname);
+ Delete(tname);
+ }
+
+ Delete(overname);
+ Delete(wname);
+ Delete(cleanup);
+ Delete(outarg);
+
+ return SWIG_OK;
+ }
+
+ void dispatchFunction(Node *n) {
+ Wrapper *f = NewWrapper();
+
+ String *iname = Getattr(n, "sym:name");
+ String *wname = Swig_name_wrapper(iname);
+ int maxargs;
+ String *dispatch = Swig_overload_dispatch(n, "return %s(args, nargout);", &maxargs);
+ String *tmp = NewString("");
+
+ Printv(f->def, "static octave_value_list ", wname, " (const octave_value_list& args, int nargout) {", NIL);
+ Wrapper_add_local(f, "argc", "int argc = args.length()");
+ Printf(tmp, "octave_value_ref argv[%d]={", maxargs);
+ for (int j = 0; j < maxargs; ++j)
+ Printf(tmp, "%soctave_value_ref(args,%d)", j ? "," : " ", j);
+ Printf(tmp, "}");
+ Wrapper_add_local(f, "argv", tmp);
+ Printv(f->code, dispatch, "\n", NIL);
+ Printf(f->code, "error(\"No matching function for overload\");\n", iname);
+ Printf(f->code, "return octave_value_list();\n");
+ Printv(f->code, "}\n", NIL);
+
+ Wrapper_print(f, f_wrappers);
+ Delete(tmp);
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(wname);
+ }
+
+ virtual int variableWrapper(Node *n) {
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+
+ String *tm;
+ Wrapper *getf = NewWrapper();
+ Wrapper *setf = NewWrapper();
+
+ String *getname = Swig_name_get(iname);
+ String *setname = Swig_name_set(iname);
+
+ Printf(setf->def, "static octave_value_list _wrap_%s(const octave_value_list& args,int nargout) {", setname);
+ Printf(setf->def, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
+ if (is_assignable(n)) {
+ Setattr(n, "wrap:name", setname);
+ if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
+ Replaceall(tm, "$source", "args(0)");
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$input", "args(0)");
+ if (Getattr(n, "tmap:varin:implicitconv")) {
+ Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
+ }
+ emit_action_code(n, setf->code, 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));
+ }
+ Append(setf->code, "fail:\n");
+ Printf(setf->code, "return octave_value_list();\n");
+ } else {
+ Printf(setf->code, "return octave_set_immutable(args,nargout);");
+ }
+ Append(setf->code, "}\n");
+ Wrapper_print(setf, f_wrappers);
+
+ Setattr(n, "wrap:name", getname);
+ int addfail = 0;
+ Printf(getf->def, "static octave_value_list _wrap_%s(const octave_value_list& args,int nargout) {", getname);
+ Wrapper_add_local(getf, "obj", "octave_value obj");
+ if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
+ Replaceall(tm, "$source", name);
+ Replaceall(tm, "$target", "obj");
+ Replaceall(tm, "$result", "obj");
+ addfail = emit_action_code(n, getf->code, tm);
+ Delete(tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
+ }
+ Append(getf->code, " return obj;\n");
+ if (addfail) {
+ Append(getf->code, "fail:\n");
+ Append(getf->code, " return octave_value_list();\n");
+ }
+ Append(getf->code, "}\n");
+ Wrapper_print(getf, f_wrappers);
+
+ Printf(s_global_tab, "{\"%s\",0,_wrap_%s,_wrap_%s,2,0},\n", iname, getname, setname);
+
+ return SWIG_OK;
+ }
+
+ virtual int constantWrapper(Node *n) {
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ String *rawval = Getattr(n, "rawval");
+ String *value = rawval ? rawval : Getattr(n, "value");
+ String *tm;
+
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+
+ if (SwigType_type(type) == T_MPOINTER) {
+ String *wname = Swig_name_wrapper(iname);
+ String *str = SwigType_str(type, wname);
+ Printf(f_header, "static %s = %s;\n", str, value);
+ Delete(str);
+ value = wname;
+ }
+ if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ Replaceall(tm, "$nsname", iname);
+ 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;
+ }
+
+ virtual int nativeWrapper(Node *n) {
+ return Language::nativeWrapper(n);
+ }
+
+ virtual int enumDeclaration(Node *n) {
+ return Language::enumDeclaration(n);
+ }
+
+ virtual int enumvalueDeclaration(Node *n) {
+ return Language::enumvalueDeclaration(n);
+ }
+
+ virtual int classDeclaration(Node *n) {
+ return Language::classDeclaration(n);
+ }
+
+ virtual int classHandler(Node *n) {
+ have_constructor = 0;
+ have_destructor = 0;
+ constructor_name = 0;
+
+ class_name = Getattr(n, "sym:name");
+
+ if (!addSymbol(class_name, n))
+ return SWIG_ERROR;
+
+ // This is a bug, due to the fact that swig_type -> octave_class mapping
+ // is 1-to-n.
+ static Hash *emitted = NewHash();
+ String *mangled_classname = Swig_name_mangle(Getattr(n, "name"));
+ if (Getattr(emitted, mangled_classname)) {
+ Delete(mangled_classname);
+ return SWIG_NOWRAP;
+ }
+ Setattr(emitted, mangled_classname, "1");
+ Delete(mangled_classname);
+
+ assert(!s_members_tab);
+ s_members_tab = NewString("");
+ Printv(s_members_tab, "static swig_octave_member swig_", class_name, "_members[] = {\n", NIL);
+
+ Language::classHandler(n);
+
+ SwigType *t = Copy(Getattr(n, "name"));
+ SwigType_add_pointer(t);
+
+ String *wrap_class = NewStringf("&_wrap_class_%s", class_name);
+ SwigType_remember_clientdata(t, wrap_class);
+
+ int use_director = Swig_directorclass(n);
+ if (use_director) {
+ String *disown_shadow = NewString("");
+ Printf(disown_shadow, "static octave_value_list _wrap_disown_%s_shadow " "(const octave_value_list& args, int nargout) {\n", class_name);
+ Printf(disown_shadow, " if (args.length()!=1) {\n");
+ Printf(disown_shadow, " error(\"disown takes no arguments\");\n");
+ Printf(disown_shadow, " return octave_value_list();\n");
+ Printf(disown_shadow, " }\n");
+ Printf(disown_shadow, " _wrap_disown_%s (args, nargout);\n", class_name);
+ Printf(disown_shadow, " return args;\n");
+ Printf(disown_shadow, "}\n");
+ Printv(f_wrappers, disown_shadow, NIL);
+ Delete(disown_shadow);
+ Printf(s_members_tab, "{\"__disown\",_wrap_disown_%s_shadow,0,0,0,0},\n", class_name);
+ }
+
+ Printf(s_members_tab, "{0,0,0,0}\n};\n");
+ Printv(f_wrappers, s_members_tab, NIL);
+
+ String *base_class_names = NewString("");
+ String *base_class = NewString("");
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator b;
+ int index = 0;
+ b = First(baselist);
+ while (b.item) {
+ String *bname = Getattr(b.item, "name");
+ if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
+ b = Next(b);
+ continue;
+ }
+
+ String *bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname)));
+ Printf(base_class_names, "\"%s\",", bname_mangled);
+ Printf(base_class, "0,");
+ b = Next(b);
+ index++;
+ Delete(bname_mangled);
+ }
+ }
+
+ Printv(f_wrappers, "static const char *swig_", class_name, "_base_names[] = {", base_class_names, "0};\n", NIL);
+ Printv(f_wrappers, "static const swig_type_info *swig_", class_name, "_base[] = {", base_class, "0};\n", NIL);
+ Printv(f_wrappers, "static swig_octave_class _wrap_class_", class_name, " = {\"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
+ Printv(f_wrappers, Swig_directorclass(n) ? "1," : "0,", NIL);
+ if (have_constructor) {
+ String *cname = Swig_name_construct(constructor_name);
+ String *wcname = Swig_name_wrapper(cname);
+ String *tname = texinfo_name(n);
+ Printf(f_wrappers, "%s,%s,", wcname, tname);
+ Delete(tname);
+ Delete(wcname);
+ Delete(cname);
+ } else
+ Printv(f_wrappers, "0,0,", NIL);
+ if (have_destructor)
+ Printv(f_wrappers, "_wrap_delete_", class_name, ",", NIL);
+ else
+ Printv(f_wrappers, "0", ",", NIL);
+ Printf(f_wrappers, "swig_%s_members,swig_%s_base_names,swig_%s_base };\n\n", class_name, class_name, class_name);
+
+ Delete(base_class);
+ Delete(base_class_names);
+ Delete(t);
+ Delete(s_members_tab);
+ s_members_tab = 0;
+ class_name = 0;
+
+ return SWIG_OK;
+ }
+
+ virtual int memberfunctionHandler(Node *n) {
+ Language::memberfunctionHandler(n);
+
+ assert(s_members_tab);
+ assert(class_name);
+ String *name = Getattr(n, "name");
+ String *iname = GetChar(n, "sym:name");
+ String *realname = iname ? iname : name;
+ String *rname = Swig_name_wrapper(Swig_name_member(class_name, realname));
+
+ if (!Getattr(n, "sym:nextSibling")) {
+ String *tname = texinfo_name(n);
+ Printf(s_members_tab, "{\"%s\",%s,0,0,0,%s},\n",
+ realname, rname, tname);
+ Delete(tname);
+ }
+
+ Delete(rname);
+ return SWIG_OK;
+ }
+
+ virtual int membervariableHandler(Node *n) {
+ Setattr(n, "feature:autodoc", "0");
+
+ Language::membervariableHandler(n);
+
+ assert(s_members_tab);
+ assert(class_name);
+ String *symname = Getattr(n, "sym:name");
+ String *getname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname)));
+ String *setname = GetFlag(n, "feature:immutable") ?
+ NewString("octave_set_immutable") : Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name, symname)));
+ assert(s_members_tab);
+
+ Printf(s_members_tab, "{\"%s\",0,%s,%s,0,0},\n", symname, getname, setname);
+
+ Delete(getname);
+ Delete(setname);
+ return SWIG_OK;
+ }
+
+ virtual int constructorHandler(Node *n) {
+ have_constructor = 1;
+ if (!constructor_name)
+ constructor_name = NewString(Getattr(n, "sym:name"));
+
+ int use_director = Swig_directorclass(n);
+ if (use_director) {
+ Parm *parms = Getattr(n, "parms");
+ Parm *self;
+ String *name = NewString("self");
+ String *type = NewString("void");
+ SwigType_add_pointer(type);
+ self = NewParm(type, name);
+ Delete(type);
+ Delete(name);
+ Setattr(self, "lname", "self_obj");
+ if (parms)
+ set_nextSibling(self, parms);
+ Setattr(n, "parms", self);
+ Setattr(n, "wrap:self", "1");
+ Setattr(n, "hidden", "1");
+ Delete(self);
+ }
+
+ return Language::constructorHandler(n);;
+ }
+
+ virtual int destructorHandler(Node *n) {
+ have_destructor = 1;
+ return Language::destructorHandler(n);;
+ }
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ Language::staticmemberfunctionHandler(n);
+
+ assert(s_members_tab);
+ assert(class_name);
+ String *name = Getattr(n, "name");
+ String *iname = GetChar(n, "sym:name");
+ String *realname = iname ? iname : name;
+ String *rname = Swig_name_wrapper(Swig_name_member(class_name, realname));
+
+ if (!Getattr(n, "sym:nextSibling")) {
+ String *tname = texinfo_name(n);
+ Printf(s_members_tab, "{\"%s\",%s,0,0,1,%s},\n",
+ realname, rname, tname);
+ Delete(tname);
+ }
+
+ Delete(rname);
+ return SWIG_OK;
+ }
+
+ virtual int memberconstantHandler(Node *n) {
+ return Language::memberconstantHandler(n);
+ }
+
+ virtual int staticmembervariableHandler(Node *n) {
+ Setattr(n, "feature:autodoc", "0");
+
+ Language::staticmembervariableHandler(n);
+
+ if (!GetFlag(n, "wrappedasconstant")) {
+ assert(s_members_tab);
+ assert(class_name);
+ String *symname = Getattr(n, "sym:name");
+ String *getname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname)));
+ String *setname = GetFlag(n, "feature:immutable") ?
+ NewString("octave_set_immutable") : Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name, symname)));
+ assert(s_members_tab);
+
+ Printf(s_members_tab, "{\"%s\",0,%s,%s,1,0},\n", symname, getname, setname);
+
+ Delete(getname);
+ Delete(setname);
+ }
+ return SWIG_OK;
+ }
+
+ int classDirectorInit(Node *n) {
+ String *declaration = Swig_director_declaration(n);
+ Printf(f_directors_h, "\n");
+ Printf(f_directors_h, "%s\n", declaration);
+ Printf(f_directors_h, "public:\n");
+ Delete(declaration);
+ return Language::classDirectorInit(n);
+ }
+
+ int classDirectorEnd(Node *n) {
+ Printf(f_directors_h, "};\n\n");
+ return Language::classDirectorEnd(n);
+ }
+
+ int classDirectorConstructor(Node *n) {
+ Node *parent = Getattr(n, "parentNode");
+ String *sub = NewString("");
+ String *decl = Getattr(n, "decl");
+ String *supername = Swig_class_name(parent);
+ String *classname = NewString("");
+ Printf(classname, "SwigDirector_%s", supername);
+
+ // insert self parameter
+ Parm *p;
+ ParmList *superparms = Getattr(n, "parms");
+ ParmList *parms = CopyParmList(superparms);
+ String *type = NewString("void");
+ SwigType_add_pointer(type);
+ p = NewParm(type, NewString("self"));
+ set_nextSibling(p, parms);
+ parms = p;
+
+ if (!Getattr(n, "defaultargs")) {
+ // constructor
+ {
+ Wrapper *w = NewWrapper();
+ String *call;
+ String *basetype = Getattr(parent, "classtype");
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+ call = Swig_csuperclass_call(0, basetype, superparms);
+ Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype);
+ Append(w->def, "}\n");
+ Delete(target);
+ Wrapper_print(w, f_directors);
+ Delete(call);
+ DelWrapper(w);
+ }
+
+ // constructor header
+ {
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+ Printf(f_directors_h, " %s;\n", target);
+ Delete(target);
+ }
+ }
+
+ Delete(sub);
+ Delete(classname);
+ Delete(supername);
+ Delete(parms);
+ return Language::classDirectorConstructor(n);
+ }
+
+ int classDirectorDefaultConstructor(Node *n) {
+ String *classname = Swig_class_name(n);
+ {
+ Wrapper *w = NewWrapper();
+ Printf(w->def, "SwigDirector_%s::SwigDirector_%s(void* self) :"
+ "\nSwig::Director((octave_swig_type*)self,static_cast<%s*>(this)) { \n", classname, classname, classname);
+ Append(w->def, "}\n");
+ Wrapper_print(w, f_directors);
+ DelWrapper(w);
+ }
+ Printf(f_directors_h, " SwigDirector_%s(octave_swig_type* self);\n", classname);
+ Delete(classname);
+ return Language::classDirectorDefaultConstructor(n);
+ }
+
+ int classDirectorMethod(Node *n, Node *parent, String *super) {
+ int is_void = 0;
+ int is_pointer = 0;
+ String *decl;
+ String *type;
+ String *name;
+ String *classname;
+ String *c_classname = Getattr(parent, "name");
+ String *declaration;
+ ParmList *l;
+ Wrapper *w;
+ String *tm;
+ String *wrap_args = NewString("");
+ String *return_type;
+ String *value = Getattr(n, "value");
+ String *storage = Getattr(n, "storage");
+ bool pure_virtual = false;
+ int status = SWIG_OK;
+ int idx;
+ bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
+
+ if (Cmp(storage, "virtual") == 0) {
+ if (Cmp(value, "0") == 0) {
+ pure_virtual = true;
+ }
+ }
+
+ classname = Getattr(parent, "sym:name");
+ type = Getattr(n, "type");
+ name = Getattr(n, "name");
+
+ w = NewWrapper();
+ declaration = NewString("");
+
+ // determine if the method returns a pointer
+ decl = Getattr(n, "decl");
+ is_pointer = SwigType_ispointer_return(decl);
+ is_void = (!Cmp(type, "void") && !is_pointer);
+
+ // form complete return type
+ return_type = Copy(type);
+ {
+ SwigType *t = Copy(decl);
+ SwigType *f = 0;
+ f = SwigType_pop_function(t);
+ SwigType_push(return_type, t);
+ Delete(f);
+ Delete(t);
+ }
+
+ // virtual method definition
+ l = Getattr(n, "parms");
+ String *target;
+ String *pclassname = NewStringf("SwigDirector_%s", classname);
+ String *qualified_name = NewStringf("%s::%s", pclassname, name);
+ SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type;
+ target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+ Printf(w->def, "%s", target);
+ Delete(qualified_name);
+ Delete(target);
+
+ // header declaration
+ target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+ Printf(declaration, " virtual %s", target);
+ Delete(target);
+
+ // Get any exception classes in the throws typemap
+ ParmList *throw_parm_list = 0;
+
+ if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
+ Parm *p;
+ int gencomma = 0;
+
+ Append(w->def, " throw(");
+ Append(declaration, " throw(");
+
+ if (throw_parm_list)
+ Swig_typemap_attach_parms("throws", throw_parm_list, 0);
+ for (p = throw_parm_list; p; p = nextSibling(p)) {
+ if ((tm = Getattr(p, "tmap:throws"))) {
+ if (gencomma++) {
+ Append(w->def, ", ");
+ Append(declaration, ", ");
+ }
+ String *str = SwigType_str(Getattr(p, "type"), 0);
+ Append(w->def, str);
+ Append(declaration, str);
+ Delete(str);
+ }
+ }
+
+ Append(w->def, ")");
+ Append(declaration, ")");
+ }
+
+ Append(w->def, " {");
+ Append(declaration, ";\n");
+
+ // declare method return value
+ // if the return value is a reference or const reference, a specialized typemap must
+ // handle it, including declaration of c_result ($result).
+ if (!is_void) {
+ if (!(ignored_method && !pure_virtual)) {
+ String *cres = SwigType_lstr(return_type, "c_result");
+ Printf(w->code, "%s;\n", cres);
+ Delete(cres);
+ }
+ }
+
+ if (ignored_method) {
+ if (!pure_virtual) {
+ if (!is_void)
+ Printf(w->code, "return ");
+ String *super_call = Swig_method_call(super, l);
+ Printf(w->code, "%s;\n", super_call);
+ Delete(super_call);
+ } else {
+ Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
+ SwigType_namestr(name));
+ }
+ } else {
+ // attach typemaps to arguments (C/C++ -> Python)
+ String *parse_args = NewString("");
+
+ Swig_typemap_attach_parms("in", l, 0);
+ Swig_typemap_attach_parms("directorin", l, 0);
+ Swig_typemap_attach_parms("directorargout", l, w);
+
+ Parm *p;
+
+ int outputs = 0;
+ if (!is_void)
+ outputs++;
+
+ // build argument list and type conversion string
+ idx = 0;
+ p = l;
+ int use_parse = 0;
+ while (p != NULL) {
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+
+ if (Getattr(p, "tmap:directorargout") != 0)
+ outputs++;
+
+ String *pname = Getattr(p, "name");
+ String *ptype = Getattr(p, "type");
+ Wrapper_add_local(w, "tmpv", "octave_value tmpv");
+
+ if ((tm = Getattr(p, "tmap:directorin")) != 0) {
+ String *parse = Getattr(p, "tmap:directorin:parse");
+ if (!parse) {
+ Replaceall(tm, "$input", "tmpv");
+ Replaceall(tm, "$owner", "0");
+ Printv(wrap_args, tm, "\n", NIL);
+ Printf(wrap_args, "args.append(tmpv);\n");
+ Putc('O', parse_args);
+ } else {
+ use_parse = 1;
+ Append(parse_args, parse);
+ Replaceall(tm, "$input", pname);
+ Replaceall(tm, "$owner", "0");
+ if (Len(tm) == 0)
+ Append(tm, pname);
+ }
+ p = Getattr(p, "tmap:directorin:next");
+ continue;
+ } else if (Cmp(ptype, "void")) {
+ Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
+ SwigType_namestr(c_classname), SwigType_namestr(name));
+ status = SWIG_NOWRAP;
+ break;
+ }
+ p = nextSibling(p);
+ }
+
+ String *method_name = Getattr(n, "sym:name");
+
+ Printv(w->code, wrap_args, NIL);
+
+ // emit method invocation
+ Wrapper_add_local(w, "args", "octave_value_list args");
+ Wrapper_add_local(w, "out", "octave_value_list out");
+ Wrapper_add_local(w, "idx", "std::list<octave_value_list> idx");
+ Printf(w->code, "idx.push_back(octave_value_list(\"%s\"));\n", method_name);
+ Printf(w->code, "idx.push_back(args);\n");
+ Printf(w->code, "out=swig_get_self()->subsref(\".(\",idx,%d);\n", outputs);
+
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ idx = 0;
+
+ // marshal return value
+ if (!is_void) {
+ Printf(w->code, "if (out.length()<%d) {\n", outputs);
+ Printf(w->code, "Swig::DirectorTypeMismatchException::raise(\"Octave "
+ "method %s.%s failed to return the required number " "of arguments.\");\n", classname, method_name);
+ Printf(w->code, "}\n");
+
+ Setattr(n, "type", return_type);
+ tm = Swig_typemap_lookup("directorout", n, "result", w);
+ Setattr(n, "type", type);
+ if (tm != 0) {
+ char temp[24];
+ sprintf(temp, "out(%d)", idx);
+ Replaceall(tm, "$input", temp);
+ // Replaceall(tm, "$argnum", temp);
+ Replaceall(tm, "$disown", Getattr(n, "wrap:disown") ? "SWIG_POINTER_DISOWN" : "0");
+ if (Getattr(n, "tmap:directorout:implicitconv")) {
+ Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
+ }
+ Replaceall(tm, "$result", "c_result");
+ Printv(w->code, tm, "\n", NIL);
+ Delete(tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s in director method %s::%s (skipping method).\n",
+ SwigType_str(return_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name));
+ status = SWIG_ERROR;
+ }
+ }
+ idx++;
+
+ // marshal outputs
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
+ char temp[24];
+ sprintf(temp, "out(%d)", idx);
+ Replaceall(tm, "$input", temp);
+ Replaceall(tm, "$result", Getattr(p, "name"));
+ Printv(w->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:directorargout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ Delete(parse_args);
+ Delete(cleanup);
+ Delete(outarg);
+ }
+
+ if (!is_void) {
+ if (!(ignored_method && !pure_virtual)) {
+ String *rettype = SwigType_str(return_type, 0);
+ if (!SwigType_isreference(return_type)) {
+ Printf(w->code, "return (%s) c_result;\n", rettype);
+ } else {
+ Printf(w->code, "return (%s) *c_result;\n", rettype);
+ }
+ Delete(rettype);
+ }
+ }
+
+ Append(w->code, "}\n");
+
+ // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
+ String *inline_extra_method = NewString("");
+ if (dirprot_mode() && !is_public(n) && !pure_virtual) {
+ Printv(inline_extra_method, declaration, NIL);
+ String *extra_method_name = NewStringf("%sSwigPublic", name);
+ Replaceall(inline_extra_method, name, extra_method_name);
+ Replaceall(inline_extra_method, ";\n", " {\n ");
+ if (!is_void)
+ Printf(inline_extra_method, "return ");
+ String *methodcall = Swig_method_call(super, l);
+ Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
+ Delete(methodcall);
+ Delete(extra_method_name);
+ }
+ // emit the director method
+ if (status == SWIG_OK) {
+ if (!Getattr(n, "defaultargs")) {
+ Wrapper_print(w, f_directors);
+ Printv(f_directors_h, declaration, NIL);
+ Printv(f_directors_h, inline_extra_method, NIL);
+ }
+ }
+ // clean up
+ Delete(wrap_args);
+ Delete(return_type);
+ Delete(pclassname);
+ DelWrapper(w);
+ return status;
+ }
+
+ String *runtimeCode() {
+ String *s = NewString("");
+ String *srun = Swig_include_sys("octrun.swg");
+ if (!srun) {
+ Printf(stderr, "*** Unable to open 'octrun.swg'\n");
+ } else {
+ Append(s, srun);
+ Delete(srun);
+ }
+ return s;
+ }
+
+ String *defaultExternalRuntimeFilename() {
+ return NewString("swigoctaverun.h");
+ }
+};
+
+extern "C" Language *swig_octave(void) {
+ return new OCTAVE();
+}
diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx
new file mode 100644
index 0000000..38cb729
--- /dev/null
+++ b/Source/Modules/overload.cxx
@@ -0,0 +1,792 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_overload_cxx[] = "$Id: overload.cxx 11455 2009-07-26 21:29:55Z wsfulton $";
+
+#include "swigmod.h"
+
+#define MAX_OVERLOAD 4096
+
+/* Overload "argc" and "argv" */
+String *argv_template_string;
+String *argc_template_string;
+
+struct Overloaded {
+ Node *n; /* Node */
+ int argc; /* Argument count */
+ ParmList *parms; /* Parameters used for overload check */
+ int error; /* Ambiguity error */
+};
+
+static int fast_dispatch_mode = 0;
+static int cast_dispatch_mode = 0;
+
+/* Set fast_dispatch_mode */
+void Wrapper_fast_dispatch_mode_set(int flag) {
+ fast_dispatch_mode = flag;
+}
+
+void Wrapper_cast_dispatch_mode_set(int flag) {
+ cast_dispatch_mode = flag;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_overload_rank()
+ *
+ * This function takes an overloaded declaration and creates a list that ranks
+ * all overloaded methods in an order that can be used to generate a dispatch
+ * function.
+ * Slight difference in the way this function is used by scripting languages and
+ * statically typed languages. The script languages call this method via
+ * Swig_overload_dispatch() - where wrappers for all overloaded methods are generated,
+ * however sometimes the code can never be executed. The non-scripting languages
+ * call this method via Swig_overload_check() for each overloaded method in order
+ * to determine whether or not the method should be wrapped. Note the slight
+ * difference when overloading methods that differ by const only. The
+ * scripting languages will ignore the const method, whereas the non-scripting
+ * languages ignore the first method parsed.
+ * ----------------------------------------------------------------------------- */
+
+static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
+ Overloaded nodes[MAX_OVERLOAD];
+ int nnodes = 0;
+ Node *o = Getattr(n, "sym:overloaded");
+ Node *c;
+
+ if (!o)
+ return 0;
+
+ c = o;
+ while (c) {
+ if (Getattr(c, "error")) {
+ c = Getattr(c, "sym:nextSibling");
+ continue;
+ }
+ /* if (SmartPointer && Getattr(c,"cplus:staticbase")) {
+ c = Getattr(c,"sym:nextSibling");
+ continue;
+ } */
+
+ /* Make a list of all the declarations (methods) that are overloaded with
+ * this one particular method name */
+ if (Getattr(c, "wrap:name")) {
+ assert(nnodes < MAX_OVERLOAD);
+ nodes[nnodes].n = c;
+ nodes[nnodes].parms = Getattr(c, "wrap:parms");
+ nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
+ nodes[nnodes].error = 0;
+ nnodes++;
+ }
+ c = Getattr(c, "sym:nextSibling");
+ }
+
+ /* Sort the declarations by required argument count */
+ {
+ int i, j;
+ for (i = 0; i < nnodes; i++) {
+ for (j = i + 1; j < nnodes; j++) {
+ if (nodes[i].argc > nodes[j].argc) {
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ }
+ }
+ }
+ }
+
+ /* Sort the declarations by argument types */
+ {
+ int i, j;
+ for (i = 0; i < nnodes - 1; i++) {
+ if (nodes[i].argc == nodes[i + 1].argc) {
+ for (j = i + 1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
+ Parm *p1 = nodes[i].parms;
+ Parm *p2 = nodes[j].parms;
+ int differ = 0;
+ int num_checked = 0;
+ while (p1 && p2 && (num_checked < nodes[i].argc)) {
+ // Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
+ if (checkAttribute(p1, "tmap:in:numinputs", "0")) {
+ p1 = Getattr(p1, "tmap:in:next");
+ continue;
+ }
+ if (checkAttribute(p2, "tmap:in:numinputs", "0")) {
+ p2 = Getattr(p2, "tmap:in:next");
+ continue;
+ }
+ String *t1 = Getattr(p1, "tmap:typecheck:precedence");
+ String *t2 = Getattr(p2, "tmap:typecheck:precedence");
+ if ((!t1) && (!nodes[i].error)) {
+ Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
+ "Overloaded method %s not supported (no type checking rule for '%s').\n",
+ Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0));
+ nodes[i].error = 1;
+ } else if ((!t2) && (!nodes[j].error)) {
+ Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s not supported (no type checking rule for '%s').\n",
+ Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0));
+ nodes[j].error = 1;
+ }
+ if (t1 && t2) {
+ int t1v, t2v;
+ t1v = atoi(Char(t1));
+ t2v = atoi(Char(t2));
+ differ = t1v - t2v;
+ } else if (!t1 && t2)
+ differ = 1;
+ else if (t1 && !t2)
+ differ = -1;
+ else if (!t1 && !t2)
+ differ = -1;
+ num_checked++;
+ if (differ > 0) {
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ break;
+ } else if ((differ == 0) && (Strcmp(t1, "0") == 0)) {
+ t1 = Getattr(p1, "ltype");
+ if (!t1) {
+ t1 = SwigType_ltype(Getattr(p1, "type"));
+ if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) {
+ SwigType_add_pointer(t1);
+ }
+ Setattr(p1, "ltype", t1);
+ }
+ t2 = Getattr(p2, "ltype");
+ if (!t2) {
+ t2 = SwigType_ltype(Getattr(p2, "type"));
+ if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) {
+ SwigType_add_pointer(t2);
+ }
+ Setattr(p2, "ltype", t2);
+ }
+
+ /* Need subtype check here. If t2 is a subtype of t1, then we need to change the
+ order */
+
+ if (SwigType_issubtype(t2, t1)) {
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ }
+
+ if (Strcmp(t1, t2) != 0) {
+ differ = 1;
+ break;
+ }
+ } else if (differ) {
+ break;
+ }
+ if (Getattr(p1, "tmap:in:next")) {
+ p1 = Getattr(p1, "tmap:in:next");
+ } else {
+ p1 = nextSibling(p1);
+ }
+ if (Getattr(p2, "tmap:in:next")) {
+ p2 = Getattr(p2, "tmap:in:next");
+ } else {
+ p2 = nextSibling(p2);
+ }
+ }
+ if (!differ) {
+ /* See if declarations differ by const only */
+ String *d1 = Getattr(nodes[i].n, "decl");
+ String *d2 = Getattr(nodes[j].n, "decl");
+ if (d1 && d2) {
+ String *dq1 = Copy(d1);
+ String *dq2 = Copy(d2);
+ if (SwigType_isconst(d1)) {
+ Delete(SwigType_pop(dq1));
+ }
+ if (SwigType_isconst(d2)) {
+ Delete(SwigType_pop(dq2));
+ }
+ if (Strcmp(dq1, dq2) == 0) {
+
+ if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
+ if (script_lang_wrapping) {
+ // Swap nodes so that the const method gets ignored (shadowed by the non-const method)
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ }
+ differ = 1;
+ if (!nodes[j].error) {
+ if (script_lang_wrapping) {
+ Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s ignored. Non-const method %s at %s:%d used.\n",
+ Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), Getfile(nodes[i].n), Getline(nodes[i].n));
+ } else {
+ if (!Getattr(nodes[j].n, "overload:ignore"))
+ Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s ignored. Method %s at %s:%d used.\n",
+ Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), 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) {
+ if (script_lang_wrapping) {
+ Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s ignored. Non-const method %s at %s:%d used.\n",
+ Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), Getfile(nodes[i].n), Getline(nodes[i].n));
+ } else {
+ if (!Getattr(nodes[j].n, "overload:ignore"))
+ Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s ignored. Method %s at %s:%d used.\n",
+ Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), Getfile(nodes[i].n), Getline(nodes[i].n));
+ }
+ }
+ nodes[j].error = 1;
+ }
+ }
+ Delete(dq1);
+ Delete(dq2);
+ }
+ }
+ if (!differ) {
+ if (!nodes[j].error) {
+ if (script_lang_wrapping) {
+ Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s is shadowed by %s at %s:%d.\n",
+ Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ } else {
+ if (!Getattr(nodes[j].n, "overload:ignore"))
+ Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s ignored. Method %s at %s:%d used.\n",
+ Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ }
+ nodes[j].error = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ List *result = NewList();
+ {
+ int i;
+ for (i = 0; i < nnodes; i++) {
+ if (nodes[i].error)
+ Setattr(nodes[i].n, "overload:ignore", "1");
+ Append(result, nodes[i].n);
+ // Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms));
+ // Swig_print_node(nodes[i].n);
+ }
+ }
+ return result;
+}
+
+// /* -----------------------------------------------------------------------------
+// * print_typecheck()
+// * ----------------------------------------------------------------------------- */
+
+static bool print_typecheck(String *f, int j, Parm *pj) {
+ char tmp[256];
+ sprintf(tmp, Char(argv_template_string), j);
+ String *tm = Getattr(pj, "tmap:typecheck");
+ if (tm) {
+ Replaceid(tm, Getattr(pj, "lname"), "_v");
+ String *conv = Getattr(pj, "implicitconv");
+ if (conv) {
+ Replaceall(tm, "$implicitconv", conv);
+ } else {
+ Replaceall(tm, "$implicitconv", "0");
+ }
+ Replaceall(tm, "$input", tmp);
+ Printv(f, tm, "\n", NIL);
+ return true;
+ } else
+ return false;
+}
+
+/* -----------------------------------------------------------------------------
+ * ReplaceFormat()
+ * ----------------------------------------------------------------------------- */
+
+static String *ReplaceFormat(const_String_or_char_ptr fmt, int j) {
+ String *lfmt = NewString(fmt);
+ char buf[50];
+ sprintf(buf, "%d", j);
+ Replaceall(lfmt, "$numargs", buf);
+ int i;
+ String *commaargs = NewString("");
+ for (i = 0; i < j; i++) {
+ Printv(commaargs, ", ", NIL);
+ Printf(commaargs, Char(argv_template_string), i);
+ }
+ Replaceall(lfmt, "$commaargs", commaargs);
+ return lfmt;
+}
+
+/* -----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+/*
+ Cast dispatch mechanism.
+*/
+String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *maxargs) {
+ int i, j;
+
+ *maxargs = 1;
+
+ String *f = NewString("");
+ String *sw = NewString("");
+ Printf(f, "{\n");
+ Printf(f, "unsigned long _index = 0;\n");
+ Printf(f, "SWIG_TypeRank _rank = 0; \n");
+
+ /* Get a list of methods ranked by precedence values and argument count */
+ List *dispatch = Swig_overload_rank(n, true);
+ int nfunc = Len(dispatch);
+
+ /* Loop over the functions */
+
+ bool emitcheck = 1;
+ for (i = 0; i < nfunc; i++) {
+ int fn = 0;
+ 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 (%s == %d) {\n", argc_template_string, num_required);
+ } else {
+ Printf(f, "if ((%s >= %d) && (%s <= %d)) {\n", argc_template_string, num_required, argc_template_string, num_arguments);
+ }
+ } else {
+ Printf(f, "if (%s >= %d) {\n", argc_template_string, num_required);
+ }
+ Printf(f, "SWIG_TypeRank _ranki = 0;\n");
+ Printf(f, "SWIG_TypeRank _rankm = 0;\n");
+ if (num_arguments)
+ Printf(f, "SWIG_TypeRank _pi = 1;\n");
+
+ /* create a list with the wrappers that collide with the
+ current one based on argument number */
+ List *coll = NewList();
+ for (int k = i + 1; k < nfunc; k++) {
+ Node *nk = Getitem(dispatch, k);
+ Parm *pk = Getattr(nk, "wrap:parms");
+ int nrk = emit_num_required(pk);
+ int nak = emit_num_arguments(pk);
+ if ((nrk >= num_required && nrk <= num_arguments) || (nak >= num_required && nak <= num_arguments) || (nrk <= num_required && nak >= num_arguments))
+ Append(coll, nk);
+ }
+
+ // printf("overload: %s coll=%d\n", Char(Getattr(n, "sym:name")), Len(coll));
+
+ int num_braces = 0;
+ bool test = (num_arguments > 0);
+ if (test) {
+ int need_v = 1;
+ j = 0;
+ Parm *pj = pi;
+ while (pj) {
+ if (checkAttribute(pj, "tmap:in:numinputs", "0")) {
+ pj = Getattr(pj, "tmap:in:next");
+ continue;
+ }
+
+ String *tm = Getattr(pj, "tmap:typecheck");
+ if (tm) {
+ /* normalise for comparison later */
+ Replaceid(tm, Getattr(pj, "lname"), "_v");
+
+ /* if all the wrappers have the same type check on this
+ argument we can optimize it out */
+ for (int k = 0; k < Len(coll) && !emitcheck; k++) {
+ Node *nk = Getitem(coll, k);
+ Parm *pk = Getattr(nk, "wrap:parms");
+ int nak = emit_num_arguments(pk);
+ if (nak <= j)
+ continue;
+ int l = 0;
+ Parm *pl = pk;
+ /* finds arg j on the collider wrapper */
+ while (pl && l <= j) {
+ if (checkAttribute(pl, "tmap:in:numinputs", "0")) {
+ pl = Getattr(pl, "tmap:in:next");
+ continue;
+ }
+ if (l == j) {
+ /* we are at arg j, so we compare the tmaps now */
+ String *tml = Getattr(pl, "tmap:typecheck");
+ /* normalise it before comparing */
+ if (tml)
+ Replaceid(tml, Getattr(pl, "lname"), "_v");
+ if (!tml || Cmp(tm, tml))
+ emitcheck = 1;
+ //printf("tmap: %s[%d] (%d) => %s\n\n",
+ // Char(Getattr(nk, "sym:name")),
+ // l, emitcheck, tml?Char(tml):0);
+ }
+ Parm *pl1 = Getattr(pl, "tmap:in:next");
+ if (pl1)
+ pl = pl1;
+ else
+ pl = nextSibling(pl);
+ l++;
+ }
+ }
+
+ if (emitcheck) {
+ if (need_v) {
+ Printf(f, "int _v = 0;\n");
+ need_v = 0;
+ }
+ if (j >= num_required) {
+ Printf(f, "if (%s > %d) {\n", argc_template_string, j);
+ num_braces++;
+ }
+ String *tmp = NewStringf(argv_template_string, j);
+
+ String *conv = Getattr(pj, "implicitconv");
+ if (conv) {
+ Replaceall(tm, "$implicitconv", conv);
+ } else {
+ Replaceall(tm, "$implicitconv", "0");
+ }
+ Replaceall(tm, "$input", tmp);
+ Printv(f, "{\n", tm, "}\n", NIL);
+ fn = i + 1;
+ Printf(f, "if (!_v) goto check_%d;\n", fn);
+ Printf(f, "_ranki += _v*_pi;\n");
+ Printf(f, "_rankm += _pi;\n");
+ Printf(f, "_pi *= SWIG_MAXCASTRANK;\n");
+ }
+ }
+ if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) {
+ /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
+ Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
+ "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n",
+ Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0));
+ }
+ Parm *pj1 = Getattr(pj, "tmap:in:next");
+ if (pj1)
+ pj = pj1;
+ else
+ pj = nextSibling(pj);
+ j++;
+ }
+ }
+
+ /* close braces */
+ for ( /* empty */ ; num_braces > 0; num_braces--)
+ Printf(f, "}\n");
+
+ Printf(f, "if (!_index || (_ranki < _rank)) {\n");
+ Printf(f, " _rank = _ranki; _index = %d;\n", i + 1);
+ Printf(f, " if (_rank == _rankm) goto dispatch;\n");
+ Printf(f, "}\n");
+ String *lfmt = ReplaceFormat(fmt, num_arguments);
+ Printf(sw, "case %d:\n", i + 1);
+ Printf(sw, Char(lfmt), Getattr(ni, "wrap:name"));
+ Printf(sw, "\n");
+
+ Printf(f, "}\n"); /* braces closes "if" for this method */
+ if (fn)
+ Printf(f, "check_%d:\n\n", fn);
+
+ Delete(lfmt);
+ Delete(coll);
+ }
+ Delete(dispatch);
+ Printf(f, "dispatch:\n");
+ Printf(f, "switch(_index) {\n");
+ Printf(f, "%s", sw);
+ Printf(f, "}\n");
+
+ Printf(f, "}\n");
+ return f;
+}
+
+/*
+ Fast dispatch mechanism, provided by Salvador Fandi~no Garc'ia (#930586).
+*/
+String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *maxargs) {
+ 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, true);
+ int nfunc = Len(dispatch);
+
+ /* Loop over the functions */
+
+ for (i = 0; i < nfunc; i++) {
+ int fn = 0;
+ 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 (%s == %d) {\n", argc_template_string, num_required);
+ } else {
+ Printf(f, "if ((%s >= %d) && (%s <= %d)) {\n", argc_template_string, num_required, argc_template_string, num_arguments);
+ }
+ } else {
+ Printf(f, "if (%s >= %d) {\n", argc_template_string, num_required);
+ }
+
+ /* create a list with the wrappers that collide with the
+ current one based on argument number */
+ List *coll = NewList();
+ for (int k = i + 1; k < nfunc; k++) {
+ Node *nk = Getitem(dispatch, k);
+ Parm *pk = Getattr(nk, "wrap:parms");
+ int nrk = emit_num_required(pk);
+ int nak = emit_num_arguments(pk);
+ if ((nrk >= num_required && nrk <= num_arguments) || (nak >= num_required && nak <= num_arguments) || (nrk <= num_required && nak >= num_arguments))
+ Append(coll, nk);
+ }
+
+ // printf("overload: %s coll=%d\n", Char(Getattr(n, "sym:name")), Len(coll));
+
+ int num_braces = 0;
+ bool test = (Len(coll) > 0 && num_arguments);
+ if (test) {
+ int need_v = 1;
+ j = 0;
+ Parm *pj = pi;
+ while (pj) {
+ if (checkAttribute(pj, "tmap:in:numinputs", "0")) {
+ pj = Getattr(pj, "tmap:in:next");
+ continue;
+ }
+
+ String *tm = Getattr(pj, "tmap:typecheck");
+ if (tm) {
+ /* normalise for comparison later */
+ Replaceid(tm, Getattr(pj, "lname"), "_v");
+
+ /* if all the wrappers have the same type check on this
+ argument we can optimize it out */
+ bool emitcheck = 0;
+ for (int k = 0; k < Len(coll) && !emitcheck; k++) {
+ Node *nk = Getitem(coll, k);
+ Parm *pk = Getattr(nk, "wrap:parms");
+ int nak = emit_num_arguments(pk);
+ if (nak <= j)
+ continue;
+ int l = 0;
+ Parm *pl = pk;
+ /* finds arg j on the collider wrapper */
+ while (pl && l <= j) {
+ if (checkAttribute(pl, "tmap:in:numinputs", "0")) {
+ pl = Getattr(pl, "tmap:in:next");
+ continue;
+ }
+ if (l == j) {
+ /* we are at arg j, so we compare the tmaps now */
+ String *tml = Getattr(pl, "tmap:typecheck");
+ /* normalise it before comparing */
+ if (tml)
+ Replaceid(tml, Getattr(pl, "lname"), "_v");
+ if (!tml || Cmp(tm, tml))
+ emitcheck = 1;
+ //printf("tmap: %s[%d] (%d) => %s\n\n",
+ // Char(Getattr(nk, "sym:name")),
+ // l, emitcheck, tml?Char(tml):0);
+ }
+ Parm *pl1 = Getattr(pl, "tmap:in:next");
+ if (pl1)
+ pl = pl1;
+ else
+ pl = nextSibling(pl);
+ l++;
+ }
+ }
+
+ if (emitcheck) {
+ if (need_v) {
+ Printf(f, "int _v = 0;\n");
+ need_v = 0;
+ }
+ if (j >= num_required) {
+ Printf(f, "if (%s > %d) {\n", argc_template_string, j);
+ num_braces++;
+ }
+ String *tmp = NewStringf(argv_template_string, j);
+
+ String *conv = Getattr(pj, "implicitconv");
+ if (conv) {
+ Replaceall(tm, "$implicitconv", conv);
+ } else {
+ Replaceall(tm, "$implicitconv", "0");
+ }
+ Replaceall(tm, "$input", tmp);
+ Printv(f, "{\n", tm, "}\n", NIL);
+ fn = i + 1;
+ Printf(f, "if (!_v) goto check_%d;\n", fn);
+ }
+ }
+ if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) {
+ /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
+ Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
+ "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n",
+ Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0));
+ }
+ Parm *pj1 = Getattr(pj, "tmap:in:next");
+ if (pj1)
+ pj = pj1;
+ else
+ pj = nextSibling(pj);
+ j++;
+ }
+ }
+
+ /* close braces */
+ for ( /* empty */ ; num_braces > 0; num_braces--)
+ Printf(f, "}\n");
+
+
+ String *lfmt = ReplaceFormat(fmt, num_arguments);
+ Printf(f, Char(lfmt), Getattr(ni, "wrap:name"));
+
+ Printf(f, "}\n"); /* braces closes "if" for this method */
+ if (fn)
+ Printf(f, "check_%d:\n\n", fn);
+
+ Delete(lfmt);
+ Delete(coll);
+ }
+ Delete(dispatch);
+ return f;
+}
+
+String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *maxargs) {
+
+ if (fast_dispatch_mode || GetFlag(n, "feature:fastdispatch")) {
+ return Swig_overload_dispatch_fast(n, fmt, 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, true);
+ 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 (GetFlag(n, "wrap:this")) {
+ num_required++;
+ num_arguments++;
+ }
+ if (num_arguments > *maxargs)
+ *maxargs = num_arguments;
+ int varargs = emit_isvarargs(pi);
+
+ if (!varargs) {
+ if (num_required == num_arguments) {
+ Printf(f, "if (%s == %d) {\n", argc_template_string, num_required);
+ } else {
+ Printf(f, "if ((%s >= %d) && (%s <= %d)) {\n", argc_template_string, num_required, argc_template_string, num_arguments);
+ }
+ } else {
+ Printf(f, "if (%s >= %d) {\n", argc_template_string, 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) {
+ String *lfmt = ReplaceFormat(fmt, num_arguments);
+ Printf(f, "if (%s <= %d) {\n", argc_template_string, j);
+ Printf(f, Char(lfmt), Getattr(ni, "wrap:name"));
+ Printf(f, "}\n");
+ Delete(lfmt);
+ }
+ if (print_typecheck(f, (GetFlag(n, "wrap:this") ? j + 1 : j), pj)) {
+ Printf(f, "if (_v) {\n");
+ num_braces++;
+ }
+ if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) {
+ /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
+ Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
+ "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n",
+ Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0));
+ }
+ Parm *pk = Getattr(pj, "tmap:in:next");
+ if (pk)
+ pj = pk;
+ else
+ pj = nextSibling(pj);
+ j++;
+ }
+ String *lfmt = ReplaceFormat(fmt, num_arguments);
+ Printf(f, Char(lfmt), Getattr(ni, "wrap:name"));
+ Delete(lfmt);
+ /* 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;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_overload_check()
+ * ----------------------------------------------------------------------------- */
+void Swig_overload_check(Node *n) {
+ Swig_overload_rank(n, false);
+}
diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx
new file mode 100644
index 0000000..34b2701
--- /dev/null
+++ b/Source/Modules/perl5.cxx
@@ -0,0 +1,1768 @@
+/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=2:tabstop=8:smarttab:
+ */
+
+/* ----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * perl5.cxx
+ *
+ * Perl5 language module for SWIG.
+ * ------------------------------------------------------------------------- */
+
+char cvsroot_perl5_cxx[] = "$Id: perl5.cxx 11397 2009-07-15 07:43:16Z olly $";
+
+#include "swigmod.h"
+#include "cparse.h"
+static int treduce = SWIG_cparse_template_reduce(0);
+
+#include <ctype.h>
+
+static const char *usage = (char *) "\
+Perl5 Options (available with -perl5)\n\
+ -static - Omit code related to dynamic loading\n\
+ -nopm - Do not generate the .pm file\n\
+ -proxy - Create proxy classes\n\
+ -noproxy - Don't create proxy classes\n\
+ -const - Wrap constants as constants and not variables (implies -proxy)\n\
+ -nocppcast - Disable C++ casting operators, useful for generating bugs\n\
+ -cppcast - Enable C++ casting operators\n\
+ -compat - Compatibility mode\n\n";
+
+static int compat = 0;
+
+static int no_pmfile = 0;
+
+static int export_all = 0;
+
+/*
+ * pmfile
+ * set by the -pm flag, overrides the name of the .pm file
+ */
+static String *pmfile = 0;
+
+/*
+ * module
+ * set by the %module directive, e.g. "Xerces". It will determine
+ * the name of the .pm file, and the dynamic library, and the name
+ * used by any module wanting to %import the module.
+ */
+static String *module = 0;
+
+/*
+ * namespace_module
+ * the fully namespace qualified name of the module. 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. This will be
+ * the same as module, above, unless the %module directive is given
+ * the 'package' option, e.g. %module(package="Foo::Bar") "baz"
+ */
+static String *namespace_module = 0;
+
+/*
+ * cmodule
+ * the namespace of the internal glue code, set to the value of
+ * module with a 'c' appended
+ */
+static String *cmodule = 0;
+
+/*
+ * dest_package
+ * an optional namespace to put all classes into. Specified by using
+ * the %module(package="Foo::Bar") "baz" syntax
+ */
+static String *dest_package = 0;
+
+static String *command_tab = 0;
+static String *constant_tab = 0;
+static String *variable_tab = 0;
+
+static File *f_begin = 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 staticoption = 0;
+
+// controlling verbose output
+static int verbose = 0;
+
+/* The following variables are used to manage Perl5 classes */
+
+static int blessed = 1; /* Enable object oriented features */
+static int do_constants = 0; /* Constant wrapping */
+static List *classlist = 0; /* List of classes */
+static int have_constructor = 0;
+static int have_destructor = 0;
+static int have_data_members = 0;
+static String *class_name = 0; /* Name of the class (what Perl thinks it is) */
+static String *real_classname = 0; /* Real name of C/C++ class */
+static String *fullclassname = 0;
+
+static String *pcode = 0; /* Perl code associated with each class */
+ /* static String *blessedmembers = 0; *//* Member data associated with each class */
+static int member_func = 0; /* Set to 1 when wrapping a member function */
+static String *func_stubs = 0; /* Function stubs */
+static String *const_stubs = 0; /* Constant stubs */
+static int num_consts = 0; /* Number of constants */
+static String *var_stubs = 0; /* Variable stubs */
+static String *exported = 0; /* Exported symbols */
+static String *pragma_include = 0;
+static String *additional_perl_code = 0; /* Additional Perl code from %perlcode %{ ... %} */
+static Hash *operators = 0;
+static int have_operators = 0;
+
+class PERL5:public Language {
+public:
+
+ PERL5():Language () {
+ Clear(argc_template_string);
+ Printv(argc_template_string, "items", NIL);
+ Clear(argv_template_string);
+ Printv(argv_template_string, "ST(%d)", NIL);
+ }
+
+ /* Test to see if a type corresponds to something wrapped with a shadow class */
+ Node *is_shadow(SwigType *t) {
+ Node *n;
+ n = classLookup(t);
+ /* Printf(stdout,"'%s' --> '%x'\n", t, n); */
+ if (n) {
+ if (!Getattr(n, "perl5:proxy")) {
+ setclassname(n);
+ }
+ return Getattr(n, "perl5:proxy");
+ }
+ return 0;
+ }
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+ int i = 1;
+ int cppcast = 1;
+
+ SWIG_library_directory("perl5");
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-package") == 0) {
+ Printv(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", NIL);
+ SWIG_exit(EXIT_FAILURE);
+ } else if (strcmp(argv[i], "-interface") == 0) {
+ Printv(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", NIL);
+ 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) {
+ staticoption = 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], "-noproxy") == 0)) {
+ blessed = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-const") == 0) {
+ do_constants = 1;
+ blessed = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nopm") == 0) {
+ no_pmfile = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-pm") == 0) {
+ Swig_mark_arg(i);
+ i++;
+ pmfile = NewString(argv[i]);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i],"-v") == 0) {
+ Swig_mark_arg(i);
+ verbose++;
+ } else if (strcmp(argv[i], "-cppcast") == 0) {
+ cppcast = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nocppcast") == 0) {
+ cppcast = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-compat") == 0) {
+ compat = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-help") == 0) {
+ fputs(usage, stdout);
+ }
+ }
+ }
+
+ if (cppcast) {
+ Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
+ }
+
+ Preprocessor_define("SWIGPERL 1", 0);
+ // SWIGPERL5 is deprecated, and no longer documented.
+ Preprocessor_define("SWIGPERL5 1", 0);
+ SWIG_typemap_lang("perl5");
+ SWIG_config_file("perl5.swg");
+ allow_overloading();
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ 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("begin", f_begin);
+ 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("");
+ additional_perl_code = 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_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGPERL\n");
+ Printf(f_runtime, "#define SWIG_CASTRANK_MODE\n");
+ Printf(f_runtime, "\n");
+
+ // Is the imported module in another package? (IOW, does it use the
+ // %module(package="name") option and it's different than the package
+ // of this module.)
+ Node *mod = Getattr(n, "module");
+ Node *options = Getattr(mod, "options");
+ module = Copy(Getattr(n,"name"));
+
+ if (verbose > 0) {
+ fprintf(stdout, "top: using module: %s\n", Char(module));
+ }
+
+ dest_package = options ? Getattr(options, "package") : 0;
+ if (dest_package) {
+ namespace_module = Copy(dest_package);
+ if (verbose > 0) {
+ fprintf(stdout, "top: Found package: %s\n",Char(dest_package));
+ }
+ } else {
+ namespace_module = Copy(module);
+ if (verbose > 0) {
+ fprintf(stdout, "top: No package found\n");
+ }
+ }
+ String *underscore_module = Copy(module);
+ Replaceall(underscore_module,":","_");
+
+ if (verbose > 0) {
+ fprintf(stdout, "top: using namespace_module: %s\n", Char(namespace_module));
+ }
+
+ /* If we're in blessed mode, change the package name to "packagec" */
+
+ if (blessed) {
+ cmodule = NewStringf("%sc",namespace_module);
+ } else {
+ cmodule = NewString(namespace_module);
+ }
+
+ /* Create a .pm file
+ * Need to strip off any prefixes that might be found in
+ * the module name */
+
+ if (no_pmfile) {
+ f_pm = NewString(0);
+ } else {
+ if (pmfile == NULL) {
+ char *m = Char(module) + Len(module);
+ while (m != Char(module)) {
+ if (*m == ':') {
+ m++;
+ break;
+ }
+ m--;
+ }
+ pmfile = NewStringf("%s.pm", m);
+ }
+ String *filen = NewStringf("%s%s", SWIG_output_directory(), pmfile);
+ if ((f_pm = NewFile(filen, "w", SWIG_output_files())) == 0) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(filen);
+ filen = NULL;
+ Swig_register_filebyname("pm", f_pm);
+ Swig_register_filebyname("perl", f_pm);
+ }
+ {
+ String *boot_name = NewStringf("boot_%s", underscore_module);
+ Printf(f_header,"#define SWIG_init %s\n\n", boot_name);
+ Printf(f_header,"#define SWIG_name \"%s::%s\"\n", cmodule, boot_name);
+ Printf(f_header,"#define SWIG_prefix \"%s::\"\n", cmodule);
+ Delete(boot_name);
+ }
+
+ Swig_banner_target_lang(f_pm, "#");
+ Printf(f_pm, "\n");
+
+ Printf(f_pm, "package %s;\n", module);
+
+ /*
+ * If the package option has been given we are placing our
+ * symbols into some other packages namespace, so we do not
+ * mess with @ISA or require for that package
+ */
+ if (dest_package) {
+ Printf(f_pm,"use base qw(DynaLoader);\n");
+ } else {
+ Printf(f_pm,"use base qw(Exporter);\n");
+ if (!staticoption) {
+ Printf(f_pm,"use base qw(DynaLoader);\n");
+ }
+ }
+
+ /* Start creating magic code */
+
+ Printv(magic,
+ "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n",
+ "#ifdef PERL_OBJECT\n",
+ "#define MAGIC_CLASS _wrap_", underscore_module, "_var::\n",
+ "class _wrap_", underscore_module, "_var : public CPerlObj {\n",
+ "public:\n",
+ "#else\n",
+ "#define MAGIC_CLASS\n",
+ "#endif\n",
+ "SWIGCLASS_STATIC int swig_magic_readonly(pTHX_ SV *SWIGUNUSEDPARM(sv), MAGIC *SWIGUNUSEDPARM(mg)) {\n",
+ tab4, "MAGIC_PPERL\n", tab4, "croak(\"Value is read-only.\");\n", tab4, "return 0;\n", "}\n", NIL);
+
+ Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
+
+ /* emit wrappers */
+ Language::top(n);
+
+ String *base = NewString("");
+
+ /* Dump out variable wrappers */
+
+ Printv(magic, "\n\n#ifdef PERL_OBJECT\n", "};\n", "#endif\n", NIL);
+ Printv(magic, "\n#ifdef __cplusplus\n}\n#endif\n", NIL);
+
+ Printf(f_header, "%s\n", magic);
+
+ String *type_table = NewString("");
+
+ /* Patch the type table to reflect the names used by shadow classes */
+ if (blessed) {
+ Iterator cls;
+ for (cls = First(classlist); cls.item; cls = Next(cls)) {
+ String *pname = Getattr(cls.item, "perl5:proxy");
+ if (pname) {
+ SwigType *type = Getattr(cls.item, "classtypeobj");
+ if (!type)
+ continue; /* If unnamed class, no type will be found */
+ type = Copy(type);
+
+ SwigType_add_pointer(type);
+ String *mangled = SwigType_manglestr(type);
+ SwigType_remember_mangleddata(mangled, NewStringf("\"%s\"", pname));
+ Delete(type);
+ Delete(mangled);
+ }
+ }
+ }
+ SwigType_emit_type_table(f_runtime, type_table);
+
+ Printf(f_wrappers, "%s", type_table);
+ Delete(type_table);
+
+ Printf(constant_tab, "{0,0,0,0,0,0}\n};\n");
+ Printv(f_wrappers, constant_tab, NIL);
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n");
+
+ Printf(f_init, "\t ST(0) = &PL_sv_yes;\n");
+ Printf(f_init, "\t XSRETURN(1);\n");
+ Printf(f_init, "}\n");
+
+ /* Finish off tables */
+ Printf(variable_tab, "{0,0,0,0}\n};\n");
+ Printv(f_wrappers, variable_tab, NIL);
+
+ Printf(command_tab, "{0,0}\n};\n");
+ Printv(f_wrappers, command_tab, NIL);
+
+
+ Printf(f_pm, "package %s;\n", cmodule);
+
+ if (!staticoption) {
+ Printf(f_pm,"bootstrap %s;\n", module);
+ } else {
+ Printf(f_pm,"package %s;\n", cmodule);
+ Printf(f_pm,"boot_%s();\n", underscore_module);
+ }
+
+ Printf(f_pm, "package %s;\n", module);
+ /*
+ * If the package option has been given we are placing our
+ * symbols into some other packages namespace, so we do not
+ * mess with @EXPORT
+ */
+ if (!dest_package) {
+ Printf(f_pm,"@EXPORT = qw(%s);\n", exported);
+ }
+
+ Printf(f_pm, "%s", pragma_include);
+
+ if (blessed) {
+
+ /*
+ * These methods will be duplicated if package
+ * has been specified, so we do not output them
+ */
+ if (!dest_package) {
+ Printv(base, "\n# ---------- BASE METHODS -------------\n\n", "package ", namespace_module, ";\n\n", NIL);
+
+ /* Write out the TIE method */
+
+ Printv(base, "sub TIEHASH {\n", tab4, "my ($classname,$obj) = @_;\n", tab4, "return bless $obj, $classname;\n", "}\n\n", NIL);
+
+ /* Output a CLEAR method. This is just a place-holder, but by providing it we
+ * can make declarations such as
+ * %$u = ( x => 2, y=>3, z =>4 );
+ *
+ * Where x,y,z are the members of some C/C++ object. */
+
+ Printf(base, "sub CLEAR { }\n\n");
+
+ /* Output default firstkey/nextkey methods */
+
+ Printf(base, "sub FIRSTKEY { }\n\n");
+ Printf(base, "sub NEXTKEY { }\n\n");
+
+ /* Output a FETCH method. This is actually common to all classes */
+ Printv(base,
+ "sub FETCH {\n",
+ tab4, "my ($self,$field) = @_;\n", tab4, "my $member_func = \"swig_${field}_get\";\n", tab4, "$self->$member_func();\n", "}\n\n", NIL);
+
+ /* Output a STORE method. This is also common to all classes (might move to base class) */
+
+ Printv(base,
+ "sub STORE {\n",
+ tab4, "my ($self,$field,$newval) = @_;\n",
+ tab4, "my $member_func = \"swig_${field}_set\";\n", tab4, "$self->$member_func($newval);\n", "}\n\n", NIL);
+
+ /* Output a 'this' method */
+
+ Printv(base, "sub this {\n", tab4, "my $ptr = shift;\n", tab4, "return tied(%$ptr);\n", "}\n\n", NIL);
+
+ Printf(f_pm, "%s", base);
+ }
+
+ /* Emit function stubs for stand-alone functions */
+ Printf(f_pm, "\n# ------- FUNCTION WRAPPERS --------\n\n");
+ Printf(f_pm, "package %s;\n\n", namespace_module);
+ Printf(f_pm, "%s", func_stubs);
+
+ /* Emit package code for different classes */
+ Printf(f_pm, "%s", pm);
+
+ if (num_consts > 0) {
+ /* Emit constant stubs */
+ Printf(f_pm, "\n# ------- CONSTANT STUBS -------\n\n");
+ Printf(f_pm, "package %s;\n\n", namespace_module);
+ Printf(f_pm, "%s", const_stubs);
+ }
+
+ /* Emit variable stubs */
+
+ Printf(f_pm, "\n# ------- VARIABLE STUBS --------\n\n");
+ Printf(f_pm, "package %s;\n\n", namespace_module);
+ Printf(f_pm, "%s", var_stubs);
+ }
+
+ /* Add additional Perl code at the end */
+ Printf(f_pm, "%s", additional_perl_code);
+
+ Printf(f_pm, "1;\n");
+ Close(f_pm);
+ Delete(f_pm);
+ Delete(base);
+ Delete(dest_package);
+ Delete(underscore_module);
+
+ /* Close all of the files */
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * importDirective(Node *n)
+ * ------------------------------------------------------------ */
+
+ virtual int importDirective(Node *n) {
+ if (blessed) {
+ String *modname = Getattr(n, "module");
+ if (modname) {
+ Printf(f_pm, "require %s;\n", modname);
+ }
+ }
+ return Language::importDirective(n);
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int functionWrapper(Node *n) {
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *d = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *overname = 0;
+
+ Parm *p;
+ int i;
+ Wrapper *f;
+ char source[256], temp[256];
+ String *tm;
+ String *cleanup, *outarg;
+ int num_saved = 0;
+ int num_arguments, num_required;
+ int varargs = 0;
+
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ }
+
+ f = NewWrapper();
+ cleanup = NewString("");
+ outarg = NewString("");
+
+ String *wname = Swig_name_wrapper(iname);
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n, "wrap:name", wname);
+ Printv(f->def, "XS(", wname, ") {\n", "{\n", /* scope to destroy C++ objects before croaking */
+ NIL);
+
+ emit_parameter_variables(l, f);
+ emit_attach_parmmaps(l, f);
+ Setattr(n, "wrap:parms", l);
+
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+ varargs = emit_isvarargs(l);
+
+ Wrapper_add_local(f, "argvi", "int argvi = 0");
+
+ /* Check the number of arguments */
+ if (!varargs) {
+ Printf(f->code, " if ((items < %d) || (items > %d)) {\n", num_required, num_arguments);
+ } else {
+ Printf(f->code, " if (items < %d) {\n", num_required);
+ }
+ Printf(f->code, " SWIG_croak(\"Usage: %s\");\n", usage_func(Char(iname), d, l));
+ Printf(f->code, "}\n");
+
+ /* Write code to extract parameters. */
+ i = 0;
+ for (i = 0, p = l; i < num_arguments; i++) {
+
+ /* Skip ignored arguments */
+
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+
+ /* Produce string representation of source and target arguments */
+ sprintf(source, "ST(%d)", i);
+ String *target = Getattr(p, "lname");
+
+ 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 */
+
+ if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
+ Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm, "$disown", "0");
+ }
+
+ Printf(f->code, "%s\n", tm);
+ p = Getattr(p, "tmap:in:next");
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
+ p = nextSibling(p);
+ }
+ if (i >= num_required) {
+ Printf(f->code, " }\n");
+ }
+ }
+
+ if (varargs) {
+ if (p && (tm = Getattr(p, "tmap:in"))) {
+ sprintf(source, "ST(%d)", i);
+ Replaceall(tm, "$input", source);
+ Setattr(p, "emit:input", source);
+ Printf(f->code, "if (items >= %d) {\n", i);
+ Printv(f->code, tm, "\n", NIL);
+ Printf(f->code, "}\n");
+ }
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (i = 0, p = l; p; i++) {
+ if ((tm = Getattr(p, "tmap:freearg"))) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Replaceall(tm, "$arg", Getattr(p, "emit:input"));
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(cleanup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ num_saved = 0;
+ for (i = 0, p = l; p; i++) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+ SwigType *t = Getattr(p, "type");
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Replaceall(tm, "$target", "ST(argvi)");
+ Replaceall(tm, "$result", "ST(argvi)");
+ if (is_shadow(t)) {
+ Replaceall(tm, "$shadow", "SWIG_SHADOW");
+ } else {
+ Replaceall(tm, "$shadow", "0");
+ }
+
+ String *in = Getattr(p, "emit:input");
+ if (in) {
+ sprintf(temp, "_saved[%d]", num_saved);
+ Replaceall(tm, "$arg", temp);
+ Replaceall(tm, "$input", temp);
+ Printf(f->code, "_saved[%d] = %s;\n", num_saved, in);
+ num_saved++;
+ }
+ Printv(outarg, tm, "\n", NIL);
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* If there were any saved arguments, emit a local variable for them */
+ if (num_saved) {
+ sprintf(temp, "_saved[%d]", num_saved);
+ Wrapper_add_localv(f, "_saved", "SV *", temp, NIL);
+ }
+
+ /* Now write code to make the function call */
+
+ Swig_director_emit_dynamic_cast(n, f);
+ String *actioncode = emit_action(n);
+
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ SwigType *t = Getattr(n, "type");
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$target", "ST(argvi)");
+ Replaceall(tm, "$result", "ST(argvi)");
+ if (is_shadow(t)) {
+ Replaceall(tm, "$shadow", "SWIG_SHADOW");
+ } else {
+ Replaceall(tm, "$shadow", "0");
+ }
+ if (GetFlag(n, "feature:new")) {
+ Replaceall(tm, "$owner", "SWIG_OWNER");
+ } else {
+ Replaceall(tm, "$owner", "0");
+ }
+ Printf(f->code, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
+ }
+ emit_return_variable(n, d, f);
+
+ /* If there were any output args, take care of them. */
+
+ Printv(f->code, outarg, NIL);
+
+ /* If there was any cleanup, do that. */
+
+ Printv(f->code, cleanup, NIL);
+
+ if (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+
+ Printv(f->code, "XSRETURN(argvi);\n", "fail:\n", cleanup, "SWIG_croak_null();\n" "}\n" "}\n", NIL);
+
+ /* Add the dXSARGS last */
+
+ Wrapper_add_local(f, "dXSARGS", "dXSARGS");
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code, "$cleanup", cleanup);
+ Replaceall(f->code, "$symname", iname);
+
+ /* Dump the wrapper function */
+
+ Wrapper_print(f, f_wrappers);
+
+ /* Now register the function */
+
+ if (!Getattr(n, "sym:overloaded")) {
+ Printf(command_tab, "{\"%s::%s\", %s},\n", cmodule, iname, wname);
+ } else if (!Getattr(n, "sym:nextSibling")) {
+ /* Generate overloaded dispatch function */
+ int maxargs;
+ String *dispatch = Swig_overload_dispatch_cast(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");
+ 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)) {
+ Printv(func_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL);
+ }
+
+ }
+ Delete(cleanup);
+ Delete(outarg);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+ virtual int variableWrapper(Node *n) {
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ Wrapper *getf, *setf;
+ String *tm;
+ String *getname = Swig_name_get(iname);
+ String *setname = Swig_name_set(iname);
+
+ String *get_name = Swig_name_wrapper(getname);
+ String *set_name = Swig_name_wrapper(setname);
+
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+
+ getf = NewWrapper();
+ setf = NewWrapper();
+
+ /* Create a Perl function for setting the variable value */
+
+ if (!GetFlag(n, "feature:immutable")) {
+ Setattr(n, "wrap:name", set_name);
+ Printf(setf->def, "SWIGCLASS_STATIC int %s(pTHX_ SV* sv, MAGIC * SWIGUNUSEDPARM(mg)) {\n", set_name);
+ Printv(setf->code, tab4, "MAGIC_PPERL\n", NIL);
+
+ /* Check for a few typemaps */
+ tm = Swig_typemap_lookup("varin", n, name, 0);
+ if (tm) {
+ Replaceall(tm, "$source", "sv");
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$input", "sv");
+ /* Printf(setf->code,"%s\n", tm); */
+ emit_action_code(n, setf->code, tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
+ return SWIG_NOWRAP;
+ }
+ Printf(setf->code, "fail:\n");
+ Printf(setf->code, " return 1;\n}\n");
+ Replaceall(setf->code, "$symname", iname);
+ Wrapper_print(setf, magic);
+ }
+
+ /* Now write a function to evaluate the variable */
+ Setattr(n, "wrap:name", get_name);
+ int addfail = 0;
+ Printf(getf->def, "SWIGCLASS_STATIC int %s(pTHX_ SV *sv, MAGIC *SWIGUNUSEDPARM(mg)) {\n", get_name);
+ Printv(getf->code, tab4, "MAGIC_PPERL\n", NIL);
+
+ if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
+ Replaceall(tm, "$target", "sv");
+ Replaceall(tm, "$result", "sv");
+ Replaceall(tm, "$source", name);
+ if (is_shadow(t)) {
+ Replaceall(tm, "$shadow", "SWIG_SHADOW");
+ } else {
+ Replaceall(tm, "$shadow", "0");
+ }
+ /* Printf(getf->code,"%s\n", tm); */
+ addfail = emit_action_code(n, getf->code, tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
+ DelWrapper(setf);
+ DelWrapper(getf);
+ return SWIG_NOWRAP;
+ }
+ Printf(getf->code, " return 1;\n");
+ if (addfail) {
+ Append(getf->code, "fail:\n");
+ Append(getf->code, " return 0;\n");
+ }
+ Append(getf->code, "}\n");
+
+
+ Replaceall(getf->code, "$symname", iname);
+ Wrapper_print(getf, magic);
+
+ String *tt = Getattr(n, "tmap:varout:type");
+ if (tt) {
+ String *tm = NewStringf("&SWIGTYPE%s", SwigType_manglestr(t));
+ if (Replaceall(tt, "$1_descriptor", tm)) {
+ SwigType_remember(t);
+ }
+ Delete(tm);
+ SwigType *st = Copy(t);
+ SwigType_add_pointer(st);
+ tm = NewStringf("&SWIGTYPE%s", SwigType_manglestr(st));
+ if (Replaceall(tt, "$&1_descriptor", tm)) {
+ SwigType_remember(st);
+ }
+ Delete(tm);
+ Delete(st);
+ } else {
+ tt = (String *) "0";
+ }
+ /* Now add symbol to the PERL interpreter */
+ if (GetFlag(n, "feature:immutable")) {
+ Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS swig_magic_readonly, MAGIC_CLASS ", get_name, ",", tt, " },\n", NIL);
+
+ } else {
+ Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS ", set_name, ", MAGIC_CLASS ", get_name, ",", tt, " },\n", NIL);
+ }
+
+ /* If we're blessed, try to figure out what to do with the variable
+ 1. If it's a Perl object of some sort, create a tied-hash
+ around it.
+ 2. Otherwise, just hack Perl's symbol table */
+
+ if (blessed) {
+ if (is_shadow(t)) {
+ Printv(var_stubs,
+ "\nmy %__", iname, "_hash;\n",
+ "tie %__", iname, "_hash,\"", is_shadow(t), "\", $",
+ cmodule, "::", iname, ";\n", "$", iname, "= \\%__", iname, "_hash;\n", "bless $", iname, ", ", is_shadow(t), ";\n", NIL);
+ } else {
+ Printv(var_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL);
+ }
+ }
+ if (export_all)
+ Printf(exported, "$%s ", iname);
+
+ DelWrapper(setf);
+ DelWrapper(getf);
+ Delete(getname);
+ Delete(setname);
+ Delete(set_name);
+ Delete(get_name);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ String *rawval = Getattr(n, "rawval");
+ String *value = rawval ? rawval : Getattr(n, "value");
+ String *tm;
+
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+
+ /* Special hook for member pointer */
+ if (SwigType_type(type) == T_MPOINTER) {
+ String *wname = Swig_name_wrapper(iname);
+ Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type, wname), value);
+ value = Char(wname);
+ }
+
+ if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ if (is_shadow(type)) {
+ Replaceall(tm, "$shadow", "SWIG_SHADOW");
+ } else {
+ Replaceall(tm, "$shadow", "0");
+ }
+ Printf(constant_tab, "%s,\n", tm);
+ } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ if (is_shadow(type)) {
+ Replaceall(tm, "$shadow", "SWIG_SHADOW");
+ } else {
+ Replaceall(tm, "$shadow", "0");
+ }
+ Printf(f_init, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+
+ if (blessed) {
+ if (is_shadow(type)) {
+ Printv(var_stubs,
+ "\nmy %__", iname, "_hash;\n",
+ "tie %__", iname, "_hash,\"", is_shadow(type), "\", $",
+ cmodule, "::", iname, ";\n", "$", iname, "= \\%__", iname, "_hash;\n", "bless $", iname, ", ", is_shadow(type), ";\n", NIL);
+ } else if (do_constants) {
+ Printv(const_stubs, "sub ", name, " () { $", cmodule, "::", name, " }\n", NIL);
+ num_consts++;
+ } else {
+ Printv(var_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL);
+ }
+ }
+ if (export_all) {
+ if (do_constants && !is_shadow(type)) {
+ Printf(exported, "%s ", name);
+ } else {
+ Printf(exported, "$%s ", iname);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * usage_func()
+ * ------------------------------------------------------------ */
+ char *usage_func(char *iname, SwigType *, ParmList *l) {
+ static String *temp = 0;
+ Parm *p;
+ int i;
+
+ if (!temp)
+ temp = NewString("");
+ Clear(temp);
+ Printf(temp, "%s(", iname);
+
+ /* Now go through and print parameters */
+ p = l;
+ i = 0;
+ while (p != 0) {
+ SwigType *pt = Getattr(p, "type");
+ String *pn = Getattr(p, "name");
+ if (!checkAttribute(p,"tmap:in:numinputs","0")) {
+ /* 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 (!checkAttribute(p,"tmap:in:numinputs","0"))
+ Putc(',', temp);
+ } else {
+ p = nextSibling(p);
+ if (p)
+ if ((i > 0) && (!checkAttribute(p,"tmap:in:numinputs","0")))
+ Putc(',', temp);
+ }
+ }
+ Printf(temp, ");");
+ return Char(temp);
+ }
+
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int nativeWrapper(Node *n) {
+ String *name = Getattr(n, "sym:name");
+ String *funcname = Getattr(n, "wrap:name");
+
+ if (!addSymbol(funcname, n))
+ return SWIG_ERROR;
+
+ Printf(command_tab, "{\"%s::%s\", %s},\n", cmodule, name, funcname);
+ if (export_all)
+ Printf(exported, "%s ", name);
+ if (blessed) {
+ Printv(func_stubs, "*", name, " = *", cmodule, "::", name, ";\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+/* ----------------------------------------------------------------------------
+ * OBJECT-ORIENTED FEATURES
+ *
+ * These extensions provide a more object-oriented interface to C++
+ * classes and structures. The code here is based on extensions
+ * provided by David Fletcher and Gary Holt.
+ *
+ * I have generalized these extensions to make them more general purpose
+ * and to resolve object-ownership problems.
+ *
+ * The approach here is very similar to the Python module :
+ * 1. All of the original methods are placed into a single
+ * package like before except that a 'c' is appended to the
+ * package name.
+ *
+ * 2. All methods and function calls are wrapped with a new
+ * perl function. While possibly inefficient this allows
+ * us to catch complex function arguments (which are hard to
+ * track otherwise).
+ *
+ * 3. Classes are represented as tied-hashes in a manner similar
+ * to Gary Holt's extension. This allows us to access
+ * member data.
+ *
+ * 4. Stand-alone (global) C functions are modified to take
+ * tied hashes as arguments for complex datatypes (if
+ * appropriate).
+ *
+ * 5. Global variables involving a class/struct is encapsulated
+ * in a tied hash.
+ *
+ * ------------------------------------------------------------------------- */
+
+
+ void setclassname(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ String *fullname;
+ String *actualpackage;
+ Node *clsmodule = Getattr(n, "module");
+
+ if (!clsmodule) {
+ /* imported module does not define a module name. Oh well */
+ return;
+ }
+
+ /* Do some work on the class name */
+ if (verbose > 0) {
+ String *modulename = Getattr(clsmodule, "name");
+ fprintf(stdout, "setclassname: Found sym:name: %s\n", Char(symname));
+ fprintf(stdout, "setclassname: Found module: %s\n", Char(modulename));
+ fprintf(stdout, "setclassname: No package found\n");
+ }
+
+ if (dest_package) {
+ fullname = NewStringf("%s::%s", namespace_module, symname);
+ } else {
+ actualpackage = Getattr(clsmodule,"name");
+
+ if (verbose > 0) {
+ fprintf(stdout, "setclassname: Found actualpackage: %s\n", Char(actualpackage));
+ }
+ if ((!compat) && (!Strchr(symname,':'))) {
+ fullname = NewStringf("%s::%s",actualpackage,symname);
+ } else {
+ fullname = NewString(symname);
+ }
+ }
+ if (verbose > 0) {
+ fprintf(stdout, "setclassname: setting proxy: %s\n", Char(fullname));
+ }
+ Setattr(n, "perl5:proxy", fullname);
+ }
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+ virtual int classDeclaration(Node *n) {
+ /* Do some work on the class name */
+ if (!Getattr(n, "feature:onlychildren")) {
+ if (blessed) {
+ setclassname(n);
+ Append(classlist, n);
+ }
+ }
+
+ return Language::classDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int classHandler(Node *n) {
+
+ if (blessed) {
+ have_constructor = 0;
+ have_operators = 0;
+ have_destructor = 0;
+ have_data_members = 0;
+ operators = NewHash();
+
+ class_name = Getattr(n, "sym:name");
+
+ if (!addSymbol(class_name, n))
+ return SWIG_ERROR;
+
+ /* Use the fully qualified name of the Perl class */
+ if (!compat) {
+ fullclassname = NewStringf("%s::%s", namespace_module, class_name);
+ } else {
+ fullclassname = NewString(class_name);
+ }
+ real_classname = Getattr(n, "name");
+ pcode = NewString("");
+ // blessedmembers = NewString("");
+ }
+
+ /* Emit all of the members */
+ Language::classHandler(n);
+
+
+ /* Finish the rest of the class */
+ if (blessed) {
+ /* Generate a client-data entry */
+ SwigType *ct = NewStringf("p.%s", real_classname);
+ Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", SwigType_manglestr(ct), ", (void*) \"", fullclassname, "\");\n", NIL);
+ SwigType_remember(ct);
+ Delete(ct);
+
+ Printv(pm, "\n############# Class : ", fullclassname, " ##############\n", "\npackage ", fullclassname, ";\n", NIL);
+
+ if (have_operators) {
+ Printf(pm, "use overload\n");
+ Iterator ki;
+ for (ki = First(operators); ki.key; ki = Next(ki)) {
+ char *name = Char(ki.key);
+ // fprintf(stderr,"found name: <%s>\n", name);
+ if (strstr(name, "__eq__")) {
+ Printv(pm, tab4, "\"==\" => sub { $_[0]->__eq__($_[1])},\n",NIL);
+ } else if (strstr(name, "__ne__")) {
+ Printv(pm, tab4, "\"!=\" => sub { $_[0]->__ne__($_[1])},\n",NIL);
+ // there are no tests for this in operator_overload_runme.pl
+ // it is likely to be broken
+ // } else if (strstr(name, "__assign__")) {
+ // Printv(pm, tab4, "\"=\" => sub { $_[0]->__assign__($_[1])},\n",NIL);
+ } else if (strstr(name, "__str__")) {
+ Printv(pm, tab4, "'\"\"' => sub { $_[0]->__str__()},\n",NIL);
+ } else if (strstr(name, "__plusplus__")) {
+ Printv(pm, tab4, "\"++\" => sub { $_[0]->__plusplus__()},\n",NIL);
+ } else if (strstr(name, "__minmin__")) {
+ Printv(pm, tab4, "\"--\" => sub { $_[0]->__minmin__()},\n",NIL);
+ } else if (strstr(name, "__add__")) {
+ Printv(pm, tab4, "\"+\" => sub { $_[0]->__add__($_[1])},\n",NIL);
+ } else if (strstr(name, "__sub__")) {
+ Printv(pm, tab4, "\"-\" => sub { if( not $_[2] ) { $_[0]->__sub__($_[1]) }\n",NIL);
+ Printv(pm, tab8, "elsif( $_[0]->can('__rsub__') ) { $_[0]->__rsub__($_[1]) }\n",NIL);
+ Printv(pm, tab8, "else { die(\"reverse subtraction not supported\") }\n",NIL);
+ Printv(pm, tab8, "},\n",NIL);
+ } else if (strstr(name, "__mul__")) {
+ Printv(pm, tab4, "\"*\" => sub { $_[0]->__mul__($_[1])},\n",NIL);
+ } else if (strstr(name, "__div__")) {
+ Printv(pm, tab4, "\"/\" => sub { $_[0]->__div__($_[1])},\n",NIL);
+ } else if (strstr(name, "__mod__")) {
+ Printv(pm, tab4, "\"%\" => sub { $_[0]->__mod__($_[1])},\n",NIL);
+ // there are no tests for this in operator_overload_runme.pl
+ // it is likely to be broken
+ // } else if (strstr(name, "__and__")) {
+ // Printv(pm, tab4, "\"&\" => sub { $_[0]->__and__($_[1])},\n",NIL);
+
+ // there are no tests for this in operator_overload_runme.pl
+ // it is likely to be broken
+ // } else if (strstr(name, "__or__")) {
+ // Printv(pm, tab4, "\"|\" => sub { $_[0]->__or__($_[1])},\n",NIL);
+ } else if (strstr(name, "__gt__")) {
+ Printv(pm, tab4, "\">\" => sub { $_[0]->__gt__($_[1])},\n",NIL);
+ } else if (strstr(name, "__ge__")) {
+ Printv(pm, tab4, "\">=\" => sub { $_[0]->__ge__($_[1])},\n",NIL);
+ } else if (strstr(name, "__not__")) {
+ Printv(pm, tab4, "\"!\" => sub { $_[0]->__not__()},\n",NIL);
+ } else if (strstr(name, "__lt__")) {
+ Printv(pm, tab4, "\"<\" => sub { $_[0]->__lt__($_[1])},\n",NIL);
+ } else if (strstr(name, "__le__")) {
+ Printv(pm, tab4, "\"<=\" => sub { $_[0]->__le__($_[1])},\n",NIL);
+ } else if (strstr(name, "__pluseq__")) {
+ Printv(pm, tab4, "\"+=\" => sub { $_[0]->__pluseq__($_[1])},\n",NIL);
+ } else if (strstr(name, "__mineq__")) {
+ Printv(pm, tab4, "\"-=\" => sub { $_[0]->__mineq__($_[1])},\n",NIL);
+ } else if (strstr(name, "__neg__")) {
+ Printv(pm, tab4, "\"neg\" => sub { $_[0]->__neg__()},\n",NIL);
+ } else {
+ fprintf(stderr,"Unknown operator: %s\n", name);
+ }
+ }
+ Printv(pm, tab4,
+ "\"=\" => sub { my $class = ref($_[0]); $class->new($_[0]) },\n", NIL);
+ Printv(pm, tab4, "\"fallback\" => 1;\n", NIL);
+ }
+ // make use strict happy
+ Printv(pm, "use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);\n", NIL);
+
+ /* If we are inheriting from a base class, set that up */
+
+ Printv(pm, "@ISA = qw(", NIL);
+
+ /* Handle inheritance */
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator b;
+ b = First(baselist);
+ while (b.item) {
+ String *bname = Getattr(b.item, "perl5:proxy");
+ if (!bname) {
+ b = Next(b);
+ continue;
+ }
+ Printv(pm, " ", bname, NIL);
+ b = Next(b);
+ }
+ }
+
+ /* Module comes last */
+ if (!compat || Cmp(namespace_module, fullclassname)) {
+ Printv(pm, " ", namespace_module, NIL);
+ }
+
+ Printf(pm, " );\n");
+
+ /* Dump out a hash table containing the pointers that we own */
+ Printf(pm, "%%OWNER = ();\n");
+ if (have_data_members || have_destructor)
+ Printf(pm, "%%ITERATORS = ();\n");
+
+ /* Dump out the package methods */
+
+ Printv(pm, pcode, NIL);
+ Delete(pcode);
+
+ /* Output methods for managing ownership */
+
+ Printv(pm,
+ "sub DISOWN {\n",
+ tab4, "my $self = shift;\n",
+ tab4, "my $ptr = tied(%$self);\n",
+ tab4, "delete $OWNER{$ptr};\n",
+ "}\n\n", "sub ACQUIRE {\n", tab4, "my $self = shift;\n", tab4, "my $ptr = tied(%$self);\n", tab4, "$OWNER{$ptr} = 1;\n", "}\n\n", NIL);
+
+ /* Only output the following methods if a class has member data */
+
+ Delete(operators);
+ operators = 0;
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberfunctionHandler(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+
+ member_func = 1;
+ Language::memberfunctionHandler(n);
+ member_func = 0;
+
+ if ((blessed) && (!Getattr(n, "sym:nextSibling"))) {
+
+ if (Strstr(symname, "__eq__")) {
+ DohSetInt(operators, "__eq__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__ne__")) {
+ DohSetInt(operators, "__ne__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__assign__")) {
+ DohSetInt(operators, "__assign__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__str__")) {
+ DohSetInt(operators, "__str__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__add__")) {
+ DohSetInt(operators, "__add__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__sub__")) {
+ DohSetInt(operators, "__sub__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__mul__")) {
+ DohSetInt(operators, "__mul__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__div__")) {
+ DohSetInt(operators, "__div__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__mod__")) {
+ DohSetInt(operators, "__mod__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__and__")) {
+ DohSetInt(operators, "__and__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__or__")) {
+ DohSetInt(operators, "__or__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__not__")) {
+ DohSetInt(operators, "__not__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__gt__")) {
+ DohSetInt(operators, "__gt__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__ge__")) {
+ DohSetInt(operators, "__ge__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__lt__")) {
+ DohSetInt(operators, "__lt__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__le__")) {
+ DohSetInt(operators, "__le__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__neg__")) {
+ DohSetInt(operators, "__neg__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__plusplus__")) {
+ DohSetInt(operators, "__plusplus__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__minmin__")) {
+ DohSetInt(operators, "__minmin__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__mineq__")) {
+ DohSetInt(operators, "__mineq__", 1);
+ have_operators = 1;
+ } else if (Strstr(symname, "__pluseq__")) {
+ DohSetInt(operators, "__pluseq__", 1);
+ have_operators = 1;
+ }
+
+ if (Getattr(n, "feature:shadow")) {
+ String *plcode = perlcode(Getattr(n, "feature:shadow"), 0);
+ String *plaction = NewStringf("%s::%s", cmodule, Swig_name_member(class_name, symname));
+ Replaceall(plcode, "$action", plaction);
+ Delete(plaction);
+ Printv(pcode, plcode, NIL);
+ } else {
+ Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(class_name, symname), ";\n", NIL);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ *
+ * Adds an instance member.
+ * ----------------------------------------------------------------------------- */
+
+ virtual int membervariableHandler(Node *n) {
+
+ String *symname = Getattr(n, "sym:name");
+ /* SwigType *t = Getattr(n,"type"); */
+
+ /* Emit a pair of get/set functions for the variable */
+
+ member_func = 1;
+ Language::membervariableHandler(n);
+ member_func = 0;
+
+ if (blessed) {
+
+ Printv(pcode, "*swig_", symname, "_get = *", cmodule, "::", Swig_name_get(Swig_name_member(class_name, symname)), ";\n", NIL);
+ Printv(pcode, "*swig_", symname, "_set = *", cmodule, "::", Swig_name_set(Swig_name_member(class_name, symname)), ";\n", NIL);
+
+ /* Now we need to generate a little Perl code for this */
+
+ /* if (is_shadow(t)) {
+
+ *//* This is a Perl object that we have already seen. Add an
+ entry to the members list *//*
+ Printv(blessedmembers,
+ tab4, symname, " => '", is_shadow(t), "',\n",
+ NIL);
+
+ }
+ */
+ }
+ have_data_members++;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorDeclaration()
+ *
+ * Emits a blessed constructor for our class. In addition to our construct
+ * we manage a Perl hash table containing all of the pointers created by
+ * the constructor. This prevents us from accidentally trying to free
+ * something that wasn't necessarily allocated by malloc or new
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+
+ String *symname = Getattr(n, "sym:name");
+
+ member_func = 1;
+ Language::constructorHandler(n);
+
+ if ((blessed) && (!Getattr(n, "sym:nextSibling"))) {
+ if (Getattr(n, "feature:shadow")) {
+ String *plcode = perlcode(Getattr(n, "feature:shadow"), 0);
+ String *plaction = NewStringf("%s::%s", module, Swig_name_member(class_name, symname));
+ Replaceall(plcode, "$action", plaction);
+ Delete(plaction);
+ Printv(pcode, plcode, NIL);
+ } else {
+ if ((Cmp(symname, class_name) == 0)) {
+ /* Emit a blessed constructor */
+ Printf(pcode, "sub new {\n");
+ } else {
+ /* Constructor doesn't match classname so we'll just use the normal name */
+ Printv(pcode, "sub ", Swig_name_construct(symname), " {\n", NIL);
+ }
+
+ Printv(pcode,
+ tab4, "my $pkg = shift;\n",
+ tab4, "my $self = ", cmodule, "::", Swig_name_construct(symname), "(@_);\n", tab4, "bless $self, $pkg if defined($self);\n", "}\n\n", NIL);
+
+ have_constructor = 1;
+ }
+ }
+ member_func = 0;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorHandler(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ member_func = 1;
+ Language::destructorHandler(n);
+ if (blessed) {
+ if (Getattr(n, "feature:shadow")) {
+ String *plcode = perlcode(Getattr(n, "feature:shadow"), 0);
+ String *plaction = NewStringf("%s::%s", module, Swig_name_member(class_name, symname));
+ Replaceall(plcode, "$action", plaction);
+ Delete(plaction);
+ Printv(pcode, plcode, NIL);
+ } else {
+ Printv(pcode,
+ "sub DESTROY {\n",
+ tab4, "return unless $_[0]->isa('HASH');\n",
+ tab4, "my $self = tied(%{$_[0]});\n",
+ tab4, "return unless defined $self;\n",
+ tab4, "delete $ITERATORS{$self};\n",
+ tab4, "if (exists $OWNER{$self}) {\n",
+ tab8, cmodule, "::", Swig_name_destroy(symname), "($self);\n", tab8, "delete $OWNER{$self};\n", tab4, "}\n}\n\n", NIL);
+ have_destructor = 1;
+ }
+ }
+ member_func = 0;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ member_func = 1;
+ Language::staticmemberfunctionHandler(n);
+ member_func = 0;
+ if ((blessed) && (!Getattr(n, "sym:nextSibling"))) {
+ String *symname = Getattr(n, "sym:name");
+ Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(class_name, symname), ";\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmembervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ Language::staticmembervariableHandler(n);
+ if (blessed) {
+ String *symname = Getattr(n, "sym:name");
+ Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(class_name, symname), ";\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberconstantHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberconstantHandler(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ int oldblessed = blessed;
+
+ /* Create a normal constant */
+ blessed = 0;
+ Language::memberconstantHandler(n);
+ blessed = oldblessed;
+
+ if (blessed) {
+ Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(class_name, symname), ";\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * pragma()
+ *
+ * Pragma directive.
+ *
+ * %pragma(perl5) code="String" # Includes a string in the .pm file
+ * %pragma(perl5) include="file.pl" # Includes a file in the .pm file
+ * ------------------------------------------------------------ */
+
+ virtual int pragmaDirective(Node *n) {
+ String *lang;
+ String *code;
+ String *value;
+ if (!ImportMode) {
+ lang = Getattr(n, "lang");
+ code = Getattr(n, "name");
+ value = Getattr(n, "value");
+ if (Strcmp(lang, "perl5") == 0) {
+ if (Strcmp(code, "code") == 0) {
+ /* Dump the value string into the .pm file */
+ if (value) {
+ Printf(pragma_include, "%s\n", value);
+ }
+ } else if (Strcmp(code, "include") == 0) {
+ /* Include a file into the .pm file */
+ if (value) {
+ FILE *f = Swig_include_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);
+ }
+ }
+ fclose(f);
+ }
+ } else {
+ Printf(stderr, "%s : Line %d. Unrecognized pragma.\n", input_file, line_number);
+ }
+ }
+ }
+ return Language::pragmaDirective(n);
+ }
+
+ /* ------------------------------------------------------------
+ * perlcode() - Output perlcode code into the shadow file
+ * ------------------------------------------------------------ */
+
+ String *perlcode(String *code, const String *indent) {
+ String *out = NewString("");
+ String *temp;
+ char *t;
+ if (!indent)
+ indent = "";
+
+ temp = NewString(code);
+
+ t = Char(temp);
+ if (*t == '{') {
+ Delitem(temp, 0);
+ Delitem(temp, DOH_END);
+ }
+
+ /* Split the input text into lines */
+ List *clist = DohSplitLines(temp);
+ Delete(temp);
+ int initial = 0;
+ String *s = 0;
+ Iterator si;
+ /* Get the initial indentation */
+
+ for (si = First(clist); si.item; si = Next(si)) {
+ s = si.item;
+ if (Len(s)) {
+ char *c = Char(s);
+ while (*c) {
+ if (!isspace(*c))
+ break;
+ initial++;
+ c++;
+ }
+ if (*c && !isspace(*c))
+ break;
+ else {
+ initial = 0;
+ }
+ }
+ }
+ while (si.item) {
+ s = si.item;
+ if (Len(s) > initial) {
+ char *c = Char(s);
+ c += initial;
+ Printv(out, indent, c, "\n", NIL);
+ } else {
+ Printv(out, "\n", NIL);
+ }
+ si = Next(si);
+ }
+ Delete(clist);
+ return out;
+ }
+
+ /* ------------------------------------------------------------
+ * insertDirective()
+ *
+ * Hook for %insert directive.
+ * ------------------------------------------------------------ */
+
+ virtual int insertDirective(Node *n) {
+ String *code = Getattr(n, "code");
+ String *section = Getattr(n, "section");
+
+ if ((!ImportMode) && (Cmp(section, "perl") == 0)) {
+ Printv(additional_perl_code, code, NIL);
+ } else {
+ Language::insertDirective(n);
+ }
+ return SWIG_OK;
+ }
+
+ String *runtimeCode() {
+ String *s = NewString("");
+ String *shead = Swig_include_sys("perlhead.swg");
+ if (!shead) {
+ Printf(stderr, "*** Unable to open 'perlhead.swg'\n");
+ } else {
+ Append(s, shead);
+ Delete(shead);
+ }
+ String *serrors = Swig_include_sys("perlerrors.swg");
+ if (!serrors) {
+ Printf(stderr, "*** Unable to open 'perlerrors.swg'\n");
+ } else {
+ Append(s, serrors);
+ Delete(serrors);
+ }
+ String *srun = Swig_include_sys("perlrun.swg");
+ if (!srun) {
+ Printf(stderr, "*** Unable to open 'perlrun.swg'\n");
+ } else {
+ Append(s, srun);
+ Delete(srun);
+ }
+ return s;
+ }
+
+ String *defaultExternalRuntimeFilename() {
+ return NewString("swigperlrun.h");
+ }
+};
+
+/* -----------------------------------------------------------------------------
+ * swig_perl5() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_perl5() {
+ return new PERL5();
+}
+extern "C" Language *swig_perl5(void) {
+ return new_swig_perl5();
+}
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
new file mode 100644
index 0000000..a0c9e24
--- /dev/null
+++ b/Source/Modules/php.cxx
@@ -0,0 +1,2739 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * php.cxx
+ *
+ * PHP language module for SWIG.
+ * -----------------------------------------------------------------------------
+ */
+
+/* FIXME: PHP5 OO wrapping TODO list:
+ *
+ * Medium term:
+ *
+ * Handle default parameters on overloaded methods in PHP where possible.
+ * (Mostly done - just need to handle cases of overloaded methods with
+ * default parameters...)
+ * This is an optimisation - we could handle this case using a PHP
+ * default value, but currently we treat it as we would for a default
+ * value which is a compound C++ expression (i.e. as if we had a
+ * method with two overloaded forms instead of a single method with
+ * a default parameter value).
+ *
+ * Long term:
+ *
+ * Sort out locale-dependent behaviour of strtod() - it's harmless unless
+ * SWIG ever sets the locale and DOH/base.c calls atof, so we're probably
+ * OK currently at least.
+ */
+
+/*
+ * TODO: Replace remaining stderr messages with Swig_error or Swig_warning
+ * (may need to add more WARN_PHP_xxx codes...)
+ */
+
+char cvsroot_php_cxx[] = "$Id: php.cxx 11637 2009-08-18 16:23:23Z vmiklos $";
+
+#include "swigmod.h"
+
+#include <ctype.h>
+#include <errno.h>
+
+static const char *usage = (char *) "\
+PHP Options (available with -php)\n\
+ -cppext - cpp file extension (default to .cpp)\n\
+ -noproxy - Don't generate proxy classes.\n\
+ -prefix <prefix> - Prepend <prefix> to all class names in PHP wrappers\n\
+\n";
+
+/* The original class wrappers for PHP stored the pointer to the C++ class in
+ * the object property _cPtr. If we use the same name for the member variable
+ * which we put the pointer to the C++ class in, then the flat function
+ * wrappers will automatically pull it out without any changes being required.
+ * FIXME: Isn't using a leading underscore a bit suspect here?
+ */
+#define SWIG_PTR "_cPtr"
+
+/* This is the name of the hash where the variables existing only in PHP
+ * classes are stored.
+ */
+#define SWIG_DATA "_pData"
+
+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 *prefix = 0;
+
+static String *shadow_classname = 0;
+
+static File *f_begin = 0;
+static File *f_runtime = 0;
+static File *f_runtime_h = 0;
+static File *f_h = 0;
+static File *f_phpcode = 0;
+static File *f_directors = 0;
+static File *f_directors_h = 0;
+static String *phpfilename = 0;
+
+static String *s_header;
+static String *s_wrappers;
+static String *s_init;
+static String *r_init; // RINIT user code
+static String *s_shutdown; // MSHUTDOWN user code
+static String *r_shutdown; // RSHUTDOWN user code
+static String *s_vinit; // varinit initialization code.
+static String *s_vdecl;
+static String *s_cinit; // consttab initialization code.
+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;
+static String *s_oowrappers;
+static String *s_fakeoowrappers;
+static String *s_phpclasses;
+
+/* Variables for using PHP classes */
+static Node *current_class = 0;
+
+static Hash *shadow_get_vars;
+static Hash *shadow_set_vars;
+static Hash *zend_types = 0;
+
+static int shadow = 1;
+
+static bool class_has_ctor = false;
+static String *wrapping_member_constant = NULL;
+
+// These static variables are used to pass some state from Handlers into functionWrapper
+static enum {
+ standard = 0,
+ memberfn,
+ staticmemberfn,
+ membervar,
+ staticmembervar,
+ constructor,
+ directorconstructor
+} wrapperType = standard;
+
+extern "C" {
+ static void (*r_prevtracefunc) (SwigType *t, String *mangled, String *clientdata) = 0;
+}
+
+static void SwigPHP_emit_resource_registrations() {
+ Iterator ki;
+
+ if (!zend_types)
+ return;
+
+ ki = First(zend_types);
+ if (ki.key)
+ Printf(s_oinit, "\n/* Register resource destructors for pointer types */\n");
+ while (ki.key) {
+ DOH *key = ki.key;
+ Node *class_node = ki.item;
+ String *human_name = key;
+
+ // Write out destructor function header
+ Printf(s_wrappers, "static ZEND_RSRC_DTOR_FUNC(_wrap_destroy%s) {\n", key);
+
+ // write out body
+ if (class_node != NOTCLASS) {
+ String *destructor = Getattr(class_node, "destructor");
+ human_name = Getattr(class_node, "sym:name");
+ if (!human_name)
+ human_name = Getattr(class_node, "name");
+ // Do we have a known destructor for this type?
+ if (destructor) {
+ Printf(s_wrappers, " %s(rsrc, SWIGTYPE%s->name TSRMLS_CC);\n", destructor, key);
+ } else {
+ Printf(s_wrappers, " /* No destructor for class %s */\n", human_name);
+ Printf(s_wrappers, " efree(rsrc->ptr);\n");
+ }
+ } else {
+ Printf(s_wrappers, " /* No destructor for simple type %s */\n", key);
+ Printf(s_wrappers, " efree(rsrc->ptr);\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, human_name);
+
+ // 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);
+
+ ki = Next(ki);
+ }
+}
+
+class PHP : public Language {
+public:
+ PHP() {
+ director_language = 1;
+ }
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+ SWIG_library_directory("php");
+ SWIG_config_cppext("cpp");
+
+ for (int i = 1; i < argc; 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], "-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], "-help") == 0) {
+ fputs(usage, stdout);
+ } else if (strcmp(argv[i], "-make") == 0 ||
+ strcmp(argv[i], "-withc") == 0 ||
+ strcmp(argv[i], "-withcxx") == 0) {
+ Printf(stderr, "*** %s is no longer supported.\n", argv[i]);
+ SWIG_exit(EXIT_FAILURE);
+ } else if (strcmp(argv[i], "-phpfull") == 0 ||
+ strcmp(argv[i], "-withlibs") == 0 ||
+ strcmp(argv[i], "-withincs") == 0) {
+ Printf(stderr, "*** %s is no longer supported.\n*** We recommend building as a dynamically loadable module.\n", argv[i]);
+ SWIG_exit(EXIT_FAILURE);
+ } else if (strcmp(argv[i], "-dlname") == 0) {
+ Printf(stderr, "*** -dlname is no longer supported.\n*** If you want to change the module name, use -module instead.\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+
+ Preprocessor_define("SWIGPHP 1", 0);
+ // SWIGPHP5 is deprecated, and no longer documented.
+ Preprocessor_define("SWIGPHP5 1", 0);
+ SWIG_typemap_lang("php");
+ SWIG_config_file("php.swg");
+ allow_overloading();
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+
+ String *filen;
+ String *s_type;
+
+ /* Check if directors are enabled for this module. */
+ Node *mod = Getattr(n, "module");
+ if (mod) {
+ Node *options = Getattr(mod, "options");
+ if (options && Getattr(options, "directors")) {
+ allow_directors();
+ }
+ }
+
+ /* Set comparison with null for ConstructorToFunction */
+ setSubclassInstanceCheck(NewString("$arg->type != IS_NULL"));
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+ String *outfile_h = Getattr(n, "outfile_h");
+
+ /* main output file */
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewStringEmpty();
+
+ /* sections of the output file */
+ s_init = NewString("/* init section */\n");
+ r_init = NewString("/* rinit section */\n");
+ s_shutdown = NewString("/* shutdown section */\n");
+ r_shutdown = NewString("/* rshutdown section */\n");
+ s_header = NewString("/* header section */\n");
+ s_wrappers = NewString("/* wrapper section */\n");
+ s_type = NewStringEmpty();
+ /* 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 = NewStringEmpty();
+ s_phpclasses = NewString("/* PHP Proxy Classes */\n");
+ f_directors_h = NewStringEmpty();
+ f_directors = NewStringEmpty();
+
+ if (directorsEnabled()) {
+ f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
+ if (!f_runtime_h) {
+ FileErrorDisplay(outfile_h);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", s_init);
+ Swig_register_filebyname("rinit", r_init);
+ Swig_register_filebyname("shutdown", s_shutdown);
+ Swig_register_filebyname("rshutdown", r_shutdown);
+ Swig_register_filebyname("header", s_header);
+ Swig_register_filebyname("wrapper", s_wrappers);
+ Swig_register_filebyname("director", f_directors);
+ Swig_register_filebyname("director_h", f_directors_h);
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGPHP\n");
+ Printf(f_runtime, "\n");
+
+ if (directorsEnabled()) {
+ Printf(f_runtime, "#define SWIG_DIRECTORS\n");
+ }
+
+ /* Set the module name */
+ module = Copy(Getattr(n, "name"));
+ cap_module = NewStringf("%(upper)s", module);
+ if (!prefix)
+ prefix = NewStringEmpty();
+
+ if (directorsEnabled()) {
+ Swig_banner(f_directors_h);
+ Printf(f_directors_h, "\n");
+ Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", cap_module);
+ Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", cap_module);
+
+ Printf(f_directors, "\n#include \"%s\"\n\n", Swig_file_filename(outfile_h));
+ }
+
+ /* PHP module file */
+ filen = NewStringEmpty();
+ Printv(filen, SWIG_output_directory(), module, ".php", NIL);
+ phpfilename = NewString(filen);
+
+ f_phpcode = NewFile(filen, "w", SWIG_output_files());
+ if (!f_phpcode) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Printf(f_phpcode, "<?php\n\n");
+
+ Swig_banner(f_phpcode);
+
+ Printf(f_phpcode, "\n");
+ Printf(f_phpcode, "// Try to load our extension if it's not already loaded.\n");
+ Printf(f_phpcode, "if (!extension_loaded('%s')) {\n", module);
+ Printf(f_phpcode, " if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {\n");
+ Printf(f_phpcode, " if (!dl('php_%s.dll')) return;\n", module);
+ Printf(f_phpcode, " } else {\n");
+ Printf(f_phpcode, " // PHP_SHLIB_SUFFIX gives 'dylib' on MacOS X but modules are 'so'.\n");
+ Printf(f_phpcode, " if (PHP_SHLIB_SUFFIX === 'dylib') {\n");
+ Printf(f_phpcode, " if (!dl('%s.so')) return;\n", module);
+ Printf(f_phpcode, " } else {\n");
+ Printf(f_phpcode, " if (!dl('%s.'.PHP_SHLIB_SUFFIX)) return;\n", module);
+ Printf(f_phpcode, " }\n");
+ Printf(f_phpcode, " }\n");
+ Printf(f_phpcode, "}\n\n");
+
+ /* sub-sections of the php file */
+ pragma_code = NewStringEmpty();
+ pragma_incl = NewStringEmpty();
+
+ /* Initialize the rest of the module */
+
+ Printf(s_oinit, "ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, %s_destroy_globals);\n", module, module, module);
+
+ /* start the header section */
+ Printf(s_header, "ZEND_BEGIN_MODULE_GLOBALS(%s)\n", module);
+ Printf(s_header, "const char *error_msg;\n");
+ Printf(s_header, "int error_code;\n");
+ Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module);
+ Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n", module);
+ Printf(s_header, "#ifdef ZTS\n");
+ Printf(s_header, "#define SWIG_ErrorMsg() TSRMG(%s_globals_id, zend_%s_globals *, error_msg )\n", module, module);
+ Printf(s_header, "#define SWIG_ErrorCode() TSRMG(%s_globals_id, zend_%s_globals *, error_code )\n", module, module);
+ Printf(s_header, "#else\n");
+ Printf(s_header, "#define SWIG_ErrorMsg() (%s_globals.error_msg)\n", module);
+ Printf(s_header, "#define SWIG_ErrorCode() (%s_globals.error_code)\n", module);
+ Printf(s_header, "#endif\n\n");
+
+ Printf(s_header, "static void %s_init_globals(zend_%s_globals *globals ) {\n", module, module);
+ Printf(s_header, " globals->error_msg = default_error_msg;\n");
+ Printf(s_header, " globals->error_code = default_error_code;\n");
+ Printf(s_header, "}\n");
+
+ Printf(s_header, "static void %s_destroy_globals(zend_%s_globals * globals) { (void)globals; }\n", module, module);
+
+ Printf(s_header, "\n");
+ Printf(s_header, "static void SWIG_ResetError() {\n");
+ Printf(s_header, " TSRMLS_FETCH();\n");
+ Printf(s_header, " SWIG_ErrorMsg() = default_error_msg;\n");
+ Printf(s_header, " SWIG_ErrorCode() = default_error_code;\n");
+ Printf(s_header, "}\n");
+
+ Append(s_header, "\n");
+ Printf(s_header, "ZEND_NAMED_FUNCTION(_wrap_swig_%s_alter_newobject) {\n", module);
+ Append(s_header, " zval **args[2];\n");
+ Append(s_header, " swig_object_wrapper *value;\n");
+ Append(s_header, " int type;\n");
+ Append(s_header, " int thisown;\n");
+ Append(s_header, "\n");
+ Append(s_header, " SWIG_ResetError();\n");
+ Append(s_header, " if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n");
+ Append(s_header, " WRONG_PARAM_COUNT;\n");
+ Append(s_header, " }\n");
+ Append(s_header, "\n");
+ Append(s_header, " value = (swig_object_wrapper *) zend_list_find((*args[0])->value.lval, &type);\n");
+ Append(s_header, " value->newobject = zval_is_true(*args[1]);\n");
+ Append(s_header, "\n");
+ Append(s_header, " return;\n");
+ Append(s_header, "}\n");
+ Printf(s_header, "ZEND_NAMED_FUNCTION(_wrap_swig_%s_get_newobject) {\n", module);
+ Append(s_header, " zval **args[1];\n");
+ Append(s_header, " swig_object_wrapper *value;\n");
+ Append(s_header, " int type;\n");
+ Append(s_header, "\n");
+ Append(s_header, " SWIG_ResetError();\n");
+ Append(s_header, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n");
+ Append(s_header, " WRONG_PARAM_COUNT;\n");
+ Append(s_header, " }\n");
+ Append(s_header, "\n");
+ Append(s_header, " value = (swig_object_wrapper *) zend_list_find((*args[0])->value.lval, &type);\n");
+ Append(s_header, " RETVAL_LONG(value->newobject);\n");
+ Append(s_header, "\n");
+ Append(s_header, " return;\n");
+ Append(s_header, "}\n");
+
+ Printf(s_header, "#define SWIG_name \"%s\"\n", module);
+ /* Printf(s_header,"#ifdef HAVE_CONFIG_H\n");
+ Printf(s_header,"#include \"config.h\"\n");
+ Printf(s_header,"#endif\n\n");
+ */
+ Printf(s_header, "#ifdef __cplusplus\n");
+ Printf(s_header, "extern \"C\" {\n");
+ Printf(s_header, "#endif\n");
+ Printf(s_header, "#include \"php.h\"\n");
+ Printf(s_header, "#include \"php_ini.h\"\n");
+ Printf(s_header, "#include \"ext/standard/info.h\"\n");
+ Printf(s_header, "#include \"php_%s.h\"\n", module);
+ Printf(s_header, "#ifdef __cplusplus\n");
+ Printf(s_header, "}\n");
+ Printf(s_header, "#endif\n\n");
+
+ if (directorsEnabled()) {
+ // Insert director runtime
+ Swig_insert_file("director.swg", s_header);
+ }
+
+ /* Create the .h file too */
+ filen = NewStringEmpty();
+ Printv(filen, SWIG_output_directory(), "php_", module, ".h", NIL);
+ f_h = NewFile(filen, "w", SWIG_output_files());
+ if (!f_h) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Swig_banner(f_h);
+
+ Printf(f_h, "\n");
+ Printf(f_h, "#ifndef PHP_%s_H\n", cap_module);
+ Printf(f_h, "#define PHP_%s_H\n\n", cap_module);
+ Printf(f_h, "extern zend_module_entry %s_module_entry;\n", module);
+ Printf(f_h, "#define phpext_%s_ptr &%s_module_entry\n\n", module, module);
+ Printf(f_h, "#ifdef PHP_WIN32\n");
+ Printf(f_h, "# define PHP_%s_API __declspec(dllexport)\n", cap_module);
+ Printf(f_h, "#else\n");
+ Printf(f_h, "# define PHP_%s_API\n", cap_module);
+ Printf(f_h, "#endif\n\n");
+ Printf(f_h, "#ifdef ZTS\n");
+ Printf(f_h, "#include \"TSRM.h\"\n");
+ Printf(f_h, "#endif\n\n");
+ Printf(f_h, "PHP_MINIT_FUNCTION(%s);\n", module);
+ Printf(f_h, "PHP_MSHUTDOWN_FUNCTION(%s);\n", module);
+ Printf(f_h, "PHP_RINIT_FUNCTION(%s);\n", module);
+ Printf(f_h, "PHP_RSHUTDOWN_FUNCTION(%s);\n", module);
+ Printf(f_h, "PHP_MINFO_FUNCTION(%s);\n\n", 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, "static zend_function_entry %s_functions[] = {\n", module);
+
+ /* start the init section */
+ Append(s_init, "#if ZEND_MODULE_API_NO <= 20090626\n");
+ Append(s_init, "#undef ZEND_MODULE_BUILD_ID\n");
+ Append(s_init, "#define ZEND_MODULE_BUILD_ID (char*)\"API\" ZEND_TOSTR(ZEND_MODULE_API_NO) ZEND_BUILD_TS ZEND_BUILD_DEBUG ZEND_BUILD_SYSTEM ZEND_BUILD_EXTRA\n");
+ Append(s_init, "#endif\n");
+ Printv(s_init, "zend_module_entry ", module, "_module_entry = {\n" "#if ZEND_MODULE_API_NO > 20010900\n" " STANDARD_MODULE_HEADER,\n" "#endif\n", NIL);
+ Printf(s_init, " (char*)\"%s\",\n", module);
+ Printf(s_init, " %s_functions,\n", module);
+ Printf(s_init, " PHP_MINIT(%s),\n", module);
+ Printf(s_init, " PHP_MSHUTDOWN(%s),\n", module);
+ Printf(s_init, " PHP_RINIT(%s),\n", module);
+ Printf(s_init, " PHP_RSHUTDOWN(%s),\n", module);
+ Printf(s_init, " PHP_MINFO(%s),\n", module);
+ Printf(s_init, "#if ZEND_MODULE_API_NO > 20010900\n");
+ Printf(s_init, " NO_VERSION_YET,\n");
+ Printf(s_init, "#endif\n");
+ Printf(s_init, " STANDARD_MODULE_PROPERTIES\n");
+ Printf(s_init, "};\n");
+ Printf(s_init, "zend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n", module);
+
+ Printf(s_init, "#ifdef __cplusplus\n");
+ Printf(s_init, "extern \"C\" {\n");
+ Printf(s_init, "#endif\n");
+ // We want to write "SWIGEXPORT ZEND_GET_MODULE(%s)" but ZEND_GET_MODULE
+ // in PHP5 has "extern "C" { ... }" around it so we can't do that.
+ Printf(s_init, "SWIGEXPORT zend_module_entry *get_module(void) { return &%s_module_entry; }\n", module);
+ Printf(s_init, "#ifdef __cplusplus\n");
+ Printf(s_init, "}\n");
+ Printf(s_init, "#endif\n\n");
+
+ /* 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, "#define SWIG_php_minit PHP_MINIT_FUNCTION(%s)\n", module);
+
+ /* 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 */
+ Printf(s_cinit, "/* end cinit subsection */\n");
+ Printf(s_init, "%s\n", s_cinit);
+ Clear(s_cinit);
+ Delete(s_cinit);
+
+ Printf(s_init, " return SUCCESS;\n");
+ Printf(s_init, "}\n\n");
+
+ // Now do REQUEST init which holds any user specified %rinit, and also vinit
+ Printf(s_init, "PHP_RINIT_FUNCTION(%s)\n{\n", module);
+ Printf(s_init, "%s\n", r_init);
+
+ /* finish our init section which will have been used by class wrappers */
+ Printf(s_vinit, "/* end vinit subsection */\n");
+ Printf(s_init, "%s\n", s_vinit);
+ Clear(s_vinit);
+ Delete(s_vinit);
+
+ Printf(s_init, " return SUCCESS;\n");
+ Printf(s_init, "}\n\n");
+
+ Printv(s_init, "PHP_MSHUTDOWN_FUNCTION(", module, ")\n"
+ "{\n",
+ s_shutdown,
+ "#ifdef ZTS\n"
+ " ts_free_id(", module, "_globals_id);\n"
+ "#endif\n"
+ " return SUCCESS;\n"
+ "}\n\n", NIL);
+
+ Printf(s_init, "PHP_RSHUTDOWN_FUNCTION(%s)\n{\n", module);
+ Printf(s_init, "%s\n", r_shutdown);
+ Printf(s_init, " return SUCCESS;\n");
+ Printf(s_init, "}\n\n");
+
+ Printf(s_init, "PHP_MINFO_FUNCTION(%s)\n{\n", module);
+ Printf(s_init, "%s", pragma_phpinfo);
+ Printf(s_init, "}\n");
+ Printf(s_init, "/* end init section */\n");
+
+ Printf(f_h, "#endif /* PHP_%s_H */\n", cap_module);
+
+ Close(f_h);
+
+ String *type_table = NewStringEmpty();
+ 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.
+ */
+
+ if (directorsEnabled()) {
+ Dump(f_directors_h, f_runtime_h);
+ Printf(f_runtime_h, "\n");
+ Printf(f_runtime_h, "#endif\n");
+ Close(f_runtime_h);
+ }
+
+ Printf(s_header, "/* end header section */\n");
+ Printf(s_wrappers, "/* end wrapper section */\n");
+ Printf(s_vdecl, "/* end vdecl subsection */\n");
+
+ Dump(f_runtime, f_begin);
+ Printv(f_begin, s_header, NIL);
+ if (directorsEnabled()) {
+ Dump(f_directors, f_begin);
+ }
+ Printv(f_begin, s_vdecl, s_wrappers, NIL);
+ Printv(f_begin, all_cs_entry, "\n\n", s_entry,
+ " SWIG_ZEND_NAMED_FE(swig_", module, "_alter_newobject,_wrap_swig_", module, "_alter_newobject,NULL)\n"
+ " SWIG_ZEND_NAMED_FE(swig_", module, "_get_newobject,_wrap_swig_", module, "_get_newobject,NULL)\n"
+ "{NULL, NULL, NULL}\n};\n\n", NIL);
+ Printv(f_begin, s_init, NIL);
+ Delete(s_header);
+ Delete(s_wrappers);
+ Delete(s_init);
+ Delete(s_vdecl);
+ Delete(all_cs_entry);
+ Delete(s_entry);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+
+ Printf(f_phpcode, "%s\n%s\n", pragma_incl, pragma_code);
+ if (s_fakeoowrappers) {
+ Printf(f_phpcode, "abstract class %s {", Len(prefix) ? prefix : module);
+ Printf(f_phpcode, "%s", s_fakeoowrappers);
+ Printf(f_phpcode, "}\n\n");
+ Delete(s_fakeoowrappers);
+ s_fakeoowrappers = NULL;
+ }
+ Printf(f_phpcode, "%s\n?>\n", s_phpclasses);
+ Close(f_phpcode);
+
+ return SWIG_OK;
+ }
+
+ /* Just need to append function names to function table to register with PHP. */
+ void create_command(String *cname, String *iname) {
+ // This is for the single main zend_function_entry record
+ Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
+ String * s = cs_entry;
+ if (!s) s = s_entry;
+ Printf(s, " SWIG_ZEND_NAMED_FE(%(lower)s,%s,NULL)\n", cname, iname);
+ }
+
+ /* ------------------------------------------------------------
+ * dispatchFunction()
+ * ------------------------------------------------------------ */
+ void dispatchFunction(Node *n) {
+ /* Last node in overloaded chain */
+
+ int maxargs;
+ String *tmp = NewStringEmpty();
+ if (Swig_directorclass(n) && wrapperType == directorconstructor) {
+ /* We have an extra 'this' parameter. */
+ SetFlag(n, "wrap:this");
+ }
+ String *dispatch = Swig_overload_dispatch(n, "return %s(INTERNAL_FUNCTION_PARAM_PASSTHRU);", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *f = NewWrapper();
+ String *symname = Getattr(n, "sym:name");
+ String *wname = Swig_name_wrapper(symname);
+
+ create_command(symname, wname);
+ Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
+
+ Wrapper_add_local(f, "argc", "int argc");
+
+ Printf(tmp, "zval **argv[%d]", maxargs);
+ Wrapper_add_local(f, "argv", tmp);
+
+ Printf(f->code, "argc = ZEND_NUM_ARGS();\n");
+
+ Printf(f->code, "zend_get_parameters_array_ex(argc,argv);\n");
+
+ Replaceall(dispatch, "$args", "self,args");
+
+ Printv(f->code, dispatch, "\n", NIL);
+
+ Printf(f->code, "SWIG_ErrorCode() = E_ERROR;\n");
+ Printf(f->code, "SWIG_ErrorMsg() = \"No matching function for overloaded '%s'\";\n", symname);
+ Printv(f->code, "zend_error(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());\n", NIL);
+
+ Printv(f->code, "}\n", NIL);
+ Wrapper_print(f, s_wrappers);
+
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(tmp);
+ Delete(wname);
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * ------------------------------------------------------------ */
+
+ /* Helper method for PHP::functionWrapper */
+ bool is_class(SwigType *t) {
+ Node *n = classLookup(t);
+ if (n) {
+ String *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
+ if (r)
+ return true;
+ }
+ return false;
+ }
+
+ virtual int functionWrapper(Node *n) {
+ String *name = GetChar(n, "name");
+ String *iname = GetChar(n, "sym:name");
+ SwigType *d = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *nodeType = Getattr(n, "nodeType");
+ int newobject = GetFlag(n, "feature:new");
+ int constructor = (Cmp(nodeType, "constructor") == 0);
+
+ Parm *p;
+ int i;
+ int numopt;
+ String *tm;
+ Wrapper *f;
+
+ String *wname;
+ int overloaded = 0;
+ String *overname = 0;
+
+ if (Cmp(nodeType, "destructor") == 0) {
+ // We just generate the Zend List Destructor and let Zend manage the
+ // reference counting. There's no explicit destructor, but the user can
+ // just do `$obj = null;' to remove a reference to an object.
+ return CreateZendListDestructor(n);
+ }
+ // Test for overloading;
+ if (Getattr(n, "sym:overloaded")) {
+ overloaded = 1;
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ }
+
+ wname = Swig_name_wrapper(iname);
+ if (overname) {
+ Printf(wname, "%s", overname);
+ }
+
+ f = NewWrapper();
+ numopt = 0;
+
+ String *outarg = NewStringEmpty();
+ String *cleanup = NewStringEmpty();
+
+ // Not issued for overloaded functions.
+ if (!overloaded) {
+ create_command(iname, wname);
+ }
+ Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
+
+ emit_parameter_variables(l, f);
+ /* Attach standard typemaps */
+
+ emit_attach_parmmaps(l, f);
+
+ // wrap:parms is used by overload resolution.
+ Setattr(n, "wrap:parms", l);
+
+ int num_arguments = emit_num_arguments(l);
+ int num_required = emit_num_required(l);
+ numopt = num_arguments - num_required;
+
+ if (wrapperType == directorconstructor)
+ num_arguments++;
+
+ if (num_arguments > 0) {
+ String *args = NewStringEmpty();
+ if (wrapperType == directorconstructor)
+ Wrapper_add_local(f, "arg0", "zval *arg0");
+ Printf(args, "zval **args[%d]", num_arguments);
+ Wrapper_add_local(f, "args", args);
+ Delete(args);
+ args = NULL;
+ }
+ if (is_member_director(n)) {
+ Wrapper_add_local(f, "director", "Swig::Director *director = 0");
+ Printf(f->code, "director = dynamic_cast<Swig::Director*>(arg1);\n");
+ Wrapper_add_local(f, "upcall", "bool upcall = false");
+ Printf(f->code, "upcall = !director->is_overriden_method((char *)\"%s\", (char *)\"%s\");\n",
+ Swig_class_name(Swig_methodclass(n)), name);
+ }
+
+ // 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
+
+ Printf(f->code, "SWIG_ResetError();\n");
+
+ 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");
+ Printf(f->code, "if(arg_count<%d || arg_count>%d ||\n", num_required, num_arguments);
+ Printf(f->code, " zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)\n");
+ Printf(f->code, "\tWRONG_PARAM_COUNT;\n\n");
+ } else {
+ if (num_arguments == 0) {
+ Printf(f->code, "if(ZEND_NUM_ARGS() != 0) {\n");
+ } else {
+ Printf(f->code, "if(ZEND_NUM_ARGS() != %d || zend_get_parameters_array_ex(%d, args) != SUCCESS) {\n", num_arguments, num_arguments);
+ }
+ Printf(f->code, "WRONG_PARAM_COUNT;\n}\n\n");
+ }
+ if (wrapperType == directorconstructor)
+ Printf(f->code, "arg0 = *args[0];\n \n");
+
+ /* Now convert from PHP to C variables */
+ // At this point, argcount if used is the number of deliberately 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 not the first argument.
+ // This may mean looking at Language::memberfunctionHandler
+
+ int limit = num_arguments;
+ if (wrapperType == directorconstructor)
+ limit--;
+ for (i = 0, p = l; i < limit; i++) {
+ String *source;
+
+ /* 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 (wrapperType == directorconstructor) {
+ source = NewStringf("args[%d]", i+1);
+ } else {
+ source = NewStringf("args[%d]", i);
+ }
+
+ String *ln = Getattr(p, "lname");
+
+ /* Check if optional */
+ if (i >= num_required) {
+ Printf(f->code, "\tif(arg_count > %d) {\n", i);
+ }
+
+ 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);
+ if (i == 0 && Getattr(p, "self")) {
+ Printf(f->code, "\tif(!arg1) SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");\n");
+ }
+ p = Getattr(p, "tmap:in:next");
+ if (i >= num_required) {
+ Printf(f->code, "}\n");
+ }
+ 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));
+ }
+ if (i >= num_required) {
+ Printf(f->code, "\t}\n");
+ }
+ Delete(source);
+ }
+
+ Swig_director_emit_dynamic_cast(n, f);
+
+ /* 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 */
+ 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");
+ 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);
+ }
+ }
+
+ Setattr(n, "wrap:name", wname);
+
+ /* emit function call */
+ String *actioncode = emit_action(n);
+
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ 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);
+ } 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);
+ }
+ emit_return_variable(n, d, f);
+
+ if (outarg) {
+ Printv(f->code, outarg, NIL);
+ }
+
+ if (cleanup) {
+ Printv(f->code, cleanup, NIL);
+ }
+
+ /* Look to see if there is any newfree cleanup code */
+ if (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
+ Printf(f->code, "%s\n", tm);
+ Delete(tm);
+ }
+ }
+
+ /* See if there is any return cleanup code */
+ if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
+ Printf(f->code, "%s\n", tm);
+ Delete(tm);
+ }
+
+ Printf(f->code, "return;\n");
+
+ /* Error handling code */
+ Printf(f->code, "fail:\n");
+ Printv(f->code, cleanup, NIL);
+ Printv(f->code, "zend_error_noreturn(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());", NIL);
+
+ Printf(f->code, "}\n");
+
+ Replaceall(f->code, "$cleanup", cleanup);
+ Replaceall(f->code, "$symname", iname);
+
+ Wrapper_print(f, s_wrappers);
+ DelWrapper(f);
+ f = NULL;
+
+ if (overloaded && !Getattr(n, "sym:nextSibling")) {
+ dispatchFunction(n);
+ }
+
+ Delete(wname);
+ wname = NULL;
+
+ if (!shadow) {
+ return SWIG_OK;
+ }
+
+ // Handle getters and setters.
+ if (wrapperType == membervar) {
+ const char *p = Char(iname);
+ if (strlen(p) > 4) {
+ p += strlen(p) - 4;
+ String *varname = Getattr(n, "membervariableHandler:sym:name");
+ if (strcmp(p, "_get") == 0) {
+ Setattr(shadow_get_vars, varname, iname);
+ } else if (strcmp(p, "_set") == 0) {
+ Setattr(shadow_set_vars, varname, iname);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ // Only look at non-overloaded methods and the last entry in each overload
+ // chain (we check the last so that wrap:parms and wrap:name have been set
+ // for them all).
+ if (overloaded && Getattr(n, "sym:nextSibling") != 0)
+ return SWIG_OK;
+
+ if (!s_oowrappers)
+ s_oowrappers = NewStringEmpty();
+
+ if (newobject || wrapperType == memberfn || wrapperType == staticmemberfn || wrapperType == standard || wrapperType == staticmembervar) {
+ bool handle_as_overload = false;
+ String **arg_names;
+ String **arg_values;
+ // Method or static method or plain function.
+ const char *methodname = 0;
+ String *output = s_oowrappers;
+ if (constructor) {
+ class_has_ctor = true;
+ // Skip the Foo:: prefix.
+ char *ptr = strrchr(GetChar(Swig_methodclass(n), "sym:name"), ':');
+ if (ptr) {
+ ptr++;
+ } else {
+ ptr = GetChar(Swig_methodclass(n), "sym:name");
+ }
+ if (strcmp(ptr, GetChar(n, "constructorHandler:sym:name")) == 0) {
+ methodname = "__construct";
+ } else {
+ // The class has multiple constructors and this one is
+ // renamed, so this will be a static factory function
+ methodname = GetChar(n, "constructorHandler:sym:name");
+ }
+ } else if (wrapperType == memberfn) {
+ methodname = Char(Getattr(n, "memberfunctionHandler:sym:name"));
+ } else if (wrapperType == staticmemberfn) {
+ methodname = Char(Getattr(n, "staticmemberfunctionHandler:sym:name"));
+ } else if (wrapperType == staticmembervar) {
+ // Static member variable, wrapped as a function due to PHP limitations.
+ methodname = Char(Getattr(n, "staticmembervariableHandler:sym:name"));
+ } else { // wrapperType == standard
+ methodname = Char(iname);
+ if (!s_fakeoowrappers)
+ s_fakeoowrappers = NewStringEmpty();
+ output = s_fakeoowrappers;
+ }
+
+ bool really_overloaded = overloaded ? true : false;
+ int min_num_of_arguments = emit_num_required(l);
+ int max_num_of_arguments = emit_num_arguments(l);
+
+ // For a function with default arguments, we end up with the fullest
+ // parmlist in full_parmlist.
+ ParmList *full_parmlist = l;
+ Hash *ret_types = NewHash();
+ Setattr(ret_types, d, d);
+
+ if (overloaded) {
+ // Look at all the overloaded versions of this method in turn to
+ // decide if it's really an overloaded method, or just one where some
+ // parameters have default values.
+ Node *o = Getattr(n, "sym:overloaded");
+ while (o) {
+ if (o == n) {
+ o = Getattr(o, "sym:nextSibling");
+ continue;
+ }
+
+ SwigType *d2 = Getattr(o, "type");
+ if (!d2) {
+ assert(constructor);
+ } else if (!Getattr(ret_types, d2)) {
+ Setattr(ret_types, d2, d2);
+ }
+
+ ParmList *l2 = Getattr(o, "wrap:parms");
+ int num_arguments = emit_num_arguments(l2);
+ int num_required = emit_num_required(l2);
+ if (num_required < min_num_of_arguments)
+ min_num_of_arguments = num_required;
+
+ if (num_arguments > max_num_of_arguments) {
+ max_num_of_arguments = num_arguments;
+ full_parmlist = l2;
+ }
+ o = Getattr(o, "sym:nextSibling");
+ }
+
+ o = Getattr(n, "sym:overloaded");
+ while (o) {
+ if (o == n) {
+ o = Getattr(o, "sym:nextSibling");
+ continue;
+ }
+
+ ParmList *l2 = Getattr(o, "wrap:parms");
+ Parm *p = l, *p2 = l2;
+ if (wrapperType == memberfn) {
+ p = nextSibling(p);
+ p2 = nextSibling(p2);
+ }
+ while (p && p2) {
+ if (Cmp(Getattr(p, "type"), Getattr(p2, "type")) != 0)
+ break;
+ if (Cmp(Getattr(p, "name"), Getattr(p2, "name")) != 0)
+ break;
+ String *value = Getattr(p, "value");
+ String *value2 = Getattr(p2, "value");
+ if (value && !value2)
+ break;
+ if (!value && value2)
+ break;
+ if (value) {
+ if (Cmp(value, value2) != 0)
+ break;
+ }
+ p = nextSibling(p);
+ p2 = nextSibling(p2);
+ }
+ if (p && p2)
+ break;
+ // One parameter list is a prefix of the other, so check that all
+ // remaining parameters of the longer list are optional.
+ if (p2)
+ p = p2;
+ while (p && Getattr(p, "value"))
+ p = nextSibling(p);
+ if (p)
+ break;
+ o = Getattr(o, "sym:nextSibling");
+ }
+ if (!o) {
+ // This "overloaded method" is really just one with default args.
+ really_overloaded = false;
+ if (l != full_parmlist) {
+ l = full_parmlist;
+ if (wrapperType == memberfn)
+ l = nextSibling(l);
+ }
+ }
+ }
+
+ if (wrapperType == memberfn) {
+ // Allow for the "this" pointer.
+ --min_num_of_arguments;
+ --max_num_of_arguments;
+ }
+
+ arg_names = (String **) malloc(max_num_of_arguments * sizeof(String *));
+ if (!arg_names) {
+ /* FIXME: How should this be handled? The rest of SWIG just seems
+ * to not bother checking for malloc failing! */
+ fprintf(stderr, "Malloc failed!\n");
+ exit(1);
+ }
+ for (i = 0; i < max_num_of_arguments; ++i) {
+ arg_names[i] = NULL;
+ }
+
+ arg_values = (String **) malloc(max_num_of_arguments * sizeof(String *));
+ if (!arg_values) {
+ /* FIXME: How should this be handled? The rest of SWIG just seems
+ * to not bother checking for malloc failing! */
+ fprintf(stderr, "Malloc failed!\n");
+ exit(1);
+ }
+ for (i = 0; i < max_num_of_arguments; ++i) {
+ arg_values[i] = NULL;
+ }
+
+ Node *o;
+ if (overloaded) {
+ o = Getattr(n, "sym:overloaded");
+ } else {
+ o = n;
+ }
+ while (o) {
+ int argno = 0;
+ Parm *p = Getattr(o, "wrap:parms");
+ if (wrapperType == memberfn)
+ p = nextSibling(p);
+ while (p) {
+ if (GetInt(p, "tmap:in:numinputs") == 0) {
+ p = nextSibling(p);
+ continue;
+ }
+ assert(0 <= argno && argno < max_num_of_arguments);
+ String *&pname = arg_names[argno];
+ const char *pname_cstr = GetChar(p, "name");
+ // Just get rid of the C++ namespace part for now.
+ const char *ptr = NULL;
+ if (pname_cstr && (ptr = strrchr(pname_cstr, ':'))) {
+ pname_cstr = ptr + 1;
+ }
+ if (!pname_cstr) {
+ // Unnamed parameter, e.g. int foo(int);
+ } else if (pname == NULL) {
+ pname = NewString(pname_cstr);
+ } else {
+ size_t len = strlen(pname_cstr);
+ size_t spc = 0;
+ size_t len_pname = strlen(Char(pname));
+ while (spc + len <= len_pname) {
+ if (strncmp(pname_cstr, Char(pname) + spc, len) == 0) {
+ char ch = ((char *) Char(pname))[spc + len];
+ if (ch == '\0' || ch == ' ') {
+ // Already have this pname_cstr.
+ pname_cstr = NULL;
+ break;
+ }
+ }
+ char *p = strchr(Char(pname) + spc, ' ');
+ if (!p)
+ break;
+ spc = (p + 4) - Char(pname);
+ }
+ if (pname_cstr) {
+ Printf(pname, " or_%s", pname_cstr);
+ }
+ }
+ String *value = NewString(Getattr(p, "value"));
+ if (Len(value)) {
+ /* Check that value is a valid constant in PHP (and adjust it if
+ * necessary, or replace it with "?" if it's just not valid). */
+ SwigType *type = Getattr(p, "type");
+ switch (SwigType_type(type)) {
+ case T_BOOL: {
+ if (Strcmp(value, "true") == 0 || Strcmp(value, "false") == 0)
+ break;
+ char *p;
+ errno = 0;
+ int n = strtol(Char(value), &p, 0);
+ Clear(value);
+ if (errno || *p) {
+ Append(value, "?");
+ } else if (n) {
+ Append(value, "true");
+ } else {
+ Append(value, "false");
+ }
+ break;
+ }
+ case T_CHAR:
+ case T_SCHAR:
+ case T_SHORT:
+ case T_INT:
+ case T_LONG: {
+ char *p;
+ errno = 0;
+ unsigned int n = strtol(Char(value), &p, 0);
+ (void) n;
+ if (errno || *p) {
+ Clear(value);
+ Append(value, "?");
+ }
+ break;
+ }
+ case T_UCHAR:
+ case T_USHORT:
+ case T_UINT:
+ case T_ULONG: {
+ char *p;
+ errno = 0;
+ unsigned int n = strtoul(Char(value), &p, 0);
+ (void) n;
+ if (errno || *p) {
+ Clear(value);
+ Append(value, "?");
+ }
+ break;
+ }
+ case T_FLOAT:
+ case T_DOUBLE:{
+ char *p;
+ errno = 0;
+ /* FIXME: strtod is locale dependent... */
+ double val = strtod(Char(value), &p);
+ if (errno || *p) {
+ Clear(value);
+ Append(value, "?");
+ } else if (strchr(Char(value), '.') == NULL) {
+ // Ensure value is a double constant, not an integer one.
+ Append(value, ".0");
+ double val2 = strtod(Char(value), &p);
+ if (errno || *p || val != val2) {
+ Clear(value);
+ Append(value, "?");
+ }
+ }
+ break;
+ }
+ case T_REFERENCE:
+ case T_USER:
+ case T_ARRAY:
+ Clear(value);
+ Append(value, "?");
+ break;
+ case T_STRING:
+ if (Len(value) < 2) {
+ // How can a string (including "" be less than 2 characters?)
+ Clear(value);
+ Append(value, "?");
+ } else {
+ const char *v = Char(value);
+ if (v[0] != '"' || v[Len(value) - 1] != '"') {
+ Clear(value);
+ Append(value, "?");
+ }
+ // Strings containing "$" require special handling, but we do
+ // that later.
+ }
+ break;
+ case T_VOID:
+ assert(false);
+ break;
+ case T_POINTER: {
+ const char *v = Char(value);
+ if (v[0] == '(') {
+ // Handle "(void*)0", "(TYPE*)0", "(char*)NULL", etc.
+ v += strcspn(v + 1, "*()") + 1;
+ if (*v == '*') {
+ do {
+ v++;
+ v += strspn(v, " \t");
+ } while (*v == '*');
+ if (*v++ == ')') {
+ v += strspn(v, " \t");
+ String * old = value;
+ value = NewString(v);
+ Delete(old);
+ }
+ }
+ }
+ if (Strcmp(value, "NULL") == 0 ||
+ Strcmp(value, "0") == 0 ||
+ Strcmp(value, "0L") == 0) {
+ Clear(value);
+ Append(value, "null");
+ } else {
+ Clear(value);
+ Append(value, "?");
+ }
+ break;
+ }
+ }
+
+ if (!arg_values[argno]) {
+ arg_values[argno] = value;
+ value = NULL;
+ } else if (Cmp(arg_values[argno], value) != 0) {
+ // If a parameter has two different default values in
+ // different overloaded forms of the function, we can't
+ // set its default in PHP. Flag this by setting its
+ // default to `?'.
+ Delete(arg_values[argno]);
+ arg_values[argno] = NewString("?");
+ }
+ } else if (arg_values[argno]) {
+ // This argument already has a default value in another overloaded
+ // form, but doesn't in this form. So don't try to do anything
+ // clever, just let the C wrappers resolve the overload and set the
+ // default values.
+ //
+ // This handling is safe, but I'm wondering if it may be overly
+ // conservative (FIXME) in some cases. It seems it's only bad when
+ // there's an overloaded form with the appropriate number of
+ // parameters which doesn't want the default value, but I need to
+ // think about this more.
+ Delete(arg_values[argno]);
+ arg_values[argno] = NewString("?");
+ }
+ Delete(value);
+ p = nextSibling(p);
+ ++argno;
+ }
+ if (!really_overloaded)
+ break;
+ o = Getattr(o, "sym:nextSibling");
+ }
+
+ /* Clean up any parameters which haven't yet got names, or whose
+ * names clash. */
+ Hash *seen = NewHash();
+ /* We need $this to refer to the current class, so can't allow it
+ * to be used as a parameter. */
+ Setattr(seen, "this", seen);
+ /* We use $r to store the return value, so disallow that as a parameter
+ * name in case the user uses the "call-time pass-by-reference" feature
+ * (it's deprecated and off by default in PHP5, but we want to be
+ * maximally portable). Similarly we use $c for the classname or new
+ * stdClass object.
+ */
+ Setattr(seen, "r", seen);
+ Setattr(seen, "c", seen);
+
+ for (int argno = 0; argno < max_num_of_arguments; ++argno) {
+ String *&pname = arg_names[argno];
+ if (pname) {
+ Replaceall(pname, " ", "_");
+ } else {
+ /* We get here if the SWIG .i file has "int foo(int);" */
+ pname = NewStringEmpty();
+ Printf(pname, "arg%d", argno + 1);
+ }
+ // Check if we've already used this parameter name.
+ while (Getattr(seen, pname)) {
+ // Append "_" to clashing names until they stop clashing...
+ Printf(pname, "_");
+ }
+ Setattr(seen, Char(pname), seen);
+
+ if (arg_values[argno] && Cmp(arg_values[argno], "?") == 0) {
+ handle_as_overload = true;
+ }
+ }
+ Delete(seen);
+ seen = NULL;
+
+ String *invoke = NewStringEmpty();
+ String *prepare = NewStringEmpty();
+ String *args = NewStringEmpty();
+
+ if (!handle_as_overload && !(really_overloaded && max_num_of_arguments > min_num_of_arguments)) {
+ Printf(invoke, "%s(", iname);
+ if (wrapperType == memberfn) {
+ Printf(invoke, "$this->%s", SWIG_PTR);
+ }
+ for (int i = 0; i < max_num_of_arguments; ++i) {
+ if (i)
+ Printf(args, ",");
+ if (i || wrapperType == memberfn)
+ Printf(invoke, ",");
+ String *value = arg_values[i];
+ if (value) {
+ const char *v = Char(value);
+ if (v[0] == '"') {
+ /* In a PHP double quoted string, $ needs to be escaped as \$. */
+ Replaceall(value, "$", "\\$");
+ }
+ Printf(args, "$%s=%s", arg_names[i], value);
+ } else {
+ Printf(args, "$%s", arg_names[i]);
+ }
+ Printf(invoke, "$%s", arg_names[i]);
+ }
+ Printf(invoke, ")");
+ } else {
+ int i;
+ for (i = 0; i < min_num_of_arguments; ++i) {
+ if (i)
+ Printf(args, ",");
+ Printf(args, "$%s", arg_names[i]);
+ }
+ String *invoke_args = NewStringEmpty();
+ if (wrapperType == memberfn) {
+ Printf(invoke_args, "$this->%s", SWIG_PTR);
+ if (min_num_of_arguments > 0)
+ Printf(invoke_args, ",");
+ }
+ Printf(invoke_args, "%s", args);
+ bool had_a_case = false;
+ int last_handled_i = i - 1;
+ for (; i < max_num_of_arguments; ++i) {
+ if (i)
+ Printf(args, ",");
+ const char *value = Char(arg_values[i]);
+ // FIXME: (really_overloaded && handle_as_overload) is perhaps a
+ // little conservative, but it doesn't hit any cases that it
+ // shouldn't for Xapian at least (and we need it to handle
+ // "Enquire::get_mset()" correctly).
+ bool non_php_default = ((really_overloaded && handle_as_overload) ||
+ !value || strcmp(value, "?") == 0);
+ if (non_php_default)
+ value = "null";
+ Printf(args, "$%s=%s", arg_names[i], value);
+ if (non_php_default) {
+ if (!had_a_case) {
+ Printf(prepare, "\t\tswitch (func_num_args()) {\n");
+ had_a_case = true;
+ }
+ Printf(prepare, "\t\t");
+ while (last_handled_i < i) {
+ Printf(prepare, "case %d: ", ++last_handled_i);
+ }
+ if (Cmp(d, "void") != 0) {
+ if ((!directorsEnabled() || !Swig_directorclass(n)) && !newobject) {
+ Append(prepare, "$r=");
+ } else {
+ Printf(prepare, "$this->%s=", SWIG_PTR);
+ }
+ }
+ if (!directorsEnabled() || !Swig_directorclass(n) || !newobject) {
+ Printf(prepare, "%s(%s); break;\n", iname, invoke_args);
+ } else if (!i) {
+ Printf(prepare, "%s($_this%s); break;\n", iname, invoke_args);
+ } else {
+ Printf(prepare, "%s($_this, %s); break;\n", iname, invoke_args);
+ }
+ }
+ if (i || wrapperType == memberfn)
+ Printf(invoke_args, ",");
+ Printf(invoke_args, "$%s", arg_names[i]);
+ }
+ Printf(prepare, "\t\t");
+ if (had_a_case)
+ Printf(prepare, "default: ");
+ if (Cmp(d, "void") != 0) {
+ if ((!directorsEnabled() || !Swig_directorclass(n)) && !newobject) {
+ Append(prepare, "$r=");
+ } else {
+ Printf(prepare, "$this->%s=", SWIG_PTR);
+ }
+ }
+
+ if (!directorsEnabled() || !Swig_directorclass(n) || !newobject) {
+ Printf(prepare, "%s(%s);\n", iname, invoke_args);
+ } else {
+ Printf(prepare, "%s($_this, %s);\n", iname, invoke_args);
+ }
+ if (had_a_case)
+ Printf(prepare, "\t\t}\n");
+ Delete(invoke_args);
+ Printf(invoke, "$r");
+ }
+
+ Printf(output, "\n");
+ // If it's a member function or a class constructor...
+ if (wrapperType == memberfn || (constructor && current_class)) {
+ String *acc = NewString(Getattr(n, "access"));
+ // If a base has the same method with public access, then PHP
+ // requires to have it here as public as well
+ Node *bases = Getattr(Swig_methodclass(n), "bases");
+ if (bases && Strcmp(acc, "public") != 0) {
+ String *warnmsg = 0;
+ int haspublicbase = 0;
+ Iterator i = First(bases);
+ while (i.item) {
+ Node *j = firstChild(i.item);
+ while (j) {
+ if (Strcmp(Getattr(j, "name"), Getattr(n, "name")) != 0) {
+ j = nextSibling(j);
+ continue;
+ }
+ if (Strcmp(nodeType(j), "cdecl") == 0) {
+ if (!Getattr(j, "access") || checkAttribute(j, "access", "public")) {
+ haspublicbase = 1;
+ }
+ } else if (Strcmp(nodeType(j), "using") == 0 && firstChild(j) && Strcmp(nodeType(firstChild(j)), "cdecl") == 0) {
+ if (!Getattr(firstChild(j), "access") || checkAttribute(firstChild(j), "access", "public")) {
+ haspublicbase = 1;
+ }
+ }
+ if (haspublicbase) {
+ warnmsg = NewStringf("Modifying the access of '%s::%s' to public, as the base '%s' has it as public as well.\n", Getattr(current_class, "classtype"), Getattr(n, "name"), Getattr(i.item, "classtype"));
+ break;
+ }
+ j = nextSibling(j);
+ }
+ i = Next(i);
+ if (haspublicbase) {
+ break;
+ }
+ }
+ if (Getattr(n, "access") && haspublicbase) {
+ Delete(acc);
+ acc = NewString("public");
+ Swig_warning(WARN_PHP_PUBLIC_BASE, input_file, line_number, Char(warnmsg));
+ Delete(warnmsg);
+ }
+ }
+ if (Cmp(acc, "") != 0) {
+ Append(acc, " ");
+ }
+ if (constructor) {
+ const char * arg0;
+ if (max_num_of_arguments > 0) {
+ arg0 = Char(arg_names[0]);
+ } else {
+ arg0 = "res";
+ Delete(args);
+ args = NewString("$res=null");
+ }
+ SwigType *t = Getattr(current_class, "classtype");
+ String *mangled_type = SwigType_manglestr(SwigType_ltype(t));
+ Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args);
+ Printf(output, "\t\tif (is_resource($%s) && get_resource_type($%s) === '_p%s') {\n", arg0, arg0, mangled_type);
+ Printf(output, "\t\t\t$this->%s=$%s;\n", SWIG_PTR, arg0);
+ Printf(output, "\t\t\treturn;\n");
+ Printf(output, "\t\t}\n");
+ } else {
+ Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args);
+ }
+ Delete(acc);
+ } else if (wrapperType == staticmembervar) {
+ // We're called twice for a writable static member variable - first
+ // with "foo_set" and then with "foo_get" - so generate half the
+ // wrapper function each time.
+ //
+ // For a const static member, we only get called once.
+ static bool started = false;
+ if (!started) {
+ Printf(output, "\tstatic function %s() {\n", methodname);
+ if (max_num_of_arguments) {
+ // Setter.
+ Printf(output, "\t\tif (func_num_args()) {\n");
+ Printf(output, "\t\t\t%s(func_get_arg(0));\n", iname);
+ Printf(output, "\t\t\treturn;\n");
+ Printf(output, "\t\t}\n");
+ started = true;
+ goto done;
+ }
+ }
+ started = false;
+ } else {
+ Printf(output, "\tstatic function %s(%s) {\n", methodname, args);
+ }
+
+ if (!newobject)
+ Printf(output, "%s", prepare);
+ if (constructor) {
+ if (!directorsEnabled() || !Swig_directorclass(n)) {
+ if (strcmp(methodname, "__construct") == 0) {
+ Printf(output, "\t\t$this->%s=%s;\n", SWIG_PTR, invoke);
+ } else {
+ String *classname = Swig_class_name(current_class);
+ Printf(output, "\t\treturn new %s(%s);\n", classname, invoke);
+ }
+ } else {
+ Node *parent = Swig_methodclass(n);
+ String *classname = Swig_class_name(parent);
+ Printf(output, "\t\tif (get_class($this) === '%s%s') {\n", prefix, classname);
+ Printf(output, "\t\t\t$_this = null;\n");
+ Printf(output, "\t\t} else {\n");
+ Printf(output, "\t\t\t$_this = $this;\n");
+ Printf(output, "\t\t}\n");
+ if (!Len(prepare)) {
+ if (num_arguments > 1) {
+ Printf(output, "\t\t$this->%s=%s($_this, %s);\n", SWIG_PTR, iname, args);
+ } else {
+ Printf(output, "\t\t$this->%s=%s($_this);\n", SWIG_PTR, iname);
+ }
+ }
+ }
+ Printf(output, "%s", prepare);
+ } else if (Cmp(d, "void") == 0) {
+ if (Cmp(invoke, "$r") != 0)
+ Printf(output, "\t\t%s;\n", invoke);
+ } else if (is_class(d)) {
+ if (Cmp(invoke, "$r") != 0)
+ Printf(output, "\t\t$r=%s;\n", invoke);
+ if (Len(ret_types) == 1) {
+ /* If it has an abstract base, then we can't create a new
+ * base object. */
+ int hasabstractbase = 0;
+ Node *bases = Getattr(Swig_methodclass(n), "bases");
+ if (bases) {
+ Iterator i = First(bases);
+ while(i.item) {
+ if (Getattr(i.item, "abstract")) {
+ hasabstractbase = 1;
+ break;
+ }
+ i = Next(i);
+ }
+ }
+ if (newobject || !hasabstractbase) {
+ /*
+ * _p_Foo -> Foo, _p_ns__Bar -> Bar
+ * TODO: do this in a more elegant way
+ */
+ Printf(output, "\t\tif (is_resource($r)) {\n");
+ if (Getattr(classLookup(Getattr(n, "type")), "module")) {
+ if (Len(prefix) == 0) {
+ Printf(output, "\t\t\t$c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n");
+ } else {
+ Printf(output, "\t\t\t$c='%s'.substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n", prefix);
+ }
+ Printf(output, "\t\t\tif (!class_exists($c)) {\n");
+ Printf(output, "\t\t\t\treturn new %s($r);\n", Getattr(classLookup(d), "sym:name"));
+ Printf(output, "\t\t\t}\n");
+ Printf(output, "\t\t\treturn new $c($r);\n");
+ } else {
+ Printf(output, "\t\t\t$c = new stdClass();\n");
+ Printf(output, "\t\t\t$c->_cPtr = $r;\n");
+ Printf(output, "\t\t\treturn $c;\n");
+ }
+ Printf(output, "\t\t}\n\t\treturn $r;\n");
+ } else {
+ Printf(output, "\t\t$this->%s = $r;\n", SWIG_PTR);
+ Printf(output, "\t\treturn $this;\n");
+ }
+ } else {
+ Printf(output, "\t\tif (!is_resource($r)) return $r;\n");
+ Printf(output, "\t\tswitch (get_resource_type($r)) {\n");
+ Iterator i = First(ret_types);
+ while (i.item) {
+ SwigType *ret_type = i.item;
+ i = Next(i);
+ Printf(output, "\t\t");
+ String *mangled = NewString("_p");
+ Printf(mangled, "%s", SwigType_manglestr(ret_type));
+ Node *class_node = Getattr(zend_types, mangled);
+ if (!class_node) {
+ /* This is needed when we're returning a pointer to a type
+ * rather than returning the type by value or reference. */
+ class_node = current_class;
+ Delete(mangled);
+ mangled = NewString(SwigType_manglestr(ret_type));
+ class_node = Getattr(zend_types, mangled);
+ }
+ if (i.item) {
+ Printf(output, "case '%s': ", mangled);
+ } else {
+ Printf(output, "default: ");
+ }
+ const char *classname = GetChar(class_node, "sym:name");
+ if (!classname)
+ classname = GetChar(class_node, "name");
+ if (classname)
+ Printf(output, "return new %s%s($r);\n", prefix, classname);
+ else
+ Printf(output, "return $r;\n");
+ Delete(mangled);
+ }
+ Printf(output, "\t\t}\n");
+ }
+ } else {
+ Printf(output, "\t\treturn %s;\n", invoke);
+ }
+ Printf(output, "\t}\n");
+
+done:
+ Delete(prepare);
+ Delete(invoke);
+ free(arg_values);
+
+ Delete(args);
+ args = NULL;
+
+ for (int i = 0; i < max_num_of_arguments; ++i) {
+ Delete(arg_names[i]);
+ }
+ free(arg_names);
+ arg_names = NULL;
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * globalvariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int globalvariableHandler(Node *n) {
+ char *name = GetChar(n, "name");
+ char *iname = GetChar(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ String *tm;
+
+ /* First do the wrappers such as name_set(), name_get()
+ * as provided by the baseclass's implementation of variableWrapper
+ */
+ if (Language::globalvariableHandler(n) == SWIG_NOWRAP) {
+ return SWIG_NOWRAP;
+ }
+
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+
+ SwigType_remember(t);
+
+ /* First link C variables to PHP */
+
+ tm = Swig_typemap_lookup("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));
+ }
+
+ /* Now generate PHP -> C sync blocks */
+ /*
+ tm = Swig_typemap_lookup("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));
+ }
+ */
+ /* Now generate C -> PHP sync blocks */
+ /*
+ if(!GetFlag(n,"feature:immutable")) {
+
+ tm = Swig_typemap_lookup("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));
+ }
+ }
+ */
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *name = GetChar(n, "name");
+ String *iname = GetChar(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ String *rawval = Getattr(n, "rawval");
+ String *value = rawval ? rawval : Getattr(n, "value");
+ String *tm;
+
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+
+ SwigType_remember(type);
+
+ if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ Printf(s_cinit, "%s\n", tm);
+ }
+
+ if (shadow) {
+ String *enumvalue = GetChar(n, "enumvalue");
+ String *set_to = iname;
+
+ if (!enumvalue) {
+ enumvalue = GetChar(n, "enumvalueex");
+ }
+
+ if (enumvalue) {
+ // Check for a simple constant expression which is valid in PHP.
+ // If we find one, initialise the const member with it; otherwise
+ // we initialise it using the C/C++ wrapped constant.
+ const char *p;
+ for (p = Char(enumvalue); *p; ++p) {
+ if (!isdigit((unsigned char)*p) && !strchr(" +-", *p)) {
+ // FIXME: enhance to handle `<previous_enum> + 1' which is what
+ // we get for enums that don't have an explicit value set.
+ break;
+ }
+ }
+ if (!*p) set_to = enumvalue;
+ }
+
+ if (wrapping_member_constant) {
+ if (!s_oowrappers)
+ s_oowrappers = NewStringEmpty();
+ Printf(s_oowrappers, "\n\tconst %s = %s;\n", wrapping_member_constant, set_to);
+ } else {
+ if (!s_fakeoowrappers)
+ s_fakeoowrappers = NewStringEmpty();
+ Printf(s_fakeoowrappers, "\n\tconst %s = %s;\n", iname, set_to);
+ }
+ }
+
+ return SWIG_OK;
+ }
+
+ /*
+ * PHP::pragma()
+ *
+ * Pragma directive.
+ *
+ * %pragma(php) code="String" # Includes a string in the .php file
+ * %pragma(php) include="file.php" # 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, "php") == 0 || 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 {
+ Swig_warning(WARN_PHP_UNKNOWN_PRAGMA, input_file, line_number, "Unrecognized pragma <%s>.\n", type);
+ }
+ }
+ }
+ return Language::pragmaDirective(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int classDeclaration(Node *n) {
+ if (!Getattr(n, "feature:onlychildren")) {
+ 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");
+ current_class = n;
+ // 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 = NewString(rename);
+
+ shadow_get_vars = NewHash();
+ shadow_set_vars = NewHash();
+
+ /* Deal with inheritance */
+ List *baselist = Getattr(n, "bases");
+ if (baselist) {
+ Iterator base = First(baselist);
+ while (base.item && GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ }
+ base = Next(base);
+ if (base.item) {
+ /* Warn about multiple inheritance for additional base class(es) */
+ while (base.item) {
+ if (GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ continue;
+ }
+ String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
+ String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
+ Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number,
+ "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, baseclassname);
+ base = Next(base);
+ }
+ }
+ }
+ }
+
+ classnode = n;
+ Language::classHandler(n);
+ classnode = 0;
+
+ if (shadow) {
+ DOH *key;
+ List *baselist = Getattr(n, "bases");
+ Iterator ki, base;
+
+ if (baselist) {
+ base = First(baselist);
+ while (base.item && GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ }
+ } else {
+ base.item = NULL;
+ }
+
+ if (Getattr(n, "abstract") && !GetFlag(n, "feature:notabstract")) {
+ Printf(s_phpclasses, "abstract ");
+ }
+
+ Printf(s_phpclasses, "class %s%s ", prefix, shadow_classname);
+ String *baseclass = NULL;
+ if (base.item && Getattr(base.item, "module")) {
+ baseclass = Getattr(base.item, "sym:name");
+ if (!baseclass)
+ baseclass = Getattr(base.item, "name");
+ Printf(s_phpclasses, "extends %s%s ", prefix, baseclass);
+ } else if (GetFlag(n, "feature:exceptionclass")) {
+ Append(s_phpclasses, "extends Exception ");
+ }
+ Printf(s_phpclasses, "{\n\tpublic $%s=null;\n", SWIG_PTR);
+ if (!baseclass) {
+ // Only store this in the base class (NB !baseclass means we *are*
+ // a base class...)
+ Printf(s_phpclasses, "\tprotected $%s=array();\n", SWIG_DATA);
+ }
+
+ // Write property SET handlers
+ ki = First(shadow_set_vars);
+
+ if (ki.key) {
+ // This class has setters.
+ Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n");
+ // FIXME: tune this threshold...
+ if (Len(shadow_set_vars) <= 2) {
+ // Not many setters, so avoid call_user_func.
+ while (ki.key) {
+ key = ki.key;
+ Printf(s_phpclasses, "\t\tif ($var === '%s') return %s($this->%s,$value);\n", key, ki.item, SWIG_PTR);
+ ki = Next(ki);
+ }
+ } else {
+ Printf(s_phpclasses, "\t\t$func = '%s_'.$var.'_set';\n", shadow_classname);
+ Printf(s_phpclasses, "\t\tif (function_exists($func)) return call_user_func($func,$this->%s,$value);\n", SWIG_PTR);
+ }
+ Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_alter_newobject($this->%s,$value);\n", module, SWIG_PTR);
+ if (baseclass) {
+ Printf(s_phpclasses, "\t\t%s%s::__set($var,$value);\n", prefix, baseclass);
+ } else {
+ Printf(s_phpclasses, "\t\t$this->%s[$var] = $value;\n", SWIG_DATA);
+ }
+ Printf(s_phpclasses, "\t}\n");
+
+ /* Create __isset for PHP 5.1 and later; PHP 5.0 will just ignore it. */
+ Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
+ Printf(s_phpclasses, "\t\tif (function_exists('%s_'.$var.'_set')) return true;\n", shadow_classname);
+ Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n");
+ if (baseclass) {
+ Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass);
+ } else {
+ Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA);
+ }
+ Printf(s_phpclasses, "\t}\n");
+ } else {
+ Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n");
+ Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_alter_newobject($this->%s,$value);\n", module, SWIG_PTR);
+ if (baseclass) {
+ Printf(s_phpclasses, "\t\t%s%s::__set($var,$value);\n", prefix, baseclass);
+ } else {
+ Printf(s_phpclasses, "\t\t$this->%s[$var] = $value;\n", SWIG_DATA);
+ }
+ Printf(s_phpclasses, "\t}\n");
+ Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
+ Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n");
+ if (baseclass) {
+ Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass);
+ } else {
+ Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA);
+ }
+ Printf(s_phpclasses, "\t}\n");
+ }
+ // Write property GET handlers
+ ki = First(shadow_get_vars);
+
+ if (ki.key) {
+ // This class has getters.
+ Printf(s_phpclasses, "\n\tfunction __get($var) {\n");
+ // FIXME: Currently we always use call_user_func for __get, so we can
+ // check and wrap the result. This is needless if all the properties
+ // are primitive types. Also this doesn't handle all the cases which
+ // a method returning an object does.
+ Printf(s_phpclasses, "\t\t$func = '%s_'.$var.'_get';\n", shadow_classname);
+ Printf(s_phpclasses, "\t\tif (function_exists($func)) {\n");
+ Printf(s_phpclasses, "\t\t\t$r = call_user_func($func,$this->%s);\n", SWIG_PTR);
+ Printf(s_phpclasses, "\t\t\tif (!is_resource($r)) return $r;\n");
+ if (Len(prefix) == 0) {
+ Printf(s_phpclasses, "\t\t\t$c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n");
+ } else {
+ Printf(s_phpclasses, "\t\t\t$c='%s'.substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n", prefix);
+ }
+ Printf(s_phpclasses, "\t\t\treturn new $c($r);\n");
+ Printf(s_phpclasses, "\t\t}\n");
+ Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_get_newobject($this->%s);\n", module, SWIG_PTR);
+ if (baseclass) {
+ Printf(s_phpclasses, "\t\treturn %s%s::__get($var);\n", prefix, baseclass);
+ } else {
+ // Reading an unknown property name gives null in PHP.
+ Printf(s_phpclasses, "\t\treturn $this->%s[$var];\n", SWIG_DATA);
+ }
+ Printf(s_phpclasses, "\t}\n");
+ } else {
+ Printf(s_phpclasses, "\n\tfunction __get($var) {\n");
+ Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_get_newobject($this->%s);\n", module, SWIG_PTR);
+ if (baseclass) {
+ Printf(s_phpclasses, "\t\treturn %s%s::__get($var);\n", prefix, baseclass);
+ } else {
+ Printf(s_phpclasses, "\t\treturn $this->%s[$var];\n", SWIG_DATA);
+ }
+ Printf(s_phpclasses, "\t}\n");
+ }
+
+ if (!class_has_ctor) {
+ Printf(s_phpclasses, "\tfunction __construct($h) {\n");
+ Printf(s_phpclasses, "\t\t$this->%s=$h;\n", SWIG_PTR);
+ Printf(s_phpclasses, "\t}\n");
+ }
+
+ if (s_oowrappers) {
+ Printf(s_phpclasses, "%s", s_oowrappers);
+ Delete(s_oowrappers);
+ s_oowrappers = NULL;
+ }
+ class_has_ctor = false;
+
+ Printf(s_phpclasses, "}\n\n");
+
+ Delete(shadow_classname);
+ shadow_classname = NULL;
+
+ Delete(shadow_set_vars);
+ shadow_set_vars = NULL;
+ Delete(shadow_get_vars);
+ shadow_get_vars = NULL;
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberfunctionHandler(Node *n) {
+ wrapperType = memberfn;
+ Language::memberfunctionHandler(n);
+ wrapperType = standard;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int membervariableHandler(Node *n) {
+ wrapperType = membervar;
+ Language::membervariableHandler(n);
+ wrapperType = standard;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmembervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ wrapperType = staticmembervar;
+ Language::staticmembervariableHandler(n);
+ wrapperType = standard;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ wrapperType = staticmemberfn;
+ Language::staticmemberfunctionHandler(n);
+ wrapperType = standard;
+
+ return SWIG_OK;
+ }
+
+ int abstractConstructorHandler(Node *) {
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+ constructors++;
+ if (Swig_directorclass(n)) {
+ String *name = GetChar(Swig_methodclass(n), "name");
+ String *ctype = GetChar(Swig_methodclass(n), "classtype");
+ String *sname = GetChar(Swig_methodclass(n), "sym:name");
+ String *args = NewStringEmpty();
+ ParmList *p = Getattr(n, "parms");
+ int i;
+
+ for (i = 0; p; p = nextSibling(p), i++) {
+ if (i) {
+ Printf(args, ", ");
+ }
+ if (Strcmp(GetChar(p, "type"), SwigType_str(GetChar(p, "type"), 0))) {
+ SwigType *t = Getattr(p, "type");
+ Printf(args, "%s", SwigType_rcaststr(t, 0));
+ if (SwigType_isreference(t)) {
+ Append(args, "*");
+ }
+ }
+ Printf(args, "arg%d", i+1);
+ }
+
+ /* director ctor code is specific for each class */
+ Delete(director_ctor_code);
+ director_ctor_code = NewStringEmpty();
+ director_prot_ctor_code = NewStringEmpty();
+ Printf(director_ctor_code, "if ( arg0->type == IS_NULL ) { /* not subclassed */\n");
+ Printf(director_prot_ctor_code, "if ( arg0->type == IS_NULL ) { /* not subclassed */\n");
+ Printf(director_ctor_code, " result = (%s *)new %s(%s);\n", ctype, ctype, args);
+ Printf(director_prot_ctor_code, " SWIG_PHP_Error(E_ERROR, \"accessing abstract class or protected constructor\");\n", name, name, args);
+ if (i) {
+ Insert(args, 0, ", ");
+ }
+ Printf(director_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s);\n}\n", ctype, sname, args);
+ Printf(director_prot_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s);\n}\n", ctype, sname, args);
+ Delete(args);
+
+ wrapperType = directorconstructor;
+ } else {
+ wrapperType = constructor;
+ }
+ Language::constructorHandler(n);
+ wrapperType = standard;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * CreateZendListDestructor()
+ * ------------------------------------------------------------ */
+ //virtual int destructorHandler(Node *n) {
+ //}
+ int CreateZendListDestructor(Node *n) {
+ String *name = GetChar(Swig_methodclass(n), "name");
+ String *iname = GetChar(n, "sym:name");
+ ParmList *l = Getattr(n, "parms");
+
+ String *destructorname = NewStringEmpty();
+ Printf(destructorname, "_%s", Swig_name_wrapper(iname));
+ Setattr(classnode, "destructor", destructorname);
+
+ Wrapper *f = NewWrapper();
+ Printf(f->def, "/* This function is designed to be called by the zend list destructors */\n");
+ Printf(f->def, "/* to typecast and do the actual destruction */\n");
+ Printf(f->def, "static void %s(zend_rsrc_list_entry *rsrc, const char *type_name TSRMLS_DC) {\n", destructorname);
+
+ Wrapper_add_localv(f, "value", "swig_object_wrapper *value=(swig_object_wrapper *) rsrc->ptr", NIL);
+ Wrapper_add_localv(f, "ptr", "void *ptr=value->ptr", NIL);
+ Wrapper_add_localv(f, "newobject", "int newobject=value->newobject", NIL);
+
+ emit_parameter_variables(l, f);
+ emit_attach_parmmaps(l, f);
+
+ // Get type of first arg, thing to be destructed
+ // Skip ignored arguments
+ Parm *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(f->code, " efree(value);\n");
+ Printf(f->code, " if (! newobject) return; /* can't delete it! */\n");
+ Printf(f->code, " arg1 = (%s)SWIG_ZTS_ConvertResourceData(ptr,type_name,SWIGTYPE%s TSRMLS_CC);\n", SwigType_lstr(pt, 0), SwigType_manglestr(pt));
+ Printf(f->code, " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name));
+
+ Setattr(n, "wrap:name", destructorname);
+
+ String *actioncode = emit_action(n);
+ Append(f->code, actioncode);
+ Delete(actioncode);
+
+ Append(f->code, "return;\n");
+ Append(f->code, "fail:\n");
+ Append(f->code, "zend_error_noreturn(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());\n");
+ Printf(f->code, "}\n");
+
+ Wrapper_print(f, s_wrappers);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberconstantHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberconstantHandler(Node *n) {
+ wrapping_member_constant = Getattr(n, "sym:name");
+ Language::memberconstantHandler(n);
+ wrapping_member_constant = NULL;
+ return SWIG_OK;
+ }
+
+ int classDirectorInit(Node *n) {
+ String *declaration = Swig_director_declaration(n);
+ Printf(f_directors_h, "%s\n", declaration);
+ Printf(f_directors_h, "public:\n");
+ Delete(declaration);
+ return Language::classDirectorInit(n);
+ }
+
+ int classDirectorEnd(Node *n) {
+ Printf(f_directors_h, "};\n");
+ return Language::classDirectorEnd(n);
+ }
+
+ int classDirectorConstructor(Node *n) {
+ Node *parent = Getattr(n, "parentNode");
+ String *decl = Getattr(n, "decl");
+ String *supername = Swig_class_name(parent);
+ String *classname = NewStringEmpty();
+ Printf(classname, "SwigDirector_%s", supername);
+
+ /* insert self parameter */
+ Parm *p;
+ ParmList *superparms = Getattr(n, "parms");
+ ParmList *parms = CopyParmList(superparms);
+ String *type = NewString("zval");
+ SwigType_add_pointer(type);
+ p = NewParm(type, NewString("self"));
+ set_nextSibling(p, parms);
+ parms = p;
+
+ if (!Getattr(n, "defaultargs")) {
+ /* constructor */
+ {
+ Wrapper *w = NewWrapper();
+ String *call;
+ String *basetype = Getattr(parent, "classtype");
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+ call = Swig_csuperclass_call(0, basetype, superparms);
+ Printf(w->def, "%s::%s: %s, Swig::Director(self) {", classname, target, call);
+ Append(w->def, "}");
+ Delete(target);
+ Wrapper_print(w, f_directors);
+ Delete(call);
+ DelWrapper(w);
+ }
+
+ /* constructor header */
+ {
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+ Printf(f_directors_h, " %s;\n", target);
+ Delete(target);
+ }
+ }
+ return Language::classDirectorConstructor(n);
+ }
+
+ int classDirectorMethod(Node *n, Node *parent, String *super) {
+ int is_void = 0;
+ int is_pointer = 0;
+ String *decl;
+ String *type;
+ String *name;
+ String *classname;
+ String *c_classname = Getattr(parent, "name");
+ String *declaration;
+ ParmList *l;
+ Wrapper *w;
+ String *tm;
+ String *wrap_args = NewStringEmpty();
+ String *return_type;
+ String *value = Getattr(n, "value");
+ String *storage = Getattr(n, "storage");
+ bool pure_virtual = false;
+ int status = SWIG_OK;
+ int idx;
+ bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
+
+ if (Cmp(storage, "virtual") == 0) {
+ if (Cmp(value, "0") == 0) {
+ pure_virtual = true;
+ }
+ }
+
+ classname = Getattr(parent, "sym:name");
+ type = Getattr(n, "type");
+ name = Getattr(n, "name");
+
+ w = NewWrapper();
+ declaration = NewStringEmpty();
+
+ /* determine if the method returns a pointer */
+ decl = Getattr(n, "decl");
+ is_pointer = SwigType_ispointer_return(decl);
+ is_void = (Cmp(type, "void") == 0 && !is_pointer);
+
+ /* form complete return type */
+ return_type = Copy(type);
+ {
+ SwigType *t = Copy(decl);
+ SwigType *f = SwigType_pop_function(t);
+ SwigType_push(return_type, t);
+ Delete(f);
+ Delete(t);
+ }
+
+ /* virtual method definition */
+ l = Getattr(n, "parms");
+ String *target;
+ String *pclassname = NewStringf("SwigDirector_%s", classname);
+ String *qualified_name = NewStringf("%s::%s", pclassname, name);
+ SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type;
+ target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+ Printf(w->def, "%s", target);
+ Delete(qualified_name);
+ Delete(target);
+ /* header declaration */
+ target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+ Printf(declaration, " virtual %s", target);
+ Delete(target);
+
+ // Get any exception classes in the throws typemap
+ ParmList *throw_parm_list = 0;
+
+ if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
+ Parm *p;
+ int gencomma = 0;
+
+ Append(w->def, " throw(");
+ Append(declaration, " throw(");
+
+ if (throw_parm_list)
+ Swig_typemap_attach_parms("throws", throw_parm_list, 0);
+ for (p = throw_parm_list; p; p = nextSibling(p)) {
+ if ((tm = Getattr(p, "tmap:throws"))) {
+ if (gencomma++) {
+ Append(w->def, ", ");
+ Append(declaration, ", ");
+ }
+ String *str = SwigType_str(Getattr(p, "type"), 0);
+ Append(w->def, str);
+ Append(declaration, str);
+ Delete(str);
+ }
+ }
+
+ Append(w->def, ")");
+ Append(declaration, ")");
+ }
+
+ Append(w->def, " {");
+ Append(declaration, ";\n");
+
+ /* declare method return value
+ * if the return value is a reference or const reference, a specialized typemap must
+ * handle it, including declaration of c_result ($result).
+ */
+ if (!is_void) {
+ if (!(ignored_method && !pure_virtual)) {
+ String *cres = SwigType_lstr(return_type, "c_result");
+ Printf(w->code, "%s;\n", cres);
+ Delete(cres);
+ }
+ }
+
+ if (ignored_method) {
+ if (!pure_virtual) {
+ if (!is_void)
+ Printf(w->code, "return ");
+ String *super_call = Swig_method_call(super, l);
+ Printf(w->code, "%s;\n", super_call);
+ Delete(super_call);
+ } else {
+ Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
+ SwigType_namestr(name));
+ }
+ } else {
+ /* attach typemaps to arguments (C/C++ -> PHP) */
+ String *parse_args = NewStringEmpty();
+
+ /* remove the wrapper 'w' since it was producing spurious temps */
+ Swig_typemap_attach_parms("in", l, 0);
+ Swig_typemap_attach_parms("directorin", l, 0);
+ Swig_typemap_attach_parms("directorargout", l, w);
+
+ Parm *p;
+ char source[256];
+
+ int outputs = 0;
+ if (!is_void)
+ outputs++;
+
+ /* build argument list and type conversion string */
+ idx = 0;
+ p = l;
+ int use_parse = 0;
+ while (p != NULL) {
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+
+ if (Getattr(p, "tmap:directorargout") != 0)
+ outputs++;
+
+ String *pname = Getattr(p, "name");
+ String *ptype = Getattr(p, "type");
+
+ if ((tm = Getattr(p, "tmap:directorin")) != 0) {
+ String *parse = Getattr(p, "tmap:directorin:parse");
+ if (!parse) {
+ sprintf(source, "obj%d", idx++);
+ String *input = NewStringf("&%s", source);
+ Replaceall(tm, "$input", input);
+ Delete(input);
+ Replaceall(tm, "$owner", "0");
+ Printv(wrap_args, "zval ", source, ";\n", NIL);
+ Printf(wrap_args, "args[%d] = &%s;\n", idx - 1, source);
+
+ Printv(wrap_args, tm, "\n", NIL);
+ Putc('O', parse_args);
+ } else {
+ use_parse = 1;
+ Append(parse_args, parse);
+ Replaceall(tm, "$input", pname);
+ Replaceall(tm, "$owner", "0");
+ if (Len(tm) == 0)
+ Append(tm, pname);
+ }
+ p = Getattr(p, "tmap:directorin:next");
+ continue;
+ } else if (Cmp(ptype, "void")) {
+ Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
+ SwigType_namestr(c_classname), SwigType_namestr(name));
+ status = SWIG_NOWRAP;
+ break;
+ }
+ p = nextSibling(p);
+ }
+ Append(w->code, "int error;\n");
+ if (!idx) {
+ Printf(w->code, "zval **args = NULL;\n", idx);
+ } else {
+ Printf(w->code, "zval *args[%d];\n", idx);
+ }
+ Append(w->code, "zval *result, funcname;\n");
+ Append(w->code, "MAKE_STD_ZVAL(result);\n");
+ Printf(w->code, "ZVAL_STRING(&funcname, (char *)\"%s\", 0);\n", name);
+ Append(w->code, "if (!swig_self) {\n");
+ Append(w->code, " SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");");
+ Append(w->code, "}\n\n");
+
+ /* wrap complex arguments to zvals */
+ Printv(w->code, wrap_args, NIL);
+
+ Append(w->code, "call_user_function(EG(function_table), (zval**)&swig_self, &funcname,\n");
+ Printf(w->code, " result, %d, args TSRMLS_CC);\n", idx);
+
+ /* exception handling */
+ tm = Swig_typemap_lookup("director:except", n, "result", 0);
+ if (!tm) {
+ tm = Getattr(n, "feature:director:except");
+ if (tm)
+ tm = Copy(tm);
+ }
+ if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
+ Replaceall(tm, "$error", "error");
+ Printv(w->code, Str(tm), "\n", NIL);
+ }
+ Delete(tm);
+
+ /* marshal return value from PHP to C/C++ type */
+
+ String *cleanup = NewStringEmpty();
+ String *outarg = NewStringEmpty();
+
+ idx = 0;
+
+ /* marshal return value */
+ if (!is_void) {
+ /* this seems really silly. the node's type excludes
+ * qualifier/pointer/reference markers, which have to be retrieved
+ * from the decl field to construct return_type. but the typemap
+ * lookup routine uses the node's type, so we have to swap in and
+ * out the correct type. it's not just me, similar silliness also
+ * occurs in Language::cDeclaration().
+ */
+ Setattr(n, "type", return_type);
+ tm = Swig_typemap_lookup("directorout", n, "result", w);
+ Setattr(n, "type", type);
+ if (tm != 0) {
+ Replaceall(tm, "$input", "&result");
+ char temp[24];
+ sprintf(temp, "%d", idx);
+ Replaceall(tm, "$argnum", temp);
+
+ /* TODO check this */
+ if (Getattr(n, "wrap:disown")) {
+ Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm, "$disown", "0");
+ }
+ Replaceall(tm, "$result", "c_result");
+ Printv(w->code, tm, "\n", NIL);
+ Delete(tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0), SwigType_namestr(c_classname),
+ SwigType_namestr(name));
+ status = SWIG_ERROR;
+ }
+ }
+
+ /* marshal outputs */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
+ Replaceall(tm, "$input", "result");
+ Replaceall(tm, "$result", Getattr(p, "name"));
+ Printv(w->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:directorargout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ Append(w->code, "FREE_ZVAL(result);\n");
+
+ Delete(parse_args);
+ Delete(cleanup);
+ Delete(outarg);
+ }
+
+ if (!is_void) {
+ if (!(ignored_method && !pure_virtual)) {
+ String *rettype = SwigType_str(return_type, 0);
+ if (!SwigType_isreference(return_type)) {
+ Printf(w->code, "return (%s) c_result;\n", rettype);
+ } else {
+ Printf(w->code, "return (%s) *c_result;\n", rettype);
+ }
+ Delete(rettype);
+ }
+ } else {
+ Append(w->code, "return;\n");
+ }
+
+ Append(w->code, "fail:\n");
+ Append(w->code, "zend_error_noreturn(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());\n");
+ Append(w->code, "}\n");
+
+ // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
+ String *inline_extra_method = NewStringEmpty();
+ if (dirprot_mode() && !is_public(n) && !pure_virtual) {
+ Printv(inline_extra_method, declaration, NIL);
+ String *extra_method_name = NewStringf("%sSwigPublic", name);
+ Replaceall(inline_extra_method, name, extra_method_name);
+ Replaceall(inline_extra_method, ";\n", " {\n ");
+ if (!is_void)
+ Printf(inline_extra_method, "return ");
+ String *methodcall = Swig_method_call(super, l);
+ Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
+ Delete(methodcall);
+ Delete(extra_method_name);
+ }
+
+ /* emit the director method */
+ if (status == SWIG_OK) {
+ if (!Getattr(n, "defaultargs")) {
+ Wrapper_print(w, f_directors);
+ Printv(f_directors_h, declaration, NIL);
+ Printv(f_directors_h, inline_extra_method, NIL);
+ }
+ }
+
+ /* clean up */
+ Delete(wrap_args);
+ Delete(return_type);
+ Delete(pclassname);
+ DelWrapper(w);
+ return status;
+ }
+
+ int classDirectorDisown(Node *) {
+ return SWIG_OK;
+ }
+}; /* class PHP */
+
+static PHP *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 PHP::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);
+}
+
+/* -----------------------------------------------------------------------------
+ * new_swig_php() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_php() {
+ maininstance = new PHP;
+ if (!r_prevtracefunc) {
+ r_prevtracefunc = SwigType_remember_trace(typetrace);
+ } else {
+ Printf(stderr, "php Typetrace vector already saved!\n");
+ assert(0);
+ }
+ return maininstance;
+}
+
+extern "C" Language *swig_php4(void) {
+ Printf(stderr, "*** -php4 is no longer supported.\n"
+ "*** Either upgrade to PHP5 or use SWIG 1.3.36 or earlier.\n");
+ SWIG_exit(EXIT_FAILURE);
+ return NULL; // To avoid compiler warnings.
+}
+
+extern "C" Language *swig_php(void) {
+ return new_swig_php();
+}
diff --git a/Source/Modules/pike.cxx b/Source/Modules/pike.cxx
new file mode 100644
index 0000000..00e7500
--- /dev/null
+++ b/Source/Modules/pike.cxx
@@ -0,0 +1,903 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * pike.cxx
+ *
+ * Pike language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+/*
+ * Notes:
+ *
+ * - The current approach used for "out" typemaps is inconsistent with
+ * how "out" typemaps are handled by other language modules. Instead
+ * of converting the C/C++ type ($1) to a Pike object type (e.g. a
+ * struct svalue), we're just calling the appropriate push_XXX
+ * (e.g. push_int) to push the return value onto the stack.
+ *
+ * - Pike classes can't have static member functions or data, so we need
+ * to find some other appropriate mapping for C++ static member functions
+ * and data.
+ *
+ * - Pike doesn't seem to provide any default way to print the memory
+ * address, etc. for extension objects. Should we do something here?
+ *
+ */
+
+char cvsroot_pike_cxx[] = "$Id: pike.cxx 11133 2009-02-20 07:52:24Z wsfulton $";
+
+#include "swigmod.h"
+
+#include <ctype.h> // for isalnum()
+
+static const char *usage = (char *) "\
+Pike Options (available with -pike)\n\
+ [None]\n\
+\n";
+
+class PIKE:public Language {
+private:
+
+ File *f_begin;
+ File *f_runtime;
+ File *f_header;
+ File *f_wrappers;
+ File *f_init;
+ File *f_classInit;
+
+ 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_begin = 0;
+ f_runtime = 0;
+ f_header = 0;
+ f_wrappers = 0;
+ f_init = 0;
+ f_classInit = 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], "-help") == 0) {
+ fputs(usage, stdout);
+ }
+ }
+ }
+
+ /* 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_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_classInit = 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("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+ Swig_register_filebyname("classInit", f_classInit);
+
+ /* Standard stuff for the SWIG runtime section */
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGPIKE\n");
+ Printf(f_runtime, "\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_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Delete(f_classInit);
+
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+
+ /* Done */
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * validIdentifier()
+ * ------------------------------------------------------------ */
+
+ virtual int validIdentifier(String *s) {
+ char *c = Char(s);
+ const char *c0 = c;
+ const char *c1 = c0 + 1;
+ while (*c) {
+ if (*c == '`' && c == c0) {
+ c++;
+ continue;
+ }
+ if ((*c == '+' || *c == '-' || *c == '*' || *c == '/') && c == c1) {
+ c++;
+ continue;
+ }
+ if (!(isalnum(*c) || (*c == '_')))
+ return 0;
+ c++;
+ }
+ return 1;
+ }
+
+ /* ------------------------------------------------------------
+ * 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 DOHconst_String_or_char_ptr name) {
+ String *s = Copy(name);
+ if (Strncmp(name, PrefixPlusUnderscore, Len(PrefixPlusUnderscore)) != 0) {
+ return s;
+ }
+ Replaceall(s, PrefixPlusUnderscore, "");
+ return s;
+ }
+
+ /* ------------------------------------------------------------
+ * add_method()
+ * ------------------------------------------------------------ */
+
+ void add_method(const DOHconst_String_or_char_ptr name, const DOHconst_String_or_char_ptr function, const DOHconst_String_or_char_ptr description) {
+ String *rename = NULL;
+ switch (current) {
+ case NO_CPP:
+ rename = NewString(name);
+ Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
+ break;
+ case STATIC_FUNC:
+ case STATIC_VAR:
+ rename = NewString(name);
+ Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
+ break;
+ case CONSTRUCTOR:
+ case DESTRUCTOR:
+ case MEMBER_FUNC:
+ case MEMBER_VAR:
+ rename = strip(name);
+ Printf(f_classInit, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
+ break;
+ case CLASS_CONST:
+ assert(false); // shouldn't have gotten here for CLASS_CONST nodes
+ default:
+ assert(false); // what is this?
+ }
+ 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();
+
+ // Emit all of the local variables for holding arguments.
+ emit_parameter_variables(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);
+ }
+ Setattr(n, "wrap:name", wname);
+
+ 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, "Pike_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 */
+ String *actioncode = emit_action(n);
+
+ /* Clear the return stack */
+ Printf(actioncode, "pop_n_elems(args);\n");
+
+ /* Return the function value */
+ if (current == CONSTRUCTOR) {
+ Printv(actioncode, "THIS = (void *) result;\n", NIL);
+ Printv(description, ", tVoid", NIL);
+ } else if (current == DESTRUCTOR) {
+ Printv(description, ", tVoid", NIL);
+ } else {
+ Printv(description, ", ", NIL);
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ actioncode = 0;
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+ if (GetFlag(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);
+ }
+ }
+ if (actioncode) {
+ Append(f->code, actioncode);
+ Delete(actioncode);
+ }
+ emit_return_variable(n, d, f);
+
+ /* 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 (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("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("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(iname, wname, description);
+ } else {
+ 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, "%s(args); return;", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *f = NewWrapper();
+ String *symname = Getattr(n, "sym:name");
+ String *wname = Swig_name_wrapper(symname);
+
+ Printf(f->def, "static void %s(INT32 args) {", wname);
+
+ Wrapper_add_local(f, "argc", "INT32 argc");
+ Printf(tmp, "struct svalue argv[%d]", maxargs);
+ Wrapper_add_local(f, "argv", tmp);
+ Wrapper_add_local(f, "ii", "INT32 ii");
+
+ Printf(f->code, "argc = args;\n");
+ Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n", maxargs);
+ Printf(f->code, "argv[ii] = Pike_sp[ii-args];\n");
+ Printf(f->code, "}\n");
+
+ Replaceall(dispatch, "$args", "self, args");
+ Printv(f->code, dispatch, "\n", NIL);
+ Printf(f->code, "Pike_error(\"No matching function for overloaded '%s'.\");\n", symname);
+ Printv(f->code, "}\n", NIL);
+
+ Wrapper_print(f, f_wrappers);
+
+ String *description = NewString("");
+ Printf(description, "tAny,");
+ if (current == CONSTRUCTOR || current == DESTRUCTOR) {
+ Printf(description, " tVoid");
+ } else {
+ String *pd = Getattr(n, "tmap:out:pikedesc");
+ if (pd)
+ Printf(description, " %s", pd);
+ }
+ add_method(symname, wname, description);
+ Delete(description);
+
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(tmp);
+ Delete(wname);
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+ return Language::variableWrapper(n);
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+
+ Swig_require("constantWrapper", 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("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(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_classInit, "start_new_program();\n");
+
+ /* Handle inheritance */
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist) > 0) {
+ Iterator base = First(baselist);
+ while (base.item) {
+ String *basename = Getattr(base.item, "name");
+ SwigType *basetype = NewString(basename);
+ SwigType_add_pointer(basetype);
+ SwigType_remember(basetype);
+ String *basemangle = SwigType_manglestr(basetype);
+ Printf(f_classInit, "low_inherit((struct program *) SWIGTYPE%s->clientdata, 0, 0, 0, 0, 0);\n", basemangle);
+ Delete(basemangle);
+ Delete(basetype);
+ base = Next(base);
+ }
+ } else {
+ Printf(f_classInit, "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 and dump its definition to the init function */
+ Printf(f_classInit, "add_program_constant(\"%s\", pr = end_program(), 0);\n", symname);
+ Dump(f_classInit, f_init);
+ Clear(f_classInit);
+
+ 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;
+ Iterator i;
+ bool need_setter;
+ String *funcname;
+
+ /* If at least one of them is mutable, we need a setter */
+ need_setter = false;
+ i = First(membervariables);
+ while (i.item) {
+ if (!GetFlag(i.item, "feature:immutable")) {
+ need_setter = true;
+ break;
+ }
+ i = Next(i);
+ }
+
+ /* 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(Pike_sp[0-args].u.string);\n");
+
+ i = First(membervariables);
+ while (i.item) {
+ if (!GetFlag(i.item, "feature:immutable")) {
+ name = Getattr(i.item, "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);
+ }
+ i = Next(i);
+ }
+
+ /* 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("`->=", 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(Pike_sp[0-args].u.string);\n");
+
+ i = First(membervariables);
+ while (i.item) {
+ name = Getattr(i.item, "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);
+ i = Next(i);
+ }
+
+ /* 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("`->", 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
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_pike() {
+ return new PIKE();
+}
+extern "C" Language *swig_pike(void) {
+ return new_swig_pike();
+}
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
new file mode 100644
index 0000000..83df3aa
--- /dev/null
+++ b/Source/Modules/python.cxx
@@ -0,0 +1,4067 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * python.cxx
+ *
+ * Python language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_python_cxx[] = "$Id: python.cxx 11518 2009-08-08 22:56:10Z wsfulton $";
+
+#include "swigmod.h"
+#include "cparse.h"
+
+static int treduce = SWIG_cparse_template_reduce(0);
+
+#include <ctype.h>
+
+#define PYSHADOW_MEMBER 0x2
+
+static String *const_code = 0;
+static String *module = 0;
+static String *package = 0;
+static String *mainmodule = 0;
+static String *interface = 0;
+static String *global_name = 0;
+static int shadow = 1;
+static int use_kw = 0;
+static int director_method_index = 0;
+
+static File *f_begin = 0;
+static File *f_runtime = 0;
+static File *f_runtime_h = 0;
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_directors = 0;
+static File *f_directors_h = 0;
+static File *f_init = 0;
+static File *f_shadow_py = 0;
+static String *f_shadow = 0;
+static String *f_shadow_imports = 0;
+static String *f_shadow_stubs = 0;
+
+static String *methods;
+static String *class_name;
+static String *shadow_indent = 0;
+static int in_class = 0;
+static int classic = 0;
+static int modern = 0;
+static int new_repr = 1;
+static int no_header_file = 0;
+
+static int py3 = 0;
+
+/* C++ Support + Shadow Classes */
+
+static int have_constructor;
+static int have_repr;
+static String *real_classname;
+
+/* Thread Support */
+static int threads = 0;
+static int nothreads = 0;
+static int classptr = 0;
+/* Other options */
+static int shadowimport = 1;
+static int buildnone = 0;
+static int nobuildnone = 0;
+static int safecstrings = 0;
+static int dirvtable = 0;
+static int proxydel = 1;
+static int fastunpack = 0;
+static int fastproxy = 0;
+static int fastquery = 0;
+static int fastinit = 0;
+static int olddefs = 0;
+static int modernargs = 0;
+static int aliasobj0 = 0;
+static int castmode = 0;
+static int extranative = 0;
+static int outputtuple = 0;
+static int nortti = 0;
+
+/* flags for the make_autodoc function */
+enum autodoc_t {
+ AUTODOC_CLASS,
+ AUTODOC_CTOR,
+ AUTODOC_DTOR,
+ AUTODOC_STATICFUNC,
+ AUTODOC_FUNC,
+ AUTODOC_METHOD
+};
+
+
+static const char *usage1 = (char *) "\
+Python Options (available with -python)\n\
+ -aliasobj0 - Alias obj0 when using fastunpack, needed for some old typemaps \n\
+ -buildnone - Use Py_BuildValue(" ") to obtain Py_None (default in Windows)\n\
+ -castmode - Enable the casting mode, which allows implicit cast between types in python\n\
+ -classic - Use classic classes only\n\
+ -classptr - Generate shadow 'ClassPtr' as in older swig versions\n\
+ -cppcast - Enable C++ casting operators (default) \n\
+ -dirvtable - Generate a pseudo virtual table for directors for faster dispatch \n\
+ -extranative - Return extra native C++ wraps for std containers when possible \n\
+ -fastinit - Use fast init mechanism for classes (default)\n\
+ -fastunpack - Use fast unpack mechanism to parse the argument functions \n\
+ -fastproxy - Use fast proxy mechanism for member methods \n\
+ -fastquery - Use fast query mechanism for types \n\
+ -globals <name> - Set <name> used to access C global variable [default: 'cvar']\n\
+ -interface <lib>- Set the lib name to <lib>\n\
+ -keyword - Use keyword arguments\n\
+ -modern - Use modern python features only, without compatibility code\n\
+ -modernargs - Use \"modern\" args mechanism to pack/unpack the function arguments\n";
+static const char *usage2 = (char *) "\
+ -newrepr - Use more informative version of __repr__ in proxy classes (default) \n\
+ -newvwm - New value wrapper mode, use only when everything else fails \n\
+ -noaliasobj0 - Don't generate an obj0 alias when using fastunpack (default) \n\
+ -nobuildnone - Access Py_None directly (default in non-Windows systems)\n\
+ -nocastmode - Disable the casting mode (default)\n\
+ -nocppcast - Disable C++ casting operators, useful for generating bugs\n\
+ -nodirvtable - Don't use the virtual table feature, resolve the python method each time (default)\n\
+ -noexcept - No automatic exception handling\n\
+ -noextranative - Don't use extra native C++ wraps for std containers when possible (default) \n\
+ -nofastinit - Use traditional init mechanism for classes \n\
+ -nofastunpack - Use traditional UnpackTuple method to parse the argument functions (default) \n\
+ -nofastproxy - Use traditional proxy mechanism for member methods (default) \n\
+ -nofastquery - Use traditional query mechanism for types (default) \n\
+ -noh - Don't generate the output header file\n\
+ -nomodern - Don't use modern python features which are not back compatible \n\
+ -nomodernargs - Use classic ParseTuple/CallFunction methods to pack/unpack the function arguments (default) \n";
+static const char *usage3 = (char *) "\
+ -noolddefs - Don't emit the old method definitions even when using fastproxy (default) \n\
+ -nooutputtuple - Use a PyList for appending output values (default) \n\
+ -noproxy - Don't generate proxy classes \n\
+ -noproxydel - Don't generate the redundant __del__ method \n\
+ -noproxyimport - Don't insert proxy import statements derived from the %import directive \n\
+ -nortti - Disable the use of the native C++ RTTI with directors\n\
+ -nosafecstrings - Avoid extra strings copies when possible (default)\n\
+ -nothreads - Disable thread support for the entire interface\n\
+ -olddefs - Keep the old method definitions even when using fastproxy\n\
+ -oldrepr - Use shorter and old version of __repr__ in proxy classes\n\
+ -outputtuple - Use a PyTuple for outputs instead of a PyList (use carefully with legacy interfaces) \n\
+ -proxydel - Generate a __del__ method even though it is now redundant (default) \n\
+ -safecstrings - Use safer (but slower) C string mapping, generating copies from Python -> C/C++\n\
+ -threads - Add thread support for all the interface\n\
+ -O - Enable all the optimization options: \n\
+ -modern -fastdispatch -dirvtable -nosafecstrings -fvirtual -noproxydel \n\
+ -fastproxy -fastinit -fastunpack -fastquery -modernargs -nobuildnone \n\
+ -py3 - Generate code with Python 3 specific features:\n\
+ Function annotation \n\
+\n";
+
+class PYTHON:public Language {
+public:
+ PYTHON() {
+ /* Add code to manage protected constructors and directors */
+ director_prot_ctor_code = NewString("");
+ Printv(director_prot_ctor_code,
+ "if ( $comparison ) { /* subclassed */\n",
+ " $director_new \n",
+ "} else {\n", " SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL);
+ director_multiple_inheritance = 1;
+ director_language = 1;
+ }
+
+ /* ------------------------------------------------------------
+ * Thread Implementation
+ * ------------------------------------------------------------ */
+
+ int threads_enable(Node *n) const {
+ return threads && !GetFlagAttr(n, "feature:nothread");
+ }
+
+ int initialize_threads(String *f_init) {
+ if (!threads) {
+ return SWIG_OK;
+ }
+ Printf(f_init, "\n");
+ Printf(f_init, "/* Initialize threading */\n");
+ Printf(f_init, "SWIG_PYTHON_INITIALIZE_THREADS;\n");
+
+ return SWIG_OK;
+ }
+
+ virtual void thread_begin_block(Node *n, String *f) {
+ if (!GetFlag(n, "feature:nothreadblock")) {
+ String *bb = Getattr(n, "feature:threadbeginblock");
+ if (bb) {
+ Append(f, bb);
+ } else {
+ Append(f, "SWIG_PYTHON_THREAD_BEGIN_BLOCK;\n");
+ }
+ }
+ }
+
+ virtual void thread_end_block(Node *n, String *f) {
+ if (!GetFlag(n, "feature:nothreadblock")) {
+ String *eb = Getattr(n, "feature:threadendblock");
+ if (eb) {
+ Append(f, eb);
+ } else {
+ Append(f, "SWIG_PYTHON_THREAD_END_BLOCK;\n");
+ }
+ }
+ }
+
+ virtual void thread_begin_allow(Node *n, String *f) {
+ if (!GetFlag(n, "feature:nothreadallow")) {
+ String *bb = Getattr(n, "feature:threadbeginallow");
+ if (bb) {
+ Append(f, bb);
+ } else {
+ Append(f, "SWIG_PYTHON_THREAD_BEGIN_ALLOW;\n");
+ }
+ }
+ }
+
+ virtual void thread_end_allow(Node *n, String *f) {
+ if (!GetFlag(n, "feature:nothreadallow")) {
+ String *eb = Getattr(n, "feature:threadendallow");
+ if (eb) {
+ Append(f, eb);
+ } else {
+ Append(f, "SWIG_PYTHON_THREAD_END_ALLOW;\n");
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+ int cppcast = 1;
+
+ SWIG_library_directory("python");
+
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-interface") == 0) {
+ if (argv[i + 1]) {
+ interface = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ /* end added */
+ } else if (strcmp(argv[i], "-globals") == 0) {
+ if (argv[i + 1]) {
+ global_name = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
+ shadow = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-new_repr") == 0) || (strcmp(argv[i], "-newrepr") == 0)) {
+ new_repr = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-old_repr") == 0) || (strcmp(argv[i], "-oldrepr") == 0)) {
+ new_repr = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-classptr") == 0) {
+ classptr = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-noproxy") == 0)) {
+ shadow = 0;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-noproxyimport") == 0)) {
+ shadowimport = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-keyword") == 0) {
+ use_kw = 1;
+ SWIG_cparse_set_compact_default_args(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-classic") == 0) {
+ classic = 1;
+ modernargs = 0;
+ modern = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-cppcast") == 0) {
+ cppcast = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nocppcast") == 0) {
+ cppcast = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-outputtuple") == 0) {
+ outputtuple = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nooutputtuple") == 0) {
+ outputtuple = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nortti") == 0) {
+ nortti = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-threads") == 0) {
+ threads = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nothreads") == 0) {
+ /* Turn off thread suppor mode */
+ nothreads = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-safecstrings") == 0) {
+ safecstrings = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nosafecstrings") == 0) {
+ safecstrings = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-buildnone") == 0) {
+ buildnone = 1;
+ nobuildnone = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nobuildnone") == 0) {
+ buildnone = 0;
+ nobuildnone = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-dirvtable") == 0) {
+ dirvtable = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nodirvtable") == 0) {
+ dirvtable = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-fastunpack") == 0) {
+ fastunpack = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nofastunpack") == 0) {
+ fastunpack = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-fastproxy") == 0) {
+ fastproxy = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nofastproxy") == 0) {
+ fastproxy = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-fastquery") == 0) {
+ fastquery = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nofastquery") == 0) {
+ fastquery = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-fastinit") == 0) {
+ fastinit = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nofastinit") == 0) {
+ fastinit = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-olddefs") == 0) {
+ olddefs = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noolddefs") == 0) {
+ olddefs = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-castmode") == 0) {
+ castmode = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nocastmode") == 0) {
+ castmode = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-extranative") == 0) {
+ extranative = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noextranative") == 0) {
+ extranative = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-modernargs") == 0) {
+ modernargs = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nomodernargs") == 0) {
+ modernargs = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-aliasobj0") == 0) {
+ aliasobj0 = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noaliasobj0") == 0) {
+ aliasobj0 = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-proxydel") == 0) {
+ proxydel = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noproxydel") == 0) {
+ proxydel = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-modern") == 0) {
+ classic = 0;
+ modern = 1;
+ modernargs = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nomodern") == 0) {
+ modern = 0;
+ modernargs = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noh") == 0) {
+ no_header_file = 1;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-new_vwm") == 0) || (strcmp(argv[i], "-newvwm") == 0)) {
+ /* Turn on new value wrapper mpde */
+ Swig_value_wrapper_mode(1);
+ no_header_file = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-O") == 0) {
+ classic = 0;
+ modern = 1;
+ dirvtable = 1;
+ safecstrings = 0;
+ buildnone = 0;
+ nobuildnone = 1;
+ classptr = 0;
+ proxydel = 0;
+ fastunpack = 1;
+ fastproxy = 1;
+ fastinit = 1;
+ fastquery = 1;
+ modernargs = 1;
+ Wrapper_fast_dispatch_mode_set(1);
+ Wrapper_virtual_elimination_mode_set(1);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-help") == 0) {
+ fputs(usage1, stdout);
+ fputs(usage2, stdout);
+ fputs(usage3, stdout);
+ } else if (strcmp(argv[i], "-py3") == 0) {
+ py3 = 1;
+ Swig_mark_arg(i);
+ }
+
+ }
+ } /* for */
+
+ if (py3) {
+ /* force disable features that not compatible with Python 3.x */
+ classic = 0;
+ }
+
+ if (cppcast) {
+ Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
+ }
+
+ if (!global_name)
+ global_name = NewString("cvar");
+ Preprocessor_define("SWIGPYTHON 1", 0);
+ SWIG_typemap_lang("python");
+ SWIG_config_file("python.swg");
+ allow_overloading();
+ }
+
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+ /* check if directors are enabled for this module. note: this
+ * is a "master" switch, without which no director code will be
+ * emitted. %feature("director") statements are also required
+ * to enable directors for individual classes or methods.
+ *
+ * use %module(directors="1") modulename at the start of the
+ * interface file to enable director generation.
+ */
+ String *mod_docstring = NULL;
+ {
+ Node *mod = Getattr(n, "module");
+ if (mod) {
+ Node *options = Getattr(mod, "options");
+ if (options) {
+ int dirprot = 0;
+ if (Getattr(options, "dirprot")) {
+ dirprot = 1;
+ }
+ if (Getattr(options, "nodirprot")) {
+ dirprot = 0;
+ }
+ if (Getattr(options, "directors")) {
+ allow_directors();
+ if (dirprot)
+ allow_dirprot();
+ }
+ if (Getattr(options, "threads")) {
+ threads = 1;
+ }
+ if (Getattr(options, "castmode")) {
+ castmode = 1;
+ }
+ if (Getattr(options, "nocastmode")) {
+ castmode = 0;
+ }
+ if (Getattr(options, "extranative")) {
+ extranative = 1;
+ }
+ if (Getattr(options, "noextranative")) {
+ extranative = 0;
+ }
+ if (Getattr(options, "outputtuple")) {
+ outputtuple = 1;
+ }
+ if (Getattr(options, "nooutputtuple")) {
+ outputtuple = 0;
+ }
+ mod_docstring = Getattr(options, "docstring");
+ package = Getattr(options, "package");
+ }
+ }
+ }
+
+ /* Set comparison with none for ConstructorToFunction */
+ setSubclassInstanceCheck(NewString("$arg != Py_None"));
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+ String *outfile_h = !no_header_file ? Getattr(n, "outfile_h") : 0;
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+ f_directors_h = NewString("");
+ f_directors = NewString("");
+
+ if (directorsEnabled()) {
+ if (!no_header_file) {
+ f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
+ if (!f_runtime_h) {
+ FileErrorDisplay(outfile_h);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ } else {
+ f_runtime_h = f_runtime;
+ }
+ }
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+ Swig_register_filebyname("director", f_directors);
+ Swig_register_filebyname("director_h", f_directors_h);
+
+ const_code = NewString("");
+ methods = NewString("");
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGPYTHON\n");
+
+ if (directorsEnabled()) {
+ Printf(f_runtime, "#define SWIG_DIRECTORS\n");
+ }
+
+ if (nothreads) {
+ Printf(f_runtime, "#define SWIG_PYTHON_NO_THREADS\n");
+ } else if (threads) {
+ Printf(f_runtime, "#define SWIG_PYTHON_THREADS\n");
+ }
+
+ if (safecstrings) {
+ Printf(f_runtime, "#define SWIG_PYTHON_SAFE_CSTRINGS\n");
+ }
+
+ if (buildnone) {
+ Printf(f_runtime, "#define SWIG_PYTHON_BUILD_NONE\n");
+ }
+
+ if (nobuildnone) {
+ Printf(f_runtime, "#define SWIG_PYTHON_NO_BUILD_NONE\n");
+ }
+
+ if (!dirvtable) {
+ Printf(f_runtime, "#define SWIG_PYTHON_DIRECTOR_NO_VTABLE\n");
+ }
+
+ if (outputtuple) {
+ Printf(f_runtime, "#define SWIG_PYTHON_OUTPUT_TUPLE\n");
+ }
+
+ if (nortti) {
+ Printf(f_runtime, "#ifndef SWIG_DIRECTOR_NORTTI\n");
+ Printf(f_runtime, "#define SWIG_DIRECTOR_NORTTI\n");
+ Printf(f_runtime, "#endif\n");
+ }
+
+ if (castmode) {
+ Printf(f_runtime, "#define SWIG_CASTRANK_MODE\n");
+ Printf(f_runtime, "#define SWIG_PYTHON_CAST_MODE\n");
+ }
+
+ if (extranative) {
+ Printf(f_runtime, "#define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS\n");
+ }
+
+ if (classic) {
+ Printf(f_runtime, "#define SWIG_PYTHON_CLASSIC\n");
+ }
+
+ Printf(f_runtime, "\n");
+
+ Printf(f_header, "#if (PY_VERSION_HEX <= 0x02000000)\n");
+ Printf(f_header, "# if !defined(SWIG_PYTHON_CLASSIC)\n");
+ Printf(f_header, "# error \"This python version requires swig to be run with the '-classic' option\"\n");
+ Printf(f_header, "# endif\n");
+ Printf(f_header, "#endif\n");
+
+ if (modern) {
+ Printf(f_header, "#if (PY_VERSION_HEX <= 0x02020000)\n");
+ Printf(f_header, "# error \"This python version requires swig to be run with the '-nomodern' option\"\n");
+ Printf(f_header, "#endif\n");
+ }
+
+ if (modernargs) {
+ Printf(f_header, "#if (PY_VERSION_HEX <= 0x02020000)\n");
+ Printf(f_header, "# error \"This python version requires swig to be run with the '-nomodernargs' option\"\n");
+ Printf(f_header, "#endif\n");
+ }
+
+ if (fastunpack) {
+ Printf(f_header, "#ifndef METH_O\n");
+ Printf(f_header, "# error \"This python version requires swig to be run with the '-nofastunpack' option\"\n");
+ Printf(f_header, "#endif\n");
+ }
+
+ if (fastquery) {
+ Printf(f_header, "#ifdef SWIG_TypeQuery\n");
+ Printf(f_header, "# undef SWIG_TypeQuery\n");
+ Printf(f_header, "#endif\n");
+ Printf(f_header, "#define SWIG_TypeQuery SWIG_Python_TypeQuery\n");
+ }
+
+
+ /* Set module name */
+ module = Copy(Getattr(n, "name"));
+ mainmodule = Getattr(n, "name");
+
+ if (directorsEnabled()) {
+ Swig_banner(f_directors_h);
+ Printf(f_directors_h, "\n");
+ Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module);
+ Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module);
+ if (dirprot_mode()) {
+ Printf(f_directors_h, "#include <map>\n");
+ Printf(f_directors_h, "#include <string>\n\n");
+ }
+
+ Printf(f_directors, "\n\n");
+ Printf(f_directors, "/* ---------------------------------------------------\n");
+ Printf(f_directors, " * C++ director class methods\n");
+ Printf(f_directors, " * --------------------------------------------------- */\n\n");
+ if (outfile_h)
+ Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h));
+ }
+
+ /* If shadow classing is enabled, we're going to change the module name to "_module" */
+ if (shadow) {
+ String *filen = NewStringf("%s%s.py", SWIG_output_directory(), 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_py = NewFile(filen, "w", SWIG_output_files())) == 0) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(filen);
+ filen = NULL;
+
+ f_shadow = NewString("");
+ f_shadow_imports = NewString("");
+ f_shadow_stubs = NewString("");
+
+ Swig_register_filebyname("shadow", f_shadow);
+ Swig_register_filebyname("python", f_shadow);
+
+ Swig_banner_target_lang(f_shadow, "#");
+
+ if (!modern) {
+ Printv(f_shadow, "# This file is compatible with both classic and new-style classes.\n", NIL);
+ }
+
+ if (mod_docstring && Len(mod_docstring)) {
+ Printv(f_shadow, "\n\"\"\"\n", mod_docstring, "\n\"\"\"\n", NIL);
+ Delete(mod_docstring);
+ mod_docstring = NULL;
+ }
+
+ Printv(f_shadow, "\nfrom sys import version_info\n", NULL);
+
+ if(fastproxy)
+ {
+ Printv(f_shadow, "if version_info >= (3,0,0):\n", NULL);
+ Printf(f_shadow, tab4 "new_instancemethod = lambda func, inst, cls: %s.SWIG_PyInstanceMethod_New(func)\n", module);
+ Printv(f_shadow, "else:\n", NULL);
+ Printv(f_shadow, tab4, "from new import instancemethod as new_instancemethod\n", NULL);
+ }
+ /* Import the C-extension module. This should be a relative import,
+ * since the shadow module may also have been imported by a relative
+ * import, and there is thus no guarantee that the C-extension is on
+ * sys.path. Relative imports must be explicitly specified from 2.6.0
+ * onwards (implicit relative imports will raise a DeprecationWarning
+ * in 2.6, and fail in 2.7 onwards), but the relative import syntax
+ * isn't available in python 2.4 or earlier, so we have to write some
+ * code conditional on the python version.
+ */
+ Printv(f_shadow, "if version_info >= (2,6,0):\n", NULL);
+ Printv(f_shadow, tab4, "def swig_import_helper():\n", NULL);
+ Printv(f_shadow, tab8, "from os.path import dirname\n", NULL);
+ Printv(f_shadow, tab8, "import imp\n", NULL);
+ Printv(f_shadow, tab8, "fp = None\n", NULL);
+ Printv(f_shadow, tab8, "try:\n", NULL);
+ Printf(f_shadow, tab4 tab8 "fp, pathname, description = imp.find_module('%s', [dirname(__file__)])\n", module);
+ Printf(f_shadow, tab8 "except ImportError:\n");
+ /* At here, the module may already loaded, so simply import it. */
+ Printf(f_shadow, tab4 tab8 "import %s\n", module);
+ Printf(f_shadow, tab4 tab8 "return %s\n", module);
+ Printv(f_shadow, tab8 "if fp is not None:\n", NULL);
+ Printv(f_shadow, tab4 tab8 "try:\n", NULL);
+ Printf(f_shadow, tab8 tab8 "_mod = imp.load_module('%s', fp, pathname, description)\n", module);
+ Printv(f_shadow, tab4 tab8, "finally:\n", NULL);
+ Printv(f_shadow, tab8 tab8, "fp.close()\n", NULL);
+ Printv(f_shadow, tab4 tab8, "return _mod\n", NULL);
+ Printf(f_shadow, tab4 "%s = swig_import_helper()\n", module);
+ Printv(f_shadow, tab4, "del swig_import_helper\n", NULL);
+ Printv(f_shadow, "else:\n", NULL);
+ Printf(f_shadow, tab4 "import %s\n", module);
+
+ /* Delete the version_info symbol since we don't use it elsewhere in the
+ * module. */
+ Printv(f_shadow, "del version_info\n", NULL);
+
+ if (modern || !classic) {
+ Printv(f_shadow, "try:\n", tab4, "_swig_property = property\n", "except NameError:\n", tab4, "pass # Python < 2.2 doesn't have 'property'.\n", NULL);
+ }
+ /* if (!modern) */
+ /* always needed, a class can be forced to be no-modern, such as an exception */
+ {
+ // Python-2.2 object hack
+ Printv(f_shadow,
+ "def _swig_setattr_nondynamic(self,class_type,name,value,static=1):\n",
+ tab4, "if (name == \"thisown\"): return self.this.own(value)\n",
+ tab4, "if (name == \"this\"):\n", tab4, tab4, "if type(value).__name__ == 'SwigPyObject':\n", tab4, tab8, "self.__dict__[name] = value\n",
+#ifdef USE_THISOWN
+ tab4, tab8, "if hasattr(value,\"thisown\"): self.__dict__[\"thisown\"] = value.thisown\n", tab4, tab8, "del value.thisown\n",
+#endif
+ tab4, tab8, "return\n", tab4, "method = class_type.__swig_setmethods__.get(name,None)\n", tab4, "if method: return method(self,value)\n",
+#ifdef USE_THISOWN
+ tab4, "if (not static) or hasattr(self,name) or (name == \"thisown\"):\n",
+#else
+ tab4, "if (not static) or hasattr(self,name):\n",
+#endif
+ tab4, tab4, "self.__dict__[name] = value\n",
+ tab4, "else:\n",
+ tab4, tab4, "raise AttributeError(\"You cannot add attributes to %s\" % self)\n\n",
+ "def _swig_setattr(self,class_type,name,value):\n", tab4, "return _swig_setattr_nondynamic(self,class_type,name,value,0)\n\n", NIL);
+
+ Printv(f_shadow,
+ "def _swig_getattr(self,class_type,name):\n",
+ tab4, "if (name == \"thisown\"): return self.this.own()\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);
+
+ Printv(f_shadow,
+ "def _swig_repr(self):\n",
+ tab4, "try: strthis = \"proxy of \" + self.this.__repr__()\n",
+ tab4, "except: strthis = \"\"\n", tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
+
+ if (!classic) {
+ /* Usage of types.ObjectType is deprecated.
+ * But don't sure wether this would broken old Python?
+ */
+ Printv(f_shadow,
+// "import types\n",
+ "try:\n",
+// " _object = types.ObjectType\n",
+ " _object = object\n",
+ " _newclass = 1\n", "except AttributeError:\n", " class _object : pass\n", " _newclass = 0\n",
+// "del types\n",
+ "\n\n", NIL);
+ }
+ }
+ if (modern) {
+ Printv(f_shadow, "def _swig_setattr_nondynamic_method(set):\n", tab4, "def set_attr(self,name,value):\n",
+#ifdef USE_THISOWN
+ tab4, tab4, "if hasattr(self,name) or (name in (\"this\", \"thisown\")):\n",
+#else
+ tab4, tab4, "if (name == \"thisown\"): return self.this.own(value)\n", tab4, tab4, "if hasattr(self,name) or (name == \"this\"):\n",
+#endif
+ tab4, tab4, tab4, "set(self,name,value)\n",
+ tab4, tab4, "else:\n",
+ tab4, tab4, tab4, "raise AttributeError(\"You cannot add attributes to %s\" % self)\n", tab4, "return set_attr\n\n\n", NIL);
+ }
+
+ if (directorsEnabled()) {
+ // Try loading weakref.proxy, which is only available in Python 2.1 and higher
+ Printv(f_shadow,
+ "try:\n", tab4, "import weakref\n", tab4, "weakref_proxy = weakref.proxy\n", "except:\n", tab4, "weakref_proxy = lambda x: x\n", "\n\n", NIL);
+ }
+ // Include some information in the code
+ Printf(f_header, "\n/*-----------------------------------------------\n @(target):= %s.so\n\
+ ------------------------------------------------*/\n", module);
+
+ }
+
+ Printf(f_header, "#if PY_VERSION_HEX >= 0x03000000\n");
+ Printf(f_header, "# define SWIG_init PyInit_%s\n\n", module);
+ Printf(f_header, "#else\n");
+ Printf(f_header, "# define SWIG_init init%s\n\n", module);
+ Printf(f_header, "#endif\n");
+ Printf(f_header, "#define SWIG_name \"%s\"\n", module);
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n");
+ Printf(f_wrappers, "extern \"C\" {\n");
+ Printf(f_wrappers, "#endif\n");
+ Append(const_code, "static swig_const_info swig_const_table[] = {\n");
+ Append(methods, "static PyMethodDef SwigMethods[] = {\n");
+
+ /* the method exported for replacement of new.instancemethod in Python 3 */
+ add_pyinstancemethod_new();
+
+ /* emit code */
+ Language::top(n);
+
+ if (directorsEnabled()) {
+ // Insert director runtime into the f_runtime file (make it occur before %header section)
+ Swig_insert_file("director.swg", f_runtime);
+ }
+
+ /* Close language module */
+ Append(methods, "\t { NULL, NULL, 0, NULL }\n");
+ Append(methods, "};\n");
+ Printf(f_wrappers, "%s\n", methods);
+
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+
+ Append(const_code, "{0, 0, 0, 0.0, 0, 0}};\n");
+ Printf(f_wrappers, "%s\n", const_code);
+ initialize_threads(f_init);
+
+ Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n");
+ Printf(f_init, " return m;\n");
+ Printf(f_init, "#else\n");
+ Printf(f_init, " return;\n");
+ Printf(f_init, "#endif\n");
+ Printf(f_init, "}\n");
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n");
+ Printf(f_wrappers, "}\n");
+ Printf(f_wrappers, "#endif\n");
+
+ if (shadow) {
+ Printv(f_shadow_py, f_shadow, "\n", NIL);
+ Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
+
+ Close(f_shadow_py);
+ Delete(f_shadow_py);
+ }
+
+ /* Close all of the files */
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+
+ if (directorsEnabled()) {
+ Dump(f_directors_h, f_runtime_h);
+ Printf(f_runtime_h, "\n");
+ Printf(f_runtime_h, "#endif\n");
+ if (f_runtime_h != f_begin)
+ Close(f_runtime_h);
+ Dump(f_directors, f_begin);
+ }
+
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Delete(f_directors);
+ Delete(f_directors_h);
+
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * Emit the wrapper for PyInstanceMethod_New to MethodDef array.
+ * This wrapper is used to implement -fastproxy,
+ * as a replacement of new.instancemethod in Python 3.
+ * ------------------------------------------------------------ */
+ int add_pyinstancemethod_new()
+ {
+ String* name = NewString("SWIG_PyInstanceMethod_New");
+ Printf(methods, "\t { (char *)\"%s\", (PyCFunction)%s, METH_O, NULL},\n", name, name);
+ Delete(name);
+ return 0;
+ }
+
+ /* ------------------------------------------------------------
+ * importDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int importDirective(Node *n) {
+ if (shadow) {
+ String *modname = Getattr(n, "module");
+
+ if (modname) {
+ String *import = NewString("import ");
+
+ // Find the module node for this imported module. It should be the
+ // first child but search just in case.
+ Node *mod = firstChild(n);
+ while (mod && Strcmp(nodeType(mod), "module") != 0)
+ mod = nextSibling(mod);
+
+ // Is the imported module in another package? (IOW, does it use the
+ // %module(package="name") option and it's different than the package
+ // of this module.)
+ Node *options = Getattr(mod, "options");
+ String *pkg = options ? Getattr(options, "package") : 0;
+ if (pkg && (!package || Strcmp(pkg, package) != 0)) {
+ Printf(import, "%s.", pkg);
+ }
+ // finally, output the name of the imported module
+ if (shadowimport) {
+ if (!options || (!Getattr(options, "noshadow") && !Getattr(options, "noproxy"))) {
+ Printf(import, "_%s\n", modname);
+ if (!Strstr(f_shadow_imports, import)) {
+ if (pkg && (!package || Strcmp(pkg, package) != 0)) {
+ Printf(f_shadow, "import %s.%s\n", pkg, modname);
+ } else {
+ Printf(f_shadow, "import %s\n", modname);
+ }
+ Printv(f_shadow_imports, import, NULL);
+ }
+ }
+ }
+
+ Delete(import);
+ }
+ }
+ return Language::importDirective(n);
+ }
+
+ /* ------------------------------------------------------------
+ * funcCall()
+ * Emit shadow code to call a function in the extension
+ * module. Using proper argument and calling style for
+ * given node n.
+ * ------------------------------------------------------------ */
+ String *funcCall(String *name, String *parms) {
+ String *str = NewString("");
+
+ Printv(str, module, ".", name, "(", parms, ")", NIL);
+ return str;
+ }
+
+
+ /* ------------------------------------------------------------
+ * pythoncode() - Output python code into the shadow file
+ * ------------------------------------------------------------ */
+
+ String *pythoncode(String *code, const_String_or_char_ptr indent) {
+ String *out = NewString("");
+ String *temp;
+ char *t;
+ if (!indent)
+ indent = "";
+
+ temp = NewString(code);
+
+ t = Char(temp);
+ if (*t == '{') {
+ Delitem(temp, 0);
+ Delitem(temp, DOH_END);
+ }
+
+ /* Split the input text into lines */
+ List *clist = DohSplitLines(temp);
+ Delete(temp);
+ int initial = 0;
+ String *s = 0;
+ Iterator si;
+ /* Get the initial indentation */
+
+ for (si = First(clist); si.item; si = Next(si)) {
+ s = si.item;
+ if (Len(s)) {
+ char *c = Char(s);
+ while (*c) {
+ if (!isspace(*c))
+ break;
+ initial++;
+ c++;
+ }
+ if (*c && !isspace(*c))
+ break;
+ else {
+ initial = 0;
+ }
+ }
+ }
+ while (si.item) {
+ s = si.item;
+ if (Len(s) > initial) {
+ char *c = Char(s);
+ c += initial;
+ Printv(out, indent, c, "\n", NIL);
+ } else {
+ Printv(out, "\n", NIL);
+ }
+ si = Next(si);
+ }
+ Delete(clist);
+ return out;
+ }
+
+
+ /* ------------------------------------------------------------
+ * autodoc level declarations
+ * ------------------------------------------------------------ */
+
+ enum autodoc_l {
+ NO_AUTODOC = -2, // no autodoc
+ STRING_AUTODOC = -1, // use provided string
+ NAMES_AUTODOC = 0, // only parameter names
+ TYPES_AUTODOC = 1, // parameter names and types
+ EXTEND_AUTODOC = 2, // extended documentation and parameter names
+ EXTEND_TYPES_AUTODOC = 3 // extended documentation and parameter types + names
+ };
+
+
+ autodoc_l autodoc_level(String *autodoc) {
+ autodoc_l dlevel = NO_AUTODOC;
+ if (autodoc) {
+ char *c = Char(autodoc);
+ if (c && isdigit(c[0])) {
+ dlevel = (autodoc_l) atoi(c);
+ } else {
+ if (strcmp(c, "extended") == 0) {
+ dlevel = EXTEND_AUTODOC;
+ } else {
+ dlevel = STRING_AUTODOC;
+ }
+ }
+ }
+ return dlevel;
+ }
+
+
+ /* ------------------------------------------------------------
+ * have_docstring()
+ * Check if there is a docstring directive and it has text,
+ * or there is an autodoc flag set
+ * ------------------------------------------------------------ */
+
+ bool have_docstring(Node *n) {
+ String *str = Getattr(n, "feature:docstring");
+ return (str != NULL && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
+ }
+
+ /* ------------------------------------------------------------
+ * docstring()
+ * Get the docstring text, stripping off {} if neccessary,
+ * and enclose in triple double quotes. If autodoc is also
+ * set then it will build a combined docstring.
+ * ------------------------------------------------------------ */
+
+ String *docstring(Node *n, autodoc_t ad_type, const String *indent, bool use_triple = true) {
+ String *str = Getattr(n, "feature:docstring");
+ bool have_ds = (str != NULL && Len(str) > 0);
+ bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
+ const char *triple_double = use_triple ? "\"\"\"" : "";
+ String *autodoc = NULL;
+ String *doc = NULL;
+
+ if (have_ds) {
+ char *t = Char(str);
+ if (*t == '{') {
+ Delitem(str, 0);
+ Delitem(str, DOH_END);
+ }
+ }
+
+ if (have_auto) {
+ autodoc = make_autodoc(n, ad_type);
+ have_auto = (autodoc != NULL && Len(autodoc) > 0);
+ }
+ // If there is more than one line then make docstrings like this:
+ //
+ // """
+ // This is line1
+ // And here is line2 followed by the rest of them
+ // """
+ //
+ // otherwise, put it all on a single line
+ //
+ if (have_auto && have_ds) { // Both autodoc and docstring are present
+ doc = NewString("");
+ Printv(doc, triple_double, "\n", pythoncode(autodoc, indent), "\n", pythoncode(str, indent), indent, triple_double, NIL);
+ } else if (!have_auto && have_ds) { // only docstring
+ if (Strchr(str, '\n') == NULL) {
+ doc = NewStringf("%s%s%s", triple_double, str, triple_double);
+ } else {
+ doc = NewString("");
+ Printv(doc, triple_double, "\n", pythoncode(str, indent), indent, triple_double, NIL);
+ }
+ } else if (have_auto && !have_ds) { // only autodoc
+ if (Strchr(autodoc, '\n') == NULL) {
+ doc = NewStringf("%s%s%s", triple_double, autodoc, triple_double);
+ } else {
+ doc = NewString("");
+ Printv(doc, triple_double, "\n", pythoncode(autodoc, indent), indent, triple_double, NIL);
+ }
+ } else
+ doc = NewString("");
+
+ // Save the generated strings in the parse tree in case they are used later
+ // by post processing tools
+ Setattr(n, "python:docstring", doc);
+ Setattr(n, "python:autodoc", autodoc);
+ return doc;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * makeParameterName()
+ * Note: the generated name should consist with that in kwnames[]
+ *
+ * Inputs:
+ * n - Node
+ * p - parameter node
+ * arg_num - parameter argument number
+ * Return:
+ * arg - a unique parameter name
+ * ----------------------------------------------------------------------------- */
+
+ String *makeParameterName(ParmList *plist, Parm *p, int arg_num) {
+ String *arg = 0;
+ String *pn = Swig_name_make(p, 0, Getattr(p, "name"), 0, 0);
+ // Use C parameter name unless it is a duplicate or an empty parameter name
+ int count = 0;
+ if ( SwigType_isvarargs(Getattr(p, "type")) ) {
+ return NewString("*args");
+ }
+ while (plist) {
+ if ((Cmp(pn, Getattr(plist, "name")) == 0))
+ count++;
+ plist = nextSibling(plist);
+ }
+ arg = (!pn || !Len(pn) || (count > 1)) ? NewStringf("arg%d", arg_num) : Copy(pn);
+ return arg;
+ }
+
+
+ /* ------------------------------------------------------------
+ * make_autodocParmList()
+ * Generate the documentation for the function parameters
+ * Parameters:
+ * func_annotation: Function annotation support
+ * ------------------------------------------------------------ */
+
+ String *make_autodocParmList(Node *n, bool showTypes, bool calling=false, bool func_annotation=false) {
+
+
+ String *doc = NewString("");
+ String *pdocs = Copy(Getattr(n, "feature:pdocs"));
+ ParmList *plist = CopyParmList(Getattr(n, "parms"));
+ Parm *p;
+ Parm *pnext;
+ Node *lookup;
+
+
+ int lines = 0;
+ int arg_num = 0;
+ const int maxwidth = 50;
+
+ if(calling)
+ func_annotation = false;
+
+ if (pdocs)
+ Append(pdocs, "\n");
+
+ Swig_typemap_attach_parms("in", plist, 0);
+ Swig_typemap_attach_parms("doc", plist, 0);
+
+ if (Strcmp(ParmList_protostr(plist), "void")==0) {
+ //No parameters actually
+ return doc;
+ }
+
+ for (p = plist; p; p = pnext) {
+
+ String *tm = Getattr(p, "tmap:in");
+ if (tm) {
+ pnext = Getattr(p, "tmap:in:next");
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ continue;
+ }
+ } else {
+ pnext = nextSibling(p);
+ }
+
+ String *name = 0;
+ String *type = 0;
+ String *value = 0;
+ String *ptype = 0;
+ String *pdoc = Getattr(p, "tmap:doc");
+ if (pdoc) {
+ name = Getattr(p, "tmap:doc:name");
+ type = Getattr(p, "tmap:doc:type");
+ value = Getattr(p, "tmap:doc:value");
+ ptype = Getattr(p, "tmap:doc:pytype");
+ }
+
+ name = name ? name : Getattr(p, "name");
+ type = type ? type : Getattr(p, "type");
+ value = value ? value : Getattr(p, "value");
+
+ name = makeParameterName(plist, p, arg_num);
+ // Reset it for convinient in further use. (mainly for makeParameterName())
+ // Since the plist is created by CopyParmList,
+ // we can hope that the set would have no side effect
+ Setattr(p, "name", name);
+
+ arg_num++;
+
+
+ if (Len(doc)) {
+ // add a comma to the previous one if any
+ Append(doc, ", ");
+
+ // Do we need to wrap a long line?
+ if ((Len(doc) - lines * maxwidth) > maxwidth) {
+ Printf(doc, "\n%s", tab4);
+ lines += 1;
+ }
+ }
+
+ type = SwigType_base(type);
+ lookup = Swig_symbol_clookup(type, 0);
+ if (lookup)
+ type = Getattr(lookup, "sym:name");
+
+ // Do the param type too?
+ if (showTypes)
+ Printf(doc, "%s ", type);
+
+
+ Append(doc, name);
+ if (pdoc) {
+ if (!pdocs)
+ pdocs = NewString("Parameters:\n");
+ Printf(pdocs, " %s\n", pdoc);
+ }
+
+ // Write the function annoation
+ if (func_annotation)
+ Printf(doc, " : '%s'", type);
+
+ // Write default value
+ if (value && !calling) {
+ String* pv = pyvalue(value, Getattr(p, "type"));
+ if (pv)
+ value = pv;
+ else {
+ lookup = Swig_symbol_clookup(value, 0);
+ if (lookup) {
+ value = Getattr(lookup, "sym:name");
+ }
+ }
+ Printf(doc, " = %s", value);
+ }
+ }
+ if (pdocs)
+ Setattr(n, "feature:pdocs", pdocs);
+ Delete(plist);
+ return doc;
+ }
+
+ /* ------------------------------------------------------------
+ * make_autodoc()
+ * Build a docstring for the node, using parameter and other
+ * info in the parse tree. If the value of the autodoc
+ * attribute is "0" then do not include parameter types, if
+ * it is "1" (the default) then do. If it has some other
+ * value then assume it is supplied by the extension writer
+ * and use it directly.
+ * ------------------------------------------------------------ */
+
+ String *make_autodoc(Node *n, autodoc_t ad_type) {
+ int extended = 0;
+ // If the function is overloaded then this funciton is called
+ // for the last one. Rewind to the first so the docstrings are
+ // in order.
+ while (Getattr(n, "sym:previousSibling"))
+ n = Getattr(n, "sym:previousSibling");
+
+ String *doc = NewString("");
+ while (n) {
+ bool showTypes = false;
+ bool skipAuto = false;
+ String *autodoc = Getattr(n, "feature:autodoc");
+ autodoc_l dlevel = autodoc_level(autodoc);
+ switch (dlevel) {
+ case NO_AUTODOC:
+ break;
+ case NAMES_AUTODOC:
+ showTypes = false;
+ break;
+ case TYPES_AUTODOC:
+ showTypes = true;
+ break;
+ case EXTEND_AUTODOC:
+ extended = 1;
+ showTypes = false;
+ break;
+ case EXTEND_TYPES_AUTODOC:
+ extended = 1;
+ showTypes = true;
+ break;
+ case STRING_AUTODOC:
+ Append(doc, autodoc);
+ skipAuto = true;
+ break;
+ }
+
+ if (!skipAuto) {
+ String *symname = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+
+ if (type) {
+ if (Strcmp(type, "void") == 0)
+ type = NULL;
+ else {
+ type = SwigType_base(type);
+ Node *lookup = Swig_symbol_clookup(type, 0);
+ if (lookup)
+ type = Getattr(lookup, "sym:name");
+ }
+ }
+
+ switch (ad_type) {
+ case AUTODOC_CLASS:
+ {
+ // Only do the autodoc if there isn't a docstring for the class
+ String *str = Getattr(n, "feature:docstring");
+ if (str == NULL || Len(str) == 0) {
+ if (CPlusPlus) {
+ Printf(doc, "Proxy of C++ %s class", real_classname);
+ } else {
+ Printf(doc, "Proxy of C %s struct", real_classname);
+ }
+ }
+ }
+ break;
+ case AUTODOC_CTOR:
+ if (Strcmp(class_name, symname) == 0) {
+ String *paramList = make_autodocParmList(n, showTypes);
+ if (Len(paramList))
+ Printf(doc, "__init__(self, %s) -> %s", paramList, class_name);
+ else
+ Printf(doc, "__init__(self) -> %s", class_name);
+ } else
+ Printf(doc, "%s(%s) -> %s", symname, make_autodocParmList(n, showTypes), class_name);
+ break;
+
+ case AUTODOC_DTOR:
+ Append(doc, "__del__(self)");
+ break;
+
+ case AUTODOC_STATICFUNC:
+ Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes));
+ if (type)
+ Printf(doc, " -> %s", type);
+ break;
+
+ case AUTODOC_FUNC:
+ Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes));
+ if (type)
+ Printf(doc, " -> %s", type);
+ break;
+
+ case AUTODOC_METHOD:
+ String *paramList = make_autodocParmList(n, showTypes);
+ if (Len(paramList))
+ Printf(doc, "%s(self, %s)", symname, paramList);
+ else
+ Printf(doc, "%s(self)", symname);
+ if (type)
+ Printf(doc, " -> %s", type);
+ break;
+ }
+ }
+ if (extended) {
+ String *pdocs = Getattr(n, "feature:pdocs");
+ if (pdocs) {
+ Printv(doc, "\n", pdocs, NULL);
+ }
+ }
+
+ // if it's overloaded then get the next decl and loop around again
+ n = Getattr(n, "sym:nextSibling");
+ if (n)
+ Append(doc, "\n");
+ }
+
+ return doc;
+ }
+
+ /* ------------------------------------------------------------
+ * pyvalue()
+ * Check if string v can be a Python value literal,
+ * (eg. number or string), or translate it to a Python literal.
+ * ------------------------------------------------------------ */
+ String* pyvalue(String *v, SwigType *t)
+ {
+ if (v && Len(v)>0) {
+ char fc = (Char(v))[0];
+ if (('0'<=fc && fc<='9') || '\''==fc || '"'==fc) {
+ /* number or string (or maybe NULL pointer)*/
+ if (SwigType_ispointer(t) && Strcmp(v, "0")==0)
+ return NewString("None");
+ else
+ return v;
+ }
+ if (Strcmp(v, "true")==0 || Strcmp(v, "FALSE")==0)
+ return NewString("True");
+ if (Strcmp(v, "false")==0 || Strcmp(v, "FALSE")==0)
+ return NewString("False");
+ if (Strcmp(v, "NULL")==0)
+ return NewString("None");
+ }
+ return 0;
+ }
+ /* ------------------------------------------------------------
+ * is_primitive_defaultargs()
+ * Check if all the default args have primitive type.
+ * (So we can generate proper parameter list with default
+ * values..)
+ * ------------------------------------------------------------ */
+ bool is_primitive_defaultargs(Node *n)
+ {
+ ParmList *plist = CopyParmList(Getattr(n, "parms"));
+ Parm *p;
+ Parm *pnext;
+
+ Swig_typemap_attach_parms("in", plist, 0);
+ for (p = plist; p; p = pnext) {
+ String *tm = Getattr(p, "tmap:in");
+ if (tm) {
+ pnext = Getattr(p, "tmap:in:next");
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ continue;
+ }
+ } else {
+ pnext = nextSibling(p);
+ }
+ String *type = Getattr(p, "type");
+ String *value = Getattr(p, "value");
+ if (!pyvalue(value, type))
+ return false;
+ }
+ return true;
+ }
+
+
+ /* ------------------------------------------------------------
+ * is_real_overloaded()
+ * Check if the function is overloaded, but not just have some
+ * siblings generated due to the original function have
+ * default arguments.
+ * ------------------------------------------------------------ */
+ bool is_real_overloaded(Node *n)
+ {
+ Node *h = Getattr(n, "sym:overloaded");
+ Node *i;
+ if (!h)
+ return false;
+
+ i = Getattr(h, "sym:nextSibling");
+ while (i) {
+ Node *nn = Getattr(i, "defaultargs");
+ if (nn != h) {
+ /* Check if overloaded function has defaultargs and
+ * pointed to the first overloaded. */
+ return true;
+ }
+ i = Getattr(i, "sym:nextSibling");
+ }
+
+ return false;
+ }
+
+ /* ------------------------------------------------------------
+ * make_pyParmList()
+ * Generate parameter list for Python functions or methods,
+ * reuse make_autodocParmList() to do so.
+ * ------------------------------------------------------------ */
+ String* make_pyParmList(Node *n, bool in_class, bool is_calling, int kw)
+ {
+ /* Get the original function for a defaultargs copy,
+ * see default_arguments() in parser.y. */
+ Node *nn = Getattr(n, "defaultargs");
+ if (nn) n = nn;
+
+ /* For overloaded function, just use *args */
+ if (is_real_overloaded(n) ||
+ GetFlag(n, "feature:compactdefaultargs") ||
+ !is_primitive_defaultargs(n))
+ {
+ String *parms = NewString("");
+ if(in_class)
+ Printf(parms, "self, ");
+ Printf(parms, "*args");
+ if (kw)
+ Printf(parms, ", **kwargs");
+ return parms;
+ }
+
+ bool funcanno = py3 ? true : false;
+ String *params = NewString("");
+ String *_params = make_autodocParmList(n, false, is_calling, funcanno);
+
+ if (in_class)
+ {
+ Printf(params, "self");
+ if(Len(_params) > 0)
+ Printf(params, ", ");
+ }
+
+ Printv(params, _params, NULL);
+
+ return params;
+ }
+
+ /* ------------------------------------------------------------
+ * have_pythonprepend()
+ * Check if there is a %pythonprepend directive and it has text
+ * ------------------------------------------------------------ */
+
+ bool have_pythonprepend(Node *n) {
+ String *str = Getattr(n, "feature:pythonprepend");
+ return (str != NULL && Len(str) > 0);
+ }
+
+ /* ------------------------------------------------------------
+ * pythonprepend()
+ * Get the %pythonprepend code, stripping off {} if neccessary
+ * ------------------------------------------------------------ */
+
+ String *pythonprepend(Node *n) {
+ String *str = Getattr(n, "feature:pythonprepend");
+ char *t = Char(str);
+ if (*t == '{') {
+ Delitem(str, 0);
+ Delitem(str, DOH_END);
+ }
+ return str;
+ }
+
+ /* ------------------------------------------------------------
+ * have_pythonappend()
+ * Check if there is a %pythonappend directive and it has text
+ * ------------------------------------------------------------ */
+
+ bool have_pythonappend(Node *n) {
+ String *str = Getattr(n, "feature:pythonappend");
+ if (!str)
+ str = Getattr(n, "feature:addtofunc");
+ return (str != NULL && Len(str) > 0);
+ }
+
+ /* ------------------------------------------------------------
+ * pythonappend()
+ * Get the %pythonappend code, stripping off {} if neccessary
+ * ------------------------------------------------------------ */
+
+ String *pythonappend(Node *n) {
+ String *str = Getattr(n, "feature:pythonappend");
+ if (!str)
+ str = Getattr(n, "feature:addtofunc");
+
+ char *t = Char(str);
+ if (*t == '{') {
+ Delitem(str, 0);
+ Delitem(str, DOH_END);
+ }
+ return str;
+ }
+
+ /* ------------------------------------------------------------
+ * have_addtofunc()
+ * Check if there is a %addtofunc directive and it has text
+ * ------------------------------------------------------------ */
+
+ bool have_addtofunc(Node *n) {
+ return have_pythonappend(n) || have_pythonprepend(n) || have_docstring(n);
+ }
+
+
+ /* ------------------------------------------------------------
+ * returnTypeAnnotation()
+ * Helper function for constructing the function annotation
+ * of the returning type, return a empty string for Python 2.x
+ * ------------------------------------------------------------ */
+ String* returnTypeAnnotation(Node *n)
+ {
+ String *ret=0;
+ Parm *p = Getattr(n, "parms");
+ String *tm;
+ /* Try to guess the returning type by argout typemap,
+ * however the result may not accurate. */
+ while (p) {
+ if ((tm=Getattr(p, "tmap:argout:match_type"))) {
+ tm = SwigType_str(tm, 0);
+ if (ret)
+ Printv(ret, ", ", tm, NULL);
+ else
+ ret = tm;
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ /* If no argout typemap, then get the returning type from
+ * the function prototype. */
+ if (!ret) {
+ ret = Getattr(n, "type");
+ if (ret) ret = SwigType_str(ret, 0);
+ }
+ return (ret && py3) ? NewStringf(" -> \"%s\" ", ret)
+ : NewString("");
+ }
+
+ /* ------------------------------------------------------------
+ * emitFunctionShadowHelper()
+ * Refactoring some common code out of functionWrapper and
+ * dispatchFunction that writes the proxy code for non-member
+ * functions.
+ * ------------------------------------------------------------ */
+
+ void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) {
+ String *parms = make_pyParmList(n, false, false, kw);
+ String *callParms = make_pyParmList(n, false, true, kw);
+ /* Make a wrapper function to insert the code into */
+ Printv(f_dest, "\ndef ", name, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
+ if (have_docstring(n))
+ Printv(f_dest, " ", docstring(n, AUTODOC_FUNC, tab4), "\n", NIL);
+ if (have_pythonprepend(n))
+ Printv(f_dest, pythoncode(pythonprepend(n), " "), "\n", NIL);
+ if (have_pythonappend(n)) {
+ Printv(f_dest, " val = ", funcCall(name, callParms), "\n", NIL);
+ Printv(f_dest, pythoncode(pythonappend(n), " "), "\n", NIL);
+ Printv(f_dest, " return val\n", NIL);
+ } else {
+ Printv(f_dest, " return ", funcCall(name, callParms), "\n", NIL);
+ }
+
+ if (Getattr(n, "feature:python:callback") || !have_addtofunc(n)) {
+ /* If there is no addtofunc directive then just assign from the extension module (for speed up) */
+ Printv(f_dest, name, " = ", module, ".", name, "\n", NIL);
+ }
+ }
+
+
+ /* ------------------------------------------------------------
+ * check_kwargs()
+ * check if using kwargs is allowed for this Node
+ * ------------------------------------------------------------ */
+
+ int check_kwargs(Node *n) {
+ return (use_kw || GetFlag(n, "feature:kwargs"))
+ && !GetFlag(n, "memberset") && !GetFlag(n, "memberget");
+ }
+
+
+
+ /* ------------------------------------------------------------
+ * add_method()
+ * ------------------------------------------------------------ */
+
+ void add_method(String *name, String *function, int kw, Node *n = 0, int funpack = 0, int num_required = -1, int num_arguments = -1) {
+ if (!kw) {
+ if (n && funpack) {
+ if (num_required == 0 && num_arguments == 0) {
+ Printf(methods, "\t { (char *)\"%s\", (PyCFunction)%s, METH_NOARGS, ", name, function);
+ } else if (num_required == 1 && num_arguments == 1) {
+ Printf(methods, "\t { (char *)\"%s\", (PyCFunction)%s, METH_O, ", name, function);
+ } else {
+ Printf(methods, "\t { (char *)\"%s\", %s, METH_VARARGS, ", name, function);
+ }
+ } else {
+ Printf(methods, "\t { (char *)\"%s\", %s, METH_VARARGS, ", name, function);
+ }
+ } else {
+ Printf(methods, "\t { (char *)\"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS, ", name, function);
+ }
+
+ if (!n) {
+ Append(methods, "NULL");
+ } else if (Getattr(n, "feature:callback")) {
+ if (have_docstring(n)) {
+ String *ds = docstring(n, AUTODOC_FUNC, "", false);
+ Replaceall(ds, "\\", "\\\\");
+ Replaceall(ds, "\"", "\\\"");
+ Replaceall(ds, "\n", "\\n\"\n\t\t\"");
+ Printf(methods, "(char *)\"%s\\nswig_ptr: %s\"", ds, Getattr(n, "feature:callback:name"));
+ } else {
+ Printf(methods, "(char *)\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
+ }
+ } else if (have_docstring(n)) {
+ String *ds = docstring(n, AUTODOC_FUNC, "", false);
+ Replaceall(ds, "\\", "\\\\");
+ Replaceall(ds, "\"", "\\\"");
+ Replaceall(ds, "\n", "\\n\"\n\t\t\"");
+ Printf(methods, "(char *)\"%s\"", ds);
+ } else {
+ Append(methods, "NULL");
+ }
+
+ Append(methods, "},\n");
+ }
+
+ /* ------------------------------------------------------------
+ * dispatchFunction()
+ * ------------------------------------------------------------ */
+ void dispatchFunction(Node *n, int funpack = 0) {
+ /* Last node in overloaded chain */
+
+ int maxargs;
+
+ String *tmp = NewString("");
+ String *dispatch;
+ const char *dispatch_code = funpack ? "return %s(self, argc, argv);" : "return %s(self, args);";
+
+ if (castmode) {
+ dispatch = Swig_overload_dispatch_cast(n, dispatch_code, &maxargs);
+ } else {
+ dispatch = Swig_overload_dispatch(n, dispatch_code, &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, "SWIGINTERN 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);
+
+ if (!fastunpack) {
+ Wrapper_add_local(f, "ii", "int ii");
+ Append(f->code, "if (!PyTuple_Check(args)) SWIG_fail;\n");
+ Append(f->code, "argc = (int)PyObject_Length(args);\n");
+ Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n", maxargs);
+ Append(f->code, "argv[ii] = PyTuple_GET_ITEM(args,ii);\n");
+ Append(f->code, "}\n");
+ } else {
+ String *iname = Getattr(n, "sym:name");
+ Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args,\"%s\",0,%d,argv))) SWIG_fail;\n", iname, maxargs);
+ Append(f->code, "--argc;\n");
+ }
+
+ Replaceall(dispatch, "$args", "self,args");
+
+ Printv(f->code, dispatch, "\n", NIL);
+
+ if (GetFlag(n, "feature:python:maybecall")) {
+ Append(f->code, "fail:\n");
+ Append(f->code, "Py_INCREF(Py_NotImplemented);\n");
+ Append(f->code, "return Py_NotImplemented;\n");
+ } else {
+ Node *sibl = n;
+ while (Getattr(sibl, "sym:previousSibling"))
+ sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up
+ String *protoTypes = NewString("");
+ do {
+ Printf(protoTypes, "\n\" %s(%s)\\n\"", SwigType_str(Getattr(sibl, "name"), 0), ParmList_protostr(Getattr(sibl, "wrap:parms")));
+ } while ((sibl = Getattr(sibl, "sym:nextSibling")));
+ Append(f->code, "fail:\n");
+ Printf(f->code, "SWIG_SetErrorMsg(PyExc_NotImplementedError,"
+ "\"Wrong number of arguments for overloaded function '%s'.\\n\"" "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes);
+ Append(f->code, "return NULL;\n");
+ Delete(protoTypes);
+ }
+ Printv(f->code, "}\n", NIL);
+ Wrapper_print(f, f_wrappers);
+ Node *p = Getattr(n, "sym:previousSibling");
+ add_method(symname, wname, 0, p);
+
+ /* Create a shadow for this function (if enabled and not in a member function) */
+ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ emitFunctionShadowHelper(n, f_shadow_stubs, symname, 0);
+ }
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(tmp);
+ Delete(wname);
+ }
+
+ /* ------------------------------------------------------------
+ * functionWrapper()
+ * ------------------------------------------------------------ */
+
+
+ const char *get_implicitconv_flag(Node *klass) {
+ int conv = 0;
+ if (klass && GetFlag(klass, "feature:implicitconv")) {
+ conv = 1;
+ }
+ return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "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");
+ int director_method = 0;
+
+ Parm *p;
+ int i;
+ 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 = check_kwargs(n);
+
+ String *nodeType = Getattr(n, "nodeType");
+ int constructor = (!Cmp(nodeType, "constructor"));
+ int destructor = (!Cmp(nodeType, "destructor"));
+ String *storage = Getattr(n, "storage");
+ /* Only the first constructor is handled as init method. Others
+ constructor can be emitted via %rename */
+ int handled_as_init = 0;
+ if (!have_constructor && (constructor || Getattr(n, "handled_as_constructor"))
+ && ((shadow & PYSHADOW_MEMBER))) {
+ String *nname = Getattr(n, "sym:name");
+ String *sname = Getattr(getCurrentClass(), "sym:name");
+ String *cname = Swig_name_construct(sname);
+ handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0);
+ Delete(cname);
+ }
+
+
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ }
+
+ f = NewWrapper();
+ parse_args = NewString("");
+ arglist = NewString("");
+ get_pointers = NewString("");
+ cleanup = NewString("");
+ outarg = NewString("");
+ kwargs = NewString("");
+
+ int allow_thread = threads_enable(n);
+
+ Wrapper_add_local(f, "resultobj", "PyObject *resultobj = 0");
+
+ // Emit all of the local variables for holding arguments.
+ emit_parameter_variables(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);
+ if (((num_arguments == 0) && (num_required == 0)) || ((num_arguments == 1) && (num_required == 1) && Getattr(l, "self")))
+ allow_kwargs = 0;
+ varargs = emit_isvarargs(l);
+
+ String *wname = Swig_name_wrapper(iname);
+ if (overname) {
+ Append(wname, overname);
+ }
+
+ if (!allow_kwargs || Getattr(n, "sym:overloaded")) {
+ if (!varargs) {
+ Printv(f->def, "SWIGINTERN PyObject *", wname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {", NIL);
+ } else {
+ Printv(f->def, "SWIGINTERN PyObject *", wname, "__varargs__", "(PyObject *SWIGUNUSEDPARM(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 (%s).\n", Swig_name_decl(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, "SWIGINTERN PyObject *", wname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {", NIL);
+ }
+ if (!allow_kwargs) {
+ Append(parse_args, " if (!PyArg_ParseTuple(args,(char *)\"");
+ } else {
+ Append(parse_args, " if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)\"");
+ Append(arglist, ",kwnames");
+ }
+
+ int funpack = modernargs && fastunpack && !varargs && !allow_kwargs;
+ int noargs = funpack && (num_required == 0 && num_arguments == 0);
+ int onearg = funpack && (num_required == 1 && num_arguments == 1);
+
+ /* Generate code for argument marshalling */
+ if (funpack) {
+ if (overname) {
+ if (aliasobj0) {
+ Append(f->code, "#define obj0 (swig_obj[0])\n");
+ }
+ } else if (num_arguments) {
+ sprintf(source, "PyObject *swig_obj[%d]", num_arguments);
+ Wrapper_add_localv(f, "swig_obj", source, NIL);
+ if (aliasobj0) {
+ Append(f->code, "#define obj0 (swig_obj[0])\n");
+ }
+ }
+ }
+
+
+ if (constructor && num_arguments == 1 && num_required == 1) {
+ if (Cmp(storage, "explicit") == 0) {
+ Node *parent = Swig_methodclass(n);
+ if (GetFlag(parent, "feature:implicitconv")) {
+ String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type")));
+ Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc);
+ Delete(desc);
+ }
+ }
+ }
+
+ int use_parse = 0;
+ Append(kwargs, "{");
+ for (i = 0, p = l; i < num_arguments; i++) {
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *pn = Getattr(p, "name");
+ String *ln = Getattr(p, "lname");
+ if (funpack) {
+ sprintf(source, "swig_obj[%d]", i);
+ } else {
+ sprintf(source, "obj%d", i);
+ }
+
+
+ Putc(',', arglist);
+ if (i == num_required)
+ Putc('|', parse_args); /* Optional argument separator */
+
+ /* Keyword argument handling */
+ if (allow_kwargs) {
+ if (Len(pn)) {
+ String *tmp = 0;
+ String *name = pn;
+ if (!Getattr(p,"hidden")) {
+ name = tmp = Swig_name_make(p, 0, pn, 0, 0);
+ }
+ Printf(kwargs, "(char *) \"%s\",", name);
+ if (tmp)
+ Delete(tmp);
+ } else {
+ Printf(kwargs, "(char *)\"arg%d\",", i + 1);
+ }
+ }
+
+ /* Look for an input typemap */
+ if ((tm = Getattr(p, "tmap:in"))) {
+ String *parse = Getattr(p, "tmap:in:parse");
+ if (!parse) {
+ if (funpack) {
+ Replaceall(tm, "$self", "swig_obj[0]");
+ } else {
+ Replaceall(tm, "$self", "obj0");
+ }
+ 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");
+ }
+
+ if (Getattr(p, "tmap:in:implicitconv")) {
+ const char *convflag = "0";
+ if (!Getattr(p,"hidden")) {
+ SwigType *ptype = Getattr(p, "type");
+ convflag = get_implicitconv_flag(classLookup(ptype));
+ }
+ Replaceall(tm, "$implicitconv", convflag);
+ Setattr(p, "implicitconv", convflag);
+ }
+
+ Putc('O', parse_args);
+ if (!funpack) {
+ Wrapper_add_localv(f, source, "PyObject *", source, "= 0", NIL);
+ Printf(arglist, "&%s", source);
+ }
+ if (i >= num_required)
+ Printv(get_pointers, "if (", source, ") {\n", NIL);
+ Printv(get_pointers, tm, "\n", NIL);
+ if (i >= num_required)
+ Printv(get_pointers, "}\n", NIL);
+
+ } else {
+ use_parse = 1;
+ Append(parse_args, 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;
+ }
+ }
+
+ /* finish argument marshalling */
+ Append(kwargs, " NULL }");
+ if (allow_kwargs) {
+ Printv(f->locals, " char * kwnames[] = ", kwargs, ";\n", NIL);
+ }
+
+ if (use_parse || allow_kwargs || !modernargs) {
+ Printf(parse_args, ":%s\"", iname);
+ Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
+ funpack = 0;
+ } else {
+ Clear(parse_args);
+ if (funpack) {
+ Clear(f->def);
+ if (overname) {
+ if (noargs) {
+ Printv(f->def, "SWIGINTERN PyObject *", wname, "(PyObject *SWIGUNUSEDPARM(self), int nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
+ } else {
+ Printv(f->def, "SWIGINTERN PyObject *", wname, "(PyObject *SWIGUNUSEDPARM(self), int nobjs, PyObject **swig_obj) {", NIL);
+ }
+ Printf(parse_args, "if ((nobjs < %d) || (nobjs > %d)) SWIG_fail;\n", num_required, num_arguments);
+ } else {
+ if (noargs) {
+ Printv(f->def, "SWIGINTERN PyObject *", wname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {", NIL);
+ } else {
+ Printv(f->def, "SWIGINTERN PyObject *", wname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {", NIL);
+ }
+ if (onearg) {
+ Printf(parse_args, "if (!args) SWIG_fail;\n");
+ Printf(parse_args, "swig_obj[0] = args;\n");
+ } else if (!noargs) {
+ Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args,\"%s\",%d,%d,swig_obj)) SWIG_fail;\n", iname, num_required, num_arguments);
+ } else if (noargs) {
+ Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args,\"%s\",%d,%d,0)) SWIG_fail;\n", iname, num_required, num_arguments);
+ }
+ }
+ } else {
+ Printf(parse_args, "if(!PyArg_UnpackTuple(args,(char *)\"%s\",%d,%d", iname, num_required, num_arguments);
+ Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
+ }
+ }
+
+ /* Now piece together the first part of the wrapper function */
+ Printv(f->code, parse_args, get_pointers, NIL);
+
+ /* Check for trailing varargs */
+ if (varargs) {
+ if (p && (tm = Getattr(p, "tmap:in"))) {
+ Replaceall(tm, "$input", "varargs");
+ Printv(f->code, tm, "\n", NIL);
+ }
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ // if (!checkAttribute(p,"tmap:in:numinputs","0") && !Getattr(p,"tmap:in:parse")) {
+ if (!Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) {
+ if (Getattr(p, "tmap:freearg:implicitconv")) {
+ const char *convflag = "0";
+ if (!Getattr(p,"hidden")) {
+ SwigType *ptype = Getattr(p, "type");
+ convflag = get_implicitconv_flag(classLookup(ptype));
+ }
+ if (strcmp(convflag, "0") == 0) {
+ tm = 0;
+ }
+ }
+ if (tm && (Len(tm) != 0)) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Printv(cleanup, tm, "\n", NIL);
+ }
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$arg", Getattr(p, "emit:input"));
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(outarg, tm, "\n", NIL);
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* if the object is a director, and the method call originated from its
+ * underlying python object, resolve the call by going up the c++
+ * inheritance chain. otherwise try to resolve the method in python.
+ * without this check an infinite loop is set up between the director and
+ * shadow class method calls.
+ */
+
+ // NOTE: this code should only be inserted if this class is the
+ // base class of a director class. however, in general we haven't
+ // yet analyzed all classes derived from this one to see if they are
+ // directors. furthermore, this class may be used as the base of
+ // a director class defined in a completely different module at a
+ // later time, so this test must be included whether or not directorbase
+ // is true. we do skip this code if directors have not been enabled
+ // at the command line to preserve source-level compatibility with
+ // non-polymorphic swig. also, if this wrapper is for a smart-pointer
+ // method, there is no need to perform the test since the calling object
+ // (the smart-pointer) and the director object (the "pointee") are
+ // distinct.
+
+ director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
+ if (director_method) {
+ Wrapper_add_local(f, "director", "Swig::Director *director = 0");
+ Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
+ if (dirprot_mode() && !is_public(n)) {
+ Printf(f->code, "if (!director || !(director->swig_get_inner(\"%s\"))) {\n", name);
+ Printf(f->code, "SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing protected member %s\");\n", name);
+ Append(f->code, "SWIG_fail;\n");
+ Append(f->code, "}\n");
+ }
+ Wrapper_add_local(f, "upcall", "bool upcall = false");
+ if (funpack) {
+ Append(f->code, "upcall = (director && (director->swig_get_self()==swig_obj[0]));\n");
+ } else {
+ Append(f->code, "upcall = (director && (director->swig_get_self()==obj0));\n");
+ }
+ }
+
+ /* Emit the function call */
+ if (director_method) {
+ Append(f->code, "try {\n");
+ } else {
+ if (allow_thread) {
+ Append(f->code, "{\n");
+ thread_begin_allow(n, f->code);
+ }
+ }
+
+ Setattr(n, "wrap:name", wname);
+
+ Swig_director_emit_dynamic_cast(n, f);
+ String *actioncode = emit_action(n);
+
+ if (director_method) {
+ Append(actioncode, "} catch (Swig::DirectorException&) {\n");
+ Append(actioncode, " SWIG_fail;\n");
+ Append(actioncode, "}\n");
+ } else {
+ if (allow_thread) {
+ thread_end_allow(n, actioncode);
+ Append(actioncode, "}\n");
+ }
+ }
+
+ /* This part below still needs cleanup */
+
+ /* Return the function value */
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ if (funpack) {
+ Replaceall(tm, "$self", "swig_obj[0]");
+ } else {
+ Replaceall(tm, "$self", "obj0");
+ }
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+ if (handled_as_init) {
+ Replaceall(tm, "$owner", "SWIG_POINTER_NEW");
+ } else {
+ if (GetFlag(n, "feature:new")) {
+ Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
+ } else {
+ Replaceall(tm, "$owner", "0");
+ }
+ }
+ // FIXME: this will not try to unwrap directors returned as non-director
+ // base class pointers!
+
+ /* New addition to unwrap director return values so that the original
+ * python object is returned instead.
+ */
+#if 1
+ int unwrap = 0;
+ String *decl = Getattr(n, "decl");
+ int is_pointer = SwigType_ispointer_return(decl);
+ int is_reference = SwigType_isreference_return(decl);
+ if (is_pointer || is_reference) {
+ String *type = Getattr(n, "type");
+ //Node *classNode = Swig_methodclass(n);
+ //Node *module = Getattr(classNode, "module");
+ Node *parent = Swig_methodclass(n);
+ Node *module = Getattr(parent, "module");
+ Node *target = Swig_directormap(module, type);
+ if (target)
+ unwrap = 1;
+ }
+ if (unwrap) {
+ Wrapper_add_local(f, "director", "Swig::Director *director = 0");
+ Append(f->code, "director = SWIG_DIRECTOR_CAST(result);\n");
+ Append(f->code, "if (director) {\n");
+ Append(f->code, " resultobj = director->swig_get_self();\n");
+ Append(f->code, " Py_INCREF(resultobj);\n");
+ Append(f->code, "} else {\n");
+ Printf(f->code, "%s\n", tm);
+ Append(f->code, "}\n");
+ } else {
+ Printf(f->code, "%s\n", tm);
+ }
+#else
+ Printf(f->code, "%s\n", tm);
+#endif
+ Delete(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);
+ }
+ emit_return_variable(n, d, f);
+
+ /* Output argument output code */
+ Printv(f->code, outarg, NIL);
+
+ /* Output cleanup code */
+ int need_cleanup = Len(cleanup) != 0;
+ if (need_cleanup) {
+ Printv(f->code, cleanup, NIL);
+ }
+
+ /* Look to see if there is any newfree cleanup code */
+ if (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ Delete(tm);
+ }
+ }
+
+ /* See if there is any return cleanup code */
+ if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ Delete(tm);
+ }
+
+ if (director_method) {
+ if ((tm = Swig_typemap_lookup("directorfree", n, "result", 0))) {
+ Replaceall(tm, "$input", "result");
+ Replaceall(tm, "$result", "resultobj");
+ Printf(f->code, "%s\n", tm);
+ Delete(tm);
+ }
+ }
+
+ Append(f->code, " return resultobj;\n");
+
+ /* Error handling code */
+
+ Append(f->code, "fail:\n");
+ if (need_cleanup) {
+ Printv(f->code, cleanup, NIL);
+ }
+ Printv(f->code, " return NULL;\n", NIL);
+
+
+ if (funpack) {
+ if (aliasobj0) {
+ Append(f->code, "#if defined(obj0)\n");
+ Append(f->code, "#undef obj0\n");
+ Append(f->code, "#endif\n");
+ }
+ }
+
+
+ Append(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");
+
+ if (funpack) {
+ Replaceall(f->code, "$self", "swig_obj[0]");
+ } else {
+ Replaceall(f->code, "$self", "obj0");
+ }
+
+ /* 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, "SWIGINTERN 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);
+ Append(f->code, "Py_XDECREF(newargs);\n");
+ Append(f->code, "Py_XDECREF(varargs);\n");
+ Append(f->code, "return resultobj;\n");
+ Append(f->code, "}\n");
+ Wrapper_print(f, f_wrappers);
+ }
+
+ /* Now register the function with the interpreter. */
+ if (!Getattr(n, "sym:overloaded")) {
+ add_method(iname, wname, allow_kwargs, n, funpack, num_required, num_arguments);
+
+ /* Create a shadow for this function (if enabled and not in a member function) */
+ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, iname, allow_kwargs);
+ }
+ } else {
+ if (!Getattr(n, "sym:nextSibling")) {
+ dispatchFunction(n, funpack);
+ }
+ }
+ Delete(parse_args);
+ Delete(arglist);
+ Delete(get_pointers);
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(kwargs);
+ Delete(wname);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+
+ static int have_globals = 0;
+ String *tm;
+ Wrapper *getf, *setf;
+
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+
+ getf = NewWrapper();
+ setf = NewWrapper();
+
+ /* If this is our first call, add the globals variable to the
+ Python dictionary. */
+
+ if (!have_globals) {
+ Printf(f_init, "\t PyDict_SetItemString(d,(char*)\"%s\", SWIG_globals());\n", global_name);
+ have_globals = 1;
+ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ Printf(f_shadow_stubs, "%s = %s.%s\n", global_name, module, global_name);
+ }
+ }
+ int assignable = is_assignable(n);
+
+ if ((shadow) && !assignable) {
+ if (!in_class) {
+ Printf(f_shadow_stubs, "%s = %s.%s\n", iname, global_name, iname);
+ }
+ }
+
+ String *getname = Swig_name_get(iname);
+ String *setname = Swig_name_set(iname);
+ String *vargetname = NewStringf("Swig_var_%s", getname);
+ String *varsetname = NewStringf("Swig_var_%s", setname);
+
+ /* Create a function for setting the value of the variable */
+ if (assignable) {
+ Setattr(n, "wrap:name", varsetname);
+ Printf(setf->def, "SWIGINTERN int %s(PyObject *_val) {", varsetname);
+ if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
+ Replaceall(tm, "$source", "_val");
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$input", "_val");
+ if (Getattr(n, "tmap:varin:implicitconv")) {
+ Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
+ }
+ emit_action_code(n, setf->code, 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));
+ }
+ Printv(setf->code, " return 0;\n", NULL);
+ Append(setf->code, "fail:\n");
+ Printv(setf->code, " return 1;\n", NULL);
+ } else {
+ /* Is a readonly variable. Issue an error */
+ if (CPlusPlus) {
+ Printf(setf->def, "SWIGINTERN int %s(PyObject *) {", varsetname);
+ } else {
+ Printf(setf->def, "SWIGINTERN int %s(PyObject *_val SWIGUNUSED) {", varsetname);
+ }
+ Printv(setf->code, " SWIG_Error(SWIG_AttributeError,\"Variable ", iname, " is read-only.\");\n", " return 1;\n", NIL);
+ }
+
+ Append(setf->code, "}\n");
+ Wrapper_print(setf, f_wrappers);
+
+ /* Create a function for getting the value of a variable */
+ Setattr(n, "wrap:name", vargetname);
+ int addfail = 0;
+ Printf(getf->def, "SWIGINTERN PyObject *%s(void) {", vargetname);
+ Wrapper_add_local(getf, "pyobj", "PyObject *pyobj = 0");
+ if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
+ Replaceall(tm, "$source", name);
+ Replaceall(tm, "$target", "pyobj");
+ Replaceall(tm, "$result", "pyobj");
+ addfail = emit_action_code(n, getf->code, tm);
+ Delete(tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
+ }
+ Append(getf->code, " return pyobj;\n");
+ if (addfail) {
+ Append(getf->code, "fail:\n");
+ Append(getf->code, " return NULL;\n");
+ }
+ Append(getf->code, "}\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, %s);\n", iname, vargetname, varsetname);
+
+ Delete(vargetname);
+ Delete(varsetname);
+ Delete(getname);
+ Delete(setname);
+ DelWrapper(setf);
+ DelWrapper(getf);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ String *rawval = Getattr(n, "rawval");
+ String *value = rawval ? rawval : 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);
+ String *str = SwigType_str(type, wname);
+ Printf(f_header, "static %s = %s;\n", str, value);
+ Delete(str);
+ value = wname;
+ }
+ if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ Printf(const_code, "%s,\n", tm);
+ Delete(tm);
+ have_tm = 1;
+ }
+ if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ Printf(f_init, "%s\n", tm);
+ Delete(tm);
+ have_tm = 1;
+ }
+ if (!have_tm) {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ if (!in_class) {
+ Printv(f_shadow, iname, " = ", module, ".", iname, "\n", NIL);
+ } else {
+ if (!(Getattr(n, "feature:python:callback"))) {
+ Printv(f_shadow_stubs, iname, " = ", module, ".", iname, "\n", NIL);
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int nativeWrapper(Node *n) {
+ String *name = Getattr(n, "sym:name");
+ String *wrapname = Getattr(n, "wrap:name");
+
+ if (!addSymbol(wrapname, n))
+ return SWIG_ERROR;
+
+ add_method(name, wrapname, 0);
+ if (shadow) {
+ Printv(f_shadow_stubs, name, " = ", module, ".", name, "\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+
+
+/* ----------------------------------------------------------------------------
+ * BEGIN C++ Director Class modifications
+ * ------------------------------------------------------------------------- */
+
+/* C++/Python polymorphism demo code, copyright (C) 2002 Mark Rose <mrose@stm.lbl.gov>
+ *
+ * TODO
+ *
+ * Move some boilerplate code generation to Swig_...() functions.
+ *
+ */
+
+ /* ---------------------------------------------------------------
+ * classDirectorMethod()
+ *
+ * Emit a virtual director method to pass a method call on to the
+ * underlying Python object.
+ * ** Moved down due to gcc-2.96 internal error **
+ * --------------------------------------------------------------- */
+
+ int classDirectorMethods(Node *n);
+
+ int classDirectorMethod(Node *n, Node *parent, String *super);
+
+ /* ------------------------------------------------------------
+ * classDirectorConstructor()
+ * ------------------------------------------------------------ */
+
+ int classDirectorConstructor(Node *n) {
+ Node *parent = Getattr(n, "parentNode");
+ String *sub = NewString("");
+ String *decl = Getattr(n, "decl");
+ String *supername = Swig_class_name(parent);
+ String *classname = NewString("");
+ Printf(classname, "SwigDirector_%s", supername);
+
+ /* insert self parameter */
+ Parm *p;
+ ParmList *superparms = Getattr(n, "parms");
+ ParmList *parms = CopyParmList(superparms);
+ String *type = NewString("PyObject");
+ SwigType_add_pointer(type);
+ p = NewParm(type, NewString("self"));
+ set_nextSibling(p, parms);
+ parms = p;
+
+ if (!Getattr(n, "defaultargs")) {
+ /* constructor */
+ {
+ Wrapper *w = NewWrapper();
+ String *call;
+ String *basetype = Getattr(parent, "classtype");
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+ call = Swig_csuperclass_call(0, basetype, superparms);
+ Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call);
+ Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
+ Append(w->def, "}\n");
+ Delete(target);
+ Wrapper_print(w, f_directors);
+ Delete(call);
+ DelWrapper(w);
+ }
+
+ /* constructor header */
+ {
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+ Printf(f_directors_h, " %s;\n", target);
+ Delete(target);
+ }
+ }
+
+ Delete(sub);
+ Delete(classname);
+ Delete(supername);
+ Delete(parms);
+ return Language::classDirectorConstructor(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorDefaultConstructor()
+ * ------------------------------------------------------------ */
+
+ int classDirectorDefaultConstructor(Node *n) {
+ String *classname = Swig_class_name(n);
+ {
+ Node *parent = Swig_methodclass(n);
+ String *basetype = Getattr(parent, "classtype");
+ Wrapper *w = NewWrapper();
+ Printf(w->def, "SwigDirector_%s::SwigDirector_%s(PyObject* self) : Swig::Director(self) { \n", classname, classname);
+ Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
+ Append(w->def, "}\n");
+ Wrapper_print(w, f_directors);
+ DelWrapper(w);
+ }
+ Printf(f_directors_h, " SwigDirector_%s(PyObject* self);\n", classname);
+ Delete(classname);
+ return Language::classDirectorDefaultConstructor(n);
+ }
+
+
+ /* ------------------------------------------------------------
+ * classDirectorInit()
+ * ------------------------------------------------------------ */
+
+ int classDirectorInit(Node *n) {
+ String *declaration = Swig_director_declaration(n);
+ Printf(f_directors_h, "\n");
+ Printf(f_directors_h, "%s\n", declaration);
+ Printf(f_directors_h, "public:\n");
+ Delete(declaration);
+ return Language::classDirectorInit(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorEnd()
+ * ------------------------------------------------------------ */
+
+ int classDirectorEnd(Node *n) {
+ String *classname = Swig_class_name(n);
+
+ if (dirprot_mode()) {
+ /*
+ This implementation uses a std::map<std::string,int>.
+
+ It should be possible to rewrite it using a more elegant way,
+ like copying the Java approach for the 'override' array.
+
+ But for now, this seems to be the least intrusive way.
+ */
+ Printf(f_directors_h, "\n\n");
+ Printf(f_directors_h, "/* Internal Director utilities */\n");
+ Printf(f_directors_h, "public:\n");
+ Printf(f_directors_h, " bool swig_get_inner(const char* name) const {\n");
+ Printf(f_directors_h, " std::map<std::string, bool>::const_iterator iv = inner.find(name);\n");
+ Printf(f_directors_h, " return (iv != inner.end() ? iv->second : false);\n");
+ Printf(f_directors_h, " }\n\n");
+
+ Printf(f_directors_h, " void swig_set_inner(const char* name, bool val) const\n");
+ Printf(f_directors_h, " { inner[name] = val;}\n\n");
+ Printf(f_directors_h, "private:\n");
+ Printf(f_directors_h, " mutable std::map<std::string, bool> inner;\n");
+
+ }
+ if (director_method_index) {
+ Printf(f_directors_h, "\n\n");
+ Printf(f_directors_h, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n");
+ Printf(f_directors_h, "/* VTable implementation */\n");
+ Printf(f_directors_h, " PyObject *swig_get_method(size_t method_index, const char *method_name) const {\n");
+ Printf(f_directors_h, " PyObject *method = vtable[method_index];\n");
+ Printf(f_directors_h, " if (!method) {\n");
+ Printf(f_directors_h, " swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name);\n");
+ Printf(f_directors_h, " method = PyObject_GetAttr(swig_get_self(), name);\n");
+ Printf(f_directors_h, " if (method == NULL) {\n");
+ Printf(f_directors_h, " std::string msg = \"Method in class %s doesn't exist, undefined \";\n", classname);
+ Printf(f_directors_h, " msg += method_name;\n");
+ Printf(f_directors_h, " Swig::DirectorMethodException::raise(msg.c_str());\n");
+ Printf(f_directors_h, " }\n");
+ Printf(f_directors_h, " vtable[method_index] = method;\n");
+ Printf(f_directors_h, " };\n");
+ Printf(f_directors_h, " return method;\n");
+ Printf(f_directors_h, " }\n");
+ Printf(f_directors_h, "private:\n");
+ Printf(f_directors_h, " mutable swig::SwigVar_PyObject vtable[%d];\n", director_method_index);
+ Printf(f_directors_h, "#endif\n\n");
+ }
+
+ Printf(f_directors_h, "};\n\n");
+ return Language::classDirectorEnd(n);
+ }
+
+
+ /* ------------------------------------------------------------
+ * classDirectorDisown()
+ * ------------------------------------------------------------ */
+
+ int classDirectorDisown(Node *n) {
+ int result;
+ int oldshadow = shadow;
+ /* disable shadowing */
+ if (shadow)
+ shadow = shadow | PYSHADOW_MEMBER;
+ result = Language::classDirectorDisown(n);
+ shadow = oldshadow;
+ if (shadow) {
+ String *symname = Getattr(n, "sym:name");
+ String *mrename = Swig_name_disown(symname); //Getattr(n, "name"));
+ Printv(f_shadow, tab4, "def __disown__(self):\n", NIL);
+#ifdef USE_THISOWN
+ Printv(f_shadow, tab8, "self.thisown = 0\n", NIL);
+#else
+ Printv(f_shadow, tab8, "self.this.disown()\n", NIL);
+#endif
+ Printv(f_shadow, tab8, module, ".", mrename, "(self)\n", NIL);
+ Printv(f_shadow, tab8, "return weakref_proxy(self)\n", NIL);
+ Delete(mrename);
+ }
+ return result;
+ }
+
+/* ----------------------------------------------------------------------------
+ * END of C++ Director Class modifications
+ * ------------------------------------------------------------------------- */
+
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int classDeclaration(Node *n) {
+ if (shadow && !Getattr(n, "feature:onlychildren")) {
+ Node *mod = Getattr(n, "module");
+ if (mod) {
+ String *importname = NewString("");
+ String *modname = Getattr(mod, "name");
+ if (Strcmp(modname, mainmodule) != 0) {
+ // check if the module has a package option
+ Node *options = Getattr(mod, "options");
+ String *pkg = options ? Getattr(options, "package") : 0;
+ if (pkg && (!package || Strcmp(pkg, package) != 0)) {
+ Printf(importname, "%s.", pkg);
+ }
+ Printf(importname, "%s.", modname);
+ }
+ Append(importname, Getattr(n, "sym:name"));
+ Setattr(n, "python:proxy", importname);
+ }
+ }
+ return Language::classDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int classHandler(Node *n) {
+ int oldclassic = classic;
+ int oldmodern = modern;
+ File *f_shadow_file = f_shadow;
+
+ if (shadow) {
+
+ /* Create new strings for building up a wrapper function */
+ have_constructor = 0;
+ have_repr = 0;
+
+ if (GetFlag(n, "feature:classic")) {
+ classic = 1;
+ modern = 0;
+ }
+ if (GetFlag(n, "feature:modern")) {
+ classic = 0;
+ modern = 1;
+ }
+ if (GetFlag(n, "feature:exceptionclass")) {
+ classic = 1;
+ modern = 0;
+ }
+
+ 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)) {
+ Iterator b;
+ b = First(baselist);
+ while (b.item) {
+ String *bname = Getattr(b.item, "python:proxy");
+ bool ignore = GetFlag(b.item, "feature:ignore") ? true : false;
+ if (!bname || ignore) {
+ if (!bname && !ignore) {
+ Swig_warning(WARN_TYPE_UNDEFINED_CLASS, input_file, line_number,
+ "Base class '%s' ignored - unknown module name for base. Either import the appropriate module interface file or specify the name of the module in the %%import directive.\n", SwigType_namestr(Getattr(b.item, "name")));
+ }
+ b = Next(b);
+ continue;
+ }
+ Printv(base_class, bname, NIL);
+ b = Next(b);
+ if (b.item) {
+ Putc(',', base_class);
+ }
+ }
+ }
+
+ /* dealing with abstract base class */
+ String *abcs = Getattr(n, "feature:python:abc");
+ if (py3 && abcs) {
+ if (Len(base_class)) {
+ Putc(',', base_class);
+ }
+ Printv(base_class, abcs, NIL);
+ }
+
+ Printv(f_shadow, "class ", class_name, NIL);
+
+ if (Len(base_class)) {
+ Printf(f_shadow, "(%s)", base_class);
+ } else {
+ if (!classic) {
+ Printf(f_shadow, modern ? "(object)" : "(_object)");
+ }
+ if (GetFlag(n, "feature:exceptionclass") ) {
+ Printf(f_shadow, "(Exception)");
+ }
+ }
+ Printf(f_shadow, ":\n");
+ if (have_docstring(n)) {
+ String *str = docstring(n, AUTODOC_CLASS, tab4);
+ if (str != NULL && Len(str))
+ Printv(f_shadow, tab4, str, "\n", NIL);
+ }
+ if (!modern) {
+ Printv(f_shadow, tab4, "__swig_setmethods__ = {}\n", NIL);
+ if (Len(base_class)) {
+ Printf(f_shadow, "%sfor _s in [%s]: __swig_setmethods__.update(getattr(_s,'__swig_setmethods__',{}))\n", tab4, base_class);
+ }
+
+ if (!GetFlag(n, "feature:python:nondynamic")) {
+ Printv(f_shadow, tab4, "__setattr__ = lambda self, name, value: _swig_setattr(self, ", class_name, ", name, value)\n", NIL);
+ } else {
+ Printv(f_shadow, tab4, "__setattr__ = lambda self, name, value: _swig_setattr_nondynamic(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(getattr(_s,'__swig_getmethods__',{}))\n", tab4, base_class);
+ }
+
+ Printv(f_shadow, tab4, "__getattr__ = lambda self, name: _swig_getattr(self, ", class_name, ", name)\n", NIL);
+ } else {
+ Printv(f_shadow, tab4, "thisown = _swig_property(lambda x: x.this.own(), ", "lambda x, v: x.this.own(v), doc='The membership flag')\n", NIL);
+ /* Add static attribute */
+ if (GetFlag(n, "feature:python:nondynamic")) {
+ Printv(f_shadow_file,
+ tab4, "__setattr__ = _swig_setattr_nondynamic_method(object.__setattr__)\n",
+ tab4, "class __metaclass__(type):\n", tab4, tab4, "__setattr__ = _swig_setattr_nondynamic_method(type.__setattr__)\n", NIL);
+ }
+ }
+ }
+
+ /* Emit all of the members */
+
+ in_class = 1;
+
+ /* Overide the shadow file so we can capture its methods */
+ f_shadow = NewString("");
+
+ Language::classHandler(n);
+ in_class = 0;
+
+ /* Complete the class */
+ if (shadow) {
+ /* Generate a class registration function */
+ {
+ String *smartptr = Getattr(n, "feature:smartptr"); // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers)
+ SwigType *smart = 0;
+ if (smartptr) {
+ SwigType *cpt = Swig_cparse_type(smartptr);
+ if (cpt) {
+ smart = SwigType_typedef_resolve_all(cpt);
+ Delete(cpt);
+ } else {
+ // TODO: report line number of where the feature comes from
+ Swig_error(Getfile(n), Getline(n), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, real_classname);
+ }
+ }
+ SwigType *ct = Copy(smart ? smart : real_classname);
+ SwigType_add_pointer(ct);
+ SwigType *realct = Copy(real_classname);
+ SwigType_add_pointer(realct);
+ SwigType_remember(realct);
+ Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
+ Printv(f_wrappers, " PyObject *obj;\n", NIL);
+ if (modernargs) {
+ if (fastunpack) {
+ Printv(f_wrappers, " if (!SWIG_Python_UnpackTuple(args,(char*)\"swigregister\", 1, 1,&obj)) return NULL;\n", NIL);
+ } else {
+ Printv(f_wrappers, " if (!PyArg_UnpackTuple(args,(char*)\"swigregister\", 1, 1,&obj)) return NULL;\n", NIL);
+ }
+ } else {
+ Printv(f_wrappers, " if (!PyArg_ParseTuple(args,(char*)\"O:swigregister\", &obj)) return NULL;\n", NIL);
+ }
+
+ Printv(f_wrappers,
+ " SWIG_TypeNewClientData(SWIGTYPE", SwigType_manglestr(ct), ", SWIG_NewClientData(obj));\n",
+ " return SWIG_Py_Void();\n", "}\n\n", NIL);
+ String *cname = NewStringf("%s_swigregister", class_name);
+ add_method(cname, cname, 0);
+ Delete(smart);
+ Delete(cname);
+ Delete(ct);
+ Delete(realct);
+ }
+ if (!have_constructor) {
+ Printv(f_shadow_file, tab4, "def __init__(self, *args, **kwargs): raise AttributeError(\"", "No constructor defined", (Getattr(n, "abstract") ? " - class is abstract" : ""), "\")\n", NIL);
+ } else if (fastinit) {
+
+ Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
+ Printv(f_wrappers, " return SWIG_Python_InitShadowInstance(args);\n", "}\n\n", NIL);
+ String *cname = NewStringf("%s_swiginit", class_name);
+ add_method(cname, cname, 0);
+ Delete(cname);
+ }
+ if (!have_repr) {
+ /* Supply a repr method for this class */
+ String *rname = SwigType_namestr(real_classname);
+ if (new_repr) {
+ Printv(f_shadow_file, tab4, "__repr__ = _swig_repr\n", NIL);
+ } else {
+ Printv(f_shadow_file, tab4, "def __repr__(self):\n", tab8, "return \"<C ", rname, " instance at 0x%x>\" % (self.this,)\n", NIL);
+ }
+ Delete(rname);
+ }
+
+
+ /* Now emit methods */
+ Printv(f_shadow_file, f_shadow, NIL);
+
+ /* Now the Ptr class */
+ if (classptr) {
+ Printv(f_shadow_file, "\nclass ", class_name, "Ptr(", class_name, "):\n", tab4, "def __init__(self, this):\n", NIL);
+ if (!modern) {
+ Printv(f_shadow_file,
+ tab8, "try: self.this.append(this)\n",
+ tab8, "except: self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL);
+ } else {
+ Printv(f_shadow_file,
+ tab8, "try: self.this.append(this)\n",
+ tab8, "except: self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL);
+ }
+ }
+
+ if (fastproxy) {
+ List *shadow_list = Getattr(n, "shadow_methods");
+ for (int i = 0; i < Len(shadow_list); ++i) {
+ String *symname = Getitem(shadow_list, i);
+ Printf(f_shadow_file, "%s.%s = new_instancemethod(%s.%s,None,%s)\n", class_name, symname, module, Swig_name_member(class_name, symname), class_name);
+ }
+ }
+ Printf(f_shadow_file, "%s_swigregister = %s.%s_swigregister\n", class_name, module, class_name);
+ Printf(f_shadow_file, "%s_swigregister(%s)\n", class_name, class_name);
+
+ shadow_indent = 0;
+ Printf(f_shadow_file, "%s\n", f_shadow_stubs);
+ Clear(f_shadow_stubs);
+ }
+ classic = oldclassic;
+ modern = oldmodern;
+
+ /* Restore shadow file back to original version */
+ Delete(f_shadow);
+ f_shadow = f_shadow_file;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * functionHandler() - Mainly overloaded for callback handling
+ * ------------------------------------------------------------ */
+
+ virtual int functionHandler(Node *n) {
+ String *pcb = GetFlagAttr(n, "feature:python:callback");
+ if (pcb) {
+ if (Strcmp(pcb, "1") == 0) {
+ SetFlagAttr(n, "feature:callback", "%s_cb_ptr");
+ } else {
+ SetFlagAttr(n, "feature:callback", pcb);
+ }
+ autodoc_l dlevel = autodoc_level(Getattr(n, "feature:autodoc"));
+ if (dlevel != NO_AUTODOC && dlevel > TYPES_AUTODOC) {
+ Setattr(n, "feature:autodoc", "1");
+ }
+ }
+ return Language::functionHandler(n);
+ }
+
+ /* ------------------------------------------------------------
+ * 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 = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
+ int fproxy = fastproxy;
+ if (Strcmp(symname, "__repr__") == 0) {
+ have_repr = 1;
+ }
+ if (Getattr(n, "feature:shadow")) {
+ String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4);
+ String *pyaction = NewStringf("%s.%s", module, Swig_name_member(class_name, symname));
+ Replaceall(pycode, "$action", pyaction);
+ Delete(pyaction);
+ Printv(f_shadow, pycode, "\n", NIL);
+ Delete(pycode);
+ fproxy = 0;
+ } else {
+ String *parms = make_pyParmList(n, true, false, allow_kwargs);
+ String *callParms = make_pyParmList(n, true, true, allow_kwargs);
+ if (!have_addtofunc(n)) {
+ if (!fastproxy || olddefs) {
+ Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL);
+ Printv(f_shadow, " return ", funcCall(Swig_name_member(class_name, symname), callParms), "\n", NIL);
+ }
+ } else {
+ Printv(f_shadow, tab4, "def ", symname, "(",parms , ")", returnTypeAnnotation(n), ":", NIL);
+ Printv(f_shadow, "\n", NIL);
+ if (have_docstring(n))
+ Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL);
+ if (have_pythonprepend(n)) {
+ fproxy = 0;
+ Printv(f_shadow, pythoncode(pythonprepend(n), tab8), "\n", NIL);
+ }
+ if (have_pythonappend(n)) {
+ fproxy = 0;
+ Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(class_name, symname), callParms), "\n", NIL);
+ Printv(f_shadow, pythoncode(pythonappend(n), tab8), "\n", NIL);
+ Printv(f_shadow, tab8, "return val\n\n", NIL);
+ } else {
+ Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(class_name, symname), callParms), "\n\n", NIL);
+ }
+ }
+ }
+ if (fproxy) {
+ List *shadow_list = Getattr(getCurrentClass(), "shadow_methods");
+ if (!shadow_list) {
+ shadow_list = NewList();
+ Setattr(getCurrentClass(), "shadow_methods", shadow_list);
+ Delete(shadow_list);
+ }
+ Append(shadow_list, symname);
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ Language::staticmemberfunctionHandler(n);
+
+ if (Getattr(n, "sym:nextSibling")) {
+ return SWIG_OK;
+ }
+
+ if (shadow) {
+ if (!classic && !Getattr(n, "feature:python:callback") && have_addtofunc(n)) {
+ int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
+ String *parms = make_pyParmList(n, false, false, kw);
+ String *callParms = make_pyParmList(n, false, true, kw);
+ Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
+ if (have_docstring(n))
+ Printv(f_shadow, tab8, docstring(n, AUTODOC_STATICFUNC, tab8), "\n", NIL);
+ if (have_pythonprepend(n))
+ Printv(f_shadow, pythoncode(pythonprepend(n), tab8), "\n", NIL);
+ if (have_pythonappend(n)) {
+ Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(class_name, symname), callParms), "\n", NIL);
+ Printv(f_shadow, pythoncode(pythonappend(n), tab8), "\n", NIL);
+ Printv(f_shadow, tab8, "return val\n\n", NIL);
+ } else {
+ Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(class_name, symname), callParms), "\n\n", NIL);
+ }
+ Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", symname, ")\n", NIL);
+
+ if (!modern) {
+ Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", symname, "\n", NIL);
+ }
+
+ } else {
+ if (!modern) {
+ Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", module, ".", Swig_name_member(class_name, symname), "\n", NIL);
+ }
+ if (!classic) {
+ Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", module, ".", Swig_name_member(class_name, symname), ")\n", NIL);
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ int oldshadow = shadow;
+ int use_director = Swig_directorclass(n);
+
+ /*
+ * If we're wrapping the constructor of a C++ director class, prepend a new parameter
+ * to receive the scripting language object (e.g. 'self')
+ *
+ */
+ Swig_save("python:constructorHandler", n, "parms", NIL);
+ if (use_director) {
+ Parm *parms = Getattr(n, "parms");
+ Parm *self;
+ String *name = NewString("self");
+ String *type = NewString("PyObject");
+ SwigType_add_pointer(type);
+ self = NewParm(type, name);
+ Delete(type);
+ Delete(name);
+ Setattr(self, "lname", "O");
+ if (parms)
+ set_nextSibling(self, parms);
+ Setattr(n, "parms", self);
+ Setattr(n, "wrap:self", "1");
+ Setattr(n, "hidden", "1");
+ Delete(self);
+ }
+
+ if (shadow)
+ shadow = shadow | PYSHADOW_MEMBER;
+ Language::constructorHandler(n);
+ shadow = oldshadow;
+
+ Delattr(n, "wrap:self");
+ Swig_restore(n);
+
+ if (!Getattr(n, "sym:nextSibling")) {
+ if (shadow) {
+ int allow_kwargs = (check_kwargs(n) && (!Getattr(n, "sym:overloaded"))) ? 1 : 0;
+ int handled_as_init = 0;
+ if (!have_constructor) {
+ String *nname = Getattr(n, "sym:name");
+ String *sname = Getattr(getCurrentClass(), "sym:name");
+ String *cname = Swig_name_construct(sname);
+ handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0);
+ Delete(cname);
+ }
+
+ if (!have_constructor && handled_as_init) {
+ if (Getattr(n, "feature:shadow")) {
+ String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4);
+ String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(symname));
+ Replaceall(pycode, "$action", pyaction);
+ Delete(pyaction);
+ Printv(f_shadow, pycode, "\n", NIL);
+ Delete(pycode);
+ } else {
+ String *pass_self = NewString("");
+ Node *parent = Swig_methodclass(n);
+ String *classname = Swig_class_name(parent);
+ String *rclassname = Swig_class_name(getCurrentClass());
+ assert(rclassname);
+
+ String *parms = make_pyParmList(n, true, false, allow_kwargs);
+ /* Pass 'self' only if using director */
+ String *callParms = make_pyParmList(n, false, true, allow_kwargs);
+
+ if (use_director) {
+ Insert(callParms, 0, "_self, ");
+ Printv(pass_self, tab8, NIL);
+ Printf(pass_self, "if self.__class__ == %s:\n", classname);
+ //Printv(pass_self, tab8, tab4, "args = (None,) + args\n", tab8, "else:\n", tab8, tab4, "args = (self,) + args\n", NIL);
+ Printv(pass_self, tab8, tab4, "_self = None\n", tab8, "else:\n", tab8, tab4, "_self = self\n", NIL);
+ }
+
+ Printv(f_shadow, tab4, "def __init__(", parms, ")", returnTypeAnnotation(n), ": \n", NIL);
+ if (have_docstring(n))
+ Printv(f_shadow, tab8, docstring(n, AUTODOC_CTOR, tab8), "\n", NIL);
+ if (have_pythonprepend(n))
+ Printv(f_shadow, pythoncode(pythonprepend(n), tab8), "\n", NIL);
+ Printv(f_shadow, pass_self, NIL);
+ if (fastinit) {
+ Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self,", funcCall(Swig_name_construct(symname), callParms), ")\n", NIL);
+ } else {
+ Printv(f_shadow,
+ tab8, "this = ", funcCall(Swig_name_construct(symname), callParms), "\n",
+ tab8, "try: self.this.append(this)\n", tab8, "except: self.this = this\n", NIL);
+ }
+ if (have_pythonappend(n))
+ Printv(f_shadow, pythoncode(pythonappend(n), tab8), "\n\n", NIL);
+ Delete(pass_self);
+ }
+ have_constructor = 1;
+ } else {
+ /* Hmmm. We seem to be creating a different constructor. We're just going to create a
+ function for it. */
+
+ if (Getattr(n, "feature:shadow")) {
+ String *pycode = pythoncode(Getattr(n, "feature:shadow"), "");
+ String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(symname));
+ Replaceall(pycode, "$action", pyaction);
+ Delete(pyaction);
+ Printv(f_shadow_stubs, pycode, "\n", NIL);
+ Delete(pycode);
+ } else {
+ String *parms = make_pyParmList(n, true, false, allow_kwargs);
+ String *callParms = make_pyParmList(n, true, true, allow_kwargs);
+
+ Printv(f_shadow_stubs, "\ndef ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
+ if (have_docstring(n))
+ Printv(f_shadow_stubs, tab4, docstring(n, AUTODOC_CTOR, tab4), "\n", NIL);
+ if (have_pythonprepend(n))
+ Printv(f_shadow_stubs, pythoncode(pythonprepend(n), tab4), "\n", NIL);
+ Printv(f_shadow_stubs, tab4, "val = ", funcCall(Swig_name_construct(symname), callParms), "\n", NIL);
+#ifdef USE_THISOWN
+ Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL);
+#endif
+ if (have_pythonappend(n))
+ Printv(f_shadow_stubs, pythoncode(pythonappend(n), tab4), "\n", NIL);
+ Printv(f_shadow_stubs, tab4, "return val\n", NIL);
+ }
+ }
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorHandler(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ int oldshadow = shadow;
+
+ if (shadow)
+ shadow = shadow | PYSHADOW_MEMBER;
+ //Setattr(n,"emit:dealloc","1");
+ Language::destructorHandler(n);
+ shadow = oldshadow;
+ if (shadow) {
+ if (Getattr(n, "feature:shadow")) {
+ String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4);
+ String *pyaction = NewStringf("%s.%s", module, Swig_name_destroy(symname));
+ Replaceall(pycode, "$action", pyaction);
+ Delete(pyaction);
+ Printv(f_shadow, pycode, "\n", NIL);
+ Delete(pycode);
+ } else {
+ Printv(f_shadow, tab4, "__swig_destroy__ = ", module, ".", Swig_name_destroy(symname), "\n", NIL);
+ if (!have_pythonprepend(n) && !have_pythonappend(n)) {
+ if (proxydel) {
+ Printv(f_shadow, tab4, "__del__ = lambda self : None;\n", NIL);
+ }
+ return SWIG_OK;
+ }
+ Printv(f_shadow, tab4, "def __del__(self):\n", NIL);
+ if (have_docstring(n))
+ Printv(f_shadow, tab8, docstring(n, AUTODOC_DTOR, tab8), "\n", NIL);
+ if (have_pythonprepend(n))
+ Printv(f_shadow, pythoncode(pythonprepend(n), tab8), "\n", NIL);
+#ifdef USE_THISOWN
+ Printv(f_shadow, tab8, "try:\n", NIL);
+ Printv(f_shadow, tab8, tab4, "if self.thisown: ", module, ".", Swig_name_destroy(symname), "(self)\n", NIL);
+ Printv(f_shadow, tab8, "except: pass\n", NIL);
+#else
+#endif
+ if (have_pythonappend(n))
+ Printv(f_shadow, pythoncode(pythonappend(n), tab8), "\n", NIL);
+ Printv(f_shadow, tab8, "pass\n", NIL);
+ Printv(f_shadow, "\n", NIL);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int membervariableHandler(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+
+ int oldshadow = shadow;
+ if (shadow)
+ shadow = shadow | PYSHADOW_MEMBER;
+ Language::membervariableHandler(n);
+ shadow = oldshadow;
+
+ if (shadow) {
+ String *mname = Swig_name_member(class_name, symname);
+ String *setname = Swig_name_set(mname);
+ String *getname = Swig_name_get(mname);
+ if (shadow) {
+ int assignable = is_assignable(n);
+ if (!modern) {
+ if (assignable) {
+ Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", setname, "\n", NIL);
+ }
+ Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", getname, "\n", NIL);
+ }
+ if (!classic) {
+ if (!assignable) {
+ Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ")\n", NIL);
+ } else {
+ Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ", ", module, ".", setname, ")\n", NIL);
+ }
+ }
+ }
+ Delete(mname);
+ Delete(setname);
+ Delete(getname);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * staticmembervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ Language::staticmembervariableHandler(n);
+
+ if (shadow && !GetFlag(n, "wrappedasconstant")) {
+ String *symname = Getattr(n, "sym:name");
+ if (GetFlag(n, "hasconsttype")) {
+ String *mname = Swig_name_member(class_name, symname);
+ Printf(f_shadow_stubs, "%s.%s = %s.%s.%s\n", class_name, symname, module, global_name, mname);
+ Delete(mname);
+ } else {
+ String *mname = Swig_name_member(class_name, symname);
+ String *getname = Swig_name_get(mname);
+ String *wrapgetname = Swig_name_wrapper(getname);
+ String *vargetname = NewStringf("Swig_var_%s", getname);
+ String *setname = Swig_name_set(mname);
+ String *wrapsetname = Swig_name_wrapper(setname);
+ String *varsetname = NewStringf("Swig_var_%s", setname);
+
+ Wrapper *f = NewWrapper();
+ Printv(f->def, "SWIGINTERN PyObject *", wrapgetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(args)) {", NIL);
+ Printv(f->code, " return ", vargetname, "();\n", NIL);
+ Append(f->code, "}\n");
+ add_method(getname, wrapgetname, 0);
+ Wrapper_print(f, f_wrappers);
+ DelWrapper(f);
+ int assignable = is_assignable(n);
+ if (assignable) {
+ Wrapper *f = NewWrapper();
+ Printv(f->def, "SWIGINTERN PyObject *", wrapsetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {", NIL);
+ Wrapper_add_local(f, "value", "PyObject *value");
+ Wrapper_add_local(f, "res", "int res");
+ Append(f->code, "if (!PyArg_ParseTuple(args,(char *)\"O:set\",&value)) return NULL;\n");
+ Printv(f->code, "res = ", varsetname, "(value);\n", NIL);
+ Append(f->code, "return !res ? SWIG_Py_Void() : NULL;\n");
+ Append(f->code, "}\n");
+ Wrapper_print(f, f_wrappers);
+ add_method(setname, wrapsetname, 0);
+ DelWrapper(f);
+ }
+ if (!modern) {
+ if (assignable) {
+ Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", setname, "\n", NIL);
+ }
+ Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", getname, "\n", NIL);
+ }
+ if (!classic) {
+ if (!assignable) {
+ Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ")\n", NIL);
+ } else {
+ Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ", ", module, ".", setname, ")\n", NIL);
+ }
+ }
+ Delete(mname);
+ Delete(getname);
+ Delete(wrapgetname);
+ Delete(vargetname);
+ Delete(setname);
+ Delete(wrapsetname);
+ Delete(varsetname);
+ }
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberconstantHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberconstantHandler(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ int oldshadow = shadow;
+ if (shadow)
+ shadow = shadow | PYSHADOW_MEMBER;
+ Language::memberconstantHandler(n);
+ shadow = oldshadow;
+
+ if (shadow) {
+ Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(class_name, symname), "\n", NIL);
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * 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, NIL);
+ Delete(pycode);
+ }
+ } else {
+ Language::insertDirective(n);
+ }
+ return SWIG_OK;
+ }
+
+ virtual String *runtimeCode() {
+ String *s = NewString("");
+ String *shead = Swig_include_sys("pyhead.swg");
+ if (!shead) {
+ Printf(stderr, "*** Unable to open 'pyhead.swg'\n");
+ } else {
+ Append(s, shead);
+ Delete(shead);
+ }
+ String *serrors = Swig_include_sys("pyerrors.swg");
+ if (!serrors) {
+ Printf(stderr, "*** Unable to open 'pyerrors.swg'\n");
+ } else {
+ Append(s, serrors);
+ Delete(serrors);
+ }
+ String *sthread = Swig_include_sys("pythreads.swg");
+ if (!sthread) {
+ Printf(stderr, "*** Unable to open 'pythreads.swg'\n");
+ } else {
+ Append(s, sthread);
+ Delete(sthread);
+ }
+ String *sapi = Swig_include_sys("pyapi.swg");
+ if (!sapi) {
+ Printf(stderr, "*** Unable to open 'pyapi.swg'\n");
+ } else {
+ Append(s, sapi);
+ Delete(sapi);
+ }
+ String *srun = Swig_include_sys("pyrun.swg");
+ if (!srun) {
+ Printf(stderr, "*** Unable to open 'pyrun.swg'\n");
+ } else {
+ Append(s, srun);
+ Delete(srun);
+ }
+ return s;
+ }
+
+ virtual String *defaultExternalRuntimeFilename() {
+ return NewString("swigpyrun.h");
+ }
+
+};
+
+/* ---------------------------------------------------------------
+ * classDirectorMethod()
+ *
+ * Emit a virtual director method to pass a method call on to the
+ * underlying Python object.
+ *
+ * ** Moved it here due to internal error on gcc-2.96 **
+ * --------------------------------------------------------------- */
+int PYTHON::classDirectorMethods(Node *n) {
+ director_method_index = 0;
+ return Language::classDirectorMethods(n);
+}
+
+
+int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
+ int is_void = 0;
+ int is_pointer = 0;
+ String *decl;
+ String *type;
+ String *name;
+ String *classname;
+ String *c_classname = Getattr(parent, "name");
+ String *declaration;
+ ParmList *l;
+ Wrapper *w;
+ String *tm;
+ String *wrap_args = NewString("");
+ String *return_type;
+ String *value = Getattr(n, "value");
+ String *storage = Getattr(n, "storage");
+ bool pure_virtual = false;
+ int status = SWIG_OK;
+ int idx;
+ bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
+
+ if (Cmp(storage, "virtual") == 0) {
+ if (Cmp(value, "0") == 0) {
+ pure_virtual = true;
+ }
+ }
+
+ classname = Getattr(parent, "sym:name");
+ type = Getattr(n, "type");
+ name = Getattr(n, "name");
+
+ w = NewWrapper();
+ declaration = NewString("");
+
+ /* determine if the method returns a pointer */
+ decl = Getattr(n, "decl");
+ is_pointer = SwigType_ispointer_return(decl);
+ is_void = (!Cmp(type, "void") && !is_pointer);
+
+ /* form complete return type */
+ return_type = Copy(type);
+ {
+ SwigType *t = Copy(decl);
+ SwigType *f = 0;
+ f = SwigType_pop_function(t);
+ SwigType_push(return_type, t);
+ Delete(f);
+ Delete(t);
+ }
+
+ /* virtual method definition */
+ l = Getattr(n, "parms");
+ String *target;
+ String *pclassname = NewStringf("SwigDirector_%s", classname);
+ String *qualified_name = NewStringf("%s::%s", pclassname, name);
+ SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type;
+ target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+ Printf(w->def, "%s", target);
+ Delete(qualified_name);
+ Delete(target);
+ /* header declaration */
+ target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+ Printf(declaration, " virtual %s", target);
+ Delete(target);
+
+ // Get any exception classes in the throws typemap
+ ParmList *throw_parm_list = 0;
+
+ if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
+ Parm *p;
+ int gencomma = 0;
+
+ Append(w->def, " throw(");
+ Append(declaration, " throw(");
+
+ if (throw_parm_list)
+ Swig_typemap_attach_parms("throws", throw_parm_list, 0);
+ for (p = throw_parm_list; p; p = nextSibling(p)) {
+ if ((tm = Getattr(p, "tmap:throws"))) {
+ if (gencomma++) {
+ Append(w->def, ", ");
+ Append(declaration, ", ");
+ }
+ String *str = SwigType_str(Getattr(p, "type"), 0);
+ Append(w->def, str);
+ Append(declaration, str);
+ Delete(str);
+ }
+ }
+
+ Append(w->def, ")");
+ Append(declaration, ")");
+ }
+
+ Append(w->def, " {");
+ Append(declaration, ";\n");
+
+ /* declare method return value
+ * if the return value is a reference or const reference, a specialized typemap must
+ * handle it, including declaration of c_result ($result).
+ */
+ if (!is_void) {
+ if (!(ignored_method && !pure_virtual)) {
+ String *cres = SwigType_lstr(return_type, "c_result");
+ Printf(w->code, "%s;\n", cres);
+ Delete(cres);
+ }
+ }
+
+ if (ignored_method) {
+ if (!pure_virtual) {
+ if (!is_void)
+ Printf(w->code, "return ");
+ String *super_call = Swig_method_call(super, l);
+ Printf(w->code, "%s;\n", super_call);
+ Delete(super_call);
+ } else {
+ Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
+ SwigType_namestr(name));
+ }
+ } else {
+ /* attach typemaps to arguments (C/C++ -> Python) */
+ String *arglist = NewString("");
+ String *parse_args = NewString("");
+
+ /* remove the wrapper 'w' since it was producing spurious temps */
+ Swig_typemap_attach_parms("in", l, 0);
+ Swig_typemap_attach_parms("directorin", l, 0);
+ Swig_typemap_attach_parms("directorargout", l, w);
+
+ Parm *p;
+ char source[256];
+
+ int outputs = 0;
+ if (!is_void)
+ outputs++;
+
+ /* build argument list and type conversion string */
+ idx = 0;
+ p = l;
+ int use_parse = 0;
+ while (p != NULL) {
+ if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+
+ /* old style? caused segfaults without the p!=0 check
+ in the for() condition, and seems dangerous in the
+ while loop as well.
+ while (Getattr(p, "tmap:ignore")) {
+ p = Getattr(p, "tmap:ignore:next");
+ }
+ */
+
+ if (Getattr(p, "tmap:directorargout") != 0)
+ outputs++;
+
+ String *pname = Getattr(p, "name");
+ String *ptype = Getattr(p, "type");
+
+ Putc(',', arglist);
+ if ((tm = Getattr(p, "tmap:directorin")) != 0) {
+ String *parse = Getattr(p, "tmap:directorin:parse");
+ if (!parse) {
+ sprintf(source, "obj%d", idx++);
+ String *input = NewString(source);
+ Replaceall(tm, "$input", input);
+ Delete(input);
+ Replaceall(tm, "$owner", "0");
+ /* Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL); */
+ Printv(wrap_args, "swig::SwigVar_PyObject ", source, ";\n", NIL);
+
+ Printv(wrap_args, tm, "\n", NIL);
+ Printv(arglist, "(PyObject *)", source, NIL);
+ Putc('O', parse_args);
+ } else {
+ use_parse = 1;
+ Append(parse_args, parse);
+ Replaceall(tm, "$input", pname);
+ Replaceall(tm, "$owner", "0");
+ if (Len(tm) == 0)
+ Append(tm, pname);
+ Append(arglist, tm);
+ }
+ p = Getattr(p, "tmap:directorin:next");
+ continue;
+ } else if (Cmp(ptype, "void")) {
+ /* special handling for pointers to other C++ director classes.
+ * ideally this would be left to a typemap, but there is currently no
+ * way to selectively apply the dynamic_cast<> to classes that have
+ * directors. in other words, the type "SwigDirector_$1_lname" only exists
+ * for classes with directors. we avoid the problem here by checking
+ * module.wrap::directormap, but it's not clear how to get a typemap to
+ * do something similar. perhaps a new default typemap (in addition
+ * to SWIGTYPE) called DIRECTORTYPE?
+ */
+ if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
+ Node *module = Getattr(parent, "module");
+ Node *target = Swig_directormap(module, ptype);
+ sprintf(source, "obj%d", idx++);
+ String *nonconst = 0;
+ /* strip pointer/reference --- should move to Swig/stype.c */
+ String *nptype = NewString(Char(ptype) + 2);
+ /* name as pointer */
+ String *ppname = Copy(pname);
+ if (SwigType_isreference(ptype)) {
+ Insert(ppname, 0, "&");
+ }
+ /* if necessary, cast away const since Python doesn't support it! */
+ if (SwigType_isconst(nptype)) {
+ nonconst = NewStringf("nc_tmp_%s", pname);
+ String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(ptype, 0), ppname);
+ Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
+ Delete(nonconst_i);
+ Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
+ "Target language argument '%s' discards const in director method %s::%s.\n",
+ SwigType_str(ptype, pname), SwigType_namestr(c_classname), SwigType_namestr(name));
+ } else {
+ nonconst = Copy(ppname);
+ }
+ Delete(nptype);
+ Delete(ppname);
+ String *mangle = SwigType_manglestr(ptype);
+ if (target) {
+ String *director = NewStringf("director_%s", mangle);
+ Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
+ Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL);
+ Printf(wrap_args, "%s = SWIG_DIRECTOR_CAST(%s);\n", director, nonconst);
+ Printf(wrap_args, "if (!%s) {\n", director);
+ Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
+ Append(wrap_args, "} else {\n");
+ Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
+ Printf(wrap_args, "Py_INCREF((PyObject *)%s);\n", source);
+ Append(wrap_args, "}\n");
+ Delete(director);
+ Printv(arglist, source, NIL);
+ } else {
+ Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL);
+ Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
+ //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
+ // source, nonconst, base);
+ Printv(arglist, source, NIL);
+ }
+ Putc('O', parse_args);
+ Delete(mangle);
+ Delete(nonconst);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
+ SwigType_namestr(c_classname), SwigType_namestr(name));
+ status = SWIG_NOWRAP;
+ break;
+ }
+ }
+ p = nextSibling(p);
+ }
+
+ /* add the method name as a PyString */
+ String *pyname = Getattr(n, "sym:name");
+
+ int allow_thread = threads_enable(n);
+
+ if (allow_thread) {
+ thread_begin_block(n, w->code);
+ Append(w->code, "{\n");
+ }
+
+ /* wrap complex arguments to PyObjects */
+ Printv(w->code, wrap_args, NIL);
+
+ /* pass the method call on to the Python object */
+ if (dirprot_mode() && !is_public(n)) {
+ Printf(w->code, "swig_set_inner(\"%s\", true);\n", name);
+ }
+
+
+ Append(w->code, "if (!swig_get_self()) {\n");
+ Printf(w->code, " Swig::DirectorException::raise(\"'self' uninitialized, maybe you forgot to call %s.__init__.\");\n", classname);
+ Append(w->code, "}\n");
+ Append(w->code, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n");
+ Printf(w->code, "const size_t swig_method_index = %d;\n", director_method_index++);
+ Printf(w->code, "const char * const swig_method_name = \"%s\";\n", pyname);
+
+ Append(w->code, "PyObject* method = swig_get_method(swig_method_index, swig_method_name);\n");
+ if (Len(parse_args) > 0) {
+ if (use_parse || !modernargs) {
+ Printf(w->code, "swig::SwigVar_PyObject result = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", parse_args, arglist);
+ } else {
+ Printf(w->code, "swig::SwigVar_PyObject result = PyObject_CallFunctionObjArgs(method %s, NULL);\n", arglist);
+ }
+ } else {
+ if (modernargs) {
+ Append(w->code, "swig::SwigVar_PyObject args = PyTuple_New(0);\n");
+ Append(w->code, "swig::SwigVar_PyObject result = PyObject_Call(method, (PyObject*) args, NULL);\n");
+ } else {
+ Printf(w->code, "swig::SwigVar_PyObject result = PyObject_CallFunction(method, NULL, NULL);\n");
+ }
+ }
+ Append(w->code, "#else\n");
+ if (Len(parse_args) > 0) {
+ if (use_parse || !modernargs) {
+ Printf(w->code, "swig::SwigVar_PyObject result = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n",
+ pyname, parse_args, arglist);
+ } else {
+ Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar((char *)\"%s\");\n", pyname);
+ Printf(w->code, "swig::SwigVar_PyObject result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name %s, NULL);\n", arglist);
+ }
+ } else {
+ if (!modernargs) {
+ Printf(w->code, "swig::SwigVar_PyObject result = PyObject_CallMethod(swig_get_self(), (char *) \"%s\", NULL);\n", pyname);
+ } else {
+ Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar((char *)\"%s\");\n", pyname);
+ Append(w->code, "swig::SwigVar_PyObject result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n");
+ }
+ }
+ Append(w->code, "#endif\n");
+
+ if (dirprot_mode() && !is_public(n))
+ Printf(w->code, "swig_set_inner(\"%s\", false);\n", name);
+
+ /* exception handling */
+ tm = Swig_typemap_lookup("director:except", n, "result", 0);
+ if (!tm) {
+ tm = Getattr(n, "feature:director:except");
+ if (tm)
+ tm = Copy(tm);
+ }
+ Append(w->code, "if (result == NULL) {\n");
+ Append(w->code, " PyObject *error = PyErr_Occurred();\n");
+ if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
+ Replaceall(tm, "$error", "error");
+ Printv(w->code, Str(tm), "\n", NIL);
+ } else {
+ Append(w->code, " if (error != NULL) {\n");
+ Printf(w->code, " Swig::DirectorMethodException::raise(\"Error detected when calling '%s.%s'\");\n", classname, pyname);
+ Append(w->code, " }\n");
+ }
+ Append(w->code, "}\n");
+ Delete(tm);
+
+ /*
+ * Python method may return a simple object, or a tuple.
+ * for in/out aruments, we have to extract the appropriate PyObjects from the tuple,
+ * then marshal everything back to C/C++ (return value and output arguments).
+ *
+ */
+
+ /* marshal return value and other outputs (if any) from PyObject to C/C++ type */
+
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+
+ if (outputs > 1) {
+ Wrapper_add_local(w, "output", "PyObject *output");
+ Append(w->code, "if (!PyTuple_Check(result)) {\n");
+ Printf(w->code, " Swig::DirectorTypeMismatchException::raise(\"Python method %s.%sfailed to return a tuple.\");\n", classname, pyname);
+ Append(w->code, "}\n");
+ }
+
+ idx = 0;
+
+ /* marshal return value */
+ if (!is_void) {
+ /* this seems really silly. the node's type excludes
+ * qualifier/pointer/reference markers, which have to be retrieved
+ * from the decl field to construct return_type. but the typemap
+ * lookup routine uses the node's type, so we have to swap in and
+ * out the correct type. it's not just me, similar silliness also
+ * occurs in Language::cDeclaration().
+ */
+ Setattr(n, "type", return_type);
+ tm = Swig_typemap_lookup("directorout", n, "result", w);
+ Setattr(n, "type", type);
+ if (tm != 0) {
+ if (outputs > 1) {
+ Printf(w->code, "output = PyTuple_GetItem(result, %d);\n", idx++);
+ Replaceall(tm, "$input", "output");
+ } else {
+ Replaceall(tm, "$input", "result");
+ }
+ char temp[24];
+ sprintf(temp, "%d", idx);
+ Replaceall(tm, "$argnum", temp);
+
+ /* TODO check this */
+ if (Getattr(n, "wrap:disown")) {
+ Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm, "$disown", "0");
+ }
+ if (Getattr(n, "tmap:directorout:implicitconv")) {
+ Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
+ }
+ Replaceall(tm, "$result", "c_result");
+ Printv(w->code, tm, "\n", NIL);
+ Delete(tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0), SwigType_namestr(c_classname),
+ SwigType_namestr(name));
+ status = SWIG_ERROR;
+ }
+ }
+
+ /* marshal outputs */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
+ if (outputs > 1) {
+ Printf(w->code, "output = PyTuple_GetItem(result, %d);\n", idx++);
+ Replaceall(tm, "$input", "output");
+ } else {
+ Replaceall(tm, "$input", "result");
+ }
+ Replaceall(tm, "$result", Getattr(p, "name"));
+ Printv(w->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:directorargout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* any existing helper functions to handle this? */
+ if (allow_thread) {
+ Append(w->code, "}\n");
+ thread_end_block(n, w->code);
+ }
+
+ Delete(parse_args);
+ Delete(arglist);
+ Delete(cleanup);
+ Delete(outarg);
+ }
+
+ if (!is_void) {
+ if (!(ignored_method && !pure_virtual)) {
+ String *rettype = SwigType_str(return_type, 0);
+ if (!SwigType_isreference(return_type)) {
+ Printf(w->code, "return (%s) c_result;\n", rettype);
+ } else {
+ Printf(w->code, "return (%s) *c_result;\n", rettype);
+ }
+ Delete(rettype);
+ }
+ }
+
+ Append(w->code, "}\n");
+
+ // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
+ String *inline_extra_method = NewString("");
+ if (dirprot_mode() && !is_public(n) && !pure_virtual) {
+ Printv(inline_extra_method, declaration, NIL);
+ String *extra_method_name = NewStringf("%sSwigPublic", name);
+ Replaceall(inline_extra_method, name, extra_method_name);
+ Replaceall(inline_extra_method, ";\n", " {\n ");
+ if (!is_void)
+ Printf(inline_extra_method, "return ");
+ String *methodcall = Swig_method_call(super, l);
+ Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
+ Delete(methodcall);
+ Delete(extra_method_name);
+ }
+
+ /* emit the director method */
+ if (status == SWIG_OK) {
+ if (!Getattr(n, "defaultargs")) {
+ Wrapper_print(w, f_directors);
+ Printv(f_directors_h, declaration, NIL);
+ Printv(f_directors_h, inline_extra_method, NIL);
+ }
+ }
+
+ /* clean up */
+ Delete(wrap_args);
+ Delete(return_type);
+ Delete(pclassname);
+ DelWrapper(w);
+ return status;
+}
+
+/* -----------------------------------------------------------------------------
+ * swig_python() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_python() {
+ return new PYTHON();
+}
+extern "C" Language *swig_python(void) {
+ return new_swig_python();
+}
diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx
new file mode 100644
index 0000000..966feb7
--- /dev/null
+++ b/Source/Modules/r.cxx
@@ -0,0 +1,2745 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * r.cxx
+ *
+ * R language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_r_cxx[] = "$Id: r.cxx 11454 2009-07-26 21:21:26Z wsfulton $";
+
+#include "swigmod.h"
+
+#define UNUSED(a) (void)a
+
+static const double DEFAULT_NUMBER = .0000123456712312312323;
+static const int MAX_OVERLOAD_ARGS = 5;
+
+static String* replaceInitialDash(const String *name)
+{
+ String *retval;
+ if (!Strncmp(name, "_", 1)) {
+ retval = Copy(name);
+ Insert(retval, 0, "s");
+ } else {
+ retval = Copy(name);
+ }
+ return retval;
+}
+
+static String * getRTypeName(SwigType *t, int *outCount = NULL) {
+ String *b = SwigType_base(t);
+ List *els = SwigType_split(t);
+ int count = 0;
+ int i;
+
+ if(Strncmp(b, "struct ", 7) == 0)
+ Replace(b, "struct ", "", DOH_REPLACE_FIRST);
+
+ /* Printf(stderr, "<getRTypeName> %s,base = %s\n", t, b);
+ for(i = 0; i < Len(els); i++)
+ Printf(stderr, "%d) %s, ", i, Getitem(els,i));
+ Printf(stderr, "\n"); */
+
+ for(i = 0; i < Len(els); i++) {
+ String *el = Getitem(els, i);
+ if(Strcmp(el, "p.") == 0 || Strncmp(el, "a(", 2) == 0) {
+ count++;
+ Append(b, "Ref");
+ }
+ }
+ if(outCount)
+ *outCount = count;
+
+ String *tmp = NewString("");
+ char *retName = Char(SwigType_manglestr(t));
+ Insert(tmp, 0, retName);
+ return tmp;
+
+ /*
+ if(count)
+ return(b);
+
+ Delete(b);
+ return(NewString(""));
+ */
+}
+
+#if 0
+static String * getRType(Node *n) {
+ SwigType *elType = Getattr(n, "type");
+ SwigType *elDecl = Getattr(n, "decl");
+ //XXX How can we tell if this is already done.
+ SwigType_push(elType, elDecl);
+ String *ans;
+
+ String *rtype = Swig_typemap_lookup("rtype", n, "", 0);
+ String *i = getRTypeName(elType);
+
+ if(Len(i) == 0) {
+ SwigType *td = SwigType_typedef_resolve(elType);
+ if(td) {
+ // Printf(stderr, "Resolving typedef %s -> %s\n", elType, td);
+ i = getRTypeName(td);
+ }
+ }
+ // Printf(stderr, "<getRType> i = %s, rtype = %s (for %s)\n",
+ // i, rtype, elType);
+ if(rtype) {
+ ans = NewString("");
+ Printf(ans, "%s", rtype);
+ Replaceall(ans, "$R_class", Char(i));
+ // Printf(stderr, "Found r type in typemap for %s (for %s) => %s (%s) => %s\n",
+ // SwigType_str(elType, 0), Getattr(n, "name"), rtype, i, ans);
+ } else {
+ ans = i;
+ }
+
+ return(ans);
+}
+#endif
+
+/*********************
+ Tries to get the name of the R class corresponding to the given type
+ e.g. struct A * is ARef, struct A** is ARefRef.
+ Now handles arrays, i.e. struct A[2]
+****************/
+
+static String *getRClassName(String *retType, int /*addRef*/ = 1, int upRef=0) {
+ String *tmp = NewString("");
+ SwigType *resolved = SwigType_typedef_resolve_all(retType);
+ char *retName = Char(SwigType_manglestr(resolved));
+ if (upRef) {
+ Printf(tmp, "_p%s", retName);
+ } else{
+ Insert(tmp, 0, retName);
+ }
+
+ return tmp;
+/*
+#if 1
+ List *l = SwigType_split(retType);
+ int n = Len(l);
+ if(!l || n == 0) {
+#ifdef R_SWIG_VERBOSE
+ if (debugMode)
+ Printf(stderr, "SwigType_split return an empty list for %s\n",
+ retType);
+#endif
+ return(tmp);
+ }
+
+
+ String *el = Getitem(l, n-1);
+ char *ptr = Char(el);
+ if(strncmp(ptr, "struct ", 7) == 0)
+ ptr += 7;
+
+ Printf(tmp, "%s", ptr);
+
+ if(addRef) {
+ for(int i = 0; i < n; i++) {
+ if(Strcmp(Getitem(l, i), "p.") == 0 ||
+ Strncmp(Getitem(l, i), "a(", 2) == 0)
+ Printf(tmp, "Ref");
+ }
+ }
+
+#else
+ char *retName = Char(SwigType_manglestr(retType));
+ if(!retName)
+ return(tmp);
+
+ if(addRef) {
+ while(retName && strlen(retName) > 1 && strncmp(retName, "_p", 2) == 0) {
+ retName += 2;
+ Printf(tmp, "Ref");
+ }
+ }
+ if(retName[0] == '_')
+ retName ++;
+ Insert(tmp, 0, retName);
+#endif
+
+ return tmp;
+*/
+}
+
+/*********************
+ Tries to get the name of the R class corresponding to the given type
+ e.g. struct A * is ARef, struct A** is ARefRef.
+ Now handles arrays, i.e. struct A[2]
+****************/
+
+static String * getRClassNameCopyStruct(String *retType, int addRef) {
+ String *tmp = NewString("");
+
+#if 1
+ List *l = SwigType_split(retType);
+ int n = Len(l);
+ if(!l || n == 0) {
+#ifdef R_SWIG_VERBOSE
+ Printf(stderr, "SwigType_split return an empty list for %s\n", retType);
+#endif
+ return(tmp);
+ }
+
+
+ String *el = Getitem(l, n-1);
+ char *ptr = Char(el);
+ if(strncmp(ptr, "struct ", 7) == 0)
+ ptr += 7;
+
+ Printf(tmp, "%s", ptr);
+
+ if(addRef) {
+ for(int i = 0; i < n; i++) {
+ if(Strcmp(Getitem(l, i), "p.") == 0 ||
+ Strncmp(Getitem(l, i), "a(", 2) == 0)
+ Printf(tmp, "Ref");
+ }
+ }
+
+#else
+ char *retName = Char(SwigType_manglestr(retType));
+ if(!retName)
+ return(tmp);
+
+ if(addRef) {
+ while(retName && strlen(retName) > 1 &&
+ strncmp(retName, "_p", 2) == 0) {
+ retName += 2;
+ Printf(tmp, "Ref");
+ }
+ }
+
+ if(retName[0] == '_')
+ retName ++;
+ Insert(tmp, 0, retName);
+#endif
+
+ return tmp;
+}
+
+
+/*********************************
+ Write the elements of a list to the File*, one element per line.
+ If quote is true, surround the element with "element".
+ This takes care of inserting a tab in front of each line and also
+ a comma after each element, except the last one.
+**********************************/
+
+static void writeListByLine(List *l, File *out, bool quote = 0) {
+ int i, n = Len(l);
+ for(i = 0; i < n; i++)
+ Printf(out, "%s%s%s%s%s\n", tab8,
+ quote ? "\"" :"",
+ Getitem(l, i),
+ quote ? "\"" :"", i < n-1 ? "," : "");
+}
+
+
+static const char *usage = (char *)"\
+R Options (available with -r)\n\
+ -copystruct - Emit R code to copy C structs (on by default)\n\
+ -cppcast - Enable C++ casting operators (default) \n\
+ -debug - Output debug\n\
+ -dll <name> - Name of the DLL (without the .dll or .so suffix). Default is the module name.\n\
+ -gc - Aggressive garbage collection\n\
+ -memoryprof - Add memory profile\n\
+ -namespace - Output NAMESPACE file\n\
+ -no-init-code - Turn off the generation of the R_init_<pkgname> code (registration information still generated)\n\
+ -package <name> - Package name for the PACKAGE argument of the R .Call() invocations. Default is the module name.\n\
+";
+
+
+
+/************
+ Display the help for this module on the screen/console.
+*************/
+static void showUsage() {
+ fputs(usage, stdout);
+}
+
+static bool expandTypedef(SwigType *t) {
+ if (SwigType_isenum(t)) return false;
+ String *prefix = SwigType_prefix(t);
+ if (Strncmp(prefix, "f", 1)) return false;
+ if (Strncmp(prefix, "p.f", 3)) return false;
+ return true;
+}
+
+
+/*****
+ Determine whether we should add a .copy argument to the S function
+ that wraps/interfaces to the routine that returns the given type.
+*****/
+static int addCopyParameter(SwigType *type) {
+ int ok = 0;
+ ok = Strncmp(type, "struct ", 7) == 0 || Strncmp(type, "p.struct ", 9) == 0;
+ if(!ok) {
+ ok = Strncmp(type, "p.", 2);
+ }
+
+ return(ok);
+}
+
+static void replaceRClass(String *tm, SwigType *type) {
+ String *tmp = getRClassName(type);
+ String *tmp_base = getRClassName(type, 0);
+ String *tmp_ref = getRClassName(type, 1, 1);
+ Replaceall(tm, "$R_class", tmp);
+ Replaceall(tm, "$*R_class", tmp_base);
+ Replaceall(tm, "$&R_class", tmp_ref);
+ Delete(tmp); Delete(tmp_base); Delete(tmp_ref);
+}
+
+static double getNumber(String *value, String *type) {
+ UNUSED(type);
+
+ double d = DEFAULT_NUMBER;
+ if(Char(value)) {
+ // Printf(stderr, "getNumber %s %s\n", Char(value), type);
+ if(sscanf(Char(value), "%lf", &d) != 1)
+ return(DEFAULT_NUMBER);
+ }
+ return(d);
+}
+
+class R : public Language {
+public:
+ R();
+ void registerClass(Node *n);
+ void main(int argc, char *argv[]);
+ int top(Node *n);
+
+ void dispatchFunction(Node *n);
+ int functionWrapper(Node *n);
+ int variableWrapper(Node *n);
+
+ int classDeclaration(Node *n);
+ int enumDeclaration(Node *n);
+
+ int membervariableHandler(Node *n);
+
+ int typedefHandler(Node *n);
+
+ int memberfunctionHandler(Node *n) {
+ if (debugMode)
+ Printf(stderr, "<memberfunctionHandler> %s %s\n",
+ Getattr(n, "name"),
+ Getattr(n, "type"));
+ member_name = Getattr(n, "name");
+ processing_class_member_function = 1;
+ int status = Language::memberfunctionHandler(n);
+ processing_class_member_function = 0;
+ return status;
+ }
+
+ /* Grab the name of the current class being processed so that we can
+ deal with members of that class. */
+ int classHandler(Node *n){
+ if(!ClassMemberTable)
+ ClassMemberTable = NewHash();
+
+ class_name = Getattr(n, "name");
+ int status = Language::classHandler(n);
+
+ class_name = NULL;
+ return status;
+ }
+
+ // Not used:
+ String *runtimeCode();
+
+protected:
+ int addRegistrationRoutine(String *rname, int nargs);
+ int outputRegistrationRoutines(File *out);
+
+ int outputCommandLineArguments(File *out);
+ int generateCopyRoutines(Node *n);
+ int DumpCode(Node *n);
+
+ int OutputMemberReferenceMethod(String *className, int isSet, List *el, File *out);
+ int OutputArrayMethod(String *className, List *el, File *out);
+ int OutputClassMemberTable(Hash *tb, File *out);
+ int OutputClassMethodsTable(File *out);
+ int OutputClassAccessInfo(Hash *tb, File *out);
+
+ int defineArrayAccessors(SwigType *type);
+
+ void addNamespaceFunction(String *name) {
+ if(!namespaceFunctions)
+ namespaceFunctions = NewList();
+ Append(namespaceFunctions, name);
+ }
+
+ void addNamespaceMethod(String *name) {
+ if(!namespaceMethods)
+ namespaceMethods = NewList();
+ Append(namespaceMethods, name);
+ }
+
+ String* processType(SwigType *t, Node *n, int *nargs = NULL);
+ String *createFunctionPointerHandler(SwigType *t, Node *n, int *nargs);
+ int addFunctionPointerProxy(String *name, Node *n, SwigType *t, String *s_paramTypes) {
+ /*XXX Do we need to put the t in there to get the return type later. */
+ if(!functionPointerProxyTable)
+ functionPointerProxyTable = NewHash();
+
+ Setattr(functionPointerProxyTable, name, n);
+
+ Setattr(SClassDefs, name, name);
+ Printv(s_classes, "setClass('",
+ name,
+ "',\n", tab8,
+ "prototype = list(parameterTypes = c(", s_paramTypes, "),\n",
+ tab8, tab8, tab8,
+ "returnType = '", SwigType_manglestr(t), "'),\n", tab8,
+ "contains = 'CRoutinePointer')\n\n##\n", NIL);
+
+ return SWIG_OK;
+ }
+
+
+ void addSMethodInfo(String *name,
+ String *argType, int nargs);
+ // Simple initialization such as constant strings that can be reused.
+ void init();
+
+
+ void addAccessor(String *memberName, Wrapper *f,
+ String *name, int isSet = -1);
+
+ static int getFunctionPointerNumArgs(Node *n, SwigType *tt);
+
+protected:
+ bool copyStruct;
+ bool memoryProfile;
+ bool aggressiveGc;
+
+ // Strings into which we cumulate the generated code that is to be written
+ //vto the files.
+ String *sfile;
+ String *f_init;
+ String *s_classes;
+ String *f_begin;
+ String *f_runtime;
+ String *f_wrapper;
+ String *s_header;
+ String *f_wrappers;
+ String *s_init;
+ String *s_init_routine;
+ String *s_namespace;
+
+ // State variables that carry information across calls to functionWrapper()
+ // from member accessors and class declarations.
+ String *opaqueClassDeclaration;
+ int processing_variable;
+ int processing_member_access_function;
+ String *member_name;
+ String *class_name;
+
+
+ int processing_class_member_function;
+ List *class_member_functions;
+ List *class_member_set_functions;
+
+ /* */
+ Hash *ClassMemberTable;
+ Hash *ClassMethodsTable;
+ Hash *SClassDefs;
+ Hash *SMethodInfo;
+
+ // Information about routines that are generated and to be registered with
+ // R for dynamic lookup.
+ Hash *registrationTable;
+ Hash *functionPointerProxyTable;
+
+ List *namespaceFunctions;
+ List *namespaceMethods;
+ List *namespaceClasses; // Probably can do this from ClassMemberTable.
+
+
+ // Store a copy of the command line.
+ // Need only keep a string that has it formatted.
+ char **Argv;
+ int Argc;
+ bool inCPlusMode;
+
+ // State variables that we remember from the command line settings
+ // potentially that govern the code we generate.
+ String *DllName;
+ String *Rpackage;
+ bool noInitializationCode;
+ bool outputNamespaceInfo;
+
+ String *UnProtectWrapupCode;
+
+ // Static members
+ static bool debugMode;
+};
+
+R::R() :
+ copyStruct(false),
+ memoryProfile(false),
+ aggressiveGc(false),
+ sfile(0),
+ f_init(0),
+ s_classes(0),
+ f_begin(0),
+ f_runtime(0),
+ f_wrapper(0),
+ s_header(0),
+ f_wrappers(0),
+ s_init(0),
+ s_init_routine(0),
+ s_namespace(0),
+ opaqueClassDeclaration(0),
+ processing_variable(0),
+ processing_member_access_function(0),
+ member_name(0),
+ class_name(0),
+ processing_class_member_function(0),
+ class_member_functions(0),
+ class_member_set_functions(0),
+ ClassMemberTable(0),
+ ClassMethodsTable(0),
+ SClassDefs(0),
+ SMethodInfo(0),
+ registrationTable(0),
+ functionPointerProxyTable(0),
+ namespaceFunctions(0),
+ namespaceMethods(0),
+ namespaceClasses(0),
+ Argv(0),
+ Argc(0),
+ inCPlusMode(false),
+ DllName(0),
+ Rpackage(0),
+ noInitializationCode(false),
+ outputNamespaceInfo(false),
+ UnProtectWrapupCode(0) {
+}
+
+bool R::debugMode = false;
+
+int R::getFunctionPointerNumArgs(Node *n, SwigType *tt) {
+ (void) tt;
+ n = Getattr(n, "type");
+ if (debugMode)
+ Printf(stderr, "type: %s\n", n);
+#if 0
+ SwigType *tmp = SwigType_typedef_resolve(tt);
+
+ n = SwigType_typedef_resolve(tt);
+#endif
+
+ ParmList *parms = Getattr(n, "parms");
+ if (debugMode)
+ Printf(stderr, "parms = %p\n", parms);
+ return ParmList_len(parms);
+}
+
+
+void R::addSMethodInfo(String *name, String *argType, int nargs) {
+ (void) argType;
+
+ if(!SMethodInfo)
+ SMethodInfo = NewHash();
+ if (debugMode)
+ Printf(stderr, "[addMethodInfo] %s\n", name);
+
+ Hash *tb = Getattr(SMethodInfo, name);
+
+ if(!tb) {
+ tb = NewHash();
+ Setattr(SMethodInfo, name, tb);
+ }
+
+ String *str = Getattr(tb, "max");
+ int max = -1;
+ if(str)
+ max = atoi(Char(str));
+ if(max < nargs) {
+ if(str) Delete(str);
+ str = NewStringf("%d", max);
+ Setattr(tb, "max", str);
+ }
+}
+
+/*
+Returns the name of the new routine.
+*/
+String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
+ String *funName = SwigType_manglestr(t);
+
+ /* See if we have already processed this one. */
+ if(functionPointerProxyTable && Getattr(functionPointerProxyTable, funName))
+ return funName;
+
+ if (debugMode)
+ Printf(stderr, "<createFunctionPointerHandler> Defining %s\n", t);
+
+ SwigType *rettype = Copy(Getattr(n, "type"));
+ SwigType *funcparams = SwigType_functionpointer_decompose(rettype);
+ String *rtype = SwigType_str(rettype, 0);
+
+ // ParmList *parms = Getattr(n, "parms");
+ // memory leak
+ ParmList *parms = SwigType_function_parms(SwigType_del_pointer(Copy(t)));
+
+
+ // if (debugMode) {
+ Printf(stderr, "Type: %s\n", t);
+ Printf(stderr, "Return type: %s\n", SwigType_base(t));
+ //}
+
+ bool isVoidType = Strcmp(rettype, "void") == 0;
+ if (debugMode)
+ Printf(stderr, "%s is void ? %s (%s)\n", funName, isVoidType ? "yes" : "no", rettype);
+
+ Wrapper *f = NewWrapper();
+
+ /* Go through argument list, attach lnames for arguments */
+ int i = 0;
+ Parm *p = parms;
+ for (i = 0; p; p = nextSibling(p), ++i) {
+ String *arg = Getattr(p, "name");
+ String *lname = NewString("");
+
+ if (!arg && Cmp(Getattr(p, "type"), "void")) {
+ lname = NewStringf("s_arg%d", i+1);
+ Setattr(p, "name", lname);
+ } else
+ lname = arg;
+
+ Setattr(p, "lname", lname);
+ }
+
+ Swig_typemap_attach_parms("out", parms, f);
+ Swig_typemap_attach_parms("scoerceout", parms, f);
+ Swig_typemap_attach_parms("scheck", parms, f);
+
+ Printf(f->def, "%s %s(", rtype, funName);
+
+ emit_parameter_variables(parms, f);
+ emit_return_variable(n, rettype, f);
+// emit_attach_parmmaps(parms,f);
+
+ /* Using weird name and struct to avoid potential conflicts. */
+ Wrapper_add_local(f, "r_swig_cb_data", "RCallbackFunctionData *r_swig_cb_data = R_SWIG_getCallbackFunctionData()");
+ String *lvar = NewString("r_swig_cb_data");
+
+ Wrapper_add_local(f, "r_tmp", "SEXP r_tmp"); // for use in converting arguments to R objects for call.
+ Wrapper_add_local(f, "r_nprotect", "int r_nprotect = 0"); // for use in converting arguments to R objects for call.
+ Wrapper_add_local(f, "r_vmax", "char * r_vmax= 0"); // for use in converting arguments to R objects for call.
+
+ // Add local for error code in return value. This is not in emit_return_variable because that assumes an out typemap
+ // whereas the type makes are reverse
+ Wrapper_add_local(f, "ecode", "int ecode = 0");
+
+ p = parms;
+ int nargs = ParmList_len(parms);
+ if(numArgs) {
+ *numArgs = nargs;
+ if (debugMode)
+ Printf(stderr, "Setting number of parameters to %d\n", *numArgs);
+ }
+ String *setExprElements = NewString("");
+
+ String *s_paramTypes = NewString("");
+ for(i = 0; p; i++) {
+ SwigType *tt = Getattr(p, "type");
+ SwigType *name = Getattr(p, "name");
+ // String *lname = Getattr(p,"lname");
+ Printf(f->def, "%s %s", SwigType_str(tt, 0), name);
+ String *tm = Getattr(p, "tmap:out");
+ if(tm) {
+ Replaceall(tm, "$1", name);
+ Replaceall(tm, "$result", "r_tmp");
+ replaceRClass(tm, Getattr(p,"type"));
+ Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
+ }
+
+ Printf(setExprElements, "%s\n", tm);
+ Printf(setExprElements, "SETCAR(r_swig_cb_data->el, %s);\n", "r_tmp");
+ Printf(setExprElements, "r_swig_cb_data->el = CDR(r_swig_cb_data->el);\n\n");
+
+ Printf(s_paramTypes, "'%s'", SwigType_manglestr(tt));
+
+
+ p = nextSibling(p);
+ if(p) {
+ Printf(f->def, ", ");
+ Printf(s_paramTypes, ", ");
+ }
+ }
+
+ Printf(f->def, ") {\n");
+
+ Printf(f->code, "Rf_protect(%s->expr = Rf_allocVector(LANGSXP, %d));\n", lvar, nargs + 1);
+ Printf(f->code, "r_nprotect++;\n");
+ Printf(f->code, "r_swig_cb_data->el = r_swig_cb_data->expr;\n\n");
+
+ Printf(f->code, "SETCAR(r_swig_cb_data->el, r_swig_cb_data->fun);\n");
+ Printf(f->code, "r_swig_cb_data->el = CDR(r_swig_cb_data->el);\n\n");
+
+ Printf(f->code, "%s\n\n", setExprElements);
+
+ Printv(f->code, "r_swig_cb_data->retValue = R_tryEval(",
+ "r_swig_cb_data->expr,",
+ " R_GlobalEnv,",
+ " &r_swig_cb_data->errorOccurred",
+ ");\n",
+ NIL);
+
+ Printv(f->code, "\n",
+ "if(r_swig_cb_data->errorOccurred) {\n",
+ "R_SWIG_popCallbackFunctionData(1);\n",
+ "Rf_error(\"error in calling R function as a function pointer (",
+ funName,
+ ")\");\n",
+ "}\n",
+ NIL);
+
+
+
+ if(!isVoidType) {
+ /* Need to deal with the return type of the function pointer, not the function pointer itself.
+ So build a new node that has the relevant pieces.
+ XXX Have to be a little more clever so that we can deal with struct A * - the * is getting lost.
+ Is this still true? If so, will a SwigType_push() solve things?
+ */
+ Node *bbase = NewHash();
+
+ Setattr(bbase, "type", rettype);
+ Setattr(bbase, "name", NewString("result"));
+ String *returnTM = Swig_typemap_lookup("in", bbase, "result", f);
+ if(returnTM) {
+ String *tm = returnTM;
+ Replaceall(tm,"$input", "r_swig_cb_data->retValue");
+ Replaceall(tm,"$target", "result");
+ replaceRClass(tm, rettype);
+ Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
+ Replaceall(tm,"$disown","0");
+ Printf(f->code, "%s\n", tm);
+ }
+ Delete(bbase);
+ }
+
+ Printv(f->code, "R_SWIG_popCallbackFunctionData(1);\n", NIL);
+ Printv(f->code, "\n", UnProtectWrapupCode, NIL);
+
+ if(!isVoidType)
+ Printv(f->code, "return result;\n", NIL);
+
+ Printv(f->code, "\n}\n", NIL);
+
+ /* To coerce correctly in S, we really want to have an extra/intermediate
+ function that handles the scoerceout.
+ We need to check if any of the argument types have an entry in
+ that map. If none do, the ignore and call the function straight.
+ Otherwise, generate the a marshalling function.
+ Need to be able to find it in S. Or use an entirely generic one
+ that evaluates the expressions.
+ Handle errors in the evaluation of the function by restoring
+ the stack, if there is one in use for this function (i.e. no
+ userData).
+ */
+
+ Wrapper_print(f, f_wrapper);
+
+ addFunctionPointerProxy(funName, n, t, s_paramTypes);
+ Delete(s_paramTypes);
+ Delete(rtype);
+ Delete(rettype);
+ Delete(funcparams);
+
+ return funName;
+}
+
+void R::init() {
+ UnProtectWrapupCode =
+ NewStringf("%s", "vmaxset(r_vmax);\nif(r_nprotect) Rf_unprotect(r_nprotect);\n\n");
+
+ SClassDefs = NewHash();
+
+ sfile = NewString("");
+ f_init = NewString("");
+ s_header = NewString("");
+ f_begin = NewString("");
+ f_runtime = NewString("");
+ f_wrapper = NewString("");
+ s_classes = NewString("");
+ s_init = NewString("");
+ s_init_routine = NewString("");
+}
+
+
+
+#if 0
+int R::cDeclaration(Node *n) {
+ SwigType *t = Getattr(n, "type");
+ SwigType *name = Getattr(n, "name");
+ if (debugMode)
+ Printf(stderr, "cDeclaration (%s): %s\n", name, SwigType_lstr(t, 0));
+ return Language::cDeclaration(n);
+}
+#endif
+
+
+/**
+ Method from Language that is called to start the entire
+ processing off, i.e. the generation of the code.
+ It is called after the input has been read and parsed.
+ Here we open the output streams and generate the code.
+***/
+int R::top(Node *n) {
+ String *module = Getattr(n, "name");
+ if(!Rpackage)
+ Rpackage = Copy(module);
+ if(!DllName)
+ DllName = Copy(module);
+
+ if(outputNamespaceInfo) {
+ s_namespace = NewString("");
+ Swig_register_filebyname("snamespace", s_namespace);
+ Printf(s_namespace, "useDynLib(%s)\n", DllName);
+ }
+
+ /* Associate the different streams with names so that they can be used in %insert directives by the
+ typemap code. */
+ Swig_register_filebyname("sinit", s_init);
+ Swig_register_filebyname("sinitroutine", s_init_routine);
+
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+ Swig_register_filebyname("header", s_header);
+ Swig_register_filebyname("wrapper", f_wrapper);
+ Swig_register_filebyname("s", sfile);
+ Swig_register_filebyname("sclasses", s_classes);
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGR\n");
+ Printf(f_runtime, "\n");
+
+
+ Swig_banner_target_lang(s_init, "#");
+ outputCommandLineArguments(s_init);
+
+ Printf(f_wrapper, "#ifdef __cplusplus\n");
+ Printf(f_wrapper, "extern \"C\" {\n");
+ Printf(f_wrapper, "#endif\n\n");
+
+ Language::top(n);
+
+ Printf(f_wrapper, "#ifdef __cplusplus\n");
+ Printf(f_wrapper, "}\n");
+ Printf(f_wrapper, "#endif\n");
+
+ String *type_table = NewString("");
+ SwigType_emit_type_table(f_runtime,f_wrapper);
+ Delete(type_table);
+
+ if(ClassMemberTable) {
+ //XXX OutputClassAccessInfo(ClassMemberTable, sfile);
+ Delete(ClassMemberTable);
+ ClassMemberTable = NULL;
+ }
+
+ Printf(f_init,"}\n");
+ if(registrationTable)
+ outputRegistrationRoutines(f_init);
+
+ /* Now arrange to write the 2 files - .S and .c. */
+
+ DumpCode(n);
+
+ Delete(sfile);
+ Delete(s_classes);
+ Delete(s_init);
+ Delete(f_wrapper);
+ Delete(f_init);
+
+ Delete(s_header);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+
+ return SWIG_OK;
+}
+
+
+/*****************************************************
+ Write the generated code to the .S and the .c files.
+****************************************************/
+int R::DumpCode(Node *n) {
+ String *output_filename = NewString("");
+
+
+ /* The name of the file in which we will generate the S code. */
+ Printf(output_filename, "%s%s.R", SWIG_output_directory(), Rpackage);
+
+#ifdef R_SWIG_VERBOSE
+ Printf(stderr, "Writing S code to %s\n", output_filename);
+#endif
+
+ File *scode = NewFile(output_filename, "w", SWIG_output_files());
+ if (!scode) {
+ FileErrorDisplay(output_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(output_filename);
+
+
+ Printf(scode, "%s\n\n", s_init);
+ Printf(scode, "%s\n\n", s_classes);
+ Printf(scode, "%s\n", sfile);
+
+ Close(scode);
+ // Delete(scode);
+ String *outfile = Getattr(n,"outfile");
+ File *runtime = NewFile(outfile,"w", SWIG_output_files());
+ if (!runtime) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Printf(runtime, "%s", f_begin);
+ Printf(runtime, "%s\n", f_runtime);
+ Printf(runtime, "%s\n", s_header);
+ Printf(runtime, "%s\n", f_wrapper);
+ Printf(runtime, "%s\n", f_init);
+
+ Close(runtime);
+ Delete(runtime);
+
+ if(outputNamespaceInfo) {
+ output_filename = NewString("");
+ Printf(output_filename, "%sNAMESPACE", SWIG_output_directory());
+ File *ns = NewFile(output_filename, "w", SWIG_output_files());
+ if (!ns) {
+ FileErrorDisplay(output_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(output_filename);
+
+ Printf(ns, "%s\n", s_namespace);
+
+ Printf(ns, "\nexport(\n");
+ writeListByLine(namespaceFunctions, ns);
+ Printf(ns, ")\n");
+ Printf(ns, "\nexportMethods(\n");
+ writeListByLine(namespaceFunctions, ns, 1);
+ Printf(ns, ")\n");
+ Close(ns);
+ Delete(ns);
+ Delete(s_namespace);
+ }
+
+ return SWIG_OK;
+}
+
+
+
+/*
+ We may need to do more.... so this is left as a
+ stub for the moment.
+*/
+int R::OutputClassAccessInfo(Hash *tb, File *out) {
+ int n = OutputClassMemberTable(tb, out);
+ OutputClassMethodsTable(out);
+ return n;
+}
+
+/************************************************************************
+ Currently this just writes the information collected about the
+ different methods of the C++ classes that have been processed
+ to the console.
+ This will be used later to define S4 generics and methods.
+**************************************************************************/
+int R::OutputClassMethodsTable(File *) {
+ Hash *tb = ClassMethodsTable;
+
+ if(!tb)
+ return SWIG_OK;
+
+ List *keys = Keys(tb);
+ String *key;
+ int i, n = Len(keys);
+ if (debugMode) {
+ for(i = 0; i < n ; i++ ) {
+ key = Getitem(keys, i);
+ Printf(stderr, "%d) %s\n", i, key);
+ List *els = Getattr(tb, key);
+ int nels = Len(els);
+ Printf(stderr, "\t");
+ for(int j = 0; j < nels; j+=2) {
+ Printf(stderr, "%s%s", Getitem(els, j), j < nels - 1 ? ", " : "");
+ Printf(stderr, "%s\n", Getitem(els, j+1));
+ }
+ Printf(stderr, "\n");
+ }
+ }
+
+ return SWIG_OK;
+}
+
+
+/*
+ Iterate over the <class name>_set and <>_get
+ elements and generate the $ and $<- functions
+ that provide constrained access to the member
+ fields in these elements.
+
+ tb - a hash table that is built up in functionWrapper
+ as we process each membervalueHandler.
+ The entries are indexed by <class name>_set and
+ <class_name>_get. Each entry is a List *.
+
+ out - the stram where the code is to be written. This is the S
+ code stream as we generate only S code here..
+*/
+int R::OutputClassMemberTable(Hash *tb, File *out) {
+ List *keys = Keys(tb), *el;
+
+ String *key;
+ int i, n = Len(keys);
+ /* Loop over all the <Class>_set and <Class>_get entries in the table. */
+
+ if(n && outputNamespaceInfo) {
+ Printf(s_namespace, "exportClasses(");
+ }
+ for(i = 0; i < n; i++) {
+ key = Getitem(keys, i);
+ el = Getattr(tb, key);
+
+ String *className = Getitem(el, 0);
+ char *ptr = Char(key);
+ ptr = &ptr[Len(key) - 3];
+ int isSet = strcmp(ptr, "set") == 0;
+
+ // OutputArrayMethod(className, el, out);
+ OutputMemberReferenceMethod(className, isSet, el, out);
+
+ if(outputNamespaceInfo)
+ Printf(s_namespace, "\"%s\"%s", className, i < n-1 ? "," : "");
+ }
+ if(n && outputNamespaceInfo) {
+ Printf(s_namespace, ")\n");
+ }
+
+ return n;
+}
+
+/*******************************************************************
+ Write the methods for $ or $<- for accessing a member field in an
+ struct or union (or class).
+ className - the name of the struct or union (e.g. Bar for struct Bar)
+ isSet - a logical value indicating whether the method is for
+ modifying ($<-) or accessing ($) the member field.
+ el - a list of length 2 * # accessible member elements + 1.
+ The first element is the name of the class.
+ The other pairs are member name and the name of the R function to access it.
+ out - the stream where we write the code.
+********************************************************************/
+int R::OutputMemberReferenceMethod(String *className, int isSet,
+ List *el, File *out) {
+ int numMems = Len(el), j;
+ int has_getitem = 0, has_setitem = 0, has_str = 0;
+ int varaccessor = 0;
+ if (numMems == 0)
+ return SWIG_OK;
+
+ Wrapper *f = NewWrapper(), *attr = NewWrapper();
+
+ Printf(f->def, "function(x, name%s)", isSet ? ", value" : "");
+ Printf(attr->def, "function(x, i, j, ...%s)", isSet ? ", value" : "");
+
+ Printf(f->code, "{\n");
+ Printf(f->code, "%saccessorFuns = list(", tab8);
+
+ Node *itemList = NewHash();
+ bool has_prev = false;
+ for(j = 0; j < numMems; j+=3) {
+ String *item = Getitem(el, j);
+ if (Getattr(itemList, item))
+ continue;
+ Setattr(itemList, item, "1");
+ if (!Strcmp(item, "__getitem__")) has_getitem = 1;
+ if (!Strcmp(item, "__setitem__")) has_setitem = 1;
+ if (!Strcmp(item, "__str__")) has_str = 1;
+
+ String *dup = Getitem(el, j + 1);
+ char *ptr = Char(dup);
+ ptr = &ptr[Len(dup) - 3];
+
+ if (!strcmp(ptr, "get"))
+ varaccessor++;
+
+ String *pitem;
+ if (!Strcmp(item, "operator ()")) {
+ pitem = NewString("call");
+ } else if (!Strcmp(item, "operator ->")) {
+ pitem = NewString("deref");
+ } else if (!Strcmp(item, "operator +")) {
+ pitem = NewString("add");
+ } else if (!Strcmp(item, "operator -")) {
+ pitem = NewString("sub");
+ } else {
+ pitem = Copy(item);
+ }
+ if (has_prev)
+ Printf(f->code, ", ");
+ Printf(f->code, "'%s' = %s", pitem, dup);
+ has_prev = true;
+ Delete(pitem);
+ }
+ Delete(itemList);
+ Printf(f->code, ")\n");
+
+ if (!isSet && varaccessor > 0) {
+ Printf(f->code, "%svaccessors = c(", tab8);
+ int vcount = 0;
+ for(j = 0; j < numMems; j+=3) {
+ String *item = Getitem(el, j);
+ String *dup = Getitem(el, j + 1);
+ char *ptr = Char(dup);
+ ptr = &ptr[Len(dup) - 3];
+
+ if (!strcmp(ptr, "get")) {
+ vcount++;
+ Printf(f->code, "'%s'%s", item, vcount < varaccessor ? ", " : "");
+ }
+ }
+ Printf(f->code, ")\n");
+ }
+
+
+ /* Printv(f->code, tab8,
+ "idx = pmatch(name, names(accessorFuns))\n",
+ tab8,
+ "if(is.na(idx)) {\n",
+ tab8, tab4,
+ "stop(\"No ", (isSet ? "modifiable" : "accessible"), " field named \", name, \" in ", className,
+ ": fields are \", paste(names(accessorFuns), sep = \", \")",
+ ")", "\n}\n", NIL); */
+ Printv(f->code, tab8,
+ "idx = pmatch(name, names(accessorFuns))\n",
+ tab8,
+ "if(is.na(idx)) \n",
+ tab8, tab4, NIL);
+ Printf(f->code, "return(callNextMethod(x, name%s))\n",
+ isSet ? ", value" : "");
+ Printv(f->code, tab8, "f = accessorFuns[[idx]]\n", NIL);
+ if(isSet) {
+ Printv(f->code, tab8, "f(x, value)\n", NIL);
+ Printv(f->code, tab8, "x\n", NIL); // make certain to return the S value.
+ } else {
+ Printv(f->code, tab8, "formals(f)[[1]] = x\n", NIL);
+ if (varaccessor) {
+ Printv(f->code, tab8,
+ "if (is.na(match(name, vaccessors))) f else f(x)\n", NIL);
+ } else {
+ Printv(f->code, tab8, "f\n", NIL);
+ }
+ }
+ Printf(f->code, "}\n");
+
+
+ Printf(out, "# Start of accessor method for %s\n", className);
+ Printf(out, "setMethod('$%s', '_p%s', ",
+ isSet ? "<-" : "",
+ getRClassName(className));
+ Wrapper_print(f, out);
+ Printf(out, ")\n");
+
+ if(isSet) {
+ Printf(out, "setMethod('[[<-', c('_p%s', 'character'),",
+ getRClassName(className));
+ Insert(f->code, 2, "name = i\n");
+ Printf(attr->code, "%s", f->code);
+ Wrapper_print(attr, out);
+ Printf(out, ")\n");
+ }
+
+ DelWrapper(attr);
+ DelWrapper(f);
+
+ Printf(out, "# end of accessor method for %s\n", className);
+
+ return SWIG_OK;
+}
+
+/*******************************************************************
+ Write the methods for [ or [<- for accessing a member field in an
+ struct or union (or class).
+ className - the name of the struct or union (e.g. Bar for struct Bar)
+ el - a list of length 2 * # accessible member elements + 1.
+ The first element is the name of the class.
+ The other pairs are member name and the name of the R function to access it.
+ out - the stream where we write the code.
+********************************************************************/
+int R::OutputArrayMethod(String *className, List *el, File *out) {
+ int numMems = Len(el), j;
+
+ if(!el || numMems == 0)
+ return(0);
+
+ Printf(out, "# start of array methods for %s\n", className);
+ for(j = 0; j < numMems; j+=3) {
+ String *item = Getitem(el, j);
+ String *dup = Getitem(el, j + 1);
+ if (!Strcmp(item, "__getitem__")) {
+ Printf(out,
+ "setMethod('[', '_p%s', function(x, i, j, ..., drop =TRUE) ",
+ getRClassName(className));
+ Printf(out, " sapply(i, function (n) %s(x, as.integer(n-1))))\n\n", dup);
+ }
+ if (!Strcmp(item, "__setitem__")) {
+ Printf(out, "setMethod('[<-', '_p%s', function(x, i, j, ..., value)",
+ getRClassName(className));
+ Printf(out, " sapply(1:length(i), function(n) %s(x, as.integer(i[n]-1), value[n])))\n\n", dup);
+ }
+
+ }
+
+ Printf(out, "# end of array methods for %s\n", className);
+
+ return SWIG_OK;
+}
+
+
+/************************************************************
+ Called when a enumeration is to be processed.
+ We want to call the R function defineEnumeration().
+ tdname is the typedef of the enumeration, i.e. giving its name.
+*************************************************************/
+int R::enumDeclaration(Node *n) {
+ String *name = Getattr(n, "name");
+ String *tdname = Getattr(n, "tdname");
+
+ /* Using name if tdname is empty. */
+
+ if(Len(tdname) == 0)
+ tdname = name;
+
+
+ if(!tdname || Strcmp(tdname, "") == 0) {
+ Language::enumDeclaration(n);
+ return SWIG_OK;
+ }
+
+ String *mangled_tdname = SwigType_manglestr(tdname);
+ String *scode = NewString("");
+
+ Printv(scode, "defineEnumeration('", mangled_tdname, "'",
+ ",\n", tab8, tab8, tab4, ".values = c(\n", NIL);
+
+ Node *c;
+ int value = -1; // First number is zero
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ // const char *tag = Char(nodeType(c));
+ // if (Strcmp(tag,"cdecl") == 0) {
+ name = Getattr(c, "name");
+ String *type = Getattr(c, "type");
+ String *val = Getattr(c, "enumvalue");
+ if(val && Char(val)) {
+ int inval = (int) getNumber(val, type);
+ if(inval == DEFAULT_NUMBER)
+ value++;
+ else
+ value = inval;
+ } else
+ value++;
+
+ Printf(scode, "%s%s%s'%s' = %d%s\n", tab8, tab8, tab8, name, value,
+ nextSibling(c) ? ", " : "");
+ // }
+ }
+
+ Printv(scode, "))", NIL);
+ Printf(sfile, "%s\n", scode);
+
+ Delete(scode);
+ Delete(mangled_tdname);
+
+ return SWIG_OK;
+}
+
+
+/*************************************************************
+**************************************************************/
+int R::variableWrapper(Node *n) {
+ String *name = Getattr(n, "sym:name");
+
+ processing_variable = 1;
+ Language::variableWrapper(n); // Force the emission of the _set and _get function wrappers.
+ processing_variable = 0;
+
+
+ SwigType *ty = Getattr(n, "type");
+ int addCopyParam = addCopyParameter(ty);
+
+ //XXX
+ processType(ty, n);
+
+ if(!SwigType_isconst(ty)) {
+ Wrapper *f = NewWrapper();
+ Printf(f->def, "%s = \nfunction(value%s)\n{\n",
+ name, addCopyParam ? ", .copy = FALSE" : "");
+ Printv(f->code, "if(missing(value)) {\n",
+ name, "_get(", addCopyParam ? ".copy" : "", ")\n}", NIL);
+ Printv(f->code, " else {\n",
+ name, "_set(value)\n}\n}", NIL);
+
+ Wrapper_print(f, sfile);
+ DelWrapper(f);
+ } else {
+ Printf(sfile, "%s = %s_get\n", name, name);
+ }
+
+ return SWIG_OK;
+}
+
+
+void R::addAccessor(String *memberName, Wrapper *wrapper, String *name,
+ int isSet) {
+ if(isSet < 0) {
+ int n = Len(name);
+ char *ptr = Char(name);
+ isSet = Strcmp(NewString(&ptr[n-3]), "set") == 0;
+ }
+
+ List *l = isSet ? class_member_set_functions : class_member_functions;
+
+ if(!l) {
+ l = NewList();
+ if(isSet)
+ class_member_set_functions = l;
+ else
+ class_member_functions = l;
+ }
+
+ Append(l, memberName);
+ Append(l, name);
+
+ String *tmp = NewString("");
+ Wrapper_print(wrapper, tmp);
+ Append(l, tmp);
+ // if we could put the wrapper in directly: Append(l, Copy(sfun));
+ if (debugMode)
+ Printf(stderr, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp);
+}
+
+#define MAX_OVERLOAD 256
+
+struct Overloaded {
+ Node *n; /* Node */
+ int argc; /* Argument count */
+ ParmList *parms; /* Parameters used for overload check */
+ int error; /* Ambiguity error */
+};
+
+
+static List * Swig_overload_rank(Node *n,
+ bool script_lang_wrapping) {
+ Overloaded nodes[MAX_OVERLOAD];
+ int nnodes = 0;
+ Node *o = Getattr(n,"sym:overloaded");
+
+
+ if (!o) return 0;
+
+ Node *c = o;
+ while (c) {
+ if (Getattr(c,"error")) {
+ c = Getattr(c,"sym:nextSibling");
+ continue;
+ }
+ /* if (SmartPointer && Getattr(c,"cplus:staticbase")) {
+ c = Getattr(c,"sym:nextSibling");
+ continue;
+ } */
+
+ /* Make a list of all the declarations (methods) that are overloaded with
+ * this one particular method name */
+
+ if (Getattr(c,"wrap:name")) {
+ nodes[nnodes].n = c;
+ nodes[nnodes].parms = Getattr(c,"wrap:parms");
+ nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
+ nodes[nnodes].error = 0;
+ nnodes++;
+ }
+ c = Getattr(c,"sym:nextSibling");
+ }
+
+ /* Sort the declarations by required argument count */
+ {
+ int i,j;
+ for (i = 0; i < nnodes; i++) {
+ for (j = i+1; j < nnodes; j++) {
+ if (nodes[i].argc > nodes[j].argc) {
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ }
+ }
+ }
+ }
+
+ /* Sort the declarations by argument types */
+ {
+ int i,j;
+ for (i = 0; i < nnodes-1; i++) {
+ if (nodes[i].argc == nodes[i+1].argc) {
+ for (j = i+1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
+ Parm *p1 = nodes[i].parms;
+ Parm *p2 = nodes[j].parms;
+ int differ = 0;
+ int num_checked = 0;
+ while (p1 && p2 && (num_checked < nodes[i].argc)) {
+ // Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
+ if (checkAttribute(p1,"tmap:in:numinputs","0")) {
+ p1 = Getattr(p1,"tmap:in:next");
+ continue;
+ }
+ if (checkAttribute(p2,"tmap:in:numinputs","0")) {
+ p2 = Getattr(p2,"tmap:in:next");
+ continue;
+ }
+ String *t1 = Getattr(p1,"tmap:typecheck:precedence");
+ String *t2 = Getattr(p2,"tmap:typecheck:precedence");
+ if ((!t1) && (!nodes[i].error)) {
+ Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
+ "Overloaded method %s not supported (no type checking rule for '%s').\n",
+ Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0));
+ nodes[i].error = 1;
+ } else if ((!t2) && (!nodes[j].error)) {
+ Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "xx Overloaded method %s not supported (no type checking rule for '%s').\n",
+ Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0));
+ nodes[j].error = 1;
+ }
+ if (t1 && t2) {
+ int t1v, t2v;
+ t1v = atoi(Char(t1));
+ t2v = atoi(Char(t2));
+ differ = t1v-t2v;
+ }
+ else if (!t1 && t2) differ = 1;
+ else if (t1 && !t2) differ = -1;
+ else if (!t1 && !t2) differ = -1;
+ num_checked++;
+ if (differ > 0) {
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ break;
+ } else if ((differ == 0) && (Strcmp(t1,"0") == 0)) {
+ t1 = Getattr(p1,"ltype");
+ if (!t1) {
+ t1 = SwigType_ltype(Getattr(p1,"type"));
+ if (Getattr(p1,"tmap:typecheck:SWIGTYPE")) {
+ SwigType_add_pointer(t1);
+ }
+ Setattr(p1,"ltype",t1);
+ }
+ t2 = Getattr(p2,"ltype");
+ if (!t2) {
+ t2 = SwigType_ltype(Getattr(p2,"type"));
+ if (Getattr(p2,"tmap:typecheck:SWIGTYPE")) {
+ SwigType_add_pointer(t2);
+ }
+ Setattr(p2,"ltype",t2);
+ }
+
+ /* Need subtype check here. If t2 is a subtype of t1, then we need to change the
+ order */
+
+ if (SwigType_issubtype(t2,t1)) {
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ }
+
+ if (Strcmp(t1,t2) != 0) {
+ differ = 1;
+ break;
+ }
+ } else if (differ) {
+ break;
+ }
+ if (Getattr(p1,"tmap:in:next")) {
+ p1 = Getattr(p1,"tmap:in:next");
+ } else {
+ p1 = nextSibling(p1);
+ }
+ if (Getattr(p2,"tmap:in:next")) {
+ p2 = Getattr(p2,"tmap:in:next");
+ } else {
+ p2 = nextSibling(p2);
+ }
+ }
+ if (!differ) {
+ /* See if declarations differ by const only */
+ String *d1 = Getattr(nodes[i].n,"decl");
+ String *d2 = Getattr(nodes[j].n,"decl");
+ if (d1 && d2) {
+ String *dq1 = Copy(d1);
+ String *dq2 = Copy(d2);
+ if (SwigType_isconst(d1)) {
+ Delete(SwigType_pop(dq1));
+ }
+ if (SwigType_isconst(d2)) {
+ Delete(SwigType_pop(dq2));
+ }
+ if (Strcmp(dq1,dq2) == 0) {
+
+ if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
+ if (script_lang_wrapping) {
+ // Swap nodes so that the const method gets ignored (shadowed by the non-const method)
+ Overloaded t = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = t;
+ }
+ differ = 1;
+ if (!nodes[j].error) {
+ if (script_lang_wrapping) {
+ Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n",
+ Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ } else {
+ if (!Getattr(nodes[j].n, "overload:ignore"))
+ Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s(%s) ignored. Method %s(%s) const at %s:%d used.\n",
+ Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms),
+ Getattr(nodes[i].n,"name"), ParmList_errorstr(nodes[i].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) {
+ if (script_lang_wrapping) {
+ 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_errorstr(nodes[j].parms),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ } else {
+ if (!Getattr(nodes[j].n, "overload:ignore"))
+ Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s(%s) const ignored. Method %s(%s) at %s:%d used.\n",
+ Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms),
+ Getattr(nodes[i].n,"name"), ParmList_errorstr(nodes[i].parms),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ }
+ }
+ nodes[j].error = 1;
+ }
+ }
+ Delete(dq1);
+ Delete(dq2);
+ }
+ }
+ if (!differ) {
+ if (!nodes[j].error) {
+ if (script_lang_wrapping) {
+ Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s is shadowed by %s at %s:%d.\n",
+ Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ } else {
+ if (!Getattr(nodes[j].n, "overload:ignore"))
+ Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
+ "Overloaded method %s ignored. Method %s at %s:%d used.\n",
+ Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n),
+ Getfile(nodes[i].n), Getline(nodes[i].n));
+ }
+ nodes[j].error = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ List *result = NewList();
+ {
+ int i;
+ for (i = 0; i < nnodes; i++) {
+ if (nodes[i].error)
+ Setattr(nodes[i].n, "overload:ignore", "1");
+ Append(result,nodes[i].n);
+ // Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms));
+ // Swig_print_node(nodes[i].n);
+ }
+ }
+ return result;
+}
+
+void R::dispatchFunction(Node *n) {
+ Wrapper *f = NewWrapper();
+ String *symname = Getattr(n, "sym:name");
+ String *nodeType = Getattr(n, "nodeType");
+ bool constructor = (!Cmp(nodeType, "constructor"));
+
+ String *sfname = NewString(symname);
+
+ if (constructor)
+ Replace(sfname, "new_", "", DOH_REPLACE_FIRST);
+
+ Printf(f->def,
+ "`%s` <- function(...) {", sfname);
+ List *dispatch = Swig_overload_rank(n, true);
+ int nfunc = Len(dispatch);
+ Printv(f->code,
+ "argtypes <- mapply(class, list(...))\n",
+ "argv <- list(...)\n",
+ "argc <- length(argtypes)\n", NIL );
+
+ Printf(f->code, "# dispatch functions %d\n", nfunc);
+ int cur_args = -1;
+ bool first_compare = true;
+ for (int i=0; i < nfunc; i++) {
+ Node *ni = Getitem(dispatch,i);
+ Parm *pi = Getattr(ni,"wrap:parms");
+ int num_arguments = emit_num_arguments(pi);
+
+ String *overname = Getattr(ni,"sym:overname");
+ if (cur_args != num_arguments) {
+ if (cur_args != -1) {
+ Printv(f->code, "} else ", NIL);
+ }
+ Printf(f->code, "if (argc == %d) {", num_arguments);
+ cur_args = num_arguments;
+ first_compare = true;
+ }
+ Parm *p;
+ int j;
+ if (num_arguments > 0) {
+ if (!first_compare) {
+ Printv(f->code, " else ", NIL);
+ } else {
+ first_compare = false;
+ }
+ Printv(f->code, "if (", NIL);
+ for (p =pi, j = 0 ; j < num_arguments ; j++) {
+ String *tm = Swig_typemap_lookup("rtype", p, "", 0);
+ if(tm) {
+ replaceRClass(tm, Getattr(p, "type"));
+ }
+ if (DohStrcmp(tm,"numeric")==0) {
+ Printf(f->code, "%sis.numeric(argv[[%d]])",
+ j == 0 ? "" : " && ",
+ j+1);
+ }
+ else {
+ Printf(f->code, "%sextends(argtypes[%d], '%s')",
+ j == 0 ? "" : " && ",
+ j+1,
+ tm);
+ }
+ p = Getattr(p, "tmap:in:next");
+ }
+ Printf(f->code, ") { f <- %s%s }\n", sfname, overname);
+ } else {
+ Printf(f->code, "f <- %s%s", sfname, overname);
+ }
+ }
+ if (cur_args != -1) {
+ Printv(f->code, "}", NIL);
+ }
+ Printv(f->code, "\nf(...)", NIL);
+ Printv(f->code, "\n}", NIL);
+ Wrapper_print(f, sfile);
+ Printv(sfile, "# Dispatch function\n", NIL);
+ DelWrapper(f);
+}
+
+/******************************************************************
+
+*******************************************************************/
+int R::functionWrapper(Node *n) {
+ String *fname = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ String *type = Getattr(n, "type");
+
+ if (debugMode) {
+ Printf(stderr,
+ "<functionWrapper> %s %s %s\n", fname, iname, type);
+ }
+ String *overname = 0;
+ String *nodeType = Getattr(n, "nodeType");
+ bool constructor = (!Cmp(nodeType, "constructor"));
+ bool destructor = (!Cmp(nodeType, "destructor"));
+
+ String *sfname = NewString(iname);
+
+ if (constructor)
+ Replace(sfname, "new_", "", DOH_REPLACE_FIRST);
+
+ if (Getattr(n,"sym:overloaded")) {
+ overname = Getattr(n,"sym:overname");
+ Append(sfname, overname);
+ }
+
+ if (debugMode)
+ Printf(stderr,
+ "<functionWrapper> processing parameters\n");
+
+
+ ParmList *l = Getattr(n, "parms");
+ Parm *p;
+ String *tm;
+
+ p = l;
+ while(p) {
+ SwigType *resultType = Getattr(p, "type");
+ if (expandTypedef(resultType) &&
+ SwigType_istypedef(resultType)) {
+ SwigType *resolved =
+ SwigType_typedef_resolve_all(resultType);
+ if (expandTypedef(resolved)) {
+ Setattr(p, "type", Copy(resolved));
+ }
+ }
+ p = nextSibling(p);
+ }
+
+ String *unresolved_return_type =
+ Copy(type);
+ if (expandTypedef(type) &&
+ SwigType_istypedef(type)) {
+ SwigType *resolved =
+ SwigType_typedef_resolve_all(type);
+ if (expandTypedef(resolved)) {
+ type = Copy(resolved);
+ Setattr(n, "type", type);
+ }
+ }
+ if (debugMode)
+ Printf(stderr, "<functionWrapper> unresolved_return_type %s\n",
+ unresolved_return_type);
+ if(processing_member_access_function) {
+ if (debugMode)
+ Printf(stderr, "<functionWrapper memberAccess> '%s' '%s' '%s' '%s'\n",
+ fname, iname, member_name, class_name);
+
+ if(opaqueClassDeclaration)
+ return SWIG_OK;
+
+
+ /* Add the name of this member to a list for this class_name.
+ We will dump all these at the end. */
+
+ int n = Len(iname);
+ char *ptr = Char(iname);
+ bool isSet(Strcmp(NewString(&ptr[n-3]), "set") == 0);
+
+
+ String *tmp = NewString("");
+ Printf(tmp, "%s_%s", class_name, isSet ? "set" : "get");
+
+ List *memList = Getattr(ClassMemberTable, tmp);
+ if(!memList) {
+ memList = NewList();
+ Append(memList, class_name);
+ Setattr(ClassMemberTable, tmp, memList);
+ }
+ Delete(tmp);
+ Append(memList, member_name);
+ Append(memList, iname);
+ }
+
+ int i;
+ int nargs, num_required, varargs;
+ UNUSED(varargs);
+
+ String *wname = Swig_name_wrapper(iname);
+ Replace(wname, "_wrap", "R_swig", DOH_REPLACE_FIRST);
+ if(overname)
+ Append(wname, overname);
+ Setattr(n,"wrap:name", wname);
+
+ Wrapper *f = NewWrapper();
+ Wrapper *sfun = NewWrapper();
+
+ int isVoidReturnType = (Strcmp(type, "void") == 0);
+ // Need to use the unresolved return type since
+ // typedef resolution removes the const which causes a
+ // mismatch with the function action
+ emit_return_variable(n, unresolved_return_type, f);
+
+ SwigType *rtype = Getattr(n, "type");
+ int addCopyParam = 0;
+
+ if(!isVoidReturnType)
+ addCopyParam = addCopyParameter(rtype);
+
+
+ // Can we get the nodeType() of the type node! and see if it is a struct.
+ // int addCopyParam = SwigType_isclass(rtype);
+
+ // if(addCopyParam)
+ if (debugMode)
+ Printf(stderr, "Adding a .copy argument to %s for %s = %s\n",
+ iname, type, addCopyParam ? "yes" : "no");
+
+ Printv(f->def, "SWIGEXPORT SEXP\n", wname, " ( ", NIL);
+
+ Printf(sfun->def, "# Start of %s\n", iname);
+ Printv(sfun->def, "\n`", sfname, "` = function(", NIL);
+
+ if(outputNamespaceInfo) //XXX Need to be a little more discriminating
+ addNamespaceFunction(iname);
+
+ Swig_typemap_attach_parms("scoercein", l, f);
+ Swig_typemap_attach_parms("scoerceout", l, f);
+ Swig_typemap_attach_parms("scheck", l, f);
+
+ emit_parameter_variables(l, f);
+ emit_attach_parmmaps(l,f);
+ Setattr(n,"wrap:parms",l);
+
+ nargs = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+ varargs = emit_isvarargs(l);
+
+ Wrapper_add_local(f, "r_nprotect", "unsigned int r_nprotect = 0");
+ Wrapper_add_localv(f, "r_ans", "SEXP", "r_ans = R_NilValue", NIL);
+ Wrapper_add_localv(f, "r_vmax", "VMAXTYPE", "r_vmax = vmaxget()", NIL);
+
+ String *sargs = NewString("");
+
+
+ String *s_inputTypes = NewString("");
+ String *s_inputMap = NewString("");
+ bool inFirstArg = true;
+ bool inFirstType = true;
+ Parm *curP;
+ for (p =l, i = 0 ; i < nargs ; i++) {
+
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *tt = Getattr(p, "type");
+ int nargs = -1;
+ String *funcptr_name = processType(tt, p, &nargs);
+
+ // SwigType *tp = Getattr(p, "type");
+ String *name = Getattr(p,"name");
+ String *lname = Getattr(p,"lname");
+
+ // R keyword renaming
+ if (name && Swig_name_warning(p, 0, name, 0))
+ name = 0;
+
+ /* If we have a :: in the parameter name because we are accessing a static member of a class, say, then
+ we need to remove that prefix. */
+ while (Strstr(name, "::")) {
+ //XXX need to free.
+ name = NewStringf("%s", Strchr(name, ':') + 2);
+ if (debugMode)
+ Printf(stderr, "+++ parameter name with :: in it %s\n", name);
+ }
+ if (Len(name) == 0)
+ name = NewStringf("s_arg%d", i+1);
+
+ name = replaceInitialDash(name);
+
+ if (!Strncmp(name, "arg", 3)) {
+ name = Copy(name);
+ Insert(name, 0, "s_");
+ }
+
+ if(processing_variable) {
+ name = Copy(name);
+ Insert(name, 0, "s_");
+ }
+
+ if(!Strcmp(name, fname)) {
+ name = Copy(name);
+ Insert(name, 0, "s_");
+ }
+
+ Printf(sargs, "%s, ", name);
+
+ String *tm;
+ if((tm = Getattr(p, "tmap:scoercein"))) {
+ Replaceall(tm, "$input", name);
+ replaceRClass(tm, Getattr(p, "type"));
+
+ if(funcptr_name) {
+ //XXX need to get this to return non-zero
+ if(nargs == -1)
+ nargs = getFunctionPointerNumArgs(p, tt);
+
+ String *snargs = NewStringf("%d", nargs);
+ Printv(sfun->code, "if(is.function(", name, ")) {", "\n",
+ "assert('...' %in% names(formals(", name,
+ ")) || length(formals(", name, ")) >= ", snargs, ")\n} ", NIL);
+ Delete(snargs);
+
+ Printv(sfun->code, "else {\n",
+ "if(is.character(", name, ")) {\n",
+ name, " = getNativeSymbolInfo(", name, ")",
+ "\n}\n",
+ "if(is(", name, ", \"NativeSymbolInfo\")) {\n",
+ name, " = ", name, "$address", "\n}\n",
+ "}\n",
+ NIL);
+ } else {
+ Printf(sfun->code, "%s\n", tm);
+ }
+ }
+
+ Printv(sfun->def, inFirstArg ? "" : ", ", name, NIL);
+
+ if ((tm = Getattr(p,"tmap:scheck"))) {
+
+ Replaceall(tm,"$target", lname);
+ Replaceall(tm,"$source", name);
+ Replaceall(tm,"$input", name);
+ replaceRClass(tm, Getattr(p, "type"));
+ Printf(sfun->code,"%s\n",tm);
+ }
+
+
+
+ curP = p;
+ if ((tm = Getattr(p,"tmap:in"))) {
+
+ Replaceall(tm,"$target", lname);
+ Replaceall(tm,"$source", name);
+ Replaceall(tm,"$input", name);
+
+ if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) {
+ Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm,"$disown","0");
+ }
+
+ if(funcptr_name) {
+ /* have us a function pointer */
+ Printf(f->code, "if(TYPEOF(%s) != CLOSXP) {\n", name);
+ Replaceall(tm,"$R_class", "");
+ } else {
+ replaceRClass(tm, Getattr(p, "type"));
+ }
+
+
+ Printf(f->code,"%s\n",tm);
+ if(funcptr_name)
+ Printf(f->code, "} else {\n%s = %s;\nR_SWIG_pushCallbackFunctionData(%s, NULL);\n}\n",
+ lname, funcptr_name, name);
+ Printv(f->def, inFirstArg ? "" : ", ", "SEXP ", name, NIL);
+ if (Len(name) != 0)
+ inFirstArg = false;
+ p = Getattr(p,"tmap:in:next");
+
+ } else {
+ p = nextSibling(p);
+ }
+
+
+ tm = Swig_typemap_lookup("rtype", curP, "", 0);
+ if(tm) {
+ replaceRClass(tm, Getattr(curP, "type"));
+ }
+ Printf(s_inputTypes, "%s'%s'", inFirstType ? "" : ", ", tm);
+ Printf(s_inputMap, "%s%s='%s'", inFirstType ? "" : ", ", name, tm);
+ inFirstType = false;
+
+ if(funcptr_name)
+ Delete(funcptr_name);
+ } /* end of looping over parameters. */
+
+ if(addCopyParam) {
+ Printf(sfun->def, "%s.copy = FALSE", nargs > 0 ? ", " : "");
+ Printf(f->def, "%sSEXP s_swig_copy", nargs > 0 ? ", " : "");
+
+ Printf(sargs, "as.logical(.copy), ");
+ }
+
+ Printv(f->def, ")\n{\n", NIL);
+ Printv(sfun->def, ")\n{\n", NIL);
+
+
+ /* 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);
+ }
+ }
+
+ String *outargs = NewString("");
+ int numOutArgs = isVoidReturnType ? -1 : 0;
+ for(p = l, i = 0; p; i++) {
+ if((tm = Getattr(p, "tmap:argout"))) {
+ // String *lname = Getattr(p, "lname");
+ numOutArgs++;
+ String *pos = NewStringf("%d", numOutArgs);
+ Replaceall(tm,"$source", Getattr(p, "lname"));
+ Replaceall(tm,"$result", "r_ans");
+ Replaceall(tm,"$n", pos); // The position into which to store the answer.
+ Replaceall(tm,"$arg", Getattr(p, "emit:input"));
+ Replaceall(tm,"$input", Getattr(p, "emit:input"));
+ Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
+
+
+ Printf(outargs, "%s\n", tm);
+ p = Getattr(p,"tmap:argout:next");
+ } else
+ p = nextSibling(p);
+ }
+
+ String *actioncode = emit_action(n);
+
+ /* Deal with the explicit return value. */
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ SwigType *retType = Getattr(n, "type");
+ //Printf(stderr, "Return Value for %s, array? %s\n", retType, SwigType_isarray(retType) ? "yes" : "no");
+ /* if(SwigType_isarray(retType)) {
+ defineArrayAccessors(retType);
+ } */
+
+
+ Replaceall(tm,"$1", "result");
+ Replaceall(tm,"$result", "r_ans");
+ replaceRClass(tm, retType);
+
+ if (GetFlag(n,"feature:new")) {
+ Replaceall(tm, "$owner", "R_SWIG_OWNER");
+ } else {
+ Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
+ }
+
+#if 0
+ if(addCopyParam) {
+ Printf(f->code, "if(LOGICAL(s_swig_copy)[0]) {\n");
+ Printf(f->code, "/* Deal with returning a reference. */\nr_ans = R_NilValue;\n");
+ Printf(f->code, "}\n else {\n");
+ }
+#endif
+ Printf(f->code, "%s\n", tm);
+#if 0
+ if(addCopyParam)
+ Printf(f->code, "}\n"); /* end of if(s_swig_copy) ... else { ... } */
+#endif
+
+ } 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), fname);
+ }
+
+
+ if(Len(outargs)) {
+ Wrapper_add_local(f, "R_OutputValues", "SEXP R_OutputValues");
+
+ String *tmp = NewString("");
+ if(!isVoidReturnType)
+ Printf(tmp, "Rf_protect(r_ans);\n");
+
+ Printf(tmp, "Rf_protect(R_OutputValues = Rf_allocVector(VECSXP,%d));\nr_nprotect += %d;\n",
+ numOutArgs + !isVoidReturnType,
+ isVoidReturnType ? 1 : 2);
+
+ if(!isVoidReturnType)
+ Printf(tmp, "SET_VECTOR_ELT(R_OutputValues, 0, r_ans);\n");
+ Printf(tmp, "r_ans = R_OutputValues;\n");
+
+ Insert(outargs, 0, tmp);
+ Delete(tmp);
+
+
+
+ Printv(f->code, outargs, NIL);
+ Delete(outargs);
+
+ }
+
+ /* Output cleanup code */
+ Printv(f->code, cleanup, NIL);
+ Delete(cleanup);
+
+
+
+ Printv(f->code, UnProtectWrapupCode, NIL);
+
+ /*If the user gave us something to convert the result in */
+ if ((tm = Swig_typemap_lookup("scoerceout", n,
+ "result", sfun))) {
+ Replaceall(tm,"$source","ans");
+ Replaceall(tm,"$result","ans");
+ replaceRClass(tm, Getattr(n, "type"));
+ Chop(tm);
+ }
+
+
+ Printv(sfun->code, (Len(tm) ? "ans = " : ""), ".Call('", wname,
+ "', ", sargs, "PACKAGE='", Rpackage, "')\n", NIL);
+ if(Len(tm))
+ Printf(sfun->code, "%s\n\nans\n", tm);
+ if (destructor)
+ Printv(f->code, "R_ClearExternalPtr(self);\n", NIL);
+
+ Printv(f->code, "return r_ans;\n}\n", NIL);
+ Printv(sfun->code, "\n}", NIL);
+
+ /* Substitute the function name */
+ Replaceall(f->code,"$symname",iname);
+
+ Wrapper_print(f, f_wrapper);
+ Wrapper_print(sfun, sfile);
+
+ Printf(sfun->code, "\n# End of %s\n", iname);
+ tm = Swig_typemap_lookup("rtype", n, "", 0);
+ if(tm) {
+ SwigType *retType = Getattr(n, "type");
+ replaceRClass(tm, retType);
+ }
+
+ Printv(sfile, "attr(`", sfname, "`, 'returnType') = '",
+ isVoidReturnType ? "void" : (tm ? tm : ""),
+ "'\n", NIL);
+
+ if(nargs > 0)
+ Printv(sfile, "attr(`", sfname, "`, \"inputTypes\") = c(",
+ s_inputTypes, ")\n", NIL);
+ Printv(sfile, "class(`", sfname, "`) = c(\"SWIGFunction\", class('",
+ sfname, "'))\n\n", NIL);
+
+ if (memoryProfile) {
+ Printv(sfile, "memory.profile()\n", NIL);
+ }
+ if (aggressiveGc) {
+ Printv(sfile, "gc()\n", NIL);
+ }
+
+ // Printv(sfile, "setMethod('", name, "', '", name, "', ", iname, ")\n\n\n");
+
+
+
+ /* If we are dealing with a method in an C++ class, then
+ add the name of the R function and its definition.
+ XXX need to figure out how to store the Wrapper if possible in the hash/list.
+ Would like to be able to do this so that we can potentialy insert
+ */
+ if(processing_member_access_function || processing_class_member_function) {
+ String *tmp;
+ if(member_name)
+ tmp = member_name;
+ else
+ tmp = Getattr(n, "memberfunctionHandler:name");
+ addAccessor(member_name, sfun, iname);
+ }
+
+ if (Getattr(n, "sym:overloaded") &&
+ !Getattr(n, "sym:nextSibling")) {
+ dispatchFunction(n);
+ }
+
+ addRegistrationRoutine(wname, addCopyParam ? nargs +1 : nargs);
+
+ DelWrapper(f);
+ DelWrapper(sfun);
+
+ Delete(sargs);
+ Delete(sfname);
+ return SWIG_OK;
+}
+
+/*****************************************************
+ Add the specified routine name to the collection of
+ generated routines that are called from R functions.
+ This is used to register the routines with R for
+ resolving symbols.
+
+ rname - the name of the routine
+ nargs - the number of arguments it expects.
+******************************************************/
+int R::addRegistrationRoutine(String *rname, int nargs) {
+ if(!registrationTable)
+ registrationTable = NewHash();
+
+ String *el =
+ NewStringf("{\"%s\", (DL_FUNC) &%s, %d}", rname, rname, nargs);
+
+ Setattr(registrationTable, rname, el);
+
+ return SWIG_OK;
+}
+
+/*****************************************************
+ Write the registration information to an array and
+ create the initialization routine for registering
+ these.
+******************************************************/
+int R::outputRegistrationRoutines(File *out) {
+ int i, n;
+ if(!registrationTable)
+ return(0);
+ if(inCPlusMode)
+ Printf(out, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n");
+
+ Printf(out, "#include <R_ext/Rdynload.h>\n\n");
+ if(inCPlusMode)
+ Printf(out, "#ifdef __cplusplus\n}\n#endif\n\n");
+
+ Printf(out, "SWIGINTERN R_CallMethodDef CallEntries[] = {\n");
+
+ List *keys = Keys(registrationTable);
+ n = Len(keys);
+ for(i = 0; i < n; i++)
+ Printf(out, " %s,\n", Getattr(registrationTable, Getitem(keys, i)));
+
+ Printf(out, " {NULL, NULL, 0}\n};\n\n");
+
+ if(!noInitializationCode) {
+ if (inCPlusMode)
+ Printv(out, "extern \"C\" ", NIL);
+ Printf(out, "SWIGEXPORT void R_init_%s(DllInfo *dll) {\n", Rpackage);
+ Printf(out, "%sR_registerRoutines(dll, NULL, CallEntries, NULL, NULL);\n", tab4);
+ if(Len(s_init_routine)) {
+ Printf(out, "\n%s\n", s_init_routine);
+ }
+ Printf(out, "}\n");
+ }
+
+ return n;
+}
+
+
+
+/****************************************************************************
+ Process a struct, union or class declaration in the source code,
+ or an anonymous typedef struct
+
+*****************************************************************************/
+//XXX What do we need to do here -
+// Define an S4 class to refer to this.
+
+void R::registerClass(Node *n) {
+ String *name = Getattr(n, "name");
+ String *kind = Getattr(n, "kind");
+
+ if (debugMode)
+ Swig_print_node(n);
+ String *sname = NewStringf("_p%s", SwigType_manglestr(name));
+ if(!Getattr(SClassDefs, sname)) {
+ Setattr(SClassDefs, sname, sname);
+ String *base;
+
+ if(Strcmp(kind, "class") == 0) {
+ base = NewString("");
+ List *l = Getattr(n, "bases");
+ if(Len(l)) {
+ Printf(base, "c(");
+ for(int i = 0; i < Len(l); i++) {
+ registerClass(Getitem(l, i));
+ Printf(base, "'_p%s'%s",
+ SwigType_manglestr(Getattr(Getitem(l, i), "name")),
+ i < Len(l)-1 ? ", " : "");
+ }
+ Printf(base, ")");
+ } else {
+ base = NewString("'C++Reference'");
+ }
+ } else
+ base = NewString("'ExternalReference'");
+
+ Printf(s_classes, "setClass('%s', contains = %s)\n", sname, base);
+ Delete(base);
+ }
+
+}
+
+int R::classDeclaration(Node *n) {
+
+ String *name = Getattr(n, "name");
+ String *kind = Getattr(n, "kind");
+
+ if (debugMode)
+ Swig_print_node(n);
+ registerClass(n);
+
+
+ /* If we have a typedef union { ... } U, then we never get to see the typedef
+ via a regular call to typedefHandler. Instead, */
+ if(Getattr(n, "unnamed") && Strcmp(Getattr(n, "storage"), "typedef") == 0
+ && Getattr(n, "tdname") && Strcmp(Getattr(n, "tdname"), name) == 0) {
+ if (debugMode)
+ Printf(stderr, "Typedef in the class declaration for %s\n", name);
+ // typedefHandler(n);
+ }
+
+ bool opaque = GetFlag(n, "feature:opaque") ? true : false;
+
+ if(opaque)
+ opaqueClassDeclaration = name;
+
+ int status = Language::classDeclaration(n);
+
+ opaqueClassDeclaration = NULL;
+
+
+ // OutputArrayMethod(name, class_member_functions, sfile);
+ if (class_member_functions)
+ OutputMemberReferenceMethod(name, 0, class_member_functions, sfile);
+ if (class_member_set_functions)
+ OutputMemberReferenceMethod(name, 1, class_member_set_functions, sfile);
+
+ if(class_member_functions) {
+ Delete(class_member_functions);
+ class_member_functions = NULL;
+ }
+ if(class_member_set_functions) {
+ Delete(class_member_set_functions);
+ class_member_set_functions = NULL;
+ }
+ if (Getattr(n, "has_destructor")) {
+ Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n",
+ getRClassName(Getattr(n, "name")),
+ getRClassName(Getattr(n, "name")));
+
+ }
+ if(!opaque && !Strcmp(kind, "struct") && copyStruct) {
+
+ String *def =
+ NewStringf("setClass(\"%s\",\n%srepresentation(\n", name, tab4);
+ bool firstItem = true;
+
+ for(Node *c = firstChild(n); c; ) {
+ String *elName;
+ String *tp;
+
+ elName = Getattr(c, "name");
+
+ String *elKind = Getattr(c, "kind");
+ if (Strcmp(elKind, "variable") != 0) {
+ c = nextSibling(c);
+ continue;
+ }
+ if (!Len(elName)) {
+ c = nextSibling(c);
+ continue;
+ }
+#if 0
+ tp = getRType(c);
+#else
+ tp = Swig_typemap_lookup("rtype", c, "", 0);
+ if(!tp) {
+ c = nextSibling(c);
+ continue;
+ }
+ if (Strstr(tp, "R_class")) {
+ c = nextSibling(c);
+ continue;
+ }
+ if (Strcmp(tp, "character") &&
+ Strstr(Getattr(c, "decl"), "p.")) {
+ c = nextSibling(c);
+ continue;
+ }
+
+ if (!firstItem) {
+ Printf(def, ",\n");
+ }
+ // else
+ //XXX How can we tell if this is already done.
+ // SwigType_push(elType, elDecl);
+
+
+ // returns "" tp = processType(elType, c, NULL);
+ // Printf(stderr, "<classDeclaration> elType %p\n", elType);
+ // tp = getRClassNameCopyStruct(Getattr(c, "type"), 1);
+#endif
+ String *elNameT = replaceInitialDash(elName);
+ Printf(def, "%s%s = \"%s\"", tab8, elNameT, tp);
+ firstItem = false;
+ Delete(tp);
+ Delete(elNameT);
+ c = nextSibling(c);
+ }
+ Printf(def, "),\n%scontains = \"RSWIGStruct\")\n", tab8);
+ Printf(s_classes, "%s\n\n# End class %s\n\n", def, name);
+
+ generateCopyRoutines(n);
+
+ Delete(def);
+ }
+
+ return status;
+}
+
+
+
+/***************************************************************
+ Create the C routines that copy an S object of the class given
+ by the given struct definition in Node *n to the C value
+ and also the routine that goes from the C routine to an object
+ of this S class.
+****************************************************************/
+/*XXX
+ Clean up the toCRef - make certain the names are correct for the types, etc.
+ in all cases.
+*/
+
+int R::generateCopyRoutines(Node *n) {
+ Wrapper *copyToR = NewWrapper();
+ Wrapper *copyToC = NewWrapper();
+
+ String *name = Getattr(n, "name");
+ String *tdname = Getattr(n, "tdname");
+ String *kind = Getattr(n, "kind");
+ String *type;
+
+ if(Len(tdname)) {
+ type = Copy(tdname);
+ } else {
+ type = NewStringf("%s %s", kind, name);
+ }
+
+ String *mangledName = SwigType_manglestr(name);
+
+ if (debugMode)
+ Printf(stderr, "generateCopyRoutines: name = %s, %s\n", name, type);
+
+ Printf(copyToR->def, "CopyToR%s = function(value, obj = new(\"%s\"))\n{\n",
+ mangledName, name);
+ Printf(copyToC->def, "CopyToC%s = function(value, obj)\n{\n",
+ mangledName);
+
+ Node *c = firstChild(n);
+
+ for(; c; c = nextSibling(c)) {
+ String *elName = Getattr(c, "name");
+ if (!Len(elName)) {
+ continue;
+ }
+ String *elKind = Getattr(c, "kind");
+ if (Strcmp(elKind, "variable") != 0) {
+ Delete(elKind);
+ continue;
+ }
+
+ String *tp = Swig_typemap_lookup("rtype", c, "", 0);
+ if(!tp) {
+ continue;
+ }
+ if (Strstr(tp, "R_class")) {
+ continue;
+ }
+ if (Strcmp(tp, "character") &&
+ Strstr(Getattr(c, "decl"), "p.")) {
+ continue;
+ }
+
+
+ /* The S functions to get and set the member value. */
+ String *elNameT = replaceInitialDash(elName);
+ Printf(copyToR->code, "obj@%s = value$%s\n", elNameT, elNameT);
+ Printf(copyToC->code, "obj$%s = value@%s\n", elNameT, elNameT);
+ Delete(elNameT);
+ }
+ Printf(copyToR->code, "obj\n}\n\n");
+ String *rclassName = getRClassNameCopyStruct(type, 0); // without the Ref.
+ Printf(sfile, "# Start definition of copy functions & methods for %s\n", rclassName);
+
+ Wrapper_print(copyToR, sfile);
+ Printf(copyToC->code, "obj\n}\n\n");
+ Wrapper_print(copyToC, sfile);
+
+
+ Printf(sfile, "# Start definition of copy methods for %s\n", rclassName);
+ Printf(sfile, "setMethod('copyToR', '_p_%s', CopyToR%s)\n", rclassName,
+ mangledName);
+ Printf(sfile, "setMethod('copyToC', '%s', CopyToC%s)\n\n", rclassName,
+ mangledName);
+
+ Printf(sfile, "# End definition of copy methods for %s\n", rclassName);
+ Printf(sfile, "# End definition of copy functions & methods for %s\n", rclassName);
+
+ String *m = NewStringf("%sCopyToR", name);
+ addNamespaceMethod(m);
+ char *tt = Char(m); tt[Len(m)-1] = 'C';
+ addNamespaceMethod(m);
+ Delete(m);
+ Delete(rclassName);
+ Delete(mangledName);
+ DelWrapper(copyToR);
+ DelWrapper(copyToC);
+
+ return SWIG_OK;
+}
+
+
+
+/*****
+ Called when there is a typedef to be invoked.
+
+ XXX Needs to be enhanced or split to handle the case where we have a
+ typedef within a classDeclaration emission because the struct/union/etc.
+ is anonymous.
+******/
+int R::typedefHandler(Node *n) {
+ SwigType *tp = Getattr(n, "type");
+ String *type = Getattr(n, "type");
+ if (debugMode)
+ Printf(stderr, "<typedefHandler> %s\n", Getattr(n, "name"));
+
+ processType(tp, n);
+
+ if(Strncmp(type, "struct ", 7) == 0) {
+ String *name = Getattr(n, "name");
+ char *trueName = Char(type);
+ trueName += 7;
+ if (debugMode)
+ Printf(stderr, "<typedefHandler> Defining S class %s\n", trueName);
+ Printf(s_classes, "setClass('_p%s', contains = 'ExternalReference')\n",
+ SwigType_manglestr(name));
+ }
+
+ return Language::typedefHandler(n);
+}
+
+
+
+/*********************
+ Called when processing a field in a "class", i.e. struct, union or
+ actual class. We set a state variable so that we can correctly
+ interpret the resulting functionWrapper() call and understand that
+ it is for a field element.
+**********************/
+int R::membervariableHandler(Node *n) {
+ SwigType *t = Getattr(n, "type");
+ processType(t, n, NULL);
+ processing_member_access_function = 1;
+ member_name = Getattr(n,"sym:name");
+ if (debugMode)
+ Printf(stderr, "<membervariableHandler> name = %s, sym:name = %s\n",
+ Getattr(n, "name"), member_name);
+
+ int status(Language::membervariableHandler(n));
+
+ if(opaqueClassDeclaration == NULL && debugMode)
+ Printf(stderr, "<membervariableHandler> %s %s\n", Getattr(n, "name"), Getattr(n, "type"));
+
+ processing_member_access_function = 0;
+ member_name = NULL;
+
+ return status;
+}
+
+
+/*
+ This doesn't seem to get used so leave it out for the moment.
+*/
+String * R::runtimeCode() {
+ String *s = Swig_include_sys("rrun.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'rrun.swg'\n");
+ s = NewString("");
+ }
+ return s;
+}
+
+
+/**
+ Called when SWIG wants to initialize this
+ We initialize anythin we want here.
+ Most importantly, tell SWIG where to find the files (e.g. r.swg) for this module.
+ Use Swig_mark_arg() to tell SWIG that it is understood and not to throw an error.
+**/
+void R::main(int argc, char *argv[]) {
+ bool cppcast = true;
+ init();
+ Preprocessor_define("SWIGR 1", 0);
+ SWIG_library_directory("r");
+ SWIG_config_file("r.swg");
+ debugMode = false;
+ copyStruct = true;
+ memoryProfile = false;
+ aggressiveGc = false;
+ inCPlusMode = false;
+ outputNamespaceInfo = false;
+ noInitializationCode = false;
+
+ this->Argc = argc;
+ this->Argv = argv;
+
+ allow_overloading();// can we support this?
+
+ for(int i = 0; i < argc; i++) {
+ if(strcmp(argv[i], "-package") == 0) {
+ Swig_mark_arg(i);
+ i++;
+ Swig_mark_arg(i);
+ Rpackage = argv[i];
+ } else if(strcmp(argv[i], "-dll") == 0) {
+ Swig_mark_arg(i);
+ i++;
+ Swig_mark_arg(i);
+ DllName = argv[i];
+ } else if(strcmp(argv[i], "-help") == 0) {
+ showUsage();
+ } else if(strcmp(argv[i], "-namespace") == 0) {
+ outputNamespaceInfo = true;
+ Swig_mark_arg(i);
+ } else if(!strcmp(argv[i], "-no-init-code")) {
+ noInitializationCode = true;
+ Swig_mark_arg(i);
+ } else if(!strcmp(argv[i], "-c++")) {
+ inCPlusMode = true;
+ Swig_mark_arg(i);
+ Printf(s_classes, "setClass('C++Reference', contains = 'ExternalReference')\n");
+ } else if(!strcmp(argv[i], "-debug")) {
+ debugMode = true;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i],"-cppcast")) {
+ cppcast = true;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i],"-nocppcast")) {
+ cppcast = false;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i],"-copystruct")) {
+ copyStruct = true;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i], "-nocopystruct")) {
+ copyStruct = false;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i], "-memoryprof")) {
+ memoryProfile = true;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i], "-nomemoryprof")) {
+ memoryProfile = false;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i], "-aggressivegc")) {
+ aggressiveGc = true;
+ Swig_mark_arg(i);
+ } else if (!strcmp(argv[i], "-noaggressivegc")) {
+ aggressiveGc = false;
+ Swig_mark_arg(i);
+ }
+
+ if (cppcast) {
+ Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
+ }
+ /// copyToR copyToC functions.
+
+ }
+}
+
+/*
+ Could make this work for String or File and then just store the resulting string
+ rather than the collection of arguments and argc.
+*/
+int R::outputCommandLineArguments(File *out)
+{
+ if(Argc < 1 || !Argv || !Argv[0])
+ return(-1);
+
+ Printf(out, "\n## Generated via the command line invocation:\n##\t");
+ for(int i = 0; i < Argc ; i++) {
+ Printf(out, " %s", Argv[i]);
+ }
+ Printf(out, "\n\n\n");
+
+ return Argc;
+}
+
+
+
+/* How SWIG instantiates an object from this module.
+ See swigmain.cxx */
+extern "C"
+Language *swig_r(void) {
+ return new R();
+}
+
+
+
+/*************************************************************************************/
+
+/*
+ Needs to be reworked.
+*/
+String * R::processType(SwigType *t, Node *n, int *nargs) {
+ //XXX Need to handle typedefs, e.g.
+ // a type which is a typedef to a function pointer.
+
+ SwigType *tmp = Getattr(n, "tdname");
+ if (debugMode)
+ Printf(stderr, "processType %s (tdname = %s)\n", Getattr(n, "name"), tmp);
+
+ SwigType *td = t;
+ if (expandTypedef(t) &&
+ SwigType_istypedef(t)) {
+ SwigType *resolved =
+ SwigType_typedef_resolve_all(t);
+ if (expandTypedef(resolved)) {
+ td = Copy(resolved);
+ }
+ }
+
+ if(!td) {
+ int count = 0;
+ String *b = getRTypeName(t, &count);
+ if(count && b && !Getattr(SClassDefs, b)) {
+ if (debugMode)
+ Printf(stderr, "<processType> Defining class %s\n", b);
+
+ Printf(s_classes, "setClass('%s', contains = 'ExternalReference')\n", b);
+ Setattr(SClassDefs, b, b);
+ }
+
+ }
+
+
+ if(td)
+ t = td;
+
+ if(SwigType_isfunctionpointer(t)) {
+ if (debugMode)
+ Printf(stderr,
+ "<processType> Defining pointer handler %s\n", t);
+
+ String *tmp = createFunctionPointerHandler(t, n, nargs);
+ return tmp;
+ }
+
+#if 0
+ SwigType_isfunction(t) && SwigType_ispointer(t)
+#endif
+
+ return NULL;
+}
+
+
+
+
+
+
+
+
+
+/*************************************************************************************/
+
+
+
+
+
diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx
new file mode 100644
index 0000000..c9e935e
--- /dev/null
+++ b/Source/Modules/ruby.cxx
@@ -0,0 +1,3427 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * ruby.cxx
+ *
+ * Ruby language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_ruby_cxx[] = "$Id: ruby.cxx 11246 2009-06-05 17:19:29Z wsfulton $";
+
+#include "swigmod.h"
+#include "cparse.h"
+static int treduce = SWIG_cparse_template_reduce(0);
+
+#define SWIG_PROTECTED_TARGET_METHODS 1
+
+#include <ctype.h>
+#include <string.h>
+#include <limits.h> /* for INT_MAX */
+
+class RClass {
+private:
+ String *temp;
+
+public:
+ String *name; /* class name (renamed) */
+ String *cname; /* original C class/struct name */
+ String *mname; /* Mangled name */
+
+ /**
+ * The C variable name used in the SWIG-generated wrapper code to refer to
+ * this class; usually it is of the form "SwigClassXXX.klass", where SwigClassXXX
+ * is a swig_class struct instance and klass is a member of that struct.
+ */
+ String *vname;
+
+ /**
+ * The C variable name used in the SWIG-generated wrapper code to refer to
+ * the module that implements this class's methods (when we're trying to
+ * support C++ multiple inheritance). Usually it is of the form
+ * "SwigClassClassName.mImpl", where SwigClassXXX is a swig_class struct instance
+ * and mImpl is a member of that struct.
+ */
+ String *mImpl;
+
+ String *type;
+ String *prefix;
+ String *init;
+
+
+ int constructor_defined;
+ int destructor_defined;
+
+ RClass() {
+ temp = NewString("");
+ name = NewString("");
+ cname = NewString("");
+ mname = NewString("");
+ vname = NewString("");
+ mImpl = NewString("");
+ type = NewString("");
+ prefix = NewString("");
+ init = NewString("");
+ constructor_defined = 0;
+ destructor_defined = 0;
+ }
+
+ ~RClass() {
+ Delete(name);
+ Delete(cname);
+ Delete(vname);
+ Delete(mImpl);
+ Delete(mname);
+ Delete(type);
+ Delete(prefix);
+ Delete(init);
+ Delete(temp);
+ }
+
+ void set_name(const_String_or_char_ptr cn, const_String_or_char_ptr rn, const_String_or_char_ptr valn) {
+ /* Original C/C++ class (or struct) name */
+ Clear(cname);
+ Append(cname, cn);
+
+ /* Mangled name */
+ Delete(mname);
+ mname = Swig_name_mangle(cname);
+
+ /* Renamed class name */
+ Clear(name);
+ Append(name, valn);
+
+ /* Variable name for the VALUE that refers to the Ruby Class object */
+ Clear(vname);
+ Printf(vname, "SwigClass%s.klass", name);
+
+ /* Variable name for the VALUE that refers to the Ruby Class object */
+ Clear(mImpl);
+ Printf(mImpl, "SwigClass%s.mImpl", name);
+
+ /* Prefix */
+ Clear(prefix);
+ Printv(prefix, (rn ? rn : cn), "_", NIL);
+ }
+
+ char *strip(const_String_or_char_ptr s) {
+ Clear(temp);
+ Append(temp, s);
+ if (Strncmp(s, prefix, Len(prefix)) == 0) {
+ Replaceall(temp, prefix, "");
+ }
+ return Char(temp);
+ }
+};
+
+
+/* flags for the make_autodoc function */
+enum autodoc_t {
+ AUTODOC_CLASS,
+ AUTODOC_CTOR,
+ AUTODOC_DTOR,
+ AUTODOC_STATICFUNC,
+ AUTODOC_FUNC,
+ AUTODOC_METHOD,
+ AUTODOC_GETTER,
+ AUTODOC_SETTER
+};
+
+static const char *usage = "\
+Ruby Options (available with -ruby)\n\
+ -globalmodule - Wrap everything into the global module\n\
+ -minherit - Attempt to support multiple inheritance\n\
+ -nocppcast - Disable C++ casting operators, useful for generating bugs\n\
+ -cppcast - Enable C++ casting operators (default)\n\
+ -autorename - Enable renaming of classes and methods to follow Ruby coding standards\n\
+ -noautorename - Disable renaming of classes and methods (default)\n\
+ -prefix <name> - Set a prefix <name> to be prepended to all names\n\
+ -initname <name> - Set entry function to Init_<name> (used by `require')\n";
+
+
+#define RCLASS(hash, name) (RClass*)(Getattr(hash, name) ? Data(Getattr(hash, name)) : 0)
+#define SET_RCLASS(hash, name, klass) Setattr(hash, name, NewVoid(klass, 0))
+
+
+class RUBY:public Language {
+private:
+
+ String *module;
+ String *modvar;
+ String *feature;
+ String *prefix;
+ int current;
+ Hash *classes; /* key=cname val=RClass */
+ RClass *klass; /* Currently processing class */
+ Hash *special_methods; /* Python style special method name table */
+
+ File *f_directors;
+ File *f_directors_h;
+ File *f_directors_helpers;
+ File *f_begin;
+ File *f_runtime;
+ File *f_runtime_h;
+ File *f_header;
+ File *f_wrappers;
+ File *f_init;
+ File *f_initbeforefunc;
+
+ bool useGlobalModule;
+ bool multipleInheritance;
+
+ // Wrap modes
+ enum WrapperMode {
+ NO_CPP,
+ MEMBER_FUNC,
+ CONSTRUCTOR_ALLOCATE,
+ CONSTRUCTOR_INITIALIZE,
+ DESTRUCTOR,
+ MEMBER_VAR,
+ CLASS_CONST,
+ STATIC_FUNC,
+ STATIC_VAR
+ };
+
+ /* ------------------------------------------------------------
+ * autodoc level declarations
+ * ------------------------------------------------------------ */
+
+ enum autodoc_l {
+ NO_AUTODOC = -2, // no autodoc
+ STRING_AUTODOC = -1, // use provided string
+ NAMES_AUTODOC = 0, // only parameter names
+ TYPES_AUTODOC = 1, // parameter names and types
+ EXTEND_AUTODOC = 2, // extended documentation and parameter names
+ EXTEND_TYPES_AUTODOC = 3 // extended documentation and parameter types + names
+ };
+
+ autodoc_t last_mode;
+ String* last_autodoc;
+
+
+
+ autodoc_l autodoc_level(String *autodoc) {
+ autodoc_l dlevel = NO_AUTODOC;
+ if (autodoc) {
+ char *c = Char(autodoc);
+ if (c && isdigit(c[0])) {
+ dlevel = (autodoc_l) atoi(c);
+ } else {
+ if (strcmp(c, "extended") == 0) {
+ dlevel = EXTEND_AUTODOC;
+ } else {
+ dlevel = STRING_AUTODOC;
+ }
+ }
+ }
+ return dlevel;
+ }
+
+
+
+ /* ------------------------------------------------------------
+ * have_docstring()
+ * Check if there is a docstring directive and it has text,
+ * or there is an autodoc flag set
+ * ------------------------------------------------------------ */
+
+ bool have_docstring(Node *n) {
+ String *str = Getattr(n, "feature:docstring");
+ return (str != NULL && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
+ }
+
+ /* ------------------------------------------------------------
+ * docstring()
+ * Get the docstring text, stripping off {} if neccessary,
+ * and enclose in triple double quotes. If autodoc is also
+ * set then it will build a combined docstring.
+ * ------------------------------------------------------------ */
+
+ String *docstring(Node *n, autodoc_t ad_type) {
+
+ String *str = Getattr(n, "feature:docstring");
+ bool have_ds = (str != NULL && Len(str) > 0);
+ bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
+ String *autodoc = NULL;
+ String *doc = NULL;
+
+ if (have_ds) {
+ char *t = Char(str);
+ if (*t == '{') {
+ Delitem(str, 0);
+ Delitem(str, DOH_END);
+ }
+ }
+
+ if (have_auto) {
+ autodoc = make_autodoc(n, ad_type);
+ have_auto = (autodoc != NULL && Len(autodoc) > 0);
+ }
+ // If there is more than one line then make docstrings like this:
+ //
+ // This is line1
+ // And here is line2 followed by the rest of them
+ //
+ // otherwise, put it all on a single line
+ //
+ if (have_auto && have_ds) { // Both autodoc and docstring are present
+ doc = NewString("");
+ Printv(doc, "\n", autodoc, "\n", str, NIL);
+ } else if (!have_auto && have_ds) { // only docstring
+ if (Strchr(str, '\n') == NULL) {
+ doc = NewString(str);
+ } else {
+ doc = NewString("");
+ Printv(doc, str, NIL);
+ }
+ } else if (have_auto && !have_ds) { // only autodoc
+ if (Strchr(autodoc, '\n') == NULL) {
+ doc = NewStringf("%s", autodoc);
+ } else {
+ doc = NewString("");
+ Printv(doc, "\n", autodoc, NIL);
+ }
+ } else
+ doc = NewString("");
+
+ // Save the generated strings in the parse tree in case they are used later
+ // by post processing tools
+ Setattr(n, "ruby:docstring", doc);
+ Setattr(n, "ruby:autodoc", autodoc);
+ return doc;
+ }
+
+ /* ------------------------------------------------------------
+ * make_autodocParmList()
+ * Generate the documentation for the function parameters
+ * ------------------------------------------------------------ */
+
+ String *make_autodocParmList(Node *n, bool showTypes) {
+ String *doc = NewString("");
+ String *pdocs = Copy(Getattr(n, "feature:pdocs"));
+ ParmList *plist = CopyParmList(Getattr(n, "parms"));
+ Parm *p;
+ Parm *pnext;
+ Node *lookup;
+ int lines = 0;
+ const int maxwidth = 50;
+
+ if (pdocs)
+ Append(pdocs, ".\n");
+
+
+ Swig_typemap_attach_parms("in", plist, 0);
+ Swig_typemap_attach_parms("doc", plist, 0);
+
+ for (p = plist; p; p = pnext) {
+ String *name = 0;
+ String *type = 0;
+ String *value = 0;
+ String *ptype = 0;
+ String *pdoc = Getattr(p, "tmap:doc");
+ if (pdoc) {
+ name = Getattr(p, "tmap:doc:name");
+ type = Getattr(p, "tmap:doc:type");
+ value = Getattr(p, "tmap:doc:value");
+ ptype = Getattr(p, "tmap:doc:pytype");
+ }
+
+ name = name ? name : Getattr(p, "name");
+ type = type ? type : Getattr(p, "type");
+ value = value ? value : Getattr(p, "value");
+
+
+ String *tm = Getattr(p, "tmap:in");
+ if (tm) {
+ pnext = Getattr(p, "tmap:in:next");
+ } else {
+ pnext = nextSibling(p);
+ }
+
+ // Skip ignored input attributes
+ if (checkAttribute(p, "tmap:in:numinputs", "0"))
+ continue;
+
+ // Skip the 'self' parameter which in ruby is implicit
+ if ( Cmp(name, "self") == 0 )
+ continue;
+
+ // Make __p parameters just p (as used in STL)
+ Replace( name, "__", "", DOH_REPLACE_FIRST );
+
+ if (Len(doc)) {
+ // add a comma to the previous one if any
+ Append(doc, ", ");
+
+ // Do we need to wrap a long line?
+ if ((Len(doc) - lines * maxwidth) > maxwidth) {
+ Printf(doc, "\n%s", tab4);
+ lines += 1;
+ }
+ }
+ // Do the param type too?
+ if (showTypes) {
+ type = SwigType_base(type);
+ lookup = Swig_symbol_clookup(type, 0);
+ if (lookup)
+ type = Getattr(lookup, "sym:name");
+ Printf(doc, "%s ", type);
+ }
+
+ if (name) {
+ Append(doc, name);
+ if (pdoc) {
+ if (!pdocs)
+ pdocs = NewString("Parameters:\n");
+ Printf(pdocs, " %s.\n", pdoc);
+ }
+ } else {
+ Append(doc, "?");
+ }
+
+ if (value) {
+ if (Strcmp(value, "NULL") == 0)
+ value = NewString("nil");
+ else if (Strcmp(value, "true") == 0 || Strcmp(value, "TRUE") == 0)
+ value = NewString("true");
+ else if (Strcmp(value, "false") == 0 || Strcmp(value, "FALSE") == 0)
+ value = NewString("false");
+ else {
+ lookup = Swig_symbol_clookup(value, 0);
+ if (lookup)
+ value = Getattr(lookup, "sym:name");
+ }
+ Printf(doc, "=%s", value);
+ }
+ }
+ if (pdocs)
+ Setattr(n, "feature:pdocs", pdocs);
+ Delete(plist);
+ return doc;
+ }
+
+ /* ------------------------------------------------------------
+ * make_autodoc()
+ * Build a docstring for the node, using parameter and other
+ * info in the parse tree. If the value of the autodoc
+ * attribute is "0" then do not include parameter types, if
+ * it is "1" (the default) then do. If it has some other
+ * value then assume it is supplied by the extension writer
+ * and use it directly.
+ * ------------------------------------------------------------ */
+
+ String *make_autodoc(Node *n, autodoc_t ad_type) {
+ int extended = 0;
+ // If the function is overloaded then this funciton is called
+ // for the last one. Rewind to the first so the docstrings are
+ // in order.
+ while (Getattr(n, "sym:previousSibling"))
+ n = Getattr(n, "sym:previousSibling");
+
+ Node *pn = Swig_methodclass(n);
+ String* super_names = NewString("");
+ String* class_name = Getattr(pn, "sym:name") ;
+
+ if ( !class_name ) class_name = NewString("");
+ else
+ {
+ class_name = Copy(class_name);
+ List *baselist = Getattr(pn, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator base = First(baselist);
+ while (base.item && GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ }
+
+ int count = 0;
+ for ( ;base.item; ++count) {
+ if ( count ) Append(super_names, ", ");
+ String *basename = Getattr(base.item, "sym:name");
+
+ String* basenamestr = NewString(basename);
+ Node* parent = parentNode(base.item);
+ while (parent)
+ {
+ String *parent_name = Copy( Getattr(parent, "sym:name") );
+ if ( !parent_name ) {
+ Node* mod = Getattr(parent, "module");
+ if ( mod )
+ parent_name = Copy( Getattr(mod, "name") );
+ if ( parent_name )
+ {
+ (Char(parent_name))[0] = (char)toupper((Char(parent_name))[0]);
+ }
+ }
+ if ( parent_name )
+ {
+ Insert(basenamestr, 0, "::");
+ Insert(basenamestr, 0, parent_name);
+ Delete(parent_name);
+ }
+ parent = parentNode(parent);
+ }
+
+ Append(super_names, basenamestr );
+ Delete(basenamestr);
+ base = Next(base);
+ }
+ }
+ }
+ String* full_name;
+ if ( module ) {
+ full_name = NewString(module);
+ if (class_name && Len(class_name) > 0) Append(full_name, "::");
+ }
+ else
+ full_name = NewString("");
+ Append(full_name, class_name);
+
+ String* symname = Getattr(n, "sym:name");
+ if ( Getattr( special_methods, symname ) )
+ symname = Getattr( special_methods, symname );
+
+ String* methodName = NewString(full_name);
+ Append(methodName, symname);
+
+
+ // Each overloaded function will try to get documented,
+ // so we keep the name of the last overloaded function and its type.
+ // Documenting just from functionWrapper() is not possible as
+ // sym:name has already been changed to include the class name
+ if ( last_mode == ad_type && Cmp(methodName, last_autodoc) == 0 ) {
+ Delete(full_name);
+ Delete(class_name);
+ Delete(super_names);
+ Delete(methodName);
+ return NewString("");
+ }
+
+
+ last_mode = ad_type;
+ last_autodoc = Copy(methodName);
+
+ String *doc = NewString("/*\n");
+ int counter = 0;
+ bool skipAuto = false;
+ Node* on = n;
+ for ( ; n; ++counter ) {
+ skipAuto = false;
+ bool showTypes = false;
+ String *autodoc = Getattr(n, "feature:autodoc");
+ autodoc_l dlevel = autodoc_level(autodoc);
+ switch (dlevel) {
+ case NO_AUTODOC:
+ break;
+ case NAMES_AUTODOC:
+ showTypes = false;
+ break;
+ case TYPES_AUTODOC:
+ showTypes = true;
+ break;
+ case EXTEND_AUTODOC:
+ extended = 1;
+ showTypes = false;
+ break;
+ case EXTEND_TYPES_AUTODOC:
+ extended = 1;
+ showTypes = true;
+ break;
+ case STRING_AUTODOC:
+ skipAuto = true;
+ break;
+ }
+
+ SwigType *type = Getattr(n, "type");
+
+ if (type) {
+ if (Strcmp(type, "void") == 0)
+ type = NULL;
+ else {
+ SwigType *qt = SwigType_typedef_resolve_all(type);
+ if (SwigType_isenum(qt))
+ type = NewString("int");
+ else {
+ type = SwigType_base(type);
+ Node *lookup = Swig_symbol_clookup(type, 0);
+ if (lookup)
+ type = Getattr(lookup, "sym:name");
+ }
+ }
+ }
+
+ if (counter == 0) {
+ switch (ad_type) {
+ case AUTODOC_CLASS:
+ Printf(doc, " Document-class: %s", full_name);
+ if ( Len(super_names) > 0 )
+ Printf( doc, " < %s", super_names);
+ Append(doc, "\n\n");
+ break;
+ case AUTODOC_CTOR:
+ Printf(doc, " Document-method: %s.new\n\n", full_name);
+ break;
+
+ case AUTODOC_DTOR:
+ break;
+
+ case AUTODOC_STATICFUNC:
+ Printf(doc, " Document-method: %s.%s\n\n", full_name, symname);
+ break;
+
+ case AUTODOC_FUNC:
+ case AUTODOC_METHOD:
+ case AUTODOC_GETTER:
+ Printf(doc, " Document-method: %s.%s\n\n", full_name, symname);
+ break;
+ case AUTODOC_SETTER:
+ Printf(doc, " Document-method: %s.%s=\n\n", full_name, symname);
+ break;
+ }
+ }
+
+
+ if (skipAuto) {
+ if ( counter == 0 ) Printf(doc, " call-seq:\n");
+ switch( ad_type )
+ {
+ case AUTODOC_STATICFUNC:
+ case AUTODOC_FUNC:
+ case AUTODOC_METHOD:
+ case AUTODOC_GETTER:
+ {
+ String *paramList = make_autodocParmList(n, showTypes);
+ if (Len(paramList))
+ Printf(doc, " %s(%s)", symname, paramList);
+ else
+ Printf(doc, " %s", symname);
+ if (type)
+ Printf(doc, " -> %s", type);
+ break;
+ }
+ case AUTODOC_SETTER:
+ {
+ Printf(doc, " %s=(x)", symname);
+ if (type) Printf(doc, " -> %s", type);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else {
+ switch (ad_type) {
+ case AUTODOC_CLASS:
+ {
+ // Only do the autodoc if there isn't a docstring for the class
+ String *str = Getattr(n, "feature:docstring");
+ if (counter == 0 && (str == NULL || Len(str) == 0)) {
+ if (CPlusPlus) {
+ Printf(doc, " Proxy of C++ %s class", full_name);
+ } else {
+ Printf(doc, " Proxy of C %s struct", full_name);
+ }
+ }
+ }
+ break;
+ case AUTODOC_CTOR:
+ if (counter == 0) Printf(doc, " call-seq:\n");
+ if (Strcmp(class_name, symname) == 0) {
+ String *paramList = make_autodocParmList(n, showTypes);
+ if (Len(paramList))
+ Printf(doc, " %s.new(%s)", class_name, paramList);
+ else
+ Printf(doc, " %s.new", class_name);
+ } else
+ Printf(doc, " %s.new(%s)", class_name,
+ make_autodocParmList(n, showTypes));
+ break;
+
+ case AUTODOC_DTOR:
+ break;
+
+ case AUTODOC_STATICFUNC:
+ case AUTODOC_FUNC:
+ case AUTODOC_METHOD:
+ case AUTODOC_GETTER:
+ {
+ if (counter == 0) Printf(doc, " call-seq:\n");
+ String *paramList = make_autodocParmList(n, showTypes);
+ if (Len(paramList))
+ Printf(doc, " %s(%s)", symname, paramList);
+ else
+ Printf(doc, " %s", symname);
+ if (type)
+ Printf(doc, " -> %s", type);
+ break;
+ }
+ case AUTODOC_SETTER:
+ {
+ Printf(doc, " call-seq:\n");
+ Printf(doc, " %s=(x)", symname);
+ if (type) Printf(doc, " -> %s", type);
+ break;
+ }
+ }
+ }
+
+ // if it's overloaded then get the next decl and loop around again
+ n = Getattr(n, "sym:nextSibling");
+ if (n)
+ Append(doc, "\n");
+ }
+
+ Printf(doc, "\n\n");
+ if (!skipAuto) {
+ switch (ad_type) {
+ case AUTODOC_CLASS:
+ case AUTODOC_DTOR:
+ break;
+ case AUTODOC_CTOR:
+ Printf(doc, "Class constructor.\n");
+ break;
+ case AUTODOC_STATICFUNC:
+ Printf(doc, "A class method.\n");
+ break;
+ case AUTODOC_FUNC:
+ Printf(doc, "A module function.\n");
+ break;
+ case AUTODOC_METHOD:
+ Printf(doc, "An instance method.\n");
+ break;
+ case AUTODOC_GETTER:
+ Printf(doc, "Get value of attribute.\n");
+ break;
+ case AUTODOC_SETTER:
+ Printf(doc, "Set new value for attribute.\n");
+ break;
+ }
+ }
+
+
+ n = on;
+ while ( n ) {
+ String *autodoc = Getattr(n, "feature:autodoc");
+ autodoc_l dlevel = autodoc_level(autodoc);
+
+ symname = Getattr(n, "sym:name");
+ if ( Getattr( special_methods, symname ) )
+ symname = Getattr( special_methods, symname );
+
+ switch (dlevel) {
+ case NO_AUTODOC:
+ case NAMES_AUTODOC:
+ case TYPES_AUTODOC:
+ extended = 0;
+ break;
+ case STRING_AUTODOC:
+ extended = 2;
+ Replaceall( autodoc, "$class", class_name );
+ Printv(doc, autodoc, ".", NIL);
+ break;
+ case EXTEND_AUTODOC:
+ case EXTEND_TYPES_AUTODOC:
+ extended = 1;
+ break;
+ }
+
+
+ if (extended) {
+ String *pdocs = Getattr(n, "feature:pdocs");
+ if (pdocs) {
+ Printv(doc, "\n\n", pdocs, NULL);
+ break;
+ }
+ if ( extended == 2 ) break;
+ }
+ n = Getattr(n, "sym:nextSibling");
+ }
+
+ Append(doc, "\n*/\n");
+ Delete(full_name);
+ Delete(class_name);
+ Delete(super_names);
+ Delete(methodName);
+
+ return doc;
+ }
+
+public:
+
+ /* ---------------------------------------------------------------------
+ * RUBY()
+ *
+ * Initialize member data
+ * --------------------------------------------------------------------- */
+
+ RUBY() {
+ module = 0;
+ modvar = 0;
+ feature = 0;
+ prefix = 0;
+ last_autodoc = NewString("");
+ current = NO_CPP;
+ classes = 0;
+ klass = 0;
+ special_methods = 0;
+ f_begin = 0;
+ f_runtime = 0;
+ f_header = 0;
+ f_wrappers = 0;
+ f_init = 0;
+ f_initbeforefunc = 0;
+ useGlobalModule = false;
+ multipleInheritance = false;
+ director_prot_ctor_code = NewString("");
+ Printv(director_prot_ctor_code,
+ "if ( $comparison ) { /* subclassed */\n",
+ " $director_new \n",
+ "} else {\n", " rb_raise(rb_eRuntimeError,\"accessing abstract class or protected constructor\"); \n", " return Qnil;\n", "}\n", NIL);
+ director_multiple_inheritance = 0;
+ director_language = 1;
+ }
+
+ /* ---------------------------------------------------------------------
+ * main()
+ *
+ * Parse command line options and initializes variables.
+ * --------------------------------------------------------------------- */
+
+ virtual void main(int argc, char *argv[]) {
+
+ int cppcast = 1;
+ int autorename = 0;
+
+ /* 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], "-initname") == 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], "-feature") == 0) {
+ fprintf( stderr, "Warning: Ruby -feature option is deprecated, "
+ "please use -initname instead.\n");
+ 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], "-globalmodule") == 0) {
+ useGlobalModule = true;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-minherit") == 0) {
+ multipleInheritance = true;
+ director_multiple_inheritance = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-cppcast") == 0) {
+ cppcast = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nocppcast") == 0) {
+ cppcast = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-autorename") == 0) {
+ autorename = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noautorename") == 0) {
+ autorename = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-prefix") == 0) {
+ if (argv[i + 1]) {
+ char *name = argv[i + 1];
+ prefix = NewString(name);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-help") == 0) {
+ Printf(stdout, "%s\n", usage);
+ }
+ }
+ }
+
+ if (cppcast) {
+ /* Turn on cppcast mode */
+ Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
+ }
+
+ if (autorename) {
+ /* Turn on the autorename mode */
+ Preprocessor_define((DOH *) "SWIG_RUBY_AUTORENAME", 0);
+ }
+
+ /* 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();
+ }
+
+ /**
+ * Generate initialization code to define the Ruby module(s),
+ * accounting for nested modules as necessary.
+ */
+ void defineRubyModule() {
+ List *modules = Split(module, ':', INT_MAX);
+ if (modules != 0 && Len(modules) > 0) {
+ String *mv = 0;
+ Iterator m;
+ m = First(modules);
+ while (m.item) {
+ if (Len(m.item) > 0) {
+ if (mv != 0) {
+ Printv(f_init, tab4, modvar, " = rb_define_module_under(", modvar, ", \"", m.item, "\");\n", NIL);
+ } else {
+ Printv(f_init, tab4, modvar, " = rb_define_module(\"", m.item, "\");\n", NIL);
+ mv = NewString(modvar);
+ }
+ }
+ m = Next(m);
+ }
+ Delete(mv);
+ Delete(modules);
+ }
+ }
+
+ void registerMagicMethods() {
+
+ special_methods = NewHash();
+
+ /* Python->Ruby style special method name. */
+ /* Basic */
+ Setattr(special_methods, "__repr__", "inspect");
+ Setattr(special_methods, "__str__", "to_s");
+ Setattr(special_methods, "__cmp__", "<=>");
+ Setattr(special_methods, "__hash__", "hash");
+ Setattr(special_methods, "__nonzero__", "nonzero?");
+
+ /* Callable */
+ Setattr(special_methods, "__call__", "call");
+
+ /* Collection */
+ Setattr(special_methods, "__len__", "length");
+ Setattr(special_methods, "__getitem__", "[]");
+ Setattr(special_methods, "__setitem__", "[]=");
+
+ /* Operators */
+ Setattr(special_methods, "__add__", "+");
+ Setattr(special_methods, "__pos__", "+@");
+ Setattr(special_methods, "__sub__", "-");
+ Setattr(special_methods, "__neg__", "-@");
+ Setattr(special_methods, "__mul__", "*");
+ Setattr(special_methods, "__div__", "/");
+ Setattr(special_methods, "__mod__", "%");
+ Setattr(special_methods, "__lshift__", "<<");
+ Setattr(special_methods, "__rshift__", ">>");
+ Setattr(special_methods, "__and__", "&");
+ Setattr(special_methods, "__or__", "|");
+ Setattr(special_methods, "__xor__", "^");
+ Setattr(special_methods, "__invert__", "~");
+ Setattr(special_methods, "__lt__", "<");
+ Setattr(special_methods, "__le__", "<=");
+ Setattr(special_methods, "__gt__", ">");
+ Setattr(special_methods, "__ge__", ">=");
+ Setattr(special_methods, "__eq__", "==");
+
+ /* Other numeric */
+ Setattr(special_methods, "__divmod__", "divmod");
+ Setattr(special_methods, "__pow__", "**");
+ Setattr(special_methods, "__abs__", "abs");
+ Setattr(special_methods, "__int__", "to_i");
+ Setattr(special_methods, "__float__", "to_f");
+ Setattr(special_methods, "__coerce__", "coerce");
+ }
+
+ /* ---------------------------------------------------------------------
+ * top()
+ * --------------------------------------------------------------------- */
+
+ virtual int top(Node *n) {
+
+ /**
+ * See if any Ruby module options have been specified as options
+ * to the %module directive.
+ */
+ Node *swigModule = Getattr(n, "module");
+ if (swigModule) {
+ Node *options = Getattr(swigModule, "options");
+ if (options) {
+ if (Getattr(options, "directors")) {
+ allow_directors();
+ }
+ if (Getattr(options, "dirprot")) {
+ allow_dirprot();
+ }
+ if (Getattr(options, "ruby_globalmodule")) {
+ useGlobalModule = true;
+ }
+ if (Getattr(options, "ruby_minherit")) {
+ multipleInheritance = true;
+ director_multiple_inheritance = 1;
+ }
+ }
+ }
+
+ /* Set comparison with none for ConstructorToFunction */
+
+
+ setSubclassInstanceCheck(NewStringf("strcmp(rb_obj_classname(self), classname) != 0"));
+ // setSubclassInstanceCheck(NewString("CLASS_OF(self) != cFoo.klass"));
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+ String *outfile_h = Getattr(n, "outfile_h");
+
+ if (!outfile) {
+ Printf(stderr, "Unable to determine outfile\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+ f_directors_h = NewString("");
+ f_directors = NewString("");
+ f_directors_helpers = NewString("");
+ f_initbeforefunc = NewString("");
+
+ if (directorsEnabled()) {
+ if (!outfile_h) {
+ Printf(stderr, "Unable to determine outfile_h\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
+ if (!f_runtime_h) {
+ FileErrorDisplay(outfile_h);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+ Swig_register_filebyname("director", f_directors);
+ Swig_register_filebyname("director_h", f_directors_h);
+ Swig_register_filebyname("director_helpers", f_directors_helpers);
+ Swig_register_filebyname("initbeforefunc", f_initbeforefunc);
+
+ modvar = 0;
+ current = NO_CPP;
+ klass = 0;
+ classes = NewHash();
+
+ registerMagicMethods();
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGRUBY\n");
+
+ if (directorsEnabled()) {
+ Printf(f_runtime, "#define SWIG_DIRECTORS\n");
+ }
+
+ Printf(f_runtime, "\n");
+
+ /* typedef void *VALUE */
+ SwigType *value = NewSwigType(T_VOID);
+ SwigType_add_pointer(value);
+ SwigType_typedef(value, (char *) "VALUE");
+ Delete(value);
+
+ /* Set module name */
+ set_module(Char(Getattr(n, "name")));
+
+ if (directorsEnabled()) {
+ /* Build a version of the module name for use in a C macro name. */
+ String *module_macro = Copy(module);
+ Replaceall(module_macro, "::", "__");
+
+ Swig_banner(f_directors_h);
+ Printf(f_directors_h, "\n");
+ Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_macro);
+ Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_macro);
+ Printf(f_directors_h, "namespace Swig {\n");
+ Printf(f_directors_h, " class Director;\n");
+ Printf(f_directors_h, "}\n\n");
+
+ Printf(f_directors_helpers, "/* ---------------------------------------------------\n");
+ Printf(f_directors_helpers, " * C++ director class helpers\n");
+ Printf(f_directors_helpers, " * --------------------------------------------------- */\n\n");
+
+ Printf(f_directors, "\n\n");
+ Printf(f_directors, "/* ---------------------------------------------------\n");
+ Printf(f_directors, " * C++ director class methods\n");
+ Printf(f_directors, " * --------------------------------------------------- */\n\n");
+ if (outfile_h)
+ Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h));
+
+ Delete(module_macro);
+ }
+
+ 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 */
+ String* docs = docstring(n, AUTODOC_CLASS);
+ Printf(f_init, "/*\n%s\n*/", docs );
+ Printv(f_init, "\n", "#ifdef __cplusplus\n", "extern \"C\"\n", "#endif\n", "SWIGEXPORT void Init_", feature, "(void) {\n", "size_t i;\n", "\n", NIL);
+
+ Printv(f_init, tab4, "SWIG_InitRuntime();\n", NIL);
+
+ if (!useGlobalModule)
+ defineRubyModule();
+
+ Printv(f_init, "\n", "SWIG_InitializeModule(0);\n", "for (i = 0; i < swig_module.size; i++) {\n", "SWIG_define_class(swig_module.types[i]);\n", "}\n", NIL);
+ Printf(f_init, "\n");
+
+ /* Initialize code to keep track of objects */
+ Printf(f_init, "SWIG_RubyInitializeTrackings();\n");
+
+ Language::top(n);
+
+ if (directorsEnabled()) {
+ // Insert director runtime into the f_runtime file (make it occur before %header section)
+ Swig_insert_file("director.swg", f_runtime);
+ }
+
+ /* Finish off our init function */
+ Printf(f_init, "}\n");
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+
+ /* Close all of the files */
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+
+ if (directorsEnabled()) {
+ Dump(f_directors_helpers, f_begin);
+ Dump(f_directors, f_begin);
+ Dump(f_directors_h, f_runtime_h);
+ Printf(f_runtime_h, "\n");
+ Printf(f_runtime_h, "#endif\n");
+ Close(f_runtime_h);
+ }
+
+ Dump(f_wrappers, f_begin);
+ Dump(f_initbeforefunc, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Delete(f_initbeforefunc);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * importDirective()
+ * ----------------------------------------------------------------------------- */
+
+ virtual int importDirective(Node *n) {
+ String *modname = Getattr(n, "module");
+ if (modname) {
+ if (prefix) {
+ Insert(modname, 0, prefix);
+ }
+
+ List *modules = Split(modname, ':', INT_MAX);
+ if (modules && Len(modules) > 0) {
+ modname = NewString("");
+ String *last = NULL;
+ Iterator m = First(modules);
+ while (m.item) {
+ if (Len(m.item) > 0) {
+ if (last) {
+ Append(modname, "/");
+ }
+ Append(modname, m.item);
+ last = m.item;
+ }
+ m = Next(m);
+ }
+ Printf(f_init, "rb_require(\"%s\");\n", modname);
+ Delete(modname);
+ }
+ Delete(modules);
+ }
+ return Language::importDirective(n);
+ }
+
+ /* ---------------------------------------------------------------------
+ * set_module(const char *mod_name)
+ *
+ * Sets the module name. Does nothing if it's already set (so it can
+ * be overridden as a command line option).
+ *---------------------------------------------------------------------- */
+
+ void set_module(const char *s) {
+ String *mod_name = NewString(s);
+ if (module == 0) {
+ /* Start with the empty string */
+ module = NewString("");
+
+ if (prefix) {
+ Insert(mod_name, 0, prefix);
+ }
+
+ /* Account for nested modules */
+ List *modules = Split(mod_name, ':', INT_MAX);
+ if (modules != 0 && Len(modules) > 0) {
+ String *last = 0;
+ Iterator m = First(modules);
+ while (m.item) {
+ if (Len(m.item) > 0) {
+ String *cap = NewString(m.item);
+ (Char(cap))[0] = (char)toupper((Char(cap))[0]);
+ if (last != 0) {
+ Append(module, "::");
+ }
+ Append(module, cap);
+ last = m.item;
+ }
+ m = Next(m);
+ }
+ if (feature == 0) {
+ feature = Copy(last);
+ }
+ (Char(last))[0] = (char)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;
+ }
+
+ /**
+ * Process the comma-separated list of aliases (if any).
+ */
+ void defineAliases(Node *n, const_String_or_char_ptr iname) {
+ String *aliasv = Getattr(n, "feature:alias");
+ if (aliasv) {
+ List *aliases = Split(aliasv, ',', INT_MAX);
+ if (aliases && Len(aliases) > 0) {
+ Iterator alias = First(aliases);
+ while (alias.item) {
+ if (Len(alias.item) > 0) {
+ Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias.item, "\", \"", iname, "\");\n", NIL);
+ }
+ alias = Next(alias);
+ }
+ }
+ Delete(aliases);
+ }
+ }
+
+ /* ---------------------------------------------------------------------
+ * create_command(Node *n, char *iname)
+ *
+ * Creates a new command from a C function.
+ * iname = Name of function in scripting language
+ *
+ * A note about what "protected" and "private" mean in Ruby:
+ *
+ * A private method is accessible only within the class or its subclasses,
+ * and it is callable only in "function form", with 'self' (implicit or
+ * explicit) as a receiver.
+ *
+ * A protected method is callable only from within its class, but unlike
+ * a private method, it can be called with a receiver other than self, such
+ * as another instance of the same class.
+ * --------------------------------------------------------------------- */
+
+ void create_command(Node *n, const_String_or_char_ptr iname) {
+
+ String *alloc_func = Swig_name_wrapper(iname);
+ String *wname = Swig_name_wrapper(iname);
+ if (CPlusPlus) {
+ Insert(wname, 0, "VALUEFUNC(");
+ Append(wname, ")");
+ }
+ if (current != NO_CPP)
+ iname = klass->strip(iname);
+ if (Getattr(special_methods, iname)) {
+ iname = GetChar(special_methods, iname);
+ }
+
+ String *s = NewString("");
+ String *temp = NewString("");
+
+#ifdef SWIG_PROTECTED_TARGET_METHODS
+ const char *rb_define_method = is_public(n) ? "rb_define_method" : "rb_define_protected_method";
+#else
+ const char *rb_define_method = "rb_define_method";
+#endif
+ switch (current) {
+ case MEMBER_FUNC:
+ {
+ if (multipleInheritance) {
+ Printv(klass->init, tab4, rb_define_method, "(", klass->mImpl, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
+ } else {
+ Printv(klass->init, tab4, rb_define_method, "(", klass->vname, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
+ }
+ }
+ break;
+ case CONSTRUCTOR_ALLOCATE:
+ Printv(s, tab4, "rb_define_alloc_func(", klass->vname, ", ", alloc_func, ");\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);
+ /* Check for _set or _get at the end of the name. */
+ if (Len(temp) > 4) {
+ const char *p = Char(temp) + (Len(temp) - 4);
+ if (strcmp(p, "_set") == 0) {
+ Delslice(temp, Len(temp) - 4, DOH_END);
+ Append(temp, "=");
+ } else if (strcmp(p, "_get") == 0) {
+ Delslice(temp, Len(temp) - 4, DOH_END);
+ }
+ }
+ if (multipleInheritance) {
+ Printv(klass->init, tab4, "rb_define_method(", klass->mImpl, ", \"", temp, "\", ", wname, ", -1);\n", NIL);
+ } else {
+ 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;
+ case NO_CPP:
+ if (!useGlobalModule) {
+ Printv(s, tab4, "rb_define_module_function(", modvar, ", \"", iname, "\", ", wname, ", -1);\n", NIL);
+ Printv(f_init, s, NIL);
+ } else {
+ Printv(s, tab4, "rb_define_global_function(\"", iname, "\", ", wname, ", -1);\n", NIL);
+ Printv(f_init, s, NIL);
+ }
+ break;
+ case DESTRUCTOR:
+ case CLASS_CONST:
+ case STATIC_VAR:
+ assert(false); // Should not have gotten here for these types
+ default:
+ assert(false);
+ }
+
+ defineAliases(n, iname);
+
+ Delete(temp);
+ Delete(s);
+ Delete(wname);
+ Delete(alloc_func);
+ }
+
+ /* ---------------------------------------------------------------------
+ * applyInputTypemap()
+ *
+ * Look up the appropriate "in" typemap for this parameter (p),
+ * substitute the correct strings for the $target and $input typemap
+ * parameters, and dump the resulting code to the wrapper file.
+ * --------------------------------------------------------------------- */
+
+ Parm *applyInputTypemap(Parm *p, String *ln, String *source, Wrapper *f, String *symname) {
+ String *tm;
+ SwigType *pt = Getattr(p, "type");
+ if ((tm = Getattr(p, "tmap:in"))) {
+ Replaceall(tm, "$target", ln);
+ Replaceall(tm, "$source", source);
+ Replaceall(tm, "$input", source);
+ Replaceall(tm, "$symname", symname);
+
+ if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
+ Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm, "$disown", "0");
+ }
+
+ Setattr(p, "emit:input", Copy(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);
+ }
+ return p;
+ }
+
+ Parm *skipIgnoredArgs(Parm *p) {
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+ return p;
+ }
+
+ /* ---------------------------------------------------------------------
+ * marshalInputArgs()
+ *
+ * Process all of the arguments passed into the scripting language
+ * method and convert them into C/C++ function arguments using the
+ * supplied typemaps.
+ * --------------------------------------------------------------------- */
+
+ void marshalInputArgs(Node *n, ParmList *l, int numarg, int numreq, String *kwargs, bool allow_kwargs, Wrapper *f) {
+ int i;
+ Parm *p;
+ String *tm;
+ String *source;
+ String *target;
+
+ source = NewString("");
+ target = NewString("");
+
+ bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
+
+ /**
+ * The 'start' value indicates which of the C/C++ function arguments
+ * produced here corresponds to the first value in Ruby's argv[] array.
+ * The value of start is either zero or one. If start is zero, then
+ * the first argument (with name arg1) is based on the value of argv[0].
+ * If start is one, then arg1 is based on the value of argv[1].
+ */
+ int start = (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) ? 1 : 0;
+
+ int varargs = emit_isvarargs(l);
+
+ Printf(kwargs, "{ ");
+ for (i = 0, p = l; i < numarg; i++) {
+
+ p = skipIgnoredArgs(p);
+
+ String *pn = Getattr(p, "name");
+ String *ln = Getattr(p, "lname");
+
+ /* Produce string representation of source argument */
+ Clear(source);
+
+ /* First argument is a special case */
+ if (i == 0) {
+ Printv(source, (start == 0) ? "argv[0]" : "self", NIL);
+ } else {
+ Printf(source, "argv[%d]", i - start);
+ }
+
+ /* Produce string representation of target argument */
+ Clear(target);
+ Printf(target, "%s", Char(ln));
+
+ if (i >= (numreq)) { /* Check if parsing an optional argument */
+ Printf(f->code, " if (argc > %d) {\n", i - start);
+ }
+
+ /* Record argument name for keyword argument handling */
+ if (Len(pn)) {
+ Printf(kwargs, "\"%s\",", pn);
+ } else {
+ Printf(kwargs, "\"arg%d\",", i + 1);
+ }
+
+ /* Look for an input typemap */
+ p = applyInputTypemap(p, ln, source, f, Getattr(n, "name"));
+ 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"))) {
+ Clear(source);
+ Printf(source, "argv[%d]", i - start);
+ Replaceall(tm, "$input", source);
+ Setattr(p, "emit:input", Copy(source));
+ Printf(f->code, "if (argc > %d) {\n", i - start);
+ Printv(f->code, tm, "\n", NIL);
+ Printf(f->code, "}\n");
+ }
+ }
+
+ Delete(source);
+ Delete(target);
+ }
+
+ /* ---------------------------------------------------------------------
+ * insertConstraintCheckingCode(ParmList *l, Wrapper *f)
+ *
+ * Checks each of the parameters in the parameter list for a "check"
+ * typemap and (if it finds one) inserts the typemapping code into
+ * the function wrapper.
+ * --------------------------------------------------------------------- */
+
+ void insertConstraintCheckingCode(ParmList *l, Wrapper *f) {
+ Parm *p;
+ String *tm;
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* ---------------------------------------------------------------------
+ * insertCleanupCode(ParmList *l, String *cleanup)
+ *
+ * Checks each of the parameters in the parameter list for a "freearg"
+ * typemap and (if it finds one) inserts the typemapping code into
+ * the function wrapper.
+ * --------------------------------------------------------------------- */
+
+ void insertCleanupCode(ParmList *l, String *cleanup) {
+ String *tm;
+ for (Parm *p = l; p;) {
+ if ((tm = Getattr(p, "tmap:freearg"))) {
+ if (Len(tm) != 0) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Printv(cleanup, tm, "\n", NIL);
+ }
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* ---------------------------------------------------------------------
+ * insertArgOutputCode(ParmList *l, String *outarg, int& need_result)
+ *
+ * Checks each of the parameters in the parameter list for a "argout"
+ * typemap and (if it finds one) inserts the typemapping code into
+ * the function wrapper.
+ * --------------------------------------------------------------------- */
+
+ void insertArgOutputCode(ParmList *l, String *outarg, int &need_result) {
+ String *tm;
+ for (Parm *p = l; p;) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Replaceall(tm, "$target", "vresult");
+ Replaceall(tm, "$result", "vresult");
+ Replaceall(tm, "$arg", Getattr(p, "emit:input"));
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+
+ Printv(outarg, tm, "\n", NIL);
+ need_result += 1;
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+ }
+
+ /* ---------------------------------------------------------------------
+ * validIdentifier()
+ *
+ * Is this a valid identifier in the scripting language?
+ * Ruby method names can include any combination of letters, numbers
+ * and underscores. A Ruby method name may optionally end with
+ * a question mark ("?"), exclamation point ("!") or equals sign ("=").
+ *
+ * Methods whose names end with question marks are, by convention,
+ * predicate methods that return true or false (e.g. Array#empty?).
+ *
+ * Methods whose names end with exclamation points are, by convention,
+ * called bang methods that modify the instance in place (e.g. Array#sort!).
+ *
+ * Methods whose names end with an equals sign are attribute setters
+ * (e.g. Thread#critical=).
+ * --------------------------------------------------------------------- */
+
+ virtual int validIdentifier(String *s) {
+ char *c = Char(s);
+ while (*c) {
+ if (!(isalnum(*c) || (*c == '_') || (*c == '?') || (*c == '!') || (*c == '=')))
+ return 0;
+ c++;
+ }
+ return 1;
+ }
+
+ /* ---------------------------------------------------------------------
+ * functionWrapper()
+ *
+ * Create a function declaration and register it with the interpreter.
+ * --------------------------------------------------------------------- */
+
+ virtual int functionWrapper(Node *n) {
+
+ String *nodeType;
+ bool constructor;
+ bool destructor;
+ String *storage;
+
+ String *symname = Copy(Getattr(n, "sym:name"));
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ int director_method = 0;
+ String *tm;
+
+ int need_result = 0;
+
+ /* Ruby needs no destructor wrapper */
+ if (current == DESTRUCTOR)
+ return SWIG_NOWRAP;
+
+ nodeType = Getattr(n, "nodeType");
+ constructor = (!Cmp(nodeType, "constructor"));
+ destructor = (!Cmp(nodeType, "destructor"));
+ storage = Getattr(n, "storage");
+
+ /* If the C++ class constructor is overloaded, we only want to
+ * write out the "new" singleton method once since it is always
+ * the same. (It's the "initialize" method that will handle the
+ * overloading). */
+
+ if (current == CONSTRUCTOR_ALLOCATE && Swig_symbol_isoverloaded(n) && Getattr(n, "sym:nextSibling") != 0)
+ return SWIG_OK;
+
+ String *overname = 0;
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(symname, n))
+ return SWIG_ERROR;
+ }
+
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+ String *kwargs = NewString("");
+ Wrapper *f = NewWrapper();
+
+ /* Rename predicate methods */
+ if (GetFlag(n, "feature:predicate")) {
+ Append(symname, "?");
+ }
+
+ /* Rename bang methods */
+ if (GetFlag(n, "feature:bang")) {
+ Append(symname, "!");
+ }
+
+ /* Determine the name of the SWIG wrapper function */
+ String *wname = Swig_name_wrapper(symname);
+ if (overname && current != CONSTRUCTOR_ALLOCATE) {
+ Append(wname, overname);
+ }
+
+ /* Emit arguments */
+ if (current != CONSTRUCTOR_ALLOCATE) {
+ emit_parameter_variables(l, f);
+ }
+
+ /* Attach standard typemaps */
+ if (current != CONSTRUCTOR_ALLOCATE) {
+ emit_attach_parmmaps(l, f);
+ }
+ Setattr(n, "wrap:parms", l);
+
+ /* Get number of arguments */
+ int numarg = emit_num_arguments(l);
+ int numreq = emit_num_required(l);
+ int varargs = emit_isvarargs(l);
+ bool allow_kwargs = GetFlag(n, "feature:kwargs") ? true : false;
+
+ bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
+ int start = (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) ? 1 : 0;
+
+ /* Now write the wrapper function itself */
+ if (current == CONSTRUCTOR_ALLOCATE) {
+ Printf(f->def, "#ifdef HAVE_RB_DEFINE_ALLOC_FUNC\n");
+ Printv(f->def, "SWIGINTERN VALUE\n", wname, "(VALUE self) {", NIL);
+ Printf(f->def, "#else\n");
+ Printv(f->def, "SWIGINTERN VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
+ Printf(f->def, "#endif\n");
+ } else if (current == CONSTRUCTOR_INITIALIZE) {
+ Printv(f->def, "SWIGINTERN VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
+ if (!varargs) {
+ Printf(f->code, "if ((argc < %d) || (argc > %d)) ", numreq - start, numarg - start);
+ } else {
+ Printf(f->code, "if (argc < %d) ", numreq - start);
+ }
+ Printf(f->code, "{rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc); SWIG_fail;}\n", numreq - start);
+ } else {
+
+ if ( current == NO_CPP )
+ {
+ String* docs = docstring(n, AUTODOC_FUNC);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+ }
+
+ Printv(f->def, "SWIGINTERN VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL);
+ if (!varargs) {
+ Printf(f->code, "if ((argc < %d) || (argc > %d)) ", numreq - start, numarg - start);
+ } else {
+ Printf(f->code, "if (argc < %d) ", numreq - start);
+ }
+ Printf(f->code, "{rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc); SWIG_fail;}\n", numreq - start);
+ }
+
+ /* Now walk the function parameter list and generate code */
+ /* to get arguments */
+ if (current != CONSTRUCTOR_ALLOCATE) {
+ marshalInputArgs(n, l, numarg, numreq, kwargs, allow_kwargs, f);
+ }
+ // FIXME?
+ if (ctor_director) {
+ numarg--;
+ numreq--;
+ }
+
+ /* Insert constraint checking code */
+ insertConstraintCheckingCode(l, f);
+
+ /* Insert cleanup code */
+ insertCleanupCode(l, cleanup);
+
+ /* Insert argument output code */
+ insertArgOutputCode(l, outarg, need_result);
+
+ /* if the object is a director, and the method call originated from its
+ * underlying Ruby object, resolve the call by going up the c++
+ * inheritance chain. otherwise try to resolve the method in python.
+ * without this check an infinite loop is set up between the director and
+ * shadow class method calls.
+ */
+
+ // NOTE: this code should only be inserted if this class is the
+ // base class of a director class. however, in general we haven't
+ // yet analyzed all classes derived from this one to see if they are
+ // directors. furthermore, this class may be used as the base of
+ // a director class defined in a completely different module at a
+ // later time, so this test must be included whether or not directorbase
+ // is true. we do skip this code if directors have not been enabled
+ // at the command line to preserve source-level compatibility with
+ // non-polymorphic swig. also, if this wrapper is for a smart-pointer
+ // method, there is no need to perform the test since the calling object
+ // (the smart-pointer) and the director object (the "pointee") are
+ // distinct.
+
+ director_method = is_member_director(n) && !is_smart_pointer() && !destructor;
+ if (director_method) {
+ Wrapper_add_local(f, "director", "Swig::Director *director = 0");
+ Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n");
+ Wrapper_add_local(f, "upcall", "bool upcall = false");
+ Append(f->code, "upcall = (director && (director->swig_get_self() == self));\n");
+ }
+
+ /* Now write code to make the function call */
+ if (current != CONSTRUCTOR_ALLOCATE) {
+ if (current == CONSTRUCTOR_INITIALIZE) {
+ Node *pn = Swig_methodclass(n);
+ String *symname = Getattr(pn, "sym:name");
+ String *action = Getattr(n, "wrap:action");
+ if (directorsEnabled()) {
+ String *classname = NewStringf("const char *classname SWIGUNUSED = \"%s::%s\"", module, symname);
+ Wrapper_add_local(f, "classname", classname);
+ }
+ if (action) {
+ Append(action, "\nDATA_PTR(self) = result;");
+ if (GetFlag(pn, "feature:trackobjects")) {
+ Append(action, "\nSWIG_RubyAddTracking(result, self);");
+ }
+ }
+ }
+
+ /* Emit the function call */
+ if (director_method) {
+ Printf(f->code, "try {\n");
+ }
+
+ Setattr(n, "wrap:name", wname);
+
+ Swig_director_emit_dynamic_cast(n, f);
+ String *actioncode = emit_action(n);
+
+ if (director_method) {
+ Printf(actioncode, "} catch (Swig::DirectorException& e) {\n");
+ Printf(actioncode, " rb_exc_raise(e.getError());\n");
+ Printf(actioncode, " SWIG_fail;\n");
+ Printf(actioncode, "}\n");
+ }
+
+ /* Return value if necessary */
+ if (SwigType_type(t) != T_VOID && current != CONSTRUCTOR_INITIALIZE) {
+ need_result = 1;
+ if (GetFlag(n, "feature:predicate")) {
+ Printv(actioncode, tab4, "vresult = (result ? Qtrue : Qfalse);\n", NIL);
+ } else {
+ tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode);
+ actioncode = 0;
+ if (tm) {
+ Replaceall(tm, "$result", "vresult");
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$target", "vresult");
+
+ if (GetFlag(n, "feature:new"))
+ Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
+ else
+ Replaceall(tm, "$owner", "0");
+
+#if 1
+ // FIXME: this will not try to unwrap directors returned as non-director
+ // base class pointers!
+
+ /* New addition to unwrap director return values so that the original
+ * Ruby object is returned instead.
+ */
+ bool unwrap = false;
+ String *decl = Getattr(n, "decl");
+ int is_pointer = SwigType_ispointer_return(decl);
+ int is_reference = SwigType_isreference_return(decl);
+ if (is_pointer || is_reference) {
+ String *type = Getattr(n, "type");
+ Node *parent = Swig_methodclass(n);
+ Node *modname = Getattr(parent, "module");
+ Node *target = Swig_directormap(modname, type);
+ if (target)
+ unwrap = true;
+ }
+ if (unwrap) {
+ Wrapper_add_local(f, "director", "Swig::Director *director = 0");
+ Printf(f->code, "director = dynamic_cast<Swig::Director *>(result);\n");
+ Printf(f->code, "if (director) {\n");
+ Printf(f->code, " vresult = director->swig_get_self();\n");
+ Printf(f->code, "} else {\n");
+ Printf(f->code, "%s\n", tm);
+ Printf(f->code, "}\n");
+ director_method = 0;
+ } else {
+ Printf(f->code, "%s\n", tm);
+ }
+#else
+ Printf(f->code, "%s\n", tm);
+#endif
+ Delete(tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s.\n", SwigType_str(t, 0));
+ }
+ }
+ }
+ if (actioncode) {
+ Append(f->code, actioncode);
+ Delete(actioncode);
+ }
+ emit_return_variable(n, t, 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, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n");
+ Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n");
+ Printf(f->code, "#endif\n");
+ } else if (current == CONSTRUCTOR_INITIALIZE) {
+ need_result = 1;
+ // Printf(f->code, "DATA_PTR(self) = result;\n");
+ }
+ else
+ {
+ if ( need_result > 1 ) {
+ if ( SwigType_type(t) == T_VOID )
+ Printf(f->code, "vresult = rb_ary_new();\n");
+ else
+ {
+ Printf(f->code, "if (vresult == Qnil) vresult = rb_ary_new();\n");
+ Printf(f->code, "else vresult = SWIG_Ruby_AppendOutput( "
+ "rb_ary_new(), vresult);\n");
+ }
+ }
+ }
+
+ /* Dump argument output code; */
+ Printv(f->code, outarg, NIL);
+
+ /* Dump the argument cleanup code */
+ int need_cleanup = (current != CONSTRUCTOR_ALLOCATE) && (Len(cleanup) != 0);
+ if (need_cleanup) {
+ Printv(f->code, cleanup, NIL);
+ }
+
+
+ /* Look for any remaining cleanup. This processes the %new directive */
+ if (current != CONSTRUCTOR_ALLOCATE && GetFlag(n, "feature:new")) {
+ tm = Swig_typemap_lookup("newfree", n, "result", 0);
+ if (tm) {
+ Replaceall(tm, "$source", "result");
+ Printv(f->code, tm, "\n", NIL);
+ Delete(tm);
+ }
+ }
+
+ /* Special processing on return value. */
+ tm = Swig_typemap_lookup("ret", n, "result", 0);
+ if (tm) {
+ Replaceall(tm, "$source", "result");
+ Printv(f->code, tm, NIL);
+ Delete(tm);
+ }
+
+ if (director_method) {
+ if ((tm = Swig_typemap_lookup("directorfree", n, "result", 0))) {
+ Replaceall(tm, "$input", "result");
+ Replaceall(tm, "$result", "vresult");
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+
+ /* Wrap things up (in a manner of speaking) */
+ if (need_result) {
+ if (current == CONSTRUCTOR_ALLOCATE) {
+ Printv(f->code, tab4, "return vresult;\n", NIL);
+ } else if (current == CONSTRUCTOR_INITIALIZE) {
+ Printv(f->code, tab4, "return self;\n", NIL);
+ Printv(f->code, "fail:\n", NIL);
+ if (need_cleanup) {
+ Printv(f->code, cleanup, NIL);
+ }
+ Printv(f->code, tab4, "return Qnil;\n", NIL);
+ } else {
+ Wrapper_add_local(f, "vresult", "VALUE vresult = Qnil");
+ Printv(f->code, tab4, "return vresult;\n", NIL);
+ Printv(f->code, "fail:\n", NIL);
+ if (need_cleanup) {
+ Printv(f->code, cleanup, NIL);
+ }
+ Printv(f->code, tab4, "return Qnil;\n", NIL);
+ }
+ } else {
+ Printv(f->code, tab4, "return Qnil;\n", NIL);
+ Printv(f->code, "fail:\n", NIL);
+ if (need_cleanup) {
+ Printv(f->code, cleanup, NIL);
+ }
+ Printv(f->code, tab4, "return Qnil;\n", NIL);
+ }
+
+ Printf(f->code, "}\n");
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code, "$cleanup", cleanup);
+
+ /* Substitute the function name */
+ Replaceall(f->code, "$symname", symname);
+
+ /* Emit the function */
+ Wrapper_print(f, f_wrappers);
+
+ /* Now register the function with the interpreter */
+ if (!Swig_symbol_isoverloaded(n)) {
+ create_command(n, symname);
+ } else {
+ if (current == CONSTRUCTOR_ALLOCATE) {
+ create_command(n, symname);
+ } else {
+ if (!Getattr(n, "sym:nextSibling"))
+ dispatchFunction(n);
+ }
+ }
+
+ Delete(kwargs);
+ Delete(cleanup);
+ Delete(outarg);
+ DelWrapper(f);
+ Delete(symname);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * dispatchFunction()
+ * ------------------------------------------------------------ */
+
+ void dispatchFunction(Node *n) {
+ /* Last node in overloaded chain */
+
+ int maxargs;
+ String *tmp = NewString("");
+ String *dispatch = Swig_overload_dispatch(n, "return %s(nargs, args, self);", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *f = NewWrapper();
+ String *symname = Getattr(n, "sym:name");
+ String *wname = Swig_name_wrapper(symname);
+
+ Printv(f->def, "SWIGINTERN VALUE ", wname, "(int nargs, VALUE *args, VALUE self) {", NIL);
+
+ Wrapper_add_local(f, "argc", "int argc");
+ bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
+ if (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) {
+ Printf(tmp, "VALUE argv[%d]", maxargs + 1);
+ } else {
+ Printf(tmp, "VALUE argv[%d]", maxargs);
+ }
+ Wrapper_add_local(f, "argv", tmp);
+ Wrapper_add_local(f, "ii", "int ii");
+
+ if (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) {
+ maxargs += 1;
+ Printf(f->code, "argc = nargs + 1;\n");
+ Printf(f->code, "argv[0] = self;\n");
+ Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs);
+ Printf(f->code, "for (ii = 1; (ii < argc); ++ii) {\n");
+ Printf(f->code, "argv[ii] = args[ii-1];\n");
+ Printf(f->code, "}\n");
+ } else {
+ Printf(f->code, "argc = nargs;\n");
+ Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs);
+ Printf(f->code, "for (ii = 0; (ii < argc); ++ii) {\n");
+ Printf(f->code, "argv[ii] = args[ii];\n");
+ Printf(f->code, "}\n");
+ }
+
+ Replaceall(dispatch, "$args", "nargs, args, self");
+ Printv(f->code, dispatch, "\n", NIL);
+
+
+
+ // Generate prototype list, go to first node
+ Node *sibl = n;
+
+ String* type = SwigType_str(Getattr(sibl,"type"),NULL);
+
+ while (Getattr(sibl, "sym:previousSibling"))
+ sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up
+
+ // Constructors will be treated specially
+ const bool isCtor = Cmp(Getattr(sibl,"feature:new"), "1") == 0;
+ const bool isMethod = ( Cmp(Getattr(sibl, "ismember"), "1") == 0 &&
+ (!isCtor) );
+
+ // Construct real method name
+ String* methodName = NewString("");
+ if ( isMethod )
+ Printv( methodName, Getattr(parentNode(sibl),"sym:name"), ".", NIL );
+ Append( methodName, Getattr(sibl,"sym:name" ) );
+ if ( isCtor ) Append( methodName, ".new" );
+
+ // Generate prototype list
+ String *protoTypes = NewString("");
+ do {
+ Append( protoTypes, "\n\" ");
+ if ( !isCtor ) Printv( protoTypes, type, " ", NIL );
+ Printv(protoTypes, methodName, NIL );
+ Parm* p = Getattr(sibl, "wrap:parms");
+ if (p && (current == MEMBER_FUNC || current == MEMBER_VAR ||
+ ctor_director) )
+ p = nextSibling(p); // skip self
+ Append( protoTypes, "(" );
+ while(p)
+ {
+ Append( protoTypes, SwigType_str(Getattr(p,"type"), Getattr(p,"name")) );
+ if ( ( p = nextSibling(p)) ) Append(protoTypes, ", ");
+ }
+ Append( protoTypes, ")\\n\"" );
+ } while ((sibl = Getattr(sibl, "sym:nextSibling")));
+
+ Append(f->code, "fail:\n");
+ Printf(f->code, "Ruby_Format_OverloadedError( argc, %d, \"%s\", %s);\n",
+ maxargs, methodName, protoTypes);
+ Append(f->code, "\nreturn Qnil;\n");
+
+ Delete(methodName);
+ Delete(type);
+ Delete(protoTypes);
+
+ 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) {
+ String* docs = docstring(n, AUTODOC_GETTER);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+
+
+ 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 */
+ int addfail = 0;
+ String *getname = Swig_name_get(iname);
+ getfname = Swig_name_wrapper(getname);
+ Setattr(n, "wrap:name", getfname);
+ Printv(getf->def, "SWIGINTERN VALUE\n", getfname, "(", NIL);
+ Printf(getf->def, "VALUE self");
+ Printf(getf->def, ") {");
+ Wrapper_add_local(getf, "_val", "VALUE _val");
+
+ tm = Swig_typemap_lookup("varout", n, name, 0);
+ if (tm) {
+ Replaceall(tm, "$result", "_val");
+ Replaceall(tm, "$target", "_val");
+ Replaceall(tm, "$source", name);
+ /* Printv(getf->code,tm, NIL); */
+ addfail = emit_action_code(n, getf->code, tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
+ }
+ Printv(getf->code, tab4, "return _val;\n", NIL);
+ if (addfail) {
+ Append(getf->code, "fail:\n");
+ Append(getf->code, " return Qnil;\n");
+ }
+ Append(getf->code, "}\n");
+
+ Wrapper_print(getf, f_wrappers);
+
+ if (!is_assignable(n)) {
+ setfname = NewString("NULL");
+ } else {
+ /* create setter */
+ String* docs = docstring(n, AUTODOC_SETTER);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+
+ String *setname = Swig_name_set(iname);
+ setfname = Swig_name_wrapper(setname);
+ Setattr(n, "wrap:name", setfname);
+ Printv(setf->def, "SWIGINTERN VALUE\n", setfname, "(VALUE self, ", NIL);
+ Printf(setf->def, "VALUE _val) {");
+ tm = Swig_typemap_lookup("varin", n, name, 0);
+ if (tm) {
+ Replaceall(tm, "$input", "_val");
+ Replaceall(tm, "$source", "_val");
+ Replaceall(tm, "$target", name);
+ /* Printv(setf->code,tm,"\n",NIL); */
+ emit_action_code(n, setf->code, tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s\n", SwigType_str(t, 0));
+ }
+ Printv(setf->code, tab4, "return _val;\n", NIL);
+ Printf(setf->code, "fail:\n");
+ Printv(setf->code, tab4, "return Qnil;\n", NIL);
+ Printf(setf->code, "}\n");
+ Wrapper_print(setf, f_wrappers);
+ Delete(setname);
+ }
+
+ /* define accessor method */
+ if (CPlusPlus) {
+ Insert(getfname, 0, "VALUEFUNC(");
+ Append(getfname, ")");
+ Insert(setfname, 0, "VALUEFUNC(");
+ Append(setfname, ")");
+ }
+
+ String *s = NewString("");
+ switch (current) {
+ case STATIC_VAR:
+ /* C++ class variable */
+ Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "\", ", getfname, ", 0);\n", NIL);
+ if (!GetFlag(n, "feature:immutable")) {
+ 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 */
+ assert(current == NO_CPP);
+ if (!useGlobalModule) {
+ Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "\", ", getfname, ", 0);\n", NIL);
+ if (!GetFlag(n, "feature:immutable")) {
+ Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "=\", ", setfname, ", 1);\n", NIL);
+ }
+ } else {
+ Printv(s, tab4, "rb_define_global_method(\"", iname, "\", ", getfname, ", 0);\n", NIL);
+ if (!GetFlag(n, "feature:immutable")) {
+ Printv(s, tab4, "rb_define_global_method(\"", iname, "=\", ", setfname, ", 1);\n", NIL);
+ }
+ }
+ Printv(f_init, s, NIL);
+ Delete(s);
+ break;
+ }
+ Delete(getname);
+ Delete(getfname);
+ Delete(setfname);
+ DelWrapper(setf);
+ DelWrapper(getf);
+ return SWIG_OK;
+ }
+
+
+ /* ---------------------------------------------------------------------
+ * validate_const_name(char *name)
+ *
+ * Validate constant name.
+ * --------------------------------------------------------------------- */
+
+ char *validate_const_name(char *name, const char *reason) {
+ if (!name || name[0] == '\0')
+ return name;
+
+ if (isupper(name[0]))
+ return name;
+
+ if (islower(name[0])) {
+ name[0] = (char)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 %s\n", reason, name);
+
+ return name;
+ }
+
+ /* ---------------------------------------------------------------------
+ * constantWrapper()
+ * --------------------------------------------------------------------- */
+
+ virtual int constantWrapper(Node *n) {
+ Swig_require("constantWrapper", n, "*sym:name", "type", "value", NIL);
+
+ char *iname = GetChar(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ String *rawval = Getattr(n, "rawval");
+ String *value = rawval ? rawval : Getattr(n, "value");
+
+ if (current == CLASS_CONST) {
+ iname = klass->strip(iname);
+ }
+ validate_const_name(iname, "constant");
+ SetChar(n, "sym:name", iname);
+
+ /* Special hook for member pointer */
+ if (SwigType_type(type) == T_MPOINTER) {
+ String *wname = Swig_name_wrapper(iname);
+ Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value);
+ value = Char(wname);
+ }
+ String *tm = Swig_typemap_lookup("constant", n, value, 0);
+ if (!tm)
+ tm = Swig_typemap_lookup("constcode", n, value, 0);
+ if (tm) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", iname);
+ Replaceall(tm, "$symname", iname);
+ Replaceall(tm, "$value", value);
+ if (current == CLASS_CONST) {
+ if (multipleInheritance) {
+ Replaceall(tm, "$module", klass->mImpl);
+ Printv(klass->init, tm, "\n", NIL);
+ } else {
+ Replaceall(tm, "$module", klass->vname);
+ Printv(klass->init, tm, "\n", NIL);
+ }
+ } else {
+ if (!useGlobalModule) {
+ Replaceall(tm, "$module", modvar);
+ } else {
+ Replaceall(tm, "$module", "rb_cObject");
+ }
+ Printf(f_init, "%s\n", tm);
+ }
+ } else {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value);
+ }
+ Swig_restore(n);
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * classDeclaration()
+ *
+ * Records information about classes---even classes that might be defined in
+ * other modules referenced by %import.
+ * ----------------------------------------------------------------------------- */
+
+ virtual int classDeclaration(Node *n) {
+ if (!Getattr(n, "feature:onlychildren")) {
+ String *name = Getattr(n, "name");
+ String *symname = Getattr(n, "sym:name");
+ String *tdname = Getattr(n, "tdname");
+
+ name = tdname ? tdname : name;
+ String *namestr = SwigType_namestr(name);
+ klass = RCLASS(classes, Char(namestr));
+ if (!klass) {
+ klass = new RClass();
+ String *valid_name = NewString(symname ? symname : namestr);
+ validate_const_name(Char(valid_name), "class");
+ klass->set_name(namestr, symname, valid_name);
+ SET_RCLASS(classes, Char(namestr), klass);
+ Delete(valid_name);
+ }
+ Delete(namestr);
+ }
+ return Language::classDeclaration(n);
+ }
+
+ /**
+ * Process the comma-separated list of mixed-in module names (if any).
+ */
+ void includeRubyModules(Node *n) {
+ String *mixin = Getattr(n, "feature:mixin");
+ if (mixin) {
+ List *modules = Split(mixin, ',', INT_MAX);
+ if (modules && Len(modules) > 0) {
+ Iterator mod = First(modules);
+ while (mod.item) {
+ if (Len(mod.item) > 0) {
+ Printf(klass->init, "rb_include_module(%s, rb_eval_string(\"%s\"));\n", klass->vname, mod.item);
+ }
+ mod = Next(mod);
+ }
+ }
+ Delete(modules);
+ }
+ }
+
+ void handleBaseClasses(Node *n) {
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator base = First(baselist);
+ while (base.item && GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ }
+ while (base.item) {
+ String *basename = Getattr(base.item, "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);
+ if (multipleInheritance) {
+ String *bmangle = SwigType_manglestr(btype);
+ Insert(bmangle, 0, "((swig_class *) SWIGTYPE");
+ Append(bmangle, "->clientdata)->mImpl");
+ Printv(klass->init, "rb_include_module(", klass->mImpl, ", ", bmangle, ");\n", NIL);
+ Delete(bmangle);
+ } else {
+ String *bmangle = SwigType_manglestr(btype);
+ Insert(bmangle, 0, "((swig_class *) SWIGTYPE");
+ Append(bmangle, "->clientdata)->klass");
+ Replaceall(klass->init, "$super", bmangle);
+ Delete(bmangle);
+ }
+ Delete(btype);
+ }
+ base = Next(base);
+ while (base.item && GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ }
+ if (!multipleInheritance) {
+ /* Warn about multiple inheritance for additional base class(es) */
+ while (base.item) {
+ if (GetFlag(base.item, "feature:ignore")) {
+ base = Next(base);
+ continue;
+ }
+ String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
+ String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
+ Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, input_file, line_number,
+ "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Ruby.\n", proxyclassname, baseclassname);
+ base = Next(base);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Check to see if a %markfunc was specified.
+ */
+ void handleMarkFuncDirective(Node *n) {
+ String *markfunc = Getattr(n, "feature:markfunc");
+ if (markfunc) {
+ Printf(klass->init, "SwigClass%s.mark = (void (*)(void *)) %s;\n", klass->name, markfunc);
+ } else {
+ Printf(klass->init, "SwigClass%s.mark = 0;\n", klass->name);
+ }
+ }
+
+ /**
+ * Check to see if a %freefunc was specified.
+ */
+ void handleFreeFuncDirective(Node *n) {
+ String *freefunc = Getattr(n, "feature:freefunc");
+ if (freefunc) {
+ Printf(klass->init, "SwigClass%s.destroy = (void (*)(void *)) %s;\n", klass->name, freefunc);
+ } else {
+ if (klass->destructor_defined) {
+ Printf(klass->init, "SwigClass%s.destroy = (void (*)(void *)) free_%s;\n", klass->name, klass->mname);
+ }
+ }
+ }
+
+ /**
+ * Check to see if tracking is enabled for this class.
+ */
+ void handleTrackDirective(Node *n) {
+ int trackObjects = GetFlag(n, "feature:trackobjects");
+ if (trackObjects) {
+ Printf(klass->init, "SwigClass%s.trackObjects = 1;\n", klass->name);
+ } else {
+ Printf(klass->init, "SwigClass%s.trackObjects = 0;\n", klass->name);
+ }
+ }
+
+ /* ----------------------------------------------------------------------
+ * classHandler()
+ * ---------------------------------------------------------------------- */
+
+ virtual int classHandler(Node *n) {
+ String* docs = docstring(n, AUTODOC_CLASS);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+
+ String *name = Getattr(n, "name");
+ String *symname = Getattr(n, "sym:name");
+ String *namestr = SwigType_namestr(name); // does template expansion
+
+ klass = RCLASS(classes, Char(namestr));
+ assert(klass != 0);
+ Delete(namestr);
+ String *valid_name = NewString(symname);
+ validate_const_name(Char(valid_name), "class");
+
+ Clear(klass->type);
+ Printv(klass->type, Getattr(n, "classtype"), NIL);
+ Printv(f_wrappers, "swig_class SwigClass", valid_name, ";\n\n", NIL);
+ Printv(klass->init, "\n", tab4, NIL);
+
+ if (!useGlobalModule) {
+ Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar, ", \"", klass->name, "\", $super);\n", NIL);
+ } else {
+ Printv(klass->init, klass->vname, " = rb_define_class(\"", klass->name,
+ "\", $super);\n", NIL);
+ }
+
+ if (multipleInheritance) {
+ Printv(klass->init, klass->mImpl, " = rb_define_module_under(", klass->vname, ", \"Impl\");\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 *) &SwigClass%s);\n", tm, valid_name);
+ Delete(tm);
+ Delete(tt);
+ Delete(valid_name);
+
+ includeRubyModules(n);
+
+ Printv(klass->init, "$allocator", NIL);
+ Printv(klass->init, "$initializer", NIL);
+
+ Language::classHandler(n);
+
+ handleBaseClasses(n);
+ handleMarkFuncDirective(n);
+ handleFreeFuncDirective(n);
+ handleTrackDirective(n);
+
+ if (multipleInheritance) {
+ Printv(klass->init, "rb_include_module(", klass->vname, ", ", klass->mImpl, ");\n", NIL);
+ }
+
+ String *s = NewString("");
+ Printv(s, tab4, "rb_undef_alloc_func(", klass->vname, ");\n", NIL);
+ Replaceall(klass->init, "$allocator", s);
+ Replaceall(klass->init, "$initializer", "");
+
+ if (GetFlag(n, "feature:exceptionclass")) {
+ Replaceall(klass->init, "$super", "rb_eRuntimeError");
+ } else {
+ Replaceall(klass->init, "$super", "rb_cObject");
+ }
+ Delete(s);
+
+ Printv(f_init, klass->init, NIL);
+ klass = 0;
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberfunctionHandler()
+ *
+ * Method for adding C++ member function
+ *
+ * By default, we're going to create a function of the form :
+ *
+ * Foo_bar(this,args)
+ *
+ * Where Foo is the classname, bar is the member name and the this pointer
+ * is explicitly attached to the beginning.
+ *
+ * The renaming only applies to the member function part, not the full
+ * classname.
+ *
+ * --------------------------------------------------------------------- */
+
+ virtual int memberfunctionHandler(Node *n) {
+ current = MEMBER_FUNC;
+
+ String* docs = docstring(n, AUTODOC_METHOD);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+
+ Language::memberfunctionHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ---------------------------------------------------------------------
+ * constructorHandler()
+ *
+ * Method for adding C++ member constructor
+ * -------------------------------------------------------------------- */
+
+ void set_director_ctor_code(Node *n) {
+ /* director ctor code is specific for each class */
+ Delete(director_prot_ctor_code);
+ director_prot_ctor_code = NewString("");
+ Node *pn = Swig_methodclass(n);
+ String *symname = Getattr(pn, "sym:name");
+ String *name = Copy(symname);
+ char *cname = Char(name);
+ if (cname)
+ cname[0] = (char)toupper(cname[0]);
+ Printv(director_prot_ctor_code,
+ "if ( $comparison ) { /* subclassed */\n",
+ " $director_new \n",
+ "} else {\n", " rb_raise(rb_eNameError,\"accessing abstract class or protected constructor\"); \n", " return Qnil;\n", "}\n", NIL);
+ Delete(director_ctor_code);
+ director_ctor_code = NewString("");
+ Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL);
+ Delete(name);
+ }
+
+ virtual int constructorHandler(Node *n) {
+ int use_director = Swig_directorclass(n);
+ if (use_director) {
+ set_director_ctor_code(n);
+ }
+
+ /* First wrap the allocate method */
+ current = CONSTRUCTOR_ALLOCATE;
+ Swig_name_register((const_String_or_char_ptr ) "construct", (const_String_or_char_ptr ) "%c_allocate");
+
+
+ Language::constructorHandler(n);
+
+ /*
+ * If we're wrapping the constructor of a C++ director class, prepend a new parameter
+ * to receive the scripting language object (e.g. 'self')
+ *
+ */
+ Swig_save("ruby:constructorHandler", n, "parms", NIL);
+ if (use_director) {
+ Parm *parms = Getattr(n, "parms");
+ Parm *self;
+ String *name = NewString("self");
+ String *type = NewString("VALUE");
+ self = NewParm(type, name);
+ Delete(type);
+ Delete(name);
+ Setattr(self, "lname", "Qnil");
+ if (parms)
+ set_nextSibling(self, parms);
+ Setattr(n, "parms", self);
+ Setattr(n, "wrap:self", "1");
+ Delete(self);
+ }
+
+
+
+ /* Now do the instance initialize method */
+ String* docs = docstring(n, AUTODOC_CTOR);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+
+ current = CONSTRUCTOR_INITIALIZE;
+ Swig_name_register((const_String_or_char_ptr ) "construct", (const_String_or_char_ptr ) "new_%c");
+ Language::constructorHandler(n);
+
+ /* Restore original parameter list */
+ Delattr(n, "wrap:self");
+ Swig_restore(n);
+
+ /* Done */
+ Swig_name_unregister((const_String_or_char_ptr ) "construct");
+ current = NO_CPP;
+ klass->constructor_defined = 1;
+ return SWIG_OK;
+ }
+
+ virtual int copyconstructorHandler(Node *n) {
+ int use_director = Swig_directorclass(n);
+ if (use_director) {
+ set_director_ctor_code(n);
+ }
+
+ /* First wrap the allocate method */
+ current = CONSTRUCTOR_ALLOCATE;
+ Swig_name_register((const_String_or_char_ptr ) "construct", (const_String_or_char_ptr ) "%c_allocate");
+
+ return Language::copyconstructorHandler(n);
+ }
+
+
+ /* ---------------------------------------------------------------------
+ * destructorHandler()
+ * -------------------------------------------------------------------- */
+
+ virtual int destructorHandler(Node *n) {
+
+ /* Do no spit free function if user defined his own for this class */
+ Node *pn = Swig_methodclass(n);
+ String *freefunc = Getattr(pn, "feature:freefunc");
+ if (freefunc) return SWIG_OK;
+
+ current = DESTRUCTOR;
+ Language::destructorHandler(n);
+
+ freefunc = NewString("");
+ String *freebody = NewString("");
+ String *pname0 = Swig_cparm_name(0, 0);
+
+ Printv(freefunc, "free_", klass->mname, NIL);
+ Printv(freebody, "SWIGINTERN void\n", freefunc, "(", klass->type, " *", pname0, ") {\n", tab4, NIL);
+
+ /* Check to see if object tracking is activated for the class
+ that owns this destructor. */
+ if (GetFlag(pn, "feature:trackobjects")) {
+ Printf(freebody, "SWIG_RubyRemoveTracking(%s);\n", pname0);
+ Printv(freebody, tab4, NIL);
+ }
+
+ if (Extend) {
+ String *wrap = Getattr(n, "wrap:code");
+ if (wrap) {
+ Printv(f_wrappers, wrap, NIL);
+ }
+ /* Printv(freebody, Swig_name_destroy(name), "(", pname0, ")", NIL); */
+ Printv(freebody, Getattr(n, "wrap:action"), "\n", NIL);
+ } else {
+ String *action = Getattr(n, "wrap:action");
+ if (action) {
+ Printv(freebody, action, "\n", NIL);
+ } else {
+ /* In the case swig emits no destroy function. */
+ if (CPlusPlus)
+ Printf(freebody, "delete %s;\n", pname0);
+ else
+ Printf(freebody, "free((char*) %s);\n", pname0);
+ }
+ }
+
+ Printv(freebody, "}\n\n", NIL);
+
+ Printv(f_wrappers, freebody, NIL);
+
+ klass->destructor_defined = 1;
+ current = NO_CPP;
+ Delete(freefunc);
+ Delete(freebody);
+ Delete(pname0);
+ return SWIG_OK;
+ }
+
+ /* ---------------------------------------------------------------------
+ * membervariableHandler()
+ *
+ * This creates a pair of functions to set/get the variable of a member.
+ * -------------------------------------------------------------------- */
+
+ virtual int membervariableHandler(Node *n) {
+ String* docs = docstring(n, AUTODOC_GETTER);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+
+ if (is_assignable(n)) {
+ String* docs = docstring(n, AUTODOC_SETTER);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+ }
+
+ current = MEMBER_VAR;
+ Language::membervariableHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ *
+ * Wrap a static C++ function
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ String* docs = docstring(n, AUTODOC_STATICFUNC);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+
+ current = STATIC_FUNC;
+ Language::staticmemberfunctionHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * memberconstantHandler()
+ *
+ * Create a C++ constant
+ * --------------------------------------------------------------------- */
+
+ virtual int memberconstantHandler(Node *n) {
+ String* docs = docstring(n, AUTODOC_STATICFUNC);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+
+ current = CLASS_CONST;
+ Language::memberconstantHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ---------------------------------------------------------------------
+ * staticmembervariableHandler()
+ * --------------------------------------------------------------------- */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ String* docs = docstring(n, AUTODOC_GETTER);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+
+ if (is_assignable(n)) {
+ String* docs = docstring(n, AUTODOC_SETTER);
+ Printf(f_wrappers, "%s", docs);
+ Delete(docs);
+ }
+
+ current = STATIC_VAR;
+ Language::staticmembervariableHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* C++ director class generation */
+ virtual int classDirector(Node *n) {
+ return Language::classDirector(n);
+ }
+
+ virtual int classDirectorInit(Node *n) {
+ String *declaration;
+ declaration = Swig_director_declaration(n);
+ Printf(f_directors_h, "\n");
+ Printf(f_directors_h, "%s\n", declaration);
+ Printf(f_directors_h, "public:\n");
+ Delete(declaration);
+ return Language::classDirectorInit(n);
+ }
+
+ virtual int classDirectorEnd(Node *n) {
+ Printf(f_directors_h, "};\n\n");
+ return Language::classDirectorEnd(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorConstructor()
+ * ------------------------------------------------------------ */
+
+ virtual int classDirectorConstructor(Node *n) {
+ Node *parent = Getattr(n, "parentNode");
+ String *sub = NewString("");
+ String *decl = Getattr(n, "decl");
+ String *supername = Swig_class_name(parent);
+ String *classname = NewString("");
+ Printf(classname, "SwigDirector_%s", supername);
+
+ /* insert self parameter */
+ Parm *p;
+ ParmList *superparms = Getattr(n, "parms");
+ ParmList *parms = CopyParmList(superparms);
+ String *type = NewString("VALUE");
+ p = NewParm(type, NewString("self"));
+ set_nextSibling(p, parms);
+ parms = p;
+
+ if (!Getattr(n, "defaultargs")) {
+ /* constructor */
+ {
+ Wrapper *w = NewWrapper();
+ String *call;
+ String *basetype = Getattr(parent, "classtype");
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+ call = Swig_csuperclass_call(0, basetype, superparms);
+ Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
+ Delete(target);
+ Wrapper_print(w, f_directors);
+ Delete(call);
+ DelWrapper(w);
+ }
+
+ /* constructor header */
+ {
+ String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+ Printf(f_directors_h, " %s;\n", target);
+ Delete(target);
+ }
+ }
+
+ Delete(sub);
+ Delete(classname);
+ Delete(supername);
+ Delete(parms);
+ return Language::classDirectorConstructor(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorDefaultConstructor()
+ * ------------------------------------------------------------ */
+
+ virtual int classDirectorDefaultConstructor(Node *n) {
+ String *classname;
+ Wrapper *w;
+ classname = Swig_class_name(n);
+ w = NewWrapper();
+ Printf(w->def, "SwigDirector_%s::SwigDirector_%s(VALUE self) : Swig::Director(self) { }", classname, classname);
+ Wrapper_print(w, f_directors);
+ DelWrapper(w);
+ Printf(f_directors_h, " SwigDirector_%s(VALUE self);\n", classname);
+ Delete(classname);
+ return Language::classDirectorDefaultConstructor(n);
+ }
+
+ /* ---------------------------------------------------------------
+ * exceptionSafeMethodCall()
+ *
+ * Emit a virtual director method to pass a method call on to the
+ * underlying Ruby instance.
+ *
+ * --------------------------------------------------------------- */
+
+ void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args, bool initstack) {
+ Wrapper *body = NewWrapper();
+ Wrapper *rescue = NewWrapper();
+
+ String *methodName = Getattr(n, "sym:name");
+
+ String *bodyName = NewStringf("%s_%s_body", className, methodName);
+ String *rescueName = NewStringf("%s_%s_rescue", className, methodName);
+ String *depthCountName = NewStringf("%s_%s_call_depth", className, methodName);
+
+ // Check for an exception typemap of some kind
+ String *tm = Swig_typemap_lookup("director:except", n, "result", 0);
+ if (!tm) {
+ tm = Getattr(n, "feature:director:except");
+ }
+
+ if ((tm != 0) && (Len(tm) > 0) && (Strcmp(tm, "1") != 0)) {
+ // Declare a global to hold the depth count
+ if (!Getattr(n, "sym:nextSibling")) {
+ Printf(body->def, "static int %s = 0;\n", depthCountName);
+
+ // Function body
+ Printf(body->def, "VALUE %s(VALUE data) {\n", bodyName);
+ Wrapper_add_localv(body, "args", "Swig::body_args *", "args", "= reinterpret_cast<Swig::body_args *>(data)", NIL);
+ Wrapper_add_localv(body, "result", "VALUE", "result", "= Qnil", NIL);
+ Printf(body->code, "%s++;\n", depthCountName);
+ Printv(body->code, "result = rb_funcall2(args->recv, args->id, args->argc, args->argv);\n", NIL);
+ Printf(body->code, "%s--;\n", depthCountName);
+ Printv(body->code, "return result;\n", NIL);
+ Printv(body->code, "}", NIL);
+
+ // Exception handler
+ Printf(rescue->def, "VALUE %s(VALUE args, VALUE error) {\n", rescueName);
+ Replaceall(tm, "$error", "error");
+ Printf(rescue->code, "%s--;\n", depthCountName);
+ Printf(rescue->code, "if (%s == 0) ", depthCountName);
+ Printv(rescue->code, Str(tm), "\n", NIL);
+ Printv(rescue->code, "rb_exc_raise(error);\n", NIL);
+ Printv(rescue->code, "}", NIL);
+ }
+
+ // Main code
+ Wrapper_add_localv(w, "args", "Swig::body_args", "args", NIL);
+ Wrapper_add_localv(w, "status", "int", "status", NIL);
+ Printv(w->code, "args.recv = swig_get_self();\n", NIL);
+ Printf(w->code, "args.id = rb_intern(\"%s\");\n", methodName);
+ Printf(w->code, "args.argc = %d;\n", argc);
+ if (argc > 0) {
+ Printf(w->code, "args.argv = new VALUE[%d];\n", argc);
+ for (int i = 0; i < argc; i++) {
+ Printf(w->code, "args.argv[%d] = obj%d;\n", i, i);
+ }
+ } else {
+ Printv(w->code, "args.argv = 0;\n", NIL);
+ }
+ Printf(w->code, "result = rb_protect(PROTECTFUNC(%s), reinterpret_cast<VALUE>(&args), &status);\n", bodyName);
+ if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n");
+ Printf(w->code, "if (status) {\n");
+ Printf(w->code, "VALUE lastErr = rb_gv_get(\"$!\");\n");
+ Printf(w->code, "%s(reinterpret_cast<VALUE>(&args), lastErr);\n", rescueName);
+ Printf(w->code, "}\n");
+ if (argc > 0) {
+ Printv(w->code, "delete [] args.argv;\n", NIL);
+ }
+ // Dump wrapper code
+ Wrapper_print(body, f_directors_helpers);
+ Wrapper_print(rescue, f_directors_helpers);
+ } else {
+ if (argc > 0) {
+ Printf(w->code, "result = rb_funcall(swig_get_self(), rb_intern(\"%s\"), %d%s);\n", methodName, argc, args);
+ } else {
+ Printf(w->code, "result = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, NULL);\n", methodName);
+ }
+ if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n");
+ }
+
+ // Clean up
+ Delete(bodyName);
+ Delete(rescueName);
+ Delete(depthCountName);
+ DelWrapper(body);
+ DelWrapper(rescue);
+ }
+
+ virtual int classDirectorMethod(Node *n, Node *parent, String *super) {
+ int is_void = 0;
+ int is_pointer = 0;
+ String *decl;
+ String *type;
+ String *name;
+ String *classname;
+ String *c_classname = Getattr(parent, "name");
+ String *declaration;
+ ParmList *l;
+ Wrapper *w;
+ String *tm;
+ String *wrap_args = NewString("");
+ String *return_type;
+ Parm *p;
+ String *value = Getattr(n, "value");
+ String *storage = Getattr(n, "storage");
+ bool pure_virtual = false;
+ int status = SWIG_OK;
+ int idx;
+ bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
+ bool asvoid = checkAttribute( n, "feature:numoutputs", "0") ? true : false;
+ bool initstack = checkAttribute( n, "feature:initstack", "1") ? true : false;
+
+ if (Cmp(storage, "virtual") == 0) {
+ if (Cmp(value, "0") == 0) {
+ pure_virtual = true;
+ }
+ }
+ String *overnametmp = NewString(Getattr(n, "sym:name"));
+ if (Getattr(n, "sym:overloaded")) {
+ Printf(overnametmp, "::%s", Getattr(n, "sym:overname"));
+ }
+
+ classname = Getattr(parent, "sym:name");
+ type = Getattr(n, "type");
+ name = Getattr(n, "name");
+
+ w = NewWrapper();
+ declaration = NewString("");
+
+ /* determine if the method returns a pointer */
+ decl = Getattr(n, "decl");
+ is_pointer = SwigType_ispointer_return(decl);
+ is_void = (!Cmp(type, "void") && !is_pointer);
+
+ /* form complete return type */
+ return_type = Copy(type);
+ {
+ SwigType *t = Copy(decl);
+ SwigType *f = 0;
+ f = SwigType_pop_function(t);
+ SwigType_push(return_type, t);
+ Delete(f);
+ Delete(t);
+ }
+
+ /* virtual method definition */
+ l = Getattr(n, "parms");
+ String *target;
+ String *pclassname = NewStringf("SwigDirector_%s", classname);
+ String *qualified_name = NewStringf("%s::%s", pclassname, name);
+ SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type;
+ target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+ Printf(w->def, "%s", target);
+ Delete(qualified_name);
+ Delete(target);
+ /* header declaration */
+ target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+ Printf(declaration, " virtual %s", target);
+ Delete(target);
+
+ // Get any exception classes in the throws typemap
+ ParmList *throw_parm_list = 0;
+
+ if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
+ Parm *p;
+ int gencomma = 0;
+
+ Append(w->def, " throw(");
+ Append(declaration, " throw(");
+
+ if (throw_parm_list)
+ Swig_typemap_attach_parms("throws", throw_parm_list, 0);
+ for (p = throw_parm_list; p; p = nextSibling(p)) {
+ if ((tm = Getattr(p, "tmap:throws"))) {
+ if (gencomma++) {
+ Append(w->def, ", ");
+ Append(declaration, ", ");
+ }
+
+ Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0));
+ Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0));
+ }
+ }
+
+ Append(w->def, ")");
+ Append(declaration, ")");
+ }
+
+ Append(w->def, " {");
+ Append(declaration, ";\n");
+
+ if (initstack && !(ignored_method && !pure_virtual)) {
+ Append(w->def, "\nSWIG_INIT_STACK;\n");
+ }
+
+ /* declare method return value
+ * if the return value is a reference or const reference, a specialized typemap must
+ * handle it, including declaration of c_result ($result).
+ */
+ if (!is_void) {
+ if (!(ignored_method && !pure_virtual)) {
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL);
+ }
+ }
+
+ if (ignored_method) {
+ if (!pure_virtual) {
+ if (!is_void)
+ Printf(w->code, "return ");
+ String *super_call = Swig_method_call(super, l);
+ Printf(w->code, "%s;\n", super_call);
+ Delete(super_call);
+ } else {
+ Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
+ SwigType_namestr(name));
+ }
+ } else {
+ /* attach typemaps to arguments (C/C++ -> Ruby) */
+ String *arglist = NewString("");
+
+ /**
+ * For each parameter to the C++ member function, copy the parameter name
+ * to its "lname"; this ensures that Swig_typemap_attach_parms() will do
+ * the right thing when it sees strings like "$1" in your "directorin" typemaps.
+ * Not sure if it's OK to leave it like this, but seems OK so far.
+ */
+ typemap_copy_pname_to_lname(l);
+
+ Swig_typemap_attach_parms("in", l, 0);
+ Swig_typemap_attach_parms("directorin", l, 0);
+ Swig_typemap_attach_parms("directorargout", l, w);
+
+ char source[256];
+
+ int outputs = 0;
+ if (!is_void && !asvoid)
+ outputs++;
+
+ /* build argument list and type conversion string */
+ idx = 0; p = l;
+ while ( p ) {
+
+ if (Getattr(p, "tmap:ignore")) {
+ p = Getattr(p, "tmap:ignore:next");
+ continue;
+ }
+
+ if (Getattr(p, "tmap:directorargout") != 0)
+ outputs++;
+
+ if ( checkAttribute( p, "tmap:in:numinputs", "0") )
+ {
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ }
+
+ String *parameterName = Getattr(p, "name");
+ String *parameterType = Getattr(p, "type");
+
+ Putc(',', arglist);
+ if ((tm = Getattr(p, "tmap:directorin")) != 0) {
+ sprintf(source, "obj%d", idx++);
+ Replaceall(tm, "$input", source);
+ Replaceall(tm, "$owner", "0");
+ Printv(wrap_args, tm, "\n", NIL);
+ Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
+ Printv(arglist, source, NIL);
+ p = Getattr(p, "tmap:directorin:next");
+ continue;
+ } else if (Cmp(parameterType, "void")) {
+ /**
+ * Special handling for pointers to other C++ director classes.
+ * Ideally this would be left to a typemap, but there is currently no
+ * way to selectively apply the dynamic_cast<> to classes that have
+ * directors. In other words, the type "SwigDirector_$1_lname" only exists
+ * for classes with directors. We avoid the problem here by checking
+ * module.wrap::directormap, but it's not clear how to get a typemap to
+ * do something similar. Perhaps a new default typemap (in addition
+ * to SWIGTYPE) called DIRECTORTYPE?
+ */
+ if (SwigType_ispointer(parameterType) || SwigType_isreference(parameterType)) {
+ Node *modname = Getattr(parent, "module");
+ Node *target = Swig_directormap(modname, parameterType);
+ sprintf(source, "obj%d", idx++);
+ String *nonconst = 0;
+ /* strip pointer/reference --- should move to Swig/stype.c */
+ String *nptype = NewString(Char(parameterType) + 2);
+ /* name as pointer */
+ String *ppname = Copy(parameterName);
+ if (SwigType_isreference(parameterType)) {
+ Insert(ppname, 0, "&");
+ }
+ /* if necessary, cast away const since Ruby doesn't support it! */
+ if (SwigType_isconst(nptype)) {
+ nonconst = NewStringf("nc_tmp_%s", parameterName);
+ String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(parameterType, 0), ppname);
+ Wrapper_add_localv(w, nonconst, SwigType_lstr(parameterType, 0), nonconst, nonconst_i, NIL);
+ Delete(nonconst_i);
+ Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
+ "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(parameterType, parameterName),
+ SwigType_namestr(c_classname), SwigType_namestr(name));
+ } else {
+ nonconst = Copy(ppname);
+ }
+ Delete(nptype);
+ Delete(ppname);
+ String *mangle = SwigType_manglestr(parameterType);
+ if (target) {
+ String *director = NewStringf("director_%s", mangle);
+ Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
+ Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
+ Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
+ Printf(wrap_args, "if (!%s) {\n", director);
+ Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
+ Printf(wrap_args, "} else {\n");
+ Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
+ Printf(wrap_args, "}\n");
+ Delete(director);
+ Printv(arglist, source, NIL);
+ } else {
+ Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
+ Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
+ //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
+ // source, nonconst, base);
+ Printv(arglist, source, NIL);
+ }
+ Delete(mangle);
+ Delete(nonconst);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(parameterType, 0),
+ SwigType_namestr(c_classname), SwigType_namestr(name));
+ status = SWIG_NOWRAP;
+ break;
+ }
+ }
+ p = nextSibling(p);
+ }
+
+ /* declare Ruby return value */
+ Wrapper_add_local(w, "result", "VALUE result");
+
+ /* wrap complex arguments to VALUEs */
+ Printv(w->code, wrap_args, NIL);
+
+ /* pass the method call on to the Ruby object */
+ exceptionSafeMethodCall(classname, n, w, idx, arglist, initstack);
+
+ /*
+ * Ruby method may return a simple object, or an Array of objects.
+ * For in/out arguments, we have to extract the appropriate VALUEs from the Array,
+ * then marshal everything back to C/C++ (return value and output arguments).
+ */
+
+ /* Marshal return value and other outputs (if any) from VALUE to C/C++ type */
+
+ String *cleanup = NewString("");
+ String *outarg = NewString("");
+
+ if (outputs > 1) {
+ Wrapper_add_local(w, "output", "VALUE output");
+ Printf(w->code, "if (TYPE(result) != T_ARRAY) {\n");
+ Printf(w->code, "Ruby_DirectorTypeMismatchException(\"Ruby method failed to return an array.\");\n");
+ Printf(w->code, "}\n");
+ }
+
+ idx = 0;
+
+ /* Marshal return value */
+ if (!is_void) {
+ /* This seems really silly. The node's type excludes qualifier/pointer/reference markers,
+ * which have to be retrieved from the decl field to construct return_type. But the typemap
+ * lookup routine uses the node's type, so we have to swap in and out the correct type.
+ * It's not just me, similar silliness also occurs in Language::cDeclaration().
+ */
+ Setattr(n, "type", return_type);
+ tm = Swig_typemap_lookup("directorout", n, "result", w);
+ Setattr(n, "type", type);
+ if (tm != 0) {
+ if (outputs > 1 && !asvoid ) {
+ Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
+ Replaceall(tm, "$input", "output");
+ } else {
+ Replaceall(tm, "$input", "result");
+ }
+ /* TODO check this */
+ if (Getattr(n, "wrap:disown")) {
+ Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm, "$disown", "0");
+ }
+ Replaceall(tm, "$result", "c_result");
+ Printv(w->code, tm, "\n", NIL);
+ } else {
+ Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0),
+ SwigType_namestr(c_classname), SwigType_namestr(name));
+ status = SWIG_ERROR;
+ }
+ }
+
+ /* Marshal outputs */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
+ if (outputs > 1) {
+ Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
+ Replaceall(tm, "$input", "output");
+ } else {
+ Replaceall(tm, "$input", "result");
+ }
+ Replaceall(tm, "$result", Getattr(p, "name"));
+ Printv(w->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:directorargout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ Delete(arglist);
+ Delete(cleanup);
+ Delete(outarg);
+ }
+
+ /* any existing helper functions to handle this? */
+ if (!is_void) {
+ if (!(ignored_method && !pure_virtual)) {
+ String *rettype = SwigType_str(return_type, 0);
+ if (!SwigType_isreference(return_type)) {
+ Printf(w->code, "return (%s) c_result;\n", rettype);
+ } else {
+ Printf(w->code, "return (%s) *c_result;\n", rettype);
+ }
+ Delete(rettype);
+ }
+ }
+
+ Printf(w->code, "}\n");
+
+ // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
+ String *inline_extra_method = NewString("");
+ if (dirprot_mode() && !is_public(n) && !pure_virtual) {
+ Printv(inline_extra_method, declaration, NIL);
+ String *extra_method_name = NewStringf("%sSwigPublic", name);
+ Replaceall(inline_extra_method, name, extra_method_name);
+ Replaceall(inline_extra_method, ";\n", " {\n ");
+ if (!is_void)
+ Printf(inline_extra_method, "return ");
+ String *methodcall = Swig_method_call(super, l);
+ Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
+ Delete(methodcall);
+ Delete(extra_method_name);
+ }
+
+ /* emit the director method */
+ if (status == SWIG_OK) {
+ if (!Getattr(n, "defaultargs")) {
+ Wrapper_print(w, f_directors);
+ Printv(f_directors_h, declaration, NIL);
+ Printv(f_directors_h, inline_extra_method, NIL);
+ }
+ }
+
+ /* clean up */
+ Delete(wrap_args);
+ Delete(return_type);
+ Delete(pclassname);
+ DelWrapper(w);
+ return status;
+ }
+
+ virtual int classDirectorConstructors(Node *n) {
+ return Language::classDirectorConstructors(n);
+ }
+
+ virtual int classDirectorMethods(Node *n) {
+ return Language::classDirectorMethods(n);
+ }
+
+ virtual int classDirectorDisown(Node *n) {
+ return Language::classDirectorDisown(n);
+ }
+
+ void typemap_copy_pname_to_lname(ParmList *parms) {
+ Parm *p;
+ String *pname;
+ String *lname;
+
+ p = parms;
+ while (p) {
+ pname = Getattr(p, "name");
+ lname = Copy(pname);
+ Setattr(p, "lname", lname);
+ p = nextSibling(p);
+ }
+ }
+
+ String *runtimeCode() {
+ String *s = NewString("");
+ String *shead = Swig_include_sys("rubyhead.swg");
+ if (!shead) {
+ Printf(stderr, "*** Unable to open 'rubyhead.swg'\n");
+ } else {
+ Append(s, shead);
+ Delete(shead);
+ }
+ String *serrors = Swig_include_sys("rubyerrors.swg");
+ if (!serrors) {
+ Printf(stderr, "*** Unable to open 'rubyerrors.swg'\n");
+ } else {
+ Append(s, serrors);
+ Delete(serrors);
+ }
+ String *strack = Swig_include_sys("rubytracking.swg");
+ if (!strack) {
+ Printf(stderr, "*** Unable to open 'rubytracking.swg'\n");
+ } else {
+ Append(s, strack);
+ Delete(strack);
+ }
+ String *sapi = Swig_include_sys("rubyapi.swg");
+ if (!sapi) {
+ Printf(stderr, "*** Unable to open 'rubyapi.swg'\n");
+ } else {
+ Append(s, sapi);
+ Delete(sapi);
+ }
+ String *srun = Swig_include_sys("rubyrun.swg");
+ if (!srun) {
+ Printf(stderr, "*** Unable to open 'rubyrun.swg'\n");
+ } else {
+ Append(s, srun);
+ Delete(srun);
+ }
+ return s;
+ }
+
+ String *defaultExternalRuntimeFilename() {
+ return NewString("swigrubyrun.h");
+ }
+}; /* class RUBY */
+
+/* -----------------------------------------------------------------------------
+ * swig_ruby() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_ruby() {
+ return new RUBY();
+}
+extern "C" Language *swig_ruby(void) {
+ return new_swig_ruby();
+}
+
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
diff --git a/Source/Modules/s-exp.cxx b/Source/Modules/s-exp.cxx
new file mode 100644
index 0000000..c87d18c
--- /dev/null
+++ b/Source/Modules/s-exp.cxx
@@ -0,0 +1,394 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * s-exp.cxx
+ *
+ * A parse tree represented as Lisp s-expressions.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_s_exp_cxx[] = "$Id: s-exp.cxx 11133 2009-02-20 07:52:24Z wsfulton $";
+
+#include "swigmod.h"
+#include "dohint.h"
+
+static const char *usage = "\
+S-Exp Options (available with -sexp)\n\
+ -typemaplang <lang> - Typemap language\n\n";
+
+//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[]) {
+ // Add a symbol to the parser for conditional compilation
+ Preprocessor_define("SWIGSEXP 1", 0);
+
+ 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, stdout);
+ }
+ }
+ }
+
+ 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");
+ Replaceall(outfile, "_wrap.c", ".lisp");
+ out = NewFile(outfile, "w", SWIG_output_files());
+ if (!out) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+ String *f_sink = NewString("");
+ Swig_register_filebyname("header", f_sink);
+ Swig_register_filebyname("wrapper", f_sink);
+ Swig_register_filebyname("begin", f_sink);
+ Swig_register_filebyname("runtime", f_sink);
+ Swig_register_filebyname("init", f_sink);
+
+ Swig_banner_target_lang(out, ";;;");
+
+ Language::top(n);
+ Printf(out, "\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 neednewline = false) {
+ hanging_parens++;
+ if (neednewline)
+ 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[32];
+ sprintf(address, "%p%c", 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)) {
+ Iterator k;
+ open_paren(NIL);
+ for (k = First(obj); k.key; k = Next(k)) {
+ if (!internal_key_p(k.key)) {
+ DOH *value = Getattr(obj, k.key);
+ Sexp_print_as_keyword(k.key);
+ Sexp_print_value_of_key(value, k.key);
+ 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)) {
+ Iterator k;
+ open_paren(NIL);
+ for (k = First(obj); k.key; k = Next(k)) {
+ if (!internal_key_p(k.key)) {
+ DOH *value = Getattr(obj, k.key);
+ flush_parens();
+ open_paren(NIL);
+ Sexp_print_doh(k.key);
+ Printf(out, " . ");
+ Sexp_print_value_of_key(value, k.key);
+ close_paren();
+ }
+ }
+ close_paren();
+ } else if (strcmp(ObjType(obj)->objname, "List") == 0) {
+ int i;
+ open_paren(NIL);
+ for (i = 0; i < Len(obj); i++) {
+ DOH *item = Getitem(obj, i);
+ Sexp_print_doh(item);
+ }
+ close_paren();
+ } else {
+ // What is it?
+ Printf(out, "#<DOH %s %x>", ObjType(obj)->objname, 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 */
+ Iterator k;
+ bool first;
+ for (k = First(obj), first = true; k.key; k = Next(k), first = false) {
+ if (!internal_key_p(k.key)) {
+ DOH *value = Getattr(obj, k.key);
+ flush_parens();
+ if (!first) {
+ Printf(out, " ");
+ }
+ Sexp_print_as_keyword(k.key);
+ /* Print value */
+ Sexp_print_value_of_key(value, k.key);
+ }
+ }
+ }
+
+ 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);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+};
+
+
+static Language *new_swig_sexp() {
+ return new Sexp();
+}
+extern "C" Language *swig_sexp(void) {
+ return new_swig_sexp();
+}
diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx
new file mode 100644
index 0000000..aed915d
--- /dev/null
+++ b/Source/Modules/swigmain.cxx
@@ -0,0 +1,202 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * Simplified Wrapper and Interface Generator (SWIG)
+ *
+ * swigmain.cxx
+ *
+ * This file is the main entry point to SWIG. It collects the command
+ * line options, registers built-in language modules, and instantiates
+ * a module for code generation. If adding new language modules
+ * to SWIG, you would modify this file.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_swigmain_cxx[] = "$Id: swigmain.cxx 10969 2008-12-06 23:15:20Z wsfulton $";
+
+#include "swigmod.h"
+#include <ctype.h>
+
+/* Module factories. These functions are used to instantiate
+ the built-in language modules. If adding a new language
+ module to SWIG, place a similar function here. Make sure
+ the function has "C" linkage. This is required so that modules
+ can be dynamically loaded in future versions. */
+
+extern "C" {
+ Language *swig_tcl(void);
+ Language *swig_python(void);
+ Language *swig_perl5(void);
+ Language *swig_ruby(void);
+ Language *swig_guile(void);
+ Language *swig_modula3(void);
+ Language *swig_mzscheme(void);
+ Language *swig_java(void);
+ Language *swig_php(void);
+ Language *swig_php4(void);
+ Language *swig_ocaml(void);
+ Language *swig_octave(void);
+ Language *swig_pike(void);
+ Language *swig_sexp(void);
+ Language *swig_xml(void);
+ Language *swig_chicken(void);
+ Language *swig_csharp(void);
+ Language *swig_allegrocl(void);
+ Language *swig_lua(void);
+ Language *swig_clisp(void);
+ Language *swig_cffi(void);
+ Language *swig_uffi(void);
+ Language *swig_r(void);
+}
+
+struct swig_module {
+ const char *name;
+ ModuleFactory fac;
+ const char *help;
+};
+
+/* Association of command line options to language modules.
+ Place an entry for new language modules here, keeping the
+ list sorted alphabetically. */
+
+static swig_module modules[] = {
+ {"-allegrocl", swig_allegrocl, "ALLEGROCL"},
+ {"-chicken", swig_chicken, "CHICKEN"},
+ {"-clisp", swig_clisp, "CLISP"},
+ {"-cffi", swig_cffi, "CFFI"},
+ {"-csharp", swig_csharp, "C#"},
+ {"-guile", swig_guile, "Guile"},
+ {"-java", swig_java, "Java"},
+ {"-lua", swig_lua, "Lua"},
+ {"-modula3", swig_modula3, "Modula 3"},
+ {"-mzscheme", swig_mzscheme, "Mzscheme"},
+ {"-ocaml", swig_ocaml, "Ocaml"},
+ {"-octave", swig_octave, "Octave"},
+ {"-perl", swig_perl5, "Perl"},
+ {"-perl5", swig_perl5, 0},
+ {"-php", swig_php, "PHP"},
+ {"-php4", swig_php4, 0},
+ {"-php5", swig_php, 0},
+ {"-pike", swig_pike, "Pike"},
+ {"-python", swig_python, "Python"},
+ {"-r", swig_r, "R (aka GNU S)"},
+ {"-ruby", swig_ruby, "Ruby"},
+ {"-sexp", swig_sexp, "Lisp S-Expressions"},
+ {"-tcl", swig_tcl, "Tcl"},
+ {"-tcl8", swig_tcl, 0},
+ {"-uffi", swig_uffi, "Common Lisp / UFFI"},
+ {"-xml", swig_xml, "XML"},
+ {NULL, NULL, NULL}
+};
+
+#ifdef MACSWIG
+#include <console.h>
+#include <SIOUX.h>
+#endif
+
+#ifndef SWIG_LANG
+#define SWIG_LANG "-python"
+#endif
+
+//-----------------------------------------------------------------
+// main()
+//
+// Main program. Initializes the files and starts the parser.
+//-----------------------------------------------------------------
+
+void SWIG_merge_envopt(const char *env, int oargc, char *oargv[], int *nargc, char ***nargv) {
+ if (!env) {
+ *nargc = oargc;
+ *nargv = oargv;
+ return;
+ }
+
+ int argc = 1;
+ int arge = oargc + 1024;
+ char **argv = (char **) malloc(sizeof(char *) * (arge));
+ char *buffer = (char *) malloc(2048);
+ char *b = buffer;
+ char *be = b + 1023;
+ const char *c = env;
+ while ((b != be) && *c && (argc < arge)) {
+ while (isspace(*c) && *c)
+ ++c;
+ if (*c) {
+ argv[argc] = b;
+ ++argc;
+ }
+ while ((b != be) && *c && !isspace(*c)) {
+ *(b++) = *(c++);
+ }
+ *b++ = 0;
+ }
+
+ argv[0] = oargv[0];
+ for (int i = 1; (i < oargc) && (argc < arge); ++i, ++argc) {
+ argv[argc] = oargv[i];
+ }
+
+ *nargc = argc;
+ *nargv = argv;
+}
+
+int main(int margc, char **margv) {
+ int i;
+ Language *dl = 0;
+ ModuleFactory fac = 0;
+
+ int argc;
+ char **argv;
+
+ SWIG_merge_envopt(getenv("SWIG_FEATURES"), margc, margv, &argc, &argv);
+
+#ifdef MACSWIG
+ SIOUXSettings.asktosaveonclose = false;
+ argc = ccommand(&argv);
+#endif
+
+ /* Register built-in modules */
+ for (i = 0; modules[i].name; i++) {
+ Swig_register_module(modules[i].name, modules[i].fac);
+ }
+
+ Swig_init_args(argc, argv);
+
+ /* Get options */
+ for (i = 1; i < argc; i++) {
+ if (argv[i]) {
+ fac = Swig_find_module(argv[i]);
+ if (fac) {
+ dl = (fac) ();
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nolang") == 0) {
+ dl = new Language;
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-dnone") == 0) ||
+ (strcmp(argv[i], "-dhtml") == 0) ||
+ (strcmp(argv[i], "-dlatex") == 0) || (strcmp(argv[i], "-dascii") == 0) || (strcmp(argv[i], "-stat") == 0)) {
+ Printf(stderr, "swig: Warning. %s option deprecated.\n", argv[i]);
+ Swig_mark_arg(i);
+ } else if ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) {
+ if (strcmp(argv[i], "--help") == 0)
+ strcpy(argv[i], "-help");
+ Printf(stdout, "Target Language Options\n");
+ for (int j = 0; modules[j].name; j++) {
+ if (modules[j].help) {
+ Printf(stdout, " %-15s - Generate %s wrappers\n", modules[j].name, modules[j].help);
+ }
+ }
+ // Swig_mark_arg not called as the general -help options also need to be displayed later on
+ }
+ }
+ }
+ if (!dl) {
+ fac = Swig_find_module(SWIG_LANG);
+ if (fac) {
+ dl = (fac) ();
+ }
+ }
+ int res = SWIG_main(argc, argv, dl);
+ delete dl;
+ return res;
+}
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
new file mode 100644
index 0000000..dbb62b2
--- /dev/null
+++ b/Source/Modules/swigmod.h
@@ -0,0 +1,391 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * swigmod.h
+ *
+ * Main header file for SWIG modules.
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: swigmod.h 11470 2009-07-29 20:50:39Z wsfulton $ */
+
+#ifndef SWIG_SWIGMOD_H_
+#define SWIG_SWIGMOD_H_
+
+#include "swig.h"
+#include "preprocessor.h"
+#include "swigwarn.h"
+
+#if !defined(HAVE_BOOL)
+typedef int bool;
+#define true ((bool)1)
+#define false ((bool)0)
+#endif
+
+#define NOT_VIRTUAL 0
+#define PLAIN_VIRTUAL 1
+#define PURE_VIRTUAL 2
+
+extern String *input_file;
+extern int line_number;
+extern int start_line;
+extern int CPlusPlus; // C++ mode
+extern int Extend; // Extend mode
+extern int Verbose;
+extern int IsVirtual;
+extern int ImportMode;
+extern int NoExcept; // -no_except option
+extern int Abstract; // abstract base class
+extern int SmartPointer; // smart pointer methods being emitted
+extern int SwigRuntime;
+
+/* Overload "argc" and "argv" */
+extern String *argv_template_string;
+extern String *argc_template_string;
+
+/* Miscellaneous stuff */
+
+#define tab2 " "
+#define tab4 " "
+#define tab8 " "
+
+class Dispatcher {
+public:
+
+ Dispatcher ():cplus_mode(PUBLIC) {
+ }
+ virtual ~ Dispatcher () {
+ }
+
+ 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 enumforwardDeclaration(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);
+
+ enum AccessMode { PUBLIC, PRIVATE, PROTECTED };
+
+protected:
+ AccessMode cplus_mode;
+};
+
+/* ----------------------------------------------------------------------------
+ * 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 enumforwardDeclaration(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);
+
+ /* C++ director class generation */
+ virtual int classDirector(Node *n);
+ virtual int classDirectorInit(Node *n);
+ virtual int classDirectorEnd(Node *n);
+ virtual int unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase = 0);
+ virtual int classDirectorConstructor(Node *n);
+ virtual int classDirectorDefaultConstructor(Node *n);
+ virtual int classDirectorMethod(Node *n, Node *parent, String *super);
+ virtual int classDirectorConstructors(Node *n);
+ virtual int classDirectorDestructor(Node *n);
+ virtual int classDirectorMethods(Node *n);
+ virtual int classDirectorDisown(Node *n);
+
+ /* Miscellaneous */
+ virtual int validIdentifier(String *s); /* valid identifier? */
+ virtual int addSymbol(const String *s, const Node *n); /* Add symbol */
+ virtual Node *symbolLookup(String *s); /* Symbol lookup */
+ virtual Node *classLookup(SwigType *s); /* Class lookup */
+ virtual Node *enumLookup(SwigType *s); /* Enum lookup */
+ virtual int abstractClassTest(Node *n); /* Is class really abstract? */
+ virtual int is_assignable(Node *n); /* Is variable assignable? */
+ virtual String *runtimeCode(); /* returns the language specific runtime code */
+ virtual String *defaultExternalRuntimeFilename(); /* the default filename for the external runtime */
+ virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm); /* Language specific special variable substitutions for $typemap() */
+
+ /* Runtime is C++ based, so extern "C" header section */
+ void enable_cplus_runtime_mode();
+
+ /* Returns the cplus_runtime mode */
+ int cplus_runtime_mode();
+
+ /* Allow director related code generation */
+ void allow_directors(int val = 1);
+
+ /* Return true if directors are enabled */
+ int directorsEnabled() const;
+
+ /* Allow director protected members related code generation */
+ void allow_dirprot(int val = 1);
+
+ /* Allow all protected members code generation (for directors) */
+ void allow_allprotected(int val = 0);
+
+ /* Returns the dirprot mode */
+ int dirprot_mode() const;
+
+ /* Check if the non public constructor is needed (for directors) */
+ int need_nonpublic_ctor(Node *n);
+
+ /* Check if the non public member is needed (for directors) */
+ int need_nonpublic_member(Node *n);
+
+ /* Set none comparison string */
+ void setSubclassInstanceCheck(String *s);
+
+ /* Set overload variable templates argc and argv */
+ void setOverloadResolutionTemplates(String *argc, String *argv);
+
+ /* Language instance is a singleton - get instance */
+ static Language* instance();
+
+protected:
+ /* Allow multiple-input typemaps */
+ void allow_multiple_input(int val = 1);
+
+ /* Allow overloaded functions */
+ void allow_overloading(int val = 1);
+
+ /* Wrapping class query */
+ int is_wrapping_class();
+
+ /* Return the node for the current class */
+ Node *getCurrentClass() const;
+
+ /* Return C++ mode */
+ int getCPlusMode() const;
+
+ /* Return the real name of the current class */
+ String *getClassName() const;
+
+ /* Return the classes hash */
+ Hash *getClassHash() const;
+
+ /* Return the current class prefix */
+ String *getClassPrefix() const;
+
+ /* Fully qualified type name to use */
+ String *getClassType() const;
+
+ /* Return true if the current method is part of a smart-pointer */
+ int is_smart_pointer() const;
+
+ /* Some language modules require additional wrappers for virtual methods not declared in sub-classes */
+ virtual bool extraDirectorProtectedCPPMethodsRequired() const;
+
+ /* Director subclass comparison test */
+ String *none_comparison;
+
+ /* Director constructor "template" code */
+ String *director_ctor_code;
+
+ /* Director 'protected' constructor "template" code */
+ String *director_prot_ctor_code;
+
+ /* Director allows multiple inheritance */
+ int director_multiple_inheritance;
+
+ /* Director language module */
+ int director_language;
+
+private:
+ Hash *symbols;
+ Hash *classtypes;
+ Hash *enumtypes;
+ int overloading;
+ int multiinput;
+ int cplus_runtime;
+ int directors;
+ static Language *this_;
+};
+
+int SWIG_main(int, char **, Language *);
+void emit_parameter_variables(ParmList *l, Wrapper *f);
+void emit_return_variable(Node *n, SwigType *rt, Wrapper *f);
+void SWIG_exit(int); /* use EXIT_{SUCCESS,FAILURE} */
+void SWIG_config_file(const_String_or_char_ptr );
+const String *SWIG_output_directory();
+void SWIG_config_cppext(const char *ext);
+
+/* get the list of generated files */
+List *SWIG_output_files();
+
+void SWIG_library_directory(const char *);
+int emit_num_arguments(ParmList *);
+int emit_num_required(ParmList *);
+int emit_isvarargs(ParmList *);
+void emit_attach_parmmaps(ParmList *, Wrapper *f);
+void emit_mark_varargs(ParmList *l);
+String *emit_action(Node *n);
+int emit_action_code(Node *n, String *wrappercode, String *action);
+void Swig_overload_check(Node *n);
+String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *);
+String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *);
+String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *);
+SwigType *cplus_value_type(SwigType *t);
+
+/* directors.cxx start */
+String *Swig_csuperclass_call(String *base, String *method, ParmList *l);
+String *Swig_class_declaration(Node *n, String *name);
+String *Swig_class_name(Node *n);
+String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms);
+String *Swig_method_decl(SwigType *rtype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values);
+String *Swig_director_declaration(Node *n);
+void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f);
+/* directors.cxx end */
+
+extern "C" {
+ void SWIG_typemap_lang(const char *);
+ typedef Language *(*ModuleFactory) (void);
+}
+
+void Swig_register_module(const char *name, ModuleFactory fac);
+ModuleFactory Swig_find_module(const char *name);
+
+/* Utilities */
+
+int is_public(Node *n);
+int is_private(Node *n);
+int is_protected(Node *n);
+int is_member_director(Node *parentnode, Node *member);
+int is_member_director(Node *member);
+int is_non_virtual_protected_access(Node *n); /* Check if the non-virtual protected members are required (for directors) */
+int use_naturalvar_mode(Node *n);
+
+void Wrapper_virtual_elimination_mode_set(int);
+void Wrapper_fast_dispatch_mode_set(int);
+void Wrapper_cast_dispatch_mode_set(int);
+void Wrapper_naturalvar_mode_set(int);
+
+
+void clean_overloaded(Node *n);
+
+/* Contracts */
+
+void Swig_contracts(Node *n);
+void Swig_contract_mode_set(int flag);
+int Swig_contract_mode_get();
+
+/* Browser */
+
+void Swig_browser(Node *n, int);
+void Swig_default_allocators(Node *n);
+void Swig_process_types(Node *n);
+
+
+#endif
diff --git a/Source/Modules/tcl8.cxx b/Source/Modules/tcl8.cxx
new file mode 100644
index 0000000..3ff69fe
--- /dev/null
+++ b/Source/Modules/tcl8.cxx
@@ -0,0 +1,1306 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * tcl8.cxx
+ *
+ * Tcl8 language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_tcl8_cxx[] = "$Id: tcl8.cxx 11518 2009-08-08 22:56:10Z wsfulton $";
+
+#include "swigmod.h"
+#include "cparse.h"
+static int treduce = SWIG_cparse_template_reduce(0);
+
+static const char *usage = (char *) "\
+Tcl 8 Options (available with -tcl)\n\
+ -itcl - Enable ITcl support\n\
+ -nosafe - Leave out SafeInit module function.\n\
+ -prefix <name> - Set a prefix <name> to be prepended to all names\n\
+ -namespace - Build module into a Tcl 8 namespace\n\
+ -pkgversion - Set package version\n\n";
+
+static String *cmd_tab = 0; /* Table of command names */
+static String *var_tab = 0; /* Table of global variables */
+static String *const_tab = 0; /* Constant table */
+static String *methods_tab = 0; /* Methods table */
+static String *attr_tab = 0; /* Attribute table */
+static String *prefix = 0;
+static String *module = 0;
+static int nspace = 0;
+static String *init_name = 0;
+static String *ns_name = 0;
+static int have_constructor;
+static String *constructor_name;
+static int have_destructor;
+static int have_base_classes;
+static String *destructor_action = 0;
+static String *version = (String *) "0.0";
+static String *class_name = 0;
+
+static int have_attributes;
+static int have_methods;
+static int nosafe = 0;
+
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+static File *f_begin = 0;
+static File *f_runtime = 0;
+
+
+// Itcl support
+static int itcl = 0;
+static File *f_shadow = 0;
+static File *f_shadow_stubs = 0;
+
+static String *constructor = 0;
+static String *destructor = 0;
+static String *base_classes = 0;
+static String *base_class_init = 0;
+static String *methods = 0;
+static String *imethods = 0;
+static String *attributes = 0;
+static String *attribute_traces = 0;
+static String *iattribute_traces = 0;
+
+
+
+class TCL8:public Language {
+public:
+
+ /* ------------------------------------------------------------
+ * TCL8::main()
+ * ------------------------------------------------------------ */
+
+ virtual void main(int argc, char *argv[]) {
+ int cppcast = 1;
+
+ SWIG_library_directory("tcl");
+
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-prefix") == 0) {
+ if (argv[i + 1]) {
+ prefix = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else
+ Swig_arg_error();
+ } else if (strcmp(argv[i], "-pkgversion") == 0) {
+ if (argv[i + 1]) {
+ version = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ }
+ } else if (strcmp(argv[i], "-namespace") == 0) {
+ nspace = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-itcl") == 0) {
+ itcl = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nosafe") == 0) {
+ nosafe = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-cppcast") == 0) {
+ cppcast = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nocppcast") == 0) {
+ cppcast = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-help") == 0) {
+ fputs(usage, stdout);
+ }
+ }
+ }
+
+ if (cppcast) {
+ Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
+ }
+
+ Preprocessor_define("SWIGTCL 1", 0);
+ // SWIGTCL8 is deprecated, and no longer documented.
+ Preprocessor_define("SWIGTCL8 1", 0);
+ SWIG_typemap_lang("tcl8");
+ SWIG_config_file("tcl8.swg");
+ allow_overloading();
+ }
+
+ /* ------------------------------------------------------------
+ * top()
+ * ------------------------------------------------------------ */
+
+ virtual int top(Node *n) {
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ 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("begin", f_begin);
+ 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_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGTCL\n");
+ Printf(f_runtime, "\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, "_");
+
+
+ /* If shadow classing is enabled, we're going to change the module name to "_module" */
+ if (itcl) {
+ String *filen;
+ filen = NewStringf("%s%s.itcl", Swig_file_dirname(outfile), module);
+
+ Insert(module, 0, "_");
+
+ if ((f_shadow = NewFile(filen, "w", SWIG_output_files())) == 0) {
+ FileErrorDisplay(filen);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_shadow_stubs = NewString("");
+
+ Swig_register_filebyname("shadow", f_shadow);
+ Swig_register_filebyname("itcl", f_shadow);
+
+ Swig_banner_target_lang(f_shadow, "#");
+
+ Printv(f_shadow, "\npackage require Itcl\n\n", NIL);
+ Delete(filen);
+ }
+
+ /* 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");
+
+ if (!nosafe) {
+ Printf(f_init, "SWIGEXPORT int %(title)s_SafeInit(Tcl_Interp *interp) {\n", module);
+ Printf(f_init, " return SWIG_init(interp);\n");
+ Printf(f_init, "}\n");
+ }
+
+ if (itcl) {
+ Printv(f_shadow, f_shadow_stubs, "\n", NIL);
+ Close(f_shadow);
+ Delete(f_shadow);
+ }
+
+ /* Close all of the files */
+ Dump(f_runtime, f_begin);
+ Printv(f_begin, f_header, f_wrappers, NIL);
+ Wrapper_pretty_print(f_init, f_begin);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+ 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();
+
+#ifdef SWIG_USE_RESULTOBJ
+ Wrapper_add_local(f, "resultobj", "Tcl_Obj *resultobj = NULL");
+#endif
+
+
+ String *wname = Swig_name_wrapper(iname);
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n, "wrap:name", wname);
+
+ Printv(f->def, "SWIGINTERN int\n ", wname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL);
+
+ // Emit all of the local variables for holding arguments.
+ emit_parameter_variables(parms, f);
+
+ /* Attach standard typemaps */
+ emit_attach_parmmaps(parms, f);
+ Setattr(n, "wrap:parms", parms);
+
+ /* Get number of require and total arguments */
+ num_arguments = emit_num_arguments(parms);
+ num_required = emit_num_required(parms);
+ varargs = emit_isvarargs(parms);
+
+ /* Unmarshal parameters */
+
+ for (i = 0, p = parms; i < num_arguments; i++) {
+ /* Skip ignored arguments */
+
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *ln = Getattr(p, "lname");
+
+ /* Produce string representations of the source and target arguments */
+ sprintf(source, "objv[%d]", i + 1);
+
+ if (i == num_required)
+ Putc('|', argstr);
+ if ((tm = Getattr(p, "tmap:in"))) {
+ String *parse = Getattr(p, "tmap:in:parse");
+ if (!parse) {
+ Replaceall(tm, "$target", ln);
+ Replaceall(tm, "$source", source);
+ Replaceall(tm, "$input", source);
+ Setattr(p, "emit:input", source);
+
+ if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
+ Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm, "$disown", "0");
+ }
+
+ Putc('o', argstr);
+ Printf(args, ",(void *)0");
+ if (i >= num_required) {
+ Printf(incode, "if (objc > %d) {\n", i + 1);
+ }
+ Printf(incode, "%s\n", tm);
+ if (i >= num_required) {
+ Printf(incode, "}\n");
+ }
+ } else {
+ Printf(argstr, "%s", parse);
+ Printf(args, ",&%s", ln);
+ if (Strcmp(parse, "p") == 0) {
+ SwigType *lt = SwigType_ltype(pt);
+ SwigType_remember(pt);
+ if (Cmp(lt, "p.void") == 0) {
+ Printf(args, ",(void *)0");
+ } else {
+ Printf(args, ",SWIGTYPE%s", SwigType_manglestr(pt));
+ }
+ Delete(lt);
+ }
+ }
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
+ }
+ p = nextSibling(p);
+ }
+
+ if (!varargs) {
+ Putc(':', argstr);
+ } else {
+ Putc(';', argstr);
+ /* If variable length arguments we need to emit the in typemap here */
+ if (p && (tm = Getattr(p, "tmap:in"))) {
+ sprintf(source, "objv[%d]", i + 1);
+ Printf(incode, "if (objc > %d) {\n", i);
+ Replaceall(tm, "$input", source);
+ Printv(incode, tm, "\n", NIL);
+ Printf(incode, "}\n");
+ }
+ }
+
+ Printf(argstr, "%s\"", usage_string(Char(iname), type, parms));
+
+ Printv(f->code, "if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) SWIG_fail;\n", NIL);
+
+ Printv(f->code, incode, NIL);
+
+ /* Insert constraint checking code */
+ for (p = parms; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (i = 0, p = parms; p; i++) {
+ if (!checkAttribute(p, "tmap:in:numinputs", "0")
+ && !Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) {
+ if (Len(tm) != 0) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Printv(cleanup, tm, "\n", NIL);
+ }
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ for (i = 0, p = parms; p; i++) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+#ifdef SWIG_USE_RESULTOBJ
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+#else
+ Replaceall(tm, "$target", "(Tcl_GetObjResult(interp))");
+ Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))");
+#endif
+ Replaceall(tm, "$arg", Getattr(p, "emit:input"));
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(outarg, tm, "\n", NIL);
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Now write code to make the function call */
+ String *actioncode = emit_action(n);
+
+ /* Need to redo all of this code (eventually) */
+
+ /* Return value if necessary */
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ Replaceall(tm, "$source", "result");
+#ifdef SWIG_USE_RESULTOBJ
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+#else
+ Replaceall(tm, "$target", "(Tcl_GetObjResult(interp))");
+ Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))");
+#endif
+ if (GetFlag(n, "feature:new")) {
+ Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
+ } else {
+ Replaceall(tm, "$owner", "0");
+ }
+ Printf(f->code, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), name);
+ }
+ emit_return_variable(n, type, f);
+
+ /* 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 (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+#ifdef SWIG_USE_RESULTOBJ
+ Printv(f->code, "if (resultobj) Tcl_SetObjResult(interp, resultobj);\n", NIL);
+#endif
+ 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, argv - 1);", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *df = NewWrapper();
+ String *dname = Swig_name_wrapper(iname);
+
+ Printv(df->def, "SWIGINTERN int\n", dname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL);
+ Printf(df->code, "Tcl_Obj *CONST *argv = objv+1;\n");
+ Printf(df->code, "int argc = objc-1;\n");
+ Printv(df->code, dispatch, "\n", NIL);
+ Printf(df->code, "Tcl_SetResult(interp,(char *) \"No matching function for overloaded '%s'\", TCL_STATIC);\n", iname);
+ Printf(df->code, "return TCL_ERROR;\n");
+ Printv(df->code, "}\n", NIL);
+ Wrapper_print(df, f_wrappers);
+ Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", dname, ", NULL},\n", NIL);
+ DelWrapper(df);
+ Delete(dispatch);
+ Delete(dname);
+ }
+ }
+
+ Delete(incode);
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(argstr);
+ Delete(args);
+ DelWrapper(f);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+
+ String *setname = 0;
+ String *setfname = 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 */
+ int addfail = 0;
+ getf = NewWrapper();
+ String *getname = Swig_name_get(iname);
+ String *getfname = Swig_name_wrapper(getname);
+ Setattr(n, "wrap:name", getfname);
+ Printv(getf->def, "SWIGINTERN const char *", getfname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2, int flags) {", NIL);
+ Wrapper_add_local(getf, "value", "Tcl_Obj *value = 0");
+ if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
+ Replaceall(tm, "$source", name);
+ Replaceall(tm, "$target", "value");
+ Replaceall(tm, "$result", "value");
+ /* Printf(getf->code, "%s\n",tm); */
+ addfail = emit_action_code(n, getf->code, 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");
+ if (addfail) {
+ Append(getf->code, "fail:\n");
+ Printf(getf->code, "return \"%s\";\n", iname);
+ }
+ Printf(getf->code, "}\n");
+ Wrapper_print(getf, f_wrappers);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read 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 (is_assignable(n)) {
+ setf = NewWrapper();
+ setname = Swig_name_set(iname);
+ setfname = Swig_name_wrapper(setname);
+ Setattr(n, "wrap:name", setfname);
+ if (setf) {
+ Printv(setf->def, "SWIGINTERN const char *", setfname,
+ "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2 SWIGUNUSED, 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("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) SWIG_fail;\n");
+ /* Printf(setf->code,"%s\n", tm); */
+ emit_action_code(n, setf->code, tm);
+ Printf(setf->code, "return NULL;\n");
+ Printf(setf->code, "fail:\n");
+ Printf(setf->code, "return \"%s\";\n", iname);
+ Printf(setf->code, "}\n");
+ Wrapper_print(setf, f_wrappers);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
+ readonly = 1;
+ }
+ }
+ DelWrapper(setf);
+ } else {
+ readonly = 1;
+ }
+
+
+ Printv(var_tab, tab4, "{ SWIG_prefix \"", iname, "\", 0, (swig_variable_func) ", getfname, ",", NIL);
+ if (readonly) {
+ static int readonlywrap = 0;
+ if (!readonlywrap) {
+ Wrapper *ro = NewWrapper();
+ Printf(ro->def,
+ "SWIGINTERN const char *swig_readonly(ClientData clientData SWIGUNUSED, Tcl_Interp *interp SWIGUNUSED, char *name1 SWIGUNUSED, char *name2 SWIGUNUSED, int flags SWIGUNUSED) {");
+ Printv(ro->code, "return \"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) ", setfname, "},\n", NIL);
+ }
+ Delete(getfname);
+ Delete(setfname);
+ Delete(setname);
+ Delete(getname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ String *nsname = !nspace ? Copy(iname) : NewStringf("%s::%s", ns_name, iname);
+ SwigType *type = Getattr(n, "type");
+ String *rawval = Getattr(n, "rawval");
+ String *value = rawval ? rawval : Getattr(n, "value");
+ String *tm;
+
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ if (nspace)
+ Setattr(n, "sym:name", nsname);
+
+ /* 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("consttab", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ Replaceall(tm, "$nsname", nsname);
+ Printf(const_tab, "%s,\n", tm);
+ } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$value", value);
+ Replaceall(tm, "$nsname", nsname);
+ Printf(f_init, "%s\n", tm);
+ } else {
+ Delete(nsname);
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+ Delete(nsname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int nativeWrapper(Node *n) {
+ String *name = Getattr(n, "sym:name");
+ String *funcname = Getattr(n, "wrap:name");
+ if (!addSymbol(funcname, n))
+ return SWIG_ERROR;
+
+ Printf(f_init, "\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", (swig_wrapper_func) %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n", name,
+ funcname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int classHandler(Node *n) {
+ static Hash *emitted = NewHash();
+ String *mangled_classname = 0;
+ String *real_classname = 0;
+
+ have_constructor = 0;
+ have_destructor = 0;
+ destructor_action = 0;
+
+ if (itcl) {
+ constructor = NewString("");
+ destructor = NewString("");
+ base_classes = NewString("");
+ base_class_init = NewString("");
+ methods = NewString("");
+ imethods = NewString("");
+ attributes = NewString("");
+ attribute_traces = NewString("");
+ iattribute_traces = NewString("");
+
+ have_base_classes = 0;
+ have_methods = 0;
+ have_attributes = 0;
+ }
+
+ class_name = Getattr(n, "sym:name");
+ if (!addSymbol(class_name, n))
+ return SWIG_ERROR;
+
+ real_classname = Getattr(n, "name");
+ mangled_classname = Swig_name_mangle(real_classname);
+
+ if (Getattr(emitted, mangled_classname))
+ return SWIG_NOWRAP;
+ Setattr(emitted, mangled_classname, "1");
+
+ attr_tab = NewString("");
+ Printf(attr_tab, "static swig_attribute swig_");
+ Printv(attr_tab, mangled_classname, "_attributes[] = {\n", NIL);
+
+ methods_tab = NewStringf("");
+ Printf(methods_tab, "static swig_method swig_");
+ Printv(methods_tab, mangled_classname, "_methods[] = {\n", NIL);
+
+ /* Generate normal wrappers */
+ Language::classHandler(n);
+
+ SwigType *t = Copy(Getattr(n, "name"));
+ SwigType_add_pointer(t);
+
+ // Catch all: eg. a class with only static functions and/or variables will not have 'remembered'
+ // SwigType_remember(t);
+ String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname);
+ SwigType_remember_clientdata(t, wrap_class);
+
+ // t = Copy(Getattr(n,"classtype"));
+ // SwigType_add_pointer(t);
+
+ String *rt = Copy(Getattr(n, "classtype"));
+ SwigType_add_pointer(rt);
+
+ // Register the class structure with the type checker
+ /* Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname); */
+ if (have_destructor) {
+ Printv(f_wrappers, "SWIGINTERN 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, "\n", NIL);
+ } else {
+ if (CPlusPlus) {
+ Printv(f_wrappers, " delete (", SwigType_str(rt, 0), ") obj;\n", NIL);
+ } else {
+ Printv(f_wrappers, " free((char *) obj);\n", NIL);
+ }
+ }
+ Printf(f_wrappers, "}\n");
+ }
+
+ Printf(methods_tab, " {0,0}\n};\n");
+ Printv(f_wrappers, methods_tab, NIL);
+
+ Printf(attr_tab, " {0,0,0}\n};\n");
+ Printv(f_wrappers, attr_tab, NIL);
+
+ /* Handle inheritance */
+
+ String *base_class = NewString("");
+ String *base_class_names = NewString("");
+
+ if (itcl) {
+ base_classes = NewString("");
+ }
+
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator b;
+ int index = 0;
+ b = First(baselist);
+ while (b.item) {
+ String *bname = Getattr(b.item, "name");
+ if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
+ b = Next(b);
+ continue;
+ }
+ if (itcl) {
+ have_base_classes = 1;
+ Printv(base_classes, bname, " ", NIL);
+ Printv(base_class_init, " ", bname, "Ptr::constructor $ptr\n", NIL);
+ }
+ String *bmangle = Swig_name_mangle(bname);
+ // Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL);
+ // Printf(base_class,"&_wrap_class_%s",bmangle);
+ Printf(base_class, "0");
+ Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
+ /* Put code to register base classes in init function */
+
+ //Printf(f_init,"/* Register base : %s */\n", bmangle);
+ //Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n", mangled_classname, index, SwigType_namestr(bname));
+ b = Next(b);
+ index++;
+ Putc(',', base_class);
+ Delete(bmangle);
+ }
+ }
+
+ if (itcl) {
+ String *ptrclass = NewString("");
+
+ // First, build the pointer base class
+ Printv(ptrclass, "itcl::class ", class_name, "Ptr {\n", NIL);
+ if (have_base_classes)
+ Printv(ptrclass, " inherit ", base_classes, "\n", NIL);
+
+ // Define protected variables for SWIG object pointer
+ Printv(ptrclass, " protected variable swigobj\n", " protected variable thisown\n", NIL);
+
+ // Define public variables
+ if (have_attributes) {
+ Printv(ptrclass, attributes, NIL);
+
+ // base class swig_getset was being called for complex inheritance trees
+ if (nspace) {
+
+ Printv(ptrclass, " protected method ", class_name, "_swig_getset {var name1 name2 op} {\n", NIL);
+
+ Printv(ptrclass,
+ " switch -exact -- $op {\n",
+ " r {set $var [", ns_name, "::", class_name, "_[set var]_get $swigobj]}\n",
+ " w {", ns_name, "::", class_name, "_${var}_set $swigobj [set $var]}\n", " }\n", " }\n", NIL);
+ } else {
+ Printv(ptrclass,
+ " protected method ", class_name, "_swig_getset {var name1 name2 op} {\n",
+ " switch -exact -- $op {\n",
+ " r {set $var [", class_name, "_[set var]_get $swigobj]}\n",
+ " w {", class_name, "_${var}_set $swigobj [set $var]}\n", " }\n", " }\n", NIL);
+ }
+ }
+ // Add the constructor, which may include
+ // calls to base class class constructors
+
+ Printv(ptrclass, " constructor { ptr } {\n", NIL);
+ if (have_base_classes) {
+ Printv(ptrclass, base_class_init, NIL);
+ Printv(ptrclass, " } {\n", NIL);
+ }
+
+ Printv(ptrclass, " set swigobj $ptr\n", " set thisown 0\n", NIL);
+
+ if (have_attributes) {
+ Printv(ptrclass, attribute_traces, NIL);
+ }
+ Printv(ptrclass, " }\n", NIL);
+
+
+ // Add destructor
+ Printv(ptrclass, " destructor {\n",
+ " set d_func delete_", class_name, "\n",
+ " if { $thisown && ([info command $d_func] != \"\") } {\n" " $d_func $swigobj\n", " }\n", " }\n", NIL);
+
+ // Add methods
+ if (have_methods) {
+ Printv(ptrclass, imethods, NIL);
+ };
+
+ // Close out the pointer class
+ Printv(ptrclass, "}\n\n", NIL);
+ Printv(f_shadow, ptrclass, NIL);
+ // pointer class end
+
+
+ // Create the "real" class.
+ Printv(f_shadow, "itcl::class ", class_name, " {\n", NIL);
+ Printv(f_shadow, " inherit ", class_name, "Ptr\n", NIL);
+
+ // If we have a constructor, then use it.
+ // If not, then we must have an abstract class without
+ // any constructor. So we create a class constructor
+ // which will fail for this class (but not for inherited
+ // classes). Note that the constructor must fail before
+ // calling the ptrclass constructor.
+
+ if (have_constructor) {
+ Printv(f_shadow, constructor, NIL);
+ } else {
+ Printv(f_shadow, " constructor { } {\n", NIL);
+ Printv(f_shadow, " # This constructor will fail if called directly\n", NIL);
+ Printv(f_shadow, " if { [info class] == \"::", class_name, "\" } {\n", NIL);
+ Printv(f_shadow, " error \"No constructor for class ", class_name, (Getattr(n, "abstract") ? " - class is abstract" : ""), "\"\n", NIL);
+ Printv(f_shadow, " }\n", NIL);
+ Printv(f_shadow, " }\n", NIL);
+ }
+
+ Printv(f_shadow, "}\n\n", NIL);
+ }
+
+ Printv(f_wrappers, "static swig_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL);
+ Printv(f_wrappers, "static const char * swig_", mangled_classname, "_base_names[] = {", base_class_names, "0};\n", NIL);
+ Delete(base_class);
+ Delete(base_class_names);
+
+ Printv(f_wrappers, "static 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(constructor_name)));
+ Delete(constructor_name);
+ constructor_name = 0;
+ } else {
+ Printf(f_wrappers, "0");
+ }
+ if (have_destructor) {
+ Printv(f_wrappers, ", swig_delete_", class_name, NIL);
+ } else {
+ Printf(f_wrappers, ",0");
+ }
+ Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases,",
+ "swig_", mangled_classname, "_base_names, &swig_module };\n", NIL);
+
+ if (!itcl) {
+ Printv(cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, (ClientData)&_wrap_class_", mangled_classname,
+ "},\n", NIL);
+ };
+
+ Delete(t);
+ Delete(mangled_classname);
+ return SWIG_OK;
+ }
+
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int memberfunctionHandler(Node *n) {
+ String *name = Getattr(n, "name");
+ String *iname = GetChar(n, "sym:name");
+
+ String *realname, *rname;
+
+ Language::memberfunctionHandler(n);
+
+ realname = iname ? iname : name;
+ rname = Swig_name_wrapper(Swig_name_member(class_name, realname));
+ if (!Getattr(n, "sym:nextSibling")) {
+ Printv(methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL);
+ }
+
+ if (itcl) {
+ ParmList *l = Getattr(n, "parms");
+ Parm *p = 0;
+ String *pname = NewString("");
+
+ // Add this member to our class handler function
+ Printv(imethods, tab2, "method ", realname, " [list ", NIL);
+
+ int pnum = 0;
+ for (p = l; p; p = nextSibling(p)) {
+
+ String *pn = Getattr(p, "name");
+ String *dv = Getattr(p, "value");
+ SwigType *pt = Getattr(p, "type");
+
+ Printv(pname, ",(", pt, ")", NIL);
+ Clear(pname);
+
+ /* Only print an argument if not void */
+ if (Cmp(pt, "void") != 0) {
+ if (Len(pn) > 0) {
+ Printv(pname, pn, NIL);
+ } else {
+ Printf(pname, "p%d", pnum);
+ }
+
+ if (Len(dv) > 0) {
+ String *defval = NewString(dv);
+ if (nspace) {
+ Insert(defval, 0, "::");
+ Insert(defval, 0, ns_name);
+ }
+ if (Strncmp(dv, "(", 1) == 0) {
+ Insert(defval, 0, "$");
+ Replaceall(defval, "(", "");
+ Replaceall(defval, ")", "");
+ }
+ Printv(imethods, "[list ", pname, " ", defval, "] ", NIL);
+ } else {
+ Printv(imethods, pname, " ", NIL);
+ }
+ }
+ ++pnum;
+ }
+ Printv(imethods, "] ", NIL);
+
+ if (nspace) {
+ Printv(imethods, "{ ", ns_name, "::", class_name, "_", realname, " $swigobj", NIL);
+ } else {
+ Printv(imethods, "{ ", class_name, "_", realname, " $swigobj", NIL);
+ };
+
+ pnum = 0;
+ for (p = l; p; p = nextSibling(p)) {
+
+ String *pn = Getattr(p, "name");
+ SwigType *pt = Getattr(p, "type");
+ Clear(pname);
+
+ /* Only print an argument if not void */
+ if (Cmp(pt, "void") != 0) {
+ if (Len(pn) > 0) {
+ Printv(pname, pn, NIL);
+ } else {
+ Printf(pname, "p%d", pnum);
+ }
+ Printv(imethods, " $", pname, NIL);
+ }
+ ++pnum;
+ }
+ Printv(imethods, " }\n", NIL);
+ have_methods = 1;
+ }
+
+ Delete(rname);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int membervariableHandler(Node *n) {
+ String *symname = Getattr(n, "sym:name");
+ String *rname;
+
+ Language::membervariableHandler(n);
+ Printv(attr_tab, tab4, "{ \"-", symname, "\",", NIL);
+ rname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname)));
+ Printv(attr_tab, rname, ", ", NIL);
+ Delete(rname);
+ if (!GetFlag(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");
+ }
+
+ if (itcl) {
+ Printv(attributes, " public variable ", symname, "\n", NIL);
+
+ Printv(attribute_traces, " trace variable ", symname, " rw [list ", class_name, "_swig_getset ", symname, "]\n", NIL);
+ Printv(attribute_traces, " set ", symname, "\n", NIL);
+
+ have_attributes = 1;
+ }
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+ Language::constructorHandler(n);
+
+ if (itcl) {
+ String *name = Getattr(n, "name");
+ String *iname = GetChar(n, "sym:name");
+
+ String *realname;
+
+ ParmList *l = Getattr(n, "parms");
+ Parm *p = 0;
+
+ String *pname = NewString("");
+
+ realname = iname ? iname : name;
+
+ if (!have_constructor) {
+ // Add this member to our class handler function
+ Printf(constructor, " constructor { ");
+
+ // Add parameter list
+ int pnum = 0;
+ for (p = l; p; p = nextSibling(p)) {
+
+ SwigType *pt = Getattr(p, "type");
+ String *pn = Getattr(p, "name");
+ String *dv = Getattr(p, "value");
+ Clear(pname);
+
+ /* Only print an argument if not void */
+ if (Cmp(pt, "void") != 0) {
+ if (Len(pn) > 0) {
+ Printv(pname, pn, NIL);
+ } else {
+ Printf(pname, "p%d", pnum);
+ }
+
+ if (Len(dv) > 0) {
+ Printv(constructor, "{", pname, " {", dv, "} } ", NIL);
+ } else {
+ Printv(constructor, pname, " ", NIL);
+ }
+ }
+ ++pnum;
+ }
+ Printf(constructor, "} { \n");
+
+ // [BRE] 08/17/00 Added test to see if we are instantiating this object
+ // type, or, if this constructor is being called as part of the itcl
+ // inheritance hierarchy.
+ // In the former case, we need to call the C++ constructor, in the
+ // latter we don't, or we end up with two C++ objects.
+ // Check to see if we are instantiating a 'realname' or something
+ // derived from it.
+ //
+ Printv(constructor, " if { [string equal -nocase \"", realname, "\" \"[namespace tail [info class]]\" ] } {\n", NIL);
+
+ // Call to constructor wrapper and parent Ptr class
+ // [BRE] add -namespace/-prefix support
+
+ if (nspace) {
+ Printv(constructor, " ", realname, "Ptr::constructor [", ns_name, "::new_", realname, NIL);
+ } else {
+ Printv(constructor, " ", realname, "Ptr::constructor [new_", realname, NIL);
+ }
+
+ pnum = 0;
+ for (p = l; p; p = nextSibling(p)) {
+
+ SwigType *pt = Getattr(p, "type");
+ String *pn = Getattr(p, "name");
+ Clear(pname);
+
+ /* Only print an argument if not void */
+ if (Cmp(pt, "void") != 0) {
+ if (Len(pn) > 0) {
+ Printv(pname, pn, NIL);
+ } else {
+ Printf(pname, "p%d", pnum);
+ }
+ Printv(constructor, " $", pname, NIL);
+ }
+ ++pnum;
+ }
+
+ Printv(constructor, "]\n", " }\n", " } {\n", " set thisown 1\n", " }\n", NIL);
+ }
+ }
+
+ constructor_name = NewString(Getattr(n, "sym:name"));
+ have_constructor = 1;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorHandler(Node *n) {
+ Language::destructorHandler(n);
+ have_destructor = 1;
+ destructor_action = Getattr(n, "wrap:action");
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * validIdentifier()
+ * ------------------------------------------------------------ */
+
+ virtual int validIdentifier(String *s) {
+ if (Strchr(s, ' '))
+ return 0;
+ return 1;
+ }
+
+ /* ------------------------------------------------------------
+ * usage_string()
+ * ------------------------------------------------------------ */
+
+ char *usage_string(char *iname, SwigType *, ParmList *l) {
+ static String *temp = 0;
+ Parm *p;
+ int i, numopt, pcount;
+
+ if (!temp)
+ temp = NewString("");
+ Clear(temp);
+ if (nspace) {
+ Printf(temp, "%s::%s ", ns_name, iname);
+ } else {
+ Printf(temp, "%s ", iname);
+ }
+ /* Now go through and print parameters */
+ i = 0;
+ pcount = emit_num_arguments(l);
+ numopt = pcount - emit_num_required(l);
+ for (p = l; p; p = nextSibling(p)) {
+
+ SwigType *pt = Getattr(p, "type");
+ String *pn = Getattr(p, "name");
+ /* Only print an argument if not ignored */
+ if (!checkAttribute(p, "tmap:in:numinputs", "0")) {
+ if (i >= (pcount - numopt))
+ Putc('?', temp);
+ if (Len(pn) > 0) {
+ Printf(temp, "%s", pn);
+ } else {
+ Printf(temp, "%s", SwigType_str(pt, 0));
+ }
+ if (i >= (pcount - numopt))
+ Putc('?', temp);
+ Putc(' ', temp);
+ i++;
+ }
+ }
+ return Char(temp);
+ }
+
+ String *runtimeCode() {
+ String *s = NewString("");
+ String *serrors = Swig_include_sys("tclerrors.swg");
+ if (!serrors) {
+ Printf(stderr, "*** Unable to open 'tclerrors.swg'\n");
+ } else {
+ Append(s, serrors);
+ Delete(serrors);
+ }
+ String *sapi = Swig_include_sys("tclapi.swg");
+ if (!sapi) {
+ Printf(stderr, "*** Unable to open 'tclapi.swg'\n");
+ } else {
+ Append(s, sapi);
+ Delete(sapi);
+ }
+ String *srun = Swig_include_sys("tclrun.swg");
+ if (!srun) {
+ Printf(stderr, "*** Unable to open 'tclrun.swg'\n");
+ } else {
+ Append(s, srun);
+ Delete(srun);
+ }
+
+ return s;
+ }
+
+ String *defaultExternalRuntimeFilename() {
+ return NewString("swigtclrun.h");
+ }
+};
+
+/* ----------------------------------------------------------------------
+ * swig_tcl() - Instantiate module
+ * ---------------------------------------------------------------------- */
+
+static Language *new_swig_tcl() {
+ return new TCL8();
+}
+extern "C" Language *swig_tcl(void) {
+ return new_swig_tcl();
+}
diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx
new file mode 100644
index 0000000..6cb7f0a
--- /dev/null
+++ b/Source/Modules/typepass.cxx
@@ -0,0 +1,1164 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_typepass_cxx[] = "$Id: typepass.cxx 11279 2009-06-16 19:29:08Z wsfulton $";
+
+#include "swigmod.h"
+#include "cparse.h"
+
+struct normal_node {
+ Symtab *symtab;
+ Hash *typescope;
+ List *normallist;
+ normal_node *next;
+};
+
+static normal_node *patch_list = 0;
+
+/* Singleton class - all non-static methods in this class are private */
+class TypePass:private Dispatcher {
+ Node *inclass;
+ Node *module;
+ int importmode;
+ String *nsname;
+ Hash *classhash;
+ List *normalize;
+
+ TypePass() {
+ }
+
+ /* Normalize a type. Replaces type with fully qualified version */
+ void normalize_type(SwigType *ty) {
+ SwigType *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);
+ /* This is a check for a function type */
+ {
+ SwigType *qty = SwigType_typedef_resolve_all(ty);
+ if (SwigType_isfunction(qty)) {
+ SwigType_add_pointer(ty);
+ }
+ Delete(qty);
+ }
+
+ 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);
+ Iterator t;
+ for (t = First(nn->normallist); t.item; t = Next(t)) {
+ normalize_type(t.item);
+ }
+ Delete(nn->normallist);
+ np = nn->next;
+ delete(nn);
+ nn = np;
+ }
+ Swig_symbol_setscope(currentsym);
+ }
+
+ /* generate C++ inheritance type-relationships */
+ void cplus_inherit_types_impl(Node *first, Node *cls, String *clsname, const char *bases, const char *baselist, int ispublic, String *cast = 0) {
+
+ if (first == cls)
+ return; /* The Marcelo check */
+ if (!cls)
+ cls = first;
+ List *alist = 0;
+ 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(cls), Getline(cls), "'%s' does not have a valid base class.\n", Getattr(cls, "name"));
+ Swig_error(Getfile(bcls), Getline(bcls), "'%s' is not a valid base class.\n", SwigType_namestr(bname));
+ } else {
+ Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(cls), Getline(cls), "Base class '%s' is incomplete.\n", SwigType_namestr(bname));
+ Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bcls), Getline(bcls), "Only forward declaration '%s' was found.\n", SwigType_namestr(bname));
+ clsforward = 1;
+ }
+ bcls = 0;
+ } else {
+ if (Getattr(bcls, "typepass:visit")) {
+ if (!ilist)
+ ilist = alist = NewList();
+ Append(ilist, bcls);
+ } else {
+ Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Base class '%s' undefined.\n", SwigType_namestr(bname));
+ Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "'%s' must be defined before it is used as a base class.\n", SwigType_namestr(bname));
+ }
+ }
+ }
+ break;
+ }
+
+ if (tname)
+ Delete(tname);
+ if (!bcls) {
+ if (!clsforward) {
+ if (ispublic && !Getmeta(bname, "already_warned")) {
+ Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname));
+ if (Strchr(bname, '<')) {
+ Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Maybe you forgot to instantiate '%s' using %%template.\n",
+ SwigType_namestr(bname));
+ }
+ Setmeta(bname, "already_warned", "1");
+ }
+ }
+ SwigType_inherit(clsname, bname, cast, 0);
+ }
+ }
+ }
+ if (ilist) {
+ Setattr(cls, bases, ilist);
+ }
+ }
+ if (alist)
+ Delete(alist);
+
+ 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, 0);
+ 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 *st = Getattr(cls, "symtab");
+ Symtab *bst = Getattr(bclass, "symtab");
+ if (st == bst) {
+ Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(cls), Getline(cls), "Recursive scope inheritance of '%s'.\n", Getattr(cls, "name"));
+ continue;
+ }
+ Symtab *s = Swig_symbol_current();
+ Swig_symbol_setscope(st);
+ Swig_symbol_inherit(bst);
+ Swig_symbol_setscope(s);
+
+ /* Recursively hit base classes */
+ String *namestr = SwigType_namestr(Getattr(bclass, "name"));
+ String *newcast = NewStringf("(%s *)%s", namestr, cast);
+ Delete(namestr);
+ cplus_inherit_types_impl(first, bclass, clsname, bases, baselist, ispublic, newcast);
+ Delete(newcast);
+ }
+ }
+
+ void append_list(List *lb, List *la) {
+ if (la && lb) {
+ for (Iterator bi = First(la); bi.item; bi = Next(bi)) {
+ Append(lb, bi.item);
+ }
+ }
+ }
+
+ void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) {
+ cplus_inherit_types_impl(first, cls, clsname, "bases", "baselist", 1, cast);
+ cplus_inherit_types_impl(first, cls, clsname, "protectedbases", "protectedbaselist", 0, cast);
+ cplus_inherit_types_impl(first, cls, clsname, "privatebases", "privatebaselist", 0, cast);
+
+ if (!cls)
+ cls = first;
+
+ List *allbases = NewList();
+ append_list(allbases, Getattr(cls, "bases"));
+ append_list(allbases, Getattr(cls, "protectedbases"));
+ append_list(allbases, Getattr(cls, "privatebases"));
+ if (Len(allbases)) {
+ Setattr(cls, "allbases", allbases);
+ }
+ Delete(allbases);
+ }
+
+ /* ------------------------------------------------------------
+ * 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 ((n == cn)
+ || (Strcmp(nodeType(cn), "template") == 0)
+ || (Getattr(cn, "feature:onlychildren") != 0)
+ || (Getattr(n, "feature:onlychildren") != 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,\n", SwigType_namestr(name));
+ Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name")));
+ 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);
+ String *tdname = Getattr(n, "tdname");
+ if (tdname) {
+ tdname = NewStringf("%s::%s", nsname, tdname);
+ Setattr(n, "tdname", tdname);
+ }
+ }
+ 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);
+ Delete(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);
+ Delete(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 = 0;
+ if (nn)
+ 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);
+ Delete(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");
+ }
+
+ /* 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 (GetFlag(n, "conversion_operator")) {
+ /* The call to the operator in the generated wrapper must be fully qualified in order to compile */
+ SwigType *name = Getattr(n, "name");
+ SwigType *qualifiedname = Swig_symbol_string_qualify(name,0);
+ Clear(name);
+ Append(name, qualifiedname);
+ Delete(qualifiedname);
+ }
+
+ 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) && strncmp(Char(t), "::", 2)) {
+ 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");
+ }
+
+ 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) {
+ String *scope = 0;
+
+ // Add a typedef to the type table so that we can use 'enum Name' as well as just 'Name'
+ if (nsname || inclass) {
+
+ // But first correct the name and tdname to contain the fully qualified scopename
+ if (nsname && inclass) {
+ scope = NewStringf("%s::%s", nsname, Getattr(inclass, "name"));
+ } else if (nsname) {
+ scope = NewStringf("%s", nsname);
+ } else if (inclass) {
+ scope = NewStringf("%s", Getattr(inclass, "name"));
+ }
+
+ String *nname = NewStringf("%s::%s", scope, name);
+ Setattr(n, "name", nname);
+
+ String *tdname = Getattr(n, "tdname");
+ if (tdname) {
+ tdname = NewStringf("%s::%s", scope, tdname);
+ Setattr(n, "tdname", tdname);
+ }
+
+ SwigType *t = NewStringf("enum %s", nname);
+ SwigType_typedef(t, name);
+ } else {
+ SwigType *t = NewStringf("enum %s", name);
+ SwigType_typedef(t, name);
+ }
+ Delete(scope);
+ }
+
+ String *tdname = Getattr(n, "tdname");
+ String *unnamed = Getattr(n, "unnamed");
+ String *storage = Getattr(n, "storage");
+
+ // Construct enumtype - for declaring an enum of this type with SwigType_ltype() etc
+ String *enumtype = 0;
+ if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) {
+ enumtype = Copy(Getattr(n, "tdname"));
+ } else if (name) {
+ enumtype = NewStringf("%s%s", CPlusPlus ? "" : "enum ", Getattr(n, "name"));
+ } else {
+ // anonymous enums
+ enumtype = Copy(Getattr(n, "type"));
+ }
+ Setattr(n, "enumtype", enumtype);
+
+ // This block of code is for dealing with %ignore on an enum item where the target language
+ // attempts to use the C enum value in the target language itself and expects the previous enum value
+ // to be one more than the previous value... the previous enum item might not exist if it is ignored!
+ // - It sets the first non-ignored enum item with the "firstenumitem" attribute.
+ // - It adds an enumvalue attribute if the previous enum item is ignored
+ {
+ Node *c;
+ int count = 0;
+ String *previous = 0;
+ bool previous_ignored = false;
+ bool firstenumitem = false;
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ assert(strcmp(Char(nodeType(c)), "enumitem") == 0);
+
+ bool reset;
+ String *enumvalue = Getattr(c, "enumvalue");
+ if (GetFlag(c, "feature:ignore")) {
+ reset = enumvalue ? true : false;
+ previous_ignored = true;
+ } else {
+ if (!enumvalue && previous_ignored) {
+ if (previous)
+ Setattr(c, "enumvalue", NewStringf("(%s) + %d", previous, count+1));
+ else
+ Setattr(c, "enumvalue", NewStringf("%d", count));
+ SetFlag(c, "virtenumvalue"); // identify enumvalue as virtual, ie not from the parsed source
+ }
+ if (!firstenumitem) {
+ SetFlag(c, "firstenumitem");
+ firstenumitem = true;
+ }
+ reset = true;
+ previous_ignored = false;
+ }
+ if (reset) {
+ previous = enumvalue ? enumvalue : Getattr(c, "name");
+ count = 0;
+ } else {
+ count++;
+ }
+ }
+ }
+
+ 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)) && cparse_cplusplus) {
+ 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);
+ }
+ Node *next = nextSibling(n);
+
+ // Make up an enumvalue if one was not specified in the parsed code (not designed to be used on enum items and %ignore - enumvalue will be set instead)
+ if (!GetFlag(n, "feature:ignore")) {
+ if (Getattr(n, "_last") && !Getattr(n, "enumvalue")) { // Only the first enum item has _last set (Note: first non-ignored enum item has firstenumitem set)
+ Setattr(n, "enumvalueex", "0");
+ }
+ if (next && !Getattr(next, "enumvalue")) {
+ Setattr(next, "enumvalueex", NewStringf("%s + 1", Getattr(n, "sym:name")));
+ }
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * enumforwardDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int enumforwardDeclaration(Node *n) {
+
+ // Use enumDeclaration() to do all the hard work.
+ // Note that no children can be emitted in a forward declaration as there aren't any.
+ return enumDeclaration(n);
+ }
+
+#ifdef DEBUG_OVERLOADED
+ static void show_overloaded(Node *n) {
+ Node *c = Getattr(n, "sym:overloaded");
+ Node *checkoverloaded = c;
+ Printf(stdout, "-------------------- overloaded start %s sym:overloaded():%p -------------------------------\n", Getattr(n, "name"), c);
+ while (c) {
+ if (Getattr(c, "error")) {
+ c = Getattr(c, "sym:nextSibling");
+ continue;
+ }
+ if (Getattr(c, "sym:overloaded") != checkoverloaded) {
+ Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
+ Swig_print_node(c);
+ exit (1);
+ }
+
+ String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
+ Printf(stdout, " show_overloaded %s::%s(%s) [%s] nodeType:%s\n", parentNode(c) ? Getattr(parentNode(c), "name") : "NOPARENT", Getattr(c, "name"), decl, Getattr(c, "sym:overname"), nodeType(c));
+ if (!Getattr(c, "sym:overloaded")) {
+ Printf(stdout, "sym:overloaded error.....%p\n", c);
+ Swig_print_node(c);
+ exit (1);
+ }
+ c = Getattr(c, "sym:nextSibling");
+ }
+ Printf(stdout, "-------------------- overloaded end %s -------------------------------\n", Getattr(n, "name"));
+ }
+#endif
+
+ /* ------------------------------------------------------------
+ * 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 */
+ Symtab *stab = Getattr(n, "sym:symtab");
+ if (stab) {
+ String *uname = Getattr(n, "uname");
+ ns = Swig_symbol_clookup(uname, stab);
+ if (!ns && SwigType_istemplate(uname)) {
+ String *tmp = Swig_symbol_template_deftype(uname, 0);
+ if (!Equal(tmp, uname)) {
+ ns = Swig_symbol_clookup(tmp, stab);
+ }
+ Delete(tmp);
+ }
+ } else {
+ ns = 0;
+ }
+ if (!ns) {
+ if (is_public(n)) {
+ 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) && (!GetFlag(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"))
+ || GetFlag(c, "feature:ignore"))) {
+
+ /* Don't generate a method if the method is overridden in this class,
+ * for example don't generate another m(bool) should there be a Base::m(bool) :
+ * struct Derived : Base {
+ * void m(bool);
+ * using Base::m;
+ * };
+ */
+ String *csymname = Getattr(c, "sym:name");
+ if (!csymname || (Strcmp(csymname, symname) == 0)) {
+ {
+ 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);
+ Delattr(nn, "access"); // access might be different from the method in the base class
+ if (!Getattr(nn, "sym:name"))
+ Setattr(nn, "sym:name", symname);
+
+ if (!GetFlag(nn, "feature:ignore")) {
+ ParmList *parms = CopyParmList(Getattr(c, "parms"));
+ int is_pointer = SwigType_ispointer_return(Getattr(nn, "decl"));
+ int is_void = checkAttribute(nn, "type", "void") && !is_pointer;
+ Setattr(nn, "parms", parms);
+ Delete(parms);
+ if (Getattr(n, "feature:extend")) {
+ String *ucode = is_void ? NewStringf("{ self->%s(", Getattr(n, "uname")) : NewStringf("{ return self->%s(", Getattr(n, "uname"));
+
+ for (ParmList *p = parms; p;) {
+ Append(ucode, Getattr(p, "name"));
+ p = nextSibling(p);
+ if (p)
+ Append(ucode, ",");
+ }
+ Append(ucode, "); }");
+ Setattr(nn, "code", ucode);
+ Delete(ucode);
+ }
+ ParmList *throw_parm_list = Getattr(c, "throws");
+ if (throw_parm_list)
+ Setattr(nn, "throws", CopyParmList(throw_parm_list));
+ 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");
+ }
+ }
+ }
+
+ /* Hack the parse tree symbol table for overloaded methods. Replace the "using" node with the
+ * list of overloaded methods we have just added in as child nodes to the "using" node.
+ * The node will still exist, it is just the symbol table linked list of overloaded methods
+ * which is hacked. */
+ if (Getattr(n, "sym:overloaded"))
+ {
+#ifdef DEBUG_OVERLOADED
+show_overloaded(n);
+#endif
+ int cnt = 0;
+ Node *debugnode = n;
+ if (!firstChild(n)) {
+ // Remove from overloaded list ('using' node does not actually end up adding in any methods)
+ Node *ps = Getattr(n, "sym:previousSibling");
+ Node *ns = Getattr(n, "sym:nextSibling");
+ if (ps) {
+ Setattr(ps, "sym:nextSibling", ns);
+ }
+ if (ns) {
+ Setattr(ns, "sym:previousSibling", ps);
+ }
+ } else {
+ // The 'using' node results in methods being added in - slot in the these methods here
+ Node *ps = Getattr(n, "sym:previousSibling");
+ Node *ns = Getattr(n, "sym:nextSibling");
+ Node *fc = firstChild(n);
+ Node *pp = fc;
+
+ Node *firstoverloaded = Getattr(n, "sym:overloaded");
+ if (firstoverloaded == n) {
+ // This 'using' node we are cutting out was the first node in the overloaded list.
+ // Change the first node in the list to its first sibling
+ Delattr(firstoverloaded, "sym:overloaded");
+ Node *nnn = Getattr(firstoverloaded, "sym:nextSibling");
+ firstoverloaded = fc;
+ while (nnn) {
+ Setattr(nnn, "sym:overloaded", firstoverloaded);
+ nnn = Getattr(nnn, "sym:nextSibling");
+ }
+ }
+ while (pp) {
+ Node *ppn = Getattr(pp, "sym:nextSibling");
+ Setattr(pp, "sym:overloaded", firstoverloaded);
+ Setattr(pp, "sym:overname", NewStringf("%s_%d", Getattr(n, "sym:overname"), cnt++));
+ if (ppn)
+ pp = ppn;
+ else
+ break;
+ }
+ if (ps) {
+ Setattr(ps, "sym:nextSibling", fc);
+ Setattr(fc, "sym:previousSibling", ps);
+ }
+ if (ns) {
+ Setattr(ns, "sym:previousSibling", pp);
+ Setattr(pp, "sym:nextSibling", ns);
+ }
+ debugnode = firstoverloaded;
+ }
+ Delattr(n, "sym:previousSibling");
+ Delattr(n, "sym:nextSibling");
+ Delattr(n, "sym:overloaded");
+ Delattr(n, "sym:overname");
+#ifdef DEBUG_OVERLOADED
+show_overloaded(debugnode);
+#endif
+ clean_overloaded(n); // Needed?
+ }
+ }
+ }
+ } 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;
+ }
+
+public:
+ static void pass(Node *n) {
+ TypePass t;
+ t.top(n);
+ }
+};
+
+void Swig_process_types(Node *n) {
+ if (!n)
+ return;
+ TypePass::pass(n);
+}
diff --git a/Source/Modules/uffi.cxx b/Source/Modules/uffi.cxx
new file mode 100644
index 0000000..780b9e8
--- /dev/null
+++ b/Source/Modules/uffi.cxx
@@ -0,0 +1,398 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * uffi.cxx
+ *
+ * Uffi language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+// TODO: remove remnants of lisptype
+
+char cvsroot_uffi_cxx[] = "$Id: uffi.cxx 11380 2009-07-08 12:17:45Z wsfulton $";
+
+#include "swigmod.h"
+
+class UFFI:public Language {
+public:
+
+ virtual void main(int argc, char *argv[]);
+ virtual int top(Node *n);
+ virtual int functionWrapper(Node *n);
+ virtual int constantWrapper(Node *n);
+ virtual int classHandler(Node *n);
+ virtual int membervariableHandler(Node *n);
+
+};
+
+static File *f_cl = 0;
+
+static struct {
+ int count;
+ String **entries;
+} defined_foreign_types;
+
+static const char *identifier_converter = "identifier-convert-null";
+
+static int any_varargs(ParmList *pl) {
+ Parm *p;
+
+ for (p = pl; p; p = nextSibling(p)) {
+ if (SwigType_isvarargs(Getattr(p, "type")))
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* utilities */
+/* returns new string w/ parens stripped */
+static String *strip_parens(String *string) {
+ char *s = Char(string), *p;
+ int len = Len(string);
+ String *res;
+
+ if (len == 0 || s[0] != '(' || s[len - 1] != ')') {
+ return NewString(string);
+ }
+
+ p = (char *) malloc(len - 2 + 1);
+ if (!p) {
+ Printf(stderr, "Malloc failed\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ strncpy(p, s + 1, len - 1);
+ p[len - 2] = 0; /* null terminate */
+
+ res = NewString(p);
+ free(p);
+
+ return res;
+}
+
+
+static String *convert_literal(String *num_param, String *type) {
+ String *num = strip_parens(num_param), *res;
+ char *s = Char(num);
+
+ /* Make sure doubles use 'd' instead of 'e' */
+ if (!Strcmp(type, "double")) {
+ String *updated = Copy(num);
+ if (Replace(updated, "e", "d", DOH_REPLACE_ANY) > 1) {
+ Printf(stderr, "Weird!! number %s looks invalid.\n", num);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Delete(num);
+ return updated;
+ }
+
+ if (SwigType_type(type) == T_CHAR) {
+ /* Use CL syntax for character literals */
+ return NewStringf("#\\%s", num_param);
+ } else if (SwigType_type(type) == T_STRING) {
+ /* Use CL syntax for string literals */
+ return NewStringf("\"%s\"", num_param);
+ }
+
+ if (Len(num) < 2 || s[0] != '0') {
+ return num;
+ }
+
+ /* octal or hex */
+
+ res = NewStringf("#%c%s", s[1] == 'x' ? 'x' : 'o', s + 2);
+ Delete(num);
+
+ return res;
+}
+
+static void add_defined_foreign_type(String *type) {
+ if (!defined_foreign_types.count) {
+ /* Make fresh */
+ defined_foreign_types.count = 1;
+ defined_foreign_types.entries = (String **) malloc(sizeof(String *));
+ } else {
+ /* make room */
+ defined_foreign_types.count++;
+ defined_foreign_types.entries = (String **)
+ realloc(defined_foreign_types.entries, defined_foreign_types.count * sizeof(String *));
+ }
+
+ if (!defined_foreign_types.entries) {
+ Printf(stderr, "Out of memory\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ /* Fill in the new data */
+ defined_foreign_types.entries[defined_foreign_types.count - 1] = Copy(type);
+
+}
+
+
+static String *get_ffi_type(Node *n, SwigType *ty, const_String_or_char_ptr name) {
+ Node *node = NewHash();
+ Setattr(node, "type", ty);
+ Setattr(node, "name", name);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *tm = Swig_typemap_lookup("ffitype", node, "", 0);
+ Delete(node);
+
+ if (tm) {
+ return NewString(tm);
+ } else {
+ SwigType *tr = SwigType_typedef_resolve_all(ty);
+ char *type_reduced = Char(tr);
+ int i;
+
+ //Printf(stdout,"convert_type %s\n", ty);
+ if (SwigType_isconst(tr)) {
+ SwigType_pop(tr);
+ type_reduced = Char(tr);
+ }
+
+ if (SwigType_ispointer(type_reduced) || SwigType_isarray(ty) || !strncmp(type_reduced, "p.f", 3)) {
+ return NewString(":pointer-void");
+ }
+
+ for (i = 0; i < defined_foreign_types.count; i++) {
+ if (!Strcmp(ty, defined_foreign_types.entries[i])) {
+ return NewStringf("#.(%s \"%s\" :type :type)", identifier_converter, ty);
+ }
+ }
+
+ if (!Strncmp(type_reduced, "enum ", 5)) {
+ return NewString(":int");
+ }
+
+ Printf(stderr, "Unsupported data type: %s (was: %s)\n", type_reduced, ty);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ return 0;
+}
+
+static String *get_lisp_type(Node *n, SwigType *ty, const_String_or_char_ptr name) {
+ Node *node = NewHash();
+ Setattr(node, "type", ty);
+ Setattr(node, "name", name);
+ Setfile(node, Getfile(n));
+ Setline(node, Getline(n));
+ const String *tm = Swig_typemap_lookup("lisptype", node, "", 0);
+ Delete(node);
+
+ return tm ? NewString(tm) : NewString("");
+}
+
+void UFFI::main(int argc, char *argv[]) {
+ int i;
+
+ Preprocessor_define("SWIGUFFI 1", 0);
+ SWIG_library_directory("uffi");
+ SWIG_config_file("uffi.swg");
+
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-identifier-converter")) {
+ char *conv = argv[i + 1];
+
+ if (!conv)
+ Swig_arg_error();
+
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+
+ /* check for built-ins */
+ if (!strcmp(conv, "lispify")) {
+ identifier_converter = "identifier-convert-lispify";
+ } else if (!strcmp(conv, "null")) {
+ identifier_converter = "identifier-convert-null";
+ } else {
+ /* Must be user defined */
+ char *idconv = new char[strlen(conv) + 1];
+ strcpy(idconv, conv);
+ identifier_converter = idconv;
+ }
+ }
+
+ if (!strcmp(argv[i], "-help")) {
+ fprintf(stdout, "UFFI Options (available with -uffi)\n");
+ fprintf(stdout,
+ " -identifier-converter <type or funcname>\n"
+ "\tSpecifies the type of conversion to do on C identifiers to convert\n"
+ "\tthem to symbols. There are two built-in converters: 'null' and\n"
+ "\t 'lispify'. The default is 'null'. If you supply a name other\n"
+ "\tthan one of the built-ins, then a function by that name will be\n"
+ "\tcalled to convert identifiers to symbols.\n");
+ }
+ }
+}
+
+int UFFI::top(Node *n) {
+ String *module = Getattr(n, "name");
+ String *output_filename = NewString("");
+ File *f_null = NewString("");
+
+ Printf(output_filename, "%s%s.cl", SWIG_output_directory(), module);
+
+
+ f_cl = NewFile(output_filename, "w", SWIG_output_files());
+ if (!f_cl) {
+ FileErrorDisplay(output_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Swig_register_filebyname("header", f_null);
+ Swig_register_filebyname("begin", f_null);
+ Swig_register_filebyname("runtime", f_null);
+ Swig_register_filebyname("wrapper", f_cl);
+
+ Swig_banner_target_lang(f_cl, ";;");
+
+ Printf(f_cl, "\n"
+ ";; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; package: %s -*-\n\n(defpackage :%s\n (:use :common-lisp :uffi))\n\n(in-package :%s)\n",
+ module, module, module);
+ Printf(f_cl, "(eval-when (compile load eval)\n (defparameter *swig-identifier-converter* '%s))\n", identifier_converter);
+
+ Language::top(n);
+
+ Close(f_cl);
+ Delete(f_cl); // Delete the handle, not the file
+ Close(f_null);
+ Delete(f_null);
+
+ return SWIG_OK;
+}
+
+int UFFI::functionWrapper(Node *n) {
+ String *funcname = Getattr(n, "sym:name");
+ ParmList *pl = Getattr(n, "parms");
+ Parm *p;
+ int argnum = 0, first = 1, varargs = 0;
+
+ //Language::functionWrapper(n);
+
+ Printf(f_cl, "(swig-defun \"%s\"\n", funcname);
+ Printf(f_cl, " (");
+
+ /* Special cases */
+
+ if (ParmList_len(pl) == 0) {
+ Printf(f_cl, ":void");
+ } else if (any_varargs(pl)) {
+ Printf(f_cl, "#| varargs |#");
+ varargs = 1;
+ } else {
+ for (p = pl; p; p = nextSibling(p), argnum++) {
+ String *argname = Getattr(p, "name");
+ SwigType *argtype = Getattr(p, "type");
+ String *ffitype = get_ffi_type(n, argtype, argname);
+ String *lisptype = get_lisp_type(n, argtype, argname);
+ int tempargname = 0;
+
+ if (!argname) {
+ argname = NewStringf("arg%d", argnum);
+ tempargname = 1;
+ }
+
+ if (!first) {
+ Printf(f_cl, "\n ");
+ }
+ Printf(f_cl, "(%s %s %s)", argname, ffitype, lisptype);
+ first = 0;
+
+ Delete(ffitype);
+ Delete(lisptype);
+ if (tempargname)
+ Delete(argname);
+
+ }
+ }
+ Printf(f_cl, ")\n"); /* finish arg list */
+ Printf(f_cl, " :returning %s\n"
+ //" :strings-convert t\n"
+ //" :call-direct %s\n"
+ //" :optimize-for-space t"
+ ")\n", get_ffi_type(n, Getattr(n, "type"), "result")
+ //,varargs ? "nil" : "t"
+ );
+
+
+ return SWIG_OK;
+}
+
+int UFFI::constantWrapper(Node *n) {
+ String *type = Getattr(n, "type");
+ String *converted_value = convert_literal(Getattr(n, "value"), type);
+ String *name = Getattr(n, "sym:name");
+
+#if 0
+ Printf(stdout, "constant %s is of type %s. value: %s\n", name, type, converted_value);
+#endif
+
+ Printf(f_cl, "(swig-defconstant \"%s\" %s)\n", name, converted_value);
+
+ Delete(converted_value);
+
+ return SWIG_OK;
+}
+
+// Includes structs
+int UFFI::classHandler(Node *n) {
+
+ String *name = Getattr(n, "sym:name");
+ String *kind = Getattr(n, "kind");
+ Node *c;
+
+ if (Strcmp(kind, "struct")) {
+ Printf(stderr, "Don't know how to deal with %s kind of class yet.\n", kind);
+ Printf(stderr, " (name: %s)\n", name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Printf(f_cl, "(swig-def-struct \"%s\"\n \n", name);
+
+ for (c = firstChild(n); c; c = nextSibling(c)) {
+ SwigType *type = Getattr(c, "type");
+ SwigType *decl = Getattr(c, "decl");
+ type = Copy(type);
+ SwigType_push(type, decl);
+ String *lisp_type;
+
+ if (Strcmp(nodeType(c), "cdecl")) {
+ Printf(stderr, "Structure %s has a slot that we can't deal with.\n", name);
+ Printf(stderr, "nodeType: %s, name: %s, type: %s\n", nodeType(c), Getattr(c, "name"), Getattr(c, "type"));
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+
+ /* Printf(stdout, "Converting %s in %s\n", type, name); */
+ lisp_type = get_ffi_type(n, type, Getattr(c, "sym:name"));
+
+ Printf(f_cl, " (#.(%s \"%s\" :type :slot) %s)\n", identifier_converter, Getattr(c, "sym:name"), lisp_type);
+
+ Delete(lisp_type);
+ }
+
+ // Language::classHandler(n);
+
+ Printf(f_cl, " )\n");
+
+ /* Add this structure to the known lisp types */
+ //Printf(stdout, "Adding %s foreign type\n", name);
+ add_defined_foreign_type(name);
+
+ return SWIG_OK;
+}
+
+int UFFI::membervariableHandler(Node *n) {
+ Language::membervariableHandler(n);
+ return SWIG_OK;
+}
+
+
+extern "C" Language *swig_uffi(void) {
+ return new UFFI();
+}
diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx
new file mode 100644
index 0000000..496700a
--- /dev/null
+++ b/Source/Modules/utils.cxx
@@ -0,0 +1,98 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * utils.cxx
+ *
+ * Various utility functions.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_utils_cxx[] = "$Id: utils.cxx 10423 2008-05-07 20:59:00Z wsfulton $";
+
+#include <swigmod.h>
+
+int is_public(Node *n) {
+ String *access = Getattr(n, "access");
+ return !access || !Cmp(access, "public");
+}
+
+int is_private(Node *n) {
+ String *access = Getattr(n, "access");
+ return access && !Cmp(access, "private");
+}
+
+int is_protected(Node *n) {
+ String *access = Getattr(n, "access");
+ return access && !Cmp(access, "protected");
+}
+
+static int is_member_director_helper(Node *parentnode, Node *member) {
+ int parent_nodirector = GetFlag(parentnode, "feature:nodirector");
+ if (parent_nodirector)
+ return 0;
+ int parent_director = Swig_director_mode() && GetFlag(parentnode, "feature:director");
+ int cdecl_director = parent_director || GetFlag(member, "feature:director");
+ int cdecl_nodirector = GetFlag(member, "feature:nodirector");
+ return cdecl_director && !cdecl_nodirector && !GetFlag(member, "feature:extend");
+}
+
+int is_member_director(Node *parentnode, Node *member) {
+ if (parentnode && checkAttribute(member, "storage", "virtual")) {
+ return is_member_director_helper(parentnode, member);
+ } else {
+ return 0;
+ }
+}
+
+int is_member_director(Node *member) {
+ return is_member_director(Getattr(member, "parentNode"), member);
+}
+
+// Identifies the additional protected members that are generated when the allprotected option is used.
+// This does not include protected virtual methods as they are turned on with the dirprot option.
+int is_non_virtual_protected_access(Node *n) {
+ int result = 0;
+ if (Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode() && is_protected(n) && !checkAttribute(n, "storage", "virtual")) {
+ if (is_member_director_helper(Getattr(n, "parentNode"), n))
+ result = 1;
+ }
+ return result;
+}
+
+/* Clean overloaded list. Removes templates, ignored, and errors */
+
+void clean_overloaded(Node *n) {
+ Node *nn = Getattr(n, "sym:overloaded");
+ Node *first = 0;
+ while (nn) {
+ String *ntype = nodeType(nn);
+ if ((GetFlag(nn, "feature:ignore")) ||
+ (Getattr(nn, "error")) ||
+ (Strcmp(ntype, "template") == 0) ||
+ ((Strcmp(ntype, "cdecl") == 0) && is_protected(nn) && !is_member_director(nn) && !is_non_virtual_protected_access(n))) {
+ /* 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 (!first)
+ first = nn;
+ Setattr(nn, "sym:overloaded", first);
+ }
+ nn = Getattr(nn, "sym:nextSibling");
+ }
+ if (!first || (first && !Getattr(first, "sym:nextSibling"))) {
+ if (Getattr(n, "sym:overloaded"))
+ Delattr(n, "sym:overloaded");
+ }
+}
diff --git a/Source/Modules/xml.cxx b/Source/Modules/xml.cxx
new file mode 100644
index 0000000..a3d393a
--- /dev/null
+++ b/Source/Modules/xml.cxx
@@ -0,0 +1,320 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * xml.cxx
+ *
+ * An Xml parse tree generator.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_xml_cxx[] = "$Id: xml.cxx 10898 2008-11-03 12:51:45Z wsfulton $";
+
+#include "swigmod.h"
+
+static const char *usage = "\
+XML Options (available with -xml)\n\
+ -xmllang <lang> - Typedef language\n\
+ -xmllite - More lightweight version of XML\n\
+ ------\n\
+ deprecated (use -o): -xml <output.xml> - Use <output.xml> as output file (extension .xml mandatory)\n";
+
+static File *out = 0;
+static int xmllite = 0;
+
+
+class XML:public Language {
+public:
+
+ int indent_level;
+ long id;
+
+ XML() :indent_level(0) , id(0) {
+ }
+
+ virtual ~ XML() {
+ }
+
+ virtual void main(int argc, char *argv[]) {
+ SWIG_typemap_lang("xml");
+ for (int iX = 0; iX < argc; iX++) {
+ if (strcmp(argv[iX], "-xml") == 0) {
+ char *extension = 0;
+ if (iX + 1 >= argc)
+ continue;
+ 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", SWIG_output_files());
+ if (!out) {
+ FileErrorDisplay(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, stdout);
+ }
+ if (strcmp(argv[iX], "-xmllite") == 0) {
+ Swig_mark_arg(iX);
+ xmllite = 1;
+ }
+ }
+
+ // Add a symbol to the parser for conditional compilation
+ Preprocessor_define("SWIGXML 1", 0);
+ }
+
+ /* Top of the parse tree */
+
+ virtual int top(Node *n) {
+ if (out == 0) {
+ String *outfile = Getattr(n, "outfile");
+ Replaceall(outfile, ".cxx", ".xml");
+ Replaceall(outfile, ".cpp", ".xml");
+ Replaceall(outfile, ".c", ".xml");
+ out = NewFile(outfile, "w", SWIG_output_files());
+ if (!out) {
+ FileErrorDisplay(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;
+ Iterator ki;
+ ki = First(obj);
+ while (ki.key) {
+ k = ki.key;
+ 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 (!xmllite && Cmp(k, "typescope") == 0) {
+ Xml_print_typescope(Getattr(obj, k));
+ } else if (!xmllite && 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))) {
+ String *ck = NewString(k);
+ o = Str(Getattr(obj, k));
+ Replaceall(ck, ":", "_");
+ Replaceall(ck, "<", "&lt;");
+ /* Do first to avoid aliasing errors. */
+ Replaceall(o, "&", "&amp;");
+ Replaceall(o, "<", "&lt;");
+ Replaceall(o, "\"", "&quot;");
+ Replaceall(o, "\\", "\\\\");
+ Replaceall(o, "\n", "&#10;");
+ Printf(out, "<attribute name=\"%s\" value=\"%s\" id=\"%ld\" addr=\"%x\" />\n", ck, o, ++id, o);
+ Delete(o);
+ Delete(ck);
+ } else {
+ o = Getattr(obj, k);
+ String *ck = NewString(k);
+ Replaceall(ck, ":", "_");
+ Printf(out, "<attribute name=\"%s\" value=\"%x\" id=\"%ld\" addr=\"%x\" />\n", ck, o, ++id, o);
+ Delete(ck);
+ }
+ }
+ ki = Next(ki);
+ }
+ 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;
+ Iterator s;
+ for (s = First(p); s.item; s = Next(s)) {
+ print_indent(0);
+ String *item_name = Xml_escape_string(s.item);
+ Printf(out, "<base name=\"%s\" id=\"%ld\" addr=\"%x\" />\n", item_name, ++id, s.item);
+ Delete(item_name);
+ }
+ indent_level -= 4;
+ print_indent(0);
+ Printf(out, "</baselist >\n");
+ }
+
+ String *Xml_escape_string(String *str) {
+ String *escaped_str = 0;
+ if (str) {
+ escaped_str = NewString(str);
+ Replaceall(escaped_str, "&", "&amp;");
+ Replaceall(escaped_str, "<", "&lt;");
+ Replaceall(escaped_str, "\"", "&quot;");
+ Replaceall(escaped_str, "\\", "\\\\");
+ Replaceall(escaped_str, "\n", "&#10;");
+ }
+ return escaped_str;
+ }
+
+ 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;
+ Iterator n = First(p);
+ while (n.key) {
+ print_indent(0);
+ Printf(out, "<%ssitem id=\"%ld\" addr=\"%x\" >\n", markup, ++id, n.item);
+ Xml_print_attributes(n.item);
+ print_indent(0);
+ Printf(out, "</%ssitem >\n", markup);
+ n = Next(n);
+ }
+ indent_level -= 4;
+ print_indent(0);
+ Printf(out, "</%s >\n", markup);
+ }
+
+};
+
+/* -----------------------------------------------------------------------------
+ * Swig_print_xml
+ *
+ * Dump an XML version of the parse tree. This is different from using the -xml
+ * language module normally as it allows the real language module to process the
+ * tree first, possibly stuffing in new attributes, so the XML that is output ends
+ * up being a post-processing version of the tree.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_print_xml(DOH *obj, String *filename) {
+ XML xml;
+ xmllite = 1;
+
+ if (!filename) {
+ out = stdout;
+ } else {
+ out = NewFile(filename, "w", SWIG_output_files());
+ if (!out) {
+ FileErrorDisplay(filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+
+ Printf(out, "<?xml version=\"1.0\" ?> \n");
+ xml.Xml_print_tree(obj);
+}
+
+static Language *new_swig_xml() {
+ return new XML();
+}
+extern "C" Language *swig_xml(void) {
+ return new_swig_xml();
+}
diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c
new file mode 100644
index 0000000..b456b5e
--- /dev/null
+++ b/Source/Preprocessor/cpp.c
@@ -0,0 +1,1854 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * cpp.c
+ *
+ * An implementation of a C preprocessor plus some support for additional
+ * SWIG directives.
+ *
+ * - SWIG directives such as %include, %extern, and %import are handled
+ * - A new macro %define ... %enddef can be used for multiline macros
+ * - No preprocessing is performed in %{ ... %} blocks
+ * - Lines beginning with %# are stripped down to #... and passed through.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_cpp_c[] = "$Id: cpp.c 11098 2009-01-30 10:32:59Z bhy $";
+
+#include "swig.h"
+#include "preprocessor.h"
+#include <ctype.h>
+
+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 imported_depth = 0; /* Depth of %imported files */
+static int single_include = 1; /* Only include each file once */
+static Hash *included_files = 0;
+static List *dependencies = 0;
+static Scanner *id_scan = 0;
+static int error_as_warning = 0; /* Understand the cpp #error directive as a special #warning */
+
+/* Test a character to see if it starts an identifier */
+#define isidentifier(c) ((isalpha(c)) || (c == '_') || (c == '$'))
+
+/* Test a character to see if it valid in an identifier (after the first letter) */
+#define isidchar(c) ((isalnum(c)) || (c == '_') || (c == '$'))
+
+DOH *Preprocessor_replace(DOH *);
+
+/* Skip whitespace */
+static void skip_whitespace(String *s, String *out) {
+ int c;
+ while ((c = Getc(s)) != EOF) {
+ if (!isspace(c)) {
+ Ungetc(c, s);
+ break;
+ } else if (out)
+ Putc(c, out);
+ }
+}
+
+/* Skip to a specified character taking line breaks into account */
+static int skip_tochar(String *s, int ch, String *out) {
+ int c;
+ while ((c = Getc(s)) != EOF) {
+ if (out)
+ Putc(c, out);
+ if (c == ch)
+ break;
+ if (c == '\\') {
+ c = Getc(s);
+ if ((c != EOF) && (out))
+ Putc(c, out);
+ }
+ }
+ if (c == EOF)
+ return -1;
+ return 0;
+}
+
+static void copy_location(const DOH *s1, DOH *s2) {
+ Setfile(s2, Getfile((DOH *) s1));
+ Setline(s2, Getline((DOH *) s1));
+}
+
+static String *cpp_include(const_String_or_char_ptr fn, int sysfile) {
+ String *s = sysfile ? Swig_include_sys(fn) : Swig_include(fn);
+ if (s && single_include) {
+ String *file = Getfile(s);
+ if (Getattr(included_files, file)) {
+ Delete(s);
+ return 0;
+ }
+ Setattr(included_files, file, file);
+ }
+ if (!s) {
+ /* XXX(bhy) may not need the seek */
+ /* Seek(fn, 0, SEEK_SET); */
+ 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 {
+ String *lf;
+ Seek(s, 0, SEEK_SET);
+ if (!dependencies) {
+ dependencies = NewList();
+ }
+ lf = Copy(Swig_last_file());
+ Append(dependencies, lf);
+ Delete(lf);
+ }
+ return s;
+}
+
+List *Preprocessor_depend(void) {
+ return dependencies;
+}
+
+/* -----------------------------------------------------------------------------
+ * void Preprocessor_cpp_init() - Initialize the preprocessor
+ * ----------------------------------------------------------------------------- */
+static String *kpp_args = 0;
+static String *kpp_define = 0;
+static String *kpp_defined = 0;
+static String *kpp_elif = 0;
+static String *kpp_else = 0;
+static String *kpp_endif = 0;
+static String *kpp_expanded = 0;
+static String *kpp_if = 0;
+static String *kpp_ifdef = 0;
+static String *kpp_ifndef = 0;
+static String *kpp_name = 0;
+static String *kpp_swigmacro = 0;
+static String *kpp_symbols = 0;
+static String *kpp_undef = 0;
+static String *kpp_value = 0;
+static String *kpp_varargs = 0;
+static String *kpp_error = 0;
+static String *kpp_warning = 0;
+static String *kpp_line = 0;
+static String *kpp_include = 0;
+static String *kpp_pragma = 0;
+static String *kpp_level = 0;
+
+static String *kpp_dline = 0;
+static String *kpp_ddefine = 0;
+static String *kpp_dinclude = 0;
+static String *kpp_dimport = 0;
+static String *kpp_dextern = 0;
+
+static String *kpp_LINE = 0;
+static String *kpp_FILE = 0;
+
+void Preprocessor_init(void) {
+ Hash *s;
+
+ kpp_args = NewString("args");
+ kpp_define = NewString("define");
+ kpp_defined = NewString("defined");
+ kpp_else = NewString("else");
+ kpp_elif = NewString("elif");
+ kpp_endif = NewString("endif");
+ kpp_expanded = NewString("*expanded*");
+ kpp_if = NewString("if");
+ kpp_ifdef = NewString("ifdef");
+ kpp_ifndef = NewString("ifndef");
+ kpp_name = NewString("name");
+ kpp_swigmacro = NewString("swigmacro");
+ kpp_symbols = NewString("symbols");
+ kpp_undef = NewString("undef");
+ kpp_value = NewString("value");
+ kpp_error = NewString("error");
+ kpp_warning = NewString("warning");
+ kpp_pragma = NewString("pragma");
+ kpp_level = NewString("level");
+ kpp_line = NewString("line");
+ kpp_include = NewString("include");
+ kpp_varargs = NewString("varargs");
+
+ kpp_dinclude = NewString("%include");
+ kpp_dimport = NewString("%import");
+ kpp_dextern = NewString("%extern");
+ kpp_ddefine = NewString("%define");
+ kpp_dline = NewString("%line");
+
+
+ kpp_LINE = NewString("__LINE__");
+ kpp_FILE = NewString("__FILE__");
+
+ cpp = NewHash();
+ s = NewHash();
+ Setattr(cpp, kpp_symbols, s);
+ Delete(s);
+ Preprocessor_expr_init(); /* Initialize the expression evaluator */
+ included_files = NewHash();
+
+ id_scan = NewScanner();;
+
+}
+
+void Preprocessor_delete(void) {
+ Delete(kpp_args);
+ Delete(kpp_define);
+ Delete(kpp_defined);
+ Delete(kpp_else);
+ Delete(kpp_elif);
+ Delete(kpp_endif);
+ Delete(kpp_expanded);
+ Delete(kpp_if);
+ Delete(kpp_ifdef);
+ Delete(kpp_ifndef);
+ Delete(kpp_name);
+ Delete(kpp_swigmacro);
+ Delete(kpp_symbols);
+ Delete(kpp_undef);
+ Delete(kpp_value);
+ Delete(kpp_error);
+ Delete(kpp_warning);
+ Delete(kpp_pragma);
+ Delete(kpp_level);
+ Delete(kpp_line);
+ Delete(kpp_include);
+ Delete(kpp_varargs);
+
+ Delete(kpp_dinclude);
+ Delete(kpp_dimport);
+ Delete(kpp_dextern);
+ Delete(kpp_ddefine);
+ Delete(kpp_dline);
+
+
+ Delete(kpp_LINE);
+ Delete(kpp_FILE);
+ Delete(cpp);
+ Delete(included_files);
+ Preprocessor_expr_delete();
+ DelScanner(id_scan);
+
+ Delete(dependencies);
+
+ Delete(Swig_add_directory(0));
+}
+
+/* -----------------------------------------------------------------------------
+ * void Preprocessor_include_all() - Instruct preprocessor to include all files
+ * ----------------------------------------------------------------------------- */
+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;
+}
+
+void Preprocessor_error_as_warning(int a) {
+ error_as_warning = a;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Preprocessor_define()
+ *
+ * Defines a new C preprocessor symbol. swigmacro specifies whether or not the macro has
+ * SWIG macro semantics.
+ * ----------------------------------------------------------------------------- */
+
+
+String *Macro_vararg_name(const_String_or_char_ptr str, const_String_or_char_ptr line) {
+ String *argname;
+ String *varargname;
+ char *s, *dots;
+
+ argname = Copy(str);
+ s = Char(argname);
+ dots = strchr(s, '.');
+ if (!dots) {
+ Delete(argname);
+ return NULL;
+ }
+
+ if (strcmp(dots, "...") != 0) {
+ Swig_error(Getfile(line), Getline(line), "Illegal macro argument name '%s'\n", str);
+ Delete(argname);
+ return NULL;
+ }
+ if (dots == s) {
+ varargname = NewString("__VA_ARGS__");
+ } else {
+ *dots = '\0';
+ varargname = NewString(s);
+ }
+ Delete(argname);
+ return varargname;
+}
+
+Hash *Preprocessor_define(const_String_or_char_ptr _str, int swigmacro) {
+ 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 *str;
+
+ assert(cpp);
+ assert(_str);
+
+ /* First make sure that string is actually a string */
+ if (DohCheck(_str)) {
+ s = Copy(_str);
+ copy_location(_str, s);
+ str = s;
+ } else {
+ str = NewString((char *) _str);
+ }
+ Seek(str, 0, SEEK_SET);
+ line = Getline(str);
+ file = Getfile(str);
+
+ /* Skip over any leading whitespace */
+ skip_whitespace(str, 0);
+
+ /* Now look for a macro name */
+ macroname = NewStringEmpty();
+ while ((c = Getc(str)) != EOF) {
+ if (c == '(') {
+ argstr = NewStringEmpty();
+ copy_location(str, argstr);
+ /* It is a macro. Go extract its argument string */
+ while ((c = Getc(str)) != EOF) {
+ if (c == ')')
+ break;
+ else
+ Putc(c, argstr);
+ }
+ if (c != ')') {
+ Swig_error(Getfile(str), Getline(str), "Missing \')\' in macro parameters\n");
+ goto macro_error;
+ }
+ break;
+ } else if (isidchar(c) || (c == '%')) {
+ Putc(c, macroname);
+ } else if (isspace(c)) {
+ break;
+ } else if (c == '\\') {
+ c = Getc(str);
+ if (c != '\n') {
+ Ungetc(c, str);
+ Ungetc('\\', str);
+ break;
+ }
+ } else {
+ /*Swig_error(Getfile(str),Getline(str),"Illegal character in macro name\n");
+ goto macro_error; */
+ Ungetc(c, str);
+ break;
+ }
+ }
+ if (!swigmacro)
+ skip_whitespace(str, 0);
+ macrovalue = NewStringEmpty();
+ while ((c = Getc(str)) != EOF) {
+ Putc(c, macrovalue);
+ }
+
+ /* If there are any macro arguments, convert into a list */
+ if (argstr) {
+ String *argname, *varargname;
+ arglist = NewList();
+ Seek(argstr, 0, SEEK_SET);
+ argname = NewStringEmpty();
+ while ((c = Getc(argstr)) != EOF) {
+ if (c == ',') {
+ varargname = Macro_vararg_name(argname, str);
+ if (varargname) {
+ Delete(varargname);
+ Swig_error(Getfile(str), Getline(str), "Variable-length macro argument must be last parameter\n");
+ } else {
+ Append(arglist, argname);
+ }
+ Delete(argname);
+ argname = NewStringEmpty();
+ } else if (isidchar(c) || (c == '.')) {
+ Putc(c, argname);
+ } else if (!(isspace(c) || (c == '\\'))) {
+ Delete(argname);
+ Swig_error(Getfile(str), Getline(str), "Illegal character in macro argument name\n");
+ goto macro_error;
+ }
+ }
+ if (Len(argname)) {
+ /* Check for varargs */
+ varargname = Macro_vararg_name(argname, str);
+ if (varargname) {
+ Append(arglist, varargname);
+ Delete(varargname);
+ varargs = 1;
+ } else {
+ Append(arglist, argname);
+ }
+ }
+ Delete(argname);
+ }
+
+ 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); */
+ while (strstr(Char(macrovalue), "\001 ")) {
+ Replace(macrovalue, "\001 ", "\001", DOH_REPLACE_ANY);
+ }
+ while (strstr(Char(macrovalue), " \001")) {
+ Replace(macrovalue, " \001", "\001", DOH_REPLACE_ANY);
+ }
+ /* Replace '##' with a special token */
+ Replace(macrovalue, "\001\001", "\002", DOH_REPLACE_ANY);
+ /* Replace '#@' with a special token */
+ Replace(macrovalue, "\001@", "\004", DOH_REPLACE_ANY);
+ /* Replace '##@' with a special token */
+ Replace(macrovalue, "\002@", "\005", DOH_REPLACE_ANY);
+
+ /* Go create the macro */
+ macro = NewHash();
+ Setattr(macro, kpp_name, macroname);
+
+ if (arglist) {
+ Setattr(macro, kpp_args, arglist);
+ Delete(arglist);
+ if (varargs) {
+ Setattr(macro, kpp_varargs, "1");
+ }
+ }
+ Setattr(macro, kpp_value, macrovalue);
+ Setline(macro, line);
+ Setfile(macro, file);
+ if (swigmacro) {
+ Setattr(macro, kpp_swigmacro, "1");
+ }
+ symbols = Getattr(cpp, kpp_symbols);
+ if ((m1 = Getattr(symbols, macroname))) {
+ if (!Checkattr(m1, kpp_value, macrovalue)) {
+ Swig_error(Getfile(str), Getline(str), "Macro '%s' redefined,\n", macroname);
+ Swig_error(Getfile(m1), Getline(m1), "previous definition of '%s'.\n", macroname);
+ goto macro_error;
+ }
+ } else {
+ Setattr(symbols, macroname, macro);
+ Delete(macro);
+ }
+
+ Delete(macroname);
+ Delete(macrovalue);
+
+ Delete(str);
+ Delete(argstr);
+ return macro;
+
+macro_error:
+ Delete(str);
+ Delete(argstr);
+ Delete(arglist);
+ Delete(macroname);
+ Delete(macrovalue);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Preprocessor_undef()
+ *
+ * Undefines a macro.
+ * ----------------------------------------------------------------------------- */
+void Preprocessor_undef(const_String_or_char_ptr str) {
+ Hash *symbols;
+ assert(cpp);
+ symbols = Getattr(cpp, kpp_symbols);
+ Delattr(symbols, str);
+}
+
+/* -----------------------------------------------------------------------------
+ * find_args()
+ *
+ * Isolates macro arguments and returns them in a list. For each argument,
+ * leading and trailing whitespace is stripped (ala K&R, pg. 230).
+ * ----------------------------------------------------------------------------- */
+static List *find_args(String *s) {
+ List *args;
+ String *str;
+ int c, level;
+ long pos;
+
+ /* Create a new list */
+ args = NewList();
+ copy_location(s, args);
+
+ /* First look for a '(' */
+ pos = Tell(s);
+ skip_whitespace(s, 0);
+
+ /* Now see if the next character is a '(' */
+ c = Getc(s);
+ if (c != '(') {
+ /* Not a macro, bail out now! */
+ Seek(s, pos, SEEK_SET);
+ Delete(args);
+ return 0;
+ }
+ c = Getc(s);
+ /* Okay. This appears to be a macro so we will start isolating arguments */
+ while (c != EOF) {
+ if (isspace(c)) {
+ skip_whitespace(s, 0); /* Skip leading whitespace */
+ c = Getc(s);
+ }
+ str = NewStringEmpty();
+ copy_location(s, str);
+ level = 0;
+ while (c != EOF) {
+ if (c == '\"') {
+ Putc(c, str);
+ skip_tochar(s, '\"', str);
+ c = Getc(s);
+ continue;
+ } else if (c == '\'') {
+ Putc(c, str);
+ skip_tochar(s, '\'', str);
+ c = Getc(s);
+ continue;
+ }
+ if ((c == ',') && (level == 0))
+ break;
+ if ((c == ')') && (level == 0))
+ break;
+ Putc(c, str);
+ if (c == '(')
+ level++;
+ if (c == ')')
+ level--;
+ c = Getc(s);
+ }
+ if (level > 0) {
+ goto unterm;
+ }
+ Chop(str);
+ if (Len(args) || Len(str))
+ Append(args, str);
+ Delete(str);
+
+ /* if (Len(str) && (c != ')'))
+ Append(args,str); */
+
+ if (c == ')')
+ return args;
+ c = Getc(s);
+ }
+unterm:
+ Swig_error(Getfile(args), Getline(args), "Unterminated macro call.\n");
+ return args;
+}
+
+/* -----------------------------------------------------------------------------
+ * DOH *get_filename(DOH *str)
+ *
+ * Read a filename from str. A filename can be enclose in quotes, angle brackets,
+ * or bare.
+ * ----------------------------------------------------------------------------- */
+
+static String *get_filename(String *str, int *sysfile) {
+ String *fn;
+ int c;
+
+ skip_whitespace(str, 0);
+ fn = NewStringEmpty();
+ copy_location(str, fn);
+ c = Getc(str);
+ *sysfile = 0;
+ if (c == '\"') {
+ while (((c = Getc(str)) != EOF) && (c != '\"'))
+ Putc(c, fn);
+ } else if (c == '<') {
+ *sysfile = 1;
+ while (((c = Getc(str)) != EOF) && (c != '>'))
+ Putc(c, fn);
+ } else {
+ Putc(c, fn);
+ while (((c = Getc(str)) != EOF) && (!isspace(c)))
+ Putc(c, fn);
+ if (isspace(c))
+ Ungetc(c, str);
+ }
+ Swig_filename_correct(fn);
+ Seek(fn, 0, SEEK_SET);
+ 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()
+ *
+ * Perform macro expansion and return a new string. Returns NULL if some sort
+ * of error occurred.
+ * ----------------------------------------------------------------------------- */
+
+static String *expand_macro(String *name, List *args) {
+ String *ns;
+ DOH *symbols, *macro, *margs, *mvalue, *temp, *tempa, *e;
+ int i, l;
+ int isvarargs = 0;
+
+ symbols = Getattr(cpp, kpp_symbols);
+ if (!symbols)
+ return 0;
+
+ /* See if the name is actually defined */
+ macro = Getattr(symbols, name);
+ if (!macro)
+ return 0;
+ if (Getattr(macro, kpp_expanded)) {
+ ns = NewStringEmpty();
+ Append(ns, name);
+ if (args) {
+ int lenargs = Len(args);
+ if (lenargs)
+ Putc('(', ns);
+ for (i = 0; i < lenargs; i++) {
+ Append(ns, Getitem(args, i));
+ if (i < (lenargs - 1))
+ Putc(',', ns);
+ }
+ if (i)
+ Putc(')', ns);
+ }
+ return ns;
+ }
+
+ /* Get macro arguments and value */
+ mvalue = Getattr(macro, kpp_value);
+ assert(mvalue);
+ margs = Getattr(macro, kpp_args);
+
+ if (args && Getattr(macro, kpp_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 = NewStringEmpty();
+ 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 (args && (margs) && (Len(margs) != Len(args))) {
+ 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
+ Swig_error(Getfile(args), Getline(args), "Macro '%s' expects no arguments\n", name);
+ return 0;
+ }
+
+ /* If the macro expects arguments, but none were supplied, we leave it in place */
+ if (!args && (margs) && Len(margs) > 0) {
+ return NewString(name);
+ }
+
+ /* Copy the macro value */
+ ns = Copy(mvalue);
+ copy_location(mvalue, ns);
+
+ /* Tag the macro as being expanded. This is to avoid recursion in
+ macro expansion */
+
+ temp = NewStringEmpty();
+ tempa = NewStringEmpty();
+ if (args && margs) {
+ l = Len(margs);
+ for (i = 0; i < l; i++) {
+ DOH *arg, *aname;
+ String *reparg;
+ arg = Getitem(args, i); /* Get an argument value */
+ reparg = Preprocessor_replace(arg);
+ aname = Getitem(margs, i); /* Get macro argument name */
+ if (strstr(Char(ns), "\001")) {
+ /* Try to replace a quoted version of the argument */
+ Clear(temp);
+ Clear(tempa);
+ Printf(temp, "\001%s", aname);
+ Printf(tempa, "\"%s\"", arg);
+ Replace(ns, temp, tempa, DOH_REPLACE_ID_END);
+ }
+ if (strstr(Char(ns), "\002")) {
+ /* Look for concatenation tokens */
+ Clear(temp);
+ Clear(tempa);
+ Printf(temp, "\002%s", aname);
+ Append(tempa, "\002\003");
+ Replace(ns, temp, tempa, DOH_REPLACE_ID_END);
+ Clear(temp);
+ Clear(tempa);
+ Printf(temp, "%s\002", aname);
+ Append(tempa, "\003\002");
+ Replace(ns, temp, tempa, DOH_REPLACE_ID_BEGIN);
+ }
+
+ /* Non-standard macro expansion. The value `x` is replaced by a quoted
+ version of the argument except that if the argument is already quoted
+ nothing happens */
+
+ if (strchr(Char(ns), '`')) {
+ String *rep;
+ char *c;
+ Clear(temp);
+ Printf(temp, "`%s`", aname);
+ c = Char(arg);
+ if (*c == '\"') {
+ rep = arg;
+ } else {
+ Clear(tempa);
+ Printf(tempa, "\"%s\"", arg);
+ rep = tempa;
+ }
+ Replace(ns, temp, rep, DOH_REPLACE_ANY);
+ }
+
+ /* Non-standard mangle expansions.
+ The #@Name is replaced by mangle_arg(Name). */
+ if (strstr(Char(ns), "\004")) {
+ String *marg = Swig_string_mangle(arg);
+ Clear(temp);
+ Printf(temp, "\004%s", aname);
+ Replace(ns, temp, marg, DOH_REPLACE_ID_END);
+ Delete(marg);
+ }
+ if (strstr(Char(ns), "\005")) {
+ String *marg = Swig_string_mangle(arg);
+ Clear(temp);
+ Clear(tempa);
+ Printf(temp, "\005%s", aname);
+ Printf(tempa, "\"%s\"", marg);
+ Replace(ns, temp, tempa, DOH_REPLACE_ID_END);
+ Delete(marg);
+ }
+
+ if (isvarargs && i == l - 1 && Len(arg) == 0) {
+ /* Zero length varargs macro argument. We search for commas that might appear before and nuke them */
+ char *a, *s, *t, *name;
+ int namelen;
+ s = Char(ns);
+ name = Char(aname);
+ namelen = Len(aname);
+ a = strstr(s, name);
+ while (a) {
+ char ca = a[namelen + 1];
+ if (!isidchar((int) ca)) {
+ /* Matched the entire vararg name, not just a prefix */
+ t = a - 1;
+ if (*t == '\002') {
+ t--;
+ while (t >= s) {
+ if (isspace((int) *t))
+ t--;
+ else if (*t == ',') {
+ *t = ' ';
+ } else
+ break;
+ }
+ }
+ }
+ a = strstr(a + namelen, name);
+ }
+ }
+ /* Replace(ns, aname, arg, DOH_REPLACE_ID); */
+ Replace(ns, aname, reparg, DOH_REPLACE_ID); /* Replace expanded args */
+ Replace(ns, "\003", arg, DOH_REPLACE_ANY); /* Replace unexpanded arg */
+ Delete(reparg);
+ }
+ }
+ Replace(ns, "\002", "", DOH_REPLACE_ANY); /* Get rid of concatenation tokens */
+ Replace(ns, "\001", "#", DOH_REPLACE_ANY); /* Put # back (non-standard C) */
+ Replace(ns, "\004", "#@", DOH_REPLACE_ANY); /* Put # back (non-standard C) */
+
+ /* Expand this macro even further */
+ Setattr(macro, kpp_expanded, "1");
+
+ e = Preprocessor_replace(ns);
+
+ Delattr(macro, kpp_expanded);
+ Delete(ns);
+
+ if (Getattr(macro, kpp_swigmacro)) {
+ String *g;
+ String *f = NewStringEmpty();
+ Seek(e, 0, SEEK_SET);
+ copy_location(macro, e);
+ g = Preprocessor_parse(e);
+
+#if 0
+ /* Drop the macro in place, but with a marker around it */
+ Printf(f, "/*@%s,%d,%s@*/%s/*@@*/", Getfile(macro), Getline(macro), name, g);
+#else
+ /* Use simplified around markers to properly count lines in cscanner.c */
+ if (strchr(Char(g), '\n')) {
+ Printf(f, "/*@SWIG:%s,%d,%s@*/%s/*@SWIG@*/", Getfile(macro), Getline(macro), name, g);
+#if 0
+ Printf(f, "/*@SWIG:%s@*/%s/*@SWIG@*/", name, g);
+#endif
+ } else {
+ Append(f, g);
+ }
+#endif
+
+ Delete(g);
+ Delete(e);
+ e = f;
+ }
+ Delete(temp);
+ Delete(tempa);
+ return e;
+}
+
+/* -----------------------------------------------------------------------------
+ * evaluate_args()
+ *
+ * Evaluate the arguments of a macro
+ * ----------------------------------------------------------------------------- */
+
+List *evaluate_args(List *x) {
+ Iterator i;
+ List *nl = NewList();
+
+ for (i = First(x); i.item; i = Next(i)) {
+ Append(nl, Preprocessor_replace(i.item));
+ }
+ return nl;
+}
+
+/* -----------------------------------------------------------------------------
+ * DOH *Preprocessor_replace(DOH *s)
+ *
+ * Performs a macro substitution on a string s. Returns a new string with
+ * substitutions applied. This function works by walking down s and looking
+ * for identifiers. When found, a check is made to see if they are macros
+ * which are then expanded.
+ * ----------------------------------------------------------------------------- */
+
+/* #define SWIG_PUT_BUFF */
+
+DOH *Preprocessor_replace(DOH *s) {
+ DOH *ns, *symbols, *m;
+ int c, i, state = 0;
+
+ String *id = NewStringEmpty();
+
+ assert(cpp);
+ symbols = Getattr(cpp, kpp_symbols);
+
+ ns = NewStringEmpty();
+ copy_location(s, ns);
+ Seek(s, 0, SEEK_SET);
+
+ /* Try to locate identifiers in s and replace them with macro replacements */
+ while ((c = Getc(s)) != EOF) {
+ switch (state) {
+ case 0:
+ if (isidentifier(c) || (c == '%')) {
+ Clear(id);
+ Putc(c, id);
+ state = 1;
+ } else if (c == '\"') {
+ Putc(c, ns);
+ skip_tochar(s, '\"', ns);
+ } else if (c == '\'') {
+ Putc(c, ns);
+ skip_tochar(s, '\'', ns);
+ } else if (c == '/') {
+ Putc(c, ns);
+ state = 10;
+ } else {
+ Putc(c, ns);
+ }
+ break;
+ case 1: /* An identifier */
+ if (isidchar(c)) {
+ Putc(c, id);
+ state = 1;
+ } else {
+ /* We found the end of a valid identifier */
+ Ungetc(c, s);
+ /* See if this is the special "defined" macro */
+ if (Equal(kpp_defined, id)) {
+ int lenargs = 0;
+ DOH *args = 0;
+ /* See whether or not a paranthesis has been used */
+ skip_whitespace(s, 0);
+ c = Getc(s);
+ if (c == '(') {
+ Ungetc(c, s);
+ args = find_args(s);
+ } else if (isidchar(c)) {
+ DOH *arg = NewStringEmpty();
+ args = NewList();
+ Putc(c, arg);
+ while (((c = Getc(s)) != EOF)) {
+ if (!isidchar(c)) {
+ Ungetc(c, s);
+ break;
+ }
+ Putc(c, arg);
+ }
+ if (Len(arg))
+ Append(args, arg);
+ Delete(arg);
+ } else {
+ Seek(s, -1, SEEK_CUR);
+ }
+ lenargs = Len(args);
+ if ((!args) || (!lenargs)) {
+ /* This is not a defined() macro. */
+ Append(ns, id);
+ state = 0;
+ break;
+ }
+ for (i = 0; i < lenargs; i++) {
+ DOH *o = Getitem(args, i);
+ if (!Getattr(symbols, o)) {
+ break;
+ }
+ }
+ if (i < lenargs)
+ Putc('0', ns);
+ else
+ Putc('1', ns);
+ Delete(args);
+ state = 0;
+ break;
+ }
+ if (Equal(kpp_LINE, id)) {
+ Printf(ns, "%d", Getline(s));
+ state = 0;
+ break;
+ }
+ if (Equal(kpp_FILE, id)) {
+ String *fn = Copy(Getfile(s));
+ Replaceall(fn, "\\", "\\\\");
+ Printf(ns, "\"%s\"", fn);
+ Delete(fn);
+ state = 0;
+ break;
+ }
+ /* See if the macro is defined in the preprocessor symbol table */
+ if ((m = Getattr(symbols, id))) {
+ DOH *args = 0;
+ DOH *e;
+ /* See if the macro expects arguments */
+ if (Getattr(m, kpp_args)) {
+ /* Yep. We need to go find the arguments and do a substitution */
+ args = find_args(s);
+ if (!Len(args)) {
+ Delete(args);
+ args = 0;
+ }
+ } else {
+ args = 0;
+ }
+ e = expand_macro(id, args);
+ if (e) {
+ Append(ns, e);
+ }
+ Delete(e);
+ Delete(args);
+ } else {
+ Append(ns, id);
+ }
+ state = 0;
+ }
+ break;
+ case 10:
+ if (c == '/')
+ state = 11;
+ else if (c == '*')
+ state = 12;
+ else {
+ Ungetc(c, s);
+ state = 0;
+ break;
+ }
+ Putc(c, ns);
+ break;
+ case 11:
+ Putc(c, ns);
+ if (c == '\n')
+ state = 0;
+ break;
+ case 12:
+ Putc(c, ns);
+ if (c == '*')
+ state = 13;
+ break;
+ case 13:
+ Putc(c, ns);
+ if (c == '/')
+ state = 0;
+ else if (c != '*')
+ state = 12;
+ break;
+ default:
+ state = 0;
+ break;
+ }
+ }
+
+ /* Identifier at the end */
+ if (state == 1) {
+ /* See if this is the special "defined" macro */
+ if (Equal(kpp_defined, id)) {
+ Swig_error(Getfile(s), Getline(s), "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")) {
+ Swig_error(Getfile(id),Getline(id),"Macro arguments expected.\n");
+ } */
+ e = expand_macro(id, 0);
+ Append(ns, e);
+ Delete(e);
+ } else {
+ Append(ns, id);
+ }
+ }
+ Delete(id);
+ return ns;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * int checkpp_id(DOH *s)
+ *
+ * Checks the string s to see if it contains any unresolved identifiers. This
+ * function contains the heuristic that determines whether or not a macro
+ * definition passes through the preprocessor as a constant declaration.
+ * ----------------------------------------------------------------------------- */
+static int checkpp_id(DOH *s) {
+ int c;
+ int hastok = 0;
+ Scanner *scan = id_scan;
+
+ Seek(s, 0, SEEK_SET);
+
+ Scanner_clear(scan);
+ s = Copy(s);
+ Seek(s, SEEK_SET, 0);
+ Scanner_push(scan, s);
+ while ((c = Scanner_token(scan))) {
+ hastok = 1;
+ if ((c == SWIG_TOKEN_ID) || (c == SWIG_TOKEN_LBRACE) || (c == SWIG_TOKEN_RBRACE))
+ return 1;
+ }
+ if (!hastok)
+ return 1;
+ return 0;
+}
+
+/* addline(). Utility function for adding lines to a chunk */
+static void addline(DOH *s1, DOH *s2, int allow) {
+ if (allow) {
+ Append(s1, s2);
+ } else {
+ char *c = Char(s2);
+ while (*c) {
+ if (*c == '\n')
+ Putc('\n', s1);
+ c++;
+ }
+ }
+}
+
+static void add_chunk(DOH *ns, DOH *chunk, int allow) {
+ DOH *echunk;
+ Seek(chunk, 0, SEEK_SET);
+ if (allow) {
+ echunk = Preprocessor_replace(chunk);
+ addline(ns, echunk, allow);
+ Delete(echunk);
+ } else {
+ addline(ns, chunk, 0);
+ }
+ Clear(chunk);
+}
+
+/*
+ push/pop_imported(): helper functions for defining and undefining
+ SWIGIMPORTED (when %importing a file).
+ */
+static void push_imported() {
+ if (imported_depth == 0) {
+ Preprocessor_define("SWIGIMPORTED 1", 0);
+ }
+ ++imported_depth;
+}
+
+static void pop_imported() {
+ --imported_depth;
+ if (imported_depth == 0) {
+ Preprocessor_undef("SWIGIMPORTED");
+ }
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Preprocessor_parse()
+ *
+ * Parses the string s. Returns a new string containing the preprocessed version.
+ *
+ * Parsing rules :
+ * 1. Lines starting with # are C preprocessor directives
+ * 2. Macro expansion inside strings is not allowed
+ * 3. All code inside false conditionals is changed to blank lines
+ * 4. Code in %{, %} is not parsed because it may need to be
+ * included inline (with all preprocessor directives included).
+ * ----------------------------------------------------------------------------- */
+
+String *Preprocessor_parse(String *s) {
+ String *ns; /* New string containing the preprocessed text */
+ String *chunk, *decl;
+ Hash *symbols;
+ String *id = 0, *value = 0, *comment = 0;
+ int i, state, e, c;
+ int start_line = 0;
+ int allow = 1;
+ int level = 0;
+ int dlevel = 0;
+ int mask = 0;
+ int start_level = 0;
+ int cpp_lines = 0;
+ int cond_lines[256];
+
+ /* Blow away all carriage returns */
+ Replace(s, "\015", "", DOH_REPLACE_ANY);
+
+ ns = NewStringEmpty(); /* Return result */
+
+ decl = NewStringEmpty();
+ id = NewStringEmpty();
+ value = NewStringEmpty();
+ comment = NewStringEmpty();
+ chunk = NewStringEmpty();
+ copy_location(s, chunk);
+ copy_location(s, ns);
+ symbols = Getattr(cpp, kpp_symbols);
+
+ state = 0;
+ while ((c = Getc(s)) != EOF) {
+ switch (state) {
+ case 0: /* Initial state - in first column */
+ /* Look for C preprocessor directives. Otherwise, go directly to state 1 */
+ if (c == '#') {
+ add_chunk(ns, chunk, allow);
+ copy_location(s, chunk);
+ cpp_lines = 1;
+ state = 40;
+ } else if (isspace(c)) {
+ Putc(c, chunk);
+ skip_whitespace(s, chunk);
+ } else {
+ state = 1;
+ Ungetc(c, s);
+ }
+ break;
+ case 1: /* Non-preprocessor directive */
+ /* Look for SWIG directives */
+ if (c == '%') {
+ state = 100;
+ break;
+ }
+ Putc(c, chunk);
+ if (c == '\n')
+ state = 0;
+ else if (c == '\"') {
+ start_line = Getline(s);
+ if (skip_tochar(s, '\"', chunk) < 0) {
+ 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) {
+ Swig_error(Getfile(s), -1, "Unterminated character constant starting at line %d\n", start_line);
+ }
+ } else if (c == '/')
+ state = 30; /* Comment */
+ break;
+
+ case 30: /* Possibly a comment string of some sort */
+ start_line = Getline(s);
+ Putc(c, chunk);
+ if (c == '/')
+ state = 31;
+ else if (c == '*')
+ state = 32;
+ else
+ state = 1;
+ break;
+ case 31:
+ Putc(c, chunk);
+ if (c == '\n')
+ state = 0;
+ break;
+ case 32:
+ Putc(c, chunk);
+ if (c == '*')
+ state = 33;
+ break;
+ case 33:
+ Putc(c, chunk);
+ if (c == '/')
+ state = 1;
+ else if (c != '*')
+ state = 32;
+ break;
+
+ case 40: /* Start of a C preprocessor directive */
+ if (c == '\n') {
+ Putc('\n', chunk);
+ state = 0;
+ } else if (isspace(c)) {
+ state = 40;
+ } else {
+ /* Got the start of a preprocessor directive */
+ Ungetc(c, s);
+ Clear(id);
+ copy_location(s, id);
+ state = 41;
+ }
+ break;
+
+ case 41: /* Build up the name of the preprocessor directive */
+ if ((isspace(c) || (!isalpha(c)))) {
+ Clear(value);
+ Clear(comment);
+ if (c == '\n') {
+ Ungetc(c, s);
+ state = 50;
+ } else {
+ state = 42;
+ if (!isspace(c)) {
+ Ungetc(c, s);
+ }
+ }
+
+ copy_location(s, value);
+ break;
+ }
+ Putc(c, id);
+ break;
+
+ case 42: /* Strip any leading space before preprocessor value */
+ if (isspace(c)) {
+ if (c == '\n') {
+ Ungetc(c, s);
+ state = 50;
+ }
+ break;
+ }
+ state = 43;
+ /* no break intended here */
+
+ case 43:
+ /* Get preprocessor value */
+ if (c == '\n') {
+ Ungetc(c, 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;
+ }
+ break;
+
+ case 44:
+ if (c == '\n') {
+ Putc(c, value);
+ cpp_lines++;
+ } else {
+ Ungetc(c, s);
+ }
+ state = 43;
+ break;
+
+ /* States 45-48 are used to remove, but retain comments from macro values. The comments
+ will be placed in the output in an alternative form */
+
+ case 45:
+ if (c == '/')
+ state = 46;
+ else if (c == '*')
+ state = 47;
+ else if (c == '\n') {
+ Putc('/', value);
+ Ungetc(c, s);
+ cpp_lines++;
+ state = 50;
+ } else {
+ Putc('/', value);
+ Putc(c, value);
+ state = 43;
+ }
+ break;
+ case 46:
+ if (c == '\n') {
+ Ungetc(c, s);
+ cpp_lines++;
+ state = 50;
+ } else
+ Putc(c, comment);
+ break;
+ case 47:
+ if (c == '*')
+ state = 48;
+ else
+ Putc(c, comment);
+ break;
+ case 48:
+ if (c == '/')
+ state = 43;
+ else if (c == '*')
+ Putc(c, comment);
+ else {
+ Putc('*', comment);
+ Putc(c, comment);
+ state = 47;
+ }
+ break;
+ case 50:
+ /* Check for various preprocessor directives */
+ Chop(value);
+ if (Equal(id, kpp_define)) {
+ if (allow) {
+ DOH *m, *v, *v1;
+ Seek(value, 0, SEEK_SET);
+ m = Preprocessor_define(value, 0);
+ if ((m) && !(Getattr(m, kpp_args))) {
+ v = Copy(Getattr(m, kpp_value));
+ if (Len(v)) {
+ Swig_error_silent(1);
+ v1 = Preprocessor_replace(v);
+ Swig_error_silent(0);
+ /* Printf(stdout,"checking '%s'\n", v1); */
+ if (!checkpp_id(v1)) {
+ if (Len(comment) == 0)
+ Printf(ns, "%%constant %s = %s;\n", Getattr(m, kpp_name), v1);
+ else
+ Printf(ns, "%%constant %s = %s; /*%s*/\n", Getattr(m, kpp_name), v1, comment);
+ cpp_lines--;
+ }
+ Delete(v1);
+ }
+ Delete(v);
+ }
+ }
+ } else if (Equal(id, kpp_undef)) {
+ if (allow)
+ Preprocessor_undef(value);
+ } else if (Equal(id, kpp_ifdef)) {
+ cond_lines[level] = Getline(id);
+ level++;
+ if (allow) {
+ start_level = level;
+ /* See if the identifier is in the hash table */
+ if (!Getattr(symbols, value))
+ allow = 0;
+ mask = 1;
+ }
+ } else if (Equal(id, kpp_ifndef)) {
+ cond_lines[level] = Getline(id);
+ level++;
+ if (allow) {
+ start_level = level;
+ /* See if the identifier is in the hash table */
+ if (Getattr(symbols, value))
+ allow = 0;
+ mask = 1;
+ }
+ } else if (Equal(id, kpp_else)) {
+ if (level <= 0) {
+ 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 * mask;
+ }
+ }
+ } else if (Equal(id, kpp_endif)) {
+ level--;
+ if (level < 0) {
+ Swig_error(Getfile(id), Getline(id), "Extraneous #endif.\n");
+ level = 0;
+ } else {
+ if (level < start_level) {
+ allow = 1;
+ start_level--;
+ }
+ }
+ } else if (Equal(id, kpp_if)) {
+ cond_lines[level] = Getline(id);
+ level++;
+ if (allow) {
+ int val;
+ String *sval = Preprocessor_replace(value);
+ start_level = level;
+ Seek(sval, 0, SEEK_SET);
+ /* Printf(stdout,"Evaluating '%s'\n", sval); */
+ val = Preprocessor_expr(sval, &e);
+ if (e) {
+ char *msg = Preprocessor_expr_error();
+ Seek(value, 0, SEEK_SET);
+ Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Could not evaluate '%s'\n", value);
+ if (msg)
+ Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Error: '%s'\n", msg);
+ allow = 0;
+ } else {
+ if (val == 0)
+ allow = 0;
+ }
+ mask = 1;
+ }
+ } else if (Equal(id, kpp_elif)) {
+ if (level == 0) {
+ Swig_error(Getfile(s), Getline(id), "Misplaced #elif.\n");
+ } else {
+ cond_lines[level - 1] = Getline(id);
+ if (allow) {
+ allow = 0;
+ mask = 0;
+ } else if (level == start_level) {
+ int val;
+ String *sval = Preprocessor_replace(value);
+ Seek(sval, 0, SEEK_SET);
+ val = Preprocessor_expr(sval, &e);
+ if (e) {
+ char *msg = Preprocessor_expr_error();
+ Seek(value, 0, SEEK_SET);
+ Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Could not evaluate '%s'\n", value);
+ if (msg)
+ Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Error: '%s'\n", msg);
+ allow = 0;
+ } else {
+ if (val)
+ allow = 1 * mask;
+ else
+ allow = 0;
+ }
+ }
+ }
+ } else if (Equal(id, kpp_warning)) {
+ if (allow) {
+ Swig_warning(WARN_PP_CPP_WARNING, Getfile(s), Getline(id), "CPP #warning, %s\n", value);
+ }
+ } else if (Equal(id, kpp_error)) {
+ if (allow) {
+ if (error_as_warning) {
+ Swig_warning(WARN_PP_CPP_ERROR, Getfile(s), Getline(id), "CPP #error \"%s\".\n", value);
+ } else {
+ Swig_error(Getfile(s), Getline(id), "CPP #error \"%s\". Use the -cpperraswarn option to continue swig processing.\n", value);
+ }
+ }
+ } else if (Equal(id, kpp_line)) {
+ } else if (Equal(id, kpp_include)) {
+ if (((include_all) || (import_all)) && (allow)) {
+ String *s1, *s2, *fn;
+ char *dirname;
+ int sysfile = 0;
+ if (include_all && import_all) {
+ Swig_warning(WARN_PP_INCLUDEALL_IMPORTALL, Getfile(s), Getline(id), "Both includeall and importall are defined: using includeall\n");
+ import_all = 0;
+ }
+ Seek(value, 0, SEEK_SET);
+ fn = get_filename(value, &sysfile);
+ s1 = cpp_include(fn, sysfile);
+ if (s1) {
+ if (include_all)
+ Printf(ns, "%%includefile \"%s\" [\n", Swig_last_file());
+ else if (import_all) {
+ Printf(ns, "%%importfile \"%s\" [\n", Swig_last_file());
+ push_imported();
+ }
+
+ /* See if the filename has a directory component */
+ dirname = Swig_file_dirname(Swig_last_file());
+ if (sysfile || !strlen(dirname))
+ dirname = 0;
+ if (dirname) {
+ dirname[strlen(dirname) - 1] = 0; /* Kill trailing directory delimiter */
+ Swig_push_directory(dirname);
+ }
+ s2 = Preprocessor_parse(s1);
+ addline(ns, s2, allow);
+ Append(ns, "\n]");
+ if (dirname) {
+ Swig_pop_directory();
+ }
+ if (import_all) {
+ pop_imported();
+ }
+ Delete(s2);
+ }
+ Delete(s1);
+ Delete(fn);
+ }
+ } else if (Equal(id, kpp_pragma)) {
+ 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) {
+ String *val = NewString(c + 7);
+ String *nowarn = Preprocessor_replace(val);
+ Swig_warnfilter(nowarn, 1);
+ Delete(nowarn);
+ Delete(val);
+ } else if (strncmp(c, "cpperraswarn=", 13) == 0) {
+ error_as_warning = atoi(c + 13);
+ } else {
+ Swig_error(Getfile(s), Getline(id), "Unknown SWIG pragma: %s\n", c);
+ }
+ }
+ }
+ } else if (Equal(id, kpp_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);
+ state = 0;
+ break;
+
+ /* Swig directives */
+ case 100:
+ /* %{,%} block */
+ if (c == '{') {
+ start_line = Getline(s);
+ add_chunk(ns, chunk, allow);
+ copy_location(s, chunk);
+ Putc('%', chunk);
+ Putc(c, chunk);
+ state = 105;
+ }
+ /* %#cpp - an embedded C preprocessor directive (we strip off the %) */
+ else if (c == '#') {
+ add_chunk(ns, chunk, allow);
+ Putc(c, chunk);
+ state = 107;
+ } else if (isidentifier(c)) {
+ Clear(decl);
+ Putc('%', decl);
+ Putc(c, decl);
+ state = 110;
+ } else {
+ Putc('%', chunk);
+ Putc(c, chunk);
+ state = 1;
+ }
+ break;
+
+ case 105:
+ Putc(c, chunk);
+ if (c == '%')
+ state = 106;
+ break;
+
+ case 106:
+ Putc(c, chunk);
+ if (c == '}') {
+ state = 1;
+ addline(ns, chunk, allow);
+ Clear(chunk);
+ copy_location(s, chunk);
+ } else {
+ 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)) {
+ Ungetc(c, s);
+ /* Look for common Swig directives */
+ if (Equal(decl, kpp_dinclude) || Equal(decl, kpp_dimport) || Equal(decl, kpp_dextern)) {
+ /* Got some kind of file inclusion directive */
+ if (allow) {
+ DOH *s1, *s2, *fn, *opt;
+ int sysfile = 0;
+
+ if (Equal(decl, kpp_dextern)) {
+ Swig_warning(WARN_DEPRECATED_EXTERN, Getfile(s), Getline(s), "%%extern is deprecated. Use %%import instead.\n");
+ Clear(decl);
+ Append(decl, "%%import");
+ }
+ opt = get_options(s);
+ fn = get_filename(s, &sysfile);
+ s1 = cpp_include(fn, sysfile);
+ if (s1) {
+ char *dirname;
+ add_chunk(ns, chunk, allow);
+ copy_location(s, chunk);
+ Printf(ns, "%sfile%s \"%s\" [\n", decl, opt, Swig_last_file());
+ if (Equal(decl, kpp_dimport)) {
+ push_imported();
+ }
+ dirname = Swig_file_dirname(Swig_last_file());
+ if (sysfile || !strlen(dirname))
+ dirname = 0;
+ if (dirname) {
+ dirname[strlen(dirname) - 1] = 0; /* Kill trailing directory delimiter */
+ Swig_push_directory(dirname);
+ }
+ s2 = Preprocessor_parse(s1);
+ if (dirname) {
+ Swig_pop_directory();
+ }
+ if (Equal(decl, kpp_dimport)) {
+ pop_imported();
+ }
+ addline(ns, s2, allow);
+ Append(ns, "\n]");
+ Delete(s2);
+ Delete(s1);
+ }
+ Delete(fn);
+ }
+ state = 1;
+ } else if (Equal(decl, kpp_dline)) {
+ /* Got a line directive */
+ state = 1;
+ } else if (Equal(decl, kpp_ddefine)) {
+ /* Got a define directive */
+ dlevel++;
+ add_chunk(ns, chunk, allow);
+ copy_location(s, chunk);
+ Clear(value);
+ copy_location(s, value);
+ state = 150;
+ } else {
+ Append(chunk, decl);
+ state = 1;
+ }
+ } else {
+ Putc(c, decl);
+ }
+ break;
+
+ /* Searching for the end of a %define statement */
+ case 150:
+ Putc(c, value);
+ if (c == '%') {
+ const char *ed = "enddef";
+ const char *df = "define";
+ char statement[7];
+ int i = 0;
+ for (i = 0; i < 6;) {
+ c = Getc(s);
+ Putc(c, value);
+ statement[i++] = (char)c;
+ if (strncmp(statement, ed, i) && strncmp(statement, df, i))
+ break;
+ }
+ c = Getc(s);
+ Ungetc(c, s);
+ if ((i == 6) && (isspace(c))) {
+ if (strncmp(statement, df, i) == 0) {
+ ++dlevel;
+ } else {
+ if (strncmp(statement, ed, i) == 0) {
+ --dlevel;
+ if (!dlevel) {
+ /* Got the macro */
+ for (i = 0; i < 7; i++) {
+ Delitem(value, DOH_END);
+ }
+ if (allow) {
+ Seek(value, 0, SEEK_SET);
+ Preprocessor_define(value, 1);
+ }
+ /* Putc('\n',ns); */
+ addline(ns, value, 0);
+ state = 0;
+ }
+ }
+ }
+ }
+ }
+ break;
+ default:
+ Printf(stderr, "cpp: Invalid parser state %d\n", state);
+ abort();
+ break;
+ }
+ }
+ while (level > 0) {
+ 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);
+ Swig_error(Getfile(s), -1, "Missing %%enddef for macro starting on line %d\n", Getline(value));
+ }
+ if ((state >= 105) && (state < 107)) {
+ Swig_error(Getfile(s), -1, "Unterminated %%{ ... %%} block starting on line %d\n", start_line);
+ }
+ if ((state >= 30) && (state < 40)) {
+ Swig_error(Getfile(s), -1, "Unterminated comment starting on line %d\n", start_line);
+ }
+ add_chunk(ns, chunk, allow);
+ copy_location(s, chunk);
+
+ /* DelScope(scp); */
+ Delete(decl);
+ Delete(id);
+ Delete(value);
+ Delete(comment);
+ Delete(chunk);
+
+ /* fprintf(stderr,"cpp: %d\n", Len(Getattr(cpp,"symbols"))); */
+ return ns;
+}
diff --git a/Source/Preprocessor/expr.c b/Source/Preprocessor/expr.c
new file mode 100644
index 0000000..e6e9459
--- /dev/null
+++ b/Source/Preprocessor/expr.c
@@ -0,0 +1,436 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * expr.c
+ *
+ * Integer arithmetic expression evaluator used to handle expressions
+ * encountered during preprocessing.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_expr_c[] = "$Id: expr.c 10310 2008-03-17 00:36:35Z olly $";
+
+#include "swig.h"
+#include "preprocessor.h"
+
+static Scanner *scan = 0;
+
+typedef struct {
+ int op;
+ long value;
+ String *svalue;
+} exprval;
+
+#define EXPR_TOP 1
+#define EXPR_VALUE 2
+#define EXPR_OP 3
+#define EXPR_GROUP 4
+#define EXPR_UMINUS 100
+
+static exprval stack[256]; /* Parsing stack */
+static int sp = 0; /* Stack pointer */
+static int prec[256]; /* Precedence rules */
+static int expr_init = 0; /* Initialization flag */
+static char *errmsg = 0; /* Parsing error */
+
+/* Initialize the precedence table for various operators. Low values have higher precedence */
+static void init_precedence() {
+ prec[SWIG_TOKEN_NOT] = 10;
+ prec[EXPR_UMINUS] = 10;
+ prec[SWIG_TOKEN_STAR] = 20;
+ prec[SWIG_TOKEN_SLASH] = 20;
+ prec[SWIG_TOKEN_PERCENT] = 20;
+ prec[SWIG_TOKEN_PLUS] = 30;
+ prec[SWIG_TOKEN_MINUS] = 30;
+ prec[SWIG_TOKEN_LSHIFT] = 40;
+ prec[SWIG_TOKEN_RSHIFT] = 40;
+ prec[SWIG_TOKEN_AND] = 50;
+ prec[SWIG_TOKEN_XOR] = 60;
+ prec[SWIG_TOKEN_OR] = 70;
+ prec[SWIG_TOKEN_EQUALTO] = 80;
+ prec[SWIG_TOKEN_NOTEQUAL] = 80;
+ prec[SWIG_TOKEN_LESSTHAN] = 80;
+ prec[SWIG_TOKEN_GREATERTHAN] = 80;
+ prec[SWIG_TOKEN_LTEQUAL] = 80;
+ prec[SWIG_TOKEN_GTEQUAL] = 80;
+ prec[SWIG_TOKEN_LNOT] = 90;
+ prec[SWIG_TOKEN_LAND] = 100;
+ prec[SWIG_TOKEN_LOR] = 110;
+ expr_init = 1;
+}
+
+#define UNARY_OP(token) (((token) == SWIG_TOKEN_NOT) || \
+ ((token) == SWIG_TOKEN_LNOT) || \
+ ((token) == EXPR_UMINUS))
+
+/* Reduce a single operator on the stack */
+/* return 0 on failure, 1 on success */
+static int reduce_op() {
+ long op_token = stack[sp - 1].value;
+ assert(sp > 0);
+ assert(stack[sp - 1].op == EXPR_OP);
+ /* do some basic checking first: */
+ if (stack[sp].op != EXPR_VALUE) {
+ errmsg = "Right-hand side is not value";
+ return 0;
+ }
+ if (UNARY_OP(op_token)) {
+ if (stack[sp].svalue) {
+ errmsg = "Syntax error: attempt to apply unary operator to string";
+ return 0;
+ }
+ } else {
+ /* binary operator: */
+ if (sp == 1) {
+ /* top of stack: don't attempt to use sp-2! */
+ errmsg = "Missing left-hand side for binary operator";
+ return 0;
+ }
+ if (stack[sp].op != EXPR_VALUE) {
+ errmsg = "Left-hand side of binary operator is not a value";
+ return 0;
+ }
+ if ((!stack[sp - 2].svalue) != (!stack[sp].svalue)) {
+ errmsg = "Can't mix strings and integers in expression";
+ return 0;
+ }
+ }
+ if (stack[sp].svalue) {
+ /* A binary string expression */
+ 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: bad binary operator for strings";
+ return 0;
+ break;
+ }
+ } else {
+ switch (op_token) {
+ 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: bad operator";
+ return 0;
+ break;
+ }
+ }
+ stack[sp].op = EXPR_VALUE;
+ stack[sp].svalue = 0; /* ensure it's not a string! */
+ return 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * Preprocessor_expr_init()
+ *
+ * Initialize the expression evaluator
+ * ----------------------------------------------------------------------------- */
+
+void Preprocessor_expr_init(void) {
+ if (!expr_init)
+ init_precedence();
+ if (!scan)
+ scan = NewScanner();
+}
+
+void Preprocessor_expr_delete(void) {
+ DelScanner(scan);
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Tokenizer
+ * ----------------------------------------------------------------------------- */
+
+static int expr_token(Scanner * s) {
+ int t;
+ while (1) {
+ t = Scanner_token(s);
+ if (!((t == SWIG_TOKEN_BACKSLASH) || (t == SWIG_TOKEN_ENDLINE) || (t == SWIG_TOKEN_COMMENT)))
+ break;
+ }
+ return t;
+}
+
+/* -----------------------------------------------------------------------------
+ * Preprocessor_expr()
+ *
+ * Evaluates an arithmetic expression. Returns the result and sets an error code.
+ * ----------------------------------------------------------------------------- */
+
+int Preprocessor_expr(DOH *s, int *error) {
+ int token = 0;
+ int op = 0;
+
+ sp = 0;
+ assert(s);
+ assert(scan);
+
+ Seek(s, 0, SEEK_SET);
+ /* Printf(stdout,"evaluating : '%s'\n", s); */
+ *error = 0;
+ Scanner_clear(scan);
+ Scanner_push(scan, s);
+
+ /* Put initial state onto the stack */
+ stack[sp].op = EXPR_TOP;
+ stack[sp].value = 0;
+
+ while (1) {
+ /* Look at the top of the stack */
+ switch (stack[sp].op) {
+ case EXPR_TOP:
+ /* An expression. Can be a number or another expression enclosed in parens */
+ token = expr_token(scan);
+ if (!token) {
+ errmsg = "Expected an expression";
+ *error = 1;
+ return 0;
+ }
+ 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 */
+ char *c = Char(Scanner_text(scan));
+ stack[sp].value = (long) strtol(c, 0, 0);
+ stack[sp].svalue = 0;
+ /* stack[sp].value = (long) atol(Char(Scanner_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)) {
+ if (token == SWIG_TOKEN_MINUS)
+ token = EXPR_UMINUS;
+ 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;
+ stack[sp].svalue = 0;
+ } else if (token == SWIG_TOKEN_ENDLINE) {
+ } else if ((token == SWIG_TOKEN_STRING)) {
+ stack[sp].svalue = NewString(Scanner_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 */
+ token = expr_token(scan);
+ if (!token) {
+ /* End of input. Might have to reduce if an operator is on stack */
+ while (sp > 0) {
+ if (stack[sp - 1].op == EXPR_OP) {
+ if (!reduce_op())
+ goto reduce_error;
+ } else if (stack[sp - 1].op == EXPR_GROUP) {
+ errmsg = "Missing \')\'";
+ *error = 1;
+ return 0;
+ } else
+ goto syntax_error;
+ }
+ return stack[sp].value;
+ }
+ /* Token must be an operator */
+ switch (token) {
+ case SWIG_TOKEN_STAR:
+ case SWIG_TOKEN_EQUALTO:
+ case SWIG_TOKEN_NOTEQUAL:
+ case SWIG_TOKEN_PLUS:
+ case SWIG_TOKEN_MINUS:
+ case SWIG_TOKEN_AND:
+ case SWIG_TOKEN_LAND:
+ case SWIG_TOKEN_OR:
+ case SWIG_TOKEN_LOR:
+ case SWIG_TOKEN_XOR:
+ case SWIG_TOKEN_LESSTHAN:
+ case SWIG_TOKEN_GREATERTHAN:
+ case SWIG_TOKEN_LTEQUAL:
+ case SWIG_TOKEN_GTEQUAL:
+ case SWIG_TOKEN_SLASH:
+ case SWIG_TOKEN_PERCENT:
+ case SWIG_TOKEN_LSHIFT:
+ case SWIG_TOKEN_RSHIFT:
+ if ((sp == 0) || (stack[sp - 1].op == EXPR_GROUP)) {
+ /* No possibility of reduce. Push operator and expression */
+ sp++;
+ stack[sp].op = EXPR_OP;
+ stack[sp].value = token;
+ sp++;
+ stack[sp].op = EXPR_TOP;
+ stack[sp].value = 0;
+ } else {
+ if (stack[sp - 1].op != EXPR_OP)
+ goto syntax_error_expected_operator;
+ op = stack[sp - 1].value; /* Previous operator */
+
+ /* Now, depending on the precedence relationship between the last operator and the current
+ we will reduce or push */
+
+ if (prec[op] <= prec[token]) {
+ /* Reduce the previous operator */
+ if (!reduce_op())
+ goto reduce_error;
+ }
+ sp++;
+ stack[sp].op = EXPR_OP;
+ stack[sp].value = token;
+ sp++;
+ stack[sp].op = EXPR_TOP;
+ stack[sp].value = 0;
+ }
+ break;
+ case SWIG_TOKEN_RPAREN:
+ if (sp == 0)
+ goto extra_rparen;
+
+ /* Might have to reduce operators first */
+ while ((sp > 0) && (stack[sp - 1].op == EXPR_OP)) {
+ if (!reduce_op())
+ goto reduce_error;
+ }
+ if ((sp == 0) || (stack[sp - 1].op != EXPR_GROUP))
+ goto extra_rparen;
+ stack[sp - 1].op = EXPR_VALUE;
+ stack[sp - 1].value = stack[sp].value;
+ sp--;
+ break;
+ default:
+ goto syntax_error_expected_operator;
+ break;
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Internal error in expression evaluator.\n");
+ abort();
+ }
+ }
+
+syntax_error:
+ errmsg = "Syntax error";
+ *error = 1;
+ return 0;
+
+syntax_error_expected_operator:
+ errmsg = "Syntax error: expected operator";
+ *error = 1;
+ return 0;
+
+reduce_error:
+ /* errmsg has been set by reduce_op */
+ *error = 1;
+ return 0;
+
+extra_rparen:
+ errmsg = "Extra \')\'";
+ *error = 1;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Preprocessor_expr_error()
+ *
+ * Return error message set by the evaluator (if any)
+ * ----------------------------------------------------------------------------- */
+
+char *Preprocessor_expr_error() {
+ return errmsg;
+}
diff --git a/Source/Preprocessor/preprocessor.h b/Source/Preprocessor/preprocessor.h
new file mode 100644
index 0000000..2b90808
--- /dev/null
+++ b/Source/Preprocessor/preprocessor.h
@@ -0,0 +1,38 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * preprocessor.h
+ *
+ * SWIG preprocessor module.
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: preprocessor.h 11080 2009-01-24 13:15:51Z bhy $ */
+
+#ifndef SWIG_PREPROCESSOR_H_
+#define SWIG_PREPROCESSOR_H_
+
+#include "swigwarn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ extern int Preprocessor_expr(String *s, int *error);
+ extern char *Preprocessor_expr_error(void);
+ extern Hash *Preprocessor_define(const_String_or_char_ptr str, int swigmacro);
+ extern void Preprocessor_undef(const_String_or_char_ptr name);
+ extern void Preprocessor_init(void);
+ extern void Preprocessor_delete(void);
+ 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 void Preprocessor_error_as_warning(int);
+ extern List *Preprocessor_depend(void);
+ extern void Preprocessor_expr_init(void);
+ extern void Preprocessor_expr_delete(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/Source/README b/Source/README
new file mode 100644
index 0000000..814ec45
--- /dev/null
+++ b/Source/README
@@ -0,0 +1,25 @@
+SWIG Source directory
+
+ 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/Modules - Language modules.
+
+ Source/Include - Include files.
+
+Historic directories which may be in CVS, but have been removed:
+
+ Source/Modules1.1 - Old SWIG-1.1 modules. Empty.
+
+ 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/cwrap.c b/Source/Swig/cwrap.c
new file mode 100644
index 0000000..72c06f3
--- /dev/null
+++ b/Source/Swig/cwrap.c
@@ -0,0 +1,1462 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * cwrap.c
+ *
+ * This file defines a variety of wrapping rules for C/C++ handling including
+ * the naming of local variables, calling conventions, and so forth.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_cwrap_c[] = "$Id: cwrap.c 11312 2009-06-24 17:20:17Z wsfulton $";
+
+#include "swig.h"
+
+extern int cparse_cplusplus;
+
+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()
+ *
+ * Generates a name for the ith argument in an argument list
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_cparm_name(Parm *p, int i) {
+ String *name = NewStringf("arg%d", i + 1);
+ if (p) {
+ Setattr(p, "lname", name);
+ }
+
+ return name;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_clocal()
+ *
+ * Creates a string that declares a C local variable type. Converts references
+ * and user defined types to pointers.
+ * ----------------------------------------------------------------------------- */
+
+static String *Swig_clocal(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr value) {
+ String *decl;
+
+ decl = NewStringEmpty();
+
+ switch (SwigType_type(t)) {
+ case T_REFERENCE:
+ if (value) {
+ String *lstrname = SwigType_lstr(t, name);
+ String *lstr = SwigType_lstr(t, 0);
+ Printf(decl, "%s = (%s) &%s_defvalue", lstrname, lstr, name);
+ Delete(lstrname);
+ Delete(lstr);
+ } else {
+ String *lstrname = SwigType_lstr(t, name);
+ Printf(decl, "%s = 0", lstrname);
+ Delete(lstrname);
+ }
+ break;
+ case T_VOID:
+ break;
+ case T_VARARGS:
+ Printf(decl, "void *%s = 0", name);
+ break;
+
+ default:
+ if (value) {
+ String *lcaststr = SwigType_lcaststr(t, value);
+ String *lstr = SwigType_lstr(t, 0);
+ String *lstrn = SwigType_lstr(t, name);
+ Printf(decl, "%s = (%s) %s", lstrn, lstr, lcaststr);
+ Delete(lcaststr);
+ Delete(lstr);
+ Delete(lstrn);
+ } else {
+ String *lstrname = SwigType_lstr(t, name);
+ Append(decl, lstrname);
+ Delete(lstrname);
+ }
+ }
+ return decl;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_wrapped_var_convert()
+ *
+ * Converts a member variable for use in the get and set wrapper methods.
+ * This function only converts user defined types to pointers.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_wrapped_var_type(SwigType *t, int varcref) {
+ SwigType *ty;
+
+ if (!Strstr(t, "enum $unnamed")) {
+ ty = Copy(t);
+ } else {
+ /* Change the type for unnamed enum instance variables */
+ ty = NewString("int");
+ }
+
+ if (SwigType_isclass(t)) {
+ if (varcref) {
+ if (cparse_cplusplus) {
+ if (!SwigType_isconst(ty))
+ SwigType_add_qualifier(ty, "const");
+ SwigType_add_reference(ty);
+ } else {
+ return Copy(ty);
+ }
+ } else {
+ SwigType_add_pointer(ty);
+ }
+ }
+ return ty;
+}
+
+String *Swig_wrapped_member_var_type(SwigType *t, int varcref) {
+ SwigType *ty;
+
+ if (!Strstr(t, "enum $unnamed")) {
+ ty = Copy(t);
+ } else {
+ /* Change the type for unnamed enum instance variables */
+ ty = NewString("int");
+ }
+ if (SwigType_isclass(t)) {
+ if (varcref) {
+ if (cparse_cplusplus) {
+ if (!SwigType_isconst(ty))
+ SwigType_add_qualifier(ty, "const");
+ SwigType_add_reference(ty);
+ } else {
+ return Copy(ty);
+ }
+ } else {
+ SwigType_add_pointer(ty);
+ }
+ }
+ return ty;
+}
+
+
+static String *Swig_wrapped_var_deref(SwigType *t, const_String_or_char_ptr name, int varcref) {
+ if (SwigType_isclass(t)) {
+ if (varcref) {
+ if (cparse_cplusplus) {
+ return NewStringf("*%s", name);
+ } else {
+ return NewStringf("%s", name);
+ }
+ } else {
+ return NewStringf("*%s", name);
+ }
+ } else {
+ return SwigType_rcaststr(t, name);
+ }
+}
+
+static String *Swig_wrapped_var_assign(SwigType *t, const_String_or_char_ptr name, int varcref) {
+ if (SwigType_isclass(t)) {
+ if (varcref) {
+ return NewStringf("%s", name);
+ } else {
+ return NewStringf("&%s", name);
+ }
+ } else {
+ return SwigType_lcaststr(t, name);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cargs()
+ *
+ * Emit all of the local variables for a list of parameters. Returns the
+ * number of parameters.
+ * Default values for the local variables are only emitted if the compact default
+ * argument behaviour is required.
+ * ----------------------------------------------------------------------------- */
+int Swig_cargs(Wrapper *w, ParmList *p) {
+ int i = 0;
+ int compactdefargs = ParmList_is_compactdefargs(p);
+
+ while (p != 0) {
+ String *lname = Swig_cparm_name(p, i);
+ SwigType *pt = Getattr(p, "type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ String *local = 0;
+ String *type = Getattr(p, "type");
+ /* default values only emitted if in compact default args mode */
+ String *pvalue = (compactdefargs) ? Getattr(p, "value") : 0;
+
+ /* When using compactdefaultargs, the code generated initialises a variable via a constructor call that accepts the
+ * default value as a parameter. The default constructor is not called and therefore SwigValueWrapper is not needed. */
+ SwigType *altty = pvalue ? 0 : SwigType_alttype(type, 0);
+
+ int tycode = SwigType_type(type);
+ if (tycode == T_REFERENCE) {
+ if (pvalue) {
+ SwigType *tvalue;
+ String *defname, *defvalue, *rvalue, *qvalue;
+ rvalue = SwigType_typedef_resolve_all(pvalue);
+ qvalue = SwigType_typedef_qualified(rvalue);
+ defname = NewStringf("%s_defvalue", lname);
+ tvalue = Copy(type);
+ SwigType_del_reference(tvalue);
+ tycode = SwigType_type(tvalue);
+ if (tycode != T_USER) {
+ /* plain primitive type, we copy the the def value */
+ String *lstr = SwigType_lstr(tvalue, defname);
+ defvalue = NewStringf("%s = %s", lstr, qvalue);
+ Delete(lstr);
+ } else {
+ /* user type, we copy the reference value */
+ String *str = SwigType_str(type, defname);
+ defvalue = NewStringf("%s = %s", str, qvalue);
+ Delete(str);
+ }
+ Wrapper_add_localv(w, defname, defvalue, NIL);
+ Delete(tvalue);
+ Delete(rvalue);
+ Delete(qvalue);
+ Delete(defname);
+ Delete(defvalue);
+ }
+ } else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING))) {
+ pvalue = (String *) "0";
+ }
+ if (!altty) {
+ local = Swig_clocal(pt, lname, pvalue);
+ } else {
+ local = Swig_clocal(altty, lname, pvalue);
+ Delete(altty);
+ }
+ Wrapper_add_localv(w, lname, local, NIL);
+ Delete(local);
+ i++;
+ }
+ Delete(lname);
+ p = nextSibling(p);
+ }
+ return (i);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cresult()
+ *
+ * This function generates the C code needed to set the result of a C
+ * function call.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr decl) {
+ String *fcall;
+
+ fcall = NewStringEmpty();
+ switch (SwigType_type(t)) {
+ case T_VOID:
+ break;
+ case T_REFERENCE:
+ {
+ String *lstr = SwigType_lstr(t, 0);
+ Printf(fcall, "%s = (%s) &", name, lstr);
+ Delete(lstr);
+ }
+ break;
+ case T_USER:
+ Printf(fcall, "%s = ", name);
+ break;
+
+ default:
+ /* Normal return value */
+ {
+ String *lstr = SwigType_lstr(t, 0);
+ Printf(fcall, "%s = (%s)", name, lstr);
+ Delete(lstr);
+ }
+ break;
+ }
+
+ /* Now print out function call */
+ Append(fcall, decl);
+
+ /* A sick hack */
+ {
+ char *c = Char(decl) + Len(decl) - 1;
+ if (!((*c == ';') || (*c == '}')))
+ Append(fcall, ";");
+ }
+
+ return fcall;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cfunction_call()
+ *
+ * Creates a string that calls a C function using the local variable rules
+ * defined above.
+ *
+ * name(arg0, arg1, arg2, ... argn)
+ *
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms) {
+ String *func;
+ int i = 0;
+ int comma = 0;
+ Parm *p = parms;
+ String *nname;
+
+ func = NewStringEmpty();
+ nname = SwigType_namestr(name);
+
+ /*
+ SWIGTEMPLATEDISAMBIGUATOR is compiler dependent (swiglabels.swg),
+ - SUN Studio 9 requires 'template',
+ - gcc-3.4 forbids the use of 'template'.
+ the rest seems not caring very much,
+ */
+ if (SwigType_istemplate(name)) {
+ String *prefix = Swig_scopename_prefix(nname);
+ if (!prefix || Len(prefix) == 0) {
+ Printf(func, "%s(", nname);
+ } else {
+ String *last = Swig_scopename_last(nname);
+ Printf(func, "%s::SWIGTEMPLATEDISAMBIGUATOR %s(", prefix, last);
+ Delete(last);
+ }
+ Delete(prefix);
+ } else {
+ Printf(func, "%s(", nname);
+ }
+ Delete(nname);
+
+ while (p) {
+ SwigType *pt = Getattr(p, "type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ SwigType *rpt = SwigType_typedef_resolve_all(pt);
+ String *pname = Swig_cparm_name(p, i);
+ String *rcaststr = SwigType_rcaststr(rpt, pname);
+
+ if (comma) {
+ Printv(func, ",", rcaststr, NIL);
+ } else {
+ Append(func, rcaststr);
+ }
+ Delete(rpt);
+ Delete(pname);
+ Delete(rcaststr);
+ comma = 1;
+ i++;
+ }
+ p = nextSibling(p);
+ }
+ Append(func, ")");
+ return func;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cmethod_call()
+ *
+ * Generates a string that calls a C++ method from a list of parameters.
+ *
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+static String *Swig_cmethod_call(const_String_or_char_ptr name, ParmList *parms, const_String_or_char_ptr self, String *explicit_qualifier, SwigType *director_type) {
+ String *func, *nname;
+ int i = 0;
+ Parm *p = parms;
+ SwigType *pt;
+ int comma = 0;
+
+ func = NewStringEmpty();
+ if (!p)
+ return func;
+
+ if (!self)
+ self = (char *) "(this)->";
+ Append(func, self);
+
+ if (SwigType_istemplate(name) && (strncmp(Char(name), "operator ", 9) == 0)) {
+ /* fix for template + operators and compilers like gcc 3.3.5 */
+ String *tprefix = SwigType_templateprefix(name);
+ nname = tprefix;
+ } else {
+ nname = SwigType_namestr(name);
+ }
+
+ if (director_type) {
+ const char *pname = "darg";
+ String *rcaststr = SwigType_rcaststr(director_type, pname);
+ Replaceall(func, "this", rcaststr);
+ Delete(rcaststr);
+ } else {
+ 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")) {
+ String *pname = Swig_cparm_name(p, 0);
+ Replaceall(func, "this", pname);
+ Delete(pname);
+ } else {
+ String *pname = Swig_cparm_name(p, 0);
+ String *rcaststr = SwigType_rcaststr(pt, pname);
+ Replaceall(func, "this", rcaststr);
+ Delete(rcaststr);
+ Delete(pname);
+ }
+
+ /*
+ SWIGTEMPLATEDESIMBUAGATOR is compiler dependent (swiglabels.swg),
+ - SUN Studio 9 requires 'template',
+ - gcc-3.4 forbids the use of 'template' (correctly implementing the ISO C++ standard)
+ the others don't seem to care,
+ */
+ if (SwigType_istemplate(name))
+ Printf(func, "SWIGTEMPLATEDISAMBIGUATOR ");
+
+ if (explicit_qualifier) {
+ Printv(func, explicit_qualifier, "::", NIL);
+ }
+ }
+
+ Printf(func, "%s(", nname);
+
+ i++;
+ p = nextSibling(p);
+ while (p) {
+ pt = Getattr(p, "type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ String *pname = Swig_cparm_name(p, i);
+ String *rcaststr = SwigType_rcaststr(pt, pname);
+ if (comma)
+ Append(func, ",");
+ Append(func, rcaststr);
+ Delete(rcaststr);
+ Delete(pname);
+ comma = 1;
+ i++;
+ }
+ p = nextSibling(p);
+ }
+ Append(func, ")");
+ Delete(nname);
+ return func;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cconstructor_call()
+ *
+ * Creates a string that calls a C constructor function.
+ *
+ * calloc(1,sizeof(name));
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_cconstructor_call(const_String_or_char_ptr name) {
+ DOH *func;
+
+ func = NewStringEmpty();
+ Printf(func, "calloc(1, sizeof(%s))", name);
+ return func;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_cppconstructor_call()
+ *
+ * Creates a string that calls a C function using the local variable rules
+ * defined above.
+ *
+ * name(arg0, arg1, arg2, ... argn)
+ *
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_cppconstructor_base_call(const_String_or_char_ptr name, ParmList *parms, int skip_self) {
+ String *func;
+ String *nname;
+ int i = 0;
+ int comma = 0;
+ Parm *p = parms;
+ SwigType *pt;
+ if (skip_self) {
+ if (p)
+ p = nextSibling(p);
+ i++;
+ }
+ nname = SwigType_namestr(name);
+ func = NewStringEmpty();
+ Printf(func, "new %s(", nname);
+ while (p) {
+ pt = Getattr(p, "type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ String *rcaststr = 0;
+ String *pname = 0;
+ if (comma)
+ Append(func, ",");
+ if (!Getattr(p, "arg:byname")) {
+ pname = Swig_cparm_name(p, i);
+ i++;
+ } else {
+ pname = Getattr(p, "value");
+ if (pname)
+ pname = Copy(pname);
+ else
+ pname = Copy(Getattr(p, "name"));
+ }
+ rcaststr = SwigType_rcaststr(pt, pname);
+ Append(func, rcaststr);
+ Delete(rcaststr);
+ comma = 1;
+ Delete(pname);
+ }
+ p = nextSibling(p);
+ }
+ Append(func, ")");
+ Delete(nname);
+ return func;
+}
+
+String *Swig_cppconstructor_call(const_String_or_char_ptr name, ParmList *parms) {
+ return Swig_cppconstructor_base_call(name, parms, 0);
+}
+
+String *Swig_cppconstructor_nodirector_call(const_String_or_char_ptr name, ParmList *parms) {
+ return Swig_cppconstructor_base_call(name, parms, 1);
+}
+
+String *Swig_cppconstructor_director_call(const_String_or_char_ptr name, ParmList *parms) {
+ return Swig_cppconstructor_base_call(name, parms, 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_rflag_search()
+ *
+ * This function searches for the class attribute 'attr' in the class
+ * 'n' or recursively in its bases.
+ *
+ * If you define SWIG_FAST_REC_SEARCH, the method will set the found
+ * 'attr' in the target class 'n'. If not, the method will set the
+ * 'noattr' one. This prevents of having to navigate the entire
+ * hierarchy tree everytime, so, it is an O(1) method... or something
+ * like that. However, it populates all the parsed classes with the
+ * 'attr' and/or 'noattr' attributes.
+ *
+ * If you undefine the SWIG_FAST_REC_SEARCH no attribute will be set
+ * while searching. This could be slower for large projects with very
+ * large hierarchy trees... or maybe not. But it will be cleaner.
+ *
+ * Maybe later a swig option can be added to switch at runtime.
+ *
+ * ----------------------------------------------------------------------------- */
+
+/* #define SWIG_FAST_REC_SEARCH 1 */
+String *Swig_rflag_search(Node *n, const String *attr, const String *noattr) {
+ String *f = 0;
+ n = Swig_methodclass(n);
+ if (GetFlag(n, noattr)) {
+ return 0;
+ }
+ f = GetFlagAttr(n, attr);
+ if (f) {
+ return f;
+ } else {
+ List *bl = Getattr(n, "bases");
+ if (bl) {
+ Iterator bi;
+ for (bi = First(bl); bi.item; bi = Next(bi)) {
+ f = Swig_rflag_search(bi.item, attr, noattr);
+ if (f) {
+#ifdef SWIG_FAST_REC_SEARCH
+ SetFlagAttr(n, attr, f);
+#endif
+ return f;
+ }
+ }
+ }
+ }
+#ifdef SWIG_FAST_REC_SEARCH
+ SetFlag(n, noattr);
+#endif
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_unref_call()
+ *
+ * find the unref call, if any.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_unref_call(Node *n) {
+ Node *cn = Swig_methodclass(n);
+ String *unref = Swig_rflag_search(cn, "feature:unref", "feature:nounref");
+ if (unref) {
+ String *pname = Swig_cparm_name(0, 0);
+ unref = NewString(unref);
+ Replaceall(unref, "$this", pname);
+ Replaceall(unref, "$self", pname);
+ Delete(pname);
+ }
+ return unref;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_ref_call()
+ *
+ * find the ref call, if any.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_ref_call(Node *n, const String *lname) {
+ Node *cn = Swig_methodclass(n);
+ String *ref = Swig_rflag_search(cn, "feature:ref", "feature:noref");
+ if (ref) {
+ ref = NewString(ref);
+ Replaceall(ref, "$this", lname);
+ Replaceall(ref, "$self", lname);
+ }
+ return ref;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cdestructor_call()
+ *
+ * Creates a string that calls a C destructor function.
+ *
+ * free((char *) arg0);
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_cdestructor_call(Node *n) {
+ String *unref = Swig_unref_call(n);
+
+ if (unref) {
+ return unref;
+ } else {
+ String *pname = Swig_cparm_name(0, 0);
+ String *call = NewStringf("free((char *) %s);", pname);
+ Delete(pname);
+ return call;
+ }
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_cppdestructor_call()
+ *
+ * Creates a string that calls a C destructor function.
+ *
+ * delete arg1;
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_cppdestructor_call(Node *n) {
+ String *unref = Swig_unref_call(n);
+ if (unref) {
+ return unref;
+ } else {
+ String *pname = Swig_cparm_name(0, 0);
+ String *call = NewStringf("delete %s;", pname);
+ Delete(pname);
+ return call;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cmemberset_call()
+ *
+ * Generates a string that sets the name of a member in a C++ class or C struct.
+ *
+ * arg0->name = arg1
+ *
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, String *self, int varcref) {
+ String *func;
+ String *pname0 = Swig_cparm_name(0, 0);
+ String *pname1 = Swig_cparm_name(0, 1);
+ func = NewStringEmpty();
+ if (!self)
+ self = NewString("(this)->");
+ else
+ self = NewString(self);
+ Replaceall(self, "this", pname0);
+ if (SwigType_type(type) != T_ARRAY) {
+ if (!Strstr(type, "enum $unnamed")) {
+ String *dref = Swig_wrapped_var_deref(type, pname1, varcref);
+ Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
+ Delete(dref);
+ } else {
+ Printf(func, "if (%s && sizeof(int) == sizeof(%s%s)) *(int*)(void*)&(%s%s) = %s", pname0, self, name, self, name, pname1);
+ }
+ }
+ Delete(self);
+ Delete(pname0);
+ Delete(pname1);
+ return (func);
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_cmemberget_call()
+ *
+ * Generates a string that sets the name of a member in a C++ class or C struct.
+ *
+ * arg0->name
+ *
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref) {
+ String *func;
+ String *call;
+ String *pname0 = Swig_cparm_name(0, 0);
+ if (!self)
+ self = NewString("(this)->");
+ else
+ self = NewString(self);
+ Replaceall(self, "this", pname0);
+ func = NewStringEmpty();
+ call = Swig_wrapped_var_assign(t, "", varcref);
+ Printf(func, "%s (%s%s)", call, self, name);
+ Delete(self);
+ Delete(call);
+ Delete(pname0);
+ return func;
+}
+
+/* -----------------------------------------------------------------------------
+ * extension_code()
+ *
+ * Generates an extension function (a function defined in %extend)
+ *
+ * return_type function_name(parms) code
+ *
+ * ----------------------------------------------------------------------------- */
+static String *extension_code(const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) {
+ String *parms_str = cplusplus ? ParmList_str_defaultargs(parms) : ParmList_str(parms);
+ String *sig = NewStringf("%s(%s)", function_name, parms_str);
+ String *rt_sig = SwigType_str(return_type, sig);
+ String *body = NewStringf("SWIGINTERN %s", rt_sig);
+ Printv(body, code, "\n", NIL);
+ if (self)
+ Replaceall(body, "$self", self);
+ Delete(parms_str);
+ Delete(sig);
+ Delete(rt_sig);
+ return body;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_add_extension_code()
+ *
+ * Generates an extension function (a function defined in %extend) and
+ * adds it to the "wrap:code" attribute of a node
+ *
+ * See also extension_code()
+ *
+ * ----------------------------------------------------------------------------- */
+int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) {
+ String *body = extension_code(function_name, parms, return_type, code, cplusplus, self);
+ Setattr(n, "wrap:code", body);
+ Delete(body);
+ return SWIG_OK;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_MethodToFunction(Node *n)
+ *
+ * Converts a C++ method node to a function accessor function.
+ * ----------------------------------------------------------------------------- */
+
+int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director) {
+ String *name, *qualifier;
+ ParmList *parms;
+ SwigType *type;
+ Parm *p;
+ String *self = 0;
+
+ /* If smart pointer, change self dereferencing */
+ if (flags & CWRAP_SMART_POINTER) {
+ self = NewString("(*this)->");
+ }
+
+ /* If node is a member template expansion, we don't allow added code */
+ if (Getattr(n, "templatetype"))
+ flags &= ~(CWRAP_EXTEND);
+
+ name = Getattr(n, "name");
+ qualifier = Getattr(n, "qualifier");
+ parms = CopyParmList(nonvoid_parms(Getattr(n, "parms")));
+
+ type = NewString(classname);
+ if (qualifier) {
+ SwigType_push(type, qualifier);
+ }
+ SwigType_add_pointer(type);
+ p = NewParm(type, "self");
+ Setattr(p, "self", "1");
+ Setattr(p, "hidden","1");
+ /*
+ Disable the 'this' ownership in 'self' to manage inplace
+ operations like:
+
+ A& A::operator+=(int i) { ...; return *this;}
+
+ Here the 'self' parameter ownership needs to be disabled since
+ there could be two objects sharing the same 'this' pointer: the
+ input and the result one. And worse, the pointer could be deleted
+ in one of the objects (input), leaving the other (output) with
+ just a seg. fault to happen.
+
+ To avoid the previous problem, use
+
+ %feature("self:disown") *::operator+=;
+ %feature("new") *::operator+=;
+
+ These two lines just transfer the ownership of the 'this' pointer
+ from the input to the output wrapping object.
+
+ This happens in python, but may also happens in other target
+ languages.
+ */
+ if (GetFlag(n, "feature:self:disown")) {
+ Setattr(p, "wrap:disown", "1");
+ }
+ set_nextSibling(p, parms);
+ Delete(type);
+
+ /* Generate action code for the access */
+ if (!(flags & CWRAP_EXTEND)) {
+ String *explicit_qualifier = 0;
+ String *call = 0;
+ String *cres = 0;
+ String *explicitcall_name = 0;
+ int pure_virtual = !(Cmp(Getattr(n, "storage"), "virtual")) && !(Cmp(Getattr(n, "value"), "0"));
+
+ /* Call the explicit method rather than allow for a polymorphic call */
+ if ((flags & CWRAP_DIRECTOR_TWO_CALLS) || (flags & CWRAP_DIRECTOR_ONE_CALL)) {
+ String *access = Getattr(n, "access");
+ if (access && (Cmp(access, "protected") == 0)) {
+ /* If protected access (can only be if a director method) then call the extra public accessor method (language module must provide this) */
+ String *explicit_qualifier_tmp = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname"));
+ explicitcall_name = NewStringf("%sSwigPublic", name);
+ explicit_qualifier = NewStringf("SwigDirector_%s", explicit_qualifier_tmp);
+ Delete(explicit_qualifier_tmp);
+ } else {
+ explicit_qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname"));
+ }
+ }
+
+ call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type);
+ cres = Swig_cresult(Getattr(n, "type"), "result", call);
+
+ if (pure_virtual && is_director && (flags & CWRAP_DIRECTOR_TWO_CALLS)) {
+ String *qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname"));
+ Delete(cres);
+ cres = NewStringf("Swig::DirectorPureVirtualException::raise(\"%s::%s\");", qualifier, name);
+ Delete(qualifier);
+ }
+
+ if (flags & CWRAP_DIRECTOR_TWO_CALLS) {
+ /* Create two method calls, one to call the explicit method, the other a normal polymorphic function call */
+ String *cres_both_calls = NewStringf("");
+ String *call_extra = Swig_cmethod_call(name, p, self, 0, director_type);
+ String *cres_extra = Swig_cresult(Getattr(n, "type"), "result", call_extra);
+ Printv(cres_both_calls, "if (upcall) {\n", cres, "\n", "} else {", cres_extra, "\n}", NIL);
+ Setattr(n, "wrap:action", cres_both_calls);
+ Delete(cres_extra);
+ Delete(call_extra);
+ Delete(cres_both_calls);
+ } else {
+ Setattr(n, "wrap:action", cres);
+ }
+
+ Delete(explicitcall_name);
+ Delete(call);
+ Delete(cres);
+ Delete(explicit_qualifier);
+ } else {
+ /* Methods with default arguments are wrapped with additional methods for each default argument,
+ * however, only one extra %extend method is generated. */
+
+ String *defaultargs = Getattr(n, "defaultargs");
+ String *code = Getattr(n, "code");
+ String *cname = Getattr(n, "classname") ? Getattr(n, "classname") : classname;
+ String *membername = Swig_name_member(cname, name);
+ String *mangled = Swig_name_mangle(membername);
+ int is_smart_pointer = flags & CWRAP_SMART_POINTER;
+
+ type = Getattr(n, "type");
+
+ /* 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. */
+ if (Getattr(n, "sym:overloaded") && code) {
+ Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
+ }
+
+ /* See if there is any code that we need to emit */
+ if (!defaultargs && code && !is_smart_pointer) {
+ Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, "self");
+ }
+ if (is_smart_pointer) {
+ int i = 0;
+ Parm *pp = p;
+ String *func = NewStringf("%s(", mangled);
+ String *cres;
+
+ if (Cmp(Getattr(n, "storage"), "static") != 0) {
+ String *pname = Swig_cparm_name(pp, i);
+ String *ctname = SwigType_namestr(cname);
+ String *fadd = NewStringf("(%s*)(%s)->operator ->()", ctname, pname);
+ Append(func, fadd);
+ Delete(ctname);
+ Delete(fadd);
+ Delete(pname);
+ pp = nextSibling(pp);
+ if (pp)
+ Append(func, ",");
+ } else {
+ pp = nextSibling(pp);
+ }
+ ++i;
+ while (pp) {
+ SwigType *pt = Getattr(pp, "type");
+ if ((SwigType_type(pt) != T_VOID)) {
+ String *pname = Swig_cparm_name(pp, i++);
+ String *rcaststr = SwigType_rcaststr(pt, pname);
+ Append(func, rcaststr);
+ Delete(rcaststr);
+ Delete(pname);
+ pp = nextSibling(pp);
+ if (pp)
+ Append(func, ",");
+ }
+ }
+ Append(func, ")");
+ cres = Swig_cresult(Getattr(n, "type"), "result", func);
+ Setattr(n, "wrap:action", cres);
+ Delete(cres);
+ } else {
+ String *call = Swig_cfunction_call(mangled, p);
+ String *cres = Swig_cresult(Getattr(n, "type"), "result", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(call);
+ Delete(cres);
+ }
+
+ Delete(membername);
+ Delete(mangled);
+ }
+ Setattr(n, "parms", p);
+ Delete(p);
+ Delete(self);
+ Delete(parms);
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_methodclass()
+ *
+ * This function returns the class node for a given method or class.
+ * ----------------------------------------------------------------------------- */
+
+Node *Swig_methodclass(Node *n) {
+ Node *nodetype = nodeType(n);
+ if (Cmp(nodetype, "class") == 0)
+ return n;
+ return GetFlag(n, "feature:extend") ? parentNode(parentNode(n)) : parentNode(n);
+}
+
+int Swig_directorclass(Node *n) {
+ Node *classNode = Swig_methodclass(n);
+ assert(classNode != 0);
+ return (Getattr(classNode, "vtable") != 0);
+}
+
+Node *Swig_directormap(Node *module, String *type) {
+ int is_void = !Cmp(type, "void");
+ if (!is_void && module) {
+ /* ?? follow the inheritance hierarchy? */
+
+ String *base = SwigType_base(type);
+
+ Node *directormap = Getattr(module, "wrap:directormap");
+ if (directormap)
+ return Getattr(directormap, base);
+ }
+ return 0;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_ConstructorToFunction()
+ *
+ * This function creates a C wrapper for a C constructor function.
+ * ----------------------------------------------------------------------------- */
+
+int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags) {
+ ParmList *parms;
+ Parm *prefix_args;
+ Parm *p;
+ ParmList *directorparms;
+ SwigType *type;
+ Node *classNode;
+ int use_director;
+
+ classNode = Swig_methodclass(n);
+ use_director = Swig_directorclass(n);
+
+ parms = CopyParmList(nonvoid_parms(Getattr(n, "parms")));
+
+ /* Prepend the list of prefix_args (if any) */
+ prefix_args = Getattr(n, "director:prefix_args");
+ if (prefix_args != NIL) {
+ Parm *p2, *p3;
+
+ directorparms = CopyParmList(prefix_args);
+ for (p = directorparms; nextSibling(p); p = nextSibling(p));
+ for (p2 = parms; p2; p2 = nextSibling(p2)) {
+ p3 = CopyParm(p2);
+ set_nextSibling(p, p3);
+ Delete(p3);
+ p = p3;
+ }
+ } else
+ directorparms = parms;
+
+ type = NewString(classname);
+ SwigType_add_pointer(type);
+
+ if (flags & CWRAP_EXTEND) {
+ /* Constructors with default arguments are wrapped with additional constructor methods for each default argument,
+ * however, only one extra %extend method is generated. */
+ String *call;
+ String *cres;
+ String *defaultargs = Getattr(n, "defaultargs");
+ String *code = Getattr(n, "code");
+ String *membername = Swig_name_construct(classname);
+ String *mangled = Swig_name_mangle(membername);
+
+ /* Check if the constructor 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 constructors to be defined
+ in C. */
+ if (Getattr(n, "sym:overloaded") && code) {
+ Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
+ }
+
+ /* See if there is any code that we need to emit */
+ if (!defaultargs && code) {
+ Swig_add_extension_code(n, mangled, parms, type, code, cparse_cplusplus, "self");
+ }
+
+ call = Swig_cfunction_call(mangled, parms);
+ cres = Swig_cresult(type, "result", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(cres);
+ Delete(call);
+ Delete(membername);
+ Delete(mangled);
+ } else {
+ if (cplus) {
+ /* if a C++ director class exists, create it rather than the original class */
+ if (use_director) {
+ Node *parent = Swig_methodclass(n);
+ int abstract = Getattr(parent, "abstract") != 0;
+ String *name = Getattr(parent, "sym:name");
+ String *directorname = NewStringf("SwigDirector_%s", name);
+ String *action = NewStringEmpty();
+ String *tmp_none_comparison = Copy(none_comparison);
+ String *director_call;
+ String *nodirector_call;
+
+ Replaceall(tmp_none_comparison, "$arg", "arg1");
+
+ director_call = Swig_cppconstructor_director_call(directorname, directorparms);
+ nodirector_call = Swig_cppconstructor_nodirector_call(classname, parms);
+
+ if (abstract) {
+ /* whether or not the abstract class has been subclassed in python,
+ * create a director instance (there's no way to create a normal
+ * instance). if any of the pure virtual methods haven't been
+ * implemented in the target language, calls to those methods will
+ * generate Swig::DirectorPureVirtualException exceptions.
+ */
+ String *cres = Swig_cresult(type, "result", director_call);
+ Append(action, cres);
+ Delete(cres);
+ } else {
+ /* (scottm): The code for creating a new director is now a string
+ template that gets passed in via the director_ctor argument.
+
+ $comparison : an 'if' comparison from none_comparison
+ $director_new: Call new for director class
+ $nondirector_new: Call new for non-director class
+ */
+ String *cres;
+ Append(action, director_ctor);
+ Replaceall(action, "$comparison", tmp_none_comparison);
+
+ cres = Swig_cresult(type, "result", director_call);
+ Replaceall(action, "$director_new", cres);
+ Delete(cres);
+
+ cres = Swig_cresult(type, "result", nodirector_call);
+ Replaceall(action, "$nondirector_new", cres);
+ Delete(cres);
+ }
+ Setattr(n, "wrap:action", action);
+ Delete(tmp_none_comparison);
+ Delete(action);
+ Delete(directorname);
+ } else {
+ String *call = Swig_cppconstructor_call(classname, parms);
+ String *cres = Swig_cresult(type, "result", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(cres);
+ Delete(call);
+ }
+ } else {
+ String *call = Swig_cconstructor_call(classname);
+ String *cres = Swig_cresult(type, "result", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(cres);
+ Delete(call);
+ }
+ }
+ Setattr(n, "type", type);
+ Setattr(n, "parms", parms);
+ Delete(type);
+ if (directorparms != parms)
+ Delete(directorparms);
+ Delete(parms);
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_DestructorToFunction()
+ *
+ * This function creates a C wrapper for a destructor function.
+ * ----------------------------------------------------------------------------- */
+
+int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags) {
+ SwigType *type;
+ Parm *p;
+
+ type = NewString(classname);
+ SwigType_add_pointer(type);
+ p = NewParm(type, "self");
+ Setattr(p, "self", "1");
+ Setattr(p, "hidden", "1");
+ Setattr(p, "wrap:disown", "1");
+ Delete(type);
+ type = NewString("void");
+
+ if (flags & CWRAP_EXTEND) {
+ String *cres;
+ String *call;
+ String *membername, *mangled, *code;
+ membername = Swig_name_destroy(classname);
+ mangled = Swig_name_mangle(membername);
+ code = Getattr(n, "code");
+ if (code) {
+ Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, "self");
+ }
+ call = Swig_cfunction_call(mangled, p);
+ cres = NewStringf("%s;", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(membername);
+ Delete(mangled);
+ Delete(call);
+ Delete(cres);
+ } else {
+ if (cplus) {
+ String *call = Swig_cppdestructor_call(n);
+ String *cres = NewStringf("%s", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(call);
+ Delete(cres);
+ } else {
+ String *call = Swig_cdestructor_call(n);
+ String *cres = NewStringf("%s", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(call);
+ Delete(cres);
+ }
+ }
+ Setattr(n, "type", type);
+ Setattr(n, "parms", p);
+ Delete(type);
+ Delete(p);
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_MembersetToFunction()
+ *
+ * This function creates a C wrapper for setting a structure member.
+ * ----------------------------------------------------------------------------- */
+
+int Swig_MembersetToFunction(Node *n, String *classname, int flags, String **call) {
+ String *name;
+ ParmList *parms;
+ Parm *p;
+ SwigType *t;
+ SwigType *ty;
+ SwigType *type;
+ SwigType *void_type = NewString("void");
+ String *membername;
+ String *mangled;
+ String *self = 0;
+ String *sname;
+
+ int varcref = flags & CWRAP_NATURAL_VAR;
+
+ if (flags & CWRAP_SMART_POINTER) {
+ self = NewString("(*this)->");
+ }
+ if (flags & CWRAP_ALL_PROTECTED_ACCESS) {
+ self = NewStringf("darg->");
+ }
+
+ name = Getattr(n, "name");
+ type = Getattr(n, "type");
+
+ sname = Swig_name_set(name);
+ membername = Swig_name_member(classname, sname);
+ mangled = Swig_name_mangle(membername);
+
+ t = NewString(classname);
+ SwigType_add_pointer(t);
+ parms = NewParm(t, "self");
+ Setattr(parms, "self", "1");
+ Setattr(parms, "hidden","1");
+ Delete(t);
+
+ ty = Swig_wrapped_member_var_type(type, varcref);
+ p = NewParm(ty, name);
+ Setattr(parms, "hidden", "1");
+ set_nextSibling(parms, p);
+
+ /* 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 *cres;
+ String *code = Getattr(n, "code");
+ if (code) {
+ /* I don't think this ever gets run - WSF */
+ Swig_add_extension_code(n, mangled, parms, void_type, code, cparse_cplusplus, "self");
+ }
+ *call = Swig_cfunction_call(mangled, parms);
+ cres = NewStringf("%s;", *call);
+ Setattr(n, "wrap:action", cres);
+ Delete(cres);
+ } else {
+ String *cres;
+ *call = Swig_cmemberset_call(name, type, self, varcref);
+ cres = NewStringf("%s;", *call);
+ Setattr(n, "wrap:action", cres);
+ Delete(cres);
+ }
+ Setattr(n, "type", void_type);
+ Setattr(n, "parms", parms);
+ Delete(parms);
+ Delete(ty);
+ Delete(void_type);
+ Delete(membername);
+ Delete(sname);
+ Delete(mangled);
+ Delete(self);
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_MembergetToFunction()
+ *
+ * This function creates a C wrapper for getting a structure member.
+ * ----------------------------------------------------------------------------- */
+
+int Swig_MembergetToFunction(Node *n, String *classname, int flags) {
+ String *name;
+ ParmList *parms;
+ SwigType *t;
+ SwigType *ty;
+ SwigType *type;
+ String *membername;
+ String *mangled;
+ String *self = 0;
+ String *gname;
+
+ int varcref = flags & CWRAP_NATURAL_VAR;
+
+ if (flags & CWRAP_SMART_POINTER) {
+ if (checkAttribute(n, "storage", "static")) {
+ Node *sn = Getattr(n, "cplus:staticbase");
+ String *base = Getattr(sn, "name");
+ self = NewStringf("%s::", base);
+ } else {
+ self = NewString("(*this)->");
+ }
+ }
+ if (flags & CWRAP_ALL_PROTECTED_ACCESS) {
+ self = NewStringf("darg->");
+ }
+
+ name = Getattr(n, "name");
+ type = Getattr(n, "type");
+
+ gname = Swig_name_get(name);
+ membername = Swig_name_member(classname, gname);
+ mangled = Swig_name_mangle(membername);
+
+ t = NewString(classname);
+ SwigType_add_pointer(t);
+ parms = NewParm(t, "self");
+ Setattr(parms, "self", "1");
+ Setattr(parms, "hidden","1");
+ Delete(t);
+
+ ty = Swig_wrapped_member_var_type(type, varcref);
+ if (flags & CWRAP_EXTEND) {
+ String *call;
+ String *cres;
+
+ String *code = Getattr(n, "code");
+ if (code) {
+ /* I don't think this ever gets run - WSF */
+ Swig_add_extension_code(n, mangled, parms, ty, code, cparse_cplusplus, "self");
+ }
+ call = Swig_cfunction_call(mangled, parms);
+ cres = Swig_cresult(ty, "result", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(cres);
+ Delete(call);
+ } else {
+ String *call = Swig_cmemberget_call(name, type, self, varcref);
+ String *cres = Swig_cresult(ty, "result", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(call);
+ Delete(cres);
+ }
+ Setattr(n, "type", ty);
+ Setattr(n, "parms", parms);
+ Delete(parms);
+ Delete(ty);
+ Delete(membername);
+ Delete(gname);
+ Delete(mangled);
+
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_VarsetToFunction()
+ *
+ * This function creates a C wrapper for setting a global variable or static member
+ * variable.
+ * ----------------------------------------------------------------------------- */
+
+int Swig_VarsetToFunction(Node *n, int flags) {
+ String *name, *nname;
+ ParmList *parms;
+ SwigType *type, *ty;
+
+ int varcref = flags & CWRAP_NATURAL_VAR;
+
+ name = Getattr(n, "name");
+ type = Getattr(n, "type");
+ nname = SwigType_namestr(name);
+ ty = Swig_wrapped_var_type(type, varcref);
+ parms = NewParm(ty, name);
+
+ if (flags & CWRAP_EXTEND) {
+ String *sname = Swig_name_set(name);
+ String *mangled = Swig_name_mangle(sname);
+ String *call = Swig_cfunction_call(mangled, parms);
+ String *cres = NewStringf("%s;", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(cres);
+ Delete(call);
+ Delete(mangled);
+ Delete(sname);
+ } else {
+ if (!Strstr(type, "enum $unnamed")) {
+ String *pname = Swig_cparm_name(0, 0);
+ String *dref = Swig_wrapped_var_deref(type, pname, varcref);
+ String *call = NewStringf("%s = %s;", nname, dref);
+ Setattr(n, "wrap:action", call);
+ Delete(call);
+ Delete(dref);
+ Delete(pname);
+ } else {
+ String *pname = Swig_cparm_name(0, 0);
+ String *call = NewStringf("if (sizeof(int) == sizeof(%s)) *(int*)(void*)&(%s) = %s;", nname, nname, pname);
+ Setattr(n, "wrap:action", call);
+ Delete(pname);
+ Delete(call);
+ }
+ }
+ Setattr(n, "type", "void");
+ Setattr(n, "parms", parms);
+ Delete(parms);
+ Delete(ty);
+ Delete(nname);
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_VargetToFunction()
+ *
+ * This function creates a C wrapper for getting a global variable or static member
+ * variable.
+ * ----------------------------------------------------------------------------- */
+
+int Swig_VargetToFunction(Node *n, int flags) {
+ String *cres, *call;
+ String *name;
+ SwigType *type;
+ SwigType *ty = 0;
+
+ int varcref = flags & CWRAP_NATURAL_VAR;
+
+ name = Getattr(n, "name");
+ type = Getattr(n, "type");
+ ty = Swig_wrapped_var_type(type, varcref);
+
+ if (flags & CWRAP_EXTEND) {
+ String *sname = Swig_name_get(name);
+ String *mangled = Swig_name_mangle(sname);
+ call = Swig_cfunction_call(mangled, 0);
+ cres = Swig_cresult(ty, "result", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(mangled);
+ Delete(sname);
+ } else {
+ String *nname = SwigType_namestr(name);
+ call = Swig_wrapped_var_assign(type, nname, varcref);
+ cres = Swig_cresult(ty, "result", call);
+ Setattr(n, "wrap:action", cres);
+ Delete(nname);
+ }
+
+ Setattr(n, "type", ty);
+ Delattr(n, "parms");
+ Delete(cres);
+ Delete(call);
+ Delete(ty);
+ return SWIG_OK;
+}
diff --git a/Source/Swig/deprecate.c b/Source/Swig/deprecate.c
new file mode 100644
index 0000000..475d2c6
--- /dev/null
+++ b/Source/Swig/deprecate.c
@@ -0,0 +1,105 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * deprecate.c
+ *
+ * The functions in this file are SWIG core functions that are deprecated
+ * or which do not fit in nicely with everything else. Generally this means
+ * that the function and/or API needs to be changed in some future release.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_deprecate_c[] = "$Id: parms.c 9630 2007-01-02 21:17:19Z beazley $";
+
+#include "swig.h"
+
+/* ---------------------------------------------------------------------
+ * ParmList_is_compactdefargs()
+ *
+ * Returns 1 if the parameter list passed in is marked for compact argument
+ * handling (by the "compactdefargs" attribute). Otherwise returns 0.
+ * ---------------------------------------------------------------------- */
+
+/* Discussion:
+
+ "compactdefargs" is a property set by the Parser to indicate special
+ handling of default arguments. This property seems to be something that
+ is associated with functions and methods rather than low-level ParmList
+ objects. Therefore, I don't like the fact that this special purpose
+ feature is bolted onto the side of ParmList objects.
+
+ Proposed solution:
+
+ 1. "compactdefargs" should be a feature set on function/method nodes
+ instead of ParmList objects. For example, if you have a function,
+ you would check the function node to see if the parameters are
+ to be handled in this way.
+
+
+ Difficulties:
+
+ 1. This is used by functions in cwrap.c and emit.cxx, none of which
+ are passed information about the function/method node. We might
+ have to change the API of those functions to make this work correctly.
+ For example:
+
+ int emit_num_required(ParmList *parms)
+
+ might become
+
+ int emit_num_required(ParmList *parms, int compactargs)
+
+*/
+
+int ParmList_is_compactdefargs(ParmList *p) {
+ int compactdefargs = 0;
+
+ if (p) {
+ compactdefargs = Getattr(p, "compactdefargs") ? 1 : 0;
+
+ /* The "compactdefargs" attribute should only be set on the first parameter in the list.
+ * However, sometimes an extra parameter is inserted at the beginning of the parameter list,
+ * so we check the 2nd parameter too. */
+ if (!compactdefargs) {
+ Parm *nextparm = nextSibling(p);
+ compactdefargs = (nextparm && Getattr(nextparm, "compactdefargs")) ? 1 : 0;
+ }
+ }
+
+ return compactdefargs;
+}
+
+/* ---------------------------------------------------------------------
+ * ParmList_errorstr()
+ *
+ * Generate a prototype string suitable for use in error/warning messages.
+ * This function is aware of hidden parameters.
+ * ---------------------------------------------------------------------- */
+
+/* Discussion. This function is used to generate error messages, but take
+ into account that there might be a hidden parameter. Although this involves
+ parameter lists, it really isn't a core feature of swigparm.h or parms.c.
+ This is because the "hidden" attribute of parameters is added elsewhere (cwrap.c).
+
+ For now, this function is placed here because it doesn't really seem to fit in
+ with the parms.c interface.
+
+*/
+
+String *ParmList_errorstr(ParmList *p) {
+ String *out = NewStringEmpty();
+ while (p) {
+ if (Getattr(p,"hidden")) {
+ p = nextSibling(p);
+ } else {
+ String *pstr = SwigType_str(Getattr(p, "type"), 0);
+ Append(out, pstr);
+ p = nextSibling(p);
+ if (p) {
+ Append(out, ",");
+ }
+ Delete(pstr);
+ }
+ }
+ return out;
+}
diff --git a/Source/Swig/error.c b/Source/Swig/error.c
new file mode 100644
index 0000000..84520d9
--- /dev/null
+++ b/Source/Swig/error.c
@@ -0,0 +1,277 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * error.c
+ *
+ * Error handling functions. These are used to issue warnings and
+ * error messages.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_error_c[] = "$Id: error.c 11080 2009-01-24 13:15:51Z bhy $";
+
+#include "swig.h"
+#include <stdarg.h>
+#include <ctype.h>
+
+/* -----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+#if defined(_WIN32)
+# define DEFAULT_ERROR_MSG_FORMAT EMF_MICROSOFT
+#else
+# define DEFAULT_ERROR_MSG_FORMAT EMF_STANDARD
+#endif
+static ErrorMessageFormat msg_format = DEFAULT_ERROR_MSG_FORMAT;
+static int silence = 0; /* Silent operation */
+static String *filter = 0; /* Warning filter */
+static int warnall = 0;
+static int nwarning = 0;
+static int nerrors = 0;
+
+static int init_fmt = 0;
+static char wrn_wnum_fmt[64];
+static char wrn_nnum_fmt[64];
+static char err_line_fmt[64];
+static char err_eof_fmt[64];
+
+static String *format_filename(const_String_or_char_ptr filename);
+
+/* -----------------------------------------------------------------------------
+ * Swig_warning()
+ *
+ * Issue a warning message
+ * ----------------------------------------------------------------------------- */
+
+void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const char *fmt, ...) {
+ String *out;
+ char *msg;
+ int wrn = 1;
+ va_list ap;
+ if (silence)
+ return;
+ if (!init_fmt)
+ Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT);
+
+ va_start(ap, fmt);
+
+ out = NewStringEmpty();
+ vPrintf(out, fmt, ap);
+
+ msg = Char(out);
+ if (isdigit((unsigned char) *msg)) {
+ unsigned long result = strtoul(msg, &msg, 10);
+ if (msg != Char(out)) {
+ msg++;
+ wnum = result;
+ }
+ }
+
+ /* Check in the warning filter */
+ if (filter) {
+ char temp[32];
+ char *c;
+ char *f = Char(filter);
+ sprintf(temp, "%d", wnum);
+ while (*f != '\0' && (c = strstr(f, temp))) {
+ if (*(c - 1) == '-') {
+ wrn = 0; /* Warning disabled */
+ break;
+ }
+ if (*(c - 1) == '+') {
+ wrn = 1; /* Warning enabled */
+ break;
+ }
+ f += strlen(temp);
+ }
+ }
+ if (warnall || wrn) {
+ String *formatted_filename = format_filename(filename);
+ if (wnum) {
+ Printf(stderr, wrn_wnum_fmt, formatted_filename, line, wnum);
+ } else {
+ Printf(stderr, wrn_nnum_fmt, formatted_filename, line);
+ }
+ Printf(stderr, "%s", msg);
+ nwarning++;
+ Delete(formatted_filename);
+ }
+ Delete(out);
+ va_end(ap);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_error()
+ *
+ * Issue an error message
+ * ----------------------------------------------------------------------------- */
+
+void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) {
+ va_list ap;
+ String *formatted_filename = NULL;
+
+ if (silence)
+ return;
+ if (!init_fmt)
+ Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT);
+
+ va_start(ap, fmt);
+ formatted_filename = format_filename(filename);
+ if (line > 0) {
+ Printf(stderr, err_line_fmt, formatted_filename, line);
+ } else {
+ Printf(stderr, err_eof_fmt, formatted_filename);
+ }
+ vPrintf(stderr, fmt, ap);
+ va_end(ap);
+ nerrors++;
+ Delete(formatted_filename);
+}
+
+/* -----------------------------------------------------------------------------
+ * 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_ptr wlist, int add) {
+ char *c;
+ char *cw;
+ String *s;
+ if (!filter)
+ filter = NewStringEmpty();
+
+ s = NewString("");
+ Clear(s);
+ cw = Char(wlist);
+ while (*cw != '\0') {
+ if (*cw != ' ') {
+ Putc(*cw, s);
+ }
+ ++cw;
+ }
+ c = Char(s);
+ c = strtok(c, ", ");
+ while (c) {
+ if (isdigit((int) *c) || (*c == '+') || (*c == '-')) {
+ /* Even if c is a digit, the rest of the string might not be, eg in the case of typemap
+ * warnings (a bit odd really), eg: %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) */
+ if (add) {
+ Insert(filter, 0, c);
+ if (isdigit((int) *c)) {
+ Insert(filter, 0, "-");
+ }
+ } else {
+ char *temp = (char *)malloc(sizeof(char)*strlen(c) + 2);
+ if (isdigit((int) *c)) {
+ sprintf(temp, "-%s", c);
+ } else {
+ strcpy(temp, c);
+ }
+ Replace(filter, temp, "", DOH_REPLACE_FIRST);
+ free(temp);
+ }
+ }
+ 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;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_error_msg_format()
+ *
+ * Set the type of error/warning message display
+ * ----------------------------------------------------------------------------- */
+
+void Swig_error_msg_format(ErrorMessageFormat format) {
+ const char *error = "Error";
+ const char *warning = "Warning";
+
+ const char *fmt_eof = 0;
+ const char *fmt_line = 0;
+
+ /* here 'format' could be directly a string instead of an enum, but
+ by now a switch is used to translated into one. */
+ switch (format) {
+ case EMF_MICROSOFT:
+ fmt_line = "%s(%d)";
+ fmt_eof = "%s(999999)"; /* Is there a special character for EOF? Just use a large number. */
+ break;
+ case EMF_STANDARD:
+ default:
+ fmt_line = "%s:%d";
+ fmt_eof = "%s:EOF";
+ }
+
+ sprintf(wrn_wnum_fmt, "%s: %s(%%d): ", fmt_line, warning);
+ sprintf(wrn_nnum_fmt, "%s: %s: ", fmt_line, warning);
+ sprintf(err_line_fmt, "%s: %s: ", fmt_line, error);
+ sprintf(err_eof_fmt, "%s: %s: ", fmt_eof, error);
+
+ msg_format = format;
+ init_fmt = 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * format_filename()
+ *
+ * Remove double backslashes in Windows filename paths for display
+ * ----------------------------------------------------------------------------- */
+static String *format_filename(const_String_or_char_ptr filename) {
+ String *formatted_filename = NewString(filename);
+#if defined(_WIN32)
+ Replaceall(formatted_filename, "\\\\", "\\");
+#endif
+ return formatted_filename;
+}
diff --git a/Source/Swig/fragment.c b/Source/Swig/fragment.c
new file mode 100644
index 0000000..3730c71
--- /dev/null
+++ b/Source/Swig/fragment.c
@@ -0,0 +1,181 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_fragment_c[] = "$Id: fragment.c 9632 2007-01-03 20:58:19Z beazley $";
+
+#include "swig.h"
+#include "swigwarn.h"
+
+static Hash *fragments = 0;
+static Hash *looking_fragments = 0;
+static int debug = 0;
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_fragment_register()
+ *
+ * Add a fragment. Use the original Node*, so, if something needs to be
+ * changed, lang.cxx doesn't nedd to be touched again.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_fragment_register(Node *fragment) {
+ if (Getattr(fragment, "emitonly")) {
+ Swig_fragment_emit(fragment);
+ return;
+ } else {
+ String *name = Copy(Getattr(fragment, "value"));
+ String *type = Getattr(fragment, "type");
+ if (type) {
+ SwigType *rtype = SwigType_typedef_resolve_all(type);
+ String *mangle = Swig_string_mangle(type);
+ Append(name, mangle);
+ Delete(mangle);
+ Delete(rtype);
+ if (debug)
+ Printf(stdout, "register fragment %s %s\n", name, type);
+ }
+ if (!fragments) {
+ fragments = NewHash();
+ }
+ if (!Getattr(fragments, name)) {
+ String *section = Copy(Getattr(fragment, "section"));
+ String *ccode = Copy(Getattr(fragment, "code"));
+ Hash *kwargs = Getattr(fragment, "kwargs");
+ Setmeta(ccode, "section", section);
+ if (kwargs) {
+ Setmeta(ccode, "kwargs", kwargs);
+ }
+ Setattr(fragments, name, ccode);
+ if (debug)
+ Printf(stdout, "registering fragment %s %s\n", name, section);
+ Delete(section);
+ Delete(ccode);
+ }
+ Delete(name);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_fragment_emit()
+ *
+ * Emit a fragment
+ * ----------------------------------------------------------------------------- */
+
+static
+char *char_index(char *str, char c) {
+ while (*str && (c != *str))
+ ++str;
+ return (c == *str) ? str : 0;
+}
+
+void Swig_fragment_emit(Node *n) {
+ String *code;
+ char *pc, *tok;
+ String *t;
+ String *mangle = 0;
+ String *name = 0;
+ String *type = 0;
+
+ if (!fragments) {
+ Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name);
+ return;
+ }
+
+
+ name = Getattr(n, "value");
+ if (!name) {
+ name = n;
+ }
+ type = Getattr(n, "type");
+ if (type) {
+ mangle = Swig_string_mangle(type);
+ }
+
+ if (debug)
+ Printf(stdout, "looking fragment %s %s\n", name, type);
+ t = Copy(name);
+ tok = Char(t);
+ pc = char_index(tok, ',');
+ if (pc)
+ *pc = 0;
+ while (tok) {
+ String *name = NewString(tok);
+ if (mangle)
+ Append(name, mangle);
+ if (looking_fragments && Getattr(looking_fragments, name)) {
+ return;
+ }
+ code = Getattr(fragments, name);
+ if (debug)
+ Printf(stdout, "looking subfragment %s\n", name);
+ if (code && (Strcmp(code, "ignore") != 0)) {
+ String *section = Getmeta(code, "section");
+ Hash *nn = Getmeta(code, "kwargs");
+ if (!looking_fragments)
+ looking_fragments = NewHash();
+ Setattr(looking_fragments, name, "1");
+ while (nn) {
+ if (Equal(Getattr(nn, "name"), "fragment")) {
+ if (debug)
+ Printf(stdout, "emitting fragment %s %s\n", nn, type);
+ Setfile(nn, Getfile(n));
+ Setline(nn, Getline(n));
+ Swig_fragment_emit(nn);
+ }
+ nn = nextSibling(nn);
+ }
+ 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 {
+ if (debug)
+ Printf(stdout, "emitting subfragment %s %s\n", name, section);
+ if (debug)
+ Printf(f, "/* begin fragment %s */\n", name);
+ Printf(f, "%s\n", code);
+ if (debug)
+ Printf(f, "/* end fragment %s */\n\n", name);
+ Setattr(fragments, name, "ignore");
+ Delattr(looking_fragments, name);
+ }
+ }
+ } else if (!code && type) {
+ SwigType *rtype = SwigType_typedef_resolve_all(type);
+ if (!Equal(type, rtype)) {
+ String *name = Copy(Getattr(n, "value"));
+ String *mangle = Swig_string_mangle(type);
+ Append(name, mangle);
+ Setfile(name, Getfile(n));
+ Setline(name, Getline(n));
+ Swig_fragment_emit(name);
+ Delete(mangle);
+ Delete(name);
+ }
+ Delete(rtype);
+ }
+
+ if (!code) {
+ Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name);
+ }
+ tok = pc ? pc + 1 : 0;
+ if (tok) {
+ pc = char_index(tok, ',');
+ if (pc)
+ *pc = 0;
+ }
+ Delete(name);
+ }
+ Delete(t);
+}
diff --git a/Source/Swig/getopt.c b/Source/Swig/getopt.c
new file mode 100644
index 0000000..6039905
--- /dev/null
+++ b/Source/Swig/getopt.c
@@ -0,0 +1,107 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * getopt.c
+ *
+ * Handles the parsing of command line options. This is particularly nasty
+ * compared to other utilities given that command line options can potentially
+ * be read by many different modules within SWIG. Thus, in order to make sure
+ * there are no unrecognized options, each module is required to "mark"
+ * the options that it uses. Afterwards, we can make a quick scan to make
+ * sure there are no unmarked options.
+ *
+ * TODO:
+ * - This module needs to be modified so that it doesn't call exit().
+ * Should have cleaner error handling in general.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_getopt_c[] = "$Id: getopt.c 10926 2008-11-11 22:17:40Z wsfulton $";
+
+#include "swig.h"
+
+static char **args;
+static int numargs;
+static int *marked;
+
+/* -----------------------------------------------------------------------------
+ * Swig_init_args()
+ *
+ * Initialize the argument list handler.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_init_args(int argc, char **argv) {
+ int i;
+ assert(argc > 0);
+ assert(argv);
+
+ numargs = argc;
+ args = argv;
+ marked = (int *) malloc(numargs * sizeof(int));
+ for (i = 0; i < argc; i++) {
+ marked[i] = 0;
+ }
+ marked[0] = 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_mark_arg()
+ *
+ * Marks an argument as being parsed.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_mark_arg(int n) {
+ assert(marked);
+ assert((n >= 0) && (n < numargs));
+ marked[n] = 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_check_marked()
+ *
+ * Checks to see if argument has been picked up.
+ * ----------------------------------------------------------------------------- */
+
+int Swig_check_marked(int n) {
+ assert((n >= 0) && (n < numargs));
+ return marked[n];
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_check_options()
+ *
+ * Checkers for unprocessed command line options and errors.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_check_options(int check_input) {
+ int error = 0;
+ int i;
+ int max = check_input ? numargs - 1 : numargs;
+ assert(marked);
+ for (i = 1; i < max; i++) {
+ if (!marked[i]) {
+ Printf(stderr, "swig error : Unrecognized option %s\n", args[i]);
+ error = 1;
+ }
+ }
+ if (error) {
+ Printf(stderr, "Use 'swig -help' for available options.\n");
+ exit(1);
+ }
+ if (check_input && marked[numargs - 1]) {
+ Printf(stderr, "Must specify an input file. Use -help for available options.\n");
+ exit(1);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_arg_error()
+ *
+ * Generates a generic error message and exits.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_arg_error(void) {
+ Printf(stderr, "SWIG : Unable to parse command line options.\n");
+ Printf(stderr, "Use 'swig -help' for available options.\n");
+ exit(1);
+}
diff --git a/Source/Swig/include.c b/Source/Swig/include.c
new file mode 100644
index 0000000..724b191
--- /dev/null
+++ b/Source/Swig/include.c
@@ -0,0 +1,383 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * include.c
+ *
+ * The functions in this file are used to manage files in the SWIG library.
+ * General purpose functions for opening, including, and retrieving pathnames
+ * are provided.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_include_c[] = "$Id: include.c 11080 2009-01-24 13:15:51Z bhy $";
+
+#include "swig.h"
+
+static List *directories = 0; /* List of include directories */
+static String *lastpath = 0; /* Last file that was included */
+static List *pdirectories = 0; /* List of pushed directories */
+static int dopush = 1; /* Whether to push directories */
+
+/* This functions determine whether to push/pop dirs in the preprocessor */
+void Swig_set_push_dir(int push) {
+ dopush = push;
+}
+
+int Swig_get_push_dir(void) {
+ return dopush;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_add_directory()
+ *
+ * Adds a directory to the SWIG search path.
+ * ----------------------------------------------------------------------------- */
+
+List *Swig_add_directory(const_String_or_char_ptr dirname) {
+ String *adirname;
+ if (!directories)
+ directories = NewList();
+ assert(directories);
+ if (dirname) {
+ adirname = NewString(dirname);
+ Append(directories,adirname);
+ Delete(adirname);
+ }
+ return directories;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_push_directory()
+ *
+ * Inserts a directory at the front of the SWIG search path. This is used by
+ * the preprocessor to grab files in the same directory as other included files.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_push_directory(const_String_or_char_ptr dirname) {
+ String *pdirname;
+ if (!Swig_get_push_dir())
+ return;
+ if (!pdirectories)
+ pdirectories = NewList();
+ assert(pdirectories);
+ pdirname = NewString(dirname);
+ assert(pdirname);
+ Insert(pdirectories,0,pdirname);
+ Delete(pdirname);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_pop_directory()
+ *
+ * Pops a directory off the front of the SWIG search path. This is used by
+ * the preprocessor.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_pop_directory(void) {
+ if (!Swig_get_push_dir())
+ return;
+ if (!pdirectories)
+ return;
+ Delitem(pdirectories, 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_last_file()
+ *
+ * Returns the full pathname of the last file opened.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_last_file(void) {
+ assert(lastpath);
+ return lastpath;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_search_path_any()
+ *
+ * Returns a list of the current search paths.
+ * ----------------------------------------------------------------------------- */
+
+static List *Swig_search_path_any(int syspath) {
+ String *filename;
+ List *slist;
+ int i, ilen;
+
+ slist = NewList();
+ assert(slist);
+ filename = NewStringEmpty();
+ assert(filename);
+#ifdef MACSWIG
+ Printf(filename, "%s", SWIG_FILE_DELIMITER);
+#else
+ Printf(filename, ".%s", SWIG_FILE_DELIMITER);
+#endif
+ Append(slist, filename);
+ Delete(filename);
+
+ /* If there are any pushed directories. Add them first */
+ if (pdirectories) {
+ ilen = Len(pdirectories);
+ for (i = 0; i < ilen; i++) {
+ filename = NewString(Getitem(pdirectories,i));
+ Append(filename,SWIG_FILE_DELIMITER);
+ Append(slist,filename);
+ Delete(filename);
+ }
+ }
+ /* Add system directories next */
+ ilen = Len(directories);
+ for (i = 0; i < ilen; i++) {
+ filename = NewString(Getitem(directories,i));
+ Append(filename,SWIG_FILE_DELIMITER);
+ if (syspath) {
+ /* If doing a system include, put the system directories first */
+ Insert(slist,i,filename);
+ } else {
+ /* Otherwise, just put the system directories after the pushed directories (if any) */
+ Append(slist,filename);
+ }
+ Delete(filename);
+ }
+ return slist;
+}
+
+List *Swig_search_path() {
+ return Swig_search_path_any(0);
+}
+
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_open()
+ *
+ * open a file, optionally looking for it in the include path. Returns an open
+ * FILE * on success.
+ * ----------------------------------------------------------------------------- */
+
+static FILE *Swig_open_file(const_String_or_char_ptr name, int sysfile, int use_include_path) {
+ FILE *f;
+ String *filename;
+ List *spath = 0;
+ char *cname;
+ int i, ilen;
+
+ if (!directories)
+ directories = NewList();
+ assert(directories);
+
+ cname = Char(name);
+ filename = NewString(cname);
+ assert(filename);
+ f = fopen(Char(filename), "r");
+ if (!f && use_include_path) {
+ spath = Swig_search_path_any(sysfile);
+ ilen = Len(spath);
+ for (i = 0; i < ilen; i++) {
+ Clear(filename);
+ Printf(filename, "%s%s", Getitem(spath, i), cname);
+ f = fopen(Char(filename), "r");
+ if (f)
+ break;
+ }
+ Delete(spath);
+ }
+ if (f) {
+ Delete(lastpath);
+ lastpath = Swig_filename_escape(filename);
+ }
+ Delete(filename);
+ return f;
+}
+
+/* Open a file - searching the include paths to find it */
+FILE *Swig_include_open(const_String_or_char_ptr name) {
+ return Swig_open_file(name, 0, 1);
+}
+
+/* Open a file - does not use include paths to find it */
+FILE *Swig_open(const_String_or_char_ptr name) {
+ return Swig_open_file(name, 0, 0);
+}
+
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_read_file()
+ *
+ * Reads data from an open FILE * and returns it as a string.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_read_file(FILE *f) {
+ int len;
+ char buffer[4096];
+ String *str = NewStringEmpty();
+
+ assert(str);
+ while (fgets(buffer, 4095, f)) {
+ Append(str, buffer);
+ }
+ len = Len(str);
+ if (len) {
+ char *cstr = Char(str);
+ if (cstr[len - 1] != '\n') {
+ Append(str, "\n");
+ }
+ }
+ return str;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_include()
+ *
+ * Opens a file and returns it as a string.
+ * ----------------------------------------------------------------------------- */
+
+static String *Swig_include_any(const_String_or_char_ptr name, int sysfile) {
+ FILE *f;
+ String *str;
+ String *file;
+
+ f = Swig_open_file(name, sysfile, 1);
+ if (!f)
+ return 0;
+ str = Swig_read_file(f);
+ fclose(f);
+ Seek(str, 0, SEEK_SET);
+ file = Copy(lastpath);
+ Setfile(str, file);
+ Delete(file);
+ Setline(str, 1);
+ return str;
+}
+
+String *Swig_include(const_String_or_char_ptr name) {
+ return Swig_include_any(name, 0);
+}
+
+String *Swig_include_sys(const_String_or_char_ptr name) {
+ return Swig_include_any(name, 1);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_insert_file()
+ *
+ * Copies the contents of a file into another file
+ * ----------------------------------------------------------------------------- */
+
+int Swig_insert_file(const_String_or_char_ptr filename, File *outfile) {
+ char buffer[4096];
+ int nbytes;
+ FILE *f = Swig_include_open(filename);
+
+ if (!f)
+ return -1;
+ while ((nbytes = Read(f, buffer, 4096)) > 0) {
+ Write(outfile, buffer, nbytes);
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_register_filebyname()
+ *
+ * Register a "named" file with the core. Named files can become targets
+ * for %insert directives and other SWIG operations. This function takes
+ * the place of the f_header, f_wrapper, f_init, and other global variables
+ * in SWIG1.1
+ * ----------------------------------------------------------------------------- */
+
+static Hash *named_files = 0;
+
+void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile) {
+ if (!named_files)
+ named_files = NewHash();
+ Setattr(named_files, filename, outfile);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_filebyname()
+ *
+ * Get a named file
+ * ----------------------------------------------------------------------------- */
+
+File *Swig_filebyname(const_String_or_char_ptr filename) {
+ if (!named_files)
+ return 0;
+ return Getattr(named_files, filename);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_file_suffix()
+ *
+ * Returns the suffix of a file
+ * ----------------------------------------------------------------------------- */
+
+char *Swig_file_suffix(const_String_or_char_ptr filename) {
+ char *d;
+ char *c = Char(filename);
+ int len = Len(filename);
+ if (strlen(c)) {
+ d = c + len - 1;
+ while (d != c) {
+ if (*d == '.')
+ return d;
+ d--;
+ }
+ return c + len;
+ }
+ return c;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_file_basename()
+ *
+ * Returns the filename with no suffix attached.
+ * ----------------------------------------------------------------------------- */
+
+char *Swig_file_basename(const_String_or_char_ptr 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_ptr filename) {
+ static char tmp[1024];
+ const char *delim = SWIG_FILE_DELIMITER;
+ char *c;
+
+ strcpy(tmp, Char(filename));
+ c = strrchr(tmp, *delim);
+ if (c)
+ 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_ptr filename) {
+ static char tmp[1024];
+ const char *delim = SWIG_FILE_DELIMITER;
+ 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/misc.c b/Source/Swig/misc.c
new file mode 100644
index 0000000..ce4e50c
--- /dev/null
+++ b/Source/Swig/misc.c
@@ -0,0 +1,1156 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * misc.c
+ *
+ * Miscellaneous functions that don't really fit anywhere else.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_misc_c[] = "$Id: misc.c 11133 2009-02-20 07:52:24Z wsfulton $";
+
+#include "swig.h"
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+
+static char *fake_version = 0;
+
+/* -----------------------------------------------------------------------------
+ * Swig_copy_string()
+ *
+ * Duplicate a NULL-terminate string given as a char *.
+ * ----------------------------------------------------------------------------- */
+
+char *Swig_copy_string(const char *s) {
+ char *c = 0;
+ if (s) {
+ c = (char *) malloc(strlen(s) + 1);
+ strcpy(c, s);
+ }
+ return c;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_set_fakeversion()
+ *
+ * Version string override
+ * ----------------------------------------------------------------------------- */
+
+void Swig_set_fakeversion(const char *version) {
+ fake_version = Swig_copy_string(version);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_package_version()
+ *
+ * Return the package string containing the version number
+ * ----------------------------------------------------------------------------- */
+
+const char *Swig_package_version(void) {
+ return fake_version ? fake_version : PACKAGE_VERSION;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_banner()
+ *
+ * Emits the SWIG identifying banner for the C/C++ wrapper file.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_banner(File *f) {
+ Printf(f, "/* ----------------------------------------------------------------------------\n\
+ * This file was automatically generated by SWIG (http://www.swig.org).\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", Swig_package_version());
+ /* String too long for ISO compliance */
+ Printf(f, " * ----------------------------------------------------------------------------- */\n");
+
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_banner_target_lang()
+ *
+ * Emits a SWIG identifying banner in the target language
+ * ----------------------------------------------------------------------------- */
+
+void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar) {
+ Printf(f, "%s This file was automatically generated by SWIG (http://www.swig.org).\n", commentchar);
+ Printf(f, "%s Version %s\n", commentchar, Swig_package_version());
+ Printf(f, "%s\n", commentchar);
+ Printf(f, "%s Do not make changes to this file unless you know what you are doing--modify\n", commentchar);
+ Printf(f, "%s the SWIG interface file instead.\n", commentchar);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_strip_c_comments()
+ *
+ * Return a new string with C comments stripped from the input string. Null is
+ * returned if there aren't any.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_strip_c_comments(const String *s) {
+ const char *c = Char(s);
+ const char *comment_begin = 0;
+ const char *comment_end = 0;
+ String *stripped = 0;
+
+ while (*c) {
+ if (!comment_begin && *c == '/') {
+ ++c;
+ if (!*c)
+ break;
+ if (*c == '*')
+ comment_begin = c-1;
+ } else if (comment_begin && !comment_end && *c == '*') {
+ ++c;
+ if (*c == '/')
+ comment_end = c;
+ break;
+ }
+ ++c;
+ }
+
+ if (comment_begin && comment_end) {
+ int size = comment_begin - Char(s);
+ String *stripmore = 0;
+ stripped = NewStringWithSize(s, size);
+ Printv(stripped, comment_end + 1, NIL);
+ do {
+ stripmore = Swig_strip_c_comments(stripped);
+ if (stripmore) {
+ Delete(stripped);
+ stripped = stripmore;
+ }
+ } while (stripmore);
+ }
+ return stripped;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_filename_correct()
+ *
+ * Corrects filenames on non-unix systems
+ * ----------------------------------------------------------------------------- */
+
+void Swig_filename_correct(String *filename) {
+ (void)filename;
+#if defined(_WIN32) || defined(MACSWIG)
+ /* accept Unix path separator on non-Unix systems */
+ Replaceall(filename, "/", SWIG_FILE_DELIMITER);
+#endif
+#if defined(__CYGWIN__)
+ /* accept Windows path separator in addition to Unix path separator */
+ Replaceall(filename, "\\", SWIG_FILE_DELIMITER);
+#endif
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_filename_escape()
+ *
+ * Escapes backslashes in filename - for Windows
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_filename_escape(String *filename) {
+ String *adjusted_filename = Copy(filename);
+#if defined(_WIN32) /* Note not on Cygwin else filename is displayed with double '/' */
+ Replaceall(adjusted_filename, "\\\\", "\\"); /* remove double '\' in case any already present */
+ Replaceall(adjusted_filename, "\\", "\\\\");
+#endif
+ return adjusted_filename;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_escape()
+ *
+ * Takes a string object and produces a string with escape codes added to it.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_escape(String *s) {
+ String *ns;
+ int c;
+ ns = NewStringEmpty();
+
+ while ((c = Getc(s)) != EOF) {
+ if (c == '\n') {
+ Printf(ns, "\\n");
+ } else if (c == '\r') {
+ Printf(ns, "\\r");
+ } else if (c == '\t') {
+ Printf(ns, "\\t");
+ } else if (c == '\\') {
+ Printf(ns, "\\\\");
+ } else if (c == '\'') {
+ Printf(ns, "\\'");
+ } else if (c == '\"') {
+ Printf(ns, "\\\"");
+ } else if (c == ' ') {
+ Putc(c, ns);
+ } else if (!isgraph(c)) {
+ if (c < 0)
+ c += UCHAR_MAX + 1;
+ Printf(ns, "\\%o", c);
+ } else {
+ Putc(c, ns);
+ }
+ }
+ return ns;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_upper()
+ *
+ * Takes a string object and returns a copy that is uppercase
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_upper(String *s) {
+ String *ns;
+ int c;
+ ns = NewStringEmpty();
+
+ Seek(s, 0, SEEK_SET);
+ while ((c = Getc(s)) != EOF) {
+ Putc(toupper(c), ns);
+ }
+ return ns;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_lower()
+ *
+ * Takes a string object and returns a copy that is lowercase
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_lower(String *s) {
+ String *ns;
+ int c;
+ ns = NewStringEmpty();
+
+ Seek(s, 0, SEEK_SET);
+ while ((c = Getc(s)) != EOF) {
+ Putc(tolower(c), ns);
+ }
+ return ns;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_title()
+ *
+ * Takes a string object and returns a copy that is lowercase with first letter
+ * capitalized
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_title(String *s) {
+ String *ns;
+ int first = 1;
+ int c;
+ ns = NewStringEmpty();
+
+ Seek(s, 0, SEEK_SET);
+ while ((c = Getc(s)) != EOF) {
+ Putc(first ? toupper(c) : tolower(c), ns);
+ first = 0;
+ }
+ return ns;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_ccase()
+ *
+ * Takes a string object and returns a copy that is lowercase with the first
+ * letter capitalized and the one following '_', which are removed.
+ *
+ * camel_case -> CamelCase
+ * camelCase -> CamelCase
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_ccase(String *s) {
+ String *ns;
+ int first = 1;
+ int c;
+ ns = NewStringEmpty();
+
+ Seek(s, 0, SEEK_SET);
+ while ((c = Getc(s)) != EOF) {
+ if (c == '_') {
+ first = 1;
+ continue;
+ }
+ Putc(first ? toupper(c) : c, ns);
+ first = 0;
+ }
+ return ns;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_lccase()
+ *
+ * Takes a string object and returns a copy with the character after
+ * each '_' capitalised, and the '_' removed. The first character is
+ * also forced to lowercase.
+ *
+ * camel_case -> camelCase
+ * CamelCase -> camelCase
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_lccase(String *s) {
+ String *ns;
+ int first = 1;
+ int after_underscore = 0;
+ int c;
+ ns = NewStringEmpty();
+
+ Seek(s, 0, SEEK_SET);
+ while ((c = Getc(s)) != EOF) {
+ if (c == '_') {
+ after_underscore = 1;
+ continue;
+ }
+ if (first) {
+ Putc(tolower(c), ns);
+ first = 0;
+ } else {
+ Putc(after_underscore ? toupper(c) : c, ns);
+ }
+ after_underscore = 0;
+ }
+ return ns;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_ucase()
+ *
+ * This is the reverse case of ccase, ie
+ *
+ * CamelCase -> camel_case
+ * get2D -> get_2d
+ * asFloat2 -> as_float2
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_ucase(String *s) {
+ String *ns;
+ int c;
+ int lastC = 0;
+ int nextC = 0;
+ int underscore = 0;
+ ns = NewStringEmpty();
+
+ /* We insert a underscore when:
+ 1. Lower case char followed by upper case char
+ getFoo > get_foo; getFOo > get_foo; GETFOO > getfoo
+ 2. Number proceded by char and not end of string
+ get2D > get_2d; get22D > get_22d; GET2D > get_2d
+ but:
+ asFloat2 > as_float2
+ */
+
+ Seek(s, 0, SEEK_SET);
+
+ while ((c = Getc(s)) != EOF) {
+ nextC = Getc(s); Ungetc(nextC, s);
+ if (isdigit(c) && isalpha(lastC) && nextC != EOF)
+ underscore = 1;
+ else if (isupper(c) && isalpha(lastC) && !isupper(lastC))
+ underscore = 1;
+
+ lastC = c;
+
+ if (underscore) {
+ Putc('_', ns);
+ underscore = 0;
+ }
+
+ Putc(tolower(c), ns);
+ }
+ return ns;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_first_upper()
+ *
+ * Make the first character in the string uppercase, leave all the
+ * rest the same. This is used by the Ruby module to provide backwards
+ * compatibility with the old way of naming classes and constants. For
+ * more info see the Ruby documentation.
+ *
+ * firstUpper -> FirstUpper
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_first_upper(String *s) {
+ String *ns = NewStringEmpty();
+ char *cs = Char(s);
+ if (cs && cs[0] != 0) {
+ Putc(toupper((int)cs[0]), ns);
+ Append(ns, cs + 1);
+ }
+ return ns;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_first_lower()
+ *
+ * Make the first character in the string lowercase, leave all the
+ * rest the same. This is used by the Ruby module to provide backwards
+ * compatibility with the old way of naming classes and constants. For
+ * more info see the Ruby documentation.
+ *
+ * firstLower -> FirstLower
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_first_lower(String *s) {
+ String *ns = NewStringEmpty();
+ char *cs = Char(s);
+ if (cs && cs[0] != 0) {
+ Putc(tolower((int)cs[0]), ns);
+ Append(ns, cs + 1);
+ }
+ return ns;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_schemify()
+ *
+ * Replace underscores with dashes, to make identifiers look nice to Schemers.
+ *
+ * under_scores -> under-scores
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_schemify(String *s) {
+ String *ns = NewString(s);
+ Replaceall(ns, "_", "-");
+ 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 = NewStringEmpty();
+ while ((c = Getc(s)) != EOF) {
+ if (c == '`') {
+ String *str = 0;
+ tc = NewStringEmpty();
+ while ((c = Getc(s)) != EOF) {
+ if (c == '`')
+ break;
+ Putc(c, tc);
+ }
+ str = SwigType_str(tc, 0);
+ Append(ns, str);
+ Delete(str);
+ } 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()
+ *
+ * Take a string and mangle it by stripping all non-valid C identifier
+ * characters.
+ *
+ * This routine skips unnecessary blank spaces, therefore mangling
+ * 'char *' and 'char*', 'std::pair<int, int >' and
+ * 'std::pair<int,int>', produce the same result.
+ *
+ * However, note that 'long long' and 'long_long' produce different
+ * mangled strings.
+ *
+ * The mangling method still is not 'perfect', for example std::pair and
+ * std_pair return the same mangling. This is just a little better
+ * than before, but it seems to be enough for most of the purposes.
+ *
+ * Having a perfect mangling will break some examples and code which
+ * assume, for example, that A::get_value will be mangled as
+ * A_get_value.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_mangle(const String *s) {
+#if 0
+ /* old mangling, not suitable for using in macros */
+ String *t = Copy(s);
+ char *c = Char(t);
+ while (*c) {
+ if (!isalnum(*c))
+ *c = '_';
+ c++;
+ }
+ return t;
+#else
+ String *result = NewStringEmpty();
+ int space = 0;
+ int state = 0;
+ char *pc, *cb;
+ String *b = Copy(s);
+ if (SwigType_istemplate(b)) {
+ String *st = Swig_symbol_template_deftype(b, 0);
+ String *sq = Swig_symbol_type_qualify(st, 0);
+ String *t = SwigType_namestr(sq);
+ Delete(st);
+ Delete(sq);
+ Delete(b);
+ b = t;
+ }
+ pc = cb = Char(b);
+ while (*pc) {
+ char c = *pc;
+ if (isalnum((int) c) || (c == '_')) {
+ state = 1;
+ if (space && (space == state)) {
+ Append(result, "_SS_");
+ }
+ space = 0;
+ Printf(result, "%c", (int) c);
+
+ } else {
+ if (isspace((int) c)) {
+ space = state;
+ ++pc;
+ continue;
+ } else {
+ state = 3;
+ space = 0;
+ }
+ switch (c) {
+ case '.':
+ if ((cb != pc) && (*(pc - 1) == 'p')) {
+ Append(result, "_");
+ ++pc;
+ continue;
+ } else {
+ c = 'f';
+ }
+ break;
+ case ':':
+ if (*(pc + 1) == ':') {
+ Append(result, "_");
+ ++pc;
+ ++pc;
+ continue;
+ }
+ break;
+ case '*':
+ c = 'm';
+ break;
+ case '&':
+ c = 'A';
+ 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 = 'o';
+ break;
+ case '~':
+ c = 'n';
+ break;
+ case '!':
+ c = 'N';
+ break;
+ case '%':
+ c = 'M';
+ break;
+ case '?':
+ c = 'q';
+ break;
+ case '+':
+ c = 'a';
+ break;
+ case '-':
+ c = 's';
+ break;
+ case '/':
+ c = 'd';
+ break;
+ default:
+ break;
+ }
+ if (isalpha((int) c)) {
+ Printf(result, "_S%c_", (int) c);
+ } else {
+ Printf(result, "_S%02X_", (int) c);
+ }
+ }
+ ++pc;
+ }
+ Delete(b);
+ return result;
+#endif
+}
+
+String *Swig_string_emangle(String *s) {
+ return Swig_string_mangle(s);
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_scopename_prefix()
+ *
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_scopename_split(const String *s, String **rprefix, String **rlast) {
+ char *tmp = Char(s);
+ char *c = tmp;
+ char *cc = c;
+ char *co = 0;
+ if (!strstr(c, "::")) {
+ *rprefix = 0;
+ *rlast = Copy(s);
+ }
+
+ co = strstr(cc, "operator ");
+ if (co) {
+ if (co == cc) {
+ *rprefix = 0;
+ *rlast = Copy(s);
+ return;
+ } else {
+ *rprefix = NewStringWithSize(cc, co - cc - 2);
+ *rlast = NewString(co);
+ return;
+ }
+ }
+ while (*c) {
+ if ((*c == ':') && (*(c + 1) == ':')) {
+ cc = c;
+ c += 2;
+ } else {
+ if (*c == '<') {
+ int level = 1;
+ c++;
+ while (*c && level) {
+ if (*c == '<')
+ level++;
+ if (*c == '>')
+ level--;
+ c++;
+ }
+ } else {
+ c++;
+ }
+ }
+ }
+
+ if (cc != tmp) {
+ *rprefix = NewStringWithSize(tmp, cc - tmp);
+ *rlast = NewString(cc + 2);
+ return;
+ } else {
+ *rprefix = 0;
+ *rlast = Copy(s);
+ }
+}
+
+
+String *Swig_scopename_prefix(const String *s) {
+ char *tmp = Char(s);
+ char *c = tmp;
+ char *cc = c;
+ char *co = 0;
+ if (!strstr(c, "::"))
+ return 0;
+ co = strstr(cc, "operator ");
+
+ if (co) {
+ if (co == cc) {
+ return 0;
+ } else {
+ String *prefix = NewStringWithSize(cc, co - cc - 2);
+ return prefix;
+ }
+ }
+ while (*c) {
+ if ((*c == ':') && (*(c + 1) == ':')) {
+ cc = c;
+ c += 2;
+ } else {
+ if (*c == '<') {
+ int level = 1;
+ c++;
+ while (*c && level) {
+ if (*c == '<')
+ level++;
+ if (*c == '>')
+ level--;
+ c++;
+ }
+ } else {
+ c++;
+ }
+ }
+ }
+
+ if (cc != tmp) {
+ return NewStringWithSize(tmp, cc - 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(const String *s) {
+ char *tmp = Char(s);
+ char *c = tmp;
+ char *cc = c;
+ char *co = 0;
+ if (!strstr(c, "::"))
+ return NewString(s);
+
+ co = strstr(cc, "operator ");
+ if (co) {
+ return NewString(co);
+ }
+
+
+ while (*c) {
+ if ((*c == ':') && (*(c + 1) == ':')) {
+ 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(const String *s) {
+ char *tmp = Char(s);
+ char *c = tmp;
+ char *co = 0;
+ if (!strstr(c, "::"))
+ return 0;
+
+ co = strstr(c, "operator ");
+ if (co) {
+ if (co == c) {
+ return 0;
+ }
+ } else {
+ co = c + Len(s);
+ }
+
+ while (*c && (c != co)) {
+ if ((*c == ':') && (*(c + 1) == ':')) {
+ 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 NewStringWithSize(tmp, c - 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(const String *s) {
+ char *tmp = Char(s);
+ char *c = tmp;
+ char *co = 0;
+ if (!strstr(c, "::"))
+ return 0;
+
+ co = strstr(c, "operator ");
+ if (co) {
+ if (co == c)
+ return 0;
+ }
+ while (*c) {
+ if ((*c == ':') && (*(c + 1) == ':')) {
+ 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(const String *s) {
+ char *c = Char(s);
+ char *co = strstr(c, "operator ");
+
+ if (co) {
+ if (co == c)
+ return 0;
+ }
+ if (!strstr(c, "::"))
+ return 0;
+ while (*c) {
+ if ((*c == ':') && (*(c + 1) == ':')) {
+ return 1;
+ } else {
+ if (*c == '<') {
+ int level = 1;
+ c++;
+ while (*c && level) {
+ if (*c == '<')
+ level++;
+ if (*c == '>')
+ level--;
+ c++;
+ }
+ } else {
+ c++;
+ }
+ }
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_command()
+ *
+ * Executes a external command via popen with the string as a command
+ * line parameter. For example:
+ *
+ * Printf(stderr,"%(command:sed 's/[a-z]/\U\\1/' <<<)s","hello") -> Hello
+ * ----------------------------------------------------------------------------- */
+#if defined(HAVE_POPEN)
+# if defined(_MSC_VER)
+# define popen _popen
+# define pclose _pclose
+# else
+extern FILE *popen(const char *command, const char *type);
+extern int pclose(FILE *stream);
+# endif
+#else
+# if defined(_MSC_VER)
+# define HAVE_POPEN 1
+# define popen _popen
+# define pclose _pclose
+# endif
+#endif
+
+String *Swig_string_command(String *s) {
+ String *res = NewStringEmpty();
+#if defined(HAVE_POPEN)
+ if (Len(s)) {
+ char *command = Char(s);
+ FILE *fp = popen(command, "r");
+ if (fp) {
+ char buffer[1025];
+ while (fscanf(fp, "%1024s", buffer) != EOF) {
+ Append(res, buffer);
+ }
+ pclose(fp);
+ } else {
+ Swig_error("SWIG", Getline(s), "Command encoder fails attempting '%s'.\n", s);
+ exit(1);
+ }
+ }
+#endif
+ return res;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_strip()
+ *
+ * Strip given prefix from identifiers
+ *
+ * Printf(stderr,"%(strip:[wx])s","wxHello") -> Hello
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_string_strip(String *s) {
+ String *ns;
+ if (!Len(s)) {
+ ns = NewString(s);
+ } else {
+ const char *cs = Char(s);
+ const char *ce = Strchr(cs, ']');
+ if (*cs != '[' || ce == NULL) {
+ ns = NewString(s);
+ } else {
+ String *fmt = NewStringf("%%.%ds", ce-cs-1);
+ String *prefix = NewStringf(fmt, cs+1);
+ if (0 == Strncmp(ce+1, prefix, Len(prefix))) {
+ ns = NewString(ce+1+Len(prefix));
+ } else {
+ ns = NewString(ce+1);
+ }
+ }
+ }
+ return ns;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_string_rxspencer()
+ *
+ * Executes a regexp substitution via the RxSpencer library. For example:
+ *
+ * Printf(stderr,"gsl%(rxspencer:[GSL_.*_][@1])s","GSL_Hello_") -> gslHello
+ * ----------------------------------------------------------------------------- */
+#if defined(HAVE_RXSPENCER)
+#include <sys/types.h>
+#include <rxspencer/regex.h>
+#define USE_RXSPENCER
+#endif
+
+const char *skip_delim(char pb, char pe, const char *ce) {
+ int end = 0;
+ int lb = 0;
+ while (!end && *ce != '\0') {
+ if (*ce == pb) {
+ ++lb;
+ }
+ if (*ce == pe) {
+ if (!lb) {
+ end = 1;
+ --ce;
+ } else {
+ --lb;
+ }
+ }
+ ++ce;
+ }
+ return end ? ce : 0;
+}
+
+
+#if defined(USE_RXSPENCER)
+String *Swig_string_rxspencer(String *s) {
+ String *res = 0;
+ if (Len(s)) {
+ const char *cs = Char(s);
+ const char *cb;
+ const char *ce;
+ if (*cs == '[') {
+ int retval;
+ regex_t compiled;
+ cb = ++cs;
+ ce = skip_delim('[', ']', cb);
+ if (ce) {
+ char bregexp[512];
+ strncpy(bregexp, cb, ce - cb);
+ bregexp[ce - cb] = '\0';
+ ++ce;
+ retval = regcomp(&compiled, bregexp, REG_EXTENDED);
+ if (retval == 0) {
+ cs = ce;
+ if (*cs == '[') {
+ cb = ++cs;
+ ce = skip_delim('[', ']', cb);
+ if (ce) {
+ const char *cvalue = ce + 1;
+ int nsub = (int) compiled.re_nsub + 1;
+ regmatch_t *pmatch = (regmatch_t *) malloc(sizeof(regmatch_t) * (nsub));
+ retval = regexec(&compiled, cvalue, nsub, pmatch, 0);
+ if (retval != REG_NOMATCH) {
+ char *spos = 0;
+ res = NewStringWithSize(cb, ce - cb);
+ spos = Strchr(res, '@');
+ while (spos) {
+ char cd = *(++spos);
+ if (isdigit(cd)) {
+ char arg[8];
+ size_t len;
+ int i = cd - '0';
+ sprintf(arg, "@%d", i);
+ if (i < nsub && (len = pmatch[i].rm_eo - pmatch[i].rm_so)) {
+ char value[256];
+ strncpy(value, cvalue + pmatch[i].rm_so, len);
+ value[len] = 0;
+ Replaceall(res, arg, value);
+ } else {
+ Replaceall(res, arg, "");
+ }
+ spos = Strchr(res, '@');
+ } else if (cd == '@') {
+ spos = strchr(spos + 1, '@');
+ }
+ }
+ }
+ free(pmatch);
+ }
+ }
+ }
+ regfree(&compiled);
+ }
+ }
+ }
+ if (!res)
+ res = NewStringEmpty();
+ return res;
+}
+#else
+String *Swig_string_rxspencer(String *s) {
+ (void) s;
+ return NewStringEmpty();
+}
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_init()
+ *
+ * Initialize the SWIG core
+ * ----------------------------------------------------------------------------- */
+
+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("ctitle", Swig_string_ccase);
+ DohEncoding("lctitle", Swig_string_lccase);
+ DohEncoding("utitle", Swig_string_ucase);
+ DohEncoding("typecode", Swig_string_typecode);
+ DohEncoding("mangle", Swig_string_emangle);
+ DohEncoding("command", Swig_string_command);
+ DohEncoding("rxspencer", Swig_string_rxspencer);
+ DohEncoding("schemify", Swig_string_schemify);
+ DohEncoding("strip", Swig_string_strip);
+
+ /* aliases for the case encoders */
+ DohEncoding("uppercase", Swig_string_upper);
+ DohEncoding("lowercase", Swig_string_lower);
+ DohEncoding("camelcase", Swig_string_ccase);
+ DohEncoding("lowercamelcase", Swig_string_lccase);
+ DohEncoding("undercase", Swig_string_ucase);
+ DohEncoding("firstuppercase", Swig_string_first_upper);
+ DohEncoding("firstlowercase", Swig_string_first_lower);
+
+ /* Initialize typemaps */
+ Swig_typemap_init();
+
+ /* Initialize symbol table */
+ Swig_symbol_init();
+
+ /* Initialize type system */
+ SwigType_typesystem_init();
+
+ /* Initialize template system */
+ SwigType_template_init();
+}
diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c
new file mode 100644
index 0000000..1398de8
--- /dev/null
+++ b/Source/Swig/naming.c
@@ -0,0 +1,1652 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * naming.c
+ *
+ * Functions for generating various kinds of names during code generation.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_naming_c[] = "$Id: naming.c 11454 2009-07-26 21:21:26Z wsfulton $";
+
+#include "swig.h"
+#include "cparse.h"
+#include <ctype.h>
+
+/* Hash table containing naming data */
+
+static Hash *naming_hash = 0;
+
+#if 0
+#define SWIG_DEBUG
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_register()
+ *
+ * Register a new naming format.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format) {
+ if (!naming_hash)
+ naming_hash = NewHash();
+ Setattr(naming_hash, method, format);
+}
+
+void Swig_name_unregister(const_String_or_char_ptr 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((int) *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()
+ *
+ * Converts all of the non-identifier characters of a string to underscores.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_mangle(const_String_or_char_ptr s) {
+#if 0
+ String *r = NewString(s);
+ name_mangle(r);
+ return r;
+#else
+ return Swig_string_mangle(s);
+#endif
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_wrapper()
+ *
+ * Returns the name of a wrapper function.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_wrapper(const_String_or_char_ptr fname) {
+ String *r;
+ String *f;
+
+ r = NewStringEmpty();
+ if (!naming_hash)
+ naming_hash = NewHash();
+ f = Getattr(naming_hash, "wrapper");
+ if (!f) {
+ Append(r, "_wrap_%f");
+ } else {
+ Append(r, f);
+ }
+ Replace(r, "%f", fname, DOH_REPLACE_ANY);
+ name_mangle(r);
+ return r;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_member()
+ *
+ * Returns the name of a class method.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_member(const_String_or_char_ptr classname, const_String_or_char_ptr mname) {
+ String *r;
+ String *f;
+ String *rclassname;
+ char *cname;
+
+ rclassname = SwigType_namestr(classname);
+ r = NewStringEmpty();
+ if (!naming_hash)
+ naming_hash = NewHash();
+ f = Getattr(naming_hash, "member");
+ if (!f) {
+ Append(r, "%c_%m");
+ } 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);
+ Replace(r, "%m", mname, DOH_REPLACE_ANY);
+ /* name_mangle(r); */
+ Delete(rclassname);
+ return r;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_get()
+ *
+ * Returns the name of the accessor function used to get a variable.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_get(const_String_or_char_ptr vname) {
+ String *r;
+ String *f;
+
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_name_get: '%s'\n", vname);
+#endif
+
+ r = NewStringEmpty();
+ if (!naming_hash)
+ naming_hash = NewHash();
+ f = Getattr(naming_hash, "get");
+ if (!f) {
+ Append(r, "%v_get");
+ } else {
+ Append(r, f);
+ }
+ Replace(r, "%v", vname, DOH_REPLACE_ANY);
+ /* name_mangle(r); */
+ return r;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_set()
+ *
+ * Returns the name of the accessor function used to set a variable.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_set(const_String_or_char_ptr vname) {
+ String *r;
+ String *f;
+
+ r = NewStringEmpty();
+ if (!naming_hash)
+ naming_hash = NewHash();
+ f = Getattr(naming_hash, "set");
+ if (!f) {
+ Append(r, "%v_set");
+ } else {
+ Append(r, f);
+ }
+ Replace(r, "%v", vname, DOH_REPLACE_ANY);
+ /* name_mangle(r); */
+ return r;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_construct()
+ *
+ * Returns the name of the accessor function used to create an object.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_construct(const_String_or_char_ptr classname) {
+ String *r;
+ String *f;
+ String *rclassname;
+ char *cname;
+
+ rclassname = SwigType_namestr(classname);
+ r = NewStringEmpty();
+ if (!naming_hash)
+ naming_hash = NewHash();
+ f = Getattr(naming_hash, "construct");
+ if (!f) {
+ Append(r, "new_%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);
+ 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_ptr classname) {
+ String *r;
+ String *f;
+ String *rclassname;
+ char *cname;
+
+ rclassname = SwigType_namestr(classname);
+ r = NewStringEmpty();
+ if (!naming_hash)
+ naming_hash = NewHash();
+ f = Getattr(naming_hash, "copy");
+ if (!f) {
+ Append(r, "copy_%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);
+ Delete(rclassname);
+ return r;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_destroy()
+ *
+ * Returns the name of the accessor function used to destroy an object.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_destroy(const_String_or_char_ptr classname) {
+ String *r;
+ String *f;
+ String *rclassname;
+ char *cname;
+ rclassname = SwigType_namestr(classname);
+ r = NewStringEmpty();
+ if (!naming_hash)
+ naming_hash = NewHash();
+ f = Getattr(naming_hash, "destroy");
+ if (!f) {
+ Append(r, "delete_%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);
+ Delete(rclassname);
+ return r;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_disown()
+ *
+ * Returns the name of the accessor function used to disown an object.
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_disown(const_String_or_char_ptr classname) {
+ String *r;
+ String *f;
+ String *rclassname;
+ char *cname;
+ rclassname = SwigType_namestr(classname);
+ r = NewStringEmpty();
+ if (!naming_hash)
+ naming_hash = NewHash();
+ f = Getattr(naming_hash, "disown");
+ if (!f) {
+ Append(r, "disown_%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);
+ 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;
+
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_name_object_set: '%s', '%s'\n", name, decl);
+#endif
+ n = Getattr(namehash, name);
+ if (!n) {
+ n = NewHash();
+ Setattr(namehash, name, n);
+ Delete(n);
+ }
+ /* Add an object based on the declarator value */
+ if (!decl) {
+ Setattr(n, "start", object);
+ } else {
+ SwigType *cd = Copy(decl);
+ Setattr(n, cd, object);
+ Delete(cd);
+ }
+}
+
+
+/* -----------------------------------------------------------------------------
+ * 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, "start");
+ }
+ return rn;
+}
+
+static
+DOH *name_object_get(Hash *namehash, String *tname, SwigType *decl, SwigType *ncdecl) {
+ DOH *rn = 0;
+ Hash *n = Getattr(namehash, tname);
+ if (n) {
+ rn = get_object(n, decl);
+ if ((!rn) && ncdecl)
+ rn = get_object(n, ncdecl);
+ if (!rn)
+ rn = get_object(n, 0);
+ }
+ return rn;
+}
+
+DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl) {
+ String *tname = NewStringEmpty();
+ DOH *rn = 0;
+ 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++;
+ }
+ */
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_name_object_get: '%s' '%s', '%s'\n", prefix, name, decl);
+#endif
+
+
+ /* Perform a class-based lookup (if class prefix supplied) */
+ if (prefix) {
+ if (Len(prefix)) {
+ Printf(tname, "%s::%s", prefix, name);
+ rn = name_object_get(namehash, tname, decl, ncdecl);
+ if (!rn) {
+ String *cls = Swig_scopename_last(prefix);
+ if (!Equal(cls, prefix)) {
+ Clear(tname);
+ Printf(tname, "*::%s::%s", cls, name);
+ rn = name_object_get(namehash, tname, decl, ncdecl);
+ }
+ Delete(cls);
+ }
+ /* A template-based class lookup, check name first */
+ if (!rn && SwigType_istemplate(name)) {
+ String *t_name = SwigType_templateprefix(name);
+ if (!Equal(t_name, name)) {
+ rn = Swig_name_object_get(namehash, prefix, t_name, decl);
+ }
+ Delete(t_name);
+ }
+ /* A template-based class lookup */
+ /*
+ if (!rn && SwigType_istemplate(prefix)) {
+ String *t_prefix = SwigType_templateprefix(prefix);
+ if (Strcmp(t_prefix, prefix) != 0) {
+ String *t_name = SwigType_templateprefix(name);
+ rn = Swig_name_object_get(namehash, t_prefix, t_name, decl);
+ Delete(t_name);
+ }
+ Delete(t_prefix);
+ }
+ */
+ }
+ /* A wildcard-based class lookup */
+ if (!rn) {
+ Clear(tname);
+ Printf(tname, "*::%s", name);
+ rn = name_object_get(namehash, tname, decl, ncdecl);
+ }
+ } else {
+ /* Lookup in the global namespace only */
+ Clear(tname);
+ Printf(tname, "::%s", name);
+ rn = name_object_get(namehash, tname, decl, ncdecl);
+ }
+ /* Catch-all */
+ if (!rn) {
+ rn = name_object_get(namehash, name, decl, ncdecl);
+ }
+ if (!rn && Swig_scopename_check(name)) {
+ String *nprefix = NewStringEmpty();
+ String *nlast = NewStringEmpty();
+ Swig_scopename_split(name, &nprefix, &nlast);
+ rn = name_object_get(namehash, nlast, decl, ncdecl);
+ Delete(nlast);
+ Delete(nprefix);
+ }
+
+ Delete(tname);
+
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_name_object_get: found %d\n", rn ? 1 : 0);
+#endif
+
+ return rn;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_object_inherit()
+ *
+ * Implements name-based inheritance scheme.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) {
+ Iterator ki;
+ 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 (ki = First(namehash); ki.key; ki = Next(ki)) {
+ char *k = Char(ki.key);
+ if (strncmp(k, cbprefix, plen) == 0) {
+ Iterator oi;
+ String *nkey = NewStringf("%s%s", dprefix, k + plen);
+ Hash *n = ki.item;
+ Hash *newh = Getattr(namehash, nkey);
+ if (!newh) {
+ newh = NewHash();
+ Setattr(namehash, nkey, newh);
+ Delete(newh);
+ }
+ for (oi = First(n); oi.key; oi = Next(oi)) {
+ if (!Getattr(newh, oi.key)) {
+ String *ci = Copy(oi.item);
+ Setattr(newh, oi.key, ci);
+ Delete(ci);
+ }
+ }
+ Delete(nkey);
+ }
+ }
+ Delete(bprefix);
+ Delete(dprefix);
+}
+
+/* -----------------------------------------------------------------------------
+ * merge_features()
+ *
+ * Given a hash, this function merges the features in the hash into the node.
+ * ----------------------------------------------------------------------------- */
+
+static void merge_features(Hash *features, Node *n) {
+ Iterator ki;
+
+ if (!features)
+ return;
+ for (ki = First(features); ki.key; ki = Next(ki)) {
+ String *ci = Copy(ki.item);
+ Setattr(n, ki.key, ci);
+ Delete(ci);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_features_get()
+ *
+ * Attaches any features in the features hash to the node that matches
+ * the declaration, decl.
+ * ----------------------------------------------------------------------------- */
+
+static
+void features_get(Hash *features, const String *tname, SwigType *decl, SwigType *ncdecl, Node *node) {
+ Node *n = Getattr(features, tname);
+#ifdef SWIG_DEBUG
+ Printf(stdout, " features_get: %s\n", tname);
+#endif
+ if (n) {
+ merge_features(get_object(n, 0), node);
+ if (ncdecl)
+ merge_features(get_object(n, ncdecl), node);
+ merge_features(get_object(n, decl), node);
+ }
+}
+
+void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) {
+ char *ncdecl = 0;
+ String *rdecl = 0;
+ String *rname = 0;
+ if (!features)
+ return;
+
+ /* MM: This removed to more tightly control feature/name matching */
+ /*
+ if ((decl) && (SwigType_isqualifier(decl))) {
+ ncdecl = strchr(Char(decl),'.');
+ ncdecl++;
+ }
+ */
+
+ /* very specific hack for template constructors/destructors */
+ if (name && SwigType_istemplate(name)) {
+ String *nodetype = nodeType(node);
+ if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
+ String *nprefix = NewStringEmpty();
+ String *nlast = NewStringEmpty();
+ String *tprefix;
+ Swig_scopename_split(name, &nprefix, &nlast);
+ tprefix = SwigType_templateprefix(nlast);
+ Delete(nlast);
+ if (Len(nprefix)) {
+ Append(nprefix, "::");
+ Append(nprefix, tprefix);
+ Delete(tprefix);
+ rname = nprefix;
+ } else {
+ rname = tprefix;
+ Delete(nprefix);
+ }
+ rdecl = Copy(decl);
+ Replaceall(rdecl, name, rname);
+ decl = rdecl;
+ name = rname;
+ }
+ }
+
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_features_get: '%s' '%s' '%s'\n", prefix, name, decl);
+#endif
+
+ /* Global features */
+ features_get(features, "", 0, 0, node);
+ if (name) {
+ String *tname = NewStringEmpty();
+ /* add features for 'root' template */
+ if (SwigType_istemplate(name)) {
+ String *dname = SwigType_templateprefix(name);
+ features_get(features, dname, decl, ncdecl, node);
+ Delete(dname);
+ }
+ /* Catch-all */
+ features_get(features, name, decl, ncdecl, node);
+ /* Perform a class-based lookup (if class prefix supplied) */
+ if (prefix) {
+ /* A class-generic feature */
+ if (Len(prefix)) {
+ Printf(tname, "%s::", prefix);
+ features_get(features, tname, decl, ncdecl, node);
+ }
+ /* A wildcard-based class lookup */
+ Clear(tname);
+ Printf(tname, "*::%s", name);
+ features_get(features, tname, decl, ncdecl, node);
+ /* A specific class lookup */
+ if (Len(prefix)) {
+ /* A template-based class lookup */
+ if (SwigType_istemplate(prefix)) {
+ String *tprefix = SwigType_templateprefix(prefix);
+ Clear(tname);
+ Printf(tname, "%s::%s", tprefix, name);
+ features_get(features, tname, decl, ncdecl, node);
+ Delete(tprefix);
+ }
+ Clear(tname);
+ Printf(tname, "%s::%s", prefix, name);
+ features_get(features, tname, decl, ncdecl, node);
+ }
+ } else {
+ /* Lookup in the global namespace only */
+ Clear(tname);
+ Printf(tname, "::%s", name);
+ features_get(features, tname, decl, ncdecl, node);
+ }
+ Delete(tname);
+ }
+ if (name && SwigType_istemplate(name)) {
+ /* add features for complete template type */
+ String *dname = Swig_symbol_template_deftype(name, 0);
+ if (!Equal(dname, name)) {
+ Swig_features_get(features, prefix, dname, decl, node);
+ }
+ Delete(dname);
+ }
+
+ if (rname)
+ Delete(rname);
+ if (rdecl)
+ Delete(rdecl);
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_feature_set()
+ *
+ * Sets a feature name and value. Also sets optional feature attributes as
+ * passed in by featureattribs. Optional feature attributes are given a full name
+ * concatenating the feature name plus ':' plus the attribute name.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs) {
+ Hash *n;
+ Hash *fhash;
+
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_feature_set: '%s' '%s' '%s' '%s'\n", name, decl, featurename, value);
+#endif
+
+ n = Getattr(features, name);
+ if (!n) {
+ n = NewHash();
+ Setattr(features, name, n);
+ Delete(n);
+ }
+ if (!decl) {
+ fhash = Getattr(n, "start");
+ if (!fhash) {
+ fhash = NewHash();
+ Setattr(n, "start", fhash);
+ Delete(fhash);
+ }
+ } else {
+ fhash = Getattr(n, decl);
+ if (!fhash) {
+ String *cdecl_ = Copy(decl);
+ fhash = NewHash();
+ Setattr(n, cdecl_, fhash);
+ Delete(cdecl_);
+ Delete(fhash);
+ }
+ }
+ if (value) {
+ Setattr(fhash, featurename, value);
+ } else {
+ Delattr(fhash, featurename);
+ }
+
+ {
+ /* Add in the optional feature attributes */
+ Hash *attribs = featureattribs;
+ while (attribs) {
+ String *attribname = Getattr(attribs, "name");
+ String *featureattribname = NewStringf("%s:%s", featurename, attribname);
+ if (value) {
+ String *attribvalue = Getattr(attribs, "value");
+ Setattr(fhash, featureattribname, attribvalue);
+ } else {
+ Delattr(fhash, featureattribname);
+ }
+ attribs = nextSibling(attribs);
+ Delete(featureattribname);
+ }
+ }
+
+ if (name && SwigType_istemplate(name)) {
+ String *dname = Swig_symbol_template_deftype(name, 0);
+ if (Strcmp(dname, name)) {
+ Swig_feature_set(features, dname, decl, featurename, value, featureattribs);
+ }
+ Delete(dname);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * The rename/namewarn engine
+ *
+ * Code below was in parser.y for a while
+ * ----------------------------------------------------------------------------- */
+
+static Hash *namewarn_hash = 0;
+Hash *Swig_name_namewarn_hash() {
+ if (!namewarn_hash)
+ namewarn_hash = NewHash();
+ return namewarn_hash;
+}
+
+static Hash *rename_hash = 0;
+Hash *Swig_name_rename_hash() {
+ if (!rename_hash)
+ rename_hash = NewHash();
+ return rename_hash;
+}
+
+static List *namewarn_list = 0;
+List *Swig_name_namewarn_list() {
+ if (!namewarn_list)
+ namewarn_list = NewList();
+ return namewarn_list;
+}
+
+static List *rename_list = 0;
+List *Swig_name_rename_list() {
+ if (!rename_list)
+ rename_list = NewList();
+ return rename_list;
+}
+
+/* -----------------------------------------------------------------------------
+ * int Swig_need_name_warning(Node *n)
+ *
+ * Detects if a node needs name warnings
+ *
+ * ----------------------------------------------------------------------------- */
+
+int Swig_need_name_warning(Node *n) {
+ int need = 1;
+ /*
+ we don't use name warnings for:
+ - class forwards, no symbol is generated at the target language.
+ - template declarations, only for real instances using %template(name).
+ - typedefs, they have no effect at the target language.
+ */
+ if (checkAttribute(n, "nodeType", "classforward")) {
+ need = 0;
+ } else if (checkAttribute(n, "storage", "typedef")) {
+ need = 0;
+ } else if (Getattr(n, "hidden")) {
+ need = 0;
+ } else if (Getattr(n, "ignore")) {
+ need = 0;
+ } else if (Getattr(n, "templatetype")) {
+ need = 0;
+ }
+ return need;
+}
+
+/* -----------------------------------------------------------------------------
+ * int Swig_need_redefined_warn()
+ *
+ * Detects when a redefined object needs a warning
+ *
+ * ----------------------------------------------------------------------------- */
+
+static int nodes_are_equivalent(Node *a, Node *b, int a_inclass) {
+ /* they must have the same type */
+ String *ta = nodeType(a);
+ String *tb = nodeType(b);
+ if (Cmp(ta, tb) != 0)
+ return 0;
+
+ /* cdecl case */
+ if (Cmp(ta, "cdecl") == 0) {
+ /* typedef */
+ String *a_storage = Getattr(a, "storage");
+ String *b_storage = Getattr(b, "storage");
+
+ if ((Cmp(a_storage, "typedef") == 0)
+ || (Cmp(b_storage, "typedef") == 0)) {
+ if (Cmp(a_storage, b_storage) == 0) {
+ String *a_type = (Getattr(a, "type"));
+ String *b_type = (Getattr(b, "type"));
+ if (Cmp(a_type, b_type) == 0)
+ return 1;
+ }
+ return 0;
+ }
+
+ /* static functions */
+ if ((Cmp(a_storage, "static") == 0)
+ || (Cmp(b_storage, "static") == 0)) {
+ if (Cmp(a_storage, b_storage) != 0)
+ return 0;
+ }
+
+ /* friend methods */
+
+ if (!a_inclass || (Cmp(a_storage, "friend") == 0)) {
+ /* check declaration */
+
+ String *a_decl = (Getattr(a, "decl"));
+ String *b_decl = (Getattr(b, "decl"));
+ if (Cmp(a_decl, b_decl) == 0) {
+ /* check return type */
+ String *a_type = (Getattr(a, "type"));
+ String *b_type = (Getattr(b, "type"));
+ if (Cmp(a_type, b_type) == 0) {
+ /* check parameters */
+ Parm *ap = (Getattr(a, "parms"));
+ Parm *bp = (Getattr(b, "parms"));
+ while (ap && bp) {
+ SwigType *at = Getattr(ap, "type");
+ SwigType *bt = Getattr(bp, "type");
+ if (Cmp(at, bt) != 0)
+ return 0;
+ ap = nextSibling(ap);
+ bp = nextSibling(bp);
+ }
+ if (ap || bp) {
+ return 0;
+ } else {
+ Node *a_template = Getattr(a, "template");
+ Node *b_template = Getattr(b, "template");
+ /* Not equivalent if one is a template instantiation (via %template) and the other is a non-templated function */
+ if ((a_template && !b_template) || (!a_template && b_template))
+ return 0;
+ }
+ return 1;
+ }
+ }
+ }
+ } else {
+ /* %constant case */
+ String *a_storage = Getattr(a, "storage");
+ String *b_storage = Getattr(b, "storage");
+ if ((Cmp(a_storage, "%constant") == 0)
+ || (Cmp(b_storage, "%constant") == 0)) {
+ if (Cmp(a_storage, b_storage) == 0) {
+ String *a_type = (Getattr(a, "type"));
+ String *b_type = (Getattr(b, "type"));
+ if ((Cmp(a_type, b_type) == 0)
+ && (Cmp(Getattr(a, "value"), Getattr(b, "value")) == 0))
+ return 1;
+ }
+ return 0;
+ }
+ }
+ return 0;
+}
+
+int Swig_need_redefined_warn(Node *a, Node *b, int InClass) {
+ String *a_name = Getattr(a, "name");
+ String *b_name = Getattr(b, "name");
+ String *a_symname = Getattr(a, "sym:name");
+ String *b_symname = Getattr(b, "sym:name");
+ /* always send a warning if a 'rename' is involved */
+ if ((a_symname && !Equal(a_symname, a_name))
+ || (b_symname && !Equal(b_symname, b_name))) {
+ if (!Equal(a_name, b_name)) {
+ return 1;
+ }
+ }
+
+
+ return !nodes_are_equivalent(a, b, InClass);
+}
+
+
+/* -----------------------------------------------------------------------------
+ * int Swig_need_protected(Node* n)
+ *
+ * Detects when we need to fully register the protected member.
+ * This is basically any protected members when the allprotected mode is set.
+ * Otherwise we take just the protected virtual methods and non-static methods
+ * (potentially virtual methods) as well as constructors/destructors.
+ *
+ * ----------------------------------------------------------------------------- */
+
+int Swig_need_protected(Node *n) {
+ String *nodetype = nodeType(n);
+ if (checkAttribute(n, "access", "protected")) {
+ if ((Equal(nodetype, "cdecl"))) {
+ if (Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode()) {
+ return 1;
+ }
+ if (SwigType_isfunction(Getattr(n, "decl"))) {
+ String *storage = Getattr(n, "storage");
+ /* The function is declared virtual, or it has no storage. This eliminates typedef, static etc. */
+ return !storage || Equal(storage, "virtual");
+ }
+ } else if (Equal(nodetype, "constructor") || Equal(nodetype, "destructor")) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * void Swig_name_nameobj_add()
+ *
+ * Add nameobj (rename/namewarn)
+ *
+ * ----------------------------------------------------------------------------- */
+
+static List *Swig_make_attrlist(const char *ckey) {
+ List *list = NewList();
+ const char *cattr = strchr(ckey, '$');
+ if (cattr) {
+ String *nattr;
+ const char *rattr = strchr(++cattr, '$');
+ while (rattr) {
+ nattr = NewStringWithSize(cattr, rattr - cattr);
+ Append(list, nattr);
+ Delete(nattr);
+ cattr = rattr + 1;
+ rattr = strchr(cattr, '$');
+ }
+ nattr = NewString(cattr);
+ Append(list, nattr);
+ Delete(nattr);
+ } else {
+ Append(list, "nodeType");
+ }
+ return list;
+}
+
+static void Swig_name_object_attach_keys(const char *keys[], Hash *nameobj) {
+ Node *kw = nextSibling(nameobj);
+ List *matchlist = 0;
+ while (kw) {
+ Node *next = nextSibling(kw);
+ String *kname = Getattr(kw, "name");
+ char *ckey = kname ? Char(kname) : 0;
+ if (ckey) {
+ const char **rkey;
+ int isnotmatch = 0;
+ int isrxsmatch = 0;
+ if ((strncmp(ckey, "match", 5) == 0)
+ || (isnotmatch = (strncmp(ckey, "notmatch", 8) == 0))
+ || (isrxsmatch = (strncmp(ckey, "rxsmatch", 8) == 0))
+ || (isnotmatch = isrxsmatch = (strncmp(ckey, "notrxsmatch", 11) == 0))) {
+ Hash *mi = NewHash();
+ List *attrlist = Swig_make_attrlist(ckey);
+ if (!matchlist)
+ matchlist = NewList();
+ Setattr(mi, "value", Getattr(kw, "value"));
+ Setattr(mi, "attrlist", attrlist);
+#ifdef SWIG_DEBUG
+ if (isrxsmatch)
+ Printf(stdout, "rxsmatch to use: %s %s %s\n", ckey, Getattr(kw, "value"), attrlist);
+#endif
+ if (isnotmatch)
+ SetFlag(mi, "notmatch");
+ if (isrxsmatch)
+ SetFlag(mi, "rxsmatch");
+ Delete(attrlist);
+ Append(matchlist, mi);
+ Delete(mi);
+ removeNode(kw);
+ } else {
+ for (rkey = keys; *rkey != 0; ++rkey) {
+ if (strcmp(ckey, *rkey) == 0) {
+ Setattr(nameobj, *rkey, Getattr(kw, "value"));
+ removeNode(kw);
+ }
+ }
+ }
+ }
+ kw = next;
+ }
+ if (matchlist) {
+ Setattr(nameobj, "matchlist", matchlist);
+ Delete(matchlist);
+ }
+}
+
+void Swig_name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, String *name, SwigType *decl, Hash *nameobj) {
+ String *nname = 0;
+ if (name && Len(name)) {
+ String *target_fmt = Getattr(nameobj, "targetfmt");
+ nname = prefix ? NewStringf("%s::%s", prefix, name) : NewString(name);
+ if (target_fmt) {
+ String *tmp = NewStringf(target_fmt, nname);
+ Delete(nname);
+ nname = tmp;
+ }
+ }
+
+ if (!nname || !Len(nname) || Getattr(nameobj, "fullname") || /* any of these options trigger a 'list' nameobj */
+ Getattr(nameobj, "sourcefmt") || Getattr(nameobj, "matchlist")) {
+ if (decl)
+ Setattr(nameobj, "decl", decl);
+ if (nname && Len(nname))
+ Setattr(nameobj, "targetname", nname);
+ /* put the new nameobj at the beginnig of the list, such that the
+ last inserted rule take precedence */
+ Insert(name_list, 0, nameobj);
+ } else {
+ /* here we add an old 'hash' nameobj, simple and fast */
+ Swig_name_object_set(name_hash, nname, decl, nameobj);
+ }
+ Delete(nname);
+}
+
+/* -----------------------------------------------------------------------------
+ * int Swig_name_match_nameobj()
+ *
+ * Apply and check the nameobj's math list to the node
+ *
+ * ----------------------------------------------------------------------------- */
+
+static DOH *Swig_get_lattr(Node *n, List *lattr) {
+ DOH *res = 0;
+ int ilen = Len(lattr);
+ int i;
+ for (i = 0; n && (i < ilen); ++i) {
+ String *nattr = Getitem(lattr, i);
+ res = Getattr(n, nattr);
+#ifdef SWIG_DEBUG
+ if (!res) {
+ Printf(stdout, "missing %s %s %s\n", nattr, Getattr(n, "name"), Getattr(n, "member"));
+ } else {
+ Printf(stdout, "lattr %d %s %s\n", i, nattr, DohIsString(res) ? res : Getattr(res, "name"));
+ }
+#endif
+ n = res;
+ }
+ return res;
+}
+
+#if defined(HAVE_RXSPENCER)
+#include <sys/types.h>
+#include <rxspencer/regex.h>
+#define USE_RXSPENCER
+#endif
+
+#if defined(USE_RXSPENCER)
+int Swig_name_rxsmatch_value(String *mvalue, String *value) {
+ int match = 0;
+ char *cvalue = Char(value);
+ char *cmvalue = Char(mvalue);
+ regex_t compiled;
+ int retval = regcomp(&compiled, cmvalue, REG_EXTENDED | REG_NOSUB);
+ if (retval != 0)
+ return 0;
+ retval = regexec(&compiled, cvalue, 0, 0, 0);
+ match = (retval == REG_NOMATCH) ? 0 : 1;
+#ifdef SWIG_DEBUG
+ Printf(stdout, "rxsmatch_value: %s %s %d\n", cvalue, cmvalue, match);
+#endif
+ regfree(&compiled);
+ return match;
+}
+#else
+int Swig_name_rxsmatch_value(String *mvalue, String *value) {
+ (void) mvalue;
+ (void) value;
+ return 0;
+}
+#endif
+
+int Swig_name_match_value(String *mvalue, String *value) {
+#if defined(SWIG_USE_SIMPLE_MATCHOR)
+ int match = 0;
+ char *cvalue = Char(value);
+ char *cmvalue = Char(mvalue);
+ char *sep = strchr(cmvalue, '|');
+ while (sep && !match) {
+ match = strncmp(cvalue, cmvalue, sep - cmvalue) == 0;
+#ifdef SWIG_DEBUG
+ Printf(stdout, "match_value: %s %s %d\n", cvalue, cmvalue, match);
+#endif
+ cmvalue = sep + 1;
+ sep = strchr(cmvalue, '|');
+ }
+ if (!match) {
+ match = strcmp(cvalue, cmvalue) == 0;
+#ifdef SWIG_DEBUG
+ Printf(stdout, "match_value: %s %s %d\n", cvalue, cmvalue, match);
+#endif
+ }
+ return match;
+#else
+ return Equal(mvalue, value);
+#endif
+}
+
+
+int Swig_name_match_nameobj(Hash *rn, Node *n) {
+ int match = 1;
+ List *matchlist = Getattr(rn, "matchlist");
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_name_match_nameobj: %s\n", Getattr(n, "name"));
+#endif
+ if (matchlist) {
+ int ilen = Len(matchlist);
+ int i;
+ for (i = 0; match && (i < ilen); ++i) {
+ Node *mi = Getitem(matchlist, i);
+ List *lattr = Getattr(mi, "attrlist");
+ String *nval = Swig_get_lattr(n, lattr);
+ int notmatch = GetFlag(mi, "notmatch");
+ int rxsmatch = GetFlag(mi, "rxsmatch");
+#ifdef SWIG_DEBUG
+ Printf(stdout, "mi %d %s re %d not %d \n", i, nval, notmatch, rxsmatch);
+ if (rxsmatch) {
+ Printf(stdout, "rxsmatch %s\n", lattr);
+ }
+#endif
+ match = 0;
+ if (nval) {
+ String *kwval = Getattr(mi, "value");
+ match = rxsmatch ? Swig_name_rxsmatch_value(kwval, nval)
+ : Swig_name_match_value(kwval, nval);
+#ifdef SWIG_DEBUG
+ Printf(stdout, "val %s %s %d %d \n", nval, kwval, match, ilen);
+#endif
+ }
+ if (notmatch)
+ match = !match;
+ }
+ }
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_name_match_nameobj: %d\n", match);
+#endif
+ return match;
+}
+
+/* -----------------------------------------------------------------------------
+ * Hash *Swig_name_nameobj_lget()
+ *
+ * Get a nameobj (rename/namewarn) from the list of filters
+ *
+ * ----------------------------------------------------------------------------- */
+
+Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *name, String *decl) {
+ Hash *res = 0;
+ if (namelist) {
+ int len = Len(namelist);
+ int i;
+ int match = 0;
+ for (i = 0; !match && (i < len); i++) {
+ Hash *rn = Getitem(namelist, i);
+ String *rdecl = Getattr(rn, "decl");
+ if (rdecl && (!decl || !Equal(rdecl, decl))) {
+ continue;
+ } else if (Swig_name_match_nameobj(rn, n)) {
+ String *tname = Getattr(rn, "targetname");
+ if (tname) {
+ String *sfmt = Getattr(rn, "sourcefmt");
+ String *sname = 0;
+ int fullname = GetFlag(rn, "fullname");
+ int rxstarget = GetFlag(rn, "rxstarget");
+ if (sfmt) {
+ if (fullname && prefix) {
+ String *pname = NewStringf("%s::%s", prefix, name);
+ sname = NewStringf(sfmt, pname);
+ Delete(pname);
+ } else {
+ sname = NewStringf(sfmt, name);
+ }
+ } else {
+ if (fullname && prefix) {
+ sname = NewStringf("%s::%s", prefix, name);
+ } else {
+ sname = name;
+ DohIncref(name);
+ }
+ }
+ match = rxstarget ? Swig_name_rxsmatch_value(tname, sname) : Swig_name_match_value(tname, sname);
+ Delete(sname);
+ } else {
+ match = 1;
+ }
+ }
+ if (match) {
+ res = rn;
+ break;
+ }
+ }
+ }
+ return res;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_namewarn_add
+ *
+ * Add a namewarn objects
+ *
+ * ----------------------------------------------------------------------------- */
+
+void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn) {
+ const char *namewrn_keys[] = { "rename", "error", "fullname", "sourcefmt", "targetfmt", 0 };
+ Swig_name_object_attach_keys(namewrn_keys, namewrn);
+ Swig_name_nameobj_add(Swig_name_namewarn_hash(), Swig_name_namewarn_list(), prefix, name, decl, namewrn);
+}
+
+/* -----------------------------------------------------------------------------
+ * Hash *Swig_name_namewarn_get()
+ *
+ * Return the namewarn object, if there is one.
+ *
+ * ----------------------------------------------------------------------------- */
+
+Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl) {
+ if (!namewarn_hash && !namewarn_list)
+ return 0;
+ if (n) {
+ /* Return in the obvious cases */
+ if (!name || !Swig_need_name_warning(n)) {
+ return 0;
+ } else {
+ String *access = Getattr(n, "access");
+ int is_public = !access || Equal(access, "public");
+ if (!is_public && !Swig_need_protected(n)) {
+ return 0;
+ }
+ }
+ }
+ if (name) {
+ /* Check to see if the name is in the hash */
+ Hash *wrn = Swig_name_object_get(Swig_name_namewarn_hash(), prefix, name, decl);
+ if (wrn && !Swig_name_match_nameobj(wrn, n))
+ wrn = 0;
+ if (!wrn) {
+ wrn = Swig_name_nameobj_lget(Swig_name_namewarn_list(), n, prefix, name, decl);
+ }
+ if (wrn && Getattr(wrn, "error")) {
+ if (n) {
+ Swig_error(Getfile(n), Getline(n), "%s\n", Getattr(wrn, "name"));
+ } else {
+ Swig_error(cparse_file, cparse_line, "%s\n", Getattr(wrn, "name"));
+ }
+ }
+ return wrn;
+ } else {
+ return 0;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * String *Swig_name_warning()
+ *
+ * Return the name warning, if there is one.
+ *
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl) {
+ Hash *wrn = Swig_name_namewarn_get(n, prefix, name, decl);
+ return (name && wrn) ? Getattr(wrn, "name") : 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_name_rename_add()
+ *
+ * Manage the rename objects
+ *
+ * ----------------------------------------------------------------------------- */
+
+static void single_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname) {
+ Swig_name_nameobj_add(Swig_name_rename_hash(), Swig_name_rename_list(), prefix, name, decl, newname);
+}
+
+/* Add a new rename. Works much like new_feature including default argument handling. */
+void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname, ParmList *declaratorparms) {
+
+ ParmList *declparms = declaratorparms;
+
+ const char *rename_keys[] = { "fullname", "sourcefmt", "targetfmt", "continue", "rxstarget", 0 };
+ Swig_name_object_attach_keys(rename_keys, newname);
+
+ /* Add the name */
+ single_rename_add(prefix, name, decl, newname);
+
+ /* Add extra names if there are default parameters in the parameter list */
+ if (decl) {
+ int constqualifier = SwigType_isconst(decl);
+ while (declparms) {
+ if (ParmList_has_defaultargs(declparms)) {
+
+ /* Create a parameter list for the new rename by copying all
+ but the last (defaulted) parameter */
+ ParmList *newparms = CopyParmListMax(declparms,ParmList_len(declparms)-1);
+
+ /* Create new declaration - with the last parameter removed */
+ SwigType *newdecl = Copy(decl);
+ Delete(SwigType_pop_function(newdecl)); /* remove the old parameter list from newdecl */
+ SwigType_add_function(newdecl, newparms);
+ if (constqualifier)
+ SwigType_add_qualifier(newdecl, "const");
+
+ single_rename_add(prefix, name, newdecl, newname);
+ declparms = newparms;
+ Delete(newdecl);
+ } else {
+ declparms = 0;
+ }
+ }
+ }
+}
+
+
+/* Create a name applying rename/namewarn if needed */
+static String *apply_rename(String *newname, int fullname, String *prefix, String *name) {
+ String *result = 0;
+ if (newname && Len(newname)) {
+ if (Strcmp(newname, "$ignore") == 0) {
+ result = Copy(newname);
+ } else {
+ char *cnewname = Char(newname);
+ if (cnewname) {
+ int destructor = name && (*(Char(name)) == '~');
+ String *fmt = newname;
+ /* use name as a fmt, but avoid C++ "%" and "%=" operators */
+ if (Len(newname) > 1 && strchr(cnewname, '%') && !(strcmp(cnewname, "%=") == 0)) {
+ if (fullname && prefix) {
+ result = NewStringf(fmt, prefix, name);
+ } else {
+ result = NewStringf(fmt, name);
+ }
+ } else {
+ result = Copy(newname);
+ }
+ if (destructor && result && (*(Char(result)) != '~')) {
+ Insert(result, 0, "~");
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * String *Swig_name_make()
+ *
+ * Make a name after applying all the rename/namewarn objects
+ *
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname) {
+ String *nname = 0;
+ String *result = 0;
+ String *name = NewString(cname);
+ Hash *wrn = 0;
+ String *rdecl = 0;
+ String *rname = 0;
+
+ /* very specific hack for template constructors/destructors */
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_name_make: looking for %s %s %s %s\n", prefix, name, decl, oldname);
+#endif
+
+ if (name && n && SwigType_istemplate(name)) {
+ String *nodetype = nodeType(n);
+ if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
+ String *nprefix = NewStringEmpty();
+ String *nlast = NewStringEmpty();
+ String *tprefix;
+ Swig_scopename_split(name, &nprefix, &nlast);
+ tprefix = SwigType_templateprefix(nlast);
+ Delete(nlast);
+ if (Len(nprefix)) {
+ Append(nprefix, "::");
+ Append(nprefix, tprefix);
+ Delete(tprefix);
+ rname = nprefix;
+ } else {
+ rname = tprefix;
+ Delete(nprefix);
+ }
+ rdecl = Copy(decl);
+ Replaceall(rdecl, name, rname);
+#ifdef SWIG_DEBUG
+ Printf(stdout, "SWIG_name_make: use new name %s %s : %s %s\n", name, decl, rname, rdecl);
+#endif
+ decl = rdecl;
+ Delete(name);
+ name = rname;
+ }
+ }
+
+
+ if (rename_hash || rename_list || namewarn_hash || namewarn_list) {
+ Hash *rn = Swig_name_object_get(Swig_name_rename_hash(), prefix, name, decl);
+ if (!rn || !Swig_name_match_nameobj(rn, n)) {
+ rn = Swig_name_nameobj_lget(Swig_name_rename_list(), n, prefix, name, decl);
+ if (rn) {
+ String *sfmt = Getattr(rn, "sourcefmt");
+ int fullname = GetFlag(rn, "fullname");
+ if (fullname && prefix) {
+ String *sname = NewStringf("%s::%s", prefix, name);
+ Delete(name);
+ name = sname;
+ prefix = 0;
+ }
+ if (sfmt) {
+ String *sname = NewStringf(sfmt, name);
+ Delete(name);
+ name = sname;
+ }
+ }
+ }
+ if (rn) {
+ String *newname = Getattr(rn, "name");
+ int fullname = GetFlag(rn, "fullname");
+ result = apply_rename(newname, fullname, prefix, name);
+ }
+ if (result && !Equal(result, name)) {
+ /* operators in C++ allow aliases, we look for them */
+ char *cresult = Char(result);
+ if (cresult && (strncmp(cresult, "operator ", 9) == 0)) {
+ String *nresult = Swig_name_make(n, prefix, result, decl, oldname);
+ if (!Equal(nresult, result)) {
+ Delete(result);
+ result = nresult;
+ } else {
+ Delete(nresult);
+ }
+ }
+ }
+ nname = result ? result : name;
+ wrn = Swig_name_namewarn_get(n, prefix, nname, decl);
+ if (wrn) {
+ String *rename = Getattr(wrn, "rename");
+ if (rename) {
+ String *msg = Getattr(wrn, "name");
+ int fullname = GetFlag(wrn, "fullname");
+ if (result)
+ Delete(result);
+ result = apply_rename(rename, fullname, prefix, name);
+ if ((msg) && (Len(msg))) {
+ if (!Getmeta(nname, "already_warned")) {
+ if (n) {
+ SWIG_WARN_NODE_BEGIN(n);
+ Swig_warning(0, Getfile(n), Getline(n), "%s\n", msg);
+ SWIG_WARN_NODE_END(n);
+ } else {
+ Swig_warning(0, Getfile(name), Getline(name), "%s\n", msg);
+ }
+ Setmeta(nname, "already_warned", "1");
+ }
+ }
+ }
+ }
+ }
+ if (!result || !Len(result)) {
+ if (result)
+ Delete(result);
+ if (oldname) {
+ result = NewString(oldname);
+ } else {
+ result = NewString(cname);
+ }
+ }
+ Delete(name);
+
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_name_make: result '%s' '%s'\n", cname, result);
+#endif
+
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * void Swig_name_inherit()
+ *
+ * Inherit namewarn,rename, and feature objects
+ *
+ * ----------------------------------------------------------------------------- */
+
+void Swig_name_inherit(String *base, String *derived) {
+ /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */
+ Swig_name_object_inherit(Swig_name_rename_hash(), base, derived);
+ Swig_name_object_inherit(Swig_name_namewarn_hash(), base, derived);
+ Swig_name_object_inherit(Swig_cparse_features(), base, derived);
+}
+
+/* -----------------------------------------------------------------------------
+ * void Swig_name_decl()
+ *
+ * Return a stringified version of a C/C++ declaration without the return type.
+ * The node passed in is expected to be a function. Some example return values:
+ * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()"
+ * "MyNameSpace::ABC::ABC(int,double)"
+ * "MyNameSpace::ABC::constmethod(int) const"
+ *
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_decl(Node *n) {
+ String *qname;
+ String *decl;
+ String *qualifier = Swig_symbol_qualified(n);
+ String *name = Swig_scopename_last(Getattr(n, "name"));
+ if (qualifier)
+ qualifier = SwigType_namestr(qualifier);
+
+ /* Very specific hack for template constructors/destructors */
+ if (SwigType_istemplate(name)) {
+ String *nodetype = nodeType(n);
+ if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
+ String *nprefix = NewStringEmpty();
+ String *nlast = NewStringEmpty();
+ String *tprefix;
+ Swig_scopename_split(name, &nprefix, &nlast);
+ tprefix = SwigType_templateprefix(nlast);
+ Delete(nlast);
+ Delete(name);
+ name = tprefix;
+ }
+ }
+
+ qname = NewString("");
+ if (qualifier && Len(qualifier) > 0)
+ Printf(qname, "%s::", qualifier);
+ Printf(qname, "%s", SwigType_str(name, 0));
+
+ decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : "");
+
+ Delete(name);
+ Delete(qualifier);
+ Delete(qname);
+
+ return decl;
+}
+
+/* -----------------------------------------------------------------------------
+ * void Swig_name_fulldecl()
+ *
+ * Return a stringified version of a C/C++ declaration including the return type.
+ * The node passed in is expected to be a function. Some example return values:
+ * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()"
+ * "MyNameSpace::ABC::ABC(int,double)"
+ * "int * MyNameSpace::ABC::constmethod(int) const"
+ *
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_fulldecl(Node *n) {
+ String *decl = Swig_name_decl(n);
+ String *type = Getattr(n, "type");
+ String *nodetype = nodeType(n);
+ String *fulldecl;
+ /* add on the return type */
+ if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) {
+ fulldecl = decl;
+ } else {
+ String *t = SwigType_str(type, 0);
+ fulldecl = NewStringf("%s %s", t, decl);
+ Delete(decl);
+ Delete(t);
+ }
+ return fulldecl;
+}
+
diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c
new file mode 100644
index 0000000..c13c24c
--- /dev/null
+++ b/Source/Swig/parms.c
@@ -0,0 +1,196 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * parms.c
+ *
+ * Parameter list class.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_parms_c[] = "$Id: parms.c 11080 2009-01-24 13:15:51Z bhy $";
+
+#include "swig.h"
+
+/* ------------------------------------------------------------------------
+ * NewParm()
+ *
+ * Create a new parameter from datatype 'type' and name 'name'.
+ * ------------------------------------------------------------------------ */
+
+Parm *NewParm(SwigType *type, const_String_or_char_ptr name) {
+ Parm *p = NewHash();
+ set_nodeType(p, "parm");
+ if (type) {
+ SwigType *ntype = Copy(type);
+ Setattr(p, "type", ntype);
+ Delete(ntype);
+ }
+ Setattr(p, "name", name);
+ return p;
+}
+
+/* ------------------------------------------------------------------------
+ * CopyParm()
+ * ------------------------------------------------------------------------ */
+
+Parm *CopyParm(Parm *p) {
+ Parm *np = NewHash();
+ Iterator ki;
+ for (ki = First(p); ki.key; ki = Next(ki)) {
+ if (DohIsString(ki.item)) {
+ DOH *c = Copy(ki.item);
+ Setattr(np,ki.key,c);
+ Delete(c);
+ }
+ }
+ Setfile(np, Getfile(p));
+ Setline(np, Getline(p));
+ return np;
+}
+
+/* ------------------------------------------------------------------
+ * CopyParmListMax()
+ * CopyParmList()
+ * ------------------------------------------------------------------ */
+
+ParmList *CopyParmListMax(ParmList *p, int count) {
+ Parm *np;
+ Parm *pp = 0;
+ Parm *fp = 0;
+
+ if (!p)
+ return 0;
+
+ while (p) {
+ if (count == 0) break;
+ np = CopyParm(p);
+ if (pp) {
+ set_nextSibling(pp, np);
+ Delete(np);
+ } else {
+ fp = np;
+ }
+ pp = np;
+ p = nextSibling(p);
+ count--;
+ }
+ return fp;
+}
+
+ParmList *CopyParmList(ParmList *p) {
+ return CopyParmListMax(p,-1);
+}
+
+/* -----------------------------------------------------------------------------
+ * 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()
+ * ----------------------------------------------------------------------------- */
+
+int ParmList_len(ParmList *p) {
+ int i = 0;
+ while (p) {
+ i++;
+ p = nextSibling(p);
+ }
+ return i;
+}
+
+/* ---------------------------------------------------------------------
+ * ParmList_str()
+ *
+ * Generates a string of parameters
+ * ---------------------------------------------------------------------- */
+
+String *ParmList_str(ParmList *p) {
+ String *out = NewStringEmpty();
+ while (p) {
+ String *pstr = SwigType_str(Getattr(p, "type"), Getattr(p, "name"));
+ Append(out, pstr);
+ p = nextSibling(p);
+ if (p) {
+ Append(out, ",");
+ }
+ Delete(pstr);
+ }
+ return out;
+}
+
+/* ---------------------------------------------------------------------
+ * ParmList_str_defaultargs()
+ *
+ * Generates a string of parameters including default arguments
+ * ---------------------------------------------------------------------- */
+
+String *ParmList_str_defaultargs(ParmList *p) {
+ String *out = NewStringEmpty();
+ while (p) {
+ String *value = Getattr(p, "value");
+ String *pstr = SwigType_str(Getattr(p, "type"), Getattr(p, "name"));
+ Append(out, pstr);
+ if (value) {
+ Printf(out, "=%s", value);
+ }
+ p = nextSibling(p);
+ if (p) {
+ Append(out, ",");
+ }
+ Delete(pstr);
+ }
+ return out;
+}
+
+/* ---------------------------------------------------------------------
+ * ParmList_protostr()
+ *
+ * Generate a prototype string.
+ * ---------------------------------------------------------------------- */
+
+String *ParmList_protostr(ParmList *p) {
+ String *out = NewStringEmpty();
+ while (p) {
+ String *pstr = SwigType_str(Getattr(p, "type"), 0);
+ Append(out, pstr);
+ p = nextSibling(p);
+ if (p) {
+ Append(out, ",");
+ }
+ Delete(pstr);
+ }
+ return out;
+}
+
+/* ---------------------------------------------------------------------
+ * ParmList_has_defaultargs()
+ *
+ * Returns 1 if the parameter list passed in is has one or more default
+ * arguments. Otherwise returns 0.
+ * ---------------------------------------------------------------------- */
+
+int ParmList_has_defaultargs(ParmList *p) {
+ while (p) {
+ if (Getattr(p, "value")) {
+ return 1;
+ }
+ p = nextSibling(p);
+ }
+ return 0;
+}
diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c
new file mode 100644
index 0000000..328a491
--- /dev/null
+++ b/Source/Swig/scanner.c
@@ -0,0 +1,1227 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * scanner.c
+ *
+ * This file implements a general purpose C/C++ compatible lexical scanner.
+ * This scanner isn't intended to be plugged directly into a parser built
+ * with yacc. Rather, it contains a lot of generic code that could be used
+ * to easily construct yacc-compatible scanners.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_scanner_c[] = "$Id: scanner.c 11470 2009-07-29 20:50:39Z wsfulton $";
+
+#include "swig.h"
+#include <ctype.h>
+
+extern String *cparse_file;
+extern int cparse_start_line;
+
+struct Scanner {
+ String *text; /* Current token value */
+ List *scanobjs; /* Objects being scanned */
+ String *str; /* Current object being scanned */
+ char *idstart; /* Optional identifier start characters */
+ int nexttoken; /* Next token to be returned */
+ int start_line; /* Starting line of certain declarations */
+ int line;
+ int yylen; /* Length of text pushed into text */
+ String *file;
+ String *error; /* Last error message (if any) */
+ int error_line; /* Error line number */
+ int freeze_line; /* Suspend line number updates */
+};
+
+/* -----------------------------------------------------------------------------
+ * NewScanner()
+ *
+ * Create a new scanner object
+ * ----------------------------------------------------------------------------- */
+
+Scanner *NewScanner(void) {
+ Scanner *s;
+ s = (Scanner *) malloc(sizeof(Scanner));
+ s->line = 1;
+ s->file = 0;
+ s->nexttoken = -1;
+ s->start_line = 1;
+ s->yylen = 0;
+ s->idstart = NULL;
+ s->scanobjs = NewList();
+ s->text = NewStringEmpty();
+ s->str = 0;
+ s->error = 0;
+ s->freeze_line = 0;
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * DelScanner()
+ *
+ * Delete a scanner object.
+ * ----------------------------------------------------------------------------- */
+
+void DelScanner(Scanner * s) {
+ assert(s);
+ Delete(s->scanobjs);
+ Delete(s->text);
+ Delete(s->file);
+ Delete(s->error);
+ Delete(s->str);
+ free(s->idstart);
+ free(s);
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_clear()
+ *
+ * Clear the contents of a scanner object.
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_clear(Scanner * s) {
+ assert(s);
+ Delete(s->str);
+ Clear(s->text);
+ Clear(s->scanobjs);
+ Delete(s->error);
+ s->str = 0;
+ s->error = 0;
+ s->line = 1;
+ s->nexttoken = -1;
+ s->start_line = 0;
+ s->yylen = 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_push()
+ *
+ * Push some new text into the scanner. The scanner will start parsing this text
+ * immediately before returning to the old text.
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_push(Scanner * s, String *txt) {
+ assert(s && txt);
+ Push(s->scanobjs, txt);
+ if (s->str) {
+ Setline(s->str,s->line);
+ Delete(s->str);
+ }
+ s->str = txt;
+ DohIncref(s->str);
+ s->line = Getline(txt);
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_pushtoken()
+ *
+ * Push a token into the scanner. This token will be returned on the next
+ * call to Scanner_token().
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_pushtoken(Scanner * s, int nt, const_String_or_char_ptr val) {
+ assert(s);
+ assert((nt >= 0) && (nt < SWIG_MAXTOKENS));
+ s->nexttoken = nt;
+ if ( Char(val) != Char(s->text) ) {
+ Clear(s->text);
+ Append(s->text,val);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_set_location()
+ *
+ * Set the file and line number location of the scanner.
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_set_location(Scanner * s, String *file, int line) {
+ Setline(s->str, line);
+ Setfile(s->str, file);
+ s->line = line;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_file()
+ *
+ * Get the current file.
+ * ----------------------------------------------------------------------------- */
+
+String *Scanner_file(Scanner * s) {
+ return Getfile(s->str);
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_line()
+ *
+ * Get the current line number
+ * ----------------------------------------------------------------------------- */
+int Scanner_line(Scanner * s) {
+ return s->line;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_start_line()
+ *
+ * Get the line number on which the current token starts
+ * ----------------------------------------------------------------------------- */
+int Scanner_start_line(Scanner * s) {
+ return s->start_line;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_idstart()
+ *
+ * Change the set of additional characters that can be used to start an identifier.
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_idstart(Scanner * s, const char *id) {
+ free(s->idstart);
+ s->idstart = Swig_copy_string(id);
+}
+
+/* -----------------------------------------------------------------------------
+ * nextchar()
+ *
+ * Returns the next character from the scanner or 0 if end of the string.
+ * ----------------------------------------------------------------------------- */
+static char nextchar(Scanner * s) {
+ int nc;
+ if (!s->str)
+ return 0;
+ while ((nc = Getc(s->str)) == EOF) {
+ Delete(s->str);
+ s->str = 0;
+ Delitem(s->scanobjs, 0);
+ if (Len(s->scanobjs) == 0)
+ return 0;
+ s->str = Getitem(s->scanobjs, 0);
+ if (s->str) {
+ s->line = Getline(s->str);
+ DohIncref(s->str);
+ }
+ }
+ if ((nc == '\n') && (!s->freeze_line))
+ s->line++;
+ Putc(nc,s->text);
+ return (char)nc;
+}
+
+/* -----------------------------------------------------------------------------
+ * set_error()
+ *
+ * Sets error information on the scanner.
+ * ----------------------------------------------------------------------------- */
+
+static void set_error(Scanner *s, int line, const_String_or_char_ptr msg) {
+ s->error_line = line;
+ s->error = NewString(msg);
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_errmsg()
+ * Scanner_errline()
+ *
+ * Returns error information (if any)
+ * ----------------------------------------------------------------------------- */
+
+String *
+Scanner_errmsg(Scanner *s) {
+ return s->error;
+}
+
+int
+Scanner_errline(Scanner *s) {
+ return s->error_line;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_freeze_line()
+ *
+ * Freezes the current line number.
+ * ----------------------------------------------------------------------------- */
+
+void
+Scanner_freeze_line(Scanner *s, int val) {
+ s->freeze_line = val;
+}
+
+/* -----------------------------------------------------------------------------
+ * retract()
+ *
+ * Retract n characters
+ * ----------------------------------------------------------------------------- */
+static void retract(Scanner * s, int n) {
+ int i, l;
+ char *str;
+
+ str = Char(s->text);
+ l = Len(s->text);
+ assert(n <= l);
+ for (i = 0; i < n; i++) {
+ if (str[l - 1] == '\n') {
+ if (!s->freeze_line) s->line--;
+ }
+ Seek(s->str, -1, SEEK_CUR);
+ Delitem(s->text, DOH_END);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * get_escape()
+ *
+ * Get escape sequence. Called when a backslash is found in a string
+ * ----------------------------------------------------------------------------- */
+
+static void get_escape(Scanner *s) {
+ int result = 0;
+ int state = 0;
+ int c;
+
+ while (1) {
+ c = nextchar(s);
+ if (c == 0)
+ break;
+ switch (state) {
+ case 0:
+ if (c == 'n') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\n");
+ return;
+ }
+ if (c == 'r') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\r");
+ return;
+ }
+ if (c == 't') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\t");
+ return;
+ }
+ if (c == 'a') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\a");
+ return;
+ }
+ if (c == 'b') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\b");
+ return;
+ }
+ if (c == 'f') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\f");
+ return;
+ }
+ if (c == '\\') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\\");
+ return;
+ }
+ if (c == 'v') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\v");
+ return;
+ }
+ if (c == 'e') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\033");
+ return;
+ }
+ if (c == '\'') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\'");
+ return;
+ }
+ if (c == '\"') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\"");
+ return;
+ }
+ if (c == '\n') {
+ Delitem(s->text, DOH_END);
+ return;
+ }
+ if (isdigit(c)) {
+ state = 10;
+ result = (c - '0');
+ Delitem(s->text, DOH_END);
+ } else if (c == 'x') {
+ state = 20;
+ Delitem(s->text, DOH_END);
+ } else {
+ char tmp[3];
+ tmp[0] = '\\';
+ tmp[1] = (char)c;
+ tmp[2] = 0;
+ Delitem(s->text, DOH_END);
+ Append(s->text, tmp);
+ return;
+ }
+ break;
+ case 10:
+ if (!isdigit(c)) {
+ retract(s,1);
+ Putc((char)result,s->text);
+ return;
+ }
+ result = (result << 3) + (c - '0');
+ Delitem(s->text, DOH_END);
+ break;
+ case 20:
+ if (!isxdigit(c)) {
+ retract(s,1);
+ Putc((char)result, s->text);
+ return;
+ }
+ if (isdigit(c))
+ result = (result << 4) + (c - '0');
+ else
+ result = (result << 4) + (10 + tolower(c) - 'a');
+ Delitem(s->text, DOH_END);
+ break;
+ }
+ }
+ return;
+}
+
+/* -----------------------------------------------------------------------------
+ * look()
+ *
+ * Return the raw value of the next token.
+ * ----------------------------------------------------------------------------- */
+
+static int look(Scanner * s) {
+ int state;
+ int c = 0;
+
+ state = 0;
+ Clear(s->text);
+ s->start_line = s->line;
+ Setfile(s->text, Getfile(s->str));
+ while (1) {
+ switch (state) {
+ case 0:
+ if ((c = nextchar(s)) == 0)
+ return (0);
+
+ /* Process delimiters */
+
+ if (c == '\n') {
+ return SWIG_TOKEN_ENDLINE;
+ } else if (!isspace(c)) {
+ retract(s, 1);
+ state = 1000;
+ Clear(s->text);
+ Setline(s->text, s->line);
+ Setfile(s->text, Getfile(s->str));
+ }
+ break;
+
+ case 1000:
+ if ((c = nextchar(s)) == 0)
+ return (0);
+ if (c == '%')
+ state = 4; /* Possibly a SWIG directive */
+
+ /* Look for possible identifiers */
+
+ else if ((isalpha(c)) || (c == '_') ||
+ (s->idstart && strchr(s->idstart, c)))
+ state = 7;
+
+ /* Look for single character symbols */
+
+ else if (c == '(')
+ return SWIG_TOKEN_LPAREN;
+ else if (c == ')')
+ return SWIG_TOKEN_RPAREN;
+ else if (c == ';')
+ return SWIG_TOKEN_SEMI;
+ else if (c == ',')
+ return SWIG_TOKEN_COMMA;
+ else if (c == '*')
+ state = 220;
+ else if (c == '}')
+ return SWIG_TOKEN_RBRACE;
+ else if (c == '{')
+ return SWIG_TOKEN_LBRACE;
+ else if (c == '=')
+ state = 33;
+ else if (c == '+')
+ state = 200;
+ else if (c == '-')
+ state = 210;
+ else if (c == '&')
+ state = 31;
+ else if (c == '|')
+ state = 32;
+ else if (c == '^')
+ state = 230;
+ else if (c == '<')
+ state = 60;
+ else if (c == '>')
+ state = 61;
+ else if (c == '~')
+ return SWIG_TOKEN_NOT;
+ else if (c == '!')
+ state = 3;
+ else if (c == '\\')
+ return SWIG_TOKEN_BACKSLASH;
+ else if (c == '[')
+ return SWIG_TOKEN_LBRACKET;
+ else if (c == ']')
+ return SWIG_TOKEN_RBRACKET;
+ else if (c == '@')
+ return SWIG_TOKEN_AT;
+ else if (c == '$')
+ state = 75;
+ else if (c == '#')
+ return SWIG_TOKEN_POUND;
+ else if (c == '?')
+ return SWIG_TOKEN_QUESTION;
+
+ /* Look for multi-character sequences */
+
+ else if (c == '/') {
+ state = 1; /* Comment (maybe) */
+ s->start_line = s->line;
+ }
+ else if (c == '\"') {
+ state = 2; /* Possibly a string */
+ s->start_line = s->line;
+ Clear(s->text);
+ }
+
+ else if (c == ':')
+ state = 5; /* maybe double colon */
+ else if (c == '0')
+ state = 83; /* An octal or hex value */
+ else if (c == '\'') {
+ s->start_line = s->line;
+ Clear(s->text);
+ state = 9; /* A character constant */
+ } else if (c == '`') {
+ s->start_line = s->line;
+ Clear(s->text);
+ state = 900;
+ }
+
+ else if (c == '.')
+ state = 100; /* Maybe a number, maybe just a period */
+ else if (isdigit(c))
+ state = 8; /* A numerical value */
+ else
+ state = 99; /* An error */
+ break;
+
+ case 1: /* Comment block */
+ if ((c = nextchar(s)) == 0)
+ return (0);
+ if (c == '/') {
+ state = 10; /* C++ style comment */
+ Clear(s->text);
+ Setline(s->text, Getline(s->str));
+ Setfile(s->text, Getfile(s->str));
+ Append(s->text, "//");
+ } else if (c == '*') {
+ state = 11; /* C style comment */
+ Clear(s->text);
+ Setline(s->text, Getline(s->str));
+ Setfile(s->text, Getfile(s->str));
+ Append(s->text, "/*");
+ } else if (c == '=') {
+ return SWIG_TOKEN_DIVEQUAL;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_SLASH;
+ }
+ break;
+ case 10: /* C++ style comment */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '\n') {
+ retract(s,1);
+ return SWIG_TOKEN_COMMENT;
+ } else {
+ state = 10;
+ }
+ break;
+ case 11: /* C style comment block */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '*') {
+ state = 12;
+ } else {
+ state = 11;
+ }
+ break;
+ case 12: /* Still in C style comment */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '*') {
+ state = 12;
+ } else if (c == '/') {
+ return SWIG_TOKEN_COMMENT;
+ } else {
+ state = 11;
+ }
+ break;
+
+ case 2: /* Processing a string */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated string\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '\"') {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_STRING;
+ } else if (c == '\\') {
+ Delitem(s->text, DOH_END);
+ get_escape(s);
+ } else
+ state = 2;
+ break;
+
+ case 3: /* Maybe a not equals */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_LNOT;
+ else if (c == '=')
+ return SWIG_TOKEN_NOTEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_LNOT;
+ }
+ break;
+
+ case 31: /* AND or Logical AND or ANDEQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_AND;
+ else if (c == '&')
+ return SWIG_TOKEN_LAND;
+ else if (c == '=')
+ return SWIG_TOKEN_ANDEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_AND;
+ }
+ break;
+
+ case 32: /* OR or Logical OR */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_OR;
+ else if (c == '|')
+ return SWIG_TOKEN_LOR;
+ else if (c == '=')
+ return SWIG_TOKEN_OREQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_OR;
+ }
+ break;
+
+ case 33: /* EQUAL or EQUALTO */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_EQUAL;
+ else if (c == '=')
+ return SWIG_TOKEN_EQUALTO;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_EQUAL;
+ }
+ break;
+
+ case 4: /* A wrapper generator directive (maybe) */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_PERCENT;
+ if (c == '{') {
+ state = 40; /* Include block */
+ Clear(s->text);
+ Setline(s->text, Getline(s->str));
+ Setfile(s->text, Getfile(s->str));
+ s->start_line = s->line;
+ } else if (s->idstart && strchr(s->idstart, '%') &&
+ ((isalpha(c)) || (c == '_'))) {
+ state = 7;
+ } else if (c == '=') {
+ return SWIG_TOKEN_MODEQUAL;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_PERCENT;
+ }
+ break;
+
+ case 40: /* Process an include block */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated block\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '%')
+ state = 41;
+ break;
+ case 41: /* Still processing include block */
+ if ((c = nextchar(s)) == 0) {
+ set_error(s,s->start_line,"Unterminated code block");
+ return 0;
+ }
+ if (c == '}') {
+ Delitem(s->text, DOH_END);
+ Delitem(s->text, DOH_END);
+ Seek(s->text,0,SEEK_SET);
+ return SWIG_TOKEN_CODEBLOCK;
+ } else {
+ state = 40;
+ }
+ break;
+
+ case 5: /* Maybe a double colon */
+
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_COLON;
+ if (c == ':')
+ state = 50;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_COLON;
+ }
+ break;
+
+ case 50: /* DCOLON, DCOLONSTAR */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_DCOLON;
+ else if (c == '*')
+ return SWIG_TOKEN_DCOLONSTAR;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_DCOLON;
+ }
+ break;
+
+ case 60: /* shift operators */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_LESSTHAN;
+ if (c == '<')
+ state = 240;
+ else if (c == '=')
+ return SWIG_TOKEN_LTEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_LESSTHAN;
+ }
+ break;
+ case 61:
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_GREATERTHAN;
+ if (c == '>')
+ state = 250;
+ else if (c == '=')
+ return SWIG_TOKEN_GTEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_GREATERTHAN;
+ }
+ break;
+ case 7: /* Identifier */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_ID;
+ if (isalnum(c) || (c == '_') || (c == '$')) {
+ state = 7;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_ID;
+ }
+ break;
+
+ case 75: /* Special identifier $ */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_DOLLAR;
+ if (isalnum(c) || (c == '_') || (c == '*') || (c == '&')) {
+ state = 7;
+ } else {
+ retract(s,1);
+ if (Len(s->text) == 1) return SWIG_TOKEN_DOLLAR;
+ return SWIG_TOKEN_ID;
+ }
+ break;
+
+ case 8: /* A numerical digit */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_INT;
+ if (c == '.') {
+ state = 81;
+ } else if ((c == 'e') || (c == 'E')) {
+ state = 82;
+ } else if ((c == 'f') || (c == 'F')) {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_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(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ break;
+ case 81: /* A floating pointer number of some sort */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_DOUBLE;
+ if (isdigit(c))
+ state = 81;
+ else if ((c == 'e') || (c == 'E'))
+ state = 820;
+ else if ((c == 'f') || (c == 'F')) {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_FLOAT;
+ } else if ((c == 'l') || (c == 'L')) {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_DOUBLE;
+ } else {
+ retract(s, 1);
+ return (SWIG_TOKEN_DOUBLE);
+ }
+ break;
+ case 82:
+ if ((c = nextchar(s)) == 0) {
+ retract(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ if ((isdigit(c)) || (c == '-') || (c == '+'))
+ state = 86;
+ else {
+ retract(s, 2);
+ return (SWIG_TOKEN_INT);
+ }
+ break;
+ case 820:
+ /* Like case 82, but we've seen a decimal point. */
+ if ((c = nextchar(s)) == 0) {
+ retract(s, 1);
+ return SWIG_TOKEN_DOUBLE;
+ }
+ if ((isdigit(c)) || (c == '-') || (c == '+'))
+ state = 86;
+ else {
+ retract(s, 2);
+ return (SWIG_TOKEN_DOUBLE);
+ }
+ break;
+ case 83:
+ /* Might be a hexadecimal or octal number */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_INT;
+ 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(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ break;
+ case 84:
+ /* This is an octal number */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_INT;
+ if (isdigit(c))
+ state = 84;
+ else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ break;
+ case 85:
+ /* This is an hex number */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_INT;
+ if (isxdigit(c))
+ state = 85;
+ else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ break;
+
+ case 86:
+ /* Rest of floating point number */
+
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_DOUBLE;
+ if (isdigit(c))
+ state = 86;
+ else if ((c == 'f') || (c == 'F')) {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_FLOAT;
+ } else if ((c == 'l') || (c == 'L')) {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_DOUBLE;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_DOUBLE;
+ }
+ break;
+
+ case 87:
+ /* A long integer of some sort */
+ 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')) {
+ state = 880;
+ } else {
+ 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) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated character constant\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '\'') {
+ Delitem(s->text, DOH_END);
+ return (SWIG_TOKEN_CHAR);
+ } else if (c == '\\') {
+ Delitem(s->text, DOH_END);
+ get_escape(s);
+ }
+ break;
+
+ /* A period or maybe a floating point number */
+
+ case 100:
+ if ((c = nextchar(s)) == 0)
+ return (0);
+ if (isdigit(c))
+ state = 81;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_PERIOD;
+ }
+ break;
+
+ case 200: /* PLUS, PLUSPLUS, PLUSEQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_PLUS;
+ else if (c == '+')
+ return SWIG_TOKEN_PLUSPLUS;
+ else if (c == '=')
+ return SWIG_TOKEN_PLUSEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_PLUS;
+ }
+ break;
+
+ case 210: /* MINUS, MINUSMINUS, MINUSEQUAL, ARROW */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_MINUS;
+ else if (c == '-')
+ return SWIG_TOKEN_MINUSMINUS;
+ else if (c == '=')
+ return SWIG_TOKEN_MINUSEQUAL;
+ else if (c == '>')
+ state = 211;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_MINUS;
+ }
+ break;
+
+ case 211: /* ARROW, ARROWSTAR */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_ARROW;
+ else if (c == '*')
+ return SWIG_TOKEN_ARROWSTAR;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_ARROW;
+ }
+ break;
+
+
+ case 220: /* STAR, TIMESEQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_STAR;
+ else if (c == '=')
+ return SWIG_TOKEN_TIMESEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_STAR;
+ }
+ break;
+
+ case 230: /* XOR, XOREQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_XOR;
+ else if (c == '=')
+ return SWIG_TOKEN_XOREQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_XOR;
+ }
+ break;
+
+ case 240: /* LSHIFT, LSEQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_LSHIFT;
+ else if (c == '=')
+ return SWIG_TOKEN_LSEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_LSHIFT;
+ }
+ break;
+
+ case 250: /* RSHIFT, RSEQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_RSHIFT;
+ else if (c == '=')
+ return SWIG_TOKEN_RSEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_RSHIFT;
+ }
+ break;
+
+
+ /* An illegal character */
+
+ /* Reverse string */
+ case 900:
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated character constant\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '`') {
+ Delitem(s->text, DOH_END);
+ return (SWIG_TOKEN_RSTRING);
+ }
+ break;
+
+ default:
+ return SWIG_TOKEN_ILLEGAL;
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_token()
+ *
+ * Real entry point to return the next token. Returns 0 if at end of input.
+ * ----------------------------------------------------------------------------- */
+
+int Scanner_token(Scanner * s) {
+ int t;
+ Delete(s->error);
+ if (s->nexttoken >= 0) {
+ t = s->nexttoken;
+ s->nexttoken = -1;
+ return t;
+ }
+ s->start_line = 0;
+ t = look(s);
+ if (!s->start_line) {
+ Setline(s->text,s->line);
+ } else {
+ Setline(s->text,s->start_line);
+ }
+ return t;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_text()
+ *
+ * Return the lexene associated with the last returned token.
+ * ----------------------------------------------------------------------------- */
+
+String *Scanner_text(Scanner * s) {
+ return s->text;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_skip_line()
+ *
+ * Skips to the end of a line
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_skip_line(Scanner * s) {
+ char c;
+ int done = 0;
+ Clear(s->text);
+ Setfile(s->text, Getfile(s->str));
+ Setline(s->text, s->line);
+ while (!done) {
+ if ((c = nextchar(s)) == 0)
+ return;
+ if (c == '\\') {
+ c = nextchar(s);
+ } else if (c == '\n') {
+ done = 1;
+ }
+ }
+ return;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_skip_balanced()
+ *
+ * Skips a piece of code enclosed in begin/end symbols such as '{...}' or
+ * (...). Ignores symbols inside comments or strings.
+ * ----------------------------------------------------------------------------- */
+
+int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) {
+ char c;
+ int num_levels = 1;
+ int l;
+ int state = 0;
+ char temp[2] = { 0, 0 };
+ l = s->line;
+ temp[0] = (char) startchar;
+ Clear(s->text);
+ Setfile(s->text, Getfile(s->str));
+ Setline(s->text, s->line);
+
+ Append(s->text, temp);
+ while (num_levels > 0) {
+ if ((c = nextchar(s)) == 0) {
+ return -1;
+ }
+ 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;
+ }
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_isoperator()
+ *
+ * Returns 0 or 1 depending on whether or not a token corresponds to a C/C++
+ * operator.
+ * ----------------------------------------------------------------------------- */
+
+int
+Scanner_isoperator(int tokval) {
+ if (tokval >= 100) return 1;
+ return 0;
+}
diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c
new file mode 100644
index 0000000..68696ec
--- /dev/null
+++ b/Source/Swig/stype.c
@@ -0,0 +1,1105 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * stype.c
+ *
+ * This file provides general support for datatypes that are encoded in
+ * the form of simple strings.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_stype_c[] = "$Id: stype.c 11080 2009-01-24 13:15:51Z bhy $";
+
+#include "swig.h"
+#include "cparse.h"
+#include <ctype.h>
+
+/* -----------------------------------------------------------------------------
+ * Synopsis
+ *
+ * The purpose of this module is to provide a general purpose type representation
+ * based on simple text strings.
+ *
+ * General idea:
+ *
+ * Types are represented by a base type (e.g., "int") and a collection of
+ * type operators applied to the base (e.g., pointers, arrays, etc...).
+ *
+ * Encoding:
+ *
+ * Types are encoded as strings of type constructors such as follows:
+ *
+ * String Encoding C Example
+ * --------------- ---------
+ * p.p.int int **
+ * a(300).a(400).int int [300][400]
+ * p.q(const).char char const *
+ *
+ * All type constructors are denoted by a trailing '.':
+ *
+ * '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
+ * "p.q(const).char" is "a pointer to a const char".
+ *
+ * This representation of types is fairly convenient because ordinary string
+ * operations can be used for type manipulation. For example, a type could be
+ * formed by combining two strings such as the following:
+ *
+ * "p.p." + "a(400).int" = "p.p.a(400).int"
+ *
+ * Similarly, one could strip a 'const' declaration from a type doing something
+ * like this:
+ *
+ * Replace(t,"q(const).","",DOH_REPLACE_ANY)
+ *
+ * For the most part, this module tries to minimize the use of special
+ * characters (*, [, <, etc...) in its type encoding. One reason for this
+ * is that SWIG might be extended to encode data in formats such as XML
+ * where you might want to do this:
+ *
+ * <function>
+ * <type>p.p.int</type>
+ * ...
+ * </function>
+ *
+ * Or alternatively,
+ *
+ * <function type="p.p.int" ...>blah</function>
+ *
+ * In either case, it's probably best to avoid characters such as '&', '*', or '<'.
+ *
+ * Why not use C syntax? Well, C syntax is fairly complicated to parse
+ * and not particularly easy to manipulate---especially for adding, deleting and
+ * composing type constructors. The string representation presented here makes
+ * this pretty easy.
+ *
+ * Why not use a bunch of nested data structures? Are you kidding? How
+ * would that be easier to use than a few simple string operations?
+ * ----------------------------------------------------------------------------- */
+
+
+SwigType *NewSwigType(int t) {
+ switch (t) {
+ case T_BOOL:
+ return NewString("bool");
+ break;
+ case T_INT:
+ return NewString("int");
+ break;
+ case T_UINT:
+ return NewString("unsigned int");
+ break;
+ case T_SHORT:
+ return NewString("short");
+ break;
+ case T_USHORT:
+ return NewString("unsigned short");
+ break;
+ case T_LONG:
+ return NewString("long");
+ break;
+ case T_ULONG:
+ return NewString("unsigned long");
+ break;
+ case T_FLOAT:
+ return NewString("float");
+ break;
+ case T_DOUBLE:
+ return NewString("double");
+ break;
+ case T_COMPLEX:
+ return NewString("complex");
+ break;
+ case T_CHAR:
+ return NewString("char");
+ break;
+ case T_SCHAR:
+ return NewString("signed char");
+ break;
+ 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;
+ default:
+ break;
+ }
+ return NewStringEmpty();
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_push()
+ *
+ * Push a type constructor onto the type
+ * ----------------------------------------------------------------------------- */
+
+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] != '.')
+ Insert(t, 0, ".");
+ }
+ Insert(t, 0, cons);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_ispointer_return()
+ *
+ * Testing functions for querying a raw datatype
+ * ----------------------------------------------------------------------------- */
+
+int SwigType_ispointer_return(SwigType *t) {
+ char *c;
+ int idx;
+ if (!t)
+ return 0;
+ c = Char(t);
+ idx = strlen(c) - 4;
+ if (idx >= 0) {
+ return (strcmp(c + idx, ").p.") == 0);
+ }
+ return 0;
+}
+
+int SwigType_isreference_return(SwigType *t) {
+ char *c;
+ int idx;
+ if (!t)
+ return 0;
+ c = Char(t);
+ idx = strlen(c) - 4;
+ if (idx >= 0) {
+ return (strcmp(c + idx, ").r.") == 0);
+ }
+ return 0;
+}
+
+int SwigType_isconst(SwigType *t) {
+ char *c;
+ if (!t)
+ return 0;
+ c = Char(t);
+ 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) || SwigType_isarray(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;
+}
+
+/* -----------------------------------------------------------------------------
+ * 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.SWIGTYPE
+ * References: r.SWIGTYPE
+ * Arrays: a().SWIGTYPE
+ * Types: SWIGTYPE
+ * MemberPointer: m(CLASS).SWIGTYPE
+ * Enums: enum SWIGTYPE
+ *
+ * Note: if this function is applied to a primitive type, it returns NULL. This
+ * allows recursive application for special types like arrays.
+ * ----------------------------------------------------------------------------- */
+
+#ifdef SWIG_DEFAULT_CACHE
+static Hash *default_cache = 0;
+#endif
+
+#define SWIG_NEW_TYPE_DEFAULT
+/* The new default type resolution method:
+
+1.- It preserves the original mixed types, then it goes 'backward'
+ first deleting the qualifier, then the inner types
+
+ typedef A *Aptr;
+ const Aptr&;
+ r.q(const).Aptr -> r.q(const).p.SWIGTYPE
+ r.q(const).p.SWIGTYPE -> r.p.SWIGTYPE
+ r.p.SWIGTYPE -> r.SWIGTYPE
+ r.SWIGTYPE -> SWIGTYPE
+
+
+ enum Hello {};
+ const Hello& hi;
+ r.q(const).Hello -> r.q(const).enum SWIGTYPE
+ r.q(const).enum SWIGTYPE -> r.enum SWIGTYPE
+ r.enum SWIGTYPE -> r.SWIGTYPE
+ r.SWIGTYPE -> SWIGTYPE
+
+ int a[2][4];
+ a(2).a(4).int -> a(ANY).a(ANY).SWIGTYPE
+ a(ANY).a(ANY).SWIGTYPE -> a(ANY).a().SWIGTYPE
+ a(ANY).a().SWIGTYPE -> a(ANY).p.SWIGTYPE
+ a(ANY).p.SWIGTYPE -> a(ANY).SWIGTYPE
+ a(ANY).SWIGTYPE -> a().SWIGTYPE
+ a().SWIGTYPE -> p.SWIGTYPE
+ p.SWIGTYPE -> SWIGTYPE
+*/
+
+static
+void SwigType_add_default(String *def, SwigType *nr) {
+ if (Strcmp(nr, "SWIGTYPE") == 0) {
+ Append(def, "SWIGTYPE");
+ } else {
+ String *q = SwigType_isqualifier(nr) ? SwigType_pop(nr) : 0;
+ if (q && strstr(Char(nr), "SWIGTYPE")) {
+ Append(def, nr);
+ } else {
+ String *nd = SwigType_default(nr);
+ if (nd) {
+ String *bdef = nd;
+ if (q) {
+ bdef = NewStringf("%s%s", q, nd);
+ if ((Strcmp(nr, bdef) == 0)) {
+ Delete(bdef);
+ bdef = nd;
+ } else {
+ Delete(nd);
+ }
+ }
+ Append(def, bdef);
+ Delete(bdef);
+ } else {
+ Append(def, nr);
+ }
+ }
+ Delete(q);
+ }
+}
+
+
+SwigType *SwigType_default(SwigType *t) {
+ String *r1, *def;
+ String *r = 0;
+ char *cr;
+
+#ifdef SWIG_DEFAULT_CACHE
+ if (!default_cache)
+ default_cache = NewHash();
+
+ r = Getattr(default_cache, t);
+ if (r) {
+ return Copy(r);
+ }
+#endif
+
+ if (SwigType_isvarargs(t)) {
+ return 0;
+ }
+
+ r = t;
+ while ((r1 = SwigType_typedef_resolve(r))) {
+ if (r != t)
+ Delete(r);
+ r = r1;
+ }
+ if (SwigType_isqualifier(r)) {
+ String *q;
+ if (r == t)
+ r = Copy(t);
+ q = SwigType_pop(r);
+ if (strstr(Char(r), "SWIGTYPE")) {
+ Delete(q);
+ def = r;
+ return def;
+ }
+ Delete(q);
+ }
+ cr = Char(r);
+ if (strcmp(cr, "p.SWIGTYPE") == 0) {
+ def = NewString("SWIGTYPE");
+ } else if (SwigType_ispointer(r)) {
+#ifdef SWIG_NEW_TYPE_DEFAULT
+ SwigType *nr = Copy(r);
+ SwigType_del_pointer(nr);
+ def = SwigType_isfunction(nr) ? NewStringEmpty() : NewString("p.");
+ SwigType_add_default(def, nr);
+ Delete(nr);
+#else
+ def = NewString("p.SWIGTYPE");
+#endif
+ } else if (strcmp(cr, "r.SWIGTYPE") == 0) {
+ def = NewString("SWIGTYPE");
+ } else if (SwigType_isreference(r)) {
+#ifdef SWIG_NEW_TYPE_DEFAULT
+ SwigType *nr = Copy(r);
+ SwigType_del_reference(nr);
+ def = NewString("r.");
+ SwigType_add_default(def, nr);
+ Delete(nr);
+#else
+ def = NewString("r.SWIGTYPE");
+#endif
+ } else if (SwigType_isarray(r)) {
+ if (strcmp(cr, "a().SWIGTYPE") == 0) {
+ def = NewString("p.SWIGTYPE");
+ } else if (strcmp(cr, "a(ANY).SWIGTYPE") == 0) {
+ def = NewString("a().SWIGTYPE");
+ } else {
+ int i, empty = 0;
+ int ndim = SwigType_array_ndim(r);
+ SwigType *nr = Copy(r);
+ for (i = 0; i < ndim; i++) {
+ String *dim = SwigType_array_getdim(r, i);
+ if (!Len(dim)) {
+ char *c = Char(nr);
+ empty = strstr(c, "a(ANY).") != c;
+ }
+ Delete(dim);
+ }
+ if (empty) {
+ def = NewString("a().");
+ } else {
+ def = NewString("a(ANY).");
+ }
+#ifdef SWIG_NEW_TYPE_DEFAULT
+ SwigType_del_array(nr);
+ SwigType_add_default(def, nr);
+#else
+ Append(def, "SWIGTYPE");
+#endif
+ Delete(nr);
+ }
+ } else if (SwigType_ismemberpointer(r)) {
+ if (strcmp(cr, "m(CLASS).SWIGTYPE") == 0) {
+ def = NewString("p.SWIGTYPE");
+ } else {
+ def = NewString("m(CLASS).SWIGTYPE");
+ }
+ } else if (SwigType_isenum(r)) {
+ if (strcmp(cr, "enum SWIGTYPE") == 0) {
+ def = NewString("SWIGTYPE");
+ } else {
+ def = NewString("enum SWIGTYPE");
+ }
+ } else if (SwigType_isfunction(r)) {
+ if (strcmp(cr, "f(ANY).SWIGTYPE") == 0) {
+ def = NewString("p.SWIGTYPE");
+ } else {
+ def = NewString("p.f(ANY).SWIGTYPE");
+ }
+ } else {
+ def = NewString("SWIGTYPE");
+ }
+ if (r != t)
+ Delete(r);
+ if (Equal(def, t)) {
+ Delete(def);
+ def = 0;
+ }
+#ifdef SWIG_DEFAULT_CACHE
+ /* The cache produces strange results, see enum_template.i case */
+ if (def) {
+ String *cdef = Copy(def);
+ Setattr(default_cache, t, cdef);
+ Delete(cdef);
+ }
+#endif
+
+ /* Printf(stderr,"type : def %s : %s\n", t, def); */
+
+ return def;
+}
+
+/* -----------------------------------------------------------------------------
+ * 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;
+ int i, sz;
+ char *d = Char(t);
+ char *c = strstr(d, "<(");
+
+ if (!c || !strstr(c + 2, ")>"))
+ return NewString(t);
+
+ r = NewStringWithSize(d, c - d);
+ if (*(c - 1) == '<')
+ Putc(' ', r);
+ Putc('<', r);
+
+ p = SwigType_parmlist(c + 1);
+ sz = Len(p);
+ for (i = 0; i < sz; i++) {
+ String *str = SwigType_str(Getitem(p, i), 0);
+ /* Avoid creating a <: token, which is the same as [ in C++ - put a space after '<'. */
+ if (i == 0 && Len(str))
+ Putc(' ', r);
+ Append(r, str);
+ if ((i + 1) < sz)
+ Putc(',', r);
+ Delete(str);
+ }
+ Putc(' ', r);
+ Putc('>', r);
+ suffix = SwigType_templatesuffix(t);
+ Append(r, suffix);
+ Delete(suffix);
+ Delete(p);
+ return r;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_str()
+ *
+ * Create a C string representation of a datatype.
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_str(SwigType *s, const_String_or_char_ptr id) {
+ String *result;
+ String *element = 0, *nextelement;
+ List *elements;
+ int nelements, i;
+
+ if (id) {
+ result = NewString(id);
+ } else {
+ result = NewStringEmpty();
+ }
+
+ elements = SwigType_split(s);
+ 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_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, "&");
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result, 0, "(");
+ Append(result, ")");
+ }
+ } else if (SwigType_isarray(element)) {
+ 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, ",");
+ }
+ Append(result, ")");
+ Delete(parms);
+ } else {
+ if (strcmp(Char(element), "v(...)") == 0) {
+ Insert(result, 0, "...");
+ } else {
+ String *bs = SwigType_namestr(element);
+ Insert(result, 0, " ");
+ Insert(result, 0, bs);
+ Delete(bs);
+ }
+ }
+ element = nextelement;
+ }
+ Delete(elements);
+ Chop(result);
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_ltype(SwigType *ty)
+ *
+ * Create a locally assignable type
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_ltype(SwigType *s) {
+ String *result;
+ String *element;
+ SwigType *td, *tc = 0;
+ List *elements;
+ int nelements, i;
+ int firstarray = 1;
+ int notypeconv = 0;
+
+ result = NewStringEmpty();
+ tc = Copy(s);
+ /* Nuke all leading qualifiers */
+ while (SwigType_isqualifier(tc)) {
+ Delete(SwigType_pop(tc));
+ }
+ if (SwigType_issimple(tc)) {
+ /* Resolve any typedef definitions */
+ SwigType *tt = Copy(tc);
+ td = 0;
+ while ((td = SwigType_typedef_resolve(tt))) {
+ if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
+ /* We need to use the typedef type */
+ Delete(tt);
+ tt = td;
+ break;
+ } else if (td) {
+ Delete(tt);
+ tt = td;
+ }
+ }
+ if (td) {
+ Delete(tc);
+ tc = 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);
+ /* when we see a function, we need to preserve the following types */
+ if (SwigType_isfunction(element)) {
+ notypeconv = 1;
+ }
+ 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)) {
+ if (notypeconv) {
+ Append(result, element);
+ } else {
+ Append(result, "p.");
+ }
+ firstarray = 0;
+ } else if (SwigType_isarray(element) && firstarray) {
+ if (notypeconv) {
+ Append(result, element);
+ } else {
+ Append(result, "p.");
+ }
+ firstarray = 0;
+ } else if (SwigType_isenum(element)) {
+ int anonymous_enum = (Cmp(element, "enum ") == 0);
+ if (notypeconv || !anonymous_enum) {
+ Append(result, element);
+ } else {
+ Append(result, "int");
+ }
+ } else {
+ Append(result, element);
+ }
+ }
+ Delete(elements);
+ 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_ptr id) {
+ String *result;
+ SwigType *tc;
+
+ tc = SwigType_ltype(s);
+ result = SwigType_str(tc, id);
+ Delete(tc);
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_rcaststr()
+ *
+ * Produces a casting string that maps the type returned by lstr() to the real
+ * datatype printed by str().
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) {
+ String *result, *cast;
+ String *element = 0, *nextelement;
+ SwigType *td, *rs, *tc = 0;
+ List *elements;
+ int nelements, i;
+ int clear = 1;
+ int firstarray = 1;
+ int isreference = 0;
+ int isarray = 0;
+
+ result = NewStringEmpty();
+
+ if (SwigType_isconst(s)) {
+ tc = Copy(s);
+ Delete(SwigType_pop(tc));
+ rs = tc;
+ } else {
+ rs = s;
+ }
+
+ if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs))) {
+ td = 0;
+ } else {
+ td = SwigType_typedef_resolve(rs);
+ }
+
+ if (td) {
+ if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
+ elements = SwigType_split(td);
+ } else {
+ elements = SwigType_split(rs);
+ }
+ Delete(td);
+ } else {
+ elements = SwigType_split(rs);
+ }
+ 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_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, "&");
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result, 0, "(");
+ Append(result, ")");
+ }
+ isreference = 1;
+ } else if (SwigType_isarray(element)) {
+ DOH *size;
+ if (firstarray && !isreference) {
+ Append(result, "(*)");
+ firstarray = 0;
+ } else {
+ Append(result, "[");
+ size = SwigType_parm(element);
+ Append(result, size);
+ Append(result, "]");
+ Delete(size);
+ clear = 0;
+ }
+ isarray = 1;
+ } 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);
+ Delete(p);
+ if (j < (plen - 1))
+ Append(result, ",");
+ }
+ Append(result, ")");
+ Delete(parms);
+ } else {
+ String *bs = SwigType_namestr(element);
+ Insert(result, 0, " ");
+ Insert(result, 0, bs);
+ Delete(bs);
+ }
+ element = nextelement;
+ }
+ Delete(elements);
+ if (clear) {
+ cast = NewStringEmpty();
+ } else {
+ cast = NewStringf("(%s)", result);
+ }
+ if (name) {
+ if (isreference) {
+ if (isarray)
+ Clear(cast);
+ Append(cast, "*");
+ }
+ Append(cast, name);
+ }
+ Delete(result);
+ Delete(tc);
+ return cast;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_lcaststr()
+ *
+ * Casts a variable from the real type to the local datatype.
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_lcaststr(SwigType *s, const_String_or_char_ptr name) {
+ String *result;
+
+ result = NewStringEmpty();
+
+ if (SwigType_isarray(s)) {
+ String *lstr = SwigType_lstr(s, 0);
+ Printf(result, "(%s)%s", lstr, name);
+ Delete(lstr);
+ } else if (SwigType_isreference(s)) {
+ String *str = SwigType_str(s, 0);
+ Printf(result, "(%s)", str);
+ Delete(str);
+ if (name)
+ Append(result, name);
+ } else if (SwigType_isqualifier(s)) {
+ String *lstr = SwigType_lstr(s, 0);
+ Printf(result, "(%s)%s", lstr, name);
+ Delete(lstr);
+ } else {
+ if (name)
+ Append(result, name);
+ }
+ return result;
+}
+
+
+/* keep old mangling since Java codes need it */
+String *SwigType_manglestr_default(SwigType *s) {
+ char *c;
+ String *result = 0;
+ String *base = 0;
+ SwigType *lt;
+ SwigType *sr = SwigType_typedef_qualified(s);
+ SwigType *ss = SwigType_typedef_resolve_all(sr);
+
+ s = ss;
+
+ if (SwigType_istemplate(ss)) {
+ SwigType *ty = Swig_symbol_template_deftype(ss, 0);
+ Delete(ss);
+ ss = ty;
+ s = ss;
+ }
+ Delete(sr);
+
+ lt = SwigType_ltype(s);
+ result = SwigType_prefix(lt);
+ base = SwigType_base(lt);
+
+ c = Char(result);
+ while (*c) {
+ if (!isalnum((int) *c))
+ *c = '_';
+ c++;
+ }
+ if (SwigType_istemplate(base)) {
+ String *b = SwigType_namestr(base);
+ Delete(base);
+ base = b;
+ }
+
+ Replace(base, "struct ", "", DOH_REPLACE_ANY); /* This might be problematic */
+ Replace(base, "class ", "", DOH_REPLACE_ANY);
+ Replace(base, "union ", "", DOH_REPLACE_ANY);
+ Replace(base, "enum ", "", DOH_REPLACE_ANY);
+
+ 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++;
+ }
+ Append(result, base);
+ Insert(result, 0, "_");
+ Delete(lt);
+ Delete(base);
+ if (ss)
+ Delete(ss);
+ return result;
+}
+
+String *SwigType_manglestr(SwigType *s) {
+ return SwigType_manglestr_default(s);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_typename_replace()
+ *
+ * Replaces a typename in a type with something else. Needed for templates.
+ * ----------------------------------------------------------------------------- */
+
+void SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
+ String *nt;
+ int i, ilen;
+ List *elem;
+
+ if (!Strstr(t, pat))
+ return;
+
+ if (Equal(t, pat)) {
+ Replace(t, pat, rep, DOH_REPLACE_ANY);
+ return;
+ }
+ nt = NewStringEmpty();
+ elem = SwigType_split(t);
+ ilen = Len(elem);
+ for (i = 0; i < ilen; i++) {
+ String *e = Getitem(elem, i);
+ if (SwigType_issimple(e)) {
+ if (Equal(e, pat)) {
+ /* 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 (Equal(e, pat)) {
+ String *repbase = SwigType_templateprefix(rep);
+ Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST);
+ Delete(repbase);
+ }
+ {
+ String *tsuffix;
+ List *tparms = SwigType_parmlist(e);
+ int j, jlen;
+ String *nt = SwigType_templateprefix(e);
+ Append(nt, "<(");
+ jlen = Len(tparms);
+ for (j = 0; j < jlen; j++) {
+ SwigType_typename_replace(Getitem(tparms, j), pat, rep);
+ Append(nt, Getitem(tparms, j));
+ if (j < (jlen - 1))
+ Putc(',', nt);
+ }
+ tsuffix = SwigType_templatesuffix(e);
+ Printf(nt, ")>%s", tsuffix);
+ Delete(tsuffix);
+ Clear(e);
+ Append(e, nt);
+ Delete(nt);
+ Delete(tparms);
+ }
+ } else if (Swig_scopename_check(e)) {
+ String *first, *rest;
+ first = Swig_scopename_first(e);
+ rest = Swig_scopename_suffix(e);
+ SwigType_typename_replace(rest, pat, rep);
+ SwigType_typename_replace(first, pat, rep);
+ Clear(e);
+ Printv(e, first, "::", rest, NIL);
+ Delete(first);
+ Delete(rest);
+ }
+ } else if (SwigType_isfunction(e)) {
+ int j, jlen;
+ List *fparms = SwigType_parmlist(e);
+ Clear(e);
+ Append(e, "f(");
+ jlen = Len(fparms);
+ for (j = 0; j < jlen; j++) {
+ SwigType_typename_replace(Getitem(fparms, j), pat, rep);
+ Append(e, Getitem(fparms, j));
+ if (j < (jlen - 1))
+ Putc(',', e);
+ }
+ Append(e, ").");
+ Delete(fparms);
+ } else if (SwigType_isarray(e)) {
+ Replace(e, pat, rep, DOH_REPLACE_ID);
+ }
+ Append(nt, e);
+ }
+ Clear(t);
+ Append(t, nt);
+ Delete(nt);
+ Delete(elem);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_check_decl()
+ *
+ * Checks type declarators for a match
+ * ----------------------------------------------------------------------------- */
+
+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 = Equal(t2, decl);
+ Delete(t);
+ Delete(t1);
+ Delete(t2);
+ return r == 1;
+}
diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
new file mode 100644
index 0000000..a39a2ad
--- /dev/null
+++ b/Source/Swig/swig.h
@@ -0,0 +1,403 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * swig.h
+ *
+ * Header file for the SWIG core.
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: swig.h 11473 2009-07-30 06:06:49Z wsfulton $ */
+
+#ifndef SWIGCORE_H_
+#define SWIGCORE_H_
+
+#ifndef MACSWIG
+#include "swigconfig.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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;
+ typedef DOH Hash;
+ typedef DOH List;
+ typedef DOH String_or_char;
+ 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 --- */
+
+/* --- The ordering of type values is used to determine type-promotion
+ in the parser. Do not change */
+
+/* Numeric types */
+
+#define T_BOOL 1
+#define T_SCHAR 2
+#define T_UCHAR 3
+#define T_SHORT 4
+#define T_USHORT 5
+#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_LONGDOUBLE 22
+#define T_FLTCPLX 23
+#define T_DBLCPLX 24
+#define T_NUMERIC 25
+
+#define T_COMPLEX T_DBLCPLX
+
+/* non-numeric */
+
+#define T_CHAR 29
+#define T_WCHAR 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
+
+
+/* --- File interface --- */
+
+#include "swigfile.h"
+
+/* --- Command line parsing --- */
+
+#include "swigopt.h"
+
+/* --- Scanner Interface --- */
+
+#include "swigscan.h"
+
+/* --- Functions for manipulating the string-based type encoding --- */
+
+ extern SwigType *NewSwigType(int typecode);
+ extern SwigType *SwigType_del_element(SwigType *t);
+ extern SwigType *SwigType_add_pointer(SwigType *t);
+ extern SwigType *SwigType_add_memberpointer(SwigType *t, const_String_or_char_ptr qual);
+ extern SwigType *SwigType_del_memberpointer(SwigType *t);
+ extern SwigType *SwigType_del_pointer(SwigType *t);
+ extern SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size);
+ extern SwigType *SwigType_del_array(SwigType *t);
+ extern SwigType *SwigType_pop_arrays(SwigType *t);
+ extern SwigType *SwigType_add_reference(SwigType *t);
+ extern SwigType *SwigType_del_reference(SwigType *t);
+ extern SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual);
+ extern SwigType *SwigType_del_qualifier(SwigType *t);
+ extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms);
+ extern SwigType *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(const SwigType *t);
+ extern String *SwigType_pop(SwigType *t);
+ extern void SwigType_push(SwigType *t, SwigType *s);
+ extern List *SwigType_parmlist(const SwigType *p);
+ extern String *SwigType_parm(String *p);
+ extern String *SwigType_str(SwigType *s, const_String_or_char_ptr id);
+ extern String *SwigType_lstr(SwigType *s, const_String_or_char_ptr id);
+ extern String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr id);
+ extern String *SwigType_lcaststr(SwigType *s, const_String_or_char_ptr id);
+ extern String *SwigType_manglestr(SwigType *t);
+ extern SwigType *SwigType_ltype(SwigType *t);
+ extern int SwigType_ispointer(SwigType *t);
+ extern int SwigType_ispointer_return(SwigType *t);
+ extern int SwigType_isfunctionpointer(SwigType *t);
+ extern int SwigType_ismemberpointer(SwigType *t);
+ extern int SwigType_isreference(SwigType *t);
+ extern int SwigType_isreference_return(SwigType *t);
+ extern int SwigType_isarray(SwigType *t);
+ extern int SwigType_prefix_is_simple_1D_array(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_ptr decl);
+ extern SwigType *SwigType_strip_qualifiers(SwigType *t);
+ extern SwigType *SwigType_functionpointer_decompose(SwigType *t);
+ extern String *SwigType_base(const SwigType *t);
+ extern String *SwigType_namestr(const SwigType *t);
+ extern String *SwigType_templateprefix(const SwigType *t);
+ extern String *SwigType_templatesuffix(const SwigType *t);
+ extern String *SwigType_templateargs(const SwigType *t);
+ extern String *SwigType_prefix(const 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, const_String_or_char_ptr 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);
+ extern SwigType *SwigType_alttype(SwigType *t, int ltmap);
+
+ extern void SwigType_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl);
+ extern SwigType *SwigType_template_deftype(const SwigType *type, Symtab *tscope);
+
+/* --- Type-system managment --- */
+ extern void SwigType_typesystem_init(void);
+ extern int SwigType_typedef(SwigType *type, const_String_or_char_ptr name);
+ extern int SwigType_typedef_class(const_String_or_char_ptr name);
+ extern int SwigType_typedef_using(const_String_or_char_ptr qname);
+ extern void SwigType_inherit(String *subclass, String *baseclass, String *cast, String *conversioncode);
+ 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(const_String_or_char_ptr name);
+ extern void SwigType_inherit_scope(Typetab *scope);
+ extern Typetab *SwigType_pop_scope(void);
+ extern Typetab *SwigType_set_scope(Typetab *h);
+ extern void SwigType_print_scope(Typetab *t);
+ extern SwigType *SwigType_typedef_resolve(const 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_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_ptr clientdata);
+ extern void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr 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 int SwigType_type(SwigType *t);
+
+/* --- Symbol table module --- */
+
+ extern void Swig_symbol_init(void);
+ extern void Swig_symbol_setscopename(const_String_or_char_ptr name);
+ extern String *Swig_symbol_getscopename(void);
+ extern String *Swig_symbol_qualifiedscopename(Symtab *symtab);
+ extern Symtab *Swig_symbol_newscope(void);
+ extern Symtab *Swig_symbol_setscope(Symtab *);
+ extern Symtab *Swig_symbol_getscope(const_String_or_char_ptr symname);
+ extern Symtab *Swig_symbol_current(void);
+ extern Symtab *Swig_symbol_popscope(void);
+ extern Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *node);
+ extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *node);
+ extern Node *Swig_symbol_clookup(const_String_or_char_ptr symname, Symtab *tab);
+ extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
+ extern Symtab *Swig_symbol_cscope(const_String_or_char_ptr symname, Symtab *tab);
+ extern Node *Swig_symbol_clookup_local(const_String_or_char_ptr symname, Symtab *tab);
+ extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
+ 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(const_String_or_char_ptr aliasname, Symtab *tab);
+ extern void Swig_symbol_inherit(Symtab *tab);
+ extern SwigType *Swig_symbol_type_qualify(const SwigType *ty, Symtab *tab);
+ extern String *Swig_symbol_string_qualify(String *s, Symtab *tab);
+ extern SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab);
+
+ extern ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl);
+ extern SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope);
+ extern SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab);
+
+/* --- Parameters and Parameter Lists --- */
+
+#include "swigparm.h"
+
+extern String *ParmList_errorstr(ParmList *);
+extern int ParmList_is_compactdefargs(ParmList *p);
+
+/* --- Parse tree support --- */
+
+#include "swigtree.h"
+
+/* -- Wrapper function Object */
+
+#include "swigwrap.h"
+
+/* --- Naming functions --- */
+
+ extern void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format);
+ extern void Swig_name_unregister(const_String_or_char_ptr method);
+ extern String *Swig_name_mangle(const_String_or_char_ptr s);
+ extern String *Swig_name_wrapper(const_String_or_char_ptr fname);
+ extern String *Swig_name_member(const_String_or_char_ptr classname, const_String_or_char_ptr mname);
+ extern String *Swig_name_get(const_String_or_char_ptr vname);
+ extern String *Swig_name_set(const_String_or_char_ptr vname);
+ extern String *Swig_name_construct(const_String_or_char_ptr classname);
+ extern String *Swig_name_copyconstructor(const_String_or_char_ptr classname);
+ extern String *Swig_name_destroy(const_String_or_char_ptr classname);
+ extern String *Swig_name_disown(const_String_or_char_ptr classname);
+
+ extern void Swig_naming_init(void);
+ extern void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn);
+ extern Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl);
+ extern void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *namewrn, ParmList *declaratorparms);
+ extern void Swig_name_inherit(String *base, String *derived);
+ extern int Swig_need_protected(Node *n);
+ extern int Swig_need_name_warning(Node *n);
+ extern int Swig_need_redefined_warn(Node *a, Node *b, int InClass);
+
+ extern String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname);
+ extern String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl);
+ extern String *Swig_name_decl(Node *n);
+ extern String *Swig_name_fulldecl(Node *n);
+
+/* --- parameterized rename functions --- */
+
+ extern void Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object);
+ extern DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl);
+ extern void Swig_name_object_inherit(Hash *namehash, String *base, String *derived);
+ extern void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *n);
+ extern void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs);
+
+/* --- Misc --- */
+ extern char *Swig_copy_string(const char *c);
+ extern void Swig_set_fakeversion(const char *version);
+ extern const char *Swig_package_version(void);
+ extern void Swig_banner(File *f);
+ extern void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar);
+ extern String *Swig_strip_c_comments(const String *s);
+ extern String *Swig_filename_escape(String *filename);
+ extern void Swig_filename_correct(String *filename);
+ extern String *Swig_string_escape(String *s);
+ extern String *Swig_string_mangle(const String *s);
+ extern void Swig_scopename_split(const String *s, String **prefix, String **last);
+ extern String *Swig_scopename_prefix(const String *s);
+ extern String *Swig_scopename_last(const String *s);
+ extern String *Swig_scopename_first(const String *s);
+ extern String *Swig_scopename_suffix(const String *s);
+ extern int Swig_scopename_check(const String *s);
+ extern String *Swig_string_lower(String *s);
+ extern String *Swig_string_upper(String *s);
+ extern String *Swig_string_title(String *s);
+
+ extern void Swig_init(void);
+ extern void Swig_warn(const char *filename, int line, const char *msg);
+
+ extern int Swig_value_wrapper_mode(int mode);
+
+
+#define WARNING(msg) Swig_warn(__FILE__,__LINE__,msg)
+
+ typedef enum { EMF_STANDARD, EMF_MICROSOFT } ErrorMessageFormat;
+
+ extern void Swig_warning(int num, const_String_or_char_ptr filename, int line, const char *fmt, ...);
+ extern void Swig_error(const_String_or_char_ptr 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_ptr wlist, int val);
+ extern void Swig_warnall(void);
+ extern int Swig_warn_count(void);
+ extern void Swig_error_msg_format(ErrorMessageFormat format);
+
+/* --- C Wrappers --- */
+ extern String *Swig_cparm_name(Parm *p, int i);
+ extern String *Swig_wrapped_var_type(SwigType *t, int varcref);
+ extern int Swig_cargs(Wrapper *w, ParmList *l);
+ extern String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr decl);
+
+ extern String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms);
+ extern String *Swig_cconstructor_call(const_String_or_char_ptr name);
+ extern String *Swig_cppconstructor_call(const_String_or_char_ptr name, ParmList *parms);
+ extern String *Swig_unref_call(Node *n);
+ extern String *Swig_ref_call(Node *n, const String *lname);
+ extern String *Swig_cdestructor_call(Node *n);
+ extern String *Swig_cppdestructor_call(Node *n);
+ extern String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, String *self, int varcref);
+ extern String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref);
+
+ extern int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self);
+
+/* --- Transformations --- */
+
+ extern int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director);
+ extern int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparison, String *director_ctor, 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, String **call);
+ extern int Swig_MembergetToFunction(Node *n, String *classname, int flags);
+ extern int Swig_VargetToFunction(Node *n, int flags);
+ extern int Swig_VarsetToFunction(Node *n, int flags);
+
+#define CWRAP_EXTEND 0x01
+#define CWRAP_SMART_POINTER 0x02
+#define CWRAP_NATURAL_VAR 0x04
+#define CWRAP_DIRECTOR_ONE_CALL 0x08
+#define CWRAP_DIRECTOR_TWO_CALLS 0x10
+#define CWRAP_ALL_PROTECTED_ACCESS 0x20
+
+/* --- Director Helpers --- */
+ extern Node *Swig_methodclass(Node *n);
+ extern int Swig_directorclass(Node *n);
+ extern Node *Swig_directormap(Node *n, String *type);
+
+/* --- Legacy Typemap API (somewhat simplified, ha!) --- */
+
+ extern void Swig_typemap_init(void);
+ extern void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *pattern, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs);
+ extern int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcpattern, ParmList *pattern);
+ extern void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *pattern);
+ extern int Swig_typemap_apply(ParmList *srcpat, ParmList *destpat);
+ extern void Swig_typemap_clear_apply(ParmList *pattern);
+ extern void Swig_typemap_debug(void);
+
+ extern String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f);
+ extern String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f, String *actioncode);
+ extern void Swig_typemap_new_scope(void);
+ extern Hash *Swig_typemap_pop_scope(void);
+
+ extern void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f);
+
+/* --- Code fragment support --- */
+
+ extern void Swig_fragment_register(Node *fragment);
+ extern void Swig_fragment_emit(String *name);
+ extern void Swig_fragment_clear(String *section);
+
+/* hacks defined in C++ ! */
+ extern int Swig_director_mode(void);
+ extern int Swig_director_protected_mode(void);
+ extern int Swig_all_protected_mode(void);
+ extern void Wrapper_director_mode_set(int);
+ extern void Wrapper_director_protected_mode_set(int);
+ extern void Wrapper_all_protected_mode_set(int);
+ extern void Language_replace_special_variables(String *method, String *tm, Parm *parm);
+
+
+/* -- template init -- */
+ extern void SwigType_template_init(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/Source/Swig/swigfile.h b/Source/Swig/swigfile.h
new file mode 100644
index 0000000..92c7945
--- /dev/null
+++ b/Source/Swig/swigfile.h
@@ -0,0 +1,40 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * swigfile.h
+ *
+ * File handling functions in the SWIG core
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: swig.h 9603 2006-12-05 21:47:01Z beazley $ */
+
+extern List *Swig_add_directory(const_String_or_char_ptr dirname);
+extern void Swig_push_directory(const_String_or_char_ptr dirname);
+extern void Swig_pop_directory(void);
+extern String *Swig_last_file(void);
+extern List *Swig_search_path(void);
+extern FILE *Swig_include_open(const_String_or_char_ptr name);
+extern FILE *Swig_open(const_String_or_char_ptr name);
+extern String *Swig_read_file(FILE *f);
+extern String *Swig_include(const_String_or_char_ptr name);
+extern String *Swig_include_sys(const_String_or_char_ptr name);
+extern int Swig_insert_file(const_String_or_char_ptr name, File *outfile);
+extern void Swig_set_push_dir(int dopush);
+extern int Swig_get_push_dir(void);
+extern void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile);
+extern File *Swig_filebyname(const_String_or_char_ptr filename);
+extern char *Swig_file_suffix(const_String_or_char_ptr filename);
+extern char *Swig_file_basename(const_String_or_char_ptr filename);
+extern char *Swig_file_filename(const_String_or_char_ptr filename);
+extern char *Swig_file_dirname(const_String_or_char_ptr filename);
+
+/* Delimiter used in accessing files and directories */
+
+#if defined(MACSWIG)
+# define SWIG_FILE_DELIMITER ":"
+#elif defined(_WIN32)
+# define SWIG_FILE_DELIMITER "\\"
+#else
+# define SWIG_FILE_DELIMITER "/"
+#endif
diff --git a/Source/Swig/swigopt.h b/Source/Swig/swigopt.h
new file mode 100644
index 0000000..11eb5ba
--- /dev/null
+++ b/Source/Swig/swigopt.h
@@ -0,0 +1,16 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * swigopt.h
+ *
+ * Header file for the SWIG command line processing functions
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: swig.h 9622 2006-12-19 03:49:17Z beazley $ */
+
+ extern void Swig_init_args(int argc, char **argv);
+ extern void Swig_mark_arg(int n);
+ extern int Swig_check_marked(int n);
+ extern void Swig_check_options(int check_input);
+ extern void Swig_arg_error(void);
diff --git a/Source/Swig/swigparm.h b/Source/Swig/swigparm.h
new file mode 100644
index 0000000..49ae799
--- /dev/null
+++ b/Source/Swig/swigparm.h
@@ -0,0 +1,29 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * swigparm.h
+ *
+ * Functions related to the handling of function/method parameters and
+ * parameter lists.
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: swig.h 9629 2006-12-30 18:27:47Z beazley $ */
+
+/* Individual parameters */
+extern Parm *NewParm(SwigType *type, const_String_or_char_ptr name);
+extern Parm *CopyParm(Parm *p);
+
+/* Parameter lists */
+extern ParmList *CopyParmList(ParmList *);
+extern ParmList *CopyParmListMax(ParmList *, int count);
+extern int ParmList_len(ParmList *);
+extern int ParmList_numrequired(ParmList *);
+extern int ParmList_has_defaultargs(ParmList *p);
+
+/* Output functions */
+extern String *ParmList_str(ParmList *);
+extern String *ParmList_str_defaultargs(ParmList *);
+extern String *ParmList_protostr(ParmList *);
+
+
diff --git a/Source/Swig/swigscan.h b/Source/Swig/swigscan.h
new file mode 100644
index 0000000..3403098
--- /dev/null
+++ b/Source/Swig/swigscan.h
@@ -0,0 +1,108 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * swigscan.h
+ *
+ * C/C++ scanner.
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: swig.h 9633 2007-01-10 23:43:07Z beazley $ */
+
+typedef struct Scanner Scanner;
+
+extern Scanner *NewScanner(void);
+extern void DelScanner(Scanner *);
+extern void Scanner_clear(Scanner *);
+extern void Scanner_push(Scanner *, String *);
+extern void Scanner_pushtoken(Scanner *, int, const_String_or_char_ptr value);
+extern int Scanner_token(Scanner *);
+extern String *Scanner_text(Scanner *);
+extern void Scanner_skip_line(Scanner *);
+extern int Scanner_skip_balanced(Scanner *, int startchar, int endchar);
+extern void Scanner_set_location(Scanner *, String *file, int line);
+extern String *Scanner_file(Scanner *);
+extern int Scanner_line(Scanner *);
+extern int Scanner_start_line(Scanner *);
+extern void Scanner_idstart(Scanner *, const char *idchar);
+extern String *Scanner_errmsg(Scanner *);
+extern int Scanner_errline(Scanner *);
+extern int Scanner_isoperator(int tokval);
+extern void Scanner_freeze_line(Scanner *s, int val);
+
+/* Note: Tokens in range 100+ are for C/C++ operators */
+
+#define SWIG_MAXTOKENS 200
+#define SWIG_TOKEN_LPAREN 1 /* ( */
+#define SWIG_TOKEN_RPAREN 2 /* ) */
+#define SWIG_TOKEN_SEMI 3 /* ; */
+#define SWIG_TOKEN_LBRACE 4 /* { */
+#define SWIG_TOKEN_RBRACE 5 /* } */
+#define SWIG_TOKEN_LBRACKET 6 /* [ */
+#define SWIG_TOKEN_RBRACKET 7 /* ] */
+#define SWIG_TOKEN_BACKSLASH 8 /* \ */
+#define SWIG_TOKEN_ENDLINE 9 /* \n */
+#define SWIG_TOKEN_STRING 10 /* "str" */
+#define SWIG_TOKEN_POUND 11 /* # */
+#define SWIG_TOKEN_COLON 12 /* : */
+#define SWIG_TOKEN_DCOLON 13 /* :: */
+#define SWIG_TOKEN_DCOLONSTAR 14 /* ::* */
+#define SWIG_TOKEN_ID 15 /* identifer */
+#define SWIG_TOKEN_FLOAT 16 /* 3.1415F */
+#define SWIG_TOKEN_DOUBLE 17 /* 3.1415 */
+#define SWIG_TOKEN_INT 18 /* 314 */
+#define SWIG_TOKEN_UINT 19 /* 314U */
+#define SWIG_TOKEN_LONG 20 /* 314L */
+#define SWIG_TOKEN_ULONG 21 /* 314UL */
+#define SWIG_TOKEN_CHAR 22 /* 'charconst' */
+#define SWIG_TOKEN_PERIOD 23 /* . */
+#define SWIG_TOKEN_AT 24 /* @ */
+#define SWIG_TOKEN_DOLLAR 25 /* $ */
+#define SWIG_TOKEN_CODEBLOCK 26 /* %{ ... %} ... */
+#define SWIG_TOKEN_RSTRING 27 /* `charconst` */
+#define SWIG_TOKEN_LONGLONG 28 /* 314LL */
+#define SWIG_TOKEN_ULONGLONG 29 /* 314ULL */
+#define SWIG_TOKEN_QUESTION 30 /* ? */
+#define SWIG_TOKEN_COMMENT 31 /* C or C++ comment */
+#define SWIG_TOKEN_ILLEGAL 99
+#define SWIG_TOKEN_ERROR -1
+
+#define SWIG_TOKEN_COMMA 101 /* , */
+#define SWIG_TOKEN_STAR 102 /* * */
+#define SWIG_TOKEN_TIMES 102 /* * */
+#define SWIG_TOKEN_EQUAL 103 /* = */
+#define SWIG_TOKEN_EQUALTO 104 /* == */
+#define SWIG_TOKEN_NOTEQUAL 105 /* != */
+#define SWIG_TOKEN_PLUS 106 /* + */
+#define SWIG_TOKEN_MINUS 107 /* - */
+#define SWIG_TOKEN_AND 108 /* & */
+#define SWIG_TOKEN_LAND 109 /* && */
+#define SWIG_TOKEN_OR 110 /* | */
+#define SWIG_TOKEN_LOR 111 /* || */
+#define SWIG_TOKEN_XOR 112 /* ^ */
+#define SWIG_TOKEN_LESSTHAN 113 /* < */
+#define SWIG_TOKEN_GREATERTHAN 114 /* > */
+#define SWIG_TOKEN_LTEQUAL 115 /* <= */
+#define SWIG_TOKEN_GTEQUAL 116 /* >= */
+#define SWIG_TOKEN_NOT 117 /* ~ */
+#define SWIG_TOKEN_LNOT 118 /* ! */
+#define SWIG_TOKEN_SLASH 119 /* / */
+#define SWIG_TOKEN_DIVIDE 119 /* / */
+#define SWIG_TOKEN_PERCENT 120 /* % */
+#define SWIG_TOKEN_MODULO 120 /* % */
+#define SWIG_TOKEN_LSHIFT 121 /* << */
+#define SWIG_TOKEN_RSHIFT 122 /* >> */
+#define SWIG_TOKEN_PLUSPLUS 123 /* ++ */
+#define SWIG_TOKEN_MINUSMINUS 124 /* -- */
+#define SWIG_TOKEN_PLUSEQUAL 125 /* += */
+#define SWIG_TOKEN_MINUSEQUAL 126 /* -= */
+#define SWIG_TOKEN_TIMESEQUAL 127 /* *= */
+#define SWIG_TOKEN_DIVEQUAL 128 /* /= */
+#define SWIG_TOKEN_ANDEQUAL 129 /* &= */
+#define SWIG_TOKEN_OREQUAL 130 /* |= */
+#define SWIG_TOKEN_XOREQUAL 131 /* ^= */
+#define SWIG_TOKEN_LSEQUAL 132 /* <<= */
+#define SWIG_TOKEN_RSEQUAL 133 /* >>= */
+#define SWIG_TOKEN_MODEQUAL 134 /* %= */
+#define SWIG_TOKEN_ARROW 135 /* -> */
+#define SWIG_TOKEN_ARROWSTAR 136 /* ->* */
diff --git a/Source/Swig/swigtree.h b/Source/Swig/swigtree.h
new file mode 100644
index 0000000..5b43006
--- /dev/null
+++ b/Source/Swig/swigtree.h
@@ -0,0 +1,50 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * swigtree.h
+ *
+ * These functions are used to access and manipulate the SWIG parse tree.
+ * The structure of this tree is modeled directly after XML-DOM. The attribute
+ * and function names are meant to be similar.
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: swig.h 9622 2006-12-19 03:49:17Z beazley $ */
+
+/* Macros to traverse the DOM tree */
+
+#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")
+
+/* 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)
+
+/* Utility functions */
+
+extern int checkAttribute(Node *obj, const_String_or_char_ptr name, const_String_or_char_ptr value);
+extern void appendChild(Node *node, Node *child);
+extern void prependChild(Node *node, Node *child);
+extern void removeNode(Node *node);
+extern Node *copyNode(Node *node);
+
+/* Node restoration/restore functions */
+
+extern void Swig_require(const char *ns, Node *node, ...);
+extern void Swig_save(const char *ns, Node *node, ...);
+extern void Swig_restore(Node *node);
+
+/* Debugging of parse trees */
+
+extern void Swig_print_tags(File *obj, Node *root);
+extern void Swig_print_tree(Node *obj);
+extern void Swig_print_node(Node *obj);
diff --git a/Source/Swig/swigwrap.h b/Source/Swig/swigwrap.h
new file mode 100644
index 0000000..0dcf880
--- /dev/null
+++ b/Source/Swig/swigwrap.h
@@ -0,0 +1,29 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * swigwrap.h
+ *
+ * Functions related to wrapper objects.
+ * ----------------------------------------------------------------------------- */
+
+/* $Id: swig.h 9635 2007-01-12 01:44:16Z beazley $ */
+
+typedef struct Wrapper {
+ Hash *localh;
+ String *def;
+ String *locals;
+ String *code;
+} Wrapper;
+
+extern Wrapper *NewWrapper(void);
+extern void DelWrapper(Wrapper *w);
+extern void Wrapper_compact_print_mode_set(int flag);
+extern void Wrapper_pretty_print(String *str, File *f);
+extern void Wrapper_compact_print(String *str, File *f);
+extern void Wrapper_print(Wrapper *w, File *f);
+extern int Wrapper_add_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl);
+extern int Wrapper_add_localv(Wrapper *w, const_String_or_char_ptr name, ...);
+extern int Wrapper_check_local(Wrapper *w, const_String_or_char_ptr name);
+extern char *Wrapper_new_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl);
+extern char *Wrapper_new_localv(Wrapper *w, const_String_or_char_ptr name, ...);
diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
new file mode 100644
index 0000000..efafaca
--- /dev/null
+++ b/Source/Swig/symbol.c
@@ -0,0 +1,1916 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * symbol.c
+ *
+ * This file implements the SWIG symbol table. See details below.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_symbol_c[] = "$Id: symbol.c 11097 2009-01-30 10:27:37Z bhy $";
+
+#include "swig.h"
+#include "swigwarn.h"
+#include <ctype.h>
+
+/* #define SWIG_DEBUG*/
+/* -----------------------------------------------------------------------------
+ * 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.
+ *
+ * An example dump of the parse tree showing symbol table entries for the
+ * following code should clarify this:
+ *
+ * namespace OuterNamespace {
+ * namespace InnerNamespace {
+ * class Class {
+ * };
+ * struct Struct {
+ * int Var;
+ * };
+ * }
+ * }
+ *
+ * +++ namespace ----------------------------------------
+ * | sym:name - "OuterNamespace"
+ * | symtab - 0xa064bf0
+ * | sym:symtab - 0xa041690
+ * | sym:overname - "__SWIG_0"
+ *
+ * +++ namespace ----------------------------------------
+ * | sym:name - "InnerNamespace"
+ * | symtab - 0xa064cc0
+ * | sym:symtab - 0xa064bf0
+ * | sym:overname - "__SWIG_0"
+ *
+ * +++ class ----------------------------------------
+ * | sym:name - "Class"
+ * | symtab - 0xa064d80
+ * | sym:symtab - 0xa064cc0
+ * | sym:overname - "__SWIG_0"
+ * |
+ * +++ class ----------------------------------------
+ * | sym:name - "Struct"
+ * | symtab - 0xa064f00
+ * | sym:symtab - 0xa064cc0
+ * | sym:overname - "__SWIG_0"
+ *
+ * +++ cdecl ----------------------------------------
+ * | sym:name - "Var"
+ * | sym:symtab - 0xa064f00
+ * | sym:overname - "__SWIG_0"
+ * |
+ *
+ *
+ * Each class and namespace has its own scope and thus a new symbol table (sym)
+ * is created. The sym attribute is only set for the first entry in the symbol
+ * table. The sym:symtab entry points to the symbol table in which the symbol
+ * exists, so for example, Struct is in the scope OuterNamespace::InnerNamespace
+ * so sym:symtab points to this symbol table (0xa064cc0).
+ *
+ * ----------------------------------------------------------------------------- */
+
+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 */
+
+/* common attribute keys, to avoid calling find_key all the times */
+
+
+
+#if 0
+void Swig_symbol_dump_symtable() {
+ Printf(stdout, "DUMPING SYMTABLE start =======================================\n");
+ {
+ Hash *cst = Getattr(current_symtab, "csymtab");
+ Swig_print_tree(cst);
+ /*
+ Swig_print_tree(Getattr(cst, "NumSpace"));
+ */
+ }
+ Printf(stdout, "DUMPING SYMTABLE end =======================================\n");
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_init()
+ *
+ * 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);
+ Delete(current);
+ Setattr(current_symtab, "csymtab", ccurrent);
+ Delete(ccurrent);
+
+ /* Set the global scope */
+ symtabs = NewHash();
+ Setattr(symtabs, "", current_symtab);
+ Delete(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_ptr 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);
+ Delete(qname);
+}
+
+/* -----------------------------------------------------------------------------
+ * 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_ptr name) {
+ if (!symtabs)
+ return 0;
+ if (Equal("::", (const_String_or_char_ptr ) name))
+ 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 = Getattr(symtab, "parentNode");
+ if (parent) {
+ result = Swig_symbol_qualifiedscopename(parent);
+ }
+ name = Getattr(symtab, "name");
+ if (name) {
+ if (!result) {
+ result = NewStringEmpty();
+ }
+ if (Len(result)) {
+ Printv(result, "::", name, NIL);
+ } else {
+ Append(result, 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);
+ Delete(hsyms);
+ set_parentNode(h, current_symtab);
+
+ n = lastChild(current_symtab);
+ if (!n) {
+ set_firstChild(current_symtab, h);
+ } else {
+ set_nextSibling(n, h);
+ Delete(h);
+ }
+ set_lastChild(current_symtab, h);
+ current = hsyms;
+ ccurrent = NewHash();
+ Setattr(h, "csymtab", ccurrent);
+ Delete(ccurrent);
+ current_symtab = h;
+ return h;
+}
+
+/* -----------------------------------------------------------------------------
+ * 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 = Getattr(current_symtab, "parentNode");
+ 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(const_String_or_char_ptr aliasname, Symtab *s) {
+ String *qname = Swig_symbol_qualifiedscopename(current_symtab);
+ if (qname) {
+ Printf(qname, "::%s", aliasname);
+ } else {
+ qname = NewString(aliasname);
+ }
+ if (!Getattr(symtabs, qname)) {
+ Setattr(symtabs, qname, s);
+ }
+ Delete(qname);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_inherit()
+ *
+ * Inherit symbols from another scope.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_symbol_inherit(Symtab *s) {
+ int i, ilen;
+ List *inherit = Getattr(current_symtab, "inherit");
+ if (!inherit) {
+ inherit = NewList();
+ Setattr(current_symtab, "inherit", inherit);
+ Delete(inherit);
+ }
+
+ if (s == current_symtab) {
+ Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(s), Getline(s), "Recursive scope inheritance of '%s'.\n", Getattr(s, "name"));
+ return;
+ }
+ assert(s != current_symtab);
+ ilen = Len(inherit);
+ for (i = 0; i < ilen; 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(const_String_or_char_ptr 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;
+ if (SwigType_istemplate(name)) {
+ String *cname = NewString(name);
+ String *dname = Swig_symbol_template_deftype(cname, 0);
+ if (!Equal(dname, name)) {
+ Swig_symbol_cadd(dname, n);
+ }
+ Delete(dname);
+ Delete(cname);
+ }
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_cadd %s %x\n", name, n);
+#endif
+ 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 */
+ if (checkAttribute(cn, "nodeType", "template")
+ && checkAttribute(cn, "templatetype", "classforward")) {
+ /* The node is a template classforward declaration, and the
+ default template parameters here take precedence. */
+ ParmList *pc = Getattr(cn, "templateparms");
+ ParmList *pn = Getattr(n, "templateparms");
+#ifdef SWIG_DEBUG
+ Printf(stderr, "found template classforward %s\n", Getattr(cn, "name"));
+#endif
+ while (pc && pn) {
+ String *value = Getattr(pc, "value");
+ if (value) {
+#ifdef SWIG_DEBUG
+ Printf(stderr, "add default template value %s %s\n", Getattr(pc, "name"), value);
+#endif
+ Setattr(pn, "value", value);
+ }
+ pc = nextSibling(pc);
+ pn = nextSibling(pn);
+ }
+ Setattr(n, "templateparms", Getattr(cn, "templateparms"));
+ }
+ 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 && (Checkattr(cn, "nodeType", "templateparm"))) {
+ Swig_error(Getfile(n), Getline(n), "Declaration of '%s' shadows template parameter,\n", name);
+ Swig_error(Getfile(cn), Getline(cn), "previous template parameter declaration '%s'.\n", name);
+ 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 && Checkattr(td, "nodeType", "cdecl") && Checkattr(td, "storage", "typedef")) {
+ SwigType *type;
+ Node *td1;
+ type = Copy(Getattr(td, "type"));
+ SwigType_push(type, Getattr(td, "decl"));
+ td1 = Swig_symbol_clookup(type, 0);
+
+ /* Fix pathetic case #1214313:
+
+ class Foo
+ {
+ };
+
+ typedef Foo FooBar;
+
+ class CBaz
+ {
+ public:
+ typedef FooBar Foo;
+ };
+
+ ie, when Foo -> FooBar -> Foo, jump one scope up when possible.
+
+ */
+ if (td1 && Checkattr(td1, "storage", "typedef")) {
+ String *st = Getattr(td1, "type");
+ String *sn = Getattr(td, "name");
+ if (st && sn && Equal(st, sn)) {
+ Symtab *sc = Getattr(current_symtab, "parentNode");
+ if (sc)
+ td1 = Swig_symbol_clookup(type, sc);
+ }
+ }
+
+ 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(const_String_or_char_ptr 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, *overname;
+
+ /* 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 && Len(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 (GetFlag(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 */
+ String *ntype = Getattr(n, "nodeType");
+ if ((Equal(ntype, Getattr(c, "nodeType"))) && ((Equal(ntype, "namespace")))) {
+ 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 || (!Equal(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 = Getattr(n, "nodeType");
+ if (Equal(nt1, "template"))
+ nt1 = Getattr(n, "templatetype");
+ nt2 = Getattr(c, "nodeType");
+ if (Equal(nt2, "template"))
+ nt2 = Getattr(c, "templatetype");
+ if (Equal(nt1, "using"))
+ u1 = 1;
+ if (Equal(nt2, "using"))
+ u2 = 1;
+
+ if ((!Equal(nt1, nt2)) && !(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 */
+ {
+ String *nt = Getattr(n, "nodeType");
+ int n_template = Equal(nt, "template") && Checkattr(n, "templatetype", "cdecl");
+ int n_plain_cdecl = Equal(nt, "cdecl");
+ cn = c;
+ pn = 0;
+ while (cn) {
+ decl = Getattr(cn, "decl");
+ if (!(u1 || u2)) {
+ if (Cmp(ndecl, decl) == 0) {
+ /* Declarator conflict */
+ /* Now check we don't have a non-templated function overloaded by a templated function with same params,
+ * eg void foo(); template<typename> void foo(); */
+ String *cnt = Getattr(cn, "nodeType");
+ int cn_template = Equal(cnt, "template") && Checkattr(cn, "templatetype", "cdecl");
+ int cn_plain_cdecl = Equal(cnt, "cdecl");
+ if (!((n_template && cn_plain_cdecl) || (cn_template && n_plain_cdecl))) {
+ /* found a 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);
+ /* Printf(stdout,"%s %x\n", Getattr(n,"sym:overname"), current_symtab); */
+ assert(!Getattr(n, "sym:overname"));
+ overname = NewStringf("__SWIG_%d", pn);
+ Setattr(n, "sym:overname", overname);
+ /*Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */
+ Setattr(cl, "sym:nextSibling", n);
+ Setattr(n, "sym:previousSibling", cl);
+ Setattr(cl, "sym:overloaded", c);
+ Setattr(n, "sym:overloaded", c);
+ Delete(overname);
+ return n;
+ }
+
+ /* No conflict. Just add it */
+ Setattr(n, "sym:symtab", current_symtab);
+ Setattr(n, "sym:name", symname);
+ /* Printf(stdout,"%s\n", Getattr(n,"sym:overname")); */
+ overname = NewStringf("__SWIG_%d", pn);
+ Setattr(n, "sym:overname", overname);
+ Delete(overname);
+ /* Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */
+ Setattr(current, symname, n);
+ return n;
+}
+
+/* -----------------------------------------------------------------------------
+ * symbol_lookup()
+ *
+ * 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.
+ *
+ * The check function is an optional callback that can be used to verify a particular
+ * symbol match. This is only used in some of the more exotic parts of SWIG. For instance,
+ * verifying that a class hierarchy implements all pure virtual methods.
+ * ----------------------------------------------------------------------------- */
+
+static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (Node *n)) {
+ Node *n;
+ List *inherit;
+ Hash *sym = Getattr(symtab, "csymtab");
+ if (Getmark(symtab))
+ return 0;
+ Setmark(symtab, 1);
+
+
+ n = Getattr(sym, name);
+
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_look %s %x %x %s\n", name, n, symtab, Getattr(symtab, "name"));
+#endif
+
+ if (n) {
+ /* if a check-function is defined. Call it to determine a match */
+ if (check) {
+ int c = check(n);
+ if (c == 1) {
+ Setmark(symtab, 0);
+ return n;
+ }
+ if (c < 0) {
+ /* Terminate the search right away */
+ Setmark(symtab, 0);
+ return 0;
+ }
+ } else {
+ Setmark(symtab, 0);
+ return n;
+ }
+ }
+
+ if (!n && SwigType_istemplate(name)) {
+ String *dname = 0;
+ Setmark(symtab, 0);
+ dname = Swig_symbol_template_deftype(name, symtab);
+ if (!Equal(dname, name)) {
+ n = _symbol_lookup(dname, symtab, check);
+ }
+ Delete(dname);
+ if (n)
+ 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), check);
+ if (n) {
+ Setmark(symtab, 0);
+ return n;
+ }
+ }
+ }
+
+ Setmark(symtab, 0);
+ return 0;
+}
+
+static Node *symbol_lookup(const_String_or_char_ptr name, Symtab *symtab, int (*check) (Node *n)) {
+ Node *n = 0;
+ if (DohCheck(name)) {
+ n = _symbol_lookup(name, symtab, check);
+ } else {
+ String *sname = NewString(name);
+ n = _symbol_lookup(sname, symtab, check);
+ Delete(sname);
+ }
+ return n;
+}
+
+
+
+/* -----------------------------------------------------------------------------
+ * symbol_lookup_qualified()
+ * ----------------------------------------------------------------------------- */
+
+static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symtab, const String *prefix, int local, int (*checkfunc) (Node *n)) {
+ /* This is a little funky, we search by fully qualified names */
+
+ if (!symtab)
+ return 0;
+ if (!prefix) {
+ Node *n;
+ String *bname;
+ String *prefix;
+ Swig_scopename_split(name, &prefix, &bname);
+ n = symbol_lookup_qualified(bname, symtab, prefix, local, checkfunc);
+ Delete(bname);
+ Delete(prefix);
+ return n;
+ } else {
+ Symtab *st;
+ Node *n = 0;
+ /* Make qualified name of current scope */
+ String *qalloc = 0;
+ String *qname = Swig_symbol_qualifiedscopename(symtab);
+ const String *cqname;
+ if (qname) {
+ if (Len(qname)) {
+ if (prefix && Len(prefix)) {
+ Printv(qname, "::", prefix, NIL);
+ }
+ } else {
+ Append(qname, prefix);
+ }
+ qalloc = qname;
+ cqname = qname;
+ } else {
+ cqname = prefix;
+ }
+ st = Getattr(symtabs, cqname);
+ /* Found a scope match */
+ if (st) {
+ if (!name) {
+ if (qalloc)
+ Delete(qalloc);
+ return st;
+ }
+ n = symbol_lookup(name, st, checkfunc);
+ }
+ if (qalloc)
+ Delete(qalloc);
+
+ if (!n) {
+ if (!local) {
+ Node *pn = Getattr(symtab, "parentNode");
+ if (pn)
+ n = symbol_lookup_qualified(name, pn, prefix, local, checkfunc);
+ } 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(const_String_or_char_ptr name, Symtab *n) {
+ Hash *hsym = 0;
+ Node *s = 0;
+
+ if (!n) {
+ hsym = current_symtab;
+ } else {
+ if (!Checkattr(n, "nodeType", "symboltable")) {
+ n = Getattr(n, "sym:symtab");
+ }
+ assert(n);
+ if (n) {
+ hsym = n;
+ }
+ }
+
+ if (Swig_scopename_check(name)) {
+ char *cname = Char(name);
+ if (strncmp(cname, "::", 2) == 0) {
+ String *nname = NewString(cname + 2);
+ if (Swig_scopename_check(nname)) {
+ s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0);
+ }
+ Delete(nname);
+ } else {
+ String *prefix = Swig_scopename_prefix(name);
+ if (prefix) {
+ s = symbol_lookup_qualified(name, hsym, 0, 0, 0);
+ Delete(prefix);
+ if (!s) {
+ return 0;
+ }
+ }
+ }
+ }
+ if (!s) {
+ while (hsym) {
+ s = symbol_lookup(name, hsym, 0);
+ if (s)
+ break;
+ hsym = Getattr(hsym, "parentNode");
+ if (!hsym)
+ break;
+ }
+ }
+
+ if (!s) {
+ return 0;
+ }
+ /* Check if s is a 'using' node */
+ while (s && Checkattr(s, "nodeType", "using")) {
+ String *uname = Getattr(s, "uname");
+ Symtab *un = Getattr(s, "sym:symtab");
+ Node *ss = (!Equal(name, uname) || (un != n)) ? Swig_symbol_clookup(uname, un) : 0; /* avoid infinity loop */
+ 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_clookup_check()
+ *
+ * This function is identical to Swig_symbol_clookup() except that it
+ * accepts a callback function that is invoked to determine a symbol match.
+ * The purpose of this function is to support complicated algorithms that need
+ * to examine multiple definitions of the same symbol that might appear in an
+ * inheritance hierarchy.
+ * ----------------------------------------------------------------------------- */
+
+Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *n)) {
+ Hash *hsym = 0;
+ Node *s = 0;
+
+ if (!n) {
+ hsym = current_symtab;
+ } else {
+ if (!Checkattr(n, "nodeType", "symboltable")) {
+ n = Getattr(n, "sym:symtab");
+ }
+ assert(n);
+ if (n) {
+ hsym = n;
+ }
+ }
+
+ if (Swig_scopename_check(name)) {
+ char *cname = Char(name);
+ if (strncmp(cname, "::", 2) == 0) {
+ String *nname = NewString(cname + 2);
+ if (Swig_scopename_check(nname)) {
+ s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc);
+ }
+ Delete(nname);
+ } else {
+ String *prefix = Swig_scopename_prefix(name);
+ if (prefix) {
+ s = symbol_lookup_qualified(name, hsym, 0, 0, checkfunc);
+ Delete(prefix);
+ if (!s) {
+ return 0;
+ }
+ }
+ }
+ }
+ if (!s) {
+ while (hsym) {
+ s = symbol_lookup(name, hsym, checkfunc);
+ if (s)
+ break;
+ hsym = Getattr(hsym, "parentNode");
+ if (!hsym)
+ break;
+ }
+ }
+ if (!s) {
+ return 0;
+ }
+ /* Check if s is a 'using' node */
+ while (s && Checkattr(s, "nodeType", "using")) {
+ Node *ss;
+ ss = Swig_symbol_clookup(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
+ if (!ss && !checkfunc) {
+ Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s, "uname"));
+ }
+ s = ss;
+ }
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_clookup_local()
+ * ----------------------------------------------------------------------------- */
+
+Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) {
+ Hash *h, *hsym;
+ Node *s = 0;
+
+ if (!n) {
+ hsym = current_symtab;
+ h = ccurrent;
+ } else {
+ if (!Checkattr(n, "nodeType", "symboltable")) {
+ n = Getattr(n, "sym:symtab");
+ }
+ assert(n);
+ hsym = n;
+ h = Getattr(n, "csymtab");
+ }
+
+ if (Swig_scopename_check(name)) {
+ char *cname = Char(name);
+ if (strncmp(cname, "::", 2) == 0) {
+ String *nname = NewString(cname + 2);
+ if (Swig_scopename_check(nname)) {
+ s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0);
+ }
+ Delete(nname);
+ } else {
+ s = symbol_lookup_qualified(name, hsym, 0, 0, 0);
+ }
+ }
+ if (!s) {
+ s = symbol_lookup(name, hsym, 0);
+ }
+ if (!s)
+ return 0;
+ /* Check if s is a 'using' node */
+ while (s && Checkattr(s, "nodeType", "using")) {
+ 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_clookup_local_check()
+ * ----------------------------------------------------------------------------- */
+
+Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *)) {
+ Hash *h, *hsym;
+ Node *s = 0;
+
+ if (!n) {
+ hsym = current_symtab;
+ h = ccurrent;
+ } else {
+ if (!Checkattr(n, "nodeType", "symboltable")) {
+ n = Getattr(n, "sym:symtab");
+ }
+ assert(n);
+ hsym = n;
+ h = Getattr(n, "csymtab");
+ }
+
+ if (Swig_scopename_check(name)) {
+ char *cname = Char(name);
+ if (strncmp(cname, "::", 2) == 0) {
+ String *nname = NewString(cname + 2);
+ if (Swig_scopename_check(nname)) {
+ s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc);
+ }
+ Delete(nname);
+ } else {
+ s = symbol_lookup_qualified(name, hsym, 0, 0, checkfunc);
+ }
+ }
+ if (!s) {
+ s = symbol_lookup(name, hsym, checkfunc);
+ }
+ if (!s)
+ return 0;
+ /* Check if s is a 'using' node */
+ while (s && Checkattr(s, "nodeType", "using")) {
+ Node *ss = Swig_symbol_clookup_local_check(Getattr(s, "uname"), Getattr(s, "sym:symtab"), checkfunc);
+ if (!ss && !checkfunc) {
+ 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(const_String_or_char_ptr name, Symtab *symtab) {
+ char *cname = Char(name);
+ if (strncmp(cname, "::", 2) == 0)
+ return symbol_lookup_qualified(0, global_scope, name, 0, 0);
+ return symbol_lookup_qualified(0, symtab, name, 0, 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_remove()
+ *
+ * Remove a symbol. If the symbol is an overloaded function and the symbol removed
+ * is not the last in the list of overloaded functions, then the overloaded
+ * names (sym:overname attribute) are changed to start from zero, eg __SWIG_0.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_symbol_remove(Node *n) {
+ Symtab *symtab;
+ String *symname;
+ String *overname;
+ Node *symprev;
+ Node *symnext;
+ Node *fixovername = 0;
+ 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);
+ fixovername = symprev; /* fix as symbol to remove is somewhere in the middle of the linked list */
+ } else {
+ Delattr(symprev, "sym:nextSibling");
+ }
+ } else {
+ /* If no previous symbol, see if there is a next symbol */
+ if (symnext) {
+ Setattr(symtab, symname, symnext);
+ fixovername = symnext; /* fix as symbol to remove is at head of linked list */
+ } else {
+ Delattr(symtab, symname);
+ }
+ }
+ if (symnext) {
+ if (symprev) {
+ Setattr(symnext, "sym:previousSibling", symprev);
+ } else {
+ Delattr(symnext, "sym:previousSibling");
+ }
+ }
+ Delattr(n, "sym:symtab");
+ Delattr(n, "sym:previousSibling");
+ Delattr(n, "sym:nextSibling");
+ Delattr(n, "csym:nextSibling");
+ Delattr(n, "sym:overname");
+ Delattr(n, "csym:previousSibling");
+ Delattr(n, "sym:overloaded");
+ n = 0;
+
+ if (fixovername) {
+ Node *nn = fixovername;
+ Node *head = fixovername;
+ int pn = 0;
+
+ /* find head of linked list */
+ while (nn) {
+ head = nn;
+ nn = Getattr(nn, "sym:previousSibling");
+ }
+
+ /* adjust all the sym:overname strings to start from 0 and increment by one */
+ nn = head;
+ while (nn) {
+ assert(Getattr(nn, "sym:overname"));
+ Delattr(nn, "sym:overname");
+ overname = NewStringf("__SWIG_%d", pn);
+ Setattr(nn, "sym:overname", overname);
+ Delete(overname);
+ pn++;
+ nn = Getattr(nn, "sym:nextSibling");
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_qualified()
+ *
+ * Return the qualified name of a symbol
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_symbol_qualified(Node *n) {
+ Hash *symtab;
+ if (Checkattr(n, "nodeType", "symboltable")) {
+ symtab = n;
+ } else {
+ symtab = Getattr(n, "sym:symtab");
+ }
+ if (!symtab)
+ return NewStringEmpty();
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_qscope %s %x %s\n", Getattr(n, "name"), symtab, Getattr(symtab, "name"));
+#endif
+ 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
+ * ----------------------------------------------------------------------------- */
+
+/* This cache produces problems with OSS, don't active it */
+/* #define SWIG_TEMPLATE_QUALIFY_CACHE */
+static SwigType *Swig_symbol_template_qualify(const SwigType *e, Symtab *st) {
+ String *tprefix, *tsuffix;
+ SwigType *qprefix;
+ List *targs;
+ Node *tempn;
+ Symtab *tscope;
+ Iterator ti;
+#ifdef SWIG_TEMPLATE_QUALIFY_CACHE
+ static Hash *qualify_cache = 0;
+ String *scopetype = st ? NewStringf("%s::%s", Getattr(st, "name"), e)
+ : NewStringf("%s::%s", Swig_symbol_getscopename(), e);
+ if (!qualify_cache) {
+ qualify_cache = NewHash();
+ }
+ if (scopetype) {
+ String *cres = Getattr(qualify_cache, scopetype);
+ if (cres) {
+ Delete(scopetype);
+ return Copy(cres);
+ }
+ }
+#endif
+
+ tprefix = SwigType_templateprefix(e);
+ tsuffix = SwigType_templatesuffix(e);
+ qprefix = Swig_symbol_type_qualify(tprefix, st);
+ targs = SwigType_parmlist(e);
+ tempn = Swig_symbol_clookup_local(tprefix, st);
+ tscope = tempn ? Getattr(tempn, "sym:symtab") : 0;
+ Append(qprefix, "<(");
+ for (ti = First(targs); ti.item;) {
+ String *vparm;
+ String *qparm = Swig_symbol_type_qualify(ti.item, st);
+ if (tscope && (tscope != st)) {
+ String *ty = Swig_symbol_type_qualify(qparm, tscope);
+ Delete(qparm);
+ qparm = ty;
+ }
+
+ vparm = Swig_symbol_template_param_eval(qparm, st);
+ Append(qprefix, vparm);
+ ti = Next(ti);
+ if (ti.item) {
+ Putc(',', qprefix);
+ }
+ Delete(qparm);
+ Delete(vparm);
+ }
+ Append(qprefix, ")>");
+ Append(qprefix, tsuffix);
+ Delete(tprefix);
+ Delete(tsuffix);
+ Delete(targs);
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_temp_qual %s %s\n", e, qprefix);
+#endif
+#ifdef SWIG_TEMPLATE_QUALIFY_CACHE
+ Setattr(qualify_cache, scopetype, qprefix);
+ Delete(scopetype);
+#endif
+
+ return qprefix;
+}
+
+
+static int no_constructor(Node *n) {
+ return !Checkattr(n, "nodeType", "constructor");
+}
+
+SwigType *Swig_symbol_type_qualify(const SwigType *t, Symtab *st) {
+ List *elements;
+ String *result = NewStringEmpty();
+ int i, len;
+ char *c = Char(t);
+ if (strncmp(c, "::", 2) == 0) {
+ Append(result, t);
+ return result;
+ }
+
+ 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_check(e, st, no_constructor);
+ if (n) {
+ String *name = Getattr(n, "name");
+ Clear(e);
+ Append(e, name);
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_qual_ei %d %s %s %x\n", i, name, e, st);
+#endif
+ if (!Swig_scopename_check(name)) {
+ String *qname = Swig_symbol_qualified(n);
+ if (qname && Len(qname)) {
+ Insert(e, 0, "::");
+ Insert(e, 0, qname);
+ }
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_qual_sc %d %s %s %x\n", i, qname, e, st);
+#endif
+ Delete(qname);
+ }
+ } else if (SwigType_istemplate(e)) {
+ SwigType *ty = Swig_symbol_template_qualify(e, st);
+ Clear(e);
+ Append(e, ty);
+ Delete(ty);
+ }
+ if (strncmp(Char(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(");
+ Iterator pi = First(parms);
+ while (pi.item) {
+ String *pf = Swig_symbol_type_qualify(pi.item, st);
+ Append(s, pf);
+ pi = Next(pi);
+ if (pi.item) {
+ Append(s, ",");
+ }
+ Delete(pf);
+ }
+ Append(s, ").");
+ Append(result, s);
+ Delete(parms);
+ Delete(s);
+ } else {
+ Append(result, e);
+ }
+ }
+ Delete(elements);
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_qualify %s %s %x %s\n", t, result, st, st ? Getattr(st, "name") : 0);
+#endif
+
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_template_reduce()
+ * Resolves template parameter types
+ * For example:
+ * typedef int Int;
+ * typedef Int Integer;
+ * with input:
+ * Foo<(Int,Integer)>
+ * returns:
+ * Foo<(int,int)>
+ * ----------------------------------------------------------------------------- */
+
+static
+SwigType *Swig_symbol_template_reduce(SwigType *qt, Symtab *ntab) {
+ Parm *p;
+ String *templateargs = SwigType_templateargs(qt);
+ List *parms = SwigType_parmlist(templateargs);
+ Iterator pi = First(parms);
+ String *tprefix = SwigType_templateprefix(qt);
+ String *tsuffix = SwigType_templatesuffix(qt);
+ String *qprefix = SwigType_typedef_qualified(tprefix);
+ Append(qprefix, "<(");
+ while ((p = pi.item)) {
+ String *np;
+ String *tp = Swig_symbol_typedef_reduce(p, ntab);
+ String *qp = Swig_symbol_type_qualify(tp, ntab);
+ Node *n = Swig_symbol_clookup(qp, ntab);
+ if (n) {
+ String *qual = Swig_symbol_qualified(n);
+ np = Copy(Getattr(n, "name"));
+ Delete(tp);
+ tp = np;
+ if (qual && Len(qual)) {
+ Insert(np, 0, "::");
+ Insert(np, 0, qual);
+ }
+ Delete(qual);
+ } else {
+ np = qp;
+ }
+ Append(qprefix, np);
+ pi = Next(pi);
+ if (pi.item) {
+ Append(qprefix, ",");
+ }
+ Delete(qp);
+ Delete(tp);
+ }
+ Append(qprefix, ")>");
+ Append(qprefix, tsuffix);
+ Delete(parms);
+ Delete(tprefix);
+ Delete(tsuffix);
+ Delete(templateargs);
+ return qprefix;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * 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;
+ String *nt;
+
+ base = SwigType_base(ty);
+ prefix = SwigType_prefix(ty);
+
+ n = Swig_symbol_clookup(base, tab);
+ if (!n) {
+ if (SwigType_istemplate(ty)) {
+ SwigType *qt = Swig_symbol_template_reduce(base, tab);
+ Append(prefix, qt);
+ Delete(qt);
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_reduce (a) %s %s\n", ty, prefix);
+#endif
+ Delete(base);
+ return prefix;
+ } else {
+ Delete(prefix);
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_reduce (b) %s %s\n", ty, ty);
+#endif
+ return Copy(ty);
+ }
+ }
+ nt = Getattr(n, "nodeType");
+ if (Equal(nt, "using")) {
+ String *uname = Getattr(n, "uname");
+ if (uname) {
+ n = Swig_symbol_clookup(base, Getattr(n, "sym:symtab"));
+ if (!n) {
+ Delete(base);
+ Delete(prefix);
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_reduce (c) %s %s\n", ty, ty);
+#endif
+ return Copy(ty);
+ }
+ }
+ }
+ if (Equal(nt, "cdecl")) {
+ String *storage = Getattr(n, "storage");
+ if (storage && (Equal(storage, "typedef"))) {
+ SwigType *decl;
+ SwigType *rt;
+ SwigType *qt;
+ Symtab *ntab;
+ SwigType *nt = Copy(Getattr(n, "type"));
+
+ /* Fix for case 'typedef struct Hello hello;' */
+ {
+ const char *dclass[3] = { "struct ", "union ", "class " };
+ int i;
+ char *c = Char(nt);
+ for (i = 0; i < 3; i++) {
+ if (strstr(c, dclass[i]) == c) {
+ Replace(nt, dclass[i], "", DOH_REPLACE_FIRST);
+ }
+ }
+ }
+ decl = Getattr(n, "decl");
+ if (decl) {
+ SwigType_push(nt, decl);
+ }
+ SwigType_push(nt, prefix);
+ Delete(base);
+ Delete(prefix);
+ ntab = Getattr(n, "sym:symtab");
+ rt = Swig_symbol_typedef_reduce(nt, ntab);
+ qt = Swig_symbol_type_qualify(rt, ntab);
+ if (SwigType_istemplate(qt)) {
+ SwigType *qtr = Swig_symbol_template_reduce(qt, ntab);
+ Delete(qt);
+ qt = qtr;
+ }
+ Delete(nt);
+ Delete(rt);
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_reduce (d) %s %s\n", qt, ty);
+#endif
+ return qt;
+ }
+ }
+ Delete(base);
+ Delete(prefix);
+#ifdef SWIG_DEBUG
+ Printf(stderr, "symbol_reduce (e) %s %s\n", ty, ty);
+#endif
+ 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) {
+ int have_id = 0;
+ String *id = NewStringEmpty();
+ String *r = NewStringEmpty();
+ char *c = Char(s);
+ while (*c) {
+ if (isalpha((int) *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;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_template_defargs()
+ *
+ * Apply default arg from generic template default args
+ * Returns a parameter list which contains missing default arguments (if any)
+ * Note side effects: parms will also contain the extra parameters in its list
+ * (but only if non-zero).
+ * ----------------------------------------------------------------------------- */
+
+
+ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl) {
+ ParmList *expandedparms = parms;
+ if (Len(parms) < Len(targs)) {
+ Parm *lp = parms;
+ Parm *p = lp;
+ Parm *tp = targs;
+ while (p && tp) {
+ p = nextSibling(p);
+ tp = nextSibling(tp);
+ if (p)
+ lp = p;
+ }
+ while (tp) {
+ String *value = Getattr(tp, "value");
+ if (value) {
+ Parm *cp;
+ Parm *ta = targs;
+ Parm *p = parms;
+ SwigType *nt = Swig_symbol_string_qualify(value, tsdecl);
+ SwigType *ntq = 0;
+#ifdef SWIG_DEBUG
+ Printf(stderr, "value %s %s %s\n", value, nt, tsdecl ? Getattr(tsdecl, "name") : tsdecl);
+#endif
+ while (p && ta) {
+ String *name = Getattr(ta, "name");
+ String *pvalue = Getattr(p, "value");
+ String *value = pvalue ? pvalue : Getattr(p, "type");
+ String *ttq = Swig_symbol_type_qualify(value, tscope);
+ /* value = SwigType_typedef_resolve_all(value); */
+ Replaceid(nt, name, ttq);
+ p = nextSibling(p);
+ ta = nextSibling(ta);
+ Delete(ttq);
+ }
+ ntq = Swig_symbol_type_qualify(nt, tsdecl);
+ if (SwigType_istemplate(ntq)) {
+ String *ty = Swig_symbol_template_deftype(ntq, tscope);
+ Delete(ntq);
+ ntq = ty;
+ }
+ /* Printf(stderr,"value %s %s %s\n",value,ntr,ntq); */
+ cp = NewParm(ntq, 0);
+ if (lp)
+ set_nextSibling(lp, cp);
+ else
+ expandedparms = CopyParm(cp);
+ lp = cp;
+ tp = nextSibling(tp);
+ Delete(cp);
+ Delete(nt);
+ Delete(ntq);
+ } else {
+ tp = 0;
+ }
+ }
+ }
+ return expandedparms;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_template_deftype()
+ *
+ * Apply default args to generic template type
+ * ----------------------------------------------------------------------------- */
+
+#define SWIG_TEMPLATE_DEFTYPE_CACHE
+SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) {
+ String *result = NewStringEmpty();
+ List *elements = SwigType_split(type);
+ int len = Len(elements);
+ int i;
+#ifdef SWIG_TEMPLATE_DEFTYPE_CACHE
+ static Hash *deftype_cache = 0;
+ String *scopetype = tscope ? NewStringf("%s::%s", Getattr(tscope, "name"), type)
+ : NewStringf("%s::%s", Swig_symbol_getscopename(), type);
+ if (!deftype_cache) {
+ deftype_cache = NewHash();
+ }
+ if (scopetype) {
+ String *cres = Getattr(deftype_cache, scopetype);
+ if (cres) {
+ Append(result, cres);
+ Delete(scopetype);
+ return result;
+ }
+ }
+#endif
+
+#ifdef SWIG_DEBUG
+ Printf(stderr, "finding deftype %s\n", type);
+#endif
+
+ for (i = 0; i < len; i++) {
+ String *e = Getitem(elements, i);
+ if (SwigType_isfunction(e)) {
+ String *s = NewString("f(");
+ List *parms = SwigType_parmlist(e);
+ Iterator pi = First(parms);
+ while (pi.item) {
+ String *pf = SwigType_istemplate(e) ? Swig_symbol_template_deftype(pi.item, tscope)
+ : Swig_symbol_type_qualify(pi.item, tscope);
+ Append(s, pf);
+ pi = Next(pi);
+ if (pi.item) {
+ Append(s, ",");
+ }
+ Delete(pf);
+ }
+ Append(s, ").");
+ Append(result, s);
+ Delete(s);
+ Delete(parms);
+ } else if (SwigType_istemplate(e)) {
+ String *prefix = SwigType_prefix(e);
+ String *base = SwigType_base(e);
+ String *tprefix = SwigType_templateprefix(base);
+ String *targs = SwigType_templateargs(base);
+ String *tsuffix = SwigType_templatesuffix(base);
+ ParmList *tparms = SwigType_function_parms(targs);
+ Node *tempn = Swig_symbol_clookup_local(tprefix, tscope);
+ if (!tempn && tsuffix && Len(tsuffix)) {
+ tempn = Swig_symbol_clookup(tprefix, 0);
+ }
+#ifdef SWIG_DEBUG
+ Printf(stderr, "deftype type %s %s %d\n", e, tprefix, (long) tempn);
+#endif
+ if (tempn) {
+ ParmList *tnargs = Getattr(tempn, "templateparms");
+ ParmList *expandedparms;
+ Parm *p;
+ Symtab *tsdecl = Getattr(tempn, "sym:symtab");
+
+#ifdef SWIG_DEBUG
+ Printf(stderr, "deftype type %s %s %s\n", tprefix, targs, tsuffix);
+#endif
+ Append(tprefix, "<(");
+ expandedparms = Swig_symbol_template_defargs(tparms, tnargs, tscope, tsdecl);
+ p = expandedparms;
+ tscope = tsdecl;
+ while (p) {
+ SwigType *ptype = Getattr(p, "type");
+ SwigType *ttr = ptype ? ptype : Getattr(p, "value");
+ SwigType *ttf = Swig_symbol_type_qualify(ttr, tscope);
+ SwigType *ttq = Swig_symbol_template_param_eval(ttf, tscope);
+#ifdef SWIG_DEBUG
+ Printf(stderr, "arg type %s\n", ttq);
+#endif
+ if (SwigType_istemplate(ttq)) {
+ SwigType *ttd = Swig_symbol_template_deftype(ttq, tscope);
+ Delete(ttq);
+ ttq = ttd;
+#ifdef SWIG_DEBUG
+ Printf(stderr, "arg deftype %s\n", ttq);
+#endif
+ }
+ Append(tprefix, ttq);
+ p = nextSibling(p);
+ if (p)
+ Putc(',', tprefix);
+ Delete(ttf);
+ Delete(ttq);
+ }
+ Append(tprefix, ")>");
+ Append(tprefix, tsuffix);
+ Append(prefix, tprefix);
+#ifdef SWIG_DEBUG
+ Printf(stderr, "deftype %s %s \n", type, tprefix);
+#endif
+ Append(result, prefix);
+ } else {
+ Append(result, e);
+ }
+ Delete(prefix);
+ Delete(base);
+ Delete(tprefix);
+ Delete(tsuffix);
+ Delete(targs);
+ Delete(tparms);
+ } else {
+ Append(result, e);
+ }
+ }
+ Delete(elements);
+#ifdef SWIG_TEMPLATE_DEFTYPE_CACHE
+ Setattr(deftype_cache, scopetype, result);
+ Delete(scopetype);
+#endif
+
+ return result;
+}
+
+SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab) {
+ String *value = Copy(p);
+ Node *lastnode = 0;
+ while (1) {
+ Node *n = Swig_symbol_clookup(value, symtab);
+ if (n == lastnode)
+ break;
+ lastnode = n;
+ if (n) {
+ String *nt = Getattr(n, "nodeType");
+ if (Equal(nt, "enumitem")) {
+ /* An enum item. Generate a fully qualified name */
+ String *qn = Swig_symbol_qualified(n);
+ if (qn && Len(qn)) {
+ Append(qn, "::");
+ Append(qn, Getattr(n, "name"));
+ Delete(value);
+ value = qn;
+ continue;
+ } else {
+ Delete(qn);
+ break;
+ }
+ } else if ((Equal(nt, "cdecl"))) {
+ String *nv = Getattr(n, "value");
+ if (nv) {
+ Delete(value);
+ value = Copy(nv);
+ continue;
+ }
+ }
+ }
+ break;
+ }
+ return value;
+}
diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c
new file mode 100644
index 0000000..877b624
--- /dev/null
+++ b/Source/Swig/tree.c
@@ -0,0 +1,376 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * tree.c
+ *
+ * This file provides some general purpose functions for manipulating
+ * parse trees.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_tree_c[] = "$Id: tree.c 11080 2009-01-24 13:15:51Z bhy $";
+
+#include "swig.h"
+#include <stdarg.h>
+#include <assert.h>
+
+/* -----------------------------------------------------------------------------
+ * Swig_print_tags()
+ *
+ * Dump the tag structure of a parse tree to standard output
+ * ----------------------------------------------------------------------------- */
+
+void Swig_print_tags(DOH *obj, DOH *root) {
+ DOH *croot, *newroot;
+ DOH *cobj;
+
+ if (!root)
+ croot = NewStringEmpty();
+ else
+ croot = root;
+
+ while (obj) {
+ Printf(stdout, "%s . %s (%s:%d)\n", croot, nodeType(obj), Getfile(obj), Getline(obj));
+ cobj = firstChild(obj);
+ if (cobj) {
+ newroot = NewStringf("%s . %s", croot, nodeType(obj));
+ Swig_print_tags(cobj, newroot);
+ Delete(newroot);
+ }
+ obj = nextSibling(obj);
+ }
+ if (!root)
+ Delete(croot);
+}
+
+static int indent_level = 0;
+
+static void print_indent(int l) {
+ int i;
+ for (i = 0; i < indent_level; i++) {
+ fputc(' ', stdout);
+ }
+ if (l) {
+ fputc('|', stdout);
+ fputc(' ', stdout);
+ }
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_print_node(Node *n)
+ * ----------------------------------------------------------------------------- */
+
+void Swig_print_node(Node *obj) {
+ Iterator ki;
+ Node *cobj;
+
+ print_indent(0);
+ Printf(stdout, "+++ %s ----------------------------------------\n", nodeType(obj));
+ ki = First(obj);
+ while (ki.key) {
+ String *k = ki.key;
+ 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) > 80) {
+ trunc = "...";
+ }
+ Printf(stdout, "%-12s - \"%(escape)-0.80s%s\"\n", k, o, trunc);
+ Delete(o);
+ } else {
+ Printf(stdout, "%-12s - 0x%x\n", k, Getattr(obj, k));
+ }
+ }
+ ki = Next(ki);
+ }
+ 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_print_tree()
+ *
+ * Dump the tree structure of a parse tree to standard output
+ * ----------------------------------------------------------------------------- */
+
+void Swig_print_tree(DOH *obj) {
+ while (obj) {
+ Swig_print_node(obj);
+ obj = nextSibling(obj);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * appendChild()
+ *
+ * Appends a new child to a node
+ * ----------------------------------------------------------------------------- */
+
+void appendChild(Node *node, Node *chd) {
+ Node *lc;
+
+ if (!chd)
+ return;
+
+ lc = lastChild(node);
+ if (!lc) {
+ set_firstChild(node, chd);
+ } else {
+ set_nextSibling(lc, chd);
+ set_previousSibling(chd, lc);
+ }
+ while (chd) {
+ lc = chd;
+ set_parentNode(chd, node);
+ chd = nextSibling(chd);
+ }
+ set_lastChild(node, lc);
+}
+
+/* -----------------------------------------------------------------------------
+ * prependChild()
+ *
+ * Prepends a new child to a node
+ * ----------------------------------------------------------------------------- */
+
+void prependChild(Node *node, Node *chd) {
+ Node *fc;
+
+ if (!chd)
+ return;
+
+ fc = firstChild(node);
+ if (fc) {
+ set_nextSibling(chd, fc);
+ set_previousSibling(fc, chd);
+ }
+ set_firstChild(node, chd);
+ while (chd) {
+ set_parentNode(chd, node);
+ chd = nextSibling(chd);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * removeNode()
+ *
+ * Removes a node from the parse tree. Detaches it from its parent's child list.
+ * ----------------------------------------------------------------------------- */
+
+void removeNode(Node *n) {
+ Node *parent;
+ Node *prev;
+ Node *next;
+
+ parent = parentNode(n);
+ if (!parent) return;
+
+ 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);
+ }
+ }
+
+ /* Delete attributes */
+ Delattr(n,"parentNode");
+ Delattr(n,"nextSibling");
+ Delattr(n,"prevSibling");
+}
+
+/* -----------------------------------------------------------------------------
+ * copyNode()
+ *
+ * Copies a node, but only copies simple attributes (no lists, hashes).
+ * ----------------------------------------------------------------------------- */
+
+Node *copyNode(Node *n) {
+ Iterator ki;
+ Node *c = NewHash();
+ for (ki = First(n); ki.key; ki = Next(ki)) {
+ if (DohIsString(ki.item)) {
+ Setattr(c, ki.key, Copy(ki.item));
+ }
+ }
+ Setfile(c, Getfile(n));
+ Setline(c, Getline(n));
+ return c;
+}
+
+/* -----------------------------------------------------------------------------
+ * checkAttribute()
+ * ----------------------------------------------------------------------------- */
+
+int checkAttribute(Node *n, const_String_or_char_ptr name, const_String_or_char_ptr value) {
+ String *v = Getattr(n, name);
+ return v ? Equal(v, value) : 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_require()
+ * ns - namespace for the view name for saving any attributes under
+ * n - node
+ * ... - list of attribute names of type char*
+ * This method checks that the attribute names exist in the node n and asserts if
+ * not. Assert will only occur unless the attribute is optional. An attribute is
+ * optional if it is prefixed by ?, eg "?value". If the attribute name is prefixed
+ * by * or ?, eg "*value" then a copy of the attribute is saved. The saved
+ * attributes will be restored on a subsequent call to Swig_restore(). All the
+ * saved attributes are saved in the view namespace (prefixed by ns).
+ * This function can be called more than once with different namespaces.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_require(const char *ns, Node *n, ...) {
+ va_list ap;
+ char *name;
+ DOH *obj;
+
+ va_start(ap, n);
+ 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++;
+ }
+ 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) {
+ /* Save a copy of the attribute */
+ Setattr(n, NewStringf("%s:%s", ns, name), obj);
+ }
+ name = va_arg(ap, char *);
+ }
+ va_end(ap);
+
+ /* Save the view */
+ {
+ String *view = Getattr(n, "view");
+ if (view) {
+ if (Strcmp(view, ns) != 0) {
+ Setattr(n, NewStringf("%s:view", ns), view);
+ Setattr(n, "view", ns);
+ }
+ } else {
+ Setattr(n, "view", ns);
+ }
+ }
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_save()
+ * Same as Swig_require(), but all attribute names are optional and all attributes
+ * are saved, ie behaves as if all the attribute names were prefixed by ?.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_save(const char *ns, Node *n, ...) {
+ va_list ap;
+ char *name;
+ DOH *obj;
+
+ va_start(ap, n);
+ name = va_arg(ap, char *);
+ while (name) {
+ if (*name == '*') {
+ name++;
+ } else if (*name == '?') {
+ name++;
+ }
+ obj = Getattr(n, name);
+ if (!obj)
+ obj = DohNone;
+
+ /* Save a copy of the attribute */
+ if (Setattr(n, NewStringf("%s:%s", ns, name), obj)) {
+ Printf(stderr, "Swig_save('%s','%s'): Warning, attribute '%s' was already saved.\n", ns, nodeType(n), name);
+ }
+ name = va_arg(ap, char *);
+ }
+ va_end(ap);
+
+ /* Save the view */
+ {
+ String *view = Getattr(n, "view");
+ if (view) {
+ if (Strcmp(view, ns) != 0) {
+ Setattr(n, NewStringf("%s:view", ns), view);
+ Setattr(n, "view", ns);
+ }
+ } else {
+ Setattr(n, "view", ns);
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_restore()
+ * Restores attributes saved by a previous call to Swig_require() or Swig_save().
+ * ----------------------------------------------------------------------------- */
+
+void Swig_restore(Node *n) {
+ String *temp;
+ int len;
+ List *l;
+ String *ns;
+ Iterator ki;
+
+ ns = Getattr(n, "view");
+ assert(ns);
+
+ l = NewList();
+
+ temp = NewStringf("%s:", ns);
+ len = Len(temp);
+
+ for (ki = First(n); ki.key; ki = Next(ki)) {
+ if (Strncmp(temp, ki.key, len) == 0) {
+ Append(l, ki.key);
+ }
+ }
+ for (ki = First(l); ki.item; ki = Next(ki)) {
+ DOH *obj = Getattr(n, ki.item);
+ Setattr(n, Char(ki.item) + len, obj);
+ Delattr(n, ki.item);
+ }
+ Delete(l);
+ Delete(temp);
+}
diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c
new file mode 100644
index 0000000..ebda595
--- /dev/null
+++ b/Source/Swig/typemap.c
@@ -0,0 +1,1936 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * typemap.c
+ *
+ * A somewhat generalized implementation of SWIG1.1 typemaps.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_typemap_c[] = "$Id: typemap.c 11506 2009-08-05 21:40:49Z wsfulton $";
+
+#include "swig.h"
+#include "cparse.h"
+#include <ctype.h>
+
+#if 0
+#define SWIG_DEBUG
+#endif
+
+static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f);
+
+/* -----------------------------------------------------------------------------
+ * 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 typemap 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)
+ * "kwargs" - Typemap attributes
+ *
+ * Example for a typemap method named "in":
+ * %typemap(in, warning="987:my warning", noblock=1) int &my_int (int tmp) "$1 = $input;"
+ *
+ * "type" - r.int
+ * "pname" - my_int
+ * "code" - $1 = $input;
+ * "typemap" - typemap(in) int &my_int
+ * "locals" - int tmp
+ * "kwargs" - warning="987:my typemap warning", foo=123
+ *
+ * ----------------------------------------------------------------------------- */
+
+#define MAX_SCOPE 32
+
+
+static Hash *typemaps[MAX_SCOPE];
+static int tm_scope = 0;
+
+static Hash *get_typemap(int tm_scope, SwigType *type) {
+ Hash *tm = 0;
+ SwigType *dtype = 0;
+ if (SwigType_istemplate(type)) {
+ String *ty = Swig_symbol_template_deftype(type, 0);
+ dtype = Swig_symbol_type_qualify(ty, 0);
+ /* Printf(stderr,"gettm %s %s\n", type, dtype); */
+ type = dtype;
+ Delete(ty);
+ }
+ tm = Getattr(typemaps[tm_scope], type);
+
+
+ if (dtype) {
+ if (!tm) {
+ String *t_name = SwigType_templateprefix(type);
+ if (!Equal(t_name, type)) {
+ tm = Getattr(typemaps[tm_scope], t_name);
+ }
+ Delete(t_name);
+ }
+ Delete(dtype);
+ }
+
+ return tm;
+}
+
+static void set_typemap(int tm_scope, SwigType *type, Hash *tm) {
+ SwigType *dtype = 0;
+ if (SwigType_istemplate(type)) {
+ String *ty = Swig_symbol_template_deftype(type, 0);
+ dtype = Swig_symbol_type_qualify(ty, 0);
+ /* Printf(stderr,"settm %s %s\n", type, dtype); */
+ type = dtype;
+ Delete(ty);
+ } else {
+ dtype = Copy(type);
+ type = dtype;
+ }
+ Setattr(typemaps[tm_scope], type, tm);
+ Delete(dtype);
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_init()
+ *
+ * Initialize the typemap system
+ * ----------------------------------------------------------------------------- */
+
+void Swig_typemap_init() {
+ int i;
+ for (i = 0; i < MAX_SCOPE; i++) {
+ typemaps[i] = 0;
+ }
+ typemaps[0] = NewHash();
+ tm_scope = 0;
+}
+
+static String *typemap_method_name(const_String_or_char_ptr tmap_method) {
+ static Hash *names = 0;
+ String *s;
+ /* Due to "interesting" object-identity semantics of DOH,
+ we have to make sure that we only intern strings without object
+ identity into the hash table.
+
+ (typemap_attach_kwargs calls typemap_method_name several times with
+ the "same" String *tmap_method (i.e., same object identity) but differing
+ string values.)
+
+ Most other callers work around this by using char* rather than
+ String *.
+ -- mkoeppe, Jun 17, 2003
+ */
+ const char *method_without_object_identity = Char(tmap_method);
+ if (!names)
+ names = NewHash();
+ s = Getattr(names, method_without_object_identity);
+ if (s)
+ return s;
+ s = NewStringf("tmap:%s", tmap_method);
+ Setattr(names, method_without_object_identity, s);
+ Delete(s);
+ return s;
+}
+
+#if 0
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_new_scope()
+ *
+ * Create a new typemap scope
+ * ----------------------------------------------------------------------------- */
+
+void Swig_typemap_new_scope() {
+ tm_scope++;
+ typemaps[tm_scope] = NewHash();
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_pop_scope()
+ *
+ * Pop the last typemap scope off
+ * ----------------------------------------------------------------------------- */
+
+Hash *Swig_typemap_pop_scope() {
+ if (tm_scope > 0) {
+ return typemaps[tm_scope--];
+ }
+ return 0;
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_register()
+ *
+ * Add a new multi-argument typemap
+ * ----------------------------------------------------------------------------- */
+
+void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs) {
+ Hash *tm;
+ Hash *tm1;
+ Hash *tm2;
+ Parm *np;
+ String *tm_method;
+ SwigType *type;
+ String *pname;
+
+ if (!parms)
+ return;
+ tm_method = typemap_method_name(tmap_method);
+
+ /* 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 = get_typemap(tm_scope, type);
+ if (!tm) {
+ tm = NewHash();
+ set_typemap(tm_scope, type, tm);
+ Delete(tm);
+ }
+ if (pname) {
+ /* See if parameter has been seen before */
+ tm1 = Getattr(tm, pname);
+ if (!tm1) {
+ tm1 = NewHash();
+ Setattr(tm, pname, tm1);
+ Delete(tm1);
+ }
+ tm = tm1;
+ }
+
+ /* Now see if this typemap method has been seen before */
+ tm2 = Getattr(tm, tm_method);
+ if (!tm2) {
+ tm2 = NewHash();
+ Setattr(tm, tm_method, tm2);
+ Delete(tm2);
+ }
+
+ /* For a multi-argument 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:", tmap_method, type, pname);
+ /* Now reregister on the remaining arguments */
+ Swig_typemap_register(newop, np, code, locals, kwargs);
+
+ /* Setattr(tm2,newop,newop); */
+ Delete(newop);
+ } else {
+ String *str = SwigType_str(type, pname);
+ String *typemap = NewStringf("typemap(%s) %s", tmap_method, str);
+ ParmList *clocals = CopyParmList(locals);
+ ParmList *ckwargs = CopyParmList(kwargs);
+
+ Setattr(tm2, "code", code);
+ Setattr(tm2, "type", type);
+ Setattr(tm2, "typemap", typemap);
+ if (pname) {
+ Setattr(tm2, "pname", pname);
+ }
+ Setattr(tm2, "locals", clocals);
+ Setattr(tm2, "kwargs", ckwargs);
+
+ Delete(clocals);
+ Delete(ckwargs);
+
+ Delete(str);
+ Delete(typemap);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * typemap_get()
+ *
+ * Retrieve typemap information from current scope.
+ * ----------------------------------------------------------------------------- */
+
+static Hash *typemap_get(SwigType *type, const_String_or_char_ptr name, int scope) {
+ Hash *tm, *tm1;
+ /* See if this type has been seen before */
+ if ((scope < 0) || (scope > tm_scope))
+ return 0;
+ tm = get_typemap(scope, type);
+ if (!tm) {
+ return 0;
+ }
+ if ((name) && Len(name)) {
+ tm1 = Getattr(tm, name);
+ return tm1;
+ }
+ return tm;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_copy()
+ *
+ * Copy a typemap
+ * ----------------------------------------------------------------------------- */
+
+int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcparms, ParmList *parms) {
+ Hash *tm = 0;
+ String *tm_method;
+ Parm *p;
+ String *pname;
+ SwigType *ptype;
+ int ts = tm_scope;
+ String *tm_methods, *newop;
+ if (ParmList_len(parms) != ParmList_len(srcparms))
+ return -1;
+
+ tm_method = typemap_method_name(tmap_method);
+ while (ts >= 0) {
+ p = srcparms;
+ tm_methods = NewString(tm_method);
+ while (p) {
+ ptype = Getattr(p, "type");
+ pname = Getattr(p, "name");
+
+ /* Lookup the type */
+ tm = typemap_get(ptype, pname, ts);
+ if (!tm)
+ break;
+
+ tm = Getattr(tm, tm_methods);
+ if (!tm)
+ break;
+
+ /* Got a match. Look for next typemap */
+ newop = NewStringf("%s-%s+%s:", tm_methods, ptype, pname);
+ Delete(tm_methods);
+ tm_methods = newop;
+ p = nextSibling(p);
+ }
+ Delete(tm_methods);
+
+ if (!p && tm) {
+
+ /* Got some kind of match */
+ Swig_typemap_register(tmap_method, parms, Getattr(tm, "code"), Getattr(tm, "locals"), Getattr(tm, "kwargs"));
+ return 0;
+ }
+ ts--;
+ }
+ /* Not found */
+ return -1;
+
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_clear()
+ *
+ * Delete a multi-argument typemap
+ * ----------------------------------------------------------------------------- */
+
+void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *parms) {
+ SwigType *type;
+ String *name;
+ Parm *p;
+ String *newop;
+ Hash *tm = 0;
+
+ /* This might not work */
+ newop = NewString(tmap_method);
+ p = parms;
+ while (p) {
+ type = Getattr(p, "type");
+ name = Getattr(p, "name");
+ tm = 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, typemap_method_name(newop));
+ if (tm) {
+ Delattr(tm, "code");
+ Delattr(tm, "locals");
+ Delattr(tm, "kwargs");
+ }
+ }
+ Delete(newop);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_apply()
+ *
+ * Multi-argument %apply directive. This is pretty horrible so I sure hope
+ * it works.
+ * ----------------------------------------------------------------------------- */
+
+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;
+}
+
+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;
+
+ /* Printf(stdout,"apply : %s --> %s\n", ParmList_str(src), ParmList_str(dest)); */
+
+ /* Create type signature of source */
+ ssig = NewStringEmpty();
+ dsig = NewStringEmpty();
+ 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++;
+ }
+ p = np;
+ dp = nextSibling(dp);
+ }
+
+ /* make sure a typemap node exists for the last destination node */
+ type = Getattr(lastdp, "type");
+ tm = get_typemap(tm_scope, type);
+ if (!tm) {
+ tm = NewHash();
+ set_typemap(tm_scope, type, tm);
+ Delete(tm);
+ }
+ name = Getattr(lastdp, "name");
+ if (name) {
+ Hash *tm1 = Getattr(tm, name);
+ if (!tm1) {
+ tm1 = NewHash();
+ Setattr(tm, NewString(name), tm1);
+ Delete(tm1);
+ }
+ tm = tm1;
+ }
+
+ /* 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) {
+
+ /* See if there is a matching typemap in this scope */
+ sm = typemap_get(type, name, ts);
+
+ /* if there is not matching, look for a typemap in the
+ original typedef, if any, like in:
+
+ typedef unsigned long size_t;
+ ...
+ %apply(size_t) {my_size}; ==> %apply(unsigned long) {my_size};
+ */
+ if (!sm) {
+ SwigType *ntype = SwigType_typedef_resolve(type);
+ if (ntype && (Cmp(ntype, type) != 0)) {
+ sm = typemap_get(ntype, name, ts);
+ }
+ Delete(ntype);
+ }
+
+ if (sm) {
+ /* Got a typemap. Need to only merge attributes for methods that match our signature */
+ Iterator ki;
+ match = 1;
+ for (ki = First(sm); ki.key; ki = Next(ki)) {
+ /* Check for a signature match with the source signature */
+ if ((count_args(ki.key) == narg) && (Strstr(ki.key, ssig))) {
+ String *oldm;
+ /* A typemap we have to copy */
+ String *nkey = Copy(ki.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 = ki.item;
+
+ 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--;
+ }
+ Delete(ssig);
+ Delete(dsig);
+ return match;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_clear_apply()
+ *
+ * %clear directive. Clears all typemaps for a type (in the current scope only).
+ * ----------------------------------------------------------------------------- */
+
+/* Multi-argument %clear directive */
+void 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 = NewStringEmpty();
+ 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 = get_typemap(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 */
+ Iterator ki, ki2;
+ char *ctsig = Char(tsig);
+ for (ki = First(tm); ki.key; ki = Next(ki)) {
+ char *ckey = Char(ki.key);
+ if (strncmp(ckey, "tmap:", 5) == 0) {
+ int na = count_args(ki.key);
+ if ((na == narg) && strstr(ckey, ctsig)) {
+ Hash *h = ki.item;
+ for (ki2 = First(h); ki2.key; ki2 = Next(ki2)) {
+ Delattr(h, ki2.key);
+ }
+ }
+ }
+ }
+ }
+ Delete(tsig);
+}
+
+/* Internal function to strip array dimensions. */
+static SwigType *strip_arrays(SwigType *type) {
+ SwigType *t;
+ int ndim;
+ int i;
+ t = Copy(type);
+ ndim = SwigType_array_ndim(t);
+ for (i = 0; i < ndim; i++) {
+ SwigType_array_setdim(t, i, "ANY");
+ }
+ return t;
+}
+
+/* -----------------------------------------------------------------------------
+ * typemap_search()
+ *
+ * Search for a typemap match. Tries to find the most specific typemap
+ * that includes a 'code' attribute.
+ * ----------------------------------------------------------------------------- */
+
+static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type, const_String_or_char_ptr 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;
+ const String *cname = 0;
+ SwigType *unstripped = 0;
+ String *tm_method = typemap_method_name(tmap_method);
+
+ if ((name) && Len(name))
+ cname = name;
+ ts = tm_scope;
+
+ while (ts >= 0) {
+ ctype = type;
+ while (ctype) {
+ /* Try to get an exact type-match */
+ tm = get_typemap(ts, ctype);
+ if (tm && cname) {
+ tm1 = Getattr(tm, cname);
+ if (tm1) {
+ result = Getattr(tm1, tm_method); /* 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, tm_method); /* 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".
+ See if that generates a match */
+ if (!noarrays) {
+ noarrays = strip_arrays(ctype);
+ }
+ tma = get_typemap(ts, noarrays);
+ if (tma && cname) {
+ tm1 = Getattr(tma, cname);
+ if (tm1) {
+ result = Getattr(tm1, tm_method); /* type-name match */
+ if (result && Getattr(result, "code"))
+ goto ret_result;
+ if (result)
+ backup = result;
+ }
+ }
+ if (tma) {
+ result = Getattr(tma, tm_method); /* type match */
+ if (result && Getattr(result, "code"))
+ goto ret_result;
+ if (result)
+ backup = result;
+ }
+ Delete(noarrays);
+ noarrays = 0;
+ }
+
+ /* 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 (!Equal(ctype, unstripped))
+ continue; /* Types are different */
+ Delete(ctype);
+ ctype = unstripped;
+ unstripped = 0;
+ }
+ {
+ String *octype;
+ if (unstripped) {
+ Delete(ctype);
+ ctype = unstripped;
+ unstripped = 0;
+ }
+ octype = ctype;
+ ctype = SwigType_typedef_resolve(ctype);
+ if (octype != type)
+ Delete(octype);
+ }
+ }
+
+ /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default mapping */
+
+ primitive = SwigType_default(type);
+ while (primitive) {
+ tm = get_typemap(ts, primitive);
+ if (tm && cname) {
+ tm1 = Getattr(tm, cname);
+ if (tm1) {
+ result = Getattr(tm1, tm_method); /* 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, tm_method);
+ if (result)
+ goto ret_result;
+ }
+ {
+ SwigType *nprim = SwigType_default(primitive);
+ Delete(primitive);
+ primitive = nprim;
+ }
+ }
+ if (ctype != type) {
+ Delete(ctype);
+ ctype = 0;
+ }
+ 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;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * typemap_search_multi()
+ *
+ * Search for a multi-argument typemap.
+ * ----------------------------------------------------------------------------- */
+
+static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, 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 = typemap_search(tmap_method, type, name, &mtype);
+ if (tm) {
+ if (mtype && SwigType_isarray(mtype)) {
+ Setattr(parms, "tmap:match", mtype);
+ }
+ Delete(mtype);
+ newop = NewStringf("%s-%s+%s:", tmap_method, type, name);
+ tm1 = 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, const String *name, const String *rep) {
+ SwigType *t;
+ while (p) {
+ t = Getattr(p, "type");
+ Replace(t, name, rep, DOH_REPLACE_ANY);
+ p = nextSibling(p);
+ }
+}
+
+static int check_locals(ParmList *p, const char *s) {
+ while (p) {
+ char *c = GetChar(p, "type");
+ if (strstr(c, s))
+ return 1;
+ p = nextSibling(p);
+ }
+ return 0;
+}
+
+static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *rtype, String *pname, String *lname, int index) {
+ char var[512];
+ char *varname;
+ SwigType *ftype;
+ int bare_substitution_count = 0;
+
+ Replaceall(s, "$typemap", "$TYPEMAP"); /* workaround for $type substitution below */
+
+ 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
+ its array dimensions */
+
+ if (SwigType_isarray(type) || SwigType_isarray(ftype)) {
+ String *size;
+ int ndim;
+ int i;
+ if (SwigType_array_ndim(type) != SwigType_array_ndim(ftype))
+ type = ftype;
+ ndim = SwigType_array_ndim(type);
+ size = NewStringEmpty();
+ 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, *lex_type;
+ SwigType *ltype, *star_ltype, *amp_ltype;
+ String *mangle, *star_mangle, *amp_mangle, *base_mangle, *base_name;
+ String *descriptor, *star_descriptor, *amp_descriptor;
+ String *ts;
+ char *sc;
+
+ sc = Char(s);
+
+ if (strstr(sc, "type") || check_locals(locals, "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") || check_locals(locals, "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)) {
+ SwigType_del_element(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 {
+ SwigType_del_element(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);
+ }
+
+ base_name = SwigType_namestr(base_type);
+ if (index == 1) {
+ Replace(s, "$basetype", base_name, DOH_REPLACE_ANY);
+ replace_local_types(locals, "$basetype", base_name);
+ }
+ strcpy(varname, "basetype");
+ Replace(s, var, base_type, DOH_REPLACE_ANY);
+ replace_local_types(locals, var, base_name);
+
+ 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);
+ Delete(base_name);
+
+ lex_type = SwigType_base(rtype);
+ if (index == 1)
+ Replace(s, "$lextype", lex_type, DOH_REPLACE_ANY);
+ strcpy(varname, "lextype");
+ Replace(s, var, lex_type, DOH_REPLACE_ANY);
+ Delete(lex_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);
+ bare_substitution_count = Replace(s, var, lname, DOH_REPLACE_ANY);
+ Delete(ftype);
+ return bare_substitution_count;
+}
+
+/* ------------------------------------------------------------------------
+ * static typemap_locals()
+ *
+ * Takes a string, a parameter list and a wrapper function argument and
+ * creates the local variables.
+ * ------------------------------------------------------------------------ */
+
+static void typemap_locals(DOHString * s, ParmList *l, Wrapper *f, int argnum) {
+ Parm *p;
+ char *new_name;
+
+ p = l;
+ while (p) {
+ SwigType *pt = Getattr(p, "type");
+ SwigType *at = SwigType_alttype(pt, 1);
+ String *pn = Getattr(p, "name");
+ String *value = Getattr(p, "value");
+ if (at)
+ pt = at;
+ if (pn) {
+ if (Len(pn) > 0) {
+ String *str;
+ int isglobal = 0;
+
+ str = NewStringEmpty();
+
+ if (strncmp(Char(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 ((argnum >= 0) && (!isglobal)) {
+ Printf(str, "%s%d", pn, argnum);
+ } else {
+ Append(str, pn);
+ }
+ if (isglobal && Wrapper_check_local(f, str)) {
+ p = nextSibling(p);
+ Delete(str);
+ if (at)
+ Delete(at);
+ continue;
+ }
+ if (value) {
+ String *pstr = SwigType_str(pt, str);
+ new_name = Wrapper_new_localv(f, str, pstr, "=", value, NIL);
+ Delete(pstr);
+ } else {
+ String *pstr = SwigType_str(pt, str);
+ new_name = Wrapper_new_localv(f, str, pstr, NIL);
+ Delete(pstr);
+ }
+ if (!isglobal) {
+ /* Substitute */
+ Replace(s, pn, new_name, DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE);
+ }
+ Delete(str);
+ }
+ }
+ p = nextSibling(p);
+ if (at)
+ Delete(at);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_lookup()
+ *
+ * Attach one or more typemaps to a node and optionally generate the typemap contents
+ * into the wrapper.
+ *
+ * Looks for a typemap matching the given type and name and attaches the typemap code
+ * and any typemap attributes to the provided node.
+ *
+ * The node should contain the "type" and "name" attributes for the typemap match on.
+ * input. The typemap code and typemap attribute values are attached onto the node
+ * prefixed with "tmap:". For example with tmap_method="in", the typemap code can be retrieved
+ * with a call to Getattr(node, "tmap:in") (this is also the string returned) and the
+ * "noblock" attribute can be retrieved with a call to Getattr(node, "tmap:in:noblock").
+ *
+ * tmap_method - typemap method, eg "in", "out", "newfree"
+ * node - the node to attach the typemap and typemap attributes to
+ * lname - name of variable to substitute $1, $2 etc for
+ * f - wrapper code to generate into if non null
+ * actioncode - code to generate into f before the out typemap code, unless
+ * the optimal attribute is set in the out typemap in which case
+ * $1 in the out typemap will be replaced by the code in actioncode.
+ * ----------------------------------------------------------------------------- */
+
+static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f, String *actioncode) {
+ SwigType *type;
+ SwigType *mtype = 0;
+ String *pname;
+ Hash *tm = 0;
+ String *s = 0;
+ String *sdef = 0;
+ ParmList *locals;
+ ParmList *kw;
+ char temp[256];
+ String *symname;
+ String *cname = 0;
+ String *clname = 0;
+ char *cop = Char(tmap_method);
+ int optimal_attribute = 0;
+ int optimal_substitution = 0;
+ int num_substitutions = 0;
+
+ /* special case, we need to check for 'ref' call
+ and set the default code 'sdef' */
+ if (node && Cmp(tmap_method, "newfree") == 0) {
+ sdef = Swig_ref_call(node, lname);
+ }
+
+ type = Getattr(node, "type");
+ if (!type)
+ return sdef;
+
+ pname = Getattr(node, "name");
+
+#if 1
+ if (pname && node && checkAttribute(node, "kind", "function")) {
+ /*
+ For functions, look qualified names first, such as
+
+ struct Foo {
+ int *foo(int bar) -> Foo::foo
+ };
+ */
+ Symtab *st = Getattr(node, "sym:symtab");
+ String *qsn = st ? Swig_symbol_string_qualify(pname, st) : 0;
+ if (qsn) {
+ if (Len(qsn) && !Equal(qsn, pname)) {
+ tm = typemap_search(tmap_method, type, qsn, &mtype);
+ if (tm && (!Getattr(tm, "pname") || strstr(Char(Getattr(tm, "type")), "SWIGTYPE"))) {
+ tm = 0;
+ }
+ }
+ Delete(qsn);
+ }
+ }
+ if (!tm)
+#endif
+ tm = typemap_search(tmap_method, type, pname, &mtype);
+ if (!tm)
+ return sdef;
+
+ s = Getattr(tm, "code");
+ if (!s)
+ return sdef;
+
+ /* Empty typemap. No match */
+ if (Cmp(s, "pass") == 0)
+ return sdef;
+
+ s = Copy(s); /* Make a local copy of the typemap code */
+
+ /* Attach kwargs - ie the typemap attributes */
+ kw = Getattr(tm, "kwargs");
+ while (kw) {
+ String *value = Copy(Getattr(kw, "value"));
+ String *kwtype = Getattr(kw, "type");
+ char *ckwname = Char(Getattr(kw, "name"));
+ if (kwtype) {
+ String *mangle = Swig_string_mangle(kwtype);
+ Append(value, mangle);
+ Delete(mangle);
+ }
+ sprintf(temp, "%s:%s", cop, ckwname);
+ Setattr(node, typemap_method_name(temp), value);
+ if (Cmp(temp, "out:optimal") == 0)
+ optimal_attribute = (Cmp(value, "0") != 0) ? 1 : 0;
+ Delete(value);
+ kw = nextSibling(kw);
+ }
+
+ if (optimal_attribute) {
+ /* Note: "out" typemap is the only typemap that will have the "optimal" attribute set.
+ * If f and actioncode are NULL, then the caller is just looking to attach the "out" attributes
+ * ie, not use the typemap code, otherwise both f and actioncode must be non null. */
+ if (actioncode) {
+ clname = Copy(actioncode);
+ /* check that the code in the typemap can be used in this optimal way.
+ * The code should be in the form "result = ...;\n". We need to extract
+ * the "..." part. This may not be possible for various reasons, eg
+ * code added by %exception. This optimal code generation is bit of a
+ * hack and circumvents the normal requirement for a temporary variable
+ * to hold the result returned from a wrapped function call.
+ */
+ if (Strncmp(clname, "result = ", 9) == 0) {
+ int numreplacements = Replace(clname, "result = ", "", DOH_REPLACE_ID_BEGIN);
+ if (numreplacements == 1) {
+ numreplacements = Replace(clname, ";\n", "", DOH_REPLACE_ID_END);
+ if (numreplacements == 1) {
+ if (Strchr(clname, ';') == 0) {
+ lname = clname;
+ actioncode = 0;
+ optimal_substitution = 1;
+ }
+ }
+ }
+ }
+ if (!optimal_substitution) {
+ Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute in the out typemap at %s:%d ignored as the following cannot be used to generate optimal code: %s\n", Swig_name_decl(node), Getfile(s), Getline(s), clname);
+ Delattr(node, "tmap:out:optimal");
+ }
+ } else {
+ assert(!f);
+ }
+ }
+ if (actioncode) {
+ assert(f);
+ Append(f->code, actioncode);
+ }
+
+ /* emit local variables declared in typemap, eg emit declarations for aa and bb in:
+ * %typemap(in) foo (int aa, int bb) "..." */
+ 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)) {
+ num_substitutions = typemap_replace_vars(s, locals, mtype, type, pname, (char *) lname, 1);
+ } else {
+ num_substitutions = typemap_replace_vars(s, locals, type, type, pname, (char *) lname, 1);
+ }
+ if (optimal_substitution && num_substitutions > 1)
+ Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(node), Getline(node), "Multiple calls to %s might be generated due to optimal attribute usage in the out typemap at %s:%d.\n", Swig_name_decl(node), Getfile(s), Getline(s));
+
+ if (locals && f) {
+ typemap_locals(s, locals, f, -1);
+ }
+
+ {
+ ParmList *parm_sublist = NewParm(type, pname);
+ Setattr(parm_sublist, "lname", lname);
+ replace_embedded_typemap(s, parm_sublist, f);
+ Delete(parm_sublist);
+ }
+
+ Replace(s, "$name", pname, DOH_REPLACE_ANY);
+
+ symname = Getattr(node, "sym:name");
+ if (symname) {
+ Replace(s, "$symname", symname, DOH_REPLACE_ANY);
+ }
+
+ Setattr(node, typemap_method_name(tmap_method), s);
+ if (locals) {
+ sprintf(temp, "%s:locals", cop);
+ Setattr(node, typemap_method_name(temp), locals);
+ Delete(locals);
+ }
+
+ if (Checkattr(tm, "type", "SWIGTYPE")) {
+ sprintf(temp, "%s:SWIGTYPE", cop);
+ Setattr(node, typemap_method_name(temp), "1");
+ }
+
+ /* Look for warnings */
+ {
+ String *w;
+ sprintf(temp, "%s:warning", cop);
+ w = Getattr(node, typemap_method_name(temp));
+ if (w) {
+ Swig_warning(0, Getfile(node), Getline(node), "%s\n", w);
+ }
+ }
+
+ /* Look for code fragments */
+ {
+ String *fragment;
+ sprintf(temp, "%s:fragment", cop);
+ fragment = Getattr(node, typemap_method_name(temp));
+ if (fragment) {
+ String *fname = Copy(fragment);
+ Setfile(fname, Getfile(node));
+ Setline(fname, Getline(node));
+ Swig_fragment_emit(fname);
+ Delete(fname);
+ }
+ }
+
+ Delete(cname);
+ Delete(clname);
+ Delete(mtype);
+ if (sdef) { /* put 'ref' and 'newfree' codes together */
+ String *p = NewStringf("%s\n%s", sdef, s);
+ Delete(s);
+ Delete(sdef);
+ s = p;
+ }
+ Delete(actioncode);
+ return s;
+}
+
+String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f, String *actioncode) {
+ assert(actioncode);
+ assert(Cmp(tmap_method, "out") == 0);
+ return Swig_typemap_lookup_impl(tmap_method, node, lname, f, actioncode);
+}
+
+String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f) {
+ return Swig_typemap_lookup_impl(tmap_method, node, lname, f, 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * typemap_attach_kwargs()
+ *
+ * If this hash (tm) contains a linked list of parameters under its "kwargs"
+ * attribute, add keys for each of those named keyword arguments to this
+ * parameter for later use.
+ * For example, attach the typemap attributes to p:
+ * %typemap(in, foo="xyz") ...
+ * A new attribute called "tmap:in:foo" with value "xyz" is attached to p.
+ * ----------------------------------------------------------------------------- */
+
+static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *p) {
+ String *temp = NewStringEmpty();
+ Parm *kw = Getattr(tm, "kwargs");
+ while (kw) {
+ String *value = Copy(Getattr(kw, "value"));
+ String *type = Getattr(kw, "type");
+ if (type) {
+ Hash *v = NewHash();
+ Setattr(v, "type", type);
+ Setattr(v, "value", value);
+ Delete(value);
+ value = v;
+ }
+ Clear(temp);
+ Printf(temp, "%s:%s", tmap_method, Getattr(kw, "name"));
+ Setattr(p, typemap_method_name(temp), value);
+ Delete(value);
+ kw = nextSibling(kw);
+ }
+ Clear(temp);
+ Printf(temp, "%s:match_type", tmap_method);
+ Setattr(p, typemap_method_name(temp), Getattr(tm, "type"));
+ Delete(temp);
+}
+
+/* -----------------------------------------------------------------------------
+ * typemap_warn()
+ *
+ * If any warning message is attached to this parameter's "tmap:<method>:warning"
+ * attribute, print that warning message.
+ * ----------------------------------------------------------------------------- */
+
+static void typemap_warn(const_String_or_char_ptr tmap_method, Parm *p) {
+ String *temp = NewStringf("%s:warning", tmap_method);
+ String *w = Getattr(p, typemap_method_name(temp));
+ Delete(temp);
+ if (w) {
+ Swig_warning(0, Getfile(p), Getline(p), "%s\n", w);
+ }
+}
+
+static void typemap_emit_code_fragments(const_String_or_char_ptr tmap_method, Parm *p) {
+ String *temp = NewStringf("%s:fragment", tmap_method);
+ String *f = Getattr(p, typemap_method_name(temp));
+ if (f) {
+ String *fname = Copy(f);
+ Setfile(fname, Getfile(p));
+ Setline(fname, Getline(p));
+ Swig_fragment_emit(fname);
+ Delete(fname);
+ }
+ Delete(temp);
+}
+
+static String *typemap_get_option(Hash *tm, const_String_or_char_ptr name) {
+ Parm *kw = Getattr(tm, "kwargs");
+ while (kw) {
+ String *kname = Getattr(kw, "name");
+ if (Equal(kname, name)) {
+ return Getattr(kw, "value");
+ }
+ kw = nextSibling(kw);
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_attach_parms()
+ *
+ * Given a parameter list, this function attaches all of the typemaps and typemap
+ * attributes to the parameter for each type in the parameter list.
+ *
+ * This function basically provides the typemap code and typemap attribute values as
+ * attributes on each parameter prefixed with "tmap:". For example with tmap_method="in", the typemap
+ * code can be retrieved for the first parameter with a call to Getattr(parm, "tmap:in")
+ * and the "numinputs" attribute can be retrieved with a call to Getattr(parm, "tmap:in:numinputs").
+ *
+ * tmap_method - typemap method, eg "in", "out", "newfree"
+ * parms - parameter list to attach each typemap and all typemap attributes
+ * f - wrapper code to generate into if non null
+ * ----------------------------------------------------------------------------- */
+
+void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f) {
+ Parm *p, *firstp;
+ Hash *tm;
+ int nmatch = 0;
+ int i;
+ String *s;
+ ParmList *locals;
+ int argnum = 0;
+ char temp[256];
+ char *cop = Char(tmap_method);
+ String *kwmatch = 0;
+ p = parms;
+
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_typemap_attach_parms: %s\n", tmap_method);
+#endif
+
+ while (p) {
+ argnum++;
+ nmatch = 0;
+#ifdef SWIG_DEBUG
+ Printf(stdout, "parms: %s %s %s\n", tmap_method, Getattr(p, "name"), Getattr(p, "type"));
+#endif
+ tm = typemap_search_multi(tmap_method, p, &nmatch);
+#ifdef SWIG_DEBUG
+ if (tm)
+ Printf(stdout, "found: %s\n", tm);
+#endif
+ if (!tm) {
+ p = nextSibling(p);
+ continue;
+ }
+ /*
+ Check if the typemap requires to match the type of another
+ typemap, for example:
+
+ %typemap(in) SWIGTYPE * (int var) {...}
+ %typemap(freearg,match="in") SWIGTYPE * {if (var$argnum) ...}
+
+ here, the freearg typemap requires the "in" typemap to match,
+ or the 'var$argnum' variable will not exist.
+ */
+ kwmatch = typemap_get_option(tm, "match");
+ if (kwmatch) {
+ String *tmname = NewStringf("tmap:%s", kwmatch);
+ String *tmin = Getattr(p, tmname);
+ Delete(tmname);
+#ifdef SWIG_DEBUG
+ if (tm)
+ Printf(stdout, "matching: %s\n", kwmatch);
+#endif
+ if (tmin) {
+ String *tmninp = NewStringf("tmap:%s:numinputs", kwmatch);
+ String *ninp = Getattr(p, tmninp);
+ Delete(tmninp);
+ if (ninp && Equal(ninp, "0")) {
+ p = nextSibling(p);
+ continue;
+ } else {
+ SwigType *typetm = Getattr(tm, "type");
+ String *temp = NewStringf("tmap:%s:match_type", kwmatch);
+ SwigType *typein = Getattr(p, temp);
+ Delete(temp);
+ if (!Equal(typein, typetm)) {
+ p = nextSibling(p);
+ continue;
+ } else {
+ int nnmatch;
+ Hash *tmapin = typemap_search_multi(kwmatch, p, &nnmatch);
+ String *tmname = Getattr(tm, "pname");
+ String *tnname = Getattr(tmapin, "pname");
+ if (!(tmname && tnname && Equal(tmname, tnname)) && !(!tmname && !tnname)) {
+ p = nextSibling(p);
+ continue;
+ }
+ }
+
+ }
+ } else {
+ p = nextSibling(p);
+ continue;
+ }
+ }
+
+ s = Getattr(tm, "code");
+ if (!s) {
+ p = nextSibling(p);
+ continue;
+ }
+#ifdef SWIG_DEBUG
+ if (s)
+ Printf(stdout, "code: %s\n", s);
+#endif
+
+ /* 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;
+#ifdef SWIG_DEBUG
+ Printf(stdout, "nmatch: %d\n", nmatch);
+#endif
+ 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, type, pname, lname, i + 1);
+ Delattr(p, "tmap:match");
+ } else {
+ typemap_replace_vars(s, locals, type, type, pname, lname, i + 1);
+ }
+
+ if (Checkattr(tm, "type", "SWIGTYPE")) {
+ sprintf(temp, "%s:SWIGTYPE", cop);
+ Setattr(p, typemap_method_name(temp), "1");
+ }
+ p = nextSibling(p);
+ }
+
+ if (locals && f) {
+ typemap_locals(s, locals, f, argnum);
+ }
+
+ replace_embedded_typemap(s, firstp, f);
+
+ /* Replace the argument number */
+ sprintf(temp, "%d", argnum);
+ Replace(s, "$argnum", temp, DOH_REPLACE_ANY);
+
+ /* Attach attributes to object */
+#ifdef SWIG_DEBUG
+ Printf(stdout, "attach: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), s);
+#endif
+ Setattr(firstp, typemap_method_name(tmap_method), s); /* Code object */
+
+ if (locals) {
+ sprintf(temp, "%s:locals", cop);
+ Setattr(firstp, typemap_method_name(temp), locals);
+ Delete(locals);
+ }
+
+ /* Attach a link to the next parameter. Needed for multimaps */
+ sprintf(temp, "%s:next", cop);
+ Setattr(firstp, typemap_method_name(temp), p);
+
+ /* Attach kwargs */
+ typemap_attach_kwargs(tm, tmap_method, firstp);
+
+ /* Print warnings, if any */
+ typemap_warn(tmap_method, firstp);
+
+ /* Look for code fragments */
+ typemap_emit_code_fragments(tmap_method, firstp);
+
+ /* increase argnum to consider numinputs */
+ argnum += nmatch - 1;
+ Delete(s);
+#ifdef SWIG_DEBUG
+ Printf(stdout, "res: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), Getattr(firstp, typemap_method_name(tmap_method)));
+#endif
+
+ }
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_typemap_attach_parms: end\n");
+#endif
+
+}
+
+/* Splits the arguments of an embedded typemap */
+static List *split_embedded_typemap(String *s) {
+ List *args = 0;
+ char *c, *start;
+ int level = 0;
+ int angle_level = 0;
+ int leading = 1;
+
+ args = NewList();
+ c = strchr(Char(s), '(');
+ assert(c);
+ c++;
+
+ start = c;
+ while (*c) {
+ if (*c == '\"') {
+ c++;
+ while (*c) {
+ if (*c == '\\') {
+ c++;
+ } else {
+ if (*c == '\"')
+ break;
+ }
+ c++;
+ }
+ }
+ if ((level == 0) && angle_level == 0 && ((*c == ',') || (*c == ')'))) {
+ String *tmp = NewStringWithSize(start, c - start);
+ Append(args, tmp);
+ Delete(tmp);
+ start = c + 1;
+ leading = 1;
+ if (*c == ')')
+ break;
+ c++;
+ continue;
+ }
+ if (*c == '(')
+ level++;
+ if (*c == ')')
+ level--;
+ if (*c == '<')
+ angle_level++;
+ if (*c == '>')
+ angle_level--;
+ if (isspace((int) *c) && leading)
+ start++;
+ if (!isspace((int) *c))
+ leading = 0;
+ c++;
+ }
+ return args;
+}
+
+/* -----------------------------------------------------------------------------
+ * replace_embedded_typemap()
+ *
+ * This function replaces the special variable macro $typemap(...) with typemap
+ * code. The general form of $typemap is as follows:
+ *
+ * $typemap(method, typelist, var1=value, var2=value, ...)
+ *
+ * where varx parameters are optional and undocumented; they were used in an earlier version of $typemap.
+ * A search is made using the typemap matching rules of form:
+ *
+ * %typemap(method) typelist {...}
+ *
+ * and if found will substitute in the typemap contents, making appropriate variable replacements.
+ *
+ * For example:
+ * $typemap(in, int) # simple usage matching %typemap(in) int { ... }
+ * $typemap(in, int b) # simple usage matching %typemap(in) int b { ... } or above %typemap
+ * $typemap(in, (Foo<int, bool> a, int b)) # multi-argument typemap matching %typemap(in) (Foo<int, bool> a, int b) {...}
+ * ----------------------------------------------------------------------------- */
+
+static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f) {
+ char *start = 0;
+ while ((start = strstr(Char(s), "$TYPEMAP("))) { /* note $typemap capitalisation to $TYPEMAP hack */
+
+ /* Gather the parameters */
+ char *end = 0, *c;
+ int level = 0;
+ String *dollar_typemap;
+ int syntax_error = 1;
+ c = start;
+ while (*c) {
+ if (*c == '(')
+ level++;
+ if (*c == ')') {
+ level--;
+ if (level == 0) {
+ end = c + 1;
+ break;
+ }
+ }
+ c++;
+ }
+ if (end) {
+ dollar_typemap = NewStringWithSize(start, (end - start));
+ syntax_error = 0;
+ } else {
+ dollar_typemap = NewStringWithSize(start, (c - start));
+ }
+
+ if (!syntax_error) {
+ List *l;
+ String *tmap_method;
+ Hash *vars;
+ syntax_error = 1;
+
+ /* Split apart each parameter in $typemap(...) */
+ l = split_embedded_typemap(dollar_typemap);
+
+ if (Len(l) >= 2) {
+ ParmList *to_match_parms;
+ tmap_method = Getitem(l, 0);
+
+ /* the second parameter might contain multiple sub-parameters for multi-argument
+ * typemap matching, so split these parameters apart */
+ to_match_parms = Swig_cparse_parms(Getitem(l, 1));
+ if (to_match_parms) {
+ Parm *p = to_match_parms;
+ Parm *sub_p = parm_sublist;
+ String *empty_string = NewStringEmpty();
+ String *lname = empty_string;
+ while (p) {
+ if (sub_p) {
+ lname = Getattr(sub_p, "lname");
+ sub_p = nextSibling(sub_p);
+ }
+ Setattr(p, "lname", lname);
+ p = nextSibling(p);
+ }
+ Delete(empty_string);
+ }
+
+ /* process optional extra parameters - the variable replacements (undocumented) */
+ vars = NewHash();
+ {
+ int i, ilen;
+ ilen = Len(l);
+ for (i = 2; i < ilen; i++) {
+ String *parm = Getitem(l, i);
+ char *eq = strchr(Char(parm), '=');
+ char *c = Char(parm);
+ if (eq && (eq - c > 0)) {
+ String *name = NewStringWithSize(c, eq - c);
+ String *value = NewString(eq + 1);
+ Insert(name, 0, "$");
+ Setattr(vars, name, value);
+ } else {
+ to_match_parms = 0; /* error - variable replacement parameters must be of form varname=value */
+ }
+ }
+ }
+
+ /* Perform a typemap search */
+ if (to_match_parms) {
+ static int already_substituting = 0;
+ String *tm;
+ String *attr;
+ int match = 0;
+#ifdef SWIG_DEBUG
+ Printf(stdout, "Swig_typemap_attach_parms: embedded\n");
+#endif
+ if (!already_substituting) {
+ already_substituting = 1;
+ Swig_typemap_attach_parms(tmap_method, to_match_parms, f);
+ already_substituting = 0;
+
+ /* Look for the typemap code */
+ attr = NewStringf("tmap:%s", tmap_method);
+ tm = Getattr(to_match_parms, attr);
+ if (tm) {
+ Printf(attr, "%s", ":next");
+ /* fail if multi-argument lookup requested in $typemap(...) and the lookup failed */
+ if (!Getattr(to_match_parms, attr)) {
+ /* Replace parameter variables */
+ Iterator ki;
+ for (ki = First(vars); ki.key; ki = Next(ki)) {
+ Replace(tm, ki.key, ki.item, DOH_REPLACE_ANY);
+ }
+ /* offer the target language module the chance to make special variable substitutions */
+ Language_replace_special_variables(tmap_method, tm, to_match_parms);
+ /* finish up - do the substitution */
+ Replace(s, dollar_typemap, tm, DOH_REPLACE_ANY);
+ Delete(tm);
+ match = 1;
+ }
+ }
+
+ if (!match) {
+ String *dtypemap = NewString(dollar_typemap);
+ Replaceall(dtypemap, "$TYPEMAP", "$typemap");
+ Swig_error(Getfile(s), Getline(s), "No typemap found for %s\n", dtypemap);
+ Delete(dtypemap);
+ }
+ Delete(attr);
+ } else {
+ /* simple recursive call check, but prevents using an embedded typemap that contains another embedded typemap */
+ String *dtypemap = NewString(dollar_typemap);
+ Replaceall(dtypemap, "$TYPEMAP", "$typemap");
+ Swig_error(Getfile(s), Getline(s), "Recursive $typemap calls not supported - %s\n", dtypemap);
+ Delete(dtypemap);
+ }
+ syntax_error = 0;
+ }
+ Delete(vars);
+ }
+ Delete(l);
+ }
+
+ if (syntax_error) {
+ String *dtypemap = NewString(dollar_typemap);
+ Replaceall(dtypemap, "$TYPEMAP", "$typemap");
+ Swig_error(Getfile(s), Getline(s), "Syntax error in: %s\n", dtypemap);
+ Delete(dtypemap);
+ }
+ Replace(s, dollar_typemap, "<error in embedded typemap>", DOH_REPLACE_ANY);
+ Delete(dollar_typemap);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_typemap_debug()
+ * ----------------------------------------------------------------------------- */
+
+void Swig_typemap_debug() {
+ int ts;
+ Printf(stdout, "---[ typemaps ]--------------------------------------------------------------\n");
+
+ ts = tm_scope;
+ while (ts >= 0) {
+ Printf(stdout, "::: scope %d\n\n", ts);
+ Printf(stdout, "%s\n", typemaps[ts]);
+ ts--;
+ }
+ Printf(stdout, "-----------------------------------------------------------------------------\n");
+}
diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c
new file mode 100644
index 0000000..085fda3
--- /dev/null
+++ b/Source/Swig/typeobj.c
@@ -0,0 +1,1095 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * typeobj.c
+ *
+ * This file provides functions for constructing, manipulating, and testing
+ * type objects. Type objects are merely the raw low-level representation
+ * of C++ types. They do not incorporate high-level type system features
+ * like typedef, namespaces, etc.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_typeobj_c[] = "$Id: typeobj.c 11080 2009-01-24 13:15:51Z bhy $";
+
+#include "swig.h"
+#include <ctype.h>
+
+/* -----------------------------------------------------------------------------
+ * Synopsis
+ *
+ * This file provides a collection of low-level functions for constructing and
+ * manipulating C++ data types. In SWIG, C++ datatypes are encoded as simple
+ * text strings. This representation is compact, easy to debug, and easy to read.
+ *
+ * General idea:
+ *
+ * Types are represented by a base type (e.g., "int") and a collection of
+ * type operators applied to the base (e.g., pointers, arrays, etc...).
+ *
+ * Encoding:
+ *
+ * Types are encoded as strings of type constructors such as follows:
+ *
+ * String Encoding C Example
+ * --------------- ---------
+ * p.p.int int **
+ * a(300).a(400).int int [300][400]
+ * p.q(const).char char const *
+ *
+ * All type constructors are denoted by a trailing '.':
+ *
+ * '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
+ * "p.q(const).char" is "a pointer to a const char".
+ *
+ * This representation of types is fairly convenient because ordinary string
+ * operations can be used for type manipulation. For example, a type could be
+ * formed by combining two strings such as the following:
+ *
+ * "p.p." + "a(400).int" = "p.p.a(400).int"
+ *
+ * For C++, typenames may be parameterized using <(...)>. Here are some
+ * examples:
+ *
+ * String Encoding C++ Example
+ * --------------- ------------
+ * p.vector<(int)> vector<int> *
+ * r.foo<(int,p.double)> foo<int,double *> &
+ *
+ * Contents of this file:
+ *
+ * Most of this functions in this file pertain to the low-level manipulation
+ * of type objects. There are constructor functions like this:
+ *
+ * SwigType_add_pointer()
+ * SwigType_add_reference()
+ * SwigType_add_array()
+ *
+ * These are used to build new types. There are also functions to undo these
+ * operations. For example:
+ *
+ * SwigType_del_pointer()
+ * SwigType_del_reference()
+ * SwigType_del_array()
+ *
+ * In addition, there are query functions
+ *
+ * SwigType_ispointer()
+ * SwigType_isreference()
+ * SwigType_isarray()
+ *
+ * Finally, there are some data extraction functions that can be used to
+ * extract array dimensions, template arguments, and so forth.
+ *
+ * It is very important for developers to realize that the functions in this
+ * module do *NOT* incorporate higher-level type system features like typedef.
+ * For example, you could have C code like this:
+ *
+ * typedef int *intptr;
+ *
+ * In this case, a SwigType of type 'intptr' will be treated as a simple type and
+ * functions like SwigType_ispointer() will evaluate as false. It is strongly
+ * advised that developers use the TypeSys_* interface to check types in a more
+ * reliable manner.
+ * ----------------------------------------------------------------------------- */
+
+
+/* -----------------------------------------------------------------------------
+ * NewSwigType()
+ *
+ * Constructs a new type object. Eventually, it would be nice for this function
+ * to accept an initial value in the form a C/C++ abstract type (currently unimplemented).
+ * ----------------------------------------------------------------------------- */
+
+#ifdef NEW
+SwigType *NewSwigType(const_String_or_char_ptr initial) {
+ return NewString(initial);
+}
+
+#endif
+
+/* The next few functions are utility functions used in the construction and
+ management of types */
+
+/* -----------------------------------------------------------------------------
+ * static element_size()
+ *
+ * This utility function finds the size of a single type element in a type string.
+ * Type elements are always delimited by periods, but may be nested with
+ * parentheses. A nested element is always handled as a single item.
+ *
+ * Returns the integer size of the element (which can be used to extract a
+ * substring, to chop the element off, or for other purposes).
+ * ----------------------------------------------------------------------------- */
+
+static int element_size(char *c) {
+ int nparen;
+ char *s = c;
+ while (*c) {
+ if (*c == '.') {
+ c++;
+ return (int) (c - s);
+ } else if (*c == '(') {
+ nparen = 1;
+ c++;
+ while (*c) {
+ if (*c == '(')
+ nparen++;
+ if (*c == ')') {
+ nparen--;
+ if (nparen == 0)
+ break;
+ }
+ c++;
+ }
+ }
+ if (*c)
+ c++;
+ }
+ return (int) (c - s);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_del_element()
+ *
+ * Deletes one type element from the type.
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_del_element(SwigType *t) {
+ int sz = element_size(Char(t));
+ Delslice(t, 0, sz);
+ return t;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_pop()
+ *
+ * Pop one type element off the type.
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_pop(SwigType *t) {
+ SwigType *result;
+ char *c;
+ int sz;
+
+ c = Char(t);
+ if (!*c)
+ return 0;
+
+ sz = element_size(c);
+ result = NewStringWithSize(c, sz);
+ Delslice(t, 0, sz);
+ c = Char(t);
+ if (*c == '.') {
+ Delitem(t, 0);
+ }
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_parm()
+ *
+ * Returns the parameter of an operator as a string
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_parm(SwigType *t) {
+ char *start, *c;
+ int nparens = 0;
+
+ c = Char(t);
+ while (*c && (*c != '(') && (*c != '.'))
+ c++;
+ if (!*c || (*c == '.'))
+ return 0;
+ c++;
+ start = c;
+ while (*c) {
+ if (*c == ')') {
+ if (nparens == 0)
+ break;
+ nparens--;
+ } else if (*c == '(') {
+ nparens++;
+ }
+ c++;
+ }
+ return NewStringWithSize(start, (int) (c - start));
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_split()
+ *
+ * Splits a type into it's component parts and returns a list of string.
+ * ----------------------------------------------------------------------------- */
+
+List *SwigType_split(const SwigType *t) {
+ String *item;
+ List *list;
+ char *c;
+ int len;
+
+ c = Char(t);
+ list = NewList();
+ while (*c) {
+ len = element_size(c);
+ item = NewStringWithSize(c, len);
+ Append(list, item);
+ Delete(item);
+ c = c + len;
+ if (*c == '.')
+ c++;
+ }
+ return list;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_parmlist()
+ *
+ * Splits a comma separated list of parameters into its component parts
+ * The input is expected to contain the parameter list within () brackets
+ * Returns 0 if no argument list in the input, ie there are no round brackets ()
+ * Returns an empty List if there are no parameters in the () brackets
+ * For example:
+ *
+ * Foo(std::string,p.f().Bar<(int,double)>)
+ *
+ * returns 2 elements in the list:
+ * std::string
+ * p.f().Bar<(int,double)>
+ * ----------------------------------------------------------------------------- */
+
+List *SwigType_parmlist(const String *p) {
+ String *item = 0;
+ List *list;
+ char *c;
+ char *itemstart;
+ int size;
+
+ assert(p);
+ c = Char(p);
+ while (*c && (*c != '(') && (*c != '.'))
+ c++;
+ if (!*c)
+ return 0;
+ assert(*c != '.'); /* p is expected to contain sub elements of a type */
+ c++;
+ list = NewList();
+ itemstart = c;
+ while (*c) {
+ if (*c == ',') {
+ size = (int) (c - itemstart);
+ item = NewStringWithSize(itemstart, size);
+ Append(list, item);
+ Delete(item);
+ itemstart = c + 1;
+ } else if (*c == '(') {
+ int nparens = 1;
+ c++;
+ while (*c) {
+ if (*c == '(')
+ nparens++;
+ if (*c == ')') {
+ nparens--;
+ if (nparens == 0)
+ break;
+ }
+ c++;
+ }
+ } else if (*c == ')') {
+ break;
+ }
+ if (*c)
+ c++;
+ }
+ size = (int) (c - itemstart);
+ if (size > 0) {
+ item = NewStringWithSize(itemstart, size);
+ Append(list, item);
+ }
+ Delete(item);
+ return list;
+}
+
+/* -----------------------------------------------------------------------------
+ * Pointers
+ *
+ * SwigType_add_pointer()
+ * SwigType_del_pointer()
+ * SwigType_ispointer()
+ *
+ * Add, remove, and test if a type is a pointer. The deletion and query
+ * functions take into account qualifiers (if any).
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_add_pointer(SwigType *t) {
+ Insert(t, 0, "p.");
+ return t;
+}
+
+SwigType *SwigType_del_pointer(SwigType *t) {
+ char *c, *s;
+ c = Char(t);
+ s = c;
+ /* Skip qualifiers, if any */
+ if (strncmp(c, "q(", 2) == 0) {
+ c = strchr(c, '.');
+ assert(c);
+ c++;
+ }
+ if (strncmp(c, "p.", 2)) {
+ printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n");
+ abort();
+ }
+ Delslice(t, 0, (c - s) + 2);
+ return t;
+}
+
+int SwigType_ispointer(SwigType *t) {
+ char *c;
+ if (!t)
+ return 0;
+ c = Char(t);
+ /* Skip qualifiers, if any */
+ if (strncmp(c, "q(", 2) == 0) {
+ c = strchr(c, '.');
+ if (!c)
+ return 0;
+ c++;
+ }
+ if (strncmp(c, "p.", 2) == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * References
+ *
+ * SwigType_add_reference()
+ * SwigType_del_reference()
+ * SwigType_isreference()
+ *
+ * Add, remove, and test if a type is a reference. The deletion and query
+ * functions take into account qualifiers (if any).
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_add_reference(SwigType *t) {
+ Insert(t, 0, "r.");
+ return t;
+}
+
+SwigType *SwigType_del_reference(SwigType *t) {
+ char *c = Char(t);
+ int check = strncmp(c, "r.", 2);
+ assert(check == 0);
+ Delslice(t, 0, 2);
+ return t;
+}
+
+int SwigType_isreference(SwigType *t) {
+ char *c;
+ if (!t)
+ return 0;
+ c = Char(t);
+ if (strncmp(c, "r.", 2) == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Qualifiers
+ *
+ * SwigType_add_qualifier()
+ * SwigType_del_qualifier()
+ * SwigType_is_qualifier()
+ *
+ * Adds type qualifiers like "const" and "volatile". When multiple qualifiers
+ * are added to a type, they are combined together into a single qualifier.
+ * Repeated qualifications have no effect. Moreover, the order of qualifications
+ * is alphabetical---meaning that "const volatile" and "volatile const" are
+ * stored in exactly the same way as "q(const volatile)".
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) {
+ char temp[256], newq[256];
+ int sz, added = 0;
+ char *q, *cqual;
+
+ char *c = Char(t);
+ cqual = Char(qual);
+
+ if (!(strncmp(c, "q(", 2) == 0)) {
+ sprintf(temp, "q(%s).", cqual);
+ Insert(t, 0, temp);
+ return t;
+ }
+
+ /* The type already has a qualifier on it. In this case, we first check to
+ see if the qualifier is already specified. In that case do nothing.
+ If it is a new qualifier, we add it to the qualifier list in alphabetical
+ order */
+
+ sz = element_size(c);
+ strncpy(temp, c, (sz < 256) ? sz : 256);
+
+ if (strstr(temp, cqual)) {
+ /* Qualifier already added */
+ return t;
+ }
+
+ /* Add the qualifier to the existing list. */
+
+ strcpy(newq, "q(");
+ q = temp + 2;
+ q = strtok(q, " ).");
+ while (q) {
+ if (strcmp(cqual, q) < 0) {
+ /* New qualifier is less that current qualifier. We need to insert it */
+ strcat(newq, cqual);
+ strcat(newq, " ");
+ strcat(newq, q);
+ added = 1;
+ } else {
+ strcat(newq, q);
+ }
+ q = strtok(NULL, " ).");
+ if (q) {
+ strcat(newq, " ");
+ }
+ }
+ if (!added) {
+ strcat(newq, " ");
+ strcat(newq, cqual);
+ }
+ strcat(newq, ").");
+ Delslice(t, 0, sz);
+ Insert(t, 0, newq);
+ return t;
+}
+
+SwigType *SwigType_del_qualifier(SwigType *t) {
+ char *c = Char(t);
+ int check = strncmp(c, "q(", 2);
+ assert(check == 0);
+ Delslice(t, 0, element_size(c));
+ return t;
+}
+
+int SwigType_isqualifier(SwigType *t) {
+ char *c;
+ if (!t)
+ return 0;
+ c = Char(t);
+ if (strncmp(c, "q(", 2) == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Function Pointers
+ * ----------------------------------------------------------------------------- */
+
+int SwigType_isfunctionpointer(SwigType *t) {
+ char *c;
+ if (!t)
+ return 0;
+ c = Char(t);
+ if (strncmp(c, "p.f(", 4) == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_functionpointer_decompose
+ *
+ * Decompose the function pointer into the parameter list and the return type
+ * t - input and on completion contains the return type
+ * returns the function's parameters
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_functionpointer_decompose(SwigType *t) {
+ String *p;
+ assert(SwigType_isfunctionpointer(t));
+ p = SwigType_pop(t);
+ Delete(p);
+ p = SwigType_pop(t);
+ return p;
+}
+
+/* -----------------------------------------------------------------------------
+ * Member Pointers
+ *
+ * SwigType_add_memberpointer()
+ * SwigType_del_memberpointer()
+ * SwigType_ismemberpointer()
+ *
+ * Add, remove, and test for C++ pointer to members.
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_add_memberpointer(SwigType *t, const_String_or_char_ptr name) {
+ String *temp = NewStringf("m(%s).", name);
+ Insert(t, 0, temp);
+ Delete(temp);
+ return t;
+}
+
+SwigType *SwigType_del_memberpointer(SwigType *t) {
+ char *c = Char(t);
+ int check = strncmp(c, "m(", 2);
+ assert(check == 0);
+ Delslice(t, 0, element_size(c));
+ return t;
+}
+
+int SwigType_ismemberpointer(SwigType *t) {
+ char *c;
+ if (!t)
+ return 0;
+ c = Char(t);
+ if (strncmp(c, "m(", 2) == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Arrays
+ *
+ * SwigType_add_array()
+ * SwigType_del_array()
+ * SwigType_isarray()
+ *
+ * Utility functions:
+ *
+ * SwigType_array_ndim() - Calculate number of array dimensions.
+ * SwigType_array_getdim() - Get array dimension
+ * SwigType_array_setdim() - Set array dimension
+ * SwigType_array_type() - Return array type
+ * SwigType_pop_arrays() - Remove all arrays
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size) {
+ char temp[512];
+ strcpy(temp, "a(");
+ strcat(temp, Char(size));
+ strcat(temp, ").");
+ Insert(t, 0, temp);
+ return t;
+}
+
+SwigType *SwigType_del_array(SwigType *t) {
+ char *c = Char(t);
+ int check = strncmp(c, "a(", 2);
+ assert(check == 0);
+ Delslice(t, 0, element_size(c));
+ return t;
+}
+
+int SwigType_isarray(SwigType *t) {
+ char *c;
+ if (!t)
+ return 0;
+ c = Char(t);
+ if (strncmp(c, "a(", 2) == 0) {
+ return 1;
+ }
+ return 0;
+}
+/*
+ * SwigType_prefix_is_simple_1D_array
+ *
+ * Determine if the type is a 1D array type that is treated as a pointer within SWIG
+ * eg Foo[], Foo[3] return true, but Foo[3][3], Foo*[], Foo*[3], Foo**[] return false
+ */
+int SwigType_prefix_is_simple_1D_array(SwigType *t) {
+ char *c = Char(t);
+
+ if (c && (strncmp(c, "a(", 2) == 0)) {
+ c = strchr(c, '.');
+ c++;
+ return (*c == 0);
+ }
+ return 0;
+}
+
+
+/* Remove all arrays */
+SwigType *SwigType_pop_arrays(SwigType *t) {
+ String *ta;
+ assert(SwigType_isarray(t));
+ ta = NewStringEmpty();
+ while (SwigType_isarray(t)) {
+ SwigType *td = SwigType_pop(t);
+ Append(ta, td);
+ Delete(td);
+ }
+ return ta;
+}
+
+/* Return number of array dimensions */
+int SwigType_array_ndim(SwigType *t) {
+ int ndim = 0;
+ char *c = Char(t);
+
+ while (c && (strncmp(c, "a(", 2) == 0)) {
+ c = strchr(c, '.');
+ c++;
+ ndim++;
+ }
+ return ndim;
+}
+
+/* Get nth array dimension */
+String *SwigType_array_getdim(SwigType *t, int n) {
+ char *c = Char(t);
+ while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) {
+ c = strchr(c, '.');
+ c++;
+ n--;
+ }
+ if (n == 0) {
+ String *dim = SwigType_parm(c);
+ if (SwigType_istemplate(dim)) {
+ String *ndim = SwigType_namestr(dim);
+ Delete(dim);
+ dim = ndim;
+ }
+
+ return dim;
+ }
+
+ return 0;
+}
+
+/* Replace nth array dimension */
+void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep) {
+ String *result = 0;
+ char temp;
+ char *start;
+ char *c = Char(t);
+
+ start = c;
+ if (strncmp(c, "a(", 2))
+ abort();
+
+ while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) {
+ c = strchr(c, '.');
+ c++;
+ n--;
+ }
+ if (n == 0) {
+ temp = *c;
+ *c = 0;
+ result = NewString(start);
+ Printf(result, "a(%s)", rep);
+ *c = temp;
+ c = strchr(c, '.');
+ Append(result, c);
+ }
+ Clear(t);
+ Append(t, result);
+ Delete(result);
+}
+
+/* Return 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;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Functions
+ *
+ * SwigType_add_function()
+ * SwigType_del_function()
+ * SwigType_isfunction()
+ * SwigType_pop_function()
+ *
+ * Add, remove, and test for function types.
+ * ----------------------------------------------------------------------------- */
+
+/* Returns the function type, t, constructed from the parameters, parms */
+SwigType *SwigType_add_function(SwigType *t, ParmList *parms) {
+ String *pstr;
+ Parm *p;
+
+ Insert(t, 0, ").");
+ pstr = NewString("f(");
+ p = parms;
+ for (p = parms; p; p = nextSibling(p)) {
+ if (p != parms)
+ Putc(',', pstr);
+ Append(pstr, Getattr(p, "type"));
+ }
+ Insert(t, 0, pstr);
+ Delete(pstr);
+ return t;
+}
+
+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;
+}
+
+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;
+ }
+ return 0;
+}
+
+ParmList *SwigType_function_parms(SwigType *t) {
+ List *l = SwigType_parmlist(t);
+ Hash *p, *pp = 0, *firstp = 0;
+ Iterator o;
+
+ for (o = First(l); o.item; o = Next(o)) {
+ p = NewParm(o.item, 0);
+ if (!firstp)
+ firstp = p;
+ if (pp) {
+ set_nextSibling(pp, p);
+ Delete(p);
+ }
+ pp = p;
+ }
+ Delete(l);
+ return firstp;
+}
+
+int SwigType_isvarargs(const SwigType *t) {
+ if (Strcmp(t, "v(...)") == 0)
+ return 1;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Templates
+ *
+ * SwigType_add_template()
+ *
+ * Template handling.
+ * ----------------------------------------------------------------------------- */
+
+/* -----------------------------------------------------------------------------
+ * 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)>"
+ * ----------------------------------------------------------------------------- */
+
+SwigType *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, ")>");
+ return t;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_templateprefix()
+ *
+ * Returns the prefix before the first template definition.
+ * For example:
+ *
+ * Foo<(p.int)>::bar
+ *
+ * returns "Foo"
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_templateprefix(const SwigType *t) {
+ const char *s = Char(t);
+ const char *c = strstr(s, "<(");
+ return c ? NewStringWithSize(s, c - s) : NewString(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) {
+ const 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 NewStringEmpty();
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_templateargs()
+ *
+ * Returns the template arguments
+ * For example:
+ *
+ * Foo<(p.int)>::bar
+ *
+ * returns "<(p.int)>"
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_templateargs(const SwigType *t) {
+ const char *c;
+ const char *start;
+ c = Char(t);
+ while (*c) {
+ if ((*c == '<') && (*(c + 1) == '(')) {
+ int nest = 1;
+ start = c;
+ c++;
+ while (*c && nest) {
+ if (*c == '<')
+ nest++;
+ if (*c == '>')
+ nest--;
+ c++;
+ }
+ return NewStringWithSize(start, c - start);
+ }
+ c++;
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_istemplate()
+ *
+ * Tests a type to see if it includes template parameters
+ * ----------------------------------------------------------------------------- */
+
+int SwigType_istemplate(const SwigType *t) {
+ char *ct = Char(t);
+ ct = strstr(ct, "<(");
+ if (ct && (strstr(ct + 2, ")>")))
+ return 1;
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_base()
+ *
+ * This function returns the base of a type. For example, if you have a
+ * type "p.p.int", the function would return "int".
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_base(const SwigType *t) {
+ char *c;
+ char *lastop = 0;
+ c = Char(t);
+
+ lastop = c;
+
+ /* Search for the last type constructor separator '.' */
+ while (*c) {
+ if (*c == '.') {
+ if (*(c + 1)) {
+ lastop = c + 1;
+ }
+ c++;
+ continue;
+ }
+ if (*c == '<') {
+ /* Skip over template---it's part of the base name */
+ int ntemp = 1;
+ c++;
+ while ((*c) && (ntemp > 0)) {
+ if (*c == '>')
+ ntemp--;
+ else if (*c == '<')
+ ntemp++;
+ c++;
+ }
+ if (ntemp)
+ break;
+ continue;
+ }
+ if (*c == '(') {
+ /* Skip over params */
+ int nparen = 1;
+ c++;
+ while ((*c) && (nparen > 0)) {
+ if (*c == '(')
+ nparen++;
+ else if (*c == ')')
+ nparen--;
+ c++;
+ }
+ if (nparen)
+ break;
+ continue;
+ }
+ c++;
+ }
+ return NewString(lastop);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_prefix()
+ *
+ * Returns the prefix of a datatype. For example, the prefix of the
+ * type "p.p.int" is "p.p.".
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_prefix(const SwigType *t) {
+ char *c, *d;
+ String *r = 0;
+
+ 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;
+ r = NewString(c);
+ *(d + 1) = t;
+ return r;
+ }
+ }
+ return NewStringEmpty();
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_strip_qualifiers()
+ *
+ * Strip all qualifiers from a type and return a new type
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_strip_qualifiers(SwigType *t) {
+ static Hash *memoize_stripped = 0;
+ SwigType *r;
+ List *l;
+ Iterator ei;
+
+ if (!memoize_stripped)
+ memoize_stripped = NewHash();
+ r = Getattr(memoize_stripped, t);
+ if (r)
+ return Copy(r);
+
+ l = SwigType_split(t);
+ r = NewStringEmpty();
+
+ for (ei = First(l); ei.item; ei = Next(ei)) {
+ if (SwigType_isqualifier(ei.item))
+ continue;
+ Append(r, ei.item);
+ }
+ Delete(l);
+ {
+ String *key, *value;
+ key = Copy(t);
+ value = Copy(r);
+ Setattr(memoize_stripped, key, value);
+ Delete(key);
+ Delete(value);
+ }
+ return r;
+}
diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c
new file mode 100644
index 0000000..5778c45
--- /dev/null
+++ b/Source/Swig/typesys.c
@@ -0,0 +1,2074 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * 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.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_typesys_c[] = "$Id: typesys.c 11097 2009-01-30 10:27:37Z bhy $";
+
+#include "swig.h"
+#include "cparse.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 */
+#define SWIG_TYPEDEF_RESOLVE_CACHE
+static Hash *typedef_resolve_cache = 0;
+static Hash *typedef_all_cache = 0;
+static Hash *typedef_qualified_cache = 0;
+
+static Typetab *SwigType_find_scope(Typetab *s, String *nameprefix);
+
+/* common attribute keys, to avoid calling find_key all the times */
+
+/*
+ Enable this one if your language fully support SwigValueWrapper<T>.
+
+ Leaving at '0' keeps the old swig behavior, which is not
+ always safe, but is well known.
+
+ Setting at '1' activates the new scheme, which is always safe but
+ it requires all the typemaps to be ready for that.
+
+*/
+static int value_wrapper_mode = 0;
+int Swig_value_wrapper_mode(int mode) {
+ value_wrapper_mode = mode;
+ return mode;
+}
+
+
+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, const_String_or_char_ptr name) {
+ 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(const_String_or_char_ptr 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);
+ Delete(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(const_String_or_char_ptr 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);
+ Delete(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);
+ Delete(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 *t, *old = current_scope;
+ t = Getattr(current_scope, "parent");
+ if (!t)
+ t = global_scope;
+ current_scope = t;
+ current_typetab = Getattr(t, "typetab");
+ current_symtab = Getattr(t, "symtab");
+ flush_cache();
+ return old;
+}
+
+/* -----------------------------------------------------------------------------
+ * 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) {
+ Hash *ttab;
+ Iterator i, j;
+
+ for (i = First(scopes); i.key; i = Next(i)) {
+ t = i.item;
+ ttab = Getattr(i.item, "typetab");
+
+ Printf(stdout, "Type scope '%s' (%x)\n", i.key, i.item);
+ {
+ List *inherit = Getattr(i.item, "inherit");
+ if (inherit) {
+ Iterator j;
+ for (j = First(inherit); j.item; j = Next(j)) {
+ Printf(stdout, " Inherits from '%s' (%x)\n", Getattr(j.item, "qname"), j.item);
+ }
+ }
+ }
+ Printf(stdout, "-------------------------------------------------------------\n");
+ for (j = First(ttab); j.key; j = Next(j)) {
+ Printf(stdout, "%40s -> %s\n", j.key, j.item);
+ }
+ }
+}
+
+static 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;
+}
+
+/* -----------------------------------------------------------------------------
+ * 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.
+ * Internal function.
+ * ----------------------------------------------------------------------------- */
+
+static Typetab *resolved_scope = 0;
+
+/* Internal function */
+
+static SwigType *_typedef_resolve(Typetab *s, String *base, int look_parent) {
+ Hash *ttab;
+ SwigType *type = 0;
+ List *inherit;
+ Typetab *parent;
+
+ /* if (!s) return 0; *//* now is checked bellow */
+ /* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */
+
+ if (!Getmark(s)) {
+ Setmark(s, 1);
+
+ ttab = Getattr(s, "typetab");
+ type = Getattr(ttab, base);
+ if (type) {
+ resolved_scope = s;
+ Setmark(s, 0);
+ } else {
+ /* 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, 0);
+ if (type) {
+ Setmark(s, 0);
+ break;
+ }
+ }
+ }
+ if (!type) {
+ /* Hmmm. Not found in my scope. check parent */
+ if (look_parent) {
+ parent = Getattr(s, "parent");
+ type = parent ? _typedef_resolve(parent, base, 1) : 0;
+ }
+ }
+ Setmark(s, 0);
+ }
+ }
+ return type;
+}
+
+static SwigType *typedef_resolve(Typetab *s, String *base) {
+ return _typedef_resolve(s, base, 1);
+}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_typedef_resolve()
+ * ----------------------------------------------------------------------------- */
+
+/* #define SWIG_DEBUG */
+SwigType *SwigType_typedef_resolve(const SwigType *t) {
+ String *base;
+ String *type = 0;
+ String *r = 0;
+ Typetab *s;
+ Hash *ttab;
+ String *namebase = 0;
+ String *nameprefix = 0;
+ int newtype = 0;
+
+ /*
+ if (!noscope) {
+ noscope = NewStringEmpty();
+ }
+ */
+
+ resolved_scope = 0;
+
+#ifdef SWIG_TYPEDEF_RESOLVE_CACHE
+ if (!typedef_resolve_cache) {
+ typedef_resolve_cache = NewHash();
+ }
+ r = Getattr(typedef_resolve_cache, t);
+ if (r) {
+ resolved_scope = Getmeta(r, "scope");
+ return Copy(r);
+ }
+#endif
+
+ base = SwigType_base(t);
+
+#ifdef SWIG_DEBUG
+ Printf(stdout, "base = '%s' t='%s'\n", base, t);
+#endif
+
+ if (SwigType_issimple(base)) {
+ s = current_scope;
+ ttab = current_typetab;
+ if (strncmp(Char(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. */
+ Swig_scopename_split(base, &nameprefix, &namebase);
+#ifdef SWIG_DEBUG
+ Printf(stdout, "nameprefix = '%s'\n", nameprefix);
+#endif
+ 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(namebase);
+ Delete(nameprefix);
+ r = 0;
+ goto return_result;
+ }
+ /* Try to locate the name starting in the scope */
+#ifdef SWIG_DEBUG
+ Printf(stdout, "namebase = '%s'\n", namebase);
+#endif
+ type = typedef_resolve(s, namebase);
+ if (type) {
+ /* we need to look for the resolved type, this will also
+ fix the resolved_scope if 'type' and 'namebase' are
+ declared in different scopes */
+ String *rtype = 0;
+ rtype = typedef_resolve(resolved_scope, type);
+ if (rtype)
+ type = rtype;
+ }
+#ifdef SWIG_DEBUG
+ Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type);
+#endif
+ if ((type) && (!Swig_scopename_check(type)) && resolved_scope) {
+ 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);
+#ifdef SWIG_DEBUG
+ Printf(stdout, "qual %s \n", type);
+#endif
+ 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 && (Equal(base, type))) {
+ if (newtype)
+ Delete(type);
+ Delete(base);
+ Delete(namebase);
+ Delete(nameprefix);
+ 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);
+ newtype = 1;
+ 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);
+ Delete(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(");
+ newtype = 1;
+ 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);
+ Delete(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);
+ newtype = 1;
+ Delete(rt);
+ }
+ Delete(mtype);
+ } else {
+ type = 0;
+ }
+ }
+ r = SwigType_prefix(t);
+ if (!type) {
+ if (r && Len(r)) {
+ char *cr = Char(r);
+ if ((strstr(cr, "f(") || (strstr(cr, "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:
+#ifdef SWIG_TYPEDEF_RESOLVE_CACHE
+ {
+ String *key = NewString(t);
+ if (r) {
+ SwigType *r1;
+ Setattr(typedef_resolve_cache, key, r);
+ Setmeta(r, "scope", resolved_scope);
+ r1 = Copy(r);
+ Delete(r);
+ r = r1;
+ }
+ Delete(key);
+ }
+#endif
+ 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;
+
+ /* Check to see if the typedef resolve has been done before by checking the cache */
+ if (!typedef_all_cache) {
+ typedef_all_cache = NewHash();
+ }
+ r = Getattr(typedef_all_cache, t);
+ if (r) {
+ return Copy(r);
+ }
+
+ /* Recursively resolve the typedef */
+ r = NewString(t);
+ while ((n = SwigType_typedef_resolve(r))) {
+ Delete(r);
+ r = n;
+ }
+
+ /* Add the typedef to the cache for next time it is looked up */
+ {
+ String *key;
+ SwigType *rr = Copy(r);
+ key = NewString(t);
+ Setattr(typedef_all_cache, key, rr);
+ Delete(key);
+ Delete(rr);
+ }
+ return r;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_typedef_qualified()
+ *
+ * Given a type declaration, this function tries to fully qualify it according to
+ * typedef scope rules.
+ * Inconsistency to be fixed: ::Foo returns ::Foo, whereas ::Foo * returns Foo *
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_typedef_qualified(SwigType *t) {
+ List *elements;
+ String *result;
+ int i, len;
+
+ if (strncmp(Char(t), "::", 2) == 0) {
+ return Copy(t);
+ }
+
+ if (!typedef_qualified_cache)
+ typedef_qualified_cache = NewHash();
+ result = Getattr(typedef_qualified_cache, t);
+ if (result) {
+ String *rc = Copy(result);
+ return rc;
+ }
+
+ result = NewStringEmpty();
+ elements = SwigType_split(t);
+ len = Len(elements);
+ for (i = 0; i < len; i++) {
+ String *ty = 0;
+ String *e = Getitem(elements, i);
+ if (SwigType_issimple(e)) {
+ if (!SwigType_istemplate(e)) {
+ String *isenum = 0;
+ if (SwigType_isenum(e)) {
+ isenum = NewString("enum ");
+ ty = NewString(Char(e) + 5);
+ e = ty;
+ }
+ 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);
+ }
+ } else {
+ if (Swig_scopename_check(e)) {
+ String *qlast;
+ String *qname;
+ Swig_scopename_split(e, &qname, &qlast);
+ if (qname) {
+ String *tqname = SwigType_typedef_qualified(qname);
+ Clear(e);
+ Printf(e, "%s::%s", tqname, qlast);
+ Delete(qname);
+ Delete(tqname);
+ }
+ Delete(qlast);
+
+ /* Automatic template instantiation might go here??? */
+ } else {
+ /* It's a bare name. It's entirely possible, that the
+ name is part of a namespace. We'll check this by unrolling
+ out of the current scope */
+
+ Typetab *cs = current_scope;
+ while (cs) {
+ String *qs = SwigType_scope_name(cs);
+ if (Len(qs)) {
+ Append(qs, "::");
+ }
+ Append(qs, e);
+ if (Getattr(scopes, qs)) {
+ Clear(e);
+ Append(e, qs);
+ Delete(qs);
+ break;
+ }
+ Delete(qs);
+ cs = Getattr(cs, "parent");
+ }
+ }
+ }
+ if (isenum) {
+ Insert(e, 0, isenum);
+ Delete(isenum);
+ }
+ } else {
+ /* Template. We need to qualify template parameters as well as the template itself */
+ String *tprefix, *qprefix;
+ String *tsuffix;
+ Iterator pi;
+ Parm *p;
+ List *parms;
+ ty = Swig_symbol_template_deftype(e, current_symtab);
+ e = ty;
+ parms = SwigType_parmlist(e);
+ tprefix = SwigType_templateprefix(e);
+ tsuffix = SwigType_templatesuffix(e);
+ qprefix = SwigType_typedef_qualified(tprefix);
+ Append(qprefix, "<(");
+ pi = First(parms);
+ while ((p = pi.item)) {
+ String *qt = SwigType_typedef_qualified(p);
+ if (Equal(qt, p)) { /* && (!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) {
+ char *ntype = Char(nodeType(n));
+ if (strcmp(ntype, "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 {
+ Delete(qn);
+ break;
+ }
+ } else if ((strcmp(ntype, "cdecl") == 0) && (Getattr(n, "value"))) {
+ Delete(value);
+ value = Copy(Getattr(n, "value"));
+ continue;
+ }
+ }
+ break;
+ }
+ Append(qprefix, value);
+ Delete(value);
+ } else {
+ Append(qprefix, p);
+ }
+ } else {
+ Append(qprefix, qt);
+ }
+ Delete(qt);
+ pi = Next(pi);
+ if (pi.item) {
+ Append(qprefix, ",");
+ }
+ }
+ Append(qprefix, ")>");
+ Append(qprefix, tsuffix);
+ Delete(tsuffix);
+ Clear(e);
+ Append(e, qprefix);
+ Delete(tprefix);
+ Delete(qprefix);
+ Delete(parms);
+ }
+ if (strncmp(Char(e), "::", 2) == 0) {
+ Delitem(e, 0);
+ Delitem(e, 0);
+ }
+ Append(result, e);
+ Delete(ty);
+ } else if (SwigType_isfunction(e)) {
+ List *parms = SwigType_parmlist(e);
+ String *s = NewString("f(");
+ Iterator pi;
+ pi = First(parms);
+ while (pi.item) {
+ String *pq = SwigType_typedef_qualified(pi.item);
+ Append(s, pq);
+ Delete(pq);
+ pi = Next(pi);
+ if (pi.item) {
+ Append(s, ",");
+ }
+ }
+ Append(s, ").");
+ Append(result, s);
+ Delete(s);
+ Delete(parms);
+ } 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);
+ {
+ String *key, *cresult;
+ key = NewString(t);
+ cresult = NewString(result);
+ Setattr(typedef_qualified_cache, key, cresult);
+ Delete(key);
+ Delete(cresult);
+ }
+ 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(const_String_or_char_ptr 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);
+ /* Printf(stdout,"defined_name = '%s'\n", defined_name); */
+ tt = SwigType_find_scope(current_scope, defined_name);
+ }
+ }
+ if (td)
+ Delete(td);
+
+
+ /* 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 its own scope. We need to 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 (!isclass && SwigType_istemplate(qtys)) {
+ String *tp = SwigType_templateprefix(qtys);
+ if (Strcmp(tp, t) != 0) {
+ 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, "long double") == 0)
+ return T_LONGDOUBLE;
+ if (!cparse_cplusplus && (strcmp(c, "float complex") == 0))
+ return T_FLTCPLX;
+ if (!cparse_cplusplus && (strcmp(c, "double complex") == 0))
+ return T_DBLCPLX;
+ if (!cparse_cplusplus && (strcmp(c, "complex") == 0))
+ return T_COMPLEX;
+ 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;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_alttype()
+ *
+ * Returns the alternative value type needed in C++ for class value
+ * types. When swig is not sure about using a plain $ltype value,
+ * since the class doesn't have a default constructor, or it can't be
+ * assigned, you will get back 'SwigValueWrapper<type >'.
+ *
+ * This is the default behavior unless:
+ *
+ * 1.- swig detects a default_constructor and 'setallocate:default_constructor'
+ * attribute.
+ *
+ * 2.- swig doesn't mark 'type' as non-assignable.
+ *
+ * 3.- the user specify that the value wrapper is not needed by using
+ * the %feature("novaluewrapper"), in that case the user need to type
+ *
+ * %feature("novaluewrapper") MyOpaqueClass;
+ * class MyOpaqueClass;
+ *
+ * Users can also force the use of the value wrapper by using the
+ * %feature("valuewrapper").
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_alttype(SwigType *t, int local_tmap) {
+ Node *n;
+ SwigType *w = 0;
+ int use_wrapper = 0;
+ SwigType *td = 0;
+
+ if (!cparse_cplusplus)
+ return 0;
+
+ if (value_wrapper_mode == 0) {
+ /* old partial use of SwigValueTypes, it can fail for opaque types */
+ if (local_tmap)
+ return 0;
+ if (SwigType_isclass(t)) {
+ SwigType *ftd = SwigType_typedef_resolve_all(t);
+ td = SwigType_strip_qualifiers(ftd);
+ Delete(ftd);
+ n = Swig_symbol_clookup(td, 0);
+ if (n) {
+ if (GetFlag(n, "feature:valuewrapper")) {
+ use_wrapper = 1;
+ } else {
+ if (Checkattr(n, "nodeType", "class")
+ && (!Getattr(n, "allocate:default_constructor")
+ || (Getattr(n, "allocate:noassign")))) {
+ use_wrapper = !GetFlag(n, "feature:novaluewrapper") || GetFlag(n, "feature:nodefault");
+ }
+ }
+ } else {
+ if (SwigType_issimple(td) && SwigType_istemplate(td)) {
+ use_wrapper = !n || !GetFlag(n, "feature:novaluewrapper");
+ }
+ }
+ }
+ } else {
+ /* safe use of SwigValueTypes, it can fail with some typemaps */
+ SwigType *ftd = SwigType_typedef_resolve_all(t);
+ td = SwigType_strip_qualifiers(ftd);
+ Delete(ftd);
+ if (SwigType_type(td) == T_USER) {
+ use_wrapper = 1;
+ n = Swig_symbol_clookup(td, 0);
+ if (n) {
+ if ((Checkattr(n, "nodeType", "class")
+ && !Getattr(n, "allocate:noassign")
+ && (Getattr(n, "allocate:default_constructor")))
+ || (GetFlag(n, "feature:novaluewrapper"))) {
+ use_wrapper = GetFlag(n, "feature:valuewrapper");
+ }
+ }
+ }
+ }
+
+ if (use_wrapper) {
+ /* Need a space before the type in case it starts "::" (since the <:
+ * token is a digraph for [ in C++. Also need a space after the
+ * type in case it ends with ">" since then we form the token ">>".
+ */
+ w = NewStringf("SwigValueWrapper< %s >", td);
+ }
+ Delete(td);
+ return w;
+}
+
+/* ----------------------------------------------------------------------------
+ * * * * 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_mangleddata = 0; /* Hash mapping mangled 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_mangleddata(String *mangled, const_String_or_char_ptr clientdata) {
+ if (!r_mangleddata) {
+ r_mangleddata = NewHash();
+ }
+ Setattr(r_mangleddata, mangled, clientdata);
+}
+
+
+void SwigType_remember_clientdata(SwigType *t, const_String_or_char_ptr clientdata) {
+ String *mt;
+ SwigType *lt;
+ Hash *h;
+ SwigType *fr;
+ SwigType *qr;
+ String *tkey;
+ String *cd;
+ Hash *lthash;
+
+ 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;
+ }
+
+ tkey = Copy(t);
+ cd = clientdata ? NewString(clientdata) : NewStringEmpty();
+ Setattr(r_remembered, tkey, cd);
+ Delete(tkey);
+ Delete(cd);
+
+ 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);
+ }
+
+ lthash = Getattr(r_ltype, mt);
+ if (!lthash) {
+ lthash = NewHash();
+ Setattr(r_ltype, mt, lthash);
+ }
+ Setattr(lthash, lt, "1");
+ Delete(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 (t) {
+ char *ct = Char(t);
+ if (strchr(ct, '<') && !(strstr(ct, "<("))) {
+ 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 {
+ String *cstr = NewString(clientdata);
+ Setattr(r_clientdata, fr, cstr);
+ Delete(cstr);
+ }
+ }
+
+ /* If the remembered type is a reference, we also remember the pointer version.
+ This is to prevent odd problems with mixing pointers and references--especially
+ when different functions are using different typenames (via typedef). */
+
+ if (SwigType_isreference(t)) {
+ SwigType *tt = Copy(t);
+ SwigType_del_reference(tt);
+ SwigType_add_pointer(tt);
+ SwigType_remember_clientdata(tt, 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) {
+ Iterator ki;
+ ki = First(mh);
+ while (ki.key) {
+ Hash *rh;
+ if (Getattr(ch, ki.key)) {
+ ki = Next(ki);
+ continue;
+ }
+ Setattr(ch, ki.key, "1");
+ rh = Getattr(r_resolved, ki.key);
+ if (rh) {
+ Iterator rk;
+ rk = First(rh);
+ while (rk.key) {
+ Setattr(h, rk.key, "1");
+ SwigType_equivalent_mangle(rk.key, ch, h);
+ rk = Next(rk);
+ }
+ }
+ ki = Next(ki);
+ }
+ }
+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 *mh;
+ String *clientdata = 0;
+
+ if (r_mangleddata) {
+ clientdata = Getattr(r_mangleddata, ms);
+ if (clientdata)
+ return clientdata;
+ }
+
+ mh = Getattr(r_mangled, ms);
+ if (mh) {
+ Iterator ki;
+ ki = First(mh);
+ while (ki.key) {
+ clientdata = Getattr(r_clientdata, ki.key);
+ if (clientdata)
+ break;
+ ki = Next(ki);
+ }
+ }
+ 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.
+ *
+ * derived - name of derived class
+ * base - name of base class
+ * cast - additional casting code when casting from derived to base
+ * conversioncode - if set, overrides the default code in the function when casting
+ * from derived to base
+ * ----------------------------------------------------------------------------- */
+
+static Hash *subclass = 0;
+static Hash *conversions = 0;
+
+void SwigType_inherit(String *derived, String *base, String *cast, String *conversioncode) {
+ Hash *h;
+ String *dd = 0;
+ String *bb = 0;
+ if (!subclass)
+ subclass = NewHash();
+
+ /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */
+
+ if (SwigType_istemplate(derived)) {
+ String *ty = SwigType_typedef_resolve_all(derived);
+ dd = SwigType_typedef_qualified(ty);
+ derived = dd;
+ Delete(ty);
+ }
+ if (SwigType_istemplate(base)) {
+ String *ty = SwigType_typedef_resolve_all(base);
+ bb = SwigType_typedef_qualified(ty);
+ base = bb;
+ Delete(ty);
+ }
+
+ /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */
+
+ h = Getattr(subclass, base);
+ if (!h) {
+ h = NewHash();
+ Setattr(subclass, base, h);
+ Delete(h);
+ }
+ if (!Getattr(h, derived)) {
+ Hash *c = NewHash();
+ if (cast)
+ Setattr(c, "cast", cast);
+ if (conversioncode)
+ Setattr(c, "convcode", conversioncode);
+ Setattr(h, derived, c);
+ Delete(c);
+ }
+
+ Delete(dd);
+ Delete(bb);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_issubtype()
+ *
+ * Determines if a t1 is a subtype of t2, ie, is t1 derived from 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 *ckey;
+ String *prefix, *base;
+ String *mprefix, *mkey;
+ Hash *sub;
+ Hash *rh;
+ List *rlist;
+ Iterator rk, bk, ck;
+
+ if (!conversions)
+ conversions = NewHash();
+ if (!subclass)
+ subclass = NewHash();
+
+ rk = First(r_resolved);
+ while (rk.key) {
+ /* rkey is a fully qualified type. We strip all of the type constructors off of it just to get the base */
+ base = SwigType_base(rk.key);
+ /* Check to see whether the base is recorded in the subclass table */
+ sub = Getattr(subclass, base);
+ Delete(base);
+ if (!sub) {
+ rk = Next(rk);
+ continue;
+ }
+
+ /* This type has subclasses. We now need to walk through these subtypes and generate pointer converion functions */
+
+ rh = Getattr(r_resolved, rk.key);
+ rlist = NewList();
+ for (ck = First(rh); ck.key; ck = Next(ck)) {
+ Append(rlist, ck.key);
+ }
+ /* Printf(stdout,"rk.key = '%s'\n", rk.key);
+ Printf(stdout,"rh = %x '%s'\n", rh,rh); */
+
+ bk = First(sub);
+ while (bk.key) {
+ prefix = SwigType_prefix(rk.key);
+ Append(prefix, bk.key);
+ /* Printf(stdout,"set %x = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */
+ mprefix = SwigType_manglestr(prefix);
+ Setattr(rh, mprefix, prefix);
+ mkey = SwigType_manglestr(rk.key);
+ ckey = NewStringf("%s+%s", mprefix, mkey);
+ if (!Getattr(conversions, ckey)) {
+ String *convname = NewStringf("%sTo%s", mprefix, mkey);
+ String *lkey = SwigType_lstr(rk.key, 0);
+ String *lprefix = SwigType_lstr(prefix, 0);
+ Hash *subhash = Getattr(sub, bk.key);
+ String *convcode = Getattr(subhash, "convcode");
+ if (convcode) {
+ char *newmemoryused = Strstr(convcode, "newmemory"); /* see if newmemory parameter is used in order to avoid unused parameter warnings */
+ String *fn = Copy(convcode);
+ Replaceall(fn, "$from", "x");
+ Printf(out, "static void *%s(void *x, int *%s) {", convname, newmemoryused ? "newmemory" : "SWIGUNUSEDPARM(newmemory)");
+ Printf(out, "%s", fn);
+ } else {
+ String *cast = Getattr(subhash, "cast");
+ Printf(out, "static void *%s(void *x, int *SWIGUNUSEDPARM(newmemory)) {", convname);
+ Printf(out, "\n return (void *)((%s) ", lkey);
+ if (cast)
+ Printf(out, "%s", cast);
+ Printf(out, " ((%s) x));\n", lprefix);
+ }
+ Printf(out, "}\n");
+ Setattr(conversions, ckey, convname);
+ Delete(ckey);
+ Delete(lkey);
+ Delete(lprefix);
+
+ /* This inserts conversions for typedefs */
+ {
+ Hash *r = Getattr(r_resolved, prefix);
+ if (r) {
+ Iterator rrk;
+ rrk = First(r);
+ while (rrk.key) {
+ Iterator rlk;
+ String *rkeymangle;
+
+ /* Make sure this name equivalence is not due to inheritance */
+ if (Cmp(prefix, Getattr(r, rrk.key)) == 0) {
+ rkeymangle = Copy(mkey);
+ ckey = NewStringf("%s+%s", rrk.key, rkeymangle);
+ if (!Getattr(conversions, ckey)) {
+ Setattr(conversions, ckey, convname);
+ }
+ Delete(ckey);
+ for (rlk = First(rlist); rlk.item; rlk = Next(rlk)) {
+ ckey = NewStringf("%s+%s", rrk.key, rlk.item);
+ 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, rrk.key, rrk.item);
+ }
+ rrk = Next(rrk);
+ }
+ }
+ }
+ Delete(convname);
+ }
+ Delete(prefix);
+ Delete(mprefix);
+ Delete(mkey);
+ bk = Next(bk);
+ }
+ rk = Next(rk);
+ Delete(rlist);
+ }
+}
+
+/* Helper function to sort the mangled list */
+static int SwigType_compare_mangled(const DOH *a, const DOH *b) {
+ return strcmp((char *) Data(a), (char *) Data(b));
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_get_sorted_mangled_list()
+ *
+ * Returns the sorted list of mangled type names that should be exported into the
+ * wrapper file.
+ * ----------------------------------------------------------------------------- */
+List *SwigType_get_sorted_mangled_list() {
+ List *l = Keys(r_mangled);
+ SortList(l, SwigType_compare_mangled);
+ return l;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_type_table()
+ *
+ * Generate the type-table for the type-checker.
+ * ----------------------------------------------------------------------------- */
+
+void SwigType_emit_type_table(File *f_forward, File *f_table) {
+ Iterator ki;
+ String *types, *table, *cast, *cast_init, *cast_temp;
+ Hash *imported_types;
+ List *mangled_list;
+ List *table_list = NewList();
+ 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);
+
+ Printf(stdout, "---r_clientdata---\n");
+ Printf(stdout, "%s\n", r_clientdata);
+
+#endif
+ table = NewStringEmpty();
+ types = NewStringEmpty();
+ cast = NewStringEmpty();
+ cast_init = NewStringEmpty();
+ imported_types = NewHash();
+
+ Printf(table, "static swig_type_info *swig_type_initial[] = {\n");
+ Printf(cast_init, "static swig_cast_info *swig_cast_initial[] = {\n");
+
+ Printf(f_forward, "\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n");
+
+ mangled_list = SwigType_get_sorted_mangled_list();
+ for (ki = First(mangled_list); ki.item; ki = Next(ki)) {
+ List *el;
+ Iterator ei;
+ SwigType *lt;
+ SwigType *rt = 0;
+ String *nt;
+ String *ln;
+ String *rn;
+ const String *cd;
+ Hash *lthash;
+ Iterator ltiter;
+ Hash *nthash;
+
+ cast_temp = NewStringEmpty();
+
+ Printv(types, "static swig_type_info _swigt_", ki.item, " = {", NIL);
+ Append(table_list, ki.item);
+ Printf(cast_temp, "static swig_cast_info _swigc_%s[] = {", ki.item);
+ i++;
+
+ cd = SwigType_clientdata_collect(ki.item);
+ if (!cd)
+ cd = "0";
+
+ lthash = Getattr(r_ltype, ki.item);
+ nt = 0;
+ nthash = NewHash();
+ ltiter = First(lthash);
+ while (ltiter.key) {
+ lt = ltiter.key;
+ rt = SwigType_typedef_resolve_all(lt);
+ /* we save the original type and the fully resolved version */
+ ln = SwigType_lstr(lt, 0);
+ rn = SwigType_lstr(rt, 0);
+ if (Equal(ln, rn)) {
+ Setattr(nthash, ln, "1");
+ } else {
+ Setattr(nthash, rn, "1");
+ Setattr(nthash, ln, "1");
+ }
+ if (SwigType_istemplate(rt)) {
+ String *dt = Swig_symbol_template_deftype(rt, 0);
+ String *dn = SwigType_lstr(dt, 0);
+ if (!Equal(dn, rn) && !Equal(dn, ln)) {
+ Setattr(nthash, dn, "1");
+ }
+ Delete(dt);
+ Delete(dn);
+ }
+
+ ltiter = Next(ltiter);
+ }
+
+ /* now build nt */
+ ltiter = First(nthash);
+ nt = 0;
+ while (ltiter.key) {
+ if (nt) {
+ Printf(nt, "|%s", ltiter.key);
+ } else {
+ nt = NewString(ltiter.key);
+ }
+ ltiter = Next(ltiter);
+ }
+ Delete(nthash);
+
+ Printf(types, "\"%s\", \"%s\", 0, 0, (void*)%s, 0};\n", ki.item, nt, cd);
+
+ el = SwigType_equivalent_mangle(ki.item, 0, 0);
+ for (ei = First(el); ei.item; ei = Next(ei)) {
+ String *ckey;
+ String *conv;
+ ckey = NewStringf("%s+%s", ei.item, ki.item);
+ conv = Getattr(conversions, ckey);
+ if (conv) {
+ Printf(cast_temp, " {&_swigt_%s, %s, 0, 0},", ei.item, conv);
+ } else {
+ Printf(cast_temp, " {&_swigt_%s, 0, 0, 0},", ei.item);
+ }
+ Delete(ckey);
+
+ if (!Getattr(r_mangled, ei.item) && !Getattr(imported_types, ei.item)) {
+ Printf(types, "static swig_type_info _swigt_%s = {\"%s\", 0, 0, 0, 0, 0};\n", ei.item, ei.item);
+ Append(table_list, ei.item);
+
+ Printf(cast, "static swig_cast_info _swigc_%s[] = {{&_swigt_%s, 0, 0, 0},{0, 0, 0, 0}};\n", ei.item, ei.item);
+ i++;
+
+ Setattr(imported_types, ei.item, "1");
+ }
+ }
+ Delete(el);
+ Printf(cast, "%s{0, 0, 0, 0}};\n", cast_temp);
+ Delete(cast_temp);
+ Delete(nt);
+ Delete(rt);
+ }
+ /* print the tables in the proper order */
+ SortList(table_list, SwigType_compare_mangled);
+ i = 0;
+ for (ki = First(table_list); ki.item; ki = Next(ki)) {
+ Printf(f_forward, "#define SWIGTYPE%s swig_types[%d]\n", ki.item, i++);
+ Printf(table, " &_swigt_%s,\n", ki.item);
+ Printf(cast_init, " _swigc_%s,\n", ki.item);
+ }
+ if (i == 0) {
+ /* empty arrays are not allowed by ISO C */
+ Printf(table, " NULL\n");
+ Printf(cast_init, " NULL\n");
+ }
+
+ Delete(table_list);
+
+ Delete(mangled_list);
+
+ Printf(table, "};\n");
+ Printf(cast_init, "};\n");
+ Printf(f_table, "%s\n", types);
+ Printf(f_table, "%s\n", table);
+ Printf(f_table, "%s\n", cast);
+ Printf(f_table, "%s\n", cast_init);
+ Printf(f_table, "\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */\n\n");
+
+ Printf(f_forward, "static swig_type_info *swig_types[%d];\n", i + 1);
+ Printf(f_forward, "static swig_module_info swig_module = {swig_types, %d, 0, 0, 0, 0};\n", i);
+ Printf(f_forward, "#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)\n");
+ Printf(f_forward, "#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)\n");
+ Printf(f_forward, "\n/* -------- TYPES TABLE (END) -------- */\n\n");
+
+ Delete(types);
+ Delete(table);
+ Delete(cast);
+ Delete(cast_init);
+ Delete(imported_types);
+}
diff --git a/Source/Swig/warn.c b/Source/Swig/warn.c
new file mode 100644
index 0000000..8f577eb
--- /dev/null
+++ b/Source/Swig/warn.c
@@ -0,0 +1,34 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * warn.c
+ *
+ * SWIG warning framework. This was added to warn developers about
+ * deprecated APIs and other features.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_warn_c[] = "$Id: warn.c 9604 2006-12-05 21:57:44Z beazley $";
+
+#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
new file mode 100644
index 0000000..e2f3f9c
--- /dev/null
+++ b/Source/Swig/wrapfunc.c
@@ -0,0 +1,518 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * wrapfunc.c
+ *
+ * This file defines a object for creating wrapper functions. Primarily
+ * this is used for convenience since it allows pieces of a wrapper function
+ * to be created in a piecemeal manner.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_wrapfunc_c[] = "$Id: wrapfunc.c 11080 2009-01-24 13:15:51Z bhy $";
+
+#include "swig.h"
+#include <ctype.h>
+
+static int Compact_mode = 0; /* set to 0 on default */
+static int Max_line_size = 128;
+
+/* -----------------------------------------------------------------------------
+ * NewWrapper()
+ *
+ * Create a new wrapper function object.
+ * ----------------------------------------------------------------------------- */
+
+Wrapper *NewWrapper(void) {
+ Wrapper *w;
+ w = (Wrapper *) malloc(sizeof(Wrapper));
+ w->localh = NewHash();
+ w->locals = NewStringEmpty();
+ w->code = NewStringEmpty();
+ w->def = NewStringEmpty();
+ return w;
+}
+
+/* -----------------------------------------------------------------------------
+ * DelWrapper()
+ *
+ * Delete a wrapper function object.
+ * ----------------------------------------------------------------------------- */
+
+void DelWrapper(Wrapper *w) {
+ Delete(w->localh);
+ Delete(w->locals);
+ Delete(w->code);
+ Delete(w->def);
+ free(w);
+}
+
+/* -----------------------------------------------------------------------------
+ * Wrapper_compact_print_mode_set()
+ *
+ * Set compact_mode.
+ * ----------------------------------------------------------------------------- */
+
+void Wrapper_compact_print_mode_set(int flag) {
+ Compact_mode = flag;
+}
+
+/* -----------------------------------------------------------------------------
+ * Wrapper_pretty_print()
+ *
+ * Formats a wrapper function and fixes up the indentation.
+ * ----------------------------------------------------------------------------- */
+
+void Wrapper_pretty_print(String *str, File *f) {
+ String *ts;
+ int level = 0;
+ int c, i;
+ int empty = 1;
+ int indent = 2;
+ int plevel = 0;
+ int label = 0;
+
+ ts = NewStringEmpty();
+ Seek(str, 0, SEEK_SET);
+ while ((c = Getc(str)) != EOF) {
+ if (c == '\"') {
+ Putc(c, ts);
+ while ((c = Getc(str)) != EOF) {
+ if (c == '\\') {
+ Putc(c, ts);
+ c = Getc(str);
+ }
+ Putc(c, ts);
+ if (c == '\"')
+ break;
+ }
+ empty = 0;
+ } else if (c == '\'') {
+ Putc(c, ts);
+ while ((c = Getc(str)) != EOF) {
+ if (c == '\\') {
+ Putc(c, ts);
+ c = Getc(str);
+ }
+ Putc(c, ts);
+ if (c == '\'')
+ break;
+ }
+ empty = 0;
+ } else if (c == ':') {
+ Putc(c, ts);
+ if ((c = Getc(str)) == '\n') {
+ if (!empty && !strchr(Char(ts), '?'))
+ label = 1;
+ }
+ Ungetc(c, str);
+ } else if (c == '(') {
+ Putc(c, ts);
+ plevel += indent;
+ empty = 0;
+ } else if (c == ')') {
+ Putc(c, ts);
+ plevel -= indent;
+ empty = 0;
+ } else if (c == '{') {
+ Putc(c, ts);
+ Putc('\n', ts);
+ for (i = 0; i < level; i++)
+ Putc(' ', f);
+ Printf(f, "%s", ts);
+ Clear(ts);
+ level += indent;
+ while ((c = Getc(str)) != EOF) {
+ if (!isspace(c)) {
+ Ungetc(c, str);
+ break;
+ }
+ }
+ empty = 0;
+ } else if (c == '}') {
+ if (!empty) {
+ Putc('\n', ts);
+ for (i = 0; i < level; i++)
+ Putc(' ', f);
+ Printf(f, "%s", ts);
+ Clear(ts);
+ }
+ level -= indent;
+ Putc(c, ts);
+ empty = 0;
+ } else if (c == '\n') {
+ Putc(c, ts);
+ empty = 0;
+ if (!empty) {
+ int slevel = level;
+ if (label && (slevel >= indent))
+ slevel -= indent;
+ if ((Char(ts))[0] != '#') {
+ for (i = 0; i < slevel; i++)
+ Putc(' ', f);
+ }
+ Printf(f, "%s", ts);
+ for (i = 0; i < plevel; i++)
+ Putc(' ', f);
+ }
+ Clear(ts);
+ label = 0;
+ empty = 1;
+ } else if (c == '/') {
+ empty = 0;
+ 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);
+ empty = 0;
+ }
+ }
+ }
+ if (!empty)
+ Printf(f, "%s", ts);
+ Delete(ts);
+ Printf(f, "\n");
+}
+
+/* -----------------------------------------------------------------------------
+ * Wrapper_compact_print()
+ *
+ * Formats a wrapper function and fixes up the indentation.
+ * Print out in compact format, with Compact enabled.
+ * ----------------------------------------------------------------------------- */
+
+void Wrapper_compact_print(String *str, File *f) {
+ String *ts, *tf; /*temp string & temp file */
+ int level = 0;
+ int c, i;
+ int empty = 1;
+ int indent = 2;
+
+ ts = NewStringEmpty();
+ tf = NewStringEmpty();
+ Seek(str, 0, SEEK_SET);
+
+ while ((c = Getc(str)) != EOF) {
+ if (c == '\"') { /* string 1 */
+ empty = 0;
+ Putc(c, ts);
+ while ((c = Getc(str)) != EOF) {
+ if (c == '\\') {
+ Putc(c, ts);
+ c = Getc(str);
+ }
+ Putc(c, ts);
+ if (c == '\"')
+ break;
+ }
+ } else if (c == '\'') { /* string 2 */
+ empty = 0;
+ Putc(c, ts);
+ while ((c = Getc(str)) != EOF) {
+ if (c == '\\') {
+ Putc(c, ts);
+ c = Getc(str);
+ }
+ Putc(c, ts);
+ if (c == '\'')
+ break;
+ }
+ } else if (c == '{') { /* start of {...} */
+ empty = 0;
+ Putc(c, ts);
+ if (Len(tf) == 0) {
+ for (i = 0; i < level; i++)
+ Putc(' ', tf);
+ } else if ((Len(tf) + Len(ts)) < Max_line_size) {
+ Putc(' ', tf);
+ } else {
+ Putc('\n', tf);
+ Printf(f, "%s", tf);
+ Clear(tf);
+ for (i = 0; i < level; i++)
+ Putc(' ', tf);
+ }
+ Append(tf, ts);
+ Clear(ts);
+ level += indent;
+ while ((c = Getc(str)) != EOF) {
+ if (!isspace(c)) {
+ Ungetc(c, str);
+ break;
+ }
+ }
+ } else if (c == '}') { /* end of {...} */
+ empty = 0;
+ if (Len(tf) == 0) {
+ for (i = 0; i < level; i++)
+ Putc(' ', tf);
+ } else if ((Len(tf) + Len(ts)) < Max_line_size) {
+ Putc(' ', tf);
+ } else {
+ Putc('\n', tf);
+ Printf(f, "%s", tf);
+ Clear(tf);
+ for (i = 0; i < level; i++)
+ Putc(' ', tf);
+ }
+ Append(tf, ts);
+ Putc(c, tf);
+ Clear(ts);
+ level -= indent;
+ } else if (c == '\n') { /* line end */
+ while ((c = Getc(str)) != EOF) {
+ if (!isspace(c))
+ break;
+ }
+ if (c == '#') {
+ Putc('\n', ts);
+ } else if (c == '}') {
+ Putc(' ', ts);
+ } else if ((c != EOF) || (Len(ts) != 0)) {
+ if (Len(tf) == 0) {
+ for (i = 0; i < level; i++)
+ Putc(' ', tf);
+ } else if ((Len(tf) + Len(ts)) < Max_line_size) {
+ Putc(' ', tf);
+ } else {
+ Putc('\n', tf);
+ Printf(f, "%s", tf);
+ Clear(tf);
+ for (i = 0; i < level; i++)
+ Putc(' ', tf);
+ }
+ Append(tf, ts);
+ Clear(ts);
+ }
+ Ungetc(c, str);
+
+ empty = 1;
+ } else if (c == '/') { /* comment */
+ empty = 0;
+ c = Getc(str);
+ if (c != EOF) {
+ if (c == '/') { /* C++ comment */
+ while ((c = Getc(str)) != EOF) {
+ if (c == '\n') {
+ Ungetc(c, str);
+ break;
+ }
+ }
+ } else if (c == '*') { /* C comment */
+ int endstar = 0;
+ while ((c = Getc(str)) != EOF) {
+ if (endstar && c == '/') { /* end of C comment */
+ break;
+ }
+ endstar = (c == '*');
+ }
+ } else {
+ Putc('/', ts);
+ Putc(c, ts);
+ }
+ }
+ } else if (c == '#') { /* Preprocessor line */
+ Putc('#', ts);
+ while ((c = Getc(str)) != EOF) {
+ Putc(c, ts);
+ if (c == '\\') { /* Continued line of the same PP */
+ c = Getc(str);
+ if (c == '\n')
+ Putc(c, ts);
+ else
+ Ungetc(c, str);
+ } else if (c == '\n')
+ break;
+ }
+ if (!empty) {
+ Append(tf, "\n");
+ }
+ Append(tf, ts);
+ Printf(f, "%s", tf);
+ Clear(tf);
+ Clear(ts);
+ for (i = 0; i < level; i++)
+ Putc(' ', tf);
+ empty = 1;
+ } else {
+ if (!empty || !isspace(c)) {
+ Putc(c, ts);
+ empty = 0;
+ }
+ }
+ }
+ if (!empty) {
+ Append(tf, ts);
+ }
+ if (Len(tf) != 0)
+ Printf(f, "%s", tf);
+ Delete(ts);
+ Delete(tf);
+ Printf(f, "\n");
+}
+
+/* -----------------------------------------------------------------------------
+ * Wrapper_print()
+ *
+ * Print out a wrapper function. Does pretty or compact printing as well.
+ * ----------------------------------------------------------------------------- */
+
+void Wrapper_print(Wrapper *w, File *f) {
+ String *str;
+
+ str = NewStringEmpty();
+ Printf(str, "%s\n", w->def);
+ Printf(str, "%s\n", w->locals);
+ Printf(str, "%s\n", w->code);
+ if (Compact_mode == 1)
+ Wrapper_compact_print(str, f);
+ else
+ Wrapper_pretty_print(str, f);
+
+ Delete(str);
+}
+
+/* -----------------------------------------------------------------------------
+ * Wrapper_add_local()
+ *
+ * Adds a new local variable declaration to a function. Returns -1 if already
+ * present (which may or may not be okay to the caller).
+ * ----------------------------------------------------------------------------- */
+
+int Wrapper_add_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl) {
+ /* See if the local has already been declared */
+ if (Getattr(w->localh, name)) {
+ return -1;
+ }
+ Setattr(w->localh, name, decl);
+ Printf(w->locals, "%s;\n", decl);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Wrapper_add_localv()
+ *
+ * Same as add_local(), but allows a NULL terminated list of strings to be
+ * used as a replacement for decl. This saves the caller the trouble of having
+ * to manually construct the 'decl' string before calling.
+ * ----------------------------------------------------------------------------- */
+
+int Wrapper_add_localv(Wrapper *w, const_String_or_char_ptr name, ...) {
+ va_list ap;
+ int ret;
+ String *decl;
+ DOH *obj;
+ decl = NewStringEmpty();
+ va_start(ap, name);
+
+ obj = va_arg(ap, void *);
+ while (obj) {
+ Append(decl, obj);
+ Putc(' ', decl);
+ obj = va_arg(ap, void *);
+ }
+ va_end(ap);
+
+ ret = Wrapper_add_local(w, name, decl);
+ Delete(decl);
+ return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * Wrapper_check_local()
+ *
+ * Check to see if a local name has already been declared
+ * ----------------------------------------------------------------------------- */
+
+int Wrapper_check_local(Wrapper *w, const_String_or_char_ptr name) {
+ if (Getattr(w->localh, name)) {
+ return 1;
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Wrapper_new_local()
+ *
+ * Adds a new local variable with a guarantee that a unique local name will be
+ * used. Returns the name that was actually selected.
+ * ----------------------------------------------------------------------------- */
+
+char *Wrapper_new_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl) {
+ int i;
+ String *nname = NewString(name);
+ String *ndecl = NewString(decl);
+ char *ret;
+
+ i = 0;
+
+ 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(w->locals, "%s;\n", ndecl);
+ ret = Char(nname);
+ Delete(nname);
+ Delete(ndecl);
+ return ret; /* Note: nname should still exists in the w->localh hash */
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Wrapper_new_localv()
+ *
+ * Same as add_local(), but allows a NULL terminated list of strings to be
+ * used as a replacement for decl. This saves the caller the trouble of having
+ * to manually construct the 'decl' string before calling.
+ * ----------------------------------------------------------------------------- */
+
+char *Wrapper_new_localv(Wrapper *w, const_String_or_char_ptr name, ...) {
+ va_list ap;
+ char *ret;
+ String *decl;
+ DOH *obj;
+ decl = NewStringEmpty();
+ va_start(ap, name);
+
+ obj = va_arg(ap, void *);
+ while (obj) {
+ Append(decl, obj);
+ Putc(' ', decl);
+ obj = va_arg(ap, void *);
+ }
+ va_end(ap);
+
+ ret = Wrapper_new_local(w, name, decl);
+ Delete(decl);
+ return ret;
+}