From c90f71dd8c2ec6670edb45c39000a048bd163ae9 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 29 Apr 2002 19:56:57 +0000 Subject: [PATCH] Since I have made several changes to SWIG over the years to accomodate special cases and other things in wxPython, and since I plan on making several more, I've decided to put the SWIG sources in wxPython's CVS instead of relying on maintaining patches. This effectivly becomes a fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still doesn't have some things I rely on in 1.1, not to mention that my custom patches would all have to be redone, I felt that this is the easier road to take. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15307 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/my_distutils.py | 2 +- wxPython/wxSWIG/.cvsignore | 1 + wxPython/wxSWIG/Include/swig.h | 676 ++ wxPython/wxSWIG/Include/swigver.h | 6 + wxPython/wxSWIG/Include/swigver.h.in | 6 + wxPython/wxSWIG/LICENSE | 43 + wxPython/wxSWIG/Makefile.in | 231 + wxPython/wxSWIG/Modules/Makefile.in | 105 + wxPython/wxSWIG/Modules/debug.cxx | 198 + wxPython/wxSWIG/Modules/debug.h | 52 + wxPython/wxSWIG/Modules/guile.cxx | 841 +++ wxPython/wxSWIG/Modules/guile.h | 57 + wxPython/wxSWIG/Modules/makefile.vc | 79 + wxPython/wxSWIG/Modules/perl5.cxx | 2271 ++++++ wxPython/wxSWIG/Modules/perl5.h | 105 + wxPython/wxSWIG/Modules/pycpp.cxx | 517 ++ wxPython/wxSWIG/Modules/python.cxx | 1640 +++++ wxPython/wxSWIG/Modules/python.h | 111 + wxPython/wxSWIG/Modules/swigmain.cxx | 168 + wxPython/wxSWIG/Modules/swigtcl.h | 115 + wxPython/wxSWIG/Modules/tcl.cxx | 1472 ++++ wxPython/wxSWIG/Modules/tcl8.cxx | 1499 ++++ wxPython/wxSWIG/Modules/tcl8.h | 115 + wxPython/wxSWIG/Modules/wrap.h | 38 + wxPython/wxSWIG/README | 381 + wxPython/wxSWIG/README.1st | 19 + wxPython/wxSWIG/Runtime/Makefile | 131 + wxPython/wxSWIG/Runtime/Makefile.in | 130 + wxPython/wxSWIG/Runtime/libperl.c | 364 + wxPython/wxSWIG/Runtime/libperl.swg | 361 + wxPython/wxSWIG/Runtime/libpy.c | 417 ++ wxPython/wxSWIG/Runtime/libtcl.c | 249 + wxPython/wxSWIG/Runtime/libtcl8.c | 367 + wxPython/wxSWIG/Runtime/make.sh | 30 + wxPython/wxSWIG/Runtime/makefile.vc | 99 + wxPython/wxSWIG/Runtime/perlrun.h | 3 + wxPython/wxSWIG/SWIG/Makefile.in | 126 + wxPython/wxSWIG/SWIG/ascii.cxx | 464 ++ wxPython/wxSWIG/SWIG/ascii.h | 64 + wxPython/wxSWIG/SWIG/comment.cxx | 697 ++ wxPython/wxSWIG/SWIG/cplus.cxx | 2682 +++++++ wxPython/wxSWIG/SWIG/emit.cxx | 829 +++ wxPython/wxSWIG/SWIG/getopt.cxx | 141 + wxPython/wxSWIG/SWIG/hash.cxx | 359 + wxPython/wxSWIG/SWIG/html.cxx | 598 ++ wxPython/wxSWIG/SWIG/html.h | 76 + wxPython/wxSWIG/SWIG/include.cxx | 586 ++ wxPython/wxSWIG/SWIG/internal.h | 215 + wxPython/wxSWIG/SWIG/lang.cxx | 621 ++ wxPython/wxSWIG/SWIG/latex.cxx | 490 ++ wxPython/wxSWIG/SWIG/latex.h | 79 + wxPython/wxSWIG/SWIG/main.cxx | 643 ++ wxPython/wxSWIG/SWIG/makefile.vc | 107 + wxPython/wxSWIG/SWIG/naming.cxx | 299 + wxPython/wxSWIG/SWIG/newdoc.cxx | 607 ++ wxPython/wxSWIG/SWIG/nodoc.h | 54 + wxPython/wxSWIG/SWIG/parms.cxx | 478 ++ wxPython/wxSWIG/SWIG/parser.cxx | 6730 ++++++++++++++++++ wxPython/wxSWIG/SWIG/parser.h | 149 + wxPython/wxSWIG/SWIG/parser.y | 4157 +++++++++++ wxPython/wxSWIG/SWIG/scanner.cxx | 1381 ++++ wxPython/wxSWIG/SWIG/sstring.cxx | 587 ++ wxPython/wxSWIG/SWIG/symbol.cxx | 196 + wxPython/wxSWIG/SWIG/typemap.cxx | 1093 +++ wxPython/wxSWIG/SWIG/types.cxx | 1031 +++ wxPython/wxSWIG/SWIG/wrapfunc.cxx | 164 + wxPython/wxSWIG/configure.in | 445 ++ wxPython/wxSWIG/make_win.in | 70 + wxPython/wxSWIG/makefile.vc | 155 + wxPython/wxSWIG/swig_lib/array.i | 401 ++ wxPython/wxSWIG/swig_lib/autodoc.i | 109 + wxPython/wxSWIG/swig_lib/carray.i | 182 + wxPython/wxSWIG/swig_lib/config/swigptr.swg | 172 + wxPython/wxSWIG/swig_lib/constraints.i | 208 + wxPython/wxSWIG/swig_lib/ctype.i | 64 + wxPython/wxSWIG/swig_lib/exception.i | 146 + wxPython/wxSWIG/swig_lib/guile/Makefile | 4 + wxPython/wxSWIG/swig_lib/guile/guile.swg | 15 + wxPython/wxSWIG/swig_lib/guile/guilemain.i | 21 + wxPython/wxSWIG/swig_lib/guile/interpreter.i | 78 + wxPython/wxSWIG/swig_lib/malloc.i | 64 + wxPython/wxSWIG/swig_lib/math.i | 120 + wxPython/wxSWIG/swig_lib/memory.i | 39 + wxPython/wxSWIG/swig_lib/objc.i | 56 + wxPython/wxSWIG/swig_lib/perl5/Makefile | 140 + wxPython/wxSWIG/swig_lib/perl5/Makefile.in | 139 + wxPython/wxSWIG/swig_lib/perl5/Makefile.pl | 21 + wxPython/wxSWIG/swig_lib/perl5/headers.swg | 24 + wxPython/wxSWIG/swig_lib/perl5/perl5.swg | 361 + wxPython/wxSWIG/swig_lib/perl5/perl5mg.swg | 19 + wxPython/wxSWIG/swig_lib/perl5/perlmain.i | 80 + wxPython/wxSWIG/swig_lib/perl5/ptrlang.i | 650 ++ wxPython/wxSWIG/swig_lib/perl5/typemaps.i | 475 ++ wxPython/wxSWIG/swig_lib/pointer.i | 58 + wxPython/wxSWIG/swig_lib/python/Makefile | 137 + wxPython/wxSWIG/swig_lib/python/Makefile.in | 136 + wxPython/wxSWIG/swig_lib/python/defarg.swg | 36 + wxPython/wxSWIG/swig_lib/python/embed.i | 115 + wxPython/wxSWIG/swig_lib/python/embed13.i | 342 + wxPython/wxSWIG/swig_lib/python/embed14.i | 340 + wxPython/wxSWIG/swig_lib/python/embed15.i | 115 + wxPython/wxSWIG/swig_lib/python/ptrlang.i | 652 ++ wxPython/wxSWIG/swig_lib/python/pyexp.swg | 32 + wxPython/wxSWIG/swig_lib/python/python.swg | 417 ++ wxPython/wxSWIG/swig_lib/python/typemaps.i | 564 ++ wxPython/wxSWIG/swig_lib/stdlib.i | 50 + wxPython/wxSWIG/swig_lib/swigptr.swg | 326 + wxPython/wxSWIG/swig_lib/tcl/Makefile | 135 + wxPython/wxSWIG/swig_lib/tcl/Makefile.in | 134 + wxPython/wxSWIG/swig_lib/tcl/blt.i | 28 + wxPython/wxSWIG/swig_lib/tcl/configcode.swg | 27 + wxPython/wxSWIG/swig_lib/tcl/constarray.i | 108 + wxPython/wxSWIG/swig_lib/tcl/consthash.i | 223 + wxPython/wxSWIG/swig_lib/tcl/delcmd.swg | 6 + wxPython/wxSWIG/swig_lib/tcl/delcmd8.swg | 6 + wxPython/wxSWIG/swig_lib/tcl/expect.i | 97 + wxPython/wxSWIG/swig_lib/tcl/expectk.i | 733 ++ wxPython/wxSWIG/swig_lib/tcl/ish.i | 170 + wxPython/wxSWIG/swig_lib/tcl/itclsh.i | 152 + wxPython/wxSWIG/swig_lib/tcl/itkwish.i | 150 + wxPython/wxSWIG/swig_lib/tcl/iwish.i | 180 + wxPython/wxSWIG/swig_lib/tcl/mactclinit.c | 86 + wxPython/wxSWIG/swig_lib/tcl/mactkinit.c | 229 + wxPython/wxSWIG/swig_lib/tcl/methodcmd.swg | 74 + wxPython/wxSWIG/swig_lib/tcl/methodcmd8.swg | 96 + wxPython/wxSWIG/swig_lib/tcl/objcmd.swg | 69 + wxPython/wxSWIG/swig_lib/tcl/objcmd8.swg | 74 + wxPython/wxSWIG/swig_lib/tcl/ptrlang.i | 695 ++ wxPython/wxSWIG/swig_lib/tcl/swigtcl.swg | 249 + wxPython/wxSWIG/swig_lib/tcl/swigtcl8.swg | 367 + wxPython/wxSWIG/swig_lib/tcl/tclsh.i | 106 + wxPython/wxSWIG/swig_lib/tcl/tix.i | 29 + wxPython/wxSWIG/swig_lib/tcl/typemaps.i | 555 ++ wxPython/wxSWIG/swig_lib/tcl/wish.i | 170 + wxPython/wxSWIG/swig_lib/timers.i | 180 + 135 files changed, 51307 insertions(+), 1 deletion(-) create mode 100644 wxPython/wxSWIG/.cvsignore create mode 100644 wxPython/wxSWIG/Include/swig.h create mode 100644 wxPython/wxSWIG/Include/swigver.h create mode 100644 wxPython/wxSWIG/Include/swigver.h.in create mode 100644 wxPython/wxSWIG/LICENSE create mode 100644 wxPython/wxSWIG/Makefile.in create mode 100644 wxPython/wxSWIG/Modules/Makefile.in create mode 100644 wxPython/wxSWIG/Modules/debug.cxx create mode 100644 wxPython/wxSWIG/Modules/debug.h create mode 100644 wxPython/wxSWIG/Modules/guile.cxx create mode 100644 wxPython/wxSWIG/Modules/guile.h create mode 100644 wxPython/wxSWIG/Modules/makefile.vc create mode 100644 wxPython/wxSWIG/Modules/perl5.cxx create mode 100644 wxPython/wxSWIG/Modules/perl5.h create mode 100644 wxPython/wxSWIG/Modules/pycpp.cxx create mode 100644 wxPython/wxSWIG/Modules/python.cxx create mode 100644 wxPython/wxSWIG/Modules/python.h create mode 100644 wxPython/wxSWIG/Modules/swigmain.cxx create mode 100644 wxPython/wxSWIG/Modules/swigtcl.h create mode 100644 wxPython/wxSWIG/Modules/tcl.cxx create mode 100644 wxPython/wxSWIG/Modules/tcl8.cxx create mode 100644 wxPython/wxSWIG/Modules/tcl8.h create mode 100644 wxPython/wxSWIG/Modules/wrap.h create mode 100644 wxPython/wxSWIG/README create mode 100644 wxPython/wxSWIG/README.1st create mode 100644 wxPython/wxSWIG/Runtime/Makefile create mode 100644 wxPython/wxSWIG/Runtime/Makefile.in create mode 100644 wxPython/wxSWIG/Runtime/libperl.c create mode 100644 wxPython/wxSWIG/Runtime/libperl.swg create mode 100644 wxPython/wxSWIG/Runtime/libpy.c create mode 100644 wxPython/wxSWIG/Runtime/libtcl.c create mode 100644 wxPython/wxSWIG/Runtime/libtcl8.c create mode 100644 wxPython/wxSWIG/Runtime/make.sh create mode 100644 wxPython/wxSWIG/Runtime/makefile.vc create mode 100644 wxPython/wxSWIG/Runtime/perlrun.h create mode 100644 wxPython/wxSWIG/SWIG/Makefile.in create mode 100644 wxPython/wxSWIG/SWIG/ascii.cxx create mode 100644 wxPython/wxSWIG/SWIG/ascii.h create mode 100644 wxPython/wxSWIG/SWIG/comment.cxx create mode 100644 wxPython/wxSWIG/SWIG/cplus.cxx create mode 100644 wxPython/wxSWIG/SWIG/emit.cxx create mode 100644 wxPython/wxSWIG/SWIG/getopt.cxx create mode 100644 wxPython/wxSWIG/SWIG/hash.cxx create mode 100644 wxPython/wxSWIG/SWIG/html.cxx create mode 100644 wxPython/wxSWIG/SWIG/html.h create mode 100644 wxPython/wxSWIG/SWIG/include.cxx create mode 100644 wxPython/wxSWIG/SWIG/internal.h create mode 100644 wxPython/wxSWIG/SWIG/lang.cxx create mode 100644 wxPython/wxSWIG/SWIG/latex.cxx create mode 100644 wxPython/wxSWIG/SWIG/latex.h create mode 100644 wxPython/wxSWIG/SWIG/main.cxx create mode 100644 wxPython/wxSWIG/SWIG/makefile.vc create mode 100644 wxPython/wxSWIG/SWIG/naming.cxx create mode 100644 wxPython/wxSWIG/SWIG/newdoc.cxx create mode 100644 wxPython/wxSWIG/SWIG/nodoc.h create mode 100644 wxPython/wxSWIG/SWIG/parms.cxx create mode 100644 wxPython/wxSWIG/SWIG/parser.cxx create mode 100644 wxPython/wxSWIG/SWIG/parser.h create mode 100644 wxPython/wxSWIG/SWIG/parser.y create mode 100644 wxPython/wxSWIG/SWIG/scanner.cxx create mode 100644 wxPython/wxSWIG/SWIG/sstring.cxx create mode 100644 wxPython/wxSWIG/SWIG/symbol.cxx create mode 100644 wxPython/wxSWIG/SWIG/typemap.cxx create mode 100644 wxPython/wxSWIG/SWIG/types.cxx create mode 100644 wxPython/wxSWIG/SWIG/wrapfunc.cxx create mode 100644 wxPython/wxSWIG/configure.in create mode 100644 wxPython/wxSWIG/make_win.in create mode 100644 wxPython/wxSWIG/makefile.vc create mode 100644 wxPython/wxSWIG/swig_lib/array.i create mode 100644 wxPython/wxSWIG/swig_lib/autodoc.i create mode 100644 wxPython/wxSWIG/swig_lib/carray.i create mode 100644 wxPython/wxSWIG/swig_lib/config/swigptr.swg create mode 100644 wxPython/wxSWIG/swig_lib/constraints.i create mode 100644 wxPython/wxSWIG/swig_lib/ctype.i create mode 100644 wxPython/wxSWIG/swig_lib/exception.i create mode 100644 wxPython/wxSWIG/swig_lib/guile/Makefile create mode 100644 wxPython/wxSWIG/swig_lib/guile/guile.swg create mode 100644 wxPython/wxSWIG/swig_lib/guile/guilemain.i create mode 100644 wxPython/wxSWIG/swig_lib/guile/interpreter.i create mode 100644 wxPython/wxSWIG/swig_lib/malloc.i create mode 100644 wxPython/wxSWIG/swig_lib/math.i create mode 100644 wxPython/wxSWIG/swig_lib/memory.i create mode 100644 wxPython/wxSWIG/swig_lib/objc.i create mode 100644 wxPython/wxSWIG/swig_lib/perl5/Makefile create mode 100644 wxPython/wxSWIG/swig_lib/perl5/Makefile.in create mode 100644 wxPython/wxSWIG/swig_lib/perl5/Makefile.pl create mode 100644 wxPython/wxSWIG/swig_lib/perl5/headers.swg create mode 100644 wxPython/wxSWIG/swig_lib/perl5/perl5.swg create mode 100644 wxPython/wxSWIG/swig_lib/perl5/perl5mg.swg create mode 100644 wxPython/wxSWIG/swig_lib/perl5/perlmain.i create mode 100644 wxPython/wxSWIG/swig_lib/perl5/ptrlang.i create mode 100644 wxPython/wxSWIG/swig_lib/perl5/typemaps.i create mode 100644 wxPython/wxSWIG/swig_lib/pointer.i create mode 100644 wxPython/wxSWIG/swig_lib/python/Makefile create mode 100644 wxPython/wxSWIG/swig_lib/python/Makefile.in create mode 100644 wxPython/wxSWIG/swig_lib/python/defarg.swg create mode 100644 wxPython/wxSWIG/swig_lib/python/embed.i create mode 100644 wxPython/wxSWIG/swig_lib/python/embed13.i create mode 100644 wxPython/wxSWIG/swig_lib/python/embed14.i create mode 100644 wxPython/wxSWIG/swig_lib/python/embed15.i create mode 100644 wxPython/wxSWIG/swig_lib/python/ptrlang.i create mode 100644 wxPython/wxSWIG/swig_lib/python/pyexp.swg create mode 100644 wxPython/wxSWIG/swig_lib/python/python.swg create mode 100644 wxPython/wxSWIG/swig_lib/python/typemaps.i create mode 100644 wxPython/wxSWIG/swig_lib/stdlib.i create mode 100644 wxPython/wxSWIG/swig_lib/swigptr.swg create mode 100644 wxPython/wxSWIG/swig_lib/tcl/Makefile create mode 100644 wxPython/wxSWIG/swig_lib/tcl/Makefile.in create mode 100644 wxPython/wxSWIG/swig_lib/tcl/blt.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/configcode.swg create mode 100644 wxPython/wxSWIG/swig_lib/tcl/constarray.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/consthash.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/delcmd.swg create mode 100644 wxPython/wxSWIG/swig_lib/tcl/delcmd8.swg create mode 100644 wxPython/wxSWIG/swig_lib/tcl/expect.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/expectk.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/ish.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/itclsh.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/itkwish.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/iwish.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/mactclinit.c create mode 100644 wxPython/wxSWIG/swig_lib/tcl/mactkinit.c create mode 100644 wxPython/wxSWIG/swig_lib/tcl/methodcmd.swg create mode 100644 wxPython/wxSWIG/swig_lib/tcl/methodcmd8.swg create mode 100644 wxPython/wxSWIG/swig_lib/tcl/objcmd.swg create mode 100644 wxPython/wxSWIG/swig_lib/tcl/objcmd8.swg create mode 100644 wxPython/wxSWIG/swig_lib/tcl/ptrlang.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/swigtcl.swg create mode 100644 wxPython/wxSWIG/swig_lib/tcl/swigtcl8.swg create mode 100644 wxPython/wxSWIG/swig_lib/tcl/tclsh.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/tix.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/typemaps.i create mode 100644 wxPython/wxSWIG/swig_lib/tcl/wish.i create mode 100644 wxPython/wxSWIG/swig_lib/timers.i diff --git a/wxPython/my_distutils.py b/wxPython/my_distutils.py index 12b4e6d09a..f1603f4f5f 100644 --- a/wxPython/my_distutils.py +++ b/wxPython/my_distutils.py @@ -465,7 +465,7 @@ def run_swig(files, dir, gendir, package, USE_SWIG, force, swig_args, swig_deps= cpp_file = string.join(string.split(cpp_file, '\\'), '/') i_file = string.join(string.split(i_file, '\\'), '/') - cmd = ['swig'] + swig_args + ['-I'+dir, '-c', '-o', cpp_file, i_file] + cmd = ['./wxSWIG/wxswig'] + swig_args + ['-I'+dir, '-c', '-o', cpp_file, i_file] spawn(cmd, verbose=1) # copy the generated python file to the package directory diff --git a/wxPython/wxSWIG/.cvsignore b/wxPython/wxSWIG/.cvsignore new file mode 100644 index 0000000000..f82ec85a56 --- /dev/null +++ b/wxPython/wxSWIG/.cvsignore @@ -0,0 +1 @@ +wxSWIG.dsp diff --git a/wxPython/wxSWIG/Include/swig.h b/wxPython/wxSWIG/Include/swig.h new file mode 100644 index 0000000000..c02f1b9343 --- /dev/null +++ b/wxPython/wxSWIG/Include/swig.h @@ -0,0 +1,676 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ +/*********************************************************************** + * $Header$ + * + * swig.h + * + * This is the header file containing the main class definitions and + * declarations. Should be included in all extensions and code + * modules. + * + ***********************************************************************/ + +#ifndef __swig_h_ +#define __swig_h_ + +#include +#include +#include + +#include "swigver.h" + +/* Global variables. Needs to be cleaned up */ + +#ifdef MACSWIG +#define Status Swig_Status +#undef stderr +#define stderr swig_log +extern FILE *swig_log; +#endif + +extern FILE *f_header; // Some commonly used +extern FILE *f_wrappers; // FILE pointers +extern FILE *f_init; +extern FILE *f_input; +extern char InitName[256]; +extern char LibDir[512]; // Library directory +extern char **InitNames; // List of other init functions +extern int Status; // Variable creation status +extern int TypeStrict; // Type checking strictness +extern int Verbose; +extern int yyparse(); +extern int line_number; +extern int start_line; +extern char *input_file; // Current input file +extern int CPlusPlus; // C++ mode +extern int ObjC; // Objective-C mode +extern int ObjCClass; // Objective-C style class +extern int AddMethods; // AddMethods mode +extern int NewObject; // NewObject mode +extern int Inline; // Inline mode +extern int NoInclude; // NoInclude flag +extern char *typemap_lang; // Current language name +extern int error_count; +extern char *copy_string(char *); +extern char output_dir[512]; // Output directory + +#define FatalError() if ((error_count++) > 20) { fprintf(stderr,"Confused by earlier errors. Bailing out\n"); SWIG_exit(1); } + +/* Miscellaneous stuff */ + +#define STAT_READONLY 1 +#define MAXSCOPE 16 + +extern char* getSwigLib(); + +// ----------------------------------------------------------------------- +// String class +// ----------------------------------------------------------------------- + +class String { +private: + int maxsize; // Max size of current string + void add(const char *newstr); // Function to add a new string + void add(char c); // Add a character + void insert(const char *newstr); + int len; +public: + String(); + String(const char *s); + ~String(); + char *get() const; + char *str; // String data + friend String& operator<<(String&,const char *s); + friend String& operator<<(String&,const int); + friend String& operator<<(String&,const char); + friend String& operator<<(String&,String&); + friend String& operator>>(const char *s, String&); + friend String& operator>>(String&,String&); + String& operator=(const char *); + operator char*() const { return str; } + void untabify(); + void replace(const char *token, const char *rep); + void replaceid(const char *id, const char *rep); + void strip(); +}; + +#define tab2 " " +#define tab4 " " +#define tab8 " " +#define br "\n" +#define endl "\n" +#define quote "\"" + +// ------------------------------------------------------------------- +// Hash table class +// ------------------------------------------------------------------- + +class Hash { +private: + struct Node { + Node(const char *k, void *obj, void (*d)(void *)) { + key = new char[strlen(k)+1]; + strcpy(key,k); + object = obj; + del_proc = d; + next = 0; + }; + ~Node() { + delete key; + if (del_proc) (*del_proc)(object); + }; + char *key; + void *object; + struct Node *next; + void (*del_proc)(void *); + }; + int h1(const char *key); // Hashing function + int hashsize; // Size of hash table + Node **hashtable; // Actual hash table + int index; // Current index (used by iterators) + Node *current; // Current item in hash table +public: + Hash(); + ~Hash(); + int add(const char *key, void *object); + int add(const char *key, void *object, void (*del)(void *)); + void *lookup(const char *key); + void remove(const char *key); + void *first(); + void *next(); + char *firstkey(); + char *nextkey(); +}; + +/************************************************************************ + * class DataType + * + * Defines the basic datatypes supported by the translator. + * + ************************************************************************/ + +#define T_INT 1 +#define T_SHORT 2 +#define T_LONG 3 +#define T_UINT 4 +#define T_USHORT 5 +#define T_ULONG 6 +#define T_UCHAR 7 +#define T_SCHAR 8 +#define T_BOOL 9 +#define T_DOUBLE 10 +#define T_FLOAT 11 +#define T_CHAR 12 +#define T_USER 13 +#define T_VOID 14 +#define T_SYMBOL 98 +#define T_ERROR 99 + +// These types are now obsolete, but defined for backwards compatibility + +#define T_SINT 90 +#define T_SSHORT 91 +#define T_SLONG 92 + +// Class for storing data types + +#define MAX_NAME 96 + +class DataType { +private: + static Hash *typedef_hash[MAXSCOPE]; + static int scope; +public: + int type; // SWIG Type code + char name[MAX_NAME]; // Name of type + char is_pointer; // Is this a pointer? + char implicit_ptr; // Implicit ptr + char is_reference; // A C++ reference type + char status; // Is this datatype read-only? + char *qualifier; // A qualifier string (ie. const). + char *arraystr; // String containing array part + int id; // type identifier (unique for every type). + DataType(); + DataType(DataType *); + DataType(int type); + ~DataType(); + void primitive(); // Turn a datatype into its primitive type + char *print_type(); // Return string containing datatype + char *print_full(); // Return string with full datatype + char *print_cast(); // Return string for type casting + char *print_mangle();// Return mangled version of type + char *print_real(char *local=0); // Print the real datatype (as far as we can determine) + char *print_arraycast(); // Prints an array cast + char *print_mangle_default(); // Default mangling scheme + + // Array query functions + int array_dimensions(); // Return number of array dimensions (if any) + char *get_dimension(int); // Return string containing a particular dimension + char *get_array(); // Returns the array string for a datatype + + // typedef support + + void typedef_add(char *name, int mode = 0); // Add this type to typedef list + void typedef_resolve(int level = 0); // See if this type has been typedef'd + void typedef_replace(); // Replace this type with it's original type +static int is_typedef(char *name); // See if this is a typedef + void typedef_updatestatus(int newstatus); // Change status of a typedef +static void init_typedef(void); // Initialize typedef manager +static void merge_scope(Hash *h); // Functions for managing scoping of datatypes +static void new_scope(Hash *h = 0); +static Hash *collapse_scope(char *); + int check_defined(); // Check to see if type is defined by a typedef. +}; + +#define STAT_REPLACETYPE 2 + +/************************************************************************ + * class Parm + * + * Structure for holding information about function parameters + * + * CALL_VALUE --> Call by value even though function parameter + * is a pointer. + * ex : foo(&_arg0); + * CALL_REF --> Call by reference even though function parameter + * is by value + * ex : foo(*_arg0); + * + ************************************************************************/ + +#define CALL_VALUE 0x01 +#define CALL_REFERENCE 0x02 +#define CALL_OUTPUT 0x04 + +struct Parm { + DataType *t; // Datatype of this parameter + int call_type; // Call type (value or reference or value) + char *name; // Name of parameter (optional) + char *defvalue; // Default value (as a string) + int ignore; // Ignore flag + char *objc_separator; // Parameter separator for Objective-C + Parm(DataType *type, char *n); + Parm(Parm *p); + ~Parm(); +}; + +// ------------------------------------------------------------- +// class ParmList +// +// This class is used for manipulating parameter lists in +// function and type declarations. +// ------------------------------------------------------------- + +#define MAXPARMS 16 + +class ParmList { +private: + int maxparms; // Max parms possible in current list + Parm **parms; // Pointer to parms array + void moreparms(); // Increase number of stored parms + int current_parm; // Internal state for get_first,get_next +public: + int nparms; // Number of parms in list + void append(Parm *p); // Append a parameter to the end + void insert(Parm *p, int pos); // Insert a parameter into the list + void del(int pos); // Delete a parameter at position pos + int numopt(); // Get number of optional arguments + int numarg(); // Get number of active arguments + Parm *get(int pos); // Get the parameter at position pos + Parm &operator[](int); // An alias for get(). + ParmList(); + ParmList(ParmList *l); + ~ParmList(); + + // Keep this for backwards compatibility + + Parm *get_first(); // Get first parameter from list + Parm *get_next(); // Get next parameter from list + void print_types(FILE *f); // Print list of datatypes + void print_types(String &f); // Generate list of datatypes. + void print_args(FILE *f); // Print argument list + int check_defined(); // Checks to make sure the arguments are defined + void sub_parmnames(String &s); // Remaps real parameter names in code fragment +}; + +// Modes for different types of inheritance + +#define INHERIT_FUNC 0x1 +#define INHERIT_VAR 0x2 +#define INHERIT_CONST 0x4 +#define INHERIT_ALL (INHERIT_FUNC | INHERIT_VAR | INHERIT_CONST) + +struct Pragma { + Pragma() { next = 0; } + String filename; + int lineno; + String lang; + String name; + String value; + Pragma *next; +}; + +/************************************************************************ + * 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. + * + * By implementing this using virtual functions, hopefully it will be + * easy to support different types of scripting languages. + * + * The following functions are used : + * + * parse_args(argc, argv) + * Parse the arguments used by this language. + * + * parse() + * Entry function that starts parsing of a particular language + * + * create_function(fname, iname, rtype, parmlist) + * Creates a function wrappper. + * + * link_variable(vname, iname, type) + * Creates a link to a variable. + * + * declare_const(cname, type, value) + * Creates a constant (for #define). + * + * initialize(char *fn) + * Produces initialization code. + * + * headers() + * Produce code for headers + * + * close() + * Close up files + * + * usage_var(iname,type,string) + * Produces usage string for variable declaration. + * + * usage_func(iname,rttype, parmlist, string) + * Produces usage string for function declaration. + * + * usage_const(iname, type, value, string) + * Produces usage string for constants + * + * set_module(char *modname) + * Sets the name of the module (%module directive) + * + * set_init(char *initname) + * Sets name of initialization function (an alternative to set_module) + * add_native(char *name, char *funcname); + * Adds a native wrapper function to the initialize process + * + * type_mangle(DataType *t); + * Mangles the name of a datatype. + * --- C++ Functions --- + * + * These functions are optional additions to any of the target + * languages. SWIG handles inheritance, symbol tables, and other + * information. + * + * cpp_open_class(char *classname, char *rname) + * Open a new C++ class definition. + * cpp_close_class(char *) + * Close current C++ class + * cpp_member_func(char *name, char *rname, DataType *rt, ParmList *l) + * Create a C++ member function + * cpp_constructor(char *name, char *iname, ParmList *l) + * Create a C++ constructor. + * cpp_destructor(char *name, char *iname) + * Create a C++ destructor + * cpp_variable(char *name, char *iname, DataType *t) + * Create a C++ member data item. + * cpp_declare_const(char *name, char *iname, int type, char *value) + * Create a C++ constant. + * cpp_inherit(char *baseclass) + * Inherit data from baseclass. + * cpp_static_func(char *name, char *iname, DataType *t, ParmList *l) + * A C++ static member function. + * cpp_static_var(char *name, char *iname, DataType *t) + * A C++ static member data variable. + * + *************************************************************************/ + +class Language { +public: + virtual void parse_args(int argc, char *argv[]) = 0; + virtual void parse() = 0; + virtual void create_function(char *, char *, DataType *, ParmList *) = 0; + virtual void link_variable(char *, char *, DataType *) = 0; + virtual void declare_const(char *, char *, DataType *, char *) = 0; + virtual void initialize(void) = 0; + virtual void headers(void) = 0; + virtual void close(void) = 0; + virtual void set_module(char *mod_name,char **mod_list) = 0; + virtual void set_init(char *init_name); + virtual void add_native(char *, char *); + virtual char *type_mangle(DataType *t) { + return t->print_mangle_default(); + } + virtual void add_typedef(DataType *t, char *name); + virtual void create_command(char *cname, char *iname); + + // + // C++ language extensions. + // You can redefine these, or use the defaults below + // + + virtual void cpp_member_func(char *name, char *iname, DataType *t, ParmList *l); + virtual void cpp_constructor(char *name, char *iname, ParmList *l); + virtual void cpp_destructor(char *name, char *newname); + virtual void cpp_open_class(char *name, char *rename, char *ctype, int strip); + virtual void cpp_close_class(); + virtual void cpp_cleanup(); + virtual void cpp_inherit(char **baseclass, int mode = INHERIT_ALL); + virtual void cpp_variable(char *name, char *iname, DataType *t); + virtual void cpp_static_func(char *name, char *iname, DataType *t, ParmList *l); + virtual void cpp_declare_const(char *name, char *iname, DataType *type, char *value); + virtual void cpp_static_var(char *name, char *iname, DataType *t); + virtual void cpp_pragma(Pragma *plist); + + // Pragma directive + + virtual void pragma(char *, char *, char *); + + // Declaration of a class, but not a full definition + + virtual void cpp_class_decl(char *, char *, char *); + + // Import directive + + virtual void import(char *filename); + +}; + +class Documentation; + +// -------------------------------------------------------------------- +// class DocEntry +// +// Base class for the documentation system. Basically everything is +// a documentation entry of some sort. Specific derived classes +// are created internally and shouldn't be accessed by third-party +// modules. +// -------------------------------------------------------------------- + +class DocEntry { +public: + char *name; // Name of the entry + String usage; // Short description (optional) + String cinfo; // Information about C interface (optional). + String text; // Supporting text (optional) + DocEntry *parent; // Parent of this entry (optional) + DocEntry *child; // Children of this entry (optional) + DocEntry *next; // Next entry (or sibling) + DocEntry *previous; // Previous entry + int counter; // Counter for section control + int is_separator; // Is this a separator entry? + int sorted; // Sorted? + int line_number; // Line number + int end_line; // Ending line number + int format; // Format this documentation entry + int print_info; // Print C information about this entry + char *file; // File + virtual ~DocEntry(); // Destructor (common to all subclasses) + + // Methods applicable to all documentation entries + + virtual void output(Documentation *d); + void add(DocEntry *de); // Add documentation entry to the list + void addchild(DocEntry *de); // Add documentation entry as a child + void sort_children(); // Sort all of the children + void remove(); // Remove this doc entry + void parse_args(int argc, char **argv); // Parse command line options + void style(char *name,char *value);// Change doc style. + static DocEntry *dead_entries; // Dead documentation entries +}; + +extern DocEntry *doc_entry; + +// Default DocEntry style parameters + +#define SWIGDEFAULT_SORT 0 +#define SWIGDEFAULT_FORMAT 1 +#define SWIGDEFAULT_INFO 1 + +// ---------------------------------------------------------------------- +// Documentation module base class +// +// This class defines methods that need to be implemented for a +// documentation module. +// +// title() - Print out a title entry +// newsection() - Start a new section (may be nested to form subsections) +// endsection() - End a section +// print_decl() - Print a standard declaration +// print_text() - Print standard text +// init() - Initialize the documentation module +// close() - Close documentation module +// ---------------------------------------------------------------------- + +class Documentation { +public: + virtual void parse_args(int argc, char **argv) = 0; + virtual void title(DocEntry *de) = 0; + virtual void newsection(DocEntry *de, int sectnum) = 0; + virtual void endsection() = 0; + virtual void print_decl(DocEntry *de) = 0; + virtual void print_text(DocEntry *de) = 0; + virtual void separator() = 0; + virtual void init(char *filename) = 0; + virtual void close(void) = 0; + virtual void style(char *name, char *value) = 0; +}; + +/* Emit functions */ + +extern void emit_extern_var(char *, DataType *, int, FILE *); +extern void emit_extern_func(char *, DataType *, ParmList *, int, FILE *); +extern int emit_args(DataType *, ParmList *, FILE *); + +extern void emit_func_call(char *, DataType *, ParmList *, FILE *); + +extern void emit_hex(FILE *); +extern void emit_set_get(char *, char *, DataType *); +extern void emit_banner(FILE *); +extern void emit_ptr_equivalence(FILE *); +extern int SWIG_main(int, char **, Language *, Documentation *); +extern void make_wrap_name(char *); + +// Some functions for emitting some C++ helper code + +extern void cplus_emit_member_func(char *classname, char *classtype, char *classrename, + char *mname, char *mrename, DataType *type, ParmList *l, + int mode); + +extern void cplus_emit_static_func(char *classname, char *classtype, char *classrename, + char *mname, char *mrename, DataType *type, ParmList *l, + int mode); + +extern void cplus_emit_destructor(char *classname, char *classtype, char *classrename, + char *name, char *iname, int mode); + +extern void cplus_emit_constructor(char *classname, char *classtype, char *classrename, + char *name, char *iname, ParmList *l, int mode); + +extern void cplus_emit_variable_get(char *classname, char *classtype, char *classrename, + char *name, char *iname, DataType *type, int mode); + +extern void cplus_emit_variable_set(char *classname, char *classtype, char *classrename, + char *name, char *iname, DataType *type, int mode); + +extern char *cplus_base_class(char *name); + +extern void cplus_support_doc(String &f); + +/* Function for building search directories */ + +extern void add_directory(char *dirname); +extern int insert_file(char *, FILE *); +extern int get_file(char *filename, String &str); +extern int checkout_file(char *filename, char *dest); +extern int checkin_file(char *dir, char *lang, char *source, char *dest); +extern int include_file(char *filename); + +/* Miscellaneous */ + +extern void check_options(); +extern void init_args(int argc, char **); +extern void mark_arg(int n); +extern void arg_error(); + +extern void library_add(char *name); +extern void library_insert(); + +// ----------------------------------------------------------------------- +// Class for Creating Wrapper Functions +// ----------------------------------------------------------------------- + +class WrapperFunction { +private: + Hash h; +public: + String def; + String locals; + String code; + String init; + void print(FILE *f); + void print(String &f); + void add_local(char *type, char *name, char *defvalue = 0); + char *new_local(char *type, char *name, char *defvalue = 0); +static void del_type(void *obj); +}; + +extern int emit_args(DataType *, ParmList *, WrapperFunction &f); +extern void emit_func_call(char *, DataType *, ParmList *, WrapperFunction &f); +extern void SWIG_exit(int); + +// Symbol table management + +extern int add_symbol(char *, DataType *, char *); +extern void remove_symbol(char *); +extern int update_symbol(char *, DataType *, char *); +extern char *lookup_symvalue(char *); +extern DataType *lookup_symtype(char *); +extern int lookup_symbol(char *); + +// ----------------------------------------------------------------------- +// Typemap support +// ----------------------------------------------------------------------- + +extern void typemap_register(char *op, char *lang, DataType *type, char *pname, char *code, ParmList *l = 0); +extern void typemap_register(char *op, char *lang, char *type, char *pname, char *code,ParmList *l = 0); +extern void typemap_register_default(char *op, char *lang, int type, int ptr, char *arraystr, char *code, ParmList *l = 0); +extern char *typemap_lookup(char *op, char *lang, DataType *type, char *pname, char *source, char *target, + WrapperFunction *f = 0); +extern void typemap_clear(char *op, char *lang, DataType *type, char *pname); +extern void typemap_copy(char *op, char *lang, DataType *stype, char *sname, DataType *ttype, char *tname); +extern char *typemap_check(char *op, char *lang, DataType *type, char *pname); +extern void typemap_apply(DataType *tm_type, char *tmname, DataType *type, char *pname); +extern void typemap_clear_apply(DataType *type, char *pname); + + +// ----------------------------------------------------------------------- +// Code fragment support +// ----------------------------------------------------------------------- + +extern void fragment_register(char *op, char *lang, char *code); +extern char *fragment_lookup(char *op, char *lang, int age); +extern void fragment_clear(char *op, char *lang); + + +extern void emit_ptr_equivalence(WrapperFunction &); + +// ----------------------------------------------------------------------- +// Naming system +// ----------------------------------------------------------------------- + +#define AS_IS 1 + +extern void name_register(char *method, char *format); +extern int name_scope(int); +extern char *name_wrapper(char *fname, char *prefix, int suppress=0); +extern char *name_member(char *fname, char *classname, int suppress=0); +extern char *name_get(char *vname, int suppress=0); +extern char *name_set(char *vname, int suppress=0); +extern char *name_construct(char *classname, int suppress=0); +extern char *name_destroy(char *classname, int suppress=0); + + +#endif diff --git a/wxPython/wxSWIG/Include/swigver.h b/wxPython/wxSWIG/Include/swigver.h new file mode 100644 index 0000000000..706c11606f --- /dev/null +++ b/wxPython/wxSWIG/Include/swigver.h @@ -0,0 +1,6 @@ + +/* SWIG version information */ + +#define SWIG_MAJOR_VERSION 1 +#define SWIG_MINOR_VERSION 1 +#define SWIG_SPIN "(Build 883)" diff --git a/wxPython/wxSWIG/Include/swigver.h.in b/wxPython/wxSWIG/Include/swigver.h.in new file mode 100644 index 0000000000..549e14c04a --- /dev/null +++ b/wxPython/wxSWIG/Include/swigver.h.in @@ -0,0 +1,6 @@ + +/* SWIG version information */ + +#define SWIG_MAJOR_VERSION 1 +#define SWIG_MINOR_VERSION 1 +#define SWIG_SPIN "(@BUILD@)" diff --git a/wxPython/wxSWIG/LICENSE b/wxPython/wxSWIG/LICENSE new file mode 100644 index 0000000000..749ba5ac2a --- /dev/null +++ b/wxPython/wxSWIG/LICENSE @@ -0,0 +1,43 @@ +Simplified Wrapper and Interface Generator (SWIG) + +David Beazley +Department of Computer Science +University of Chicago +1100 E 58th Street +Chicago, IL 60637 +beazley@cs.uchicago.edu + +All versions of SWIG 1.1 are distributed under the following +license: + +==================================================================== + +Copyright (c) 1995-1998 +The University of Utah and the Regents of the University of California +All Rights Reserved + +Permission is hereby granted, without written agreement and without +license or royalty fees, to use, copy, modify, and distribute this +software and its documentation for any purpose, provided that +(1) The above copyright notice and the following two paragraphs +appear in all copies of the source code and (2) redistributions +including binaries reproduces these notices in the supporting +documentation. Substantial modifications to this software may be +copyrighted by their authors and need not follow the licensing terms +described here, provided that the new terms are clearly indicated in +all files where they apply. + +IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE +UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY +PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, +EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. + +THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH +SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND +THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, +SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + diff --git a/wxPython/wxSWIG/Makefile.in b/wxPython/wxSWIG/Makefile.in new file mode 100644 index 0000000000..31960e704f --- /dev/null +++ b/wxPython/wxSWIG/Makefile.in @@ -0,0 +1,231 @@ +####################################################################### +# $Header$ +# Simplified Wrapper and Interface Generator (SWIG) +# +# Makefile for version 1.1 +# Dave Beazley +# January 7, 1997 +# +# This makefile is now mostly constructed by ./configure. +# +# $Log$ +# Revision 1.1 2002/04/29 19:56:47 RD +# Since I have made several changes to SWIG over the years to accomodate +# special cases and other things in wxPython, and since I plan on making +# several more, I've decided to put the SWIG sources in wxPython's CVS +# instead of relying on maintaining patches. This effectivly becomes a +# fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still +# doesn't have some things I rely on in 1.1, not to mention that my +# custom patches would all have to be redone, I felt that this is the +# easier road to take. +# +# Revision 1.3 1999/08/17 03:31:30 beazley +# Minor cleanup. Removed Perl4 +# +# Revision 1.2 1999/02/28 02:44:43 beazley +# Initial cleanup +# +# Revision 1.1.1.1 1999/02/28 02:00:49 beazley +# Swig1.1 +# +# Revision 1.1 1996/08/12 01:55:02 dmb +# Initial revision +# +####################################################################### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +# +# Set the prefix below to indicate where you want SWIG to install its +# files. Normally this is /usr/local +# + +prefix = @prefix@ +exec_prefix= @exec_prefix@ + +# Location of the SWIG library. Is normally put in /usr/local/lib/swig_lib +# The SWIG library contains configuration files and library modules +# so you should install it someplace where it can be easily accessed. + +SWIG_LIB = $(prefix)/lib/swig_lib + +# Change these prefixes to set where you would like the +# SWIG binary file (swig) and C library (libswig.a) installed. +# Usually you don't need to change these unless you are +# installing SWIG into a CPU dependent directory such as /usr/local/bin/cpu-type/bin +# + +BIN_DIR = $(exec_prefix)/bin +LIB_DIR = $(exec_prefix)/lib + +# Other installation locations. Shouldn't need to change these unless you want + +INCLUDE_DIR = $(prefix)/include +MAN_DIR = $(prefix)/man/man1 + +SHELL = /bin/sh + +# --with-PACKAGE options for configure script. +WITH= + +# +# +# +# Rules for creation of a .o file from .cxx + +all: wxswig + @echo "Compilation complete." + +wxswig: Makefiles + @echo "Making the SWIG Parser..." + @cd SWIG; $(MAKE) + @echo "Make Modules..." + @cd Modules; $(MAKE) + +Makefiles: config.status + @cd SWIG; echo "making Makefile in subdirectory SWIG"; $(MAKE) Makefile + @cd Modules; echo "making Makefile in subdirectory Modules"; $(MAKE) Makefile + +Makefile: Makefile.in config.status + CONFIG_FILES=Makefile $(SHELL) config.status + +config.status: $(srcdir)/configure + if test -f config.status; \ + then $(SHELL) config.status --recheck; \ + $(SHELL) config.status; \ + else $(SHELL) $(srcdir)/configure $(WITH); \ + fi + +.PRECIOUS: config.status swig + +clean: + rm -f *.o *.so libswig.a swig *~ core + @cd SWIG; $(MAKE) clean + @cd Modules; $(MAKE) clean + @cd Runtime; $(MAKE) clean + +nuke: clean + @cd SWIG; $(MAKE) nuke + @cd Modules; $(MAKE) nuke + @cd Examples; $(MAKE) nuke + @cd Tests; $(MAKE) clean + @cd Runtime; $(MAKE) clean + rm -f Makefile Makefile.template config.* + +doc: swig + @echo "Building Documentation for SWIG library..." + ./swig -Iswig_lib -d ./Doc/swiglib ./swig_lib/autodoc.i + @rm -f swig_lib/autodoc_wrap* + + +runtime: swig + @cd Runtime; $(MAKE) + +test:: + cd Tests; $(MAKE) parser; $(MAKE) doc; $(MAKE) huge; + @echo "See test.log for errors" + @echo "type 'make testclean' to cleanup." + +testbuild:: + cd Tests; $(MAKE) build + +testall:: + cd Tests; $(MAKE) all; $(MAKE) clean + +# Only do this before releasing a distribution + +testclean:: + cd Tests; $(MAKE) clean; + + +## # Install the SWIG program +## +## INSTALL = ./install-sh -c +## INSTALL_DATA = ${INSTALL} -m 644 +## INSTALL_PROGRAM= ${INSTALL} -m 755 +## +## install: install-main install-lib install-runtime +## @echo "Installation complete" +## +## install-runtime: +## @cd Runtime; $(MAKE) install +## +## smallinstall: install-main +## +## install-main: +## @for i in $(LIB_DIR) $(INCLUDE_DIR) $(BIN_DIR) $(prefix)/man $(MAN_DIR); \ +## do \ +## if [ ! -d $$i ] ; then \ +## mkdir $$i; \ +## echo "Making directory $$i"; \ +## chmod 755 $$i;\ +## else true; \ +## fi; \ +## done; +## @echo "Installing $(BIN_DIR)/swig" +## @$(INSTALL_PROGRAM) swig $(BIN_DIR)/swig +## @echo "Installing $(LIB_DIR)/libswig.a..." +## @$(INSTALL_DATA) libswig.a $(LIB_DIR)/libswig.a +## @echo "Installing $(INCLUDE_DIR)/swig.h..." +## @$(INSTALL_DATA) Include/swig.h $(INCLUDE_DIR)/swig.h +## @echo "Installing $(INCLUDE_DIR)/swigver.h..." +## @$(INSTALL_DATA) Include/swigver.h $(INCLUDE_DIR)/swigver.h +## @echo "Installing $(MAN_DIR)/swig.1..." +## @$(INSTALL_DATA) swig.1 $(MAN_DIR)/swig.1 +## install-lib: +## @for i in $(SWIG_LIB) ; \ +## do \ +## if [ ! -d $$i ] ; then \ +## mkdir $$i; \ +## echo "Making directory $$i"; \ +## chmod 755 $$i;\ +## else true; \ +## fi; \ +## done; +## @echo "Installing the SWIG library" +## # cd $(SWIG_LIB); rm -rf * +## @for i in $(SWIG_LIB)/tcl $(SWIG_LIB)/perl5 $(SWIG_LIB)/python $(SWIG_LIB)/guile $(SWIG_LIB)/config ; \ +## do \ +## if [ ! -d $$i ] ; then \ +## mkdir $$i; \ +## echo "Making directory $$i"; \ +## chmod 755 $$i;\ +## else true; \ +## fi; \ +## done; +## @cd swig_lib; for i in *.i *.swg; \ +## do \ +## echo "Installing swig_lib/$$i"; \ +## ../$(INSTALL_DATA) $$i $(SWIG_LIB)/$$i; \ +## done; +## @cd swig_lib/tcl; for i in *.i *.swg Makefile; \ +## do \ +## echo "Installing swig_lib/tcl/$$i"; \ +## ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/tcl/$$i; \ +## done; +## @cd swig_lib/perl5; for i in *.i *.swg Makefile Makefile.pl; \ +## do \ +## echo "Installing swig_lib/perl5/$$i"; \ +## ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/perl5/$$i; \ +## done; +## @cd swig_lib/python; for i in *.i *.swg Makefile; \ +## do \ +## echo "Installing swig_lib/python/$$i"; \ +## ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/python/$$i; \ +## done; +## @cd swig_lib/guile; for i in *.i *.swg; \ +## do \ +## echo "Installing swig_lib/guile/$$i"; \ +## ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/guile/$$i; \ +## done; +## @cd swig_lib/config; for i in *.swg; \ +## do \ +## echo "Installing swig_lib/config/$$i"; \ +## ../../$(INSTALL_DATA) $$i $(SWIG_LIB)/config/$$i; \ +## done; +## @echo "Installing Makefile" +## $(INSTALL_DATA) Makefile.template $(SWIG_LIB)/Makefile + + + diff --git a/wxPython/wxSWIG/Modules/Makefile.in b/wxPython/wxSWIG/Modules/Makefile.in new file mode 100644 index 0000000000..8f74dbabcd --- /dev/null +++ b/wxPython/wxSWIG/Modules/Makefile.in @@ -0,0 +1,105 @@ +####################################################################### +# $Header$ +# Simplified Wrapper and Interface Generator (SWIG) +# +# Makefile for version 1.0 Final +# Dave Beazley +# August 1, 1996 +# +# This makefile is now mostly constructed by ./configure. +# +# $Log$ +# Revision 1.1 2002/04/29 19:56:47 RD +# Since I have made several changes to SWIG over the years to accomodate +# special cases and other things in wxPython, and since I plan on making +# several more, I've decided to put the SWIG sources in wxPython's CVS +# instead of relying on maintaining patches. This effectivly becomes a +# fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still +# doesn't have some things I rely on in 1.1, not to mention that my +# custom patches would all have to be redone, I felt that this is the +# easier road to take. +# +# Revision 1.2 1999/08/17 03:31:30 beazley +# Minor cleanup. Removed Perl4 +# +# Revision 1.1.1.1 1999/02/28 02:00:50 beazley +# Swig1.1 +# +# Revision 1.1 1996/08/12 01:55:02 dmb +# Initial revision +# +####################################################################### + +#.KEEP_STATE: + + +srcdir = @srcdir@ +VPATH = @srcdir@ + +# Set your C++ compiler here. g++ works on most machines, +# but you might have to change it depending on your installation. +# +CC = @CXX@ + +# +# Set the prefix below to indicate where you want SWIG to install its +# files. Normally this is /usr/local +# + +prefix = @prefix@ + +# Location of the SWIG library. Is normally put in /usr/local/lib/swig_lib +# The SWIG library contains configuration files and library modules +# so you should install it someplace where it can be easily accessed. + +SWIG_LIB = $(prefix)/lib/swig_lib + +######################################################################## +# Normally, you shouldn't have to change anything below this point # +######################################################################## + +WRAPOBJS = swigmain.o tcl.o tcl8.o perl5.o python.o pycpp.o guile.o debug.o +WRAPSRCS = swigmain.cxx tcl.cxx tcl8.cxx perl5.cxx python.cxx pycpp.cxx guile.cxx debug.cxx +WRAPHEADERS = ../Include/swig.h swigtcl.h perl5.h python.h guile.h debug.h wrap.h + +TARGET = ../wxswig +##-DSWIG_LIB='"$(SWIG_LIB)"' +CFLAGS = @CFLAGS@ -DSWIG_CC='"$(CC)"' @DEFS@ +INCLUDE = -I../Include -I../SWIG +LIBS = -L.. -lswig +SHELL = /bin/sh + +# +# +# +# Rules for creation of a .o file from .cxx +.SUFFIXES: .cxx +.cxx.o: + $(CC) $(INCLUDE) $(CFLAGS) -c -o $*.o $< + +all: $(TARGET) + +$(TARGET): $(WRAPOBJS) $(WRAPHEADERS) ../libswig.a + $(CC) $(INCLUDE) $(WRAPOBJS) $(LIBS) -o $(TARGET) + +swigmain.o: swigmain.cxx +tcl.o: tcl.cxx +perl5.o: perl5.cxx +python.o: python.cxx +pycpp.o: pycpp.cxx +guile.o: guile.cxx + +Makefile: $(srcdir)/Makefile.in ../config.status + (cd ..; CONFIG_FILES=Modules/Makefile $(SHELL) config.status) + +.PRECIOUS: Makefile + +clean:: + rm -f *.o $(TARGET) + +nuke:: + rm -f Makefile *~ #* core a.out + +wc:: + wc $(WRAPSRCS) *.h + diff --git a/wxPython/wxSWIG/Modules/debug.cxx b/wxPython/wxSWIG/Modules/debug.cxx new file mode 100644 index 0000000000..10f2805bcc --- /dev/null +++ b/wxPython/wxSWIG/Modules/debug.cxx @@ -0,0 +1,198 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ +/************************************************************************** + * $Header$ + * + * debug.cxx + * + * This is a dummy language module that is used only for testing the SWIG + * parser. + * + * It creates a wrapper file, but only containing descriptions of what + * was wrapped. + * + ***************************************************************************/ + +#include "swig.h" +#include "debug.h" + +void DEBUGLANG::parse_args(int, char **) { + sprintf(LibDir,"%s",path); + typemap_lang = "debug"; +} + +void DEBUGLANG::parse() { + headers(); + yyparse(); +} + +void DEBUGLANG::set_module(char *mod_name, char **) { + if (module) return; + module = new char[strlen(mod_name)+1]; + strcpy(module,mod_name); +} + +void DEBUGLANG::set_init(char *init_name) { + set_module(init_name,0); +} + +void DEBUGLANG::headers(void) { + fprintf(f_header,"/* DEBUG : Language specific headers go here */\n\n"); + fprintf(f_header,"/* DEBUG : Pointer conversion function here */\n\n"); + fprintf(f_header,"/* DEBUG : Language specific code here */\n\n"); +} + +void DEBUGLANG::initialize(void) { + + fprintf(f_header,"#define SWIG_init %s_init\n\n", module); + fprintf(f_header,"#define SWIG_name \"%s\"\n", module); + + fprintf(f_init,"\n/* MODULE INITIALIZATION */\n\n"); + fprintf(f_init,"void %s_init() {\n", module); + +} + +void DEBUGLANG::close(void) { + fprintf(f_init,"} /* END INIT */\n"); + + fprintf(f_wrappers,"SWIG POINTER-MAPPING TABLE\n\n"); + emit_ptr_equivalence(f_init); +} + +void DEBUGLANG::create_function(char *name, char *iname, DataType *d, ParmList *l) { + + fprintf(f_wrappers,"WRAPPER : "); + emit_extern_func(name,d,l,0,f_wrappers); + fprintf(f_wrappers,"\n"); + + fprintf(f_init," ADD COMMAND : %s --> ", iname); + emit_extern_func(name,d,l,0,f_init); + +} + +void DEBUGLANG::link_variable(char *name, char *iname, DataType *t) { + fprintf(f_wrappers,"WRAPPER : "); + emit_extern_var(name,t,0,f_wrappers); + + fprintf(f_init," ADD VARIABLE : %s --> ", iname); + emit_extern_var(name,t,0,f_init); + +} + +void DEBUGLANG::declare_const(char *name, char *, DataType *type, char *value) { + if (!value) value = "[None]"; + fprintf(f_init," ADD CONSTANT : %s %s = %s\n", type->print_cast(),name,value); +} + +void DEBUGLANG::add_native(char *name, char *funcname) { + fprintf(f_init," ADD NATIVE : %s --> %s\n", name, funcname); +} + +void DEBUGLANG::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) { + fprintf(f_wrappers," MEMBER FUNC : "); + emit_extern_func(name,t,l,0,f_wrappers); + fprintf(f_wrappers,"\n"); + if (!iname) iname = name; + fprintf(f_init," ADD MEMBER FUN : %s --> ", iname); + emit_extern_func(name,t,l,0,f_init); +} + +void DEBUGLANG::cpp_constructor(char *name, char *iname, ParmList *l) { + DataType *t; + fprintf(f_wrappers," CONSTRUCTOR : "); + t = new DataType(T_USER); + sprintf(t->name,"%s",name); + t->is_pointer=1; + emit_extern_func(name,t,l,0,f_wrappers); + if (!iname) iname = name; + fprintf(f_init," ADD CONSTRUCT : %s --> ", iname); + emit_extern_func(name,t,l,0,f_init); +} + +void DEBUGLANG::cpp_destructor(char *name, char *iname) { + fprintf(f_wrappers," DESTRUCTOR : ~%s();\n", name); + if (!iname) iname = name; + fprintf(f_init," ADD DESTRUCT : %s --> ~%s();\n",iname,name); +} + +void DEBUGLANG::cpp_open_class(char *name, char *iname, char *ctype, int strip) { + this->Language::cpp_open_class(name, iname, ctype,strip); + fprintf(f_wrappers,"C++ CLASS START : %s %s ========================================\n\n",ctype,name); + fprintf(f_init,"\n // C++ CLASS START : %s %s\n",ctype,name); +} + +void DEBUGLANG::cpp_close_class() { + fprintf(f_wrappers,"C++ CLASS END ===================================================\n\n"); + fprintf(f_init," // C++ CLASS END \n\n"); +} + +void DEBUGLANG::cpp_inherit(char **baseclass, int) { + int i = 0; + if (baseclass) { + fprintf(f_wrappers,"inheriting from baseclass :"); + while (baseclass[i]) { + fprintf(f_wrappers," %s",baseclass[i]); + i++; + } + fprintf(f_wrappers,"\n"); + } + this->Language::cpp_inherit(baseclass); +} + +void DEBUGLANG::cpp_variable(char *name, char *iname, DataType *t) { + fprintf(f_wrappers," ATTRIBUTE : "); + emit_extern_var(name,t,0,f_wrappers); + if (!iname) iname = name; + fprintf(f_init," ADD MEMBER : %s --> ", iname); + emit_extern_var(name,t,0,f_init); +} +void DEBUGLANG::cpp_static_func(char *name, char *iname, DataType *t, ParmList *l) { + + fprintf(f_wrappers," STATIC FUNC : "); + emit_extern_func(name,t,l,0,f_wrappers); + fprintf(f_init," ADD STATIC FUNC: %s --> ", iname); + emit_extern_func(name,t,l,0,f_init); + +} + +void DEBUGLANG::cpp_declare_const(char *name, char *iname, DataType *t, char *value) { + if (!value) value = "[None]"; + fprintf(f_wrappers," C++ CONST : %s %s = %s\n", t->print_cast(), name, value); + if (!iname) iname = name; + fprintf(f_init," ADD C++ CONST : %s --> %s = %s\n", iname, t->print_cast(), value); +} + +void DEBUGLANG::cpp_static_var(char *name, char *iname, DataType *t) { + fprintf(f_wrappers," C++ STATIC VAR: "); + emit_extern_var(name,t,0,f_wrappers); + if (!iname) iname = name; + fprintf(f_init," ADD STATIC VAR : %s --> ",iname); + emit_extern_var(name,t,0,f_init); +} + +void DEBUGLANG::pragma(char *lname, char *name, char *value) { + fprintf(f_wrappers,"PRAGMA : LANG = %s, NAME = %s ", lname, name); + if (value) { + fprintf(f_wrappers,", VALUE = %s\n", value); + } else { + fprintf(f_wrappers,"\n"); + } +} + +void DEBUGLANG::cpp_class_decl(char *name, char *, char *type) { + fprintf(f_wrappers,"C++ CLASS DECLARATION : %s %s\n", type,name); +} + + diff --git a/wxPython/wxSWIG/Modules/debug.h b/wxPython/wxSWIG/Modules/debug.h new file mode 100644 index 0000000000..1a0f8dd035 --- /dev/null +++ b/wxPython/wxSWIG/Modules/debug.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +class DEBUGLANG : public Language { +private: + char *path; + char *module; +public: + DEBUGLANG() { + path = "debug"; + module = "swig"; + } + void parse_args(int argc, char *argv[]); + void parse(); + void create_function(char *, char *, DataType *, ParmList *); + void link_variable(char *, char *, DataType *) ; + void declare_const(char *, char *, DataType *, char *); + void initialize(void); + void headers(void); + void close(void); + void set_module(char *mod_name, char **mod_list); + void set_init(char *init_name); + void add_native(char *, char *); + char *type_mangle(DataType *t) { + return t->print_mangle_default(); + } + void cpp_member_func(char *, char *, DataType *, ParmList *); + void cpp_constructor(char *, char *, ParmList *); + void cpp_destructor(char *, char *); + void cpp_open_class(char *, char *, char *, int strip); + void cpp_close_class(); + void cpp_inherit(char **, int mode = INHERIT_ALL); + void cpp_variable(char *, char *, DataType *); + void cpp_static_func(char *, char *, DataType *, ParmList *); + void cpp_declare_const(char *, char *, DataType *, char *); + void cpp_static_var(char *, char *, DataType *); + void pragma(char *, char *, char *); + void cpp_class_decl(char *, char *, char *); + +}; diff --git a/wxPython/wxSWIG/Modules/guile.cxx b/wxPython/wxSWIG/Modules/guile.cxx new file mode 100644 index 0000000000..36a00a307d --- /dev/null +++ b/wxPython/wxSWIG/Modules/guile.cxx @@ -0,0 +1,841 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/*********************************************************************** + * $Header$ + * + * guile.cxx + * + * Definitions for adding functions to Guile 3.0 + ***********************************************************************/ + +#include "swig.h" +#include "guile.h" + +static char *guile_usage = "\ +Guile Options (available with -guile)\n\ + None available. \n\n"; + +// --------------------------------------------------------------------- +// GUILE::parse_args(int argc, char *argv[]) +// +// Parse arguments. +// --------------------------------------------------------------------- + +void GUILE::parse_args(int argc, char *argv[]) { + + int i; + + sprintf(LibDir,"%s",guile_path); + + // Look for certain command line options + + // Look for additional command line options. + for (i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i],"-help") == 0) { + fputs(guile_usage,stderr); + SWIG_exit(0); + } + } + } + // Add a symbol for this module + + add_symbol("SWIGGUILE",0,0); + + // Set name of typemaps + + typemap_lang = "guile"; + +} + +// -------------------------------------------------------------------- +// GUILE::parse() +// +// Parse the input file +// -------------------------------------------------------------------- + +void GUILE::parse() +{ + + printf("Generating wrappers for Guile\n"); + + // Print out GUILE specific headers + + headers(); + + // Run the parser + + yyparse(); + +} + +// --------------------------------------------------------------------- +// GUILE::set_module(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 GUILE::set_module(char *mod_name, char **) { + + if (module) return; + + module = new char[strlen(mod_name)+1]; + strcpy(module,mod_name); + +} + +// --------------------------------------------------------------------- +// GUILE::set_init(char *iname) +// +// Sets the initialization function name. +// Does nothing if it's already set +// +//---------------------------------------------------------------------- + +void GUILE::set_init(char *iname) { + set_module(iname,0); +} + +// --------------------------------------------------------------------- +// GUILE::headers(void) +// +// Generate the appropriate header files for GUILE interface. +// ---------------------------------------------------------------------- + +void GUILE::headers(void) +{ + + emit_banner(f_header); + + fprintf(f_header,"/* Implementation : GUILE */\n\n"); + fprintf(f_header,"#define SWIGGUILE\n"); + fprintf(f_header,"#include \n"); + fprintf(f_header,"#include \n"); + fprintf(f_header,"#include \n"); + + // Write out hex conversion functions + + if (!NoInclude) { + if (insert_file("guile.swg", f_header) == -1) { + fprintf(stderr,"SWIG : Fatal error. Unable to locate 'guile.swg' in SWIG library.\n"); + SWIG_exit(1); + } + emit_hex(f_header); + } else { + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"extern \"C\" {\n"); + fprintf(f_header,"#endif\n"); + fprintf(f_header,"extern void SWIG_MakePtr(char *, void *, char *);\n"); + fprintf(f_header,"extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *));\n"); + fprintf(f_header,"extern char *SWIG_GetPtr(char *, void **, char *);\n"); + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"}\n"); + fprintf(f_header,"#endif\n"); + } +} + +// -------------------------------------------------------------------- +// GUILE::initialize() +// +// Output initialization code that registers functions with the +// interface. +// --------------------------------------------------------------------- +void GUILE::initialize() +{ + + int i; + + if (!module) { + module = "swig_init"; + fprintf(stderr,"SWIG : *** Warning. No module name specified.\n"); + } + + fprintf(f_header,"#define SWIG_init %s\n\n", module); + fprintf(f_init,"void %s() {\n", module); + + if (InitNames) { + i = 0; + while (InitNames[i]) { + fprintf(f_init,"\t %s();\n",InitNames[i]); + i++; + } + } +} + +// --------------------------------------------------------------------- +// GUILE::close(void) +// +// Wrap things up. Close initialization function. +// --------------------------------------------------------------------- + +void GUILE::close(void) +{ + + emit_ptr_equivalence(f_init); + fprintf(f_init,"}\n"); + +} + +// ---------------------------------------------------------------------- +// GUILE::get_pointer(int parm, DataType *t) +// +// Emits code to get a pointer from a parameter and do type checking. +// parm is the parameter number. This function is only used +// in create_function(). +// ---------------------------------------------------------------------- + +void GUILE::get_pointer(char *iname, int parm, DataType *t) { + + // Pointers are read as hex-strings with encoded type information + fprintf(f_wrappers,"\t _tempc = gh_scm2newstr(s_%d, &_len);\n",parm); + fprintf(f_wrappers,"\t if (SWIG_GetPtr(_tempc, (void **) &_arg%d,",parm); + if (t->type == T_VOID) fprintf(f_wrappers,"(char *) 0)) {\n"); + else + fprintf(f_wrappers,"\"%s\")) {\n", t->print_mangle()); + + // Now emit code according to the level of strictness desired + + switch(TypeStrict) { + case 0: // No type checking + fprintf(f_wrappers,"\t}\n"); + break; + case 1: // Warning message only + fprintf(f_wrappers, + "\t fprintf(stderr,\"Warning : type mismatch in argument %d of %s. Expected %s, received %%s\\n\", _tempc);\n", parm+1,iname, t->print_mangle()); + fprintf(f_wrappers,"\t }\n"); + break; + case 2: // Super strict mode. + +// fprintf(f_wrappers,"\t\t gscm_error(\"Type error in argument %d of %s. Expected %s.\", s_%d);\n", parm+1,iname,t->print_mangle(),parm); + fprintf(f_wrappers,"\t}\n"); + break; + + default : + fprintf(stderr,"Unknown strictness level\n"); + break; + } +} + +// ---------------------------------------------------------------------- +// GUILE::create_function(char *name, char *iname, DataType *d, +// ParmList *l) +// +// Create a function declaration and register it with the interpreter. +// ---------------------------------------------------------------------- + +void GUILE::create_function(char *name, char *iname, DataType *d, ParmList *l) +{ + + Parm *p; + int pcount; + char wname[256]; + char source[64]; + char target[64]; + char *tm; + String cleanup; + int need_len = 0; + int need_tempc = 0; + + // Make a wrapper name for this + + strcpy(wname,iname); + make_wrap_name(wname); + + // Now write the wrapper function itself....this is pretty ugly + + fprintf(f_wrappers,"SCM _wrap_gscm_%s(",wname); + + int i = 0; + p = l->get_first(); + while (p != 0) { + if (p->t->is_pointer) + need_len = 1; + if ((p->t->type != T_CHAR) && (p->t->is_pointer)) + need_tempc = 1; + + if ((p->t->type != T_VOID) || (p->t->is_pointer)) + fprintf(f_wrappers,"SCM s_%d", i); + if ((p = l->get_next())) + fprintf(f_wrappers,", "); + i++; + } + fprintf(f_wrappers,")\n{\n"); + + // Declare return variable and arguments + + pcount = emit_args(d,l,f_wrappers); + + // Now declare a few helper variables here + if (d->is_pointer && (d->type != T_CHAR) && + !typemap_lookup("out","guile",d,name,"_result","scmresult")) + fprintf(f_wrappers," char _ptemp[128];\n"); + if (need_tempc) + fprintf(f_wrappers," char *_tempc;\n"); + if (need_len) + fprintf(f_wrappers," int _len;\n"); + fprintf(f_wrappers," SCM scmresult; /* fun1 */\n"); + + // Now write code to extract the parameters(this is super ugly) + + i = 0; + p = l->get_first(); + while (p != 0) { + // Produce names of source and target + sprintf(source,"s_%d",i); + sprintf(target,"_arg%d",i); + + if ((tm = typemap_lookup("in","guile",p->t,p->name,source,target))) { + // Yep. Use it instead of the default + fprintf(f_wrappers,"%s\n", tm); + } else { + if (!p->t->is_pointer) { + switch(p->t->type) { + + // Signed Integers + + case T_INT : + case T_SINT : + case T_SHORT: + case T_SSHORT: + case T_LONG: + case T_SLONG: + case T_SCHAR: + fprintf(f_wrappers,"\t _arg%d = %s gh_scm2long(s_%d);\n",i, p->t->print_cast(), i); + break; + + // Unsigned Integers + + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + fprintf(f_wrappers,"\t _arg%d = %s gh_scm2ulong(s_%d);\n", i, p->t->print_cast(), i); + break; + + // A single character + + case T_CHAR : + fprintf(f_wrappers,"\t _arg%d = %s gh_scm2char(s_%d);\n", i, p->t->print_cast(), i); + break; + + // Floating point + + case T_DOUBLE : + case T_FLOAT: + fprintf(f_wrappers,"\t _arg%d = %s gh_scm2double(s_%d);\n", i, p->t->print_cast(), i); + break; + + // Void.. Do nothing. + + case T_VOID : + break; + + // This is some sort of user-defined call by value type. We're + // going to try and wing it here.... + + case T_USER: + + // User defined type not allowed by value. + + default : + fprintf(stderr,"%s : Line %d. Unable to use type %s as a function argument.\n", + input_file, line_number, p->t->print_type()); + break; + } + } else { + + // Argument is a pointer type. Special case is for char * + // since that is usually a string. + + if ((p->t->type == T_CHAR) && (p->t->is_pointer == 1)) { + fprintf(f_wrappers,"\t _arg%d = gh_scm2newstr(s_%d, &_len);\n",i,i); + } else { + + // Have a generic pointer type here. + + get_pointer(iname, i, p->t); + } + } + } + if ((tm = typemap_lookup("check","guile",p->t,p->name,source,target))) { + // Yep. Use it instead of the default + fprintf(f_wrappers,"%s\n",tm); + } + if ((tm = typemap_lookup("freearg","guile",p->t,p->name,target,"scmresult"))) { + // Yep. Use it instead of the default + cleanup << tm << "\n"; + } + p = l->get_next(); + i++; + } + + // Now write code to make the function call + + fprintf(f_wrappers,"\t SCM_DEFER_INTS;\n"); + emit_func_call(name,d,l,f_wrappers); + + fprintf(f_wrappers,"\t SCM_ALLOW_INTS;\n"); + // Now have return value, figure out what to do with it. + + if ((d->type != T_VOID) || (d->is_pointer)) { + if ((tm = typemap_lookup("out","guile",d,name,"_result","scmresult"))) { + // Yep. Use it instead of the default + fprintf(f_wrappers,"%s\n",tm); + } else { + if (!d->is_pointer) { + switch(d->type) { + case T_INT: case T_SINT: + case T_SHORT: case T_SSHORT: + case T_LONG: case T_SLONG: + case T_SCHAR: + fprintf(f_wrappers,"\t scmresult = gh_long2scm((long) _result);\n"); + break; + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + fprintf(f_wrappers,"\t scmresult = gh_ulong2scm((unsigned long) _result);\n"); + break; + case T_DOUBLE : + case T_FLOAT: + fprintf(f_wrappers,"\t scmresult = gh_double2scm((double) _result);\n"); + break; + case T_CHAR : + fprintf(f_wrappers,"\t scmresult = gh_char2scm(_result);\n"); + break; + default: + fprintf(stderr,"%s : Line %d: Unable to use return type %s in function %s.\n", + input_file, line_number, d->print_type(), name); + break; + } + } else { + + // Is a pointer return type + + if ((d->type == T_CHAR) && (d->is_pointer == 1)) { + fprintf(f_wrappers,"\t scmresult = gh_str02scm(_result);\n"); + } else { + + // Is an ordinary pointer type. + + fprintf(f_wrappers,"\t SWIG_MakePtr(_ptemp, _result,\"%s\");\n", + d->print_mangle()); + fprintf(f_wrappers,"\t scmresult = gh_str02scm(_ptemp);\n"); + } + } + } + } else { + /* Some void type. Need to return something. I'll return 1 */ + fprintf(f_wrappers,"\t scmresult = gh_int2scm(1);\n"); + } + + // Dump the argument cleanup code + fprintf(f_wrappers,"%s\n",cleanup.get()); + + // Look for any remaining cleanup + + if (NewObject) { + if ((tm = typemap_lookup("newfree","guile",d,iname,"_result",""))) { + fprintf(f_wrappers,"%s\n",tm); + } + } + + if ((tm = typemap_lookup("ret","guile",d,name,"_result",""))) { + // Yep. Use it instead of the default + fprintf(f_wrappers,"%s\n",tm); + } + + // Wrap things up (in a manner of speaking) + + fprintf(f_wrappers,"\t return scmresult;\n"); + fprintf(f_wrappers,"}\n"); + + // Now register the function + fprintf(f_init,"\t gh_new_procedure(\"%s\", _wrap_gscm_%s, %d, 0, 0);\n", + iname, wname, pcount); + + // Make a documentation entry for this + + if (doc_entry) { + static DocEntry *last_doc_entry = 0; + char *usage = 0; + usage_func(iname,d,l,&usage); + doc_entry->usage << usage; + if (last_doc_entry != doc_entry) { + doc_entry->cinfo << "returns " << d->print_type(); + last_doc_entry = doc_entry; + } + delete usage; + } +} + +// ----------------------------------------------------------------------- +// GUILE::link_variable(char *name, char *iname, DataType *d) +// +// Create a link to a C variable. +// This creates a single function _wrap_gscm_var_varname(). +// This function takes a single optional argument. If supplied, it means +// we are setting this variable to some value. If ommitted, it means we are +// simply evaluating this variable. Either way, we return the variables +// value. +// ----------------------------------------------------------------------- + +void GUILE::link_variable(char *name, char *iname, DataType *t) +{ + + char var_name[256]; + char *tm; + char *tm2 = typemap_lookup("varout","guile",t,name,name,"scmresult"); + + // evaluation function names + + sprintf(var_name,"_wrap_gscm_var_%s",iname); + + if ((t->type != T_USER) || (t->is_pointer)) { + + fprintf(f_wrappers,"SCM %s(SCM s_0) {\n", var_name); + + if (!(Status & STAT_READONLY) && (t->is_pointer)) { + fprintf(f_wrappers,"\t char *_temp;\n"); + fprintf(f_wrappers,"\t int _len;\n"); + } + + if (tm2) { + fprintf(f_wrappers,"\t char _ptemp[128];\n"); + } + fprintf(f_wrappers,"\t SCM scmresult; /* fun2 */\n"); + + // Check for a setting of the variable value + + fprintf(f_wrappers,"\t if (s_0 != GH_NOT_PASSED) {\n"); + + // Yup. Extract the type from s_0 and set variable value + if (Status & STAT_READONLY) { +// fprintf(f_wrappers,"\t\t gscm_error(\"Unable to set %s. Variable is read only.\", s_0);\n", iname); + } else { + if ((tm = typemap_lookup("varin","guile",t,name,"s_0",name))) { + // Yep. Use it instead of the default + fprintf(f_wrappers,"%s\n",tm); + } else { + if (!t->is_pointer) { + + switch(t->type) { + // Signed Integer + + case T_INT: case T_SINT: + case T_SHORT: case T_SSHORT: + case T_LONG: case T_SLONG: + case T_SCHAR: + fprintf(f_wrappers,"\t\t %s = %s gh_scm2long(s_0);\n",name, t->print_cast()); + break; + + // Unsigned integer + + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + fprintf(f_wrappers,"\t\t %s = %s gh_scm2ulong(s_0);\n",name, t->print_cast()); + break; + + // Floating point + + case T_FLOAT: + case T_DOUBLE: + fprintf(f_wrappers,"\t\t %s = %s gh_scm2double(s_0);\n",name, t->print_cast()); + break; + + // Character value + + case T_CHAR: + fprintf(f_wrappers,"\t\t %s = gh_scm2char(s_0);\n", name); + break; + + // Unknown value + + default: + fprintf(stderr,"Line %d. Error, unsupported data-type.\n", line_number); + break; + } + } else { + + // Have some sort of pointer type here, Process it differently + + if ((t->type == T_CHAR) && (t->is_pointer == 1)) { + fprintf(f_wrappers,"\t\t _temp = gh_scm2newstr(s_0, &_len);\n"); + fprintf(f_wrappers,"\t\t if (%s) { free(%s);}\n", name,name); + fprintf(f_wrappers,"\t\t %s = (char *) malloc((_len+1)*sizeof(char));\n",name); + fprintf(f_wrappers,"\t\t strncpy(%s,_temp,_len);\n",name); + fprintf(f_wrappers,"\t\t %s[_len] = 0;\n", name); + } else { + // Set the value of a pointer + fprintf(f_wrappers,"\t\t _temp = gh_scm2newstr(s_0,&_len);\n"); + fprintf(f_wrappers,"\t if (SWIG_GetPtr(_temp, (void **) &%s,",name); + if (t->type == T_VOID) fprintf(f_wrappers,"(char *) 0)) {\n"); + else + fprintf(f_wrappers,"\"%s\")) {\n", t->print_mangle()); + + // Now emit code according to the level of strictness desired + + switch(TypeStrict) { + case 0: // No type checking + fprintf(f_wrappers,"\t}\n"); + break; + case 1: // Warning message only + fprintf(f_wrappers, + "\t fprintf(stderr,\"Warning : type mismatch in variable %s. Expected %s, received %%s\\n\", _temp);\n", name, t->print_mangle()); + fprintf(f_wrappers,"\t }\n"); + break; + case 2: // Super strict mode. + +// fprintf(f_wrappers,"\t\t gscm_error(\"Type error in variable %s. Expected %s.\", s_0);\n", name,t->print_mangle()); + fprintf(f_wrappers,"\t}\n"); + break; + + default : + fprintf(stderr,"Unknown strictness level\n"); + break; + } + } + } + } + } + fprintf(f_wrappers,"\t}\n"); + + // Now return the value of the variable (regardless of evaluating or setting) + + if (tm2) { + // Yep. Use it instead of the default + fprintf(f_wrappers,"%s\n",tm); + } else { + if (!t->is_pointer) { + /* Return variable by value */ + + switch(t->type) { + + // Signed Integer + + case T_INT: case T_SINT: + case T_SHORT: case T_SSHORT: + case T_LONG: case T_SLONG: + case T_SCHAR: + fprintf(f_wrappers,"\t scmresult = gh_long2scm((long) %s);\n", name); + break; + + // Unsigned integer + + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + fprintf(f_wrappers,"\t scmresult = gh_ulong2scm((unsigned long) %s);\n",name); + break; + + // Floats + + case T_DOUBLE: + case T_FLOAT: + fprintf(f_wrappers,"\t scmresult = gh_double2scm((double) %s);\n", name); + break; + case T_CHAR: + fprintf(f_wrappers,"\t scmresult = gh_char2scm(%s);\n",name); + break; + default : + /* Unknown type */ + break; + } + } else { + + // Is a pointer return type + + if ((t->type == T_CHAR) && (t->is_pointer == 1)) { + fprintf(f_wrappers,"\t scmresult = gh_str02scm(%s);\n",name); + } else { + // Is an ordinary pointer type. + fprintf(f_wrappers,"\t SWIG_MakePtr(_ptemp, %s,\"%s\");\n",name, + t->print_mangle()); + fprintf(f_wrappers,"\t scmresult = gh_str02scm(_ptemp);\n"); + } + } + } + fprintf(f_wrappers,"\t return scmresult;\n"); + fprintf(f_wrappers,"}\n"); + + // Now add symbol to the Guile interpreter + + fprintf(f_init,"\t gh_new_procedure(\"%s\", %s, 0, 1, 0);\n",iname, var_name); + + } else { + fprintf(stderr,"%s : Line %d. ** Warning. Unable to link with type %s (ignored).\n", + input_file, line_number, t->print_type()); + } + + // Add a documentation entry + + if (doc_entry) { + char *usage = 0; + usage_var(iname,t,&usage); + doc_entry->usage << usage; + doc_entry->cinfo << "Global : " << t->print_type() << " " << name; + delete usage; + } + +} + +// ----------------------------------------------------------------------- +// GUILE::declare_const(char *name, char *iname, DataType *type, char *value) +// +// Makes a constant. Not sure how this is really supposed to work. +// I'm going to fake out SWIG and create a variable instead. +// ------------------------------------------------------------------------ + +void GUILE::declare_const(char *name, char *, DataType *type, char *value) { + + int OldStatus = Status; // Save old status flags + char var_name[256]; + + Status = STAT_READONLY; // Enable readonly mode. + + // Make a static variable; + + sprintf(var_name,"_wrap_const_%s",name); + + if ((type->type == T_USER) && (!type->is_pointer)) { + fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); + return; + } + + // Create variable and assign it a value + + fprintf(f_header,"static %s %s = ", type->print_type(), var_name); + if ((type->type == T_CHAR) && (type->is_pointer <= 1)) { + fprintf(f_header,"\"%s\";\n", value); + } else { + fprintf(f_header,"%s;\n", value); + } + + // Now create a variable declaration + + link_variable(var_name, name, type); + Status = OldStatus; + + if (doc_entry) { + char *usage = 0; + usage_const(name,type,value,&usage); + doc_entry->usage = ""; + doc_entry->usage << usage; + doc_entry->cinfo = ""; + doc_entry->cinfo << "Constant: " << type->print_type(); + delete usage; + } + +} + +// ---------------------------------------------------------------------- +// GUILE::usage_var(char *iname, DataType *t, char **s) +// +// Produces a usage string for a Guile variable. +// ---------------------------------------------------------------------- + +void GUILE::usage_var(char *iname, DataType *t, char **s) { + + char temp[1024], *c; + + sprintf(temp,"(%s)", iname); + c = temp + strlen(temp); + + if (!((t->type != T_USER) || (t->is_pointer))) { + sprintf(c," - unsupported"); + } + + if (*s == 0) + *s = new char[strlen(temp)+1]; + strcpy(*s,temp); +} + +// --------------------------------------------------------------------------- +// GUILE::usage_func(char *iname, DataType *t, ParmList *l, char **s) +// +// Produces a usage string for a function in Guile +// --------------------------------------------------------------------------- + +void GUILE::usage_func(char *iname, DataType *, ParmList *l, + char **s) { + + char temp[1024]; + char *c; + int i; + Parm *p; + + sprintf(temp,"(%s ", iname); + c = temp + strlen(temp); + + /* Now go through and print parameters */ + + p = l->get_first(); + while (p != 0) { + + /* If parameter has been named, use that. Otherwise, just print a type */ + + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + if (strlen(p->name) > 0) { + sprintf(c,"%s ",p->name); + c += strlen(p->name)+1; + } + else { + sprintf(c,"%s",p->t->name); + c += strlen(p->t->name); + if (p->t->is_pointer) { + for (i = 0; i < (p->t->is_pointer-p->t->implicit_ptr); i++) { + sprintf(c,"*"); + c++; + } + } + } + } + p = l->get_next(); + if (p != 0) { + sprintf(c," "); + c++; + } + } + sprintf(c,")"); + if (*s == 0) + *s = new char[strlen(temp)+1]; + strcpy(*s,temp); +} + + +// ---------------------------------------------------------------------- +// GUILE::usage_const(char *iname, DataType *type, char *value, char **s) +// +// Produces a usage string for a Guile constant +// ---------------------------------------------------------------------- + +void GUILE::usage_const(char *iname, DataType *, char *value, char **s) { + + char temp[1024]; + + sprintf(temp,"(%s %s)", iname, value); + + if (*s == 0) + *s = new char[strlen(temp)+1]; + strcpy(*s,temp); + +} diff --git a/wxPython/wxSWIG/Modules/guile.h b/wxPython/wxSWIG/Modules/guile.h new file mode 100644 index 0000000000..ffde1c4a25 --- /dev/null +++ b/wxPython/wxSWIG/Modules/guile.h @@ -0,0 +1,57 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/************************************************************************** + * $Header$ + * + * class GUILE + * + * Guile implementation + * (Caution : This is *somewhat* experimental) + * + * Seeking : highly motivated individual with plenty of spare time and + * a love of Guile. Must be willing to modify this code and + * make it better. + **************************************************************************/ + +class GUILE : public Language { +private: + char *guile_path; + char *module; + void get_pointer(char *iname, int parm, DataType *t); + void usage_var(char *, DataType *, char **); + void usage_func(char *, DataType *, ParmList *, char **); + void usage_const(char *, DataType *, char *, char **); +public : + GUILE() { + module = 0; + guile_path = "guile"; + } + void parse_args(int, char *argv[]); + void parse(); + void create_function(char *, char *, DataType *, ParmList *); + void link_variable(char *, char *, DataType *); + void declare_const(char *, char *, DataType *, char *); + void initialize(); + void headers(void); + void close(void); + void set_module(char *, char **); + void set_init(char *); + void create_command(char *, char *) { }; +}; + + + + diff --git a/wxPython/wxSWIG/Modules/makefile.vc b/wxPython/wxSWIG/Modules/makefile.vc new file mode 100644 index 0000000000..f46f3f69d0 --- /dev/null +++ b/wxPython/wxSWIG/Modules/makefile.vc @@ -0,0 +1,79 @@ +# Modified from automatic creation by Kevin Butler (butler@byu.edu) +# for Microsoft Visual C++ (11/22/96) +# +####################################################################### +# $Header$ +# Simplified Wrapper and Interface Generator (SWIG) +# +# Makefile for version 1.0 Final +# Dave Beazley +# August 1, 1996 +# +# This makefile is now mostly constructed by ./configure. +# +# $Log$ +# Revision 1.1 2002/04/29 19:56:47 RD +# Since I have made several changes to SWIG over the years to accomodate +# special cases and other things in wxPython, and since I plan on making +# several more, I've decided to put the SWIG sources in wxPython's CVS +# instead of relying on maintaining patches. This effectivly becomes a +# fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still +# doesn't have some things I rely on in 1.1, not to mention that my +# custom patches would all have to be redone, I felt that this is the +# easier road to take. +# +# Revision 1.2 1999/08/17 03:31:30 beazley +# Minor cleanup. Removed Perl4 +# +# Revision 1.1.1.1 1999/02/28 02:00:50 beazley +# Swig1.1 +# +# Revision 1.1 1996/08/12 01:55:02 dmb +# Initial revision +# +####################################################################### + +#.KEEP_STATE: + +rootdir = .. +!include <..\make_win.in> + + +######################################################################## +# Normally, you shouldn't have to change anything below this point # +######################################################################## + + + +WRAPOBJS = swigmain.obj tcl.obj tcl8.obj perl5.obj python.obj pycpp.obj debug.obj guile.obj +WRAPSRCS = swigmain.cxx tcl.cxx tcl8.cxx perl5.cxx python.cxx pycpp.cxx debug.cxx guile.cxx +WRAPHEADERS = $(rootdir)/Include/swig.h swigtcl.h tcl8.h perl5.h python.h guile.h debug.h \ + wrap.h + +TARGET = $(rootdir)\wxswig.exe +LIBNAME = $(rootdir)\libswig.lib +LIBS = $(LIBNAME) + +# +# Rules for creation of a .obj file from .cxx +.SUFFIXES: .cxx +.cxx.obj: + $(CC) $(INCFLAGS) $(CFLAGS) -c -o $*.obj $< + +all: $(TARGET) + +$(TARGET): $(WRAPOBJS) $(WRAPHEADERS) $(LIBNAME) + $(CC) -o $(TARGET) $(INCFLAGS) $(WRAPOBJS) $(LIBS) + +swigmain.obj: swigmain.cxx +tcl.obj: tcl.cxx +perl5.obj: perl5.cxx +python.obj: python.cxx +pycpp.obj: pycpp.cxx +guile.obj: guile.cxx + + +clean:: + del *.obj + del $(TARGET) + diff --git a/wxPython/wxSWIG/Modules/perl5.cxx b/wxPython/wxSWIG/Modules/perl5.cxx new file mode 100644 index 0000000000..d9b334c3ed --- /dev/null +++ b/wxPython/wxSWIG/Modules/perl5.cxx @@ -0,0 +1,2271 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/*********************************************************************** + * $Header$ + * + * perl5.c + * + * Definitions for adding functions to Perl 5 + * + * How to extend perl5 (note : this is totally different in Perl 4) : + * + * 1. Variable linkage + * + * Must declare two functions : + * + * _var_set(SV *sv, MAGIC *mg); + * _var_get(SV *sv, MAGIC *mg); + * + * These functions must set/get the values of a variable using + * Perl5 internals. + * + * To add these to Perl5 (which isn't entirely clear), need to + * do the following : + * + * SV *sv; + * MAGIC *m; + * sv = perl_get_sv("varname",TRUE); + * sv_magic(sv,sv, 'U', "varname", strlen("varname)); + * m = mg_find(sv, 'U'); + * m->mg_virtual = (MGVTBL *) malloc(sizeof(MGVTBL)); + * m->mg_virtual.svt_get = _var_set; + * m->mg_virtual.svt_set = _var_get; + * m->mg_virtual.svt_len = 0; + * m->mg_virtual.svt_free = 0; + * m->mg_virtual.svt_clear = 0; + * + * + * 2. Function extension + * + * Functions are declared as : + * XS(_wrap_func) { + * dXSARGS; + * if (items != parmcount) { + * croak("Usage :"); + * } + * ... get arguments ... + * + * ... call function ... + * ... set return value in ST(0) + * XSRETURN(1); + * } + * To extract function arguments, use the following : + * _arg = (int) SvIV(ST(0)) + * _arg = (double) SvNV(ST(0)) + * _arg = (char *) SvPV(ST(0),na); + * + * For return values, use : + * ST(0) = sv_newmortal(); + * sv_setiv(ST(0), (IV) RETVAL); // Integers + * sv_setnv(ST(0), (double) RETVAL); // Doubles + * sv_setpv((SV*) ST(0), RETVAL); // Strings + * + * New functions are added using + * newXS("name", _wrap_func, file) + * + * + * 3. Compilation. + * + * Code should be compiled into an object file for dynamic + * loading into Perl. + ***********************************************************************/ + +#include "swig.h" +#include "perl5.h" + +static String pragma_include; + +static char *usage = "\ +Perl5 Options (available with -perl5)\n\ + -module name - Set module name\n\ + -package name - Set package prefix\n\ + -static - Omit code related to dynamic loading.\n\ + -shadow - Create shadow classes.\n\ + -compat - Compatibility mode.\n\ + -alt-header file- Use an alternate header.\n\n"; + +static char *import_file = 0; +static char *smodule = 0; +static int compat = 0; + +// --------------------------------------------------------------------- +// PERL5::parse_args(int argc, char *argv[]) +// +// Parse command line options. +// --------------------------------------------------------------------- + +void +PERL5::parse_args(int argc, char *argv[]) { + + int i = 1; + + export_all = 0; + sprintf(LibDir,"%s", perl_path); + + // Look for certain command line options + + // Get options + for (i = 1; i < argc; i++) { + if (argv[i]) { + if(strcmp(argv[i],"-package") == 0) { + if (argv[i+1]) { + package = new char[strlen(argv[i+1])+1]; + strcpy(package, argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-module") == 0) { + if (argv[i+1]) { + module = new char[strlen(argv[i+1])+1]; + strcpy(module, argv[i+1]); + cmodule = module; + cmodule.replace(":","_"); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-exportall") == 0) { + export_all = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-static") == 0) { + is_static = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-shadow") == 0) { + blessed = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-alt-header") == 0) { + if (argv[i+1]) { + alt_header = copy_string(argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-compat") == 0) { + compat = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + } + } + } + // Add a symbol for this module + + add_symbol("SWIGPERL",0,0); + add_symbol("SWIGPERL5",0,0); + + // Set name of typemaps + + typemap_lang = "perl5"; + +} + +// ------------------------------------------------------------------ +// PERL5::parse() +// +// Parse an interface file +// ------------------------------------------------------------------ + +void +PERL5::parse() { + + + printf("Generating wrappers for Perl 5\n"); + + // Print out PERL5 specific headers + + headers(); + + // Run the parser + + yyparse(); + fputs(vinit.get(),f_wrappers); +} + + +// --------------------------------------------------------------------- +// PERL5::set_module(char *mod_name, char **mod_list) +// +// Sets the module name. +// Does nothing if it's already set (so it can be overridden as a command +// line option). +// +//---------------------------------------------------------------------- +static String modinit, modextern; + +void PERL5::set_module(char *mod_name, char **mod_list) { + int i; + if (import_file) { + if (!(strcmp(import_file,input_file+strlen(input_file)-strlen(import_file)))) { + if (blessed) { + fprintf(f_pm,"require %s;\n", mod_name); + } + delete [] import_file; + import_file = 0; + } + } + + if (module) return; + + module = new char[strlen(mod_name)+1]; + strcpy(module,mod_name); + + // if there was a mod_list specified, make this big hack + if (mod_list) { + modinit << "#define SWIGMODINIT "; + modextern << "#ifdef __cplusplus\n" + << "extern \"C\" {\n" + << "#endif\n"; + i = 0; + while(mod_list[i]) { + modinit << "newXS(\"" << mod_list[i] << "::boot_" << mod_list[i] << "\", boot_" << mod_list[i] << ", file);\\\n"; + modextern << "extern void boot_" << mod_list[i] << "(CV *);\n"; + i++; + } + modextern << "#ifdef __cplusplus\n" + << "}\n" + << "#endif\n"; + modinit << "/* End of extern module initialization */\n"; + } + + // Create a C module name and put it in 'cmodule' + + cmodule = module; + cmodule.replace(":","_"); +} + +// --------------------------------------------------------------------- +// PERL5::set_init(char *iname) +// +// Sets the initialization function name. +// Does nothing if it's already set +// +//---------------------------------------------------------------------- + +void PERL5::set_init(char *iname) { + set_module(iname,0); +} + +// --------------------------------------------------------------------- +// PERL5::headers(void) +// +// Generate the appropriate header files for PERL5 interface. +// ---------------------------------------------------------------------- + +void PERL5::headers(void) +{ + + emit_banner(f_header); + + if (!alt_header) { + if (insert_file("headers.swg", f_header) == -1) { + fprintf(stderr,"Perl5 : Fatal error. Unable to locate headers.swg. Possible installation problem.\n"); + SWIG_exit(1); + } + } else { + if (insert_file(alt_header, f_header) == -1) { + fprintf(stderr,"SWIG : Fatal error. Unable to locate %s.\n",alt_header); + SWIG_exit(1); + } + } + + if (NoInclude) { + fprintf(f_header,"#define SWIG_NOINCLUDE\n"); + } + + // Get special SWIG related declarations + if (insert_file("perl5.swg", f_header) == -1) { + fprintf(stderr,"SWIG : Fatal error. Unable to locate 'perl5.swg' in SWIG library.\n"); + SWIG_exit(1); + } + + // Get special SWIG related declarations + if (insert_file("perl5mg.swg", f_header) == -1) { + fprintf(stderr,"SWIG : Fatal error. Unable to locate 'perl5mg.swg' in SWIG library.\n"); + SWIG_exit(1); + } + +} + +// -------------------------------------------------------------------- +// PERL5::initialize() +// +// Output initialization code that registers functions with the +// interface. +// --------------------------------------------------------------------- + +void PERL5::initialize() +{ + + char filen[256]; + + if (!module){ + module = "swig"; + fprintf(stderr,"SWIG : *** Warning. No module name specified.\n"); + } + + if (!package) { + package = new char[strlen(module)+1]; + strcpy(package,module); + } + + // If we're in blessed mode, change the package name to "packagec" + + if (blessed) { + char *newpackage = new char[strlen(package)+2]; + sprintf(newpackage,"%sc",package); + realpackage = package; + package = newpackage; + } else { + realpackage = package; + } + + // Create a .pm file + // Need to strip off any prefixes that might be found in + // the module name + + { + char *m = module + strlen(module); + while (m != module) { + if (*m == ':') { + m++; + break; + } + m--; + } + sprintf(filen,"%s%s.pm", output_dir,m); + if ((f_pm = fopen(filen,"w")) == 0) { + fprintf(stderr,"Unable to open %s\n", filen); + SWIG_exit(0); + } + } + if (!blessed) { + smodule = module; + } else if (is_static) { + smodule = new char[strlen(module)+2]; + strcpy(smodule,module); + strcat(smodule,"c"); + cmodule << "c"; + } else { + smodule = module; + } + + fprintf(f_header,"#define SWIG_init boot_%s\n\n", cmodule.get()); + fprintf(f_header,"#define SWIG_name \"%s::boot_%s\"\n", package, cmodule.get()); + fprintf(f_header,"#define SWIG_varinit \"%s::var_%s_init();\"\n", package, cmodule.get()); + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"extern \"C\"\n"); + fprintf(f_header,"#endif\n"); + fprintf(f_header,"#ifndef PERL_OBJECT\n"); + fprintf(f_header,"SWIGEXPORT(void) boot_%s(CV* cv);\n", cmodule.get()); + fprintf(f_header,"#else\n"); + fprintf(f_header,"SWIGEXPORT(void) boot_%s(CV *cv, CPerlObj *);\n",cmodule.get()); + fprintf(f_header,"#endif\n"); + fprintf(f_init,"#ifdef __cplusplus\n"); + fprintf(f_init,"extern \"C\"\n"); + fprintf(f_init,"#endif\n"); + fprintf(f_init,"XS(boot_%s) {\n", cmodule.get()); + fprintf(f_init,"\t dXSARGS;\n"); + fprintf(f_init,"\t char *file = __FILE__;\n"); + fprintf(f_init,"\t cv = cv; items = items;\n"); + fprintf(f_init,"\t newXS(\"%s::var_%s_init\", _wrap_perl5_%s_var_init, file);\n",package,cmodule.get(), cmodule.get()); + vinit << "XS(_wrap_perl5_" << cmodule << "_var_init) {\n" + << tab4 << "dXSARGS;\n" + << tab4 << "SV *sv;\n" + << tab4 << "cv = cv; items = items;\n"; + + fprintf(f_pm,"# This file was automatically generated by SWIG\n"); + fprintf(f_pm,"package %s;\n",module); + fprintf(f_pm,"require Exporter;\n"); + if (!is_static) { + fprintf(f_pm,"require DynaLoader;\n"); + fprintf(f_pm,"@ISA = qw(Exporter DynaLoader);\n"); + } else { + fprintf(f_pm,"@ISA = qw(Exporter);\n"); + } + + // Start creating magic code + + + magic << "#ifdef PERL_OBJECT\n" + << "#define MAGIC_CLASS _wrap_" << module << "_var::\n" + << "class _wrap_" << module << "_var : public CPerlObj {\n" + << "public:\n" + << "#else\n" + << "#define MAGIC_CLASS\n" + << "#endif\n" + << "SWIGCLASS_STATIC int swig_magic_readonly(SV *sv, MAGIC *mg) {\n" + << tab4 << "MAGIC_PPERL\n" + << tab4 << "sv = sv; mg = mg;\n" + << tab4 << "croak(\"Value is read-only.\");\n" + << tab4 << "return 0;\n" + << "}\n"; // Dump out external module declarations + + /* Process additional initialization files here */ + + if (strlen(modinit.get()) > 0) { + fprintf(f_header,"%s\n",modinit.get()); + } + if (strlen(modextern.get()) > 0) { + fprintf(f_header,"%s\n",modextern.get()); + } +} + +// --------------------------------------------------------------------- +// PERL5::import(char *filename) +// +// Import directive +// --------------------------------------------------------------------- + +void PERL5::import(char *filename) { + if (import_file) delete [] import_file; + import_file = copy_string(filename); +} + + +// --------------------------------------------------------------------- +// PERL5::close(void) +// +// Wrap things up. Close initialization function. +// --------------------------------------------------------------------- + +void PERL5::close(void) +{ + String base; + + // Dump out variable wrappers + + magic << "\n\n#ifdef PERL_OBJECT\n" + << "};\n" + << "#endif\n"; + + fprintf(f_header,"%s\n", magic.get()); + + emit_ptr_equivalence(f_init); + + fprintf(f_init,"\t ST(0) = &PL_sv_yes;\n"); + fprintf(f_init,"\t XSRETURN(1);\n"); + fprintf(f_init,"}\n"); + + vinit << tab4 << "XSRETURN(1);\n" + << "}\n"; + + fprintf(f_pm,"package %s;\n", package); + + if (!is_static) { + fprintf(f_pm,"bootstrap %s;\n", smodule); + } else { + fprintf(f_pm,"boot_%s();\n", smodule); + } + fprintf(f_pm,"var_%s_init();\n", cmodule.get()); + fprintf(f_pm,"%s",pragma_include.get()); + fprintf(f_pm,"package %s;\n", realpackage); + fprintf(f_pm,"@EXPORT = qw(%s );\n",exported.get()); + + if (blessed) { + + base << "\n# ---------- BASE METHODS -------------\n\n" + << "package " << realpackage << ";\n\n"; + + // Write out the TIE method + + base << "sub TIEHASH {\n" + << tab4 << "my ($classname,$obj) = @_;\n" + << tab4 << "return bless $obj, $classname;\n" + << "}\n\n"; + + // 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. + + base << "sub CLEAR { }\n\n"; + + // Output default firstkey/nextkey methods + + base << "sub FIRSTKEY { }\n\n"; + base << "sub NEXTKEY { }\n\n"; + + // Output a 'this' method + + base << "sub this {\n" + << tab4 << "my $ptr = shift;\n" + << tab4 << "return tied(%$ptr);\n" + << "}\n\n"; + + fprintf(f_pm,"%s",base.get()); + + // Emit function stubs for stand-alone functions + + fprintf(f_pm,"\n# ------- FUNCTION WRAPPERS --------\n\n"); + fprintf(f_pm,"package %s;\n\n",realpackage); + fprintf(f_pm,"%s",func_stubs.get()); + + + // Emit package code for different classes + + fprintf(f_pm,"%s",pm.get()); + + // Emit variable stubs + + fprintf(f_pm,"\n# ------- VARIABLE STUBS --------\n\n"); + fprintf(f_pm,"package %s;\n\n",realpackage); + fprintf(f_pm,"%s",var_stubs.get()); + + } + + fprintf(f_pm,"1;\n"); + fclose(f_pm); + + // Patch up documentation title + + if ((doc_entry) && (module)) { + doc_entry->cinfo << "Module : " << module << ", " + << "Package : " << realpackage; + } + +} + +// ---------------------------------------------------------------------- +// char *PERL5::type_mangle(DataType *t) +// +// Mangles a datatype into a Perl5 name compatible with xsubpp type +// T_PTROBJ. +// ---------------------------------------------------------------------- + +char * +PERL5::type_mangle(DataType *t) { + static char result[128]; + int i; + char *r, *c; + + if (blessed) { + + // Check to see if we've blessed this datatype + + if ((classes.lookup(t->name)) && (t->is_pointer <= 1)) { + + // This is a blessed class. Return just the type-name + strcpy(result,(char *) classes.lookup(t->name)); + return result; + } + } + + r = result; + c = t->name; + + for ( c = t->name; *c; c++,r++) { + *r = *c; + } + for (i = 0; i < (t->is_pointer-t->implicit_ptr); i++, r++) { + strcpy(r,"Ptr"); + r+=2; + } + *r = 0; + return result; +} + +// ---------------------------------------------------------------------- +// PERL5::get_pointer(char *iname, char *srcname, char *src, char *target, +// DataType *t, String &f, char *ret) +// +// Emits code to get a pointer from a parameter and do type checking. +// ---------------------------------------------------------------------- + +void PERL5::get_pointer(char *iname, char *srcname, char *src, char *dest, + DataType *t, String &f, char *ret) { + + // Now get the pointer value from the string and save in dest + + f << tab4 << "if (SWIG_GetPtr(" << src << ",(void **) &" << dest << ","; + + // If we're passing a void pointer, we give the pointer conversion a NULL + // pointer, otherwise pass in the expected type. + + if (t->type == T_VOID) f << "(char *) 0 )) {\n"; + else + f << "\"" << t->print_mangle() << "\")) {\n"; + + // This part handles the type checking according to three different + // levels. 0 = no checking, 1 = warning message, 2 = strict. + + switch(TypeStrict) { + case 0: // No type checking + f << tab4 << "}\n"; + break; + + case 1: // Warning message only + + // Change this part to how you want to handle a type-mismatch warning. + // By default, it will just print to stderr. + + f << tab8 << "fprintf(stderr,\"Warning : type mismatch in " << srcname + << " of " << iname << ". Expected " << t->print_mangle() + << ", received %s\\n\"," << src << ");\n" + << tab4 << "}\n"; + + break; + case 2: // Super strict mode. + + // Change this part to return an error. + + f << tab8 << "croak(\"Type error in " << srcname + << " of " << iname << ". Expected " << t->print_mangle() << ".\");\n" + << tab8 << ret << ";\n" + << tab4 << "}\n"; + + break; + + default : + fprintf(stderr,"SWIG Error. Unknown strictness level\n"); + break; + } +} + +// ---------------------------------------------------------------------- +// PERL5::create_command(char *cname, char *iname) +// +// Create a command and register it with the interpreter +// ---------------------------------------------------------------------- + +void PERL5::create_command(char *cname, char *iname) { + fprintf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package, iname, name_wrapper(cname,"")); + if (export_all) { + exported << iname << " "; + } +} + +// ---------------------------------------------------------------------- +// PERL5::create_function(char *name, char *iname, DataType *d, +// ParmList *l) +// +// Create a function declaration and register it with the interpreter. +// ---------------------------------------------------------------------- + +void PERL5::create_function(char *name, char *iname, DataType *d, ParmList *l) +{ + Parm *p; + int pcount,i,j; + char *wname; + char *usage = 0; + WrapperFunction f; + char source[256],target[256],temp[256], argnum[32]; + char *tm; + String cleanup,outarg,build; + int numopt = 0; + int need_save, num_saved = 0; // Number of saved arguments. + int have_build = 0; + + // Make a wrapper name for this + + wname = name_wrapper(iname,""); + + // Now write the wrapper function itself....this is pretty ugly + + f.def << "XS(" << wname << ") {\n"; + f.code << tab4 << "cv = cv;\n"; + + pcount = emit_args(d, l, f); + numopt = l->numopt(); + + f.add_local("int","argvi = 0"); + + // Check the number of arguments + + usage = usage_func(iname,d,l); + f.code << tab4 << "if ((items < " << (pcount-numopt) << ") || (items > " << l->numarg() << ")) \n" + << tab8 << "croak(\"Usage: " << usage << "\");\n"; + + // Write code to extract parameters. + // This section should be able to extract virtually any kind + // parameter, represented as a string + + i = 0; + j = 0; + p = l->get_first(); + while (p != 0) { + // Produce string representation of source and target arguments + sprintf(source,"ST(%d)",j); + sprintf(target,"_arg%d",i); + sprintf(argnum,"%d",j+1); + + // Check to see if this argument is being ignored + + if (!p->ignore) { + + // If there are optional arguments, check for this + + if (j>= (pcount-numopt)) + f.code << tab4 << "if (items > " << j << ") {\n"; + + // See if there is a type-map + if ((tm = typemap_lookup("in","perl5",p->t,p->name,source,target,&f))) { + f.code << tm << "\n"; + f.code.replace("$argnum",argnum); + f.code.replace("$arg",source); + } else { + + if (!p->t->is_pointer) { + + // Extract a parameter by "value" + + switch(p->t->type) { + + // Integers + + case T_BOOL: + case T_INT : + case T_SHORT : + case T_LONG : + case T_SINT : + case T_SSHORT: + case T_SLONG: + case T_SCHAR: + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + f.code << tab4 << "_arg" << i << " = " << p->t->print_cast() + << "SvIV(ST(" << j << "));\n"; + break; + case T_CHAR : + + + + f.code << tab4 << "_arg" << i << " = (char) *SvPV(ST(" << j << "),PL_na);\n"; + break; + + // Doubles + + case T_DOUBLE : + case T_FLOAT : + f.code << tab4 << "_arg" << i << " = " << p->t->print_cast() + << " SvNV(ST(" << j << "));\n"; + break; + + // Void.. Do nothing. + + case T_VOID : + break; + + // User defined. This is invalid here. Note, user-defined types by + // value are handled in the parser. + + case T_USER: + + // Unsupported data type + + default : + fprintf(stderr,"%s : Line %d. Unable to use type %s as a function argument.\n",input_file, line_number, p->t->print_type()); + break; + } + } else { + + // Argument is a pointer type. Special case is for char * + // since that is usually a string. + + if ((p->t->type == T_CHAR) && (p->t->is_pointer == 1)) { + f.code << tab4 << "if (! SvOK((SV*) ST(" << j << "))) { " + << "_arg" << i << " = 0; }\n"; + f.code << tab4 << "else { _arg" + << i << " = (char *) SvPV(ST(" << j << "),PL_na); }\n"; + } else { + + // Have a generic pointer type here. Read it in as a swig + // typed pointer. + + sprintf(temp,"argument %d", i+1); + get_pointer(iname,temp,source,target, p->t, f.code, "XSRETURN(1)"); + } + } + } + // The source is going to be an array of saved values. + + sprintf(temp,"_saved[%d]",num_saved); + if (j>= (pcount-numopt)) + f.code << tab4 << "} \n"; + j++; + } else { + temp[0] = 0; + } + // Check to see if there is any sort of "build" typemap (highly complicated) + + if ((tm = typemap_lookup("build","perl5",p->t,p->name,source,target))) { + build << tm << "\n"; + have_build = 1; + } + + // Check if there is any constraint code + if ((tm = typemap_lookup("check","perl5",p->t,p->name,source,target))) { + f.code << tm << "\n"; + f.code.replace("$argnum",argnum); + } + need_save = 0; + + if ((tm = typemap_lookup("freearg","perl5",p->t,p->name,target,temp))) { + cleanup << tm << "\n"; + cleanup.replace("$argnum",argnum); + cleanup.replace("$arg",temp); + need_save = 1; + } + if ((tm = typemap_lookup("argout","perl5",p->t,p->name,target,"ST(argvi)"))) { + String tempstr; + tempstr = tm; + tempstr.replace("$argnum",argnum); + tempstr.replace("$arg",temp); + outarg << tempstr << "\n"; + need_save = 1; + } + // If we needed a saved variable, we need to emit to emit some code for that + // This only applies if the argument actually existed (not ignore) + if ((need_save) && (!p->ignore)) { + f.code << tab4 << temp << " = " << source << ";\n"; + num_saved++; + } + p = l->get_next(); + i++; + } + + // If there were any saved arguments, emit a local variable for them + + if (num_saved) { + sprintf(temp,"_saved[%d]",num_saved); + f.add_local("SV *",temp); + } + + // If there was a "build" typemap, we need to go in and perform a serious hack + + if (have_build) { + char temp1[32]; + char temp2[256]; + l->sub_parmnames(build); // Replace all parameter names + j = 1; + for (i = 0; i < l->nparms; i++) { + p = l->get(i); + if (strlen(p->name) > 0) { + sprintf(temp1,"_in_%s", p->name); + } else { + sprintf(temp1,"_in_arg%d", i); + } + sprintf(temp2,"argv[%d]",j); + build.replaceid(temp1,temp2); + if (!p->ignore) + j++; + } + f.code << build; + } + + // Now write code to make the function call + + emit_func_call(name,d,l,f); + + // See if there was a typemap + + if ((tm = typemap_lookup("out","perl5",d,iname,"_result","ST(argvi)"))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + } else if ((d->type != T_VOID) || (d->is_pointer)) { + if (!d->is_pointer) { + + // Function returns a "value" + f.code << tab4 << "ST(argvi) = sv_newmortal();\n"; + switch(d->type) { + case T_INT: case T_BOOL: case T_SINT: case T_UINT: + case T_SHORT: case T_SSHORT: case T_USHORT: + case T_LONG : case T_SLONG : case T_ULONG: + case T_SCHAR: case T_UCHAR : + f.code << tab4 << "sv_setiv(ST(argvi++),(IV) _result);\n"; + break; + case T_DOUBLE : + case T_FLOAT : + f.code << tab4 << "sv_setnv(ST(argvi++), (double) _result);\n"; + break; + case T_CHAR : + f.add_local("char", "_ctemp[2]"); + f.code << tab4 << "_ctemp[0] = _result;\n" + << tab4 << "_ctemp[1] = 0;\n" + << tab4 << "sv_setpv((SV*)ST(argvi++),_ctemp);\n"; + break; + + // Return a complex type by value + + case T_USER: + d->is_pointer++; + f.code << tab4 << "sv_setref_pv(ST(argvi++),\"" << d->print_mangle() + << "\", (void *) _result);\n"; + d->is_pointer--; + break; + + default : + fprintf(stderr,"%s: Line %d. Unable to use return type %s in function %s.\n", input_file, line_number, d->print_type(), name); + break; + } + } else { + + // Is a pointer return type + f.code << tab4 << "ST(argvi) = sv_newmortal();\n"; + if ((d->type == T_CHAR) && (d->is_pointer == 1)) { + + // Return a character string + f.code << tab4 << "sv_setpv((SV*)ST(argvi++),(char *) _result);\n"; + + } else { + // Is an ordinary pointer type. + f.code << tab4 << "sv_setref_pv(ST(argvi++),\"" << d->print_mangle() + << "\", (void *) _result);\n"; + } + } + } + + // If there were any output args, take care of them. + + f.code << outarg; + + // If there was any cleanup, do that. + + f.code << cleanup; + + if (NewObject) { + if ((tm = typemap_lookup("newfree","perl5",d,iname,"_result",""))) { + f.code << tm << "\n"; + } + } + + if ((tm = typemap_lookup("ret","perl5",d,iname,"_result",""))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + } + + // Wrap things up (in a manner of speaking) + + f.code << tab4 << "XSRETURN(argvi);\n}\n"; + + // Add the dXSARGS last + + f.add_local("dXSARGS",""); + + // Substitute the cleanup code + f.code.replace("$cleanup",cleanup); + f.code.replace("$name",iname); + + // Dump this function out + + f.print(f_wrappers); + + // Create a first crack at a documentation entry + + if (doc_entry) { + static DocEntry *last_doc_entry = 0; + doc_entry->usage << usage; + if (last_doc_entry != doc_entry) { + doc_entry->cinfo << "returns " << d->print_type(); + last_doc_entry = doc_entry; + } + } + + // Now register the function + + fprintf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package, iname, wname); + + if (export_all) { + exported << iname << " "; + } + + + // -------------------------------------------------------------------- + // Create a stub for this function, provided it's not a member function + // + // Really we only need to create a stub if this function involves + // complex datatypes. If it does, we'll make a small wrapper to + // process the arguments. If it doesn't, we'll just make a symbol + // table entry. + // -------------------------------------------------------------------- + + if ((blessed) && (!member_func)) { + int need_stub = 0; + String func; + + // We'll make a stub since we may need it anyways + + func << "sub " << iname << " {\n" + << tab4 << "my @args = @_;\n"; + + + // Now we have to go through and patch up the argument list. If any + // arguments to our function correspond to other Perl objects, we + // need to extract them from a tied-hash table object. + + Parm *p = l->get_first(); + int i = 0; + while(p) { + + if (!p->ignore) { + // Look up the datatype name here + + if ((classes.lookup(p->t->name)) && (p->t->is_pointer <= 1)) { + if (i >= (pcount - numopt)) + func << tab4 << "if (scalar(@args) >= " << i << ") {\n" << tab4; + + func << tab4 << "$args[" << i << "] = tied(%{$args[" << i << "]});\n"; + + if (i >= (pcount - numopt)) + func << tab4 << "}\n"; + + need_stub = 1; + } + i++; + } + p = l->get_next(); + } + + func << tab4 << "my $result = " << package << "::" << iname << "(@args);\n"; + + // Now check to see what kind of return result was found. + // If this function is returning a result by 'value', SWIG did an + // implicit malloc/new. We'll mark the object like it was created + // in Perl so we can garbage collect it. + + if ((classes.lookup(d->name)) && (d->is_pointer <=1)) { + + func << tab4 << "return undef if (!defined($result));\n"; + + // If we're returning an object by value, put it's reference + // into our local hash table + + if ((d->is_pointer == 0) || ((d->is_pointer == 1) && NewObject)) { + func << tab4 << "$" << (char *) classes.lookup(d->name) << "::OWNER{$result} = 1;\n"; + } + + // We're returning a Perl "object" of some kind. Turn it into + // a tied hash + + func << tab4 << "my %resulthash;\n" + /* << tab4 << "tie %resulthash, \"" << (char *) classes.lookup(d->name) << "\", $result;\n" + << tab4 << "return bless \\%resulthash, \"" << (char *) classes.lookup(d->name) << "\";\n" + */ + << tab4 << "tie %resulthash, ref($result), $result;\n" + << tab4 << "return bless \\%resulthash, ref($result);\n" + << "}\n"; + + need_stub = 1; + } else { + + // Hmmm. This doesn't appear to be anything I know about so just + // return it unmolested. + + func << tab4 <<"return $result;\n" + << "}\n"; + + } + + // Now check if we needed the stub. If so, emit it, otherwise + // Emit code to hack Perl's symbol table instead + + if (need_stub) { + func_stubs << func; + } else { + func_stubs << "*" << iname << " = *" << package << "::" << iname << ";\n"; + } + } +} + +// ----------------------------------------------------------------------- +// PERL5::link_variable(char *name, char *iname, DataType *d) +// +// Create a link to a C variable. +// ----------------------------------------------------------------------- + +void PERL5::link_variable(char *name, char *iname, DataType *t) +{ + char set_name[256]; + char val_name[256]; + WrapperFunction getf, setf; + char *tm; + sprintf(set_name,"_wrap_set_%s",iname); + sprintf(val_name,"_wrap_val_%s",iname); + + // Create a new scalar that we will attach magic to + + vinit << tab4 << "sv = perl_get_sv(\"" << package << "::" << iname << "\",TRUE | 0x2);\n"; + + // Create a Perl function for setting the variable value + + if (!(Status & STAT_READONLY)) { + setf.def << "SWIGCLASS_STATIC int " << set_name << "(SV* sv, MAGIC *mg) {\n"; + + setf.code << tab4 << "MAGIC_PPERL\n"; + setf.code << tab4 << "mg = mg;\n"; + + /* Check for a few typemaps */ + if ((tm = typemap_lookup("varin","perl5",t,"","sv",name))) { + setf.code << tm << "\n"; + } else if ((tm = typemap_lookup("in","perl5",t,"","sv",name))) { + setf.code << tm << "\n"; + } else { + if (!t->is_pointer) { + + // Set the value to something + + switch(t->type) { + case T_INT : case T_BOOL: case T_SINT : case T_UINT: + case T_SHORT : case T_SSHORT : case T_USHORT: + case T_LONG : case T_SLONG : case T_ULONG: + case T_UCHAR: case T_SCHAR: + setf.code << tab4 << name << " = " << t->print_cast() << " SvIV(sv);\n"; + break; + case T_DOUBLE : + case T_FLOAT : + setf.code << tab4 << name << " = " << t->print_cast() << " SvNV(sv);\n"; + break; + case T_CHAR : + setf.code << tab4 << name << " = (char) *SvPV(sv,PL_na);\n"; + break; + + case T_USER: + + // Add support for User defined type here + // Get as a pointer value + + t->is_pointer++; + setf.add_local("void","*_temp"); + get_pointer(iname,"value","sv","_temp", t, setf.code, "return(1)"); + setf.code << tab4 << name << " = *(" << t->print_cast() << " _temp);\n"; + t->is_pointer--; + break; + + default : + fprintf(stderr,"%s : Line %d. Unable to link with datatype %s (ignored).\n", input_file, line_number, t->print_type()); + return; + } + } else { + // Have some sort of pointer type here, Process it differently + if ((t->type == T_CHAR) && (t->is_pointer == 1)) { + setf.add_local("char","*_a"); + setf.code << tab4 << "_a = (char *) SvPV(sv,PL_na);\n"; + + if (CPlusPlus) + setf.code << tab4 << "if (" << name << ") delete [] " << name << ";\n" + << tab4 << name << " = new char[strlen(_a)+1];\n"; + else + setf.code << tab4 << "if (" << name << ") free(" << name << ");\n" + << tab4 << name << " = (char *) malloc(strlen(_a)+1);\n"; + setf.code << "strcpy(" << name << ",_a);\n"; + } else { + // Set the value of a pointer + + setf.add_local("void","*_temp"); + get_pointer(iname,"value","sv","_temp", t, setf.code, "return(1)"); + setf.code << tab4 << name << " = " << t->print_cast() << " _temp;\n"; + } + } + } + setf.code << tab4 << "return 1;\n" + << "}\n"; + + setf.code.replace("$name",iname); + setf.print(magic); + + } + + // Now write a function to evaluate the variable + + getf.def << "SWIGCLASS_STATIC int " << val_name << "(SV *sv, MAGIC *mg) {\n"; + getf.code << tab4 << "MAGIC_PPERL\n"; + getf.code << tab4 << "mg = mg;\n"; + + // Check for a typemap + + if ((tm = typemap_lookup("varout","perl5",t,"",name, "sv"))) { + getf.code << tm << "\n"; + } else if ((tm = typemap_lookup("out","perl5",t,"",name,"sv"))) { + setf.code << tm << "\n"; + } else { + if (!t->is_pointer) { + switch(t->type) { + case T_INT : case T_BOOL: case T_SINT: case T_UINT: + case T_SHORT : case T_SSHORT: case T_USHORT: + case T_LONG : case T_SLONG : case T_ULONG: + case T_UCHAR: case T_SCHAR: + getf.code << tab4 << "sv_setiv(sv, (IV) " << name << ");\n"; + vinit << tab4 << "sv_setiv(sv,(IV)" << name << ");\n"; + break; + case T_DOUBLE : + case T_FLOAT : + getf.code << tab4 << "sv_setnv(sv, (double) " << name << ");\n"; + vinit << tab4 << "sv_setnv(sv,(double)" << name << ");\n"; + break; + case T_CHAR : + getf.add_local("char","_ptemp[2]"); + getf.code << tab4 << "_ptemp[0] = " << name << ";\n" + << tab4 << "_ptemp[1] = 0;\n" + << tab4 << "sv_setpv((SV*) sv, _ptemp);\n"; + break; + case T_USER: + t->is_pointer++; + getf.code << tab4 << "rsv = SvRV(sv);\n" + << tab4 << "sv_setiv(rsv,(IV) &" << name << ");\n"; + + // getf.code << tab4 << "sv_setref_pv((SV*) sv,\"" << t->print_mangle() + // << "\", (void *) &" << name << ");\n"; + + getf.add_local("SV","*rsv"); + vinit << tab4 << "sv_setref_pv(sv,\"" << t->print_mangle() << "\",(void *) &" << name << ");\n"; + t->is_pointer--; + + break; + default : + break; + } + } else { + + // Have some sort of arbitrary pointer type. Return it as a string + + if ((t->type == T_CHAR) && (t->is_pointer == 1)) + getf.code << tab4 << "sv_setpv((SV*) sv, " << name << ");\n"; + else { + getf.code << tab4 << "rsv = SvRV(sv);\n" + << tab4 << "sv_setiv(rsv,(IV) " << name << ");\n"; + getf.add_local("SV","*rsv"); + vinit << tab4 << "sv_setref_pv(sv,\"" << t->print_mangle() << "\",(void *) 1);\n"; + + //getf.code << tab4 << "sv_setref_pv((SV*) sv,\"" << t->print_mangle() + // << "\", (void *) " << name << ");\n"; + } + } + } + getf.code << tab4 << "return 1;\n" + << "}\n"; + + getf.code.replace("$name",iname); + getf.print(magic); + + // Now add symbol to the PERL interpreter + if (Status & STAT_READONLY) { + vinit << tab4 << "swig_create_magic(sv,\"" << package << "::" << iname << "\",MAGIC_CAST MAGIC_CLASS swig_magic_readonly, MAGIC_CAST MAGIC_CLASS " << val_name << ");\n"; + } else { + vinit << tab4 << "swig_create_magic(sv,\"" << package << "::" << iname << "\", MAGIC_CAST MAGIC_CLASS " << set_name << ", MAGIC_CAST MAGIC_CLASS " << val_name << ");\n"; + } + // Add a documentation entry + + if (doc_entry) { + doc_entry->usage << usage_var(iname,t); + doc_entry->cinfo << "Global : " << t->print_type() << " " << name; + } + + // 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 ((classes.lookup(t->name)) && (t->is_pointer <= 1)) { + var_stubs << "\nmy %__" << iname << "_hash;\n" + << "tie %__" << iname << "_hash,\"" << (char *) classes.lookup(t->name) << "\", $" + << package << "::" << iname << ";\n" + << "$" << iname << "= \\%__" << iname << "_hash;\n" + << "bless $" << iname << ", " << (char *) classes.lookup(t->name) << ";\n"; + } else { + var_stubs << "*" << iname << " = *" << package << "::" << iname << ";\n"; + } + if (export_all) + exported << "$" << name << " "; + } +} + +// ----------------------------------------------------------------------- +// PERL5::declare_const(char *name, char *iname, DataType *type, char *value) +// +// Makes a constant. Really just creates a variable and creates a read-only +// link to it. +// ------------------------------------------------------------------------ + +// Functions used to create constants + +static const char *setiv = "#ifndef PERL_OBJECT\ +\n#define swig_setiv(a,b) _swig_setiv(a,b)\ +\nstatic void _swig_setiv(char *name, long value) { \ +\n#else\ +\n#define swig_setiv(a,b) _swig_setiv(pPerl,a,b)\ +\nstatic void _swig_setiv(CPerlObj *pPerl, char *name, long value) { \ +\n#endif\ +\n SV *sv; \ +\n sv = perl_get_sv(name,TRUE | 0x2);\ +\n sv_setiv(sv, (IV) value);\ +\n SvREADONLY_on(sv);\ +\n}\n"; + +static const char *setnv = "#ifndef PERL_OBJECT\ +\n#define swig_setnv(a,b) _swig_setnv(a,b)\ +\nstatic void _swig_setnv(char *name, double value) { \ +\n#else\ +\n#define swig_setnv(a,b) _swig_setnv(pPerl,a,b)\ +\nstatic void _swig_setnv(CPerlObj *pPerl, char *name, double value) { \ +\n#endif\ +\n SV *sv; \ +\n sv = perl_get_sv(name,TRUE | 0x2);\ +\n sv_setnv(sv, value);\ +\n SvREADONLY_on(sv);\ +\n}\n"; + +static const char *setpv = "#ifndef PERL_OBJECT\ +\n#define swig_setpv(a,b) _swig_setpv(a,b)\ +\nstatic void _swig_setpv(char *name, char *value) { \ +\n#else\ +\n#define swig_setpv(a,b) _swig_setpv(pPerl,a,b)\ +\nstatic void _swig_setpv(CPerlObj *pPerl, char *name, char *value) { \ +\n#endif\ +\n SV *sv; \ +\n sv = perl_get_sv(name,TRUE | 0x2);\ +\n sv_setpv(sv, value);\ +\n SvREADONLY_on(sv);\ +\n}\n"; + +static const char *setrv = "#ifndef PERL_OBJECT\ +\n#define swig_setrv(a,b,c) _swig_setrv(a,b,c)\ +\nstatic void _swig_setrv(char *name, void *value, char *type) { \ +\n#else\ +\n#define swig_setrv(a,b,c) _swig_setrv(pPerl,a,b,c)\ +\nstatic void _swig_setrv(CPerlObj *pPerl, char *name, void *value, char *type) { \ +\n#endif\ +\n SV *sv; \ +\n sv = perl_get_sv(name,TRUE | 0x2);\ +\n sv_setref_pv(sv, type, value);\ +\n SvREADONLY_on(sv);\ +\n}\n"; + +void +PERL5::declare_const(char *name, char *, DataType *type, char *value) + { + + char *tm; + static int have_int_func = 0; + static int have_double_func = 0; + static int have_char_func = 0; + static int have_ref_func = 0; + + if ((tm = typemap_lookup("const","perl5",type,name,value,name))) { + fprintf(f_init,"%s\n",tm); + } else { + if ((type->type == T_USER) && (!type->is_pointer)) { + fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); + return; + } + // Generate a constant + // vinit << tab4 << "sv = perl_get_sv(\"" << package << "::" << name << "\",TRUE);\n"; + if (type->is_pointer == 0) { + switch(type->type) { + case T_INT:case T_SINT: case T_UINT: case T_BOOL: + case T_SHORT: case T_SSHORT: case T_USHORT: + case T_LONG: case T_SLONG: case T_ULONG: + case T_SCHAR: case T_UCHAR: + if (!have_int_func) { + fprintf(f_header,"%s\n",setiv); + have_int_func = 1; + } + vinit << tab4 << "swig_setiv(\"" << package << "::" << name << "\", (long) " << value << ");\n"; + break; + case T_DOUBLE: + case T_FLOAT: + if (!have_double_func) { + fprintf(f_header,"%s\n",setnv); + have_double_func = 1; + } + vinit << tab4 << "swig_setnv(\"" << package << "::" << name << "\", (double) (" << value << "));\n"; + break; + case T_CHAR : + if (!have_char_func) { + fprintf(f_header,"%s\n",setpv); + have_char_func = 1; + } + vinit << tab4 << "swig_setpv(\"" << package << "::" << name << "\", \"" << value << "\");\n"; + break; + default: + fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); + break; + } + } else { + if ((type->type == T_CHAR) && (type->is_pointer == 1)) { + if (!have_char_func) { + fprintf(f_header,"%s\n",setpv); + have_char_func = 1; + } + vinit << tab4 << "swig_setpv(\"" << package << "::" << name << "\", \"" << value << "\");\n"; + } else { + // A user-defined type. We're going to munge it into a string pointer value + if (!have_ref_func) { + fprintf(f_header,"%s\n",setrv); + have_ref_func = 1; + } + vinit << tab4 << "swig_setrv(\"" << package << "::" << name << "\", (void *) " << value << ", \"" + << type->print_mangle() << "\");\n"; + } + } + } + + // Patch up the documentation entry + + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << usage_const(name,type,value); + doc_entry->cinfo = ""; + doc_entry->cinfo << "Constant: " << type->print_type(); + } + + if (blessed) { + if ((classes.lookup(type->name)) && (type->is_pointer <= 1)) { + var_stubs << "\nmy %__" << name << "_hash;\n" + << "tie %__" << name << "_hash,\"" << (char *) classes.lookup(type->name) << "\", $" + << package << "::" << name << ";\n" + << "$" << name << "= \\%__" << name << "_hash;\n" + << "bless $" << name << ", " << (char *) classes.lookup(type->name) << ";\n"; + } else { + var_stubs << "*" << name << " = *" << package << "::" << name << ";\n"; + } + } + if (export_all) + exported << "$" << name << " "; +} + +// ---------------------------------------------------------------------- +// PERL5::usage_var(char *iname, DataType *t) +// +// Produces a usage string for a Perl 5 variable. +// ---------------------------------------------------------------------- + +char *PERL5::usage_var(char *iname, DataType *) { + + static char temp[1024]; + char *c; + + sprintf(temp,"$%s", iname); + c = temp + strlen(temp); + return temp; +} + +// --------------------------------------------------------------------------- +// char *PERL5::usage_func(pkg, char *iname, DataType *t, ParmList *l) +// +// Produces a usage string for a function in Perl +// --------------------------------------------------------------------------- + +char *PERL5::usage_func(char *iname, DataType *, ParmList *l) { + + static String temp; + Parm *p; + int i; + + temp = ""; + temp << iname << "("; + + /* Now go through and print parameters */ + + p = l->get_first(); + i = 0; + while (p != 0) { + if (!p->ignore) { + /* If parameter has been named, use that. Otherwise, just print a type */ + + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + if (strlen(p->name) > 0) { + temp << p->name; + } else { + temp << p->t->print_type(); + } + } + i++; + p = l->get_next(); + if (p) + if (!p->ignore) + temp << ","; + } else { + p = l->get_next(); + if (p) + if ((i>0) && (!p->ignore)) + temp << ","; + } + } + temp << ");"; + return temp.get(); +} + +// ---------------------------------------------------------------------- +// PERL5::usage_const(char *iname, DataType *type, char *value) +// +// Produces a usage string for a Perl 5 constant +// ---------------------------------------------------------------------- + +char *PERL5::usage_const(char *iname, DataType *, char *value) { + + static char temp[1024]; + if (value) { + sprintf(temp,"$%s = %s", iname, value); + } else { + sprintf(temp,"$%s", iname); + } + return temp; +} + +// ----------------------------------------------------------------------- +// PERL5::add_native(char *name, char *funcname) +// +// Add a native module name to Perl5. +// ----------------------------------------------------------------------- + +void PERL5::add_native(char *name, char *funcname) { + fprintf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package,name, funcname); + if (export_all) + exported << name << " "; + if (blessed) { + func_stubs << "*" << name << " = *" << package << "::" << name << ";\n"; + } +} + +/**************************************************************************** + *** OBJECT-ORIENTED FEATURES + **************************************************************************** + *** These extensions provide a more object-oriented interface to C++ + *** classes and structures. The code here is based on extensions + *** provided by David Fletcher and Gary Holt. + *** + *** I have generalized these extensions to make them more general purpose + *** and to resolve object-ownership problems. + *** + *** The approach here is very similar to the Python module : + *** 1. All of the original methods are placed into a single + *** package like before except that a 'c' is appended to the + *** package name. + *** + *** 2. All methods and function calls are wrapped with a new + *** perl function. While possibly inefficient this allows + *** us to catch complex function arguments (which are hard to + *** track otherwise). + *** + *** 3. Classes are represented as tied-hashes in a manner similar + *** to Gary Holt's extension. This allows us to access + *** member data. + *** + *** 4. Stand-alone (global) C functions are modified to take + *** tied hashes as arguments for complex datatypes (if + *** appropriate). + *** + *** 5. Global variables involving a class/struct is encapsulated + *** in a tied hash. + *** + *** 6. Object ownership is maintained by having a hash table + *** within in each package called "this". It is unlikely + *** that C++ program will use this so it's a somewhat + *** safe variable name. + *** + ****************************************************************************/ + +static int class_renamed = 0; +static String fullclassname; + +// -------------------------------------------------------------------------- +// PERL5::cpp_open_class(char *classname, char *rname, int strip) +// +// Opens a new C++ class or structure. Basically, this just records +// the class name and clears a few variables. +// -------------------------------------------------------------------------- + +void PERL5::cpp_open_class(char *classname, char *rname, char *ctype, int strip) { + + char temp[256]; + extern void typeeq_addtypedef(char *, char *); + + // Register this with the default class handler + + this->Language::cpp_open_class(classname, rname, ctype, strip); + + if (blessed) { + have_constructor = 0; + have_destructor = 0; + have_data_members = 0; + + // If the class is being renamed to something else, use the renaming + + if (rname) { + class_name = copy_string(rname); + class_renamed = 1; + // Now things get even more hideous. Need to register an equivalence + // between the renamed name and the new name. Yuck! + // printf("%s %s\n", classname, rname); + typeeq_addtypedef(classname,rname); + typeeq_addtypedef(rname,classname); + /* + fprintf(f_init,"\t SWIG_RegisterMapping(\"%s\",\"%s\",0);\n",classname,rname); + fprintf(f_init,"\t SWIG_RegisterMapping(\"%s\",\"%s\",0);\n",rname,classname); + */ + } else { + class_name = copy_string(classname); + class_renamed = 0; + } + + // A highly experimental feature. This is the fully qualified + // name of the Perl class + + if (!compat) { + fullclassname = realpackage; + fullclassname << "::" << class_name; + } else { + fullclassname = class_name; + } + + fullclassname = class_name; + + real_classname = copy_string(classname); + if (base_class) delete base_class; + base_class = 0; + class_type = copy_string(ctype); + pcode = new String(); + blessedmembers = new String(); + member_keys = new String(); + + // Add some symbols to the hash tables + + // classes.add(real_classname,copy_string(class_name)); /* Map original classname to class */ + classes.add(real_classname,copy_string(fullclassname)); /* Map original classname to class */ + + // Add full name of datatype to the hash table just in case the user uses it + + sprintf(temp,"%s %s", class_type, fullclassname.get()); + // classes.add(temp,copy_string(class_name)); /* Map full classname to classs */ + } +} + +// ------------------------------------------------------------------------------- +// PERL5::cpp_close_class() +// +// These functions close a class definition. +// +// This also sets up the hash table of classes we've seen go by. +// ------------------------------------------------------------------------------- + +void PERL5::cpp_close_class() { + + // We need to check to make sure we got constructors, and other + // stuff here. + + if (blessed) { + pm << "\n############# Class : " << fullclassname << " ##############\n"; + pm << "\npackage " << fullclassname << ";\n"; + + // If we are inheriting from a base class, set that up + + if (strcmp(class_name,realpackage)) + pm << "@ISA = qw( " << realpackage; + else + pm << "@ISA = qw( "; + + if (base_class) { + pm << " " << *base_class; + } + pm << " );\n"; + + // Dump out a hash table containing the pointers that we own + + pm << "%OWNER = ();\n"; + if (have_data_members) { + pm << "%BLESSEDMEMBERS = (\n" + << blessedmembers->get() + << ");\n\n"; + } + if (have_data_members || have_destructor) + pm << "%ITERATORS = ();\n"; + + + // Dump out the package methods + + pm << *pcode; + delete pcode; + + // Output methods for managing ownership + + pm << "sub DISOWN {\n" + << tab4 << "my $self = shift;\n" + << tab4 << "my $ptr = tied(%$self);\n" + << tab4 << "delete $OWNER{$ptr};\n" + << tab4 << "};\n\n" + << "sub ACQUIRE {\n" + << tab4 << "my $self = shift;\n" + << tab4 << "my $ptr = tied(%$self);\n" + << tab4 << "$OWNER{$ptr} = 1;\n" + << tab4 << "};\n\n"; + + // Only output the following methods if a class has member data + + if (have_data_members) { + + // Output a FETCH method. This is actually common to all classes + pm << "sub FETCH {\n" + << tab4 << "my ($self,$field) = @_;\n" + << tab4 << "my $member_func = \"" << package << "::" << name_get(name_member("${field}",class_name,AS_IS),AS_IS) << "\";\n" + << tab4 << "my $val = &$member_func($self);\n" + << tab4 << "if (exists $BLESSEDMEMBERS{$field}) {\n" + << tab8 << "return undef if (!defined($val));\n" + << tab8 << "my %retval;\n" + << tab8 << "tie %retval,$BLESSEDMEMBERS{$field},$val;\n" + << tab8 << "return bless \\%retval, $BLESSEDMEMBERS{$field};\n" + << tab4 << "}\n" + << tab4 << "return $val;\n" + << "}\n\n"; + + // Output a STORE method. This is also common to all classes (might move to base class) + + pm << "sub STORE {\n" + << tab4 << "my ($self,$field,$newval) = @_;\n" + << tab4 << "my $member_func = \"" << package << "::" << name_set(name_member("${field}",class_name,AS_IS),AS_IS) << "\";\n" + << tab4 << "if (exists $BLESSEDMEMBERS{$field}) {\n" + << tab8 << "&$member_func($self,tied(%{$newval}));\n" + << tab4 << "} else {\n" + << tab8 << "&$member_func($self,$newval);\n" + << tab4 << "}\n" + << "}\n\n"; + + // Output a FIRSTKEY method. This is to allow iteration over a structure's keys. + + pm << "sub FIRSTKEY {\n" + << tab4 << "my $self = shift;\n" + << tab4 << "$ITERATORS{$self} = [" << member_keys->get() << "];\n" + << tab4 << "my $first = shift @{$ITERATORS{$self}};\n" + << tab4 << "return $first;\n" + << "}\n\n"; + + // Output a NEXTKEY method. This is the iterator so that each and keys works + + pm << "sub NEXTKEY {\n" + << tab4 << "my $self = shift;\n" + << tab4 << "$nelem = scalar @{$ITERATORS{$self}};\n" + << tab4 << "if ($nelem > 0) {\n" + << tab8 << "my $member = shift @{$ITERATORS{$self}};\n" + << tab8 << "return $member;\n" + << tab4 << "} else {\n" + << tab8 << "$ITERATORS{$self} = [" << member_keys->get() << "];\n" + << tab8 << "return ();\n" + << tab4 << "}\n" + << "}\n\n"; + } + } +} + +// -------------------------------------------------------------------------- +// PERL5::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) +// +// Handles a C++ member function. This basically does the same thing as +// the non-C++ version, but we set up a few status variables that affect +// the function generation function. +// +// -------------------------------------------------------------------------- + +void PERL5::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) { + + String func; + char *realname; + Parm *p; + int i; + String cname = "perl5:"; + int pcount, numopt; + + // First emit normal member function + + member_func = 1; + this->Language::cpp_member_func(name,iname,t,l); + member_func = 0; + + if (!blessed) return; + + // Now emit a Perl wrapper function around our member function, we might need + // to patch up some arguments along the way + + if (!iname) + realname = name; + else + realname = iname; + + cname << class_name << "::" << realname; + if (add_symbol(cname.get(),0,0)) { + return; // Forget it, we saw this function already + } + + func << "sub " << realname << " {\n" + << tab4 << "my @args = @_;\n" + << tab4 << "$args[0] = tied(%{$args[0]});\n"; + + // Now we have to go through and patch up the argument list. If any + // arguments to our function correspond to other Perl objects, we + // need to extract them from a tied-hash table object. + + p = l->get_first(); + pcount = l->nparms; + numopt = l->numopt(); + i = 1; + while(p) { + if (!p->ignore) { + + // Look up the datatype name here + if ((classes.lookup(p->t->name)) && (p->t->is_pointer <= 1)) { + // Yep. This smells alot like an object, patch up the arguments + + if (i >= (pcount - numopt)) + func << tab4 << "if (scalar(@args) >= " << i << ") {\n"; + + func << tab4 << "$args[" << i << "] = tied(%{$args[" << i << "]});\n"; + + if (i >= (pcount - numopt)) + func << tab4 << "}\n"; + } + i++; + } + p = l->get_next(); + } + + // Okay. We've made argument adjustments, now call into the package + + func << tab4 << "my $result = " << package << "::" << name_member(realname,class_name) + << "(@args);\n"; + + // Now check to see what kind of return result was found. + // If this function is returning a result by 'value', SWIG did an + // implicit malloc/new. We'll mark the object like it was created + // in Perl so we can garbage collect it. + + if ((classes.lookup(t->name)) && (t->is_pointer <=1)) { + + func << tab4 << "return undef if (!defined($result));\n"; + + // If we're returning an object by value, put it's reference + // into our local hash table + + if ((t->is_pointer == 0) || ((t->is_pointer == 1) && NewObject)) { + func << tab4 << "$" << (char *) classes.lookup(t->name) << "::OWNER{$result} = 1;\n"; + } + + // We're returning a Perl "object" of some kind. Turn it into + // a tied hash + + func << tab4 << "my %resulthash;\n" + /* << tab4 << "tie %resulthash, \"" << (char *) classes.lookup(t->name) << "\", $result;\n" + << tab4 << "return bless \\%resulthash, \"" << (char *) classes.lookup(t->name) << "\";\n" */ + << tab4 << "tie %resulthash, ref($result), $result;\n" + << tab4 << "return bless \\%resulthash, ref($result);\n" + + << "}\n"; + + } else { + + // Hmmm. This doesn't appear to be anything I know about so just + // return it unmolested. + + func << tab4 <<"return $result;\n" + << "}\n"; + + } + + // Append our function to the pcode segment + + *pcode << func; + + // Create a new kind of documentation entry for the shadow class + + if (doc_entry) { + doc_entry->usage = ""; // Blow away whatever was there before + doc_entry->usage << usage_func(realname,t,l); + } +} + +// -------------------------------------------------------------------------------- +// PERL5::cpp_variable(char *name, char *iname, DataType *t) +// +// Adds an instance member. This is a little hairy because data members are +// really added with a tied-hash table that is attached to the object. +// +// On the low level, we will emit a pair of get/set functions to retrieve +// values just like before. These will then be encapsulated in a FETCH/STORE +// method associated with the tied-hash. +// +// In the event that a member is an object that we have already wrapped, then +// we need to retrieve the data a tied-hash as opposed to what SWIG normally +// returns. To determine this, we build an internal hash called 'BLESSEDMEMBERS' +// that contains the names and types of tied data members. If a member name +// is in the list, we tie it, otherwise, we just return the normal SWIG value. +// -------------------------------------------------------------------------------- + +void PERL5::cpp_variable(char *name, char *iname, DataType *t) { + + char *realname; + String cname = "perl5:"; + + // Emit a pair of get/set functions for the variable + + member_func = 1; + this->Language::cpp_variable(name, iname, t); + member_func = 0; + + if (iname) realname = iname; + else realname = name; + + if (blessed) { + cname << class_name << "::" << realname; + if (add_symbol(cname.get(),0,0)) { + return; // Forget it, we saw this already + } + + // Store name of key for future reference + + *member_keys << "'" << realname << "', "; + + // Now we need to generate a little Perl code for this + + if ((classes.lookup(t->name)) && (t->is_pointer <= 1)) { + + // This is a Perl object that we have already seen. Add an + // entry to the members list + + *blessedmembers << tab4 << realname << " => '" << (char *) classes.lookup(t->name) << "',\n"; + + } + + // Patch up the documentation entry + + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << "$this->{" << realname << "}"; + } + } + have_data_members++; +} + + +// ----------------------------------------------------------------------------- +// void PERL5::cpp_constructor(char *name, char *iname, ParmList *l) +// +// Emits a blessed constructor for our class. In addition to our construct +// we manage a Perl hash table containing all of the pointers created by +// the constructor. This prevents us from accidentally trying to free +// something that wasn't necessarily allocated by malloc or new +// ----------------------------------------------------------------------------- + +void PERL5::cpp_constructor(char *name, char *iname, ParmList *l) { + Parm *p; + int i; + char *realname; + String cname="perl5:constructor:"; + + // Emit an old-style constructor for this class + + member_func = 1; + this->Language::cpp_constructor(name, iname, l); + + if (blessed) { + + if (iname) + realname = iname; + else { + if (class_renamed) realname = class_name; + else realname = class_name; + } + + cname << class_name << "::" << realname; + if (add_symbol(cname.get(),0,0)) { + return; // Forget it, we saw this already + } + if ((strcmp(realname,class_name) == 0) || ((!iname) && (ObjCClass)) ){ + + // Emit a blessed constructor + + *pcode << "sub new {\n"; + + } else { + + // Constructor doesn't match classname so we'll just use the normal name + + *pcode << "sub " << name_construct(realname) << " () {\n"; + + } + + *pcode << tab4 << "my $self = shift;\n" + << tab4 << "my @args = @_;\n"; + + // We are going to need to patch up arguments here if necessary + // Now we have to go through and patch up the argument list. If any + // arguments to our function correspond to other Perl objects, we + // need to extract them from a tied-hash table object. + + p = l->get_first(); + i = 0; + while(p) { + + // Look up the datatype name here + + if ((classes.lookup(p->t->name)) && (p->t->is_pointer <= 1)) { + + // Yep. This smells alot like an object, patch up the arguments + *pcode << tab4 << "$args[" << i << "] = tied(%{$args[" << i << "]});\n"; + } + p = l->get_next(); + i++; + } + + *pcode << tab4 << "$self = " << package << "::" << name_construct(realname) << "(@args);\n" + << tab4 << "return undef if (!defined($self));\n" + << tab4 << "bless $self, \"" << fullclassname << "\";\n" + << tab4 << "$OWNER{$self} = 1;\n" + << tab4 << "my %retval;\n" + << tab4 << "tie %retval, \"" << fullclassname << "\", $self;\n" + << tab4 << "return bless \\%retval,\"" << fullclassname << "\";\n" + << "}\n\n"; + have_constructor = 1; + + // Patch up the documentation entry + + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << usage_func("new",0,l); + } + } + member_func = 0; +} + + +// ------------------------------------------------------------------------------ +// void PERL5::cpp_destructor(char *name, char *newname) +// +// Creates a destructor for a blessed object +// ------------------------------------------------------------------------------ + +void PERL5::cpp_destructor(char *name, char *newname) { + + char *realname; + member_func = 1; + this->Language::cpp_destructor(name, newname); + + if (blessed) { + if (newname) realname = newname; + else { + if (class_renamed) realname = class_name; + else realname = name; + } + + // Emit a destructor for this object + + *pcode << "sub DESTROY {\n" + << tab4 << "my $self = tied(%{$_[0]});\n" + << tab4 << "delete $ITERATORS{$self};\n" + << tab4 << "if (exists $OWNER{$self}) {\n" + << tab8 << package << "::" << name_destroy(realname) << "($self);\n" + << tab8 << "delete $OWNER{$self};\n" + << tab4 << "}\n}\n\n"; + + have_destructor = 1; + + if (doc_entry) { + doc_entry->usage = "DESTROY"; + doc_entry->cinfo = "Destructor"; + } + } + member_func = 0; +} +// ----------------------------------------------------------------------------- +// void PERL5::cpp_static_func(char *name, char *iname, DataType *t, ParmList *l) +// +// Emits a wrapper for a static class function. Basically, we just call the +// appropriate method in the module package. +// ------------------------------------------------------------------------------ +void PERL5::cpp_static_func(char *name, char *iname, DataType *t, ParmList *l) { + this->Language::cpp_static_func(name,iname,t,l); + char *realname; + if (iname) realname = name; + else realname = iname; + + if (blessed) { + *pcode << "*" << realname << " = *" << realpackage << "::" << name_member(realname,class_name) << ";\n"; + } +} + +// ------------------------------------------------------------------------------ +// void PERL5::cpp_inherit(char **baseclass, int mode) +// +// This sets the Perl5 baseclass (if possible). +// ------------------------------------------------------------------------------ + +void PERL5::cpp_inherit(char **baseclass, int) { + + char *bc; + int i = 0, have_first = 0; + if (!blessed) { + this->Language::cpp_inherit(baseclass); + return; + } + + // Inherit variables and constants from base classes, but not + // functions (since Perl can handle that okay). + + this->Language::cpp_inherit(baseclass, INHERIT_CONST | INHERIT_VAR); + + // Now tell the Perl5 module that we're inheriting from base classes + + base_class = new String; + while (baseclass[i]) { + // See if this is a class we know about + bc = (char *) classes.lookup(baseclass[i]); + if (bc) { + if (have_first) *base_class << " "; + *base_class << bc; + have_first = 1; + } + i++; + } + if (!have_first) { + delete base_class; + base_class = 0; + } +} + +// -------------------------------------------------------------------------------- +// PERL5::cpp_declare_const(char *name, char *iname, DataType *type, char *value) +// +// Add access to a C++ constant. We can really just do this by hacking +// the symbol table +// -------------------------------------------------------------------------------- + +void PERL5::cpp_declare_const(char *name, char *iname, DataType *type, char *value) { + char *realname; + int oldblessed = blessed; + String cname; + + // Create a normal constant + blessed = 0; + this->Language::cpp_declare_const(name, iname, type, value); + blessed = oldblessed; + + if (blessed) { + if (!iname) + realname = name; + else + realname = iname; + + cname << class_name << "::" << realname; + if (add_symbol(cname.get(),0,0)) { + return; // Forget it, we saw this already + } + + // Create a symbol table entry for it + *pcode << "*" << realname << " = *" << package << "::" << name_member(realname,class_name) << ";\n"; + + // Fix up the documentation entry + + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << realname; + if (value) { + doc_entry->usage << " = " << value; + } + } + } +} + +// ----------------------------------------------------------------------- +// PERL5::cpp_class_decl(char *name, char *rename, char *type) +// +// Treatment of an empty class definition. Used to handle +// shadow classes across modules. +// ----------------------------------------------------------------------- + +void PERL5::cpp_class_decl(char *name, char *rename, char *type) { + char temp[256]; + if (blessed) { + classes.add(name,copy_string(rename)); + // Add full name of datatype to the hash table + if (strlen(type) > 0) { + sprintf(temp,"%s %s", type, name); + classes.add(temp,copy_string(rename)); + } + } +} + +// -------------------------------------------------------------------------------- +// PERL5::add_typedef(DataType *t, char *name) +// +// This is called whenever a typedef is encountered. When shadow classes are +// used, this function lets us discovered hidden uses of a class. For example : +// +// struct FooBar { +// ... +// } +// +// typedef FooBar *FooBarPtr; +// +// -------------------------------------------------------------------------------- + +void PERL5::add_typedef(DataType *t, char *name) { + + if (!blessed) return; + + // First check to see if there aren't too many pointers + + if (t->is_pointer > 1) return; + + if (classes.lookup(name)) return; // Already added + + // Now look up the datatype in our shadow class hash table + + if (classes.lookup(t->name)) { + + // Yep. This datatype is in the hash + + // Put this types 'new' name into the hash + + classes.add(name,copy_string((char *) classes.lookup(t->name))); + } +} + + +// -------------------------------------------------------------------------------- +// PERL5::pragma(char *, char *, char *) +// +// Pragma directive. +// +// %pragma(perl5) code="String" # Includes a string in the .pm file +// %pragma(perl5) include="file.pl" # Includes a file in the .pm file +// +// -------------------------------------------------------------------------------- + +void PERL5::pragma(char *lang, char *code, char *value) { + if (strcmp(lang,"perl5") == 0) { + if (strcmp(code,"code") == 0) { + // Dump the value string into the .pm file + if (value) { + pragma_include << value << "\n"; + } + } else if (strcmp(code,"include") == 0) { + // Include a file into the .pm file + if (value) { + if (get_file(value,pragma_include) == -1) { + fprintf(stderr,"%s : Line %d. Unable to locate file %s\n", input_file, line_number,value); + } + } + } else { + fprintf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file,line_number); + } + } +} diff --git a/wxPython/wxSWIG/Modules/perl5.h b/wxPython/wxSWIG/Modules/perl5.h new file mode 100644 index 0000000000..d020ddb1af --- /dev/null +++ b/wxPython/wxSWIG/Modules/perl5.h @@ -0,0 +1,105 @@ +/**************************************************************************** + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + ****************************************************************************/ + +/************************************************************************** + * class PERL5 + * + * A Perl 5 implementation + **************************************************************************/ + +class PERL5 : public Language { +private: + int export_all; + char *package; + char *module; + String cmodule; + String vinit; + FILE *f_pm; + String pm; // Package initialization code + String magic; // Magic variable wrappers + + char *perl_path; + int is_static; + void get_pointer(char *iname, char *srcname, char *src, char *dest, + DataType *t, String &f, char *ret); + char *usage_var(char *, DataType *); + char *usage_func(char *, DataType *, ParmList *); + char *usage_const(char *, DataType *, char *); + + char *alt_header; + +// The following variables are used to manage Perl5 classes + + int blessed; // Enable object oriented features + Hash classes; // A hash table for storing the classes we've seen so far + int have_constructor; + int have_destructor; + int have_data_members; + char *class_name; // Name of the class (what Perl thinks it is) + char *class_type; // Type of class "struct", "class", "union" + char *real_classname; // Real name of C/C++ class + String *base_class; // Base class (if using inheritance) + String *pcode; // Perl code associated with each class + String *blessedmembers; // Member data associated with each class + int member_func; // Set to 1 when wrapping a member function + char *realpackage; // Name of real module + String func_stubs; // Function stubs + String var_stubs; // Variable stubs + String *member_keys; // Keys for all member data + String exported; // Exported symbols + +public : + PERL5() { + package = 0; + module = 0; + perl_path = "perl5"; + is_static = 0; + blessed = 0; + alt_header = 0; + member_func = 0; + }; + void parse_args(int, char *argv[]); + void parse(); + void create_function(char *, char *, DataType *, ParmList *); + void link_variable(char *, char *, DataType *); + void declare_const(char *, char *, DataType *, char *); + void initialize(void); + void headers(void); + void close(void); + void set_module(char *, char **); + void set_init(char *); + void add_native(char *, char *); + void create_command(char *, char *); + char *type_mangle(DataType *); + + // Support for blessed perl thingies.... + + void cpp_open_class(char *classname, char *rename, char *ctype, int strip); + void cpp_close_class(); + void cpp_member_func(char *name, char *iname, DataType *t, ParmList *l); + void cpp_static_func(char *name, char *iname, DataType *t, ParmList *l); + void cpp_variable(char *name, char *iname, DataType *t); + void cpp_constructor(char *name, char *iname, ParmList *l); + void cpp_destructor(char *name, char *newname); + void cpp_inherit(char **baseclass, int mode = INHERIT_ALL); + void cpp_declare_const(char *name, char *iname, DataType *type, char *value); + void cpp_class_decl(char *, char *, char *); + void add_typedef(DataType *t, char *name); + void pragma(char *, char *, char *); + void import(char *filename); +}; + + + diff --git a/wxPython/wxSWIG/Modules/pycpp.cxx b/wxPython/wxSWIG/Modules/pycpp.cxx new file mode 100644 index 0000000000..256a4399d9 --- /dev/null +++ b/wxPython/wxSWIG/Modules/pycpp.cxx @@ -0,0 +1,517 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/********************************************************************** + * $Header$ + * + * pycpp.cxx + * + * This module contains code to generate Python shadow classes of C/C++ + * objects. + **************************************************************************/ + + +#include "swig.h" +#include "python.h" + +static String *setattr; +static String *getattr; +static String *pyclass; +static String *construct; +static String *cinit; +static String *additional; +static int have_constructor; +static int have_destructor; +static int have_getattr; +static int have_setattr; +static int have_repr; +static char *class_name; +static char *class_type; +static char *real_classname; +static String *base_class; +static String base_getattr; +static String base_setattr; +static int class_renamed = 0; + +// -------------------------------------------------------------------------- +// PYTHON::cpp_open_class(char *classname, char *rname, char *ctype, int strip) +// +// Opens a new C++ class or structure. +// -------------------------------------------------------------------------- + +void PYTHON::cpp_open_class(char *classname, char *rname, char *ctype, int strip) { + + char temp[256]; + + this->Language::cpp_open_class(classname, rname, ctype, strip); + + if (shadow) { + /* Create new strings for building up a wrapper function */ + + setattr = new String(); + getattr = new String(); + pyclass = new String(); + construct = new String(); + cinit = new String(); + additional= new String(); + base_class = 0; + base_getattr = ""; + base_setattr = ""; + + + // *pyclass << "class " << rname << ":\n"; + *setattr << tab4 << "def __setattr__(self,name,value):\n"; + *getattr << tab4 << "def __getattr__(self,name):\n"; + have_constructor = 0; + have_destructor = 0; + have_getattr = 0; + have_setattr = 0; + have_repr = 0; + if (rname) { + class_name = copy_string(rname); + class_renamed = 1; + } else { + class_name = copy_string(classname); + class_renamed = 0; + } + } + + real_classname = copy_string(classname); + class_type = copy_string(ctype); + + // Build up the hash table + hash.add(real_classname,copy_string(class_name)); + + sprintf(temp,"%s %s", class_type, real_classname); + hash.add(temp,copy_string(class_name)); + +} + +// -------------------------------------------------------------------------- +// PYTHON::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) +// +// Creates a C++ member function +// -------------------------------------------------------------------------- + +void PYTHON::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) { + + Parm *p; + int i; + char *realname; + int oldshadow; + int pcount; + int numopt; + int have_optional; + + String cname = "python:"; + String translate = ""; + + // Create the default member function + + oldshadow = shadow; // Disable shadowing when wrapping member functions + if (shadow) shadow = shadow | PYSHADOW_MEMBER; + this->Language::cpp_member_func(name,iname,t,l); + shadow = oldshadow; + if (shadow) { + if (!iname) + realname = name; + else + realname = iname; + + // Check to see if we've already seen this + cname << class_name << "::" << realname; + if (add_symbol(cname.get(), 0,0)) { + return; // Forget it, already saw it + } + + if (strcmp(realname,"__repr__") == 0) + have_repr = 1; + + // Now add it to the class + + *pyclass << tab4 << "def " << realname << "(self, *_args, **_kwargs):\n"; + // Create a doc string + if (docstring && doc_entry) { + *pyclass << tab8 << "\"\"\"" << add_docstring(doc_entry) << "\"\"\"\n"; + } + *pyclass << tab8 << "val = apply(" << module << "." << name_member(realname,class_name) << ",(self,) + _args, _kwargs)\n"; + + // Check to see if the return type is an object + if ((hash.lookup(t->name)) && (t->is_pointer <= 1)) { + if (!typemap_check("out",typemap_lang,t,name_member(realname,class_name))) { + if (!have_output) { + *pyclass << tab8 << "if val: val = " << (char *) hash.lookup(t->name) << "Ptr(val) "; + if (((hash.lookup(t->name)) && (t->is_pointer < 1)) || + ((hash.lookup(t->name)) && (t->is_pointer == 1) && NewObject)) + *pyclass << "; val.thisown = 1\n"; + else + *pyclass << "\n"; + } else { + // Do nothing! + } + } + } + emitAddPragmas(*pyclass, realname, tab8); + *pyclass << tab8 << "return val\n"; + + // Change the usage string to reflect our shadow class + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << usage_func(realname,t,l); + } + } +} + +// ----------------------------------------------------------------------------- +// void PYTHON::cpp_constructor(char *name, char *iname, ParmList *l) +// +// Make a constructor for our class +// ----------------------------------------------------------------------------- + +void PYTHON::cpp_constructor(char *name, char *iname, ParmList *l) { + char *realname; + Parm *p; + int i; + int oldshadow = shadow; + String cname = "python:constructor:"; + String translate = ""; + int pcount, numopt; + int have_optional; + + if (shadow) shadow = shadow | PYSHADOW_MEMBER; + this->Language::cpp_constructor(name,iname,l); + shadow = oldshadow; + + if (shadow) { + if (iname) + realname = iname; + else { + if (class_renamed) realname = class_name; + else realname = class_name; + } + + // Check to see if we've already seen this + cname << class_name << "::" << realname; + if (add_symbol(cname.get(), 0,0)) { + return; // Forget it, already seen it + } + + if (!have_constructor) { + + // Create a new constructor + + *construct << tab4 << "def __init__(self,*_args,**_kwargs):\n"; + if (docstring && doc_entry) + *construct << tab8 << "\"\"\"" << add_docstring(doc_entry) << "\"\"\"\n"; + + *construct << tab8 << "self.this = apply(" << module << "." << name_construct(realname) << ",_args,_kwargs)\n"; + *construct << tab8 << "self.thisown = 1\n"; + emitAddPragmas(*construct,"__init__",tab8); + have_constructor = 1; + } else { + + // Hmmm. We seem to be creating a different constructor. We're just going to create a + // function for it. + + *additional << "def " << realname << "(*_args,**_kwargs):\n"; + *additional << tab4 << "val = " << class_name << "Ptr(apply(" + << module << "." << name_construct(realname) << ",_args,_kwargs))\n" + << tab4 << "val.thisown = 1\n"; + emitAddPragmas(*additional, realname, tab4); + *additional << tab4 << "return val\n\n"; + } + // Patch up the documentation entry + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << usage_func(class_name,0,l); + } + } +} + +// ------------------------------------------------------------------------------ +// void PYTHON::cpp_destructor(char *name, char *newname) +// +// Creates a destructor for this object +// ------------------------------------------------------------------------------ + +void PYTHON::cpp_destructor(char *name, char *newname) { + char *realname; + int oldshadow = shadow; + + if (shadow) shadow = shadow | PYSHADOW_MEMBER; + this->Language::cpp_destructor(name,newname); + shadow = oldshadow; + if (shadow) { + if (newname) realname = newname; + else { + if (class_renamed) realname = class_name; + else realname = name; + } + + *pyclass << tab4 << "def __del__(self," << module << "=" << module << "):\n"; + emitAddPragmas(*pyclass,"__del__",tab8); + *pyclass << tab8 << "if self.thisown == 1 :\n" + << tab8 << tab4 << module << "." << name_destroy(realname) << "(self)\n"; + + have_destructor = 1; + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << "del this"; + } + } +} + +// ------------------------------------------------------------------------------- +// PYTHON::cpp_close_class() +// +// Closes a Python class and writes out a wrapper +// ------------------------------------------------------------------------------- + +void PYTHON::cpp_close_class() { + String ptrclass; + String repr; + + if (shadow) { + + if (!have_constructor) { + // Build a constructor that takes a pointer to this kind of object + *construct << tab4 << "def __init__(self,this):\n"; + *construct << tab8 << "self.this = this\n"; + } + + // First, build the pointer base class + if (base_class) { + ptrclass << "class " << class_name << "Ptr(" << *base_class << "):\n"; + } else { + ptrclass << "class " << class_name << "Ptr :\n"; + } + + // *getattr << tab8 << "return self.__dict__[name]\n"; + *getattr << tab8 << "raise AttributeError,name\n"; + *setattr << tab8 << "self.__dict__[name] = value\n"; + + ptrclass << *cinit + << tab4 << "def __init__(self,this):\n" + << tab8 << "self.this = this\n" + << tab8 << "self.thisown = 0\n"; + + classes << ptrclass + << *pyclass; + if (have_setattr) + classes << *setattr; + if (have_getattr) + classes << *getattr; + + if (!have_repr) { + // Supply a repr method for this class + repr << tab4 << "def __repr__(self):\n" + << tab8 << "return \"\" % (self.this,)\n"; + + classes << repr; + emitAddPragmas(classes,"__class__",tab4); + } + + // Now build the real class with a normal constructor + + classes << "class " << class_name << "(" << class_name << "Ptr):\n"; + + if (docstring && doc_entry) { + classes << tab4 << "\"\"\"" << add_docstring(doc_entry) << "\"\"\"\n"; + } + + classes << *construct << "\n\n" + << "\n" << *additional << "\n"; + + delete pyclass; + delete setattr; + delete getattr; + delete additional; + } +} + +void PYTHON::cpp_cleanup() { }; + +void PYTHON::cpp_inherit(char **baseclass,int) { + + char *bc; + int i = 0, first_base = 0; + + if (!shadow) { + this->Language::cpp_inherit(baseclass); + return; + } + + // We'll inherit variables and constants, but not methods + + this->Language::cpp_inherit(baseclass, INHERIT_VAR); + + if (!baseclass) return; + base_class = new String; + + // Now tell the Python module that we're inheriting from a base class + + while (baseclass[i]) { + bc = (char *) hash.lookup(baseclass[i]); + if (bc) { + if (first_base) *base_class << ","; + *base_class << bc << "Ptr"; + first_base = 1; + } + i++; + } + if (!first_base) { + delete base_class; + base_class = 0; + } +} + +// -------------------------------------------------------------------------------- +// PYTHON::cpp_variable(char *name, char *iname, DataType *t) +// +// Adds an instance member. +// -------------------------------------------------------------------------------- + +void PYTHON::cpp_variable(char *name, char *iname, DataType *t) { + char *realname; + int inhash = 0; + int oldshadow = shadow; + String cname = "python:"; + + if (shadow) shadow = shadow | PYSHADOW_MEMBER; + this->Language::cpp_variable(name,iname,t); + shadow = oldshadow; + + if (shadow) { + have_getattr = 1; + have_setattr = 1; + if (!iname) + realname = name; + else + realname = iname; + + // Check to see if we've already seen this + + cname << class_name << "::" << realname; + if (add_symbol(cname.get(), 0,0)) { + return; // Forget it, already seen it + } + + // Figure out if we've seen this datatype before + + if ((hash.lookup(t->name)) && (t->is_pointer <= 1)) inhash = 1; + + // Now write some code to set the variable + *setattr << tab8 << "if name == \"" << realname << "\" :\n"; + if (inhash) { + *setattr << tab8 << tab4 << module << "." << name_set(name_member(realname,class_name)) << "(self,value.this)\n"; + } else { + *setattr << tab8 << tab4 << module << "." << name_set(name_member(realname,class_name)) << "(self,value)\n"; + } + *setattr << tab8 << tab4 << "return\n"; + + // Write some code to get the variable + *getattr << tab8 << "if name == \"" << realname << "\" : \n"; + if (inhash) { + *getattr << tab8 << tab4 << "return " << (char *) hash.lookup(t->name) << "Ptr(" << module << "." + << name_get(name_member(realname,class_name)) << "(self))\n"; + } else { + *getattr << tab8 << tab4 << "return " << module << "." << name_get(name_member(realname,class_name)) << "(self)\n"; + } + + // Patch up ye old documentation entry + + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << "self." << realname; + } + } +} + +// -------------------------------------------------------------------------------- +// PYTHON::cpp_declare_const(char *name, char *iname, DataType *type, char *value) +// +// Add access to a C++ constant +// -------------------------------------------------------------------------------- + +void PYTHON::cpp_declare_const(char *name, char *iname, DataType *type, char *value) { + char *realname; + int oldshadow = shadow; + String cname = "python:"; + + if (shadow) shadow = shadow | PYSHADOW_MEMBER; + this->Language::cpp_declare_const(name,iname,type,value); + shadow = oldshadow; + + if (shadow) { + if (!iname) + realname = name; + else + realname = iname; + + // Check to see if we've already seen this + + cname << class_name << "::" << realname; + if (add_symbol(cname.get(), 0,0)) { + return; // Forget it, already seen it + } + + *cinit << tab4 << realname << " = " << module << "." << name_member(realname,class_name) << "\n"; + + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << "self." << realname; + if (value) { + doc_entry->usage << " = " << value; + } + } + } +} + +// -------------------------------------------------------------------------------- +// PYTHON::add_typedef(DataType *t, char *name) +// +// This is called whenever a typedef is encountered. When shadow classes are +// used, this function lets us discovered hidden uses of a class. For example : +// +// struct FooBar { +// ... +// } +// +// typedef FooBar *FooBarPtr; +// +// -------------------------------------------------------------------------------- + +void PYTHON::add_typedef(DataType *t, char *name) { + + if (!shadow) return; + + // First check to see if there aren't too many pointers + + if (t->is_pointer > 1) return; + + if (hash.lookup(name)) return; // Already added + + + // Now look up the datatype in our shadow class hash table + + if (hash.lookup(t->name)) { + + // Yep. This datatype is in the hash + + // Put this types 'new' name into the hash + + hash.add(name,copy_string((char *) hash.lookup(t->name))); + } +} diff --git a/wxPython/wxSWIG/Modules/python.cxx b/wxPython/wxSWIG/Modules/python.cxx new file mode 100644 index 0000000000..f2c9f41b2b --- /dev/null +++ b/wxPython/wxSWIG/Modules/python.cxx @@ -0,0 +1,1640 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/********************************************************************** + * $Header$ + * + * python.cxx + * + * Python module. + **************************************************************************/ + + +#include "swig.h" +#include "python.h" + +// Structures for managing doc strings + +struct DocString { + DocEntry *de; + char *name; + DocString *next; +}; + +static int doc_index = 0; +static DocString *doc_strings = 0; + +static char *usage = "\ +Python Options (available with -python)\n\ + -docstring - Produce docstrings (only applies to shadow classes)\n\ + -globals name - Set name used to access C global variable ('cvar' by default).\n\ + -module name - Set module name\n\ + -keyword - Use keyword arguments\n\ + -shadow - Generate shadow classes. \n\n"; + +static String pragma_include; + +// --------------------------------------------------------------------- +// PYTHON::parse_args(int argc, char *argv[]) +// +// --------------------------------------------------------------------- + +void PYTHON::parse_args(int argc, char *argv[]) { + + int i = 1; + + sprintf(LibDir,"%s",path); + + docstring = 0; + + // Look for additional command line options. + for (i = 1; i < argc; i++) { + if (argv[i]) { + if(strcmp(argv[i],"-module") == 0) { + if (argv[i+1]) { + module = new char[strlen(argv[i+1])+2]; + strcpy(module, argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i+=1; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-globals") == 0) { + if (argv[i+1]) { + global_name = new char[strlen(argv[i+1])+1]; + strcpy(global_name, argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-shadow") == 0) { + shadow = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-docstring") == 0) { + docstring = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-keyword") == 0) { + use_kw = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + } + } + } + // Create a symbol for this language + add_symbol("SWIGPYTHON",0,0); + + // Set name of typemaps + + typemap_lang = "python"; + +} + +// --------------------------------------------------------------------- +// PYTHON::parse() +// +// Parse the interface file +// --------------------------------------------------------------------- + +void +PYTHON::parse() { + + printf("Generating wrappers for Python\n"); + headers(); + + // Run the SWIG parser + + yyparse(); +} + +// --------------------------------------------------------------------- +// PYTHON::set_module(char *mod_name, char **mod_list) +// +// Sets the module name. +// Does nothing if it's already set (so it can be overridden as a command +// line option). +// +//---------------------------------------------------------------------- + +void PYTHON::set_module(char *mod_name, char **mod_list) { + int i; + + // If an "import" method has been set and we're in shadow class mode, + // output a python command to load the module + + if (import_file) { + if (!(strcmp(import_file,input_file+strlen(input_file)-strlen(import_file)))) { + if (shadow) { + fprintf(f_shadow,"\nfrom %s import *\n", mod_name); + } + delete import_file; + import_file = 0; + } + } + + if (module) return; + + module = new char[strlen(mod_name)+1]; + strcpy(module,mod_name); + + // If there was a mod_list specified, make this incredible hack + if (mod_list) { + modinit << "#define SWIGMODINIT "; + modextern << "#ifdef __cplusplus\n" + << "extern \"C\" {\n" + << "#endif\n"; + i = 0; + while(mod_list[i]) { + modinit << "swig_add_module(\"" << mod_list[i] << "\",init" + << mod_list[i] << "); \\\n"; + + modextern << "extern void init" << mod_list[i] << "();\n"; + i++; + } + modextern << "#ifdef __cplusplus\n" + << "}\n" + << "#endif\n"; + modinit << "/* End of extern module initialization */\n"; + + } +} + +// --------------------------------------------------------------------- +// PYTHON::set_init(char *iname) +// +// Sets the initialization function name. +// Does nothing if it's already set +// +//---------------------------------------------------------------------- + +void PYTHON::set_init(char *iname) { + set_module(iname,0); +} + + +// --------------------------------------------------------------------- +// PYTHON::import(char *filename) +// +// Imports a SWIG module as a separate file. +//---------------------------------------------------------------------- + +void PYTHON::import(char *filename) { + if (import_file) delete import_file; + import_file = copy_string(filename); +} + +// ---------------------------------------------------------------------- +// PYTHON::add_method(char *name, char *function) +// +// Add some symbols to the methods table +// ---------------------------------------------------------------------- + +void PYTHON::add_method(char *name, char *function) { + + Method *n; + + n = new Method; + n->name = new char[strlen(name)+1]; + strcpy(n->name,name); + n->function = new char[strlen(function)+1]; + strcpy(n->function, function); + + n->next = head; + head = n; +} + +// --------------------------------------------------------------------- +// PYTHON::print_methods() +// +// Prints out the method array. +// --------------------------------------------------------------------- + +void PYTHON::print_methods() { + + Method *n; + + fprintf(f_wrappers,"static PyMethodDef %sMethods[] = {\n", module); + n = head; + while (n) { + if (!use_kw) { + fprintf(f_wrappers,"\t { \"%s\", %s, METH_VARARGS },\n", n->name, n->function); + } else { + fprintf(f_wrappers,"\t { \"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS },\n", n->name, n->function); + } + n = n->next; + } + fprintf(f_wrappers,"\t { NULL, NULL }\n"); + fprintf(f_wrappers,"};\n"); + fprintf(f_wrappers,"#ifdef __cplusplus\n"); + fprintf(f_wrappers,"}\n"); + fprintf(f_wrappers,"#endif\n"); +} + +// --------------------------------------------------------------------- +// char *PYTHON::add_docstring(DocEntry *de) +// +// Adds a documentation entry to the doc-string generator. Returns a +// unique character symbol that will be used to fill in the doc-string +// at a later time. +// --------------------------------------------------------------------- + +char *PYTHON::add_docstring(DocEntry *de) { + DocString *s; + String str; + + str = "@doc"; + str << doc_index << "@"; + + s = new DocString(); + s->de = de; + s->name = copy_string(str); + s->next = doc_strings; + doc_strings = s; + doc_index++; + return s->name; +} + +// --------------------------------------------------------------------- +// PYTHON::headers(void) +// +// ---------------------------------------------------------------------- + +void PYTHON::headers(void) +{ + + emit_banner(f_header); + + fprintf(f_header,"/* Implementation : PYTHON */\n\n"); + fprintf(f_header,"#define SWIGPYTHON\n"); + + if (!NoInclude) { + if (insert_file("python.swg", f_header) == -1) { + fprintf(stderr,"SWIG : Fatal error. Unable to locate python.swg. (Possible installation problem).\n"); + SWIG_exit(1); + } + } else { + if (insert_file("pyexp.swg", f_header) == -1) { + fprintf(stderr,"SWIG : Fatal error. Unable to locate pyexp.swg. (Possible installation problem).\n"); + SWIG_exit(1); + } + } +} + + +// -------------------------------------------------------------------- +// PYTHON::initialize(void) +// +// This function outputs the starting code for a function to initialize +// your interface. It is only called once by the parser. +// +// --------------------------------------------------------------------- + +void PYTHON::initialize(void) +{ + + char filen[256]; + char *temp; + char *oldmodule = 0; + + if (!module) { + module = "swig"; + fprintf(stderr,"SWIG : *** Warning. No module name specified.\n"); + } + + // If shadow classing is enabled, we're going to change the module + // name to "modulec" + + if (shadow) { + temp = new char[strlen(module)+2]; + sprintf(temp,"%sc",module); + oldmodule = module; + module = temp; + } + /* Initialize the C code for the module */ + initialize_cmodule(); + /* Create a shadow file (if enabled).*/ + if (shadow) { + sprintf(filen,"%s%s.py", output_dir, oldmodule); + if ((f_shadow = fopen(filen,"w")) == 0) { + fprintf(stderr,"Unable to open %s\n", filen); + SWIG_exit(0); + } + fprintf(f_shadow,"# This file was created automatically by SWIG.\n"); + fprintf(f_shadow,"import %s\n", module); + } + + // Dump out external module declarations + + if (strlen(modinit.get()) > 0) { + fprintf(f_header,"%s\n",modinit.get()); + } + if (strlen(modextern.get()) > 0) { + fprintf(f_header,"%s\n",modextern.get()); + } + fprintf(f_wrappers,"#ifdef __cplusplus\n"); + fprintf(f_wrappers,"extern \"C\" {\n"); + fprintf(f_wrappers,"#endif\n"); +} + +// --------------------------------------------------------------------- +// PYTHON::initialize_cmodule(void) +// +// Initializes the C module. +// +// --------------------------------------------------------------------- +void PYTHON::initialize_cmodule(void) +{ + int i; + fprintf(f_header,"#define SWIG_init init%s\n\n", module); + fprintf(f_header,"#define SWIG_name \"%s\"\n", module); + + // Output the start of the init function. + // Modify this to use the proper return type and arguments used + // by the target Language + + fprintf(f_init,"static PyObject *SWIG_globals;\n"); + + fprintf(f_init,"#ifdef __cplusplus\n"); + fprintf(f_init,"extern \"C\" \n"); + fprintf(f_init,"#endif\n"); + + fprintf(f_init,"SWIGEXPORT(void) init%s() {\n",module); + fprintf(f_init,"\t PyObject *m, *d;\n"); + + if (InitNames) { + i = 0; + while (InitNames[i]) { + fprintf(f_init,"\t %s();\n", InitNames[i]); + i++; + } + } + fprintf(f_init,"\t SWIG_globals = SWIG_newvarlink();\n"); + fprintf(f_init,"\t m = Py_InitModule(\"%s\", %sMethods);\n", module, module); + fprintf(f_init,"\t d = PyModule_GetDict(m);\n"); +} + + +// --------------------------------------------------------------------- +// PYTHON::close(void) +// +// Called when the end of the interface file is reached. Closes the +// initialization function and performs cleanup as necessary. +// --------------------------------------------------------------------- + +void PYTHON::close(void) +{ + + print_methods(); + close_cmodule(); + if ((doc_entry) && (module)){ + String temp; + temp << "Python Module : "; + if (shadow) { + module[strlen(module)-1] = 0; + } + temp << module; + doc_entry->cinfo << temp; + } + if (shadow) { + String fullshadow; + fullshadow << classes + << "\n\n#-------------- FUNCTION WRAPPERS ------------------\n\n" + << func + << "\n\n#-------------- VARIABLE WRAPPERS ------------------\n\n" + << vars; + + if (strlen(pragma_include) > 0) { + fullshadow << "\n\n#-------------- USER INCLUDE -----------------------\n\n" + << pragma_include; + } + + // Go through all of the docstrings and replace the docstrings + + DocString *s; + s = doc_strings; + while (s) { + fullshadow.replace(s->name, s->de->text); + s = s->next; + } + /* + fprintf(f_shadow,"\n\n#-------------- FUNCTION WRAPPERS ------------------\n\n"); + fprintf(f_shadow,"%s",func.get()); + fprintf(f_shadow,"\n\n#-------------- VARIABLE WRAPPERS ------------------\n\n"); + fprintf(f_shadow,"%s",vars.get()); + if (strlen(pragma_include) > 0) { + fprintf(f_shadow,"\n\n#-------------- USER INCLUDE -----------------------\n\n"); + fprintf(f_shadow,"%s",pragma_include.get()); + } + */ + fprintf(f_shadow, "%s", fullshadow.get()); + fclose(f_shadow); + } +} + +// -------------------------------------------------------------------- +// PYTHON::close_cmodule(void) +// +// Called to cleanup the C module code +// -------------------------------------------------------------------- +void PYTHON::close_cmodule(void) +{ + emit_ptr_equivalence(f_init); + fprintf(f_init,"}\n"); +} + +// ---------------------------------------------------------------------- +// PYTHON::get_pointer(char *iname, char *srcname, char *src, char *target, +// DataType *t, WrapperFunction &f, char *ret) +// +// Emits code to get a pointer and do type checking. +// iname = name of the function/method (used for error messages) +// srcname = Name of source (used for error message reporting). +// src = name of variable where source string is located. +// dest = name of variable where pointer value is stored. +// t = Expected datatype of the parameter +// f = Wrapper function object being used to generate code. +// ret = return code upon failure. +// +// Note : pointers are stored as strings so you first need to get +// a string and then call _swig_get_hex() to extract a point. +// +// This module is pretty ugly, but type checking is kind of nasty +// anyways. +// ---------------------------------------------------------------------- + +void +PYTHON::get_pointer(char *iname, char *srcname, char *src, char *dest, + DataType *t, String &f, char *ret) +{ + + // Now get the pointer value from the string and save in dest + + f << tab4 << "if (" << src << ") {\n" + << tab8 << "if (" << src << " == Py_None) { " << dest << " = NULL; }\n" + << tab8 << "else if (SWIG_GetPtrObj(" << src << ",(void **) &" << dest << ","; + + // If we're passing a void pointer, we give the pointer conversion a NULL + // pointer, otherwise pass in the expected type. + + if (t->type == T_VOID) f << "(char *) 0 )) {\n"; + else + f << "\"" << t->print_mangle() << "\")) {\n"; + + // This part handles the type checking according to three different + // levels. 0 = no checking, 1 = warning message, 2 = strict. + + switch(TypeStrict) { + case 0: // No type checking + f << tab8 << "}\n"; + break; + + case 1: // Warning message only + + // Change this part to how you want to handle a type-mismatch warning. + // By default, it will just print to stderr. + + f << tab8 << tab4 << "fprintf(stderr,\"Warning : type mismatch in " << srcname + << " of " << iname << ". Expected " << t->print_mangle() + << ", received %s\\n\"," << src << ");\n" + << tab8 << "}\n"; + + break; + case 2: // Super strict mode. + + // Change this part to return an error. + + f << tab8 << tab4 << "PyErr_SetString(PyExc_TypeError,\"Type error in " << srcname + << " of " << iname << ". Expected " << t->print_mangle() << ".\");\n" + << tab8 << "return " << ret << ";\n" + << tab8 << "}\n"; + break; + + default : + fprintf(stderr,"SWIG Error. Unknown strictness level\n"); + break; + } + f << tab4 << "}\n"; +} + +// ---------------------------------------------------------------------- +// PYTHON::emit_function_header() +// +// Return the code to be used as a function header +// ---------------------------------------------------------------------- +void PYTHON::emit_function_header(WrapperFunction &emit_to, char *wname) +{ + if (!use_kw) { + emit_to.def << "static PyObject *" << wname + << "(PyObject *self, PyObject *args) {"; + } else { + emit_to.def << "static PyObject *" << wname + << "(PyObject *self, PyObject *args, PyObject *kwargs) {"; + } + emit_to.code << tab4 << "self = self;\n"; +} + +// ---------------------------------------------------------------------- +// PYTHON::convert_self() +// +// Called during the function generation process, to determine what to +// use as the "self" variable during the call. Derived classes may emit code +// to convert the real self pointer into a usable pointer. +// +// Returns the name of the variable to use as the self pointer +// ---------------------------------------------------------------------- +char *PYTHON::convert_self(WrapperFunction &) +{ + // Default behaviour is no translation + return ""; +} + +// ---------------------------------------------------------------------- +// PYTHON::make_funcname_wrapper() +// +// Called to create a name for a wrapper function +// ---------------------------------------------------------------------- +char *PYTHON::make_funcname_wrapper(char *fnName) +{ + return name_wrapper(fnName,""); +} + +// ---------------------------------------------------------------------- +// PYTHON::create_command(char *cname, char *iname) +// +// Create a new command in the interpreter. Used for C++ inheritance +// stuff. +// ---------------------------------------------------------------------- + +void PYTHON::create_command(char *cname, char *iname) { + + // Create the name of the wrapper function + + char *wname = name_wrapper(cname,""); + + // Now register the function with the interpreter. + + add_method(iname, wname); + +} + +// ---------------------------------------------------------------------- +// PYTHON::create_function(char *name, char *iname, DataType *d, +// ParmList *l) +// +// This function creates a wrapper function and registers it with the +// interpreter. +// +// Inputs : +// name = actual name of the function that's being wrapped +// iname = name of the function in the interpreter (may be different) +// d = Return datatype of the functions. +// l = A linked list containing function parameter information. +// +// ---------------------------------------------------------------------- + +void PYTHON::create_function(char *name, char *iname, DataType *d, ParmList *l) +{ + Parm *p; + int pcount,i,j; + String wname, self_name, call_name; + char source[64], target[64], temp[256], argnum[20]; + char *usage = 0; + WrapperFunction f; + String parse_args; + String arglist; + String get_pointers; + String cleanup, outarg; + String check; + String build; + String kwargs; + + int have_build = 0; + char *tm; + int numopt = 0; + + have_output = 0; + + // Make a valid name for this function. This removes special symbols + // that would cause problems in the C compiler. + + wname = make_funcname_wrapper(iname); + + // Now emit the function declaration for the wrapper function. You + // should modify this to return the appropriate types and use the + // appropriate parameters. + + emit_function_header(f, wname); + + f.add_local("PyObject *","_resultobj"); + + // Get the function usage string for later use + + usage = usage_func(iname,d,l); + + // Write code to extract function parameters. + // This is done in one pass, but we need to construct three independent + // pieces. + // 1. Python format string such as "iis" + // 2. The actual arguments to put values into + // 3. Pointer conversion code. + // + // If there is a type mapping, we will extract the Python argument + // as a raw PyObject and let the user deal with it. + // + + pcount = emit_args(d, l, f); + if (!use_kw) { + parse_args << tab4 << "if(!PyArg_ParseTuple(args,\""; + } else { + parse_args << tab4 << "if(!PyArg_ParseTupleAndKeywords(args,kwargs,\""; + arglist << ",_kwnames"; + } + + i = 0; + j = 0; + numopt = l->numopt(); // Get number of optional arguments + if (numopt) have_defarg = 1; + p = l->get_first(); + + kwargs << "{ "; + while (p != 0) { + + // Generate source and target strings + sprintf(source,"_obj%d",i); + sprintf(target,"_arg%d",i); + sprintf(argnum,"%d",j+1); + + // Only consider this argument if it's not ignored + + if (!p->ignore) { + arglist << ","; + // Add an optional argument separator if needed + + if (j == pcount-numopt) { + parse_args << "|"; + } + + if (strlen(p->name)) { + kwargs << "\"" << p->name << "\","; + } else { + kwargs << "\"arg" << j+1 << "\","; + // kwargs << "\"\","; + } + + // Look for input typemap + + if ((tm = typemap_lookup("in","python",p->t,p->name,source,target,&f))) { + parse_args << "O"; // Grab the argument as a raw PyObject + f.add_local("PyObject *",source,"0"); + arglist << "&" << source; + if (i >= (pcount-numopt)) + get_pointers << tab4 << "if (" << source << ")\n"; + get_pointers << tm << "\n"; + get_pointers.replace("$argnum", argnum); + get_pointers.replace("$arg",source); + } else { + + // Check if this parameter is a pointer. If not, we'll get values + + if (!p->t->is_pointer) { + // Extract a parameter by "value" + + switch(p->t->type) { + + // Handle integers here. Usually this can be done as a single + // case if you appropriate cast things. However, if you have + // special cases, you'll need to add more code. + + case T_INT : case T_UINT: case T_SINT: + parse_args << "i"; + break; + case T_SHORT: case T_USHORT: case T_SSHORT: + parse_args << "h"; + break; + case T_LONG : case T_ULONG: case T_SLONG : + parse_args << "l"; + break; + case T_SCHAR : case T_UCHAR : + parse_args << "b"; + break; + case T_CHAR: + parse_args << "c"; + break; + case T_FLOAT : + parse_args << "f"; + break; + case T_DOUBLE: + parse_args << "d"; + break; + + case T_BOOL: + { + String tempb; + String tempval; + if (p->defvalue) { + tempval << "(int) " << p->defvalue; + } + tempb << "tempbool" << i; + parse_args << "i"; + if (!p->defvalue) + f.add_local("int",tempb.get()); + else + f.add_local("int",tempb.get(),tempval.get()); + get_pointers << tab4 << target << " = " << p->t->print_cast() << " " << tempb << ";\n"; + arglist << "&" << tempb; + } + break; + + // Void.. Do nothing. + + case T_VOID : + break; + + // User defined. This is usually invalid. No way to pass a + // complex type by "value". We'll just pass into the unsupported + // datatype case. + + case T_USER: + + // Unsupported data type + + default : + fprintf(stderr,"%s : Line %d. Unable to use type %s as a function argument.\n",input_file, line_number, p->t->print_type()); + break; + } + + // Emit code for parameter list + + if ((p->t->type != T_VOID) && (p->t->type != T_BOOL)) + arglist << "&_arg" << i; + + } else { + + // Is some other kind of variable. + + if ((p->t->type == T_CHAR) && (p->t->is_pointer == 1)) { + parse_args << "s"; + arglist << "&_arg" << i; + } else { + + // Have some sort of pointer variable. Create a temporary local + // variable for the string and read the pointer value into it. + + parse_args << "O"; + sprintf(source,"_argo%d", i); + sprintf(target,"_arg%d", i); + sprintf(temp,"argument %d",i+1); + + f.add_local("PyObject *", source,"0"); + arglist << "&" << source; + get_pointer(iname, temp, source, target, p->t, get_pointers, "NULL"); + } + } + } + j++; + } + // Check if there was any constraint code + if ((tm = typemap_lookup("check","python",p->t,p->name,source,target))) { + check << tm << "\n"; + check.replace("$argnum", argnum); + } + // Check if there was any cleanup code + if ((tm = typemap_lookup("freearg","python",p->t,p->name,target,source))) { + cleanup << tm << "\n"; + cleanup.replace("$argnum", argnum); + cleanup.replace("$arg",source); + } + if ((tm = typemap_lookup("argout","python",p->t,p->name,target,"_resultobj"))) { + outarg << tm << "\n"; + outarg.replace("$argnum", argnum); + outarg.replace("$arg",source); + have_output++; + } + if ((tm = typemap_lookup("build","python",p->t,p->name,source,target))) { + build << tm << "\n"; + have_build = 1; + } + p = l->get_next(); + i++; + } + + kwargs << " NULL }"; + if (use_kw) { + f.locals << tab4 << "char *_kwnames[] = " << kwargs << ";\n"; + } + + parse_args << ":" << iname << "\""; // No additional arguments + parse_args << arglist << ")) \n" + << tab8 << "return NULL;\n"; + + self_name = convert_self(f); + + /* Now slap the whole first part of the wrapper function together */ + + f.code << parse_args << get_pointers << check; + + + // Special handling for build values + + if (have_build) { + char temp1[256]; + char temp2[256]; + l->sub_parmnames(build); // Replace all parameter names + for (i = 0; i < l->nparms; i++) { + p = l->get(i); + if (strlen(p->name) > 0) { + sprintf(temp1,"_in_%s", p->name); + } else { + sprintf(temp1,"_in_arg%d", i); + } + sprintf(temp2,"_obj%d",i); + build.replaceid(temp1,temp2); + } + f.code << build; + } + + // This function emits code to call the real function. Assuming you read + // the parameters in correctly, this will work. + + call_name = ""; + call_name << self_name << name; + emit_func_call(call_name,d,l,f); + + // Now emit code to return the functions return value (if any). + // If there was a result, it was saved in _result. + // If the function is a void type, don't do anything. + + if ((strncmp(name, "new_", 4) != 0) && // don't use the out typemap for constructors + (tm = typemap_lookup("out","python",d,iname,"_result","_resultobj"))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + } else { + + if ((d->type != T_VOID) || (d->is_pointer)) { + // Now have return value, figure out what to do with it. + + if (!d->is_pointer) { + + // Function returns a "value" + + switch(d->type) { + + // Return an integer type + + case T_INT: case T_SINT: case T_UINT: case T_BOOL: + f.code << tab4 << "_resultobj = Py_BuildValue(\"i\",_result);\n"; + break; + case T_SHORT: case T_SSHORT: case T_USHORT: + f.code << tab4 << "_resultobj = Py_BuildValue(\"h\",_result);\n"; + break; + case T_LONG : case T_SLONG : case T_ULONG: + f.code << tab4 << "_resultobj = Py_BuildValue(\"l\",_result);\n"; + break; + case T_SCHAR: case T_UCHAR : + f.code << tab4 << "_resultobj = Py_BuildValue(\"b\",_result);\n"; + break; + + // Return a floating point value + + case T_DOUBLE : + f.code << tab4 << "_resultobj = Py_BuildValue(\"d\",_result);\n"; + break; + case T_FLOAT : + f.code << tab4 << "_resultobj = Py_BuildValue(\"f\",_result);\n"; + break; + + // Return a single ASCII value. Usually we need to convert + // it to a NULL-terminate string and return that instead. + + case T_CHAR : + f.code << tab4 << "_resultobj = Py_BuildValue(\"c\",_result);\n"; + break; + + case T_USER : + + // Return something by value + // We're living dangerously here, but life is short...play hard + + // Oops. Need another local variable + f.add_local("char","_ptemp[128]"); + + d->is_pointer++; + f.code << tab4 << "SWIG_MakePtr(_ptemp, (void *) _result,\"" + << d->print_mangle() << "\");\n"; + d->is_pointer--; + // Return a character string containing our pointer. + + f.code << tab4 << "_resultobj = Py_BuildValue(\"s\",_ptemp);\n"; + break; + default : + fprintf(stderr,"%s: Line %d. Unable to use return type %s in function %s.\n", input_file, line_number, d->print_type(), name); + break; + } + } else { + + // Return type is a pointer. We'll see if it's a char * and return + // a string. Otherwise, we'll convert it into a SWIG pointer and return + // that. + + if ((d->type == T_CHAR) && (d->is_pointer == 1)) { + + // Return a character string + f.code << tab4 << "_resultobj = Py_BuildValue(\"s\", _result);\n"; + + // If declared as a new object, free the result + + } else { + + // Build a SWIG pointer. + f.add_local("char","_ptemp[128]"); + f.code << tab4 << "if (_result) {\n" + << tab8 << "SWIG_MakePtr(_ptemp, (char *) _result,\"" + << d->print_mangle() << "\");\n"; + + // Return a character string containing our pointer. + f.code << tab8 << "_resultobj = Py_BuildValue(\"s\",_ptemp);\n"; + f.code << tab4 << "} else {\n" + << tab8 << "Py_INCREF(Py_None);\n" + << tab8 << "_resultobj = Py_None;\n" + << tab4 << "}\n"; + } + } + } else { + // no return value and no output args + //if (!have_output) { + f.code << tab4 << "Py_INCREF(Py_None);\n"; + f.code << tab4 << "_resultobj = Py_None;\n"; + //} + } + } + + // Check to see if there were any output arguments, if so we're going to + // create a Python list object out of the current result + + f.code << outarg; + + // If there was any other cleanup needed, do that + + f.code << cleanup; + + // Look to see if there is any newfree cleanup code + + if (NewObject) { + if ((tm = typemap_lookup("newfree","python",d,iname,"_result",""))) { + f.code << tm << "\n"; + } + } + + // See if there is any argument cleanup code + + if ((tm = typemap_lookup("ret","python",d,iname,"_result",""))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + } + + f.code << tab4 << "return _resultobj;\n"; + f.code << "}\n"; + + // Substitute the cleanup code + f.code.replace("$cleanup",cleanup); + + // Substitute the function name + f.code.replace("$name",iname); + + // Dump the function out + f.print(f_wrappers); + + // Now register the function with the interpreter. + + add_method(iname, wname); + + // Create a documentation entry for this + + if (doc_entry) { + static DocEntry *last_doc_entry = 0; + doc_entry->usage << usage; + if (last_doc_entry != doc_entry) { + doc_entry->cinfo << "returns " << d->print_type(); + last_doc_entry = doc_entry; + } + } + + // --------------------------------------------------------------------------- + // Create a shadow for this function (if enabled and not in a member function) + // --------------------------------------------------------------------------- + + if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { + String translate; + + int need_wrapper = 0; + int munge_return = 0; + int have_optional = 0; + + // Check return code for modification + if ((hash.lookup(d->name)) && (d->is_pointer <=1)) { + need_wrapper = 1; + munge_return = 1; + } + + if (docstring && doc_entry) + need_wrapper = 1; + + // If no modification is needed. We're just going to play some + // symbol table games instead + + if (!need_wrapper) { + func << iname << " = " << module << "." << iname << "\n\n"; + } else { + func << "def " << iname << "(*_args, **_kwargs):\n"; + + // Create a docstring for this + if (docstring && doc_entry) { + func << tab4 << "\"\"\"" << add_docstring(doc_entry) << "\"\"\"\n"; + } + + func << tab4 << "val = apply(" << module << "." << iname << ",_args,_kwargs)\n"; + + if (munge_return) { + // If the output of this object has been remapped in any way, we're + // going to return it as a bare object. + + if (!typemap_check("out",typemap_lang,d,iname)) { + + // If there are output arguments, we are going to return the value + // unchanged. Otherwise, emit some shadow class conversion code. + + if (!have_output) { + func << tab4 << "if val: val = " << (char *) hash.lookup(d->name) << "Ptr(val)"; + if (((hash.lookup(d->name)) && (d->is_pointer < 1)) || + ((hash.lookup(d->name)) && (d->is_pointer == 1) && NewObject)) + func << "; val.thisown = 1\n"; + else + func << "\n"; + } else { + // Does nothing--returns the value unmolested + } + } + } + func << tab4 << "return val\n\n"; + } + } +} + +// ----------------------------------------------------------------------- +// PYTHON::link_variable(char *name, char *iname, DataType *d) +// +// Input variables: +// name = the real name of the variable being linked +// iname = Name of the variable in the interpreter (may be different) +// d = Datatype of the variable. +// +// This creates a pair of functions for evaluating/setting the value +// of a variable. These are then added to the special SWIG global +// variable type. +// ----------------------------------------------------------------------- + +void PYTHON::link_variable(char *name, char *iname, DataType *t) { + + char *wname; + static int have_globals = 0; + char *tm; + + WrapperFunction getf, setf; + + // If this is our first call, add the globals variable to the + // Python dictionary. + + if (!have_globals) { + fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", SWIG_globals);\n",global_name); + have_globals=1; + if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { + vars << global_name << " = " << module << "." << global_name << "\n"; + } + } + // First make a sanitized version of the function name (in case it's some + // funky C++ thing). + + wname = name_wrapper(name,""); + + // --------------------------------------------------------------------- + // Create a function for setting the value of the variable + // --------------------------------------------------------------------- + + setf.def << "static int " << wname << "_set(PyObject *val) {"; + if (!(Status & STAT_READONLY)) { + if ((tm = typemap_lookup("varin","python",t,name,"val",name))) { + setf.code << tm << "\n"; + setf.code.replace("$name",iname); + } else { + if ((t->type != T_VOID) || (t->is_pointer)) { + if (!t->is_pointer) { + + // Have a real value here + + switch(t->type) { + case T_INT: case T_SHORT: case T_LONG : + case T_UINT: case T_USHORT: case T_ULONG: + case T_SINT: case T_SSHORT: case T_SLONG: + case T_SCHAR: case T_UCHAR: case T_BOOL: + // Get an integer value + setf.add_local(t->print_type(), "tval"); + setf.code << tab4 << "tval = " << t->print_cast() << "PyInt_AsLong(val);\n" + << tab4 << "if (PyErr_Occurred()) {\n" + << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" + << iname << "'(" << t->print_type() << ")\");\n" + << tab8 << "return 1; \n" + << tab4 << "}\n" + << tab4 << name << " = tval;\n"; + break; + + case T_FLOAT: case T_DOUBLE: + // Get a floating point value + setf.add_local(t->print_type(), "tval"); + setf.code << tab4 << "tval = " << t->print_cast() << "PyFloat_AsDouble(val);\n" + << tab4 << "if (PyErr_Occurred()) {\n" + << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" + << iname << "'(" << t->print_type() << ")\");\n" + << tab8 << "return 1; \n" + << tab4 << "}\n" + << tab4 << name << " = tval;\n"; + break; + + // A single ascii character + + case T_CHAR: + setf.add_local("char *", "tval"); + setf.code << tab4 << "tval = (char *) PyString_AsString(val);\n" + << tab4 << "if (PyErr_Occurred()) {\n" + << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" + << iname << "'(" << t->print_type() << ")\");\n" + << tab8 << "return 1; \n" + << tab4 << "}\n" + << tab4 << name << " = *tval;\n"; + break; + case T_USER: + t->is_pointer++; + setf.add_local(t->print_type(),"temp"); + get_pointer(iname,"value","val","temp",t,setf.code,"1"); + setf.code << tab4 << name << " = *temp;\n"; + t->is_pointer--; + break; + default: + fprintf(stderr,"%s : Line %d. Unable to link with type %s.\n", input_file, line_number, t->print_type()); + } + } else { + + // Parse a pointer value + + if ((t->type == T_CHAR) && (t->is_pointer == 1)) { + setf.add_local("char *", "tval"); + setf.code << tab4 << "tval = (char *) PyString_AsString(val);\n" + << tab4 << "if (PyErr_Occurred()) {\n" + << tab8 << "PyErr_SetString(PyExc_TypeError,\"C variable '" + << iname << "'(" << t->print_type() << ")\");\n" + << tab8 << "return 1; \n" + << tab4 << "}\n"; + + if (CPlusPlus) { + setf.code << tab4 << "if (" << name << ") delete [] " << name << ";\n" + << tab4 << name << " = new char[strlen(tval)+1];\n" + << tab4 << "strcpy((char *)" << name << ",tval);\n"; + } else { + setf.code << tab4 << "if (" << name << ") free(" << name << ");\n" + << tab4 << name << " = (char *) malloc(strlen(tval)+1);\n" + << tab4 << "strcpy((char *)" << name << ",tval);\n"; + } + } else { + + // Is a generic pointer value. + + setf.add_local(t->print_type(),"temp"); + get_pointer(iname,"value","val","temp",t,setf.code,"1"); + setf.code << tab4 << name << " = temp;\n"; + } + } + } + } + setf.code << tab4 << "return 0;\n"; + } else { + // Is a readonly variable. Issue an error + setf.code << tab4 << "PyErr_SetString(PyExc_TypeError,\"Variable " << iname + << " is read-only.\");\n" + << tab4 << "return 1;\n"; + } + + setf.code << "}\n"; + + // Dump out function for setting value + + setf.print(f_wrappers); + + // ---------------------------------------------------------------- + // Create a function for getting the value of a variable + // ---------------------------------------------------------------- + + getf.def << "static PyObject *" << wname << "_get() {"; + getf.add_local("PyObject *","pyobj"); + if ((tm = typemap_lookup("varout","python",t,name,name,"pyobj"))) { + getf.code << tm << "\n"; + getf.code.replace("$name",iname); + } else if ((tm = typemap_lookup("out","python",t,name,name,"pyobj"))) { + getf.code << tm << "\n"; + getf.code.replace("$name",iname); + } else { + if ((t->type != T_VOID) || (t->is_pointer)) { + if (!t->is_pointer) { + + /* Is a normal datatype */ + switch(t->type) { + case T_INT: case T_SINT: case T_UINT: + case T_SHORT: case T_SSHORT: case T_USHORT: + case T_LONG: case T_SLONG: case T_ULONG: + case T_SCHAR: case T_UCHAR: case T_BOOL: + getf.code << tab4 << "pyobj = PyInt_FromLong((long) " << name << ");\n"; + break; + case T_FLOAT: case T_DOUBLE: + getf.code << tab4 << "pyobj = PyFloat_FromDouble((double) " << name << ");\n"; + break; + case T_CHAR: + getf.add_local("char","ptemp[2]"); + getf.code << tab4 << "ptemp[0] = " << name << ";\n" + << tab4 << "ptemp[1] = 0;\n" + << tab4 << "pyobj = PyString_FromString(ptemp);\n"; + break; + case T_USER: + // Hack this into a pointer + getf.add_local("char", "ptemp[128]"); + t->is_pointer++; + getf.code << tab4 << "SWIG_MakePtr(ptemp,(char *) &" << name + << "," << quote << t->print_mangle() << quote << ");\n" + << tab4 << "pyobj = PyString_FromString(ptemp);\n"; + t->is_pointer--; + break; + default: + fprintf(stderr,"Unable to link with type %s\n", t->print_type()); + break; + } + } else { + + // Is some sort of pointer value + if ((t->type == T_CHAR) && (t->is_pointer == 1)) { + getf.code << tab4 << "if (" << name << ")\n" + << tab8 << "pyobj = PyString_FromString(" << name << ");\n" + << tab4 << "else pyobj = PyString_FromString(\"(NULL)\");\n"; + } else { + getf.add_local("char","ptemp[128]"); + getf.code << tab4 << "SWIG_MakePtr(ptemp, (char *) " << name << ",\"" + << t->print_mangle() << "\");\n" + << tab4 << "pyobj = PyString_FromString(ptemp);\n"; + } + } + } + } + + getf.code << tab4 << "return pyobj;\n" + << "}\n"; + + getf.print(f_wrappers); + + // Now add this to the variable linking mechanism + + fprintf(f_init,"\t SWIG_addvarlink(SWIG_globals,\"%s\",%s_get, %s_set);\n", iname, wname, wname); + + + // Fill in the documentation entry + + if (doc_entry) { + doc_entry->usage << usage_var(iname, t); + doc_entry->cinfo << "Global : " << t->print_type() << " " << name; + } + + // ---------------------------------------------------------- + // Output a shadow variable. (If applicable and possible) + // ---------------------------------------------------------- + if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { + if ((hash.lookup(t->name)) && (t->is_pointer <= 1)) { + vars << iname << " = " << (char *) hash.lookup(t->name) << "Ptr(" << module << "." << global_name + << "." << iname << ")\n"; + } + } +} + +// ----------------------------------------------------------------------- +// PYTHON::declare_const(char *name, char *iname, DataType *type, char *value) +// +// Makes a constant as defined with #define. Constants are added to the +// module's dictionary and are **NOT** guaranteed to be read-only, +// sorry. +// +// ------------------------------------------------------------------------ + +void PYTHON::declare_const(char *name, char *, DataType *type, char *value) { + + char *tm; + + // Make a static python object + + if ((tm = typemap_lookup("const","python",type,name,value,name))) { + fprintf(f_init,"%s\n",tm); + } else { + + if ((type->type == T_USER) && (!type->is_pointer)) { + fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); + return; + } + + if (type->is_pointer == 0) { + switch(type->type) { + case T_INT:case T_SINT: case T_UINT: case T_BOOL: + case T_SHORT: case T_SSHORT: case T_USHORT: + case T_LONG: case T_SLONG: case T_ULONG: + case T_SCHAR: case T_UCHAR: + fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyInt_FromLong((long) %s));\n",name,value); + break; + case T_DOUBLE: + case T_FLOAT: + fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyFloat_FromDouble((double) %s));\n",name,value); + break; + case T_CHAR : + fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyString_FromString(\"%s\"));\n",name,value); + break; + default: + fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); + break; + } + } else { + if ((type->type == T_CHAR) && (type->is_pointer == 1)) { + fprintf(f_init,"\t PyDict_SetItemString(d,\"%s\", PyString_FromString(\"%s\"));\n",name,value); + } else { + // A funky user-defined type. We're going to munge it into a string pointer value + fprintf(f_init,"\t {\n"); + fprintf(f_init,"\t\t char %s_char[%d];\n", name, (int) strlen(type->print_mangle()) + 20); + fprintf(f_init,"\t\t SWIG_MakePtr(%s_char, (void *) (%s),\"%s\");\n", + name, value, type->print_mangle()); + fprintf(f_init,"\t\t PyDict_SetItemString(d,\"%s\", PyString_FromString(%s_char));\n",name,name); + fprintf(f_init,"\t }\n"); + } + } + } + if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { + vars << name << " = " << module << "." << name << "\n"; + } + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << usage_const(name,type,value); + doc_entry->cinfo = ""; + doc_entry->cinfo << "Constant: " << type->print_type(); + } +} + +// ---------------------------------------------------------------------- +// PYTHON::usage_var(char *iname, DataType *t) +// +// This function produces a string indicating how to use a variable. +// It is called by the documentation system to produce syntactically +// correct documentation entires. +// +// s is a pointer to a character pointer. You should create +// a string and set this pointer to point to it. +// ---------------------------------------------------------------------- + +char *PYTHON::usage_var(char *iname, DataType *) { + + static String temp; + + temp = ""; + temp << global_name << "." << iname; + + // Create result. Don't modify this + + return temp.get(); +} + +// --------------------------------------------------------------------------- +// PYTHON::usage_func(char *iname, DataType *t, ParmList *l) +// +// Produces a string indicating how to call a function in the target +// language. +// +// --------------------------------------------------------------------------- + +char *PYTHON::usage_func(char *iname, DataType *, ParmList *l) { + + static String temp; + Parm *p; + int i; + + temp = ""; + temp << iname << "("; + + // Now go through and print parameters + // You probably don't need to change this + + i = 0; + p = l->get_first(); + while (p != 0) { + if (!p->ignore) { + i++; + /* If parameter has been named, use that. Otherwise, just print a type */ + + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + if (strlen(p->name) > 0) { + temp << p->name; + } else { + temp << p->t->print_type(); + } + } + p = l->get_next(); + if (p != 0) { + if (!p->ignore) + temp << ","; + } + } else { + p = l->get_next(); + if (p) { + if ((!p->ignore) && (i > 0)) + temp << ","; + } + } + } + + temp << ")"; + + // Create result. Don't change this + + return temp.get(); + +} + + +// ---------------------------------------------------------------------- +// PYTHON::usage_const(char *iname, DataType *type, char *value) +// +// Produces a string for a constant. Really about the same as +// usage_var() except we'll indicate the value of the constant. +// ---------------------------------------------------------------------- + +char *PYTHON::usage_const(char *iname, DataType *, char *value) { + + static String temp; + temp = ""; + temp << iname << " = " << value; + + return temp.get(); +} + +// ----------------------------------------------------------------------- +// PYTHON::add_native(char *name, char *funcname) +// +// Add a native module name to the methods list. +// ----------------------------------------------------------------------- + +void PYTHON::add_native(char *name, char *funcname) { + add_method(name, funcname); + if (shadow) { + func << name << " = " << module << "." << name << "\n\n"; + } +} + +// ----------------------------------------------------------------------- +// PYTHON::cpp_class_decl(char *name, char *rename, char *type) +// +// Treatment of an empty class definition. Used to handle +// shadow classes across modules. +// ----------------------------------------------------------------------- + +void PYTHON::cpp_class_decl(char *name, char *rename, char *type) { + char temp[256]; + if (shadow) { + hash.add(name,copy_string(rename)); + // Add full name of datatype to the hash table + if (strlen(type) > 0) { + sprintf(temp,"%s %s", type, name); + hash.add(temp,copy_string(rename)); + } + } +} + +// ----------------------------------------------------------------------- +// PYTHON::pragma(char *name, char *type) +// +// Pragma directive. Used to do various python specific things +// ----------------------------------------------------------------------- + +void PYTHON::pragma(char *lang, char *cmd, char *value) { + + if (strcmp(lang,"python") == 0) { + if (strcmp(cmd,"CODE") == 0) { + if (shadow) { + fprintf(f_shadow,"%s\n",value); + } + } else if (strcmp(cmd,"code") == 0) { + if (shadow) { + fprintf(f_shadow,"%s\n",value); + } + } else if (strcmp(cmd,"include") == 0) { + if (shadow) { + if (value) { + if (get_file(value,pragma_include) == -1) { + fprintf(stderr,"%s : Line %d. Unable to locate file %s\n", input_file, line_number, value); + } + } + } + } else { + fprintf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number); + } + } +} + + +struct PyPragma { + PyPragma(char *method, char *text) : m_method(method), m_text(text), next(0) { } + ~PyPragma() { if (next) delete next; } + String m_method; + String m_text; + PyPragma *next; +}; + +static PyPragma *pragmas = 0; + +// ----------------------------------------------------------------------------- +// PYTHON::cpp_pragma(Pragma *plist) +// +// Handle C++ pragmas +// ----------------------------------------------------------------------------- + +void PYTHON::cpp_pragma(Pragma *plist) { + PyPragma *pyp1 = 0, *pyp2 = 0; + if (pragmas) { + delete pragmas; + pragmas = 0; + } + while (plist) { + if (strcmp(plist->lang,"python") == 0) { + if (strcmp(plist->name,"addtomethod") == 0) { + // parse value, expected to be in the form "methodName:line" + String temp = plist->value; + char* txtptr = strchr(temp.get(), ':'); + if (txtptr) { + // add name and line to a list in current_class + *txtptr = 0; + txtptr++; + pyp1 = new PyPragma(temp,txtptr); + if (pyp2) { + pyp2->next = pyp1; + pyp2 = pyp1; + } else { + pragmas = pyp1; + pyp2 = pragmas; + } + } else { + fprintf(stderr,"%s : Line %d. Malformed addtomethod pragma. Should be \"methodName:text\"\n", + plist->filename.get(),plist->lineno); + } + } else if (strcmp(plist->name, "addtoclass") == 0) { + pyp1 = new PyPragma("__class__",plist->value); + if (pyp2) { + pyp2->next = pyp1; + pyp2 = pyp1; + } else { + pragmas = pyp1; + pyp2 = pragmas; + } + } + } + plist = plist->next; + } +} + +// -------------------------------------------------------------------------------- +// PYTHON::emitAddPragmas(String& output, char* name, char* spacing); +// +// Search the current class pragma for any text belonging to name. +// Append the text properly spaced to the output string. +// -------------------------------------------------------------------------------- + +void PYTHON::emitAddPragmas(String& output, char* name, char* spacing) +{ + PyPragma *p = pragmas; + while (p) { + if (strcmp(p->m_method,name) == 0) { + output << spacing << p->m_text << "\n"; + } + p = p->next; + } +} diff --git a/wxPython/wxSWIG/Modules/python.h b/wxPython/wxSWIG/Modules/python.h new file mode 100644 index 0000000000..eb7da3011a --- /dev/null +++ b/wxPython/wxSWIG/Modules/python.h @@ -0,0 +1,111 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/************************************************************************** + * $Header$ + * + * python.h + * + * Header file for Python module. Warning ; this is work in progress. + **************************************************************************/ + +class PYTHON : public Language { +protected: + char *module; // Module name + char *path; // Pathname of where to look for library files + char *methods; // Method table name + char *global_name; // Name of global variables. + void get_pointer(char *iname, char *srcname, char *src, char *dest, DataType *t, String &f, char *ret); + int shadow; + int have_defarg; + int docstring; + int have_output; + int use_kw; + FILE *f_shadow; + struct Method { // Methods list. Needed to build methods + char *name; // Array at very end. + char *function; + Method *next; + }; + Method *head; + Hash hash; + String classes; + String func; + String vars; + String modinit; + String modextern; + + char *import_file; + void add_method(char *name, char *function); + void print_methods(); + char *usage_var(char *, DataType *); + char *usage_func(char *, DataType *, ParmList *); + char *usage_const(char *, DataType *, char *); + char *add_docstring(DocEntry *de); + + // Add for Python-COM support + virtual void initialize_cmodule(); + virtual void close_cmodule(); + virtual void emit_function_header(WrapperFunction &emit_to, char *wname); + virtual char *convert_self(WrapperFunction &f); + virtual char *make_funcname_wrapper(char *fnName); + void emitAddPragmas(String& output, char* name, char* spacing); +public : + PYTHON() { + module = (char *) 0; + path = "python"; // Set this to subdirectory where language + // Dependent library files will be stored + head = 0; // Head of method list + global_name = "cvar"; + shadow = 0; + have_defarg = 0; + import_file = 0; + use_kw = 0; + }; + + // Don't change any of this + void parse_args(int, char *argv[]); + void parse(); + void create_function(char *, char *, DataType *, ParmList *); + void link_variable(char *, char *, DataType *); + void declare_const(char *, char *, DataType *, char *); + void initialize(void); + void headers(void); + void close(void); + void set_module(char *, char **); + void set_init(char *); + void add_native(char *, char *); + void create_command(char *, char *); + void import(char *); + + // C++ extensions---for creating shadow classes + + void cpp_member_func(char *name, char *iname, DataType *t, ParmList *l); + void cpp_constructor(char *name, char *iname, ParmList *l); + void cpp_destructor(char *name, char *newname); + void cpp_open_class(char *classname, char *rname, char *ctype, int strip); + void cpp_close_class(); + void cpp_cleanup(); + void cpp_inherit(char **baseclass, int mode = INHERIT_ALL); + void cpp_variable(char *name, char *iname, DataType *t); + void cpp_declare_const(char *name, char *iname, DataType *type, char *value); + void cpp_class_decl(char *, char *,char *); + void pragma(char *, char *, char *); + void cpp_pragma(Pragma *); + void add_typedef(DataType *t, char *name); +}; + +#define PYSHADOW_MEMBER 0x2 + diff --git a/wxPython/wxSWIG/Modules/swigmain.cxx b/wxPython/wxSWIG/Modules/swigmain.cxx new file mode 100644 index 0000000000..427cd02ea1 --- /dev/null +++ b/wxPython/wxSWIG/Modules/swigmain.cxx @@ -0,0 +1,168 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/*********************************************************************** + * $Header$ + * + * swigmain.cxx + * + * The main program. + * + ***********************************************************************/ + +#include "wrap.h" +#include "swigtcl.h" +#include "tcl8.h" +#include "perl5.h" +#include "python.h" +// #include "pythoncom.h" +#include "guile.h" +#include "debug.h" +#include "ascii.h" +#include "latex.h" +#include "html.h" +#include "nodoc.h" +#include + +static char *usage = "\ +swig filename\n\n\ +Target Language Options:\n\ + -tcl - Generate Tcl wrappers.\n\ + -tcl8 - Generate Tcl 8.0 wrappers.\n\ + -python - Generate Python wrappers.\n\ + -perl5 - Generate Perl5 wrappers.\n\ + -guile - Generate Guile wrappers.\n\ + -debug - Parser debugging module.\n"; + +#ifdef MACSWIG +static char *macmessage = "\ +Copyright (c) 1995-1997\n\ +University of Utah and the Regents of the University of California\n\n\ +Enter SWIG processing options and filename below. For example :\n\ +\n\ + -tcl -c++ interface.i\n\ +\n\ +-help displays a list of all available options.\n\ +\n\ +Note : Macintosh filenames should be enclosed in quotes if they contain whitespace.\n\ +\n"; + +#endif + +//----------------------------------------------------------------- +// main() +// +// Main program. Initializes the files and starts the parser. +//----------------------------------------------------------------- + +#ifndef MACSWIG +int main(int argc, char **argv) { +#else +int Mac_main(int argc, char **argv) { +#endif + + int i; + + Language *dl = new SWIG_LANG; + Documentation *dd = new SWIG_DOC; + extern int SWIG_main(int, char **, Language *, Documentation *); + + init_args(argc,argv); + + // Get options + for (i = 1; i < argc; i++) { + if (argv[i]) { + if(strcmp(argv[i],"-tcl") == 0) { + dl = new TCL; + mark_arg(i); + } else if (strcmp(argv[i],"-tcl8") == 0) { + dl = new TCL8; + mark_arg(i); + } else if (strcmp(argv[i],"-perl5") == 0) { + dl = new PERL5; + mark_arg(i); + } else if (strcmp(argv[i],"-python") == 0) { + dl = new PYTHON; + mark_arg(i); + } else if (strcmp(argv[i],"-debug") == 0) { + dl = new DEBUGLANG; + mark_arg(i); + } else if (strcmp(argv[i],"-guile") == 0) { + dl = new GUILE; + mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + mark_arg(i); + } + } + } + SWIG_main(argc,argv,dl,dd); + return 0; +} + +#ifdef MACSWIG +int MacMainEntry(char *options) { + static char *_argv[256]; + int i,argc; + char *c,*s,*t; + + swig_log = fopen("swig_log","w"); + fprintf(swig_log,"SWIG 1.1\n"); + fprintf(swig_log,"Options : %s\n", options); + fprintf(swig_log,"-----------------------------------------------------\n"); + + // Tokenize the user input + + _argv[0] = "swig"; + i=1; + c = options; + while (*c) { + while(isspace(*c)) c++; + if (*c) { + s = c; // Starting character + while(isgraph(*c)) { + if (*c == '\"') { + c++; + while ((*c) && (*c != '\"')) + c++; + c++; + } else { + c++; + } + } + // Found some whitespace + if (*c) { + *c = 0; + c++; + } + _argv[i] = copy_string(s); + // Go through and remove quotes (if necessary) + + t = _argv[i]; + while(*s) { + if (*s != '\"') + *(t++) = *s; + s++; + } + *t = 0; + i++; + } + } + argc = i; + _argv[i] = 0; + return Mac_main(argc,_argv); +} + +#endif diff --git a/wxPython/wxSWIG/Modules/swigtcl.h b/wxPython/wxSWIG/Modules/swigtcl.h new file mode 100644 index 0000000000..7403e3ffdd --- /dev/null +++ b/wxPython/wxSWIG/Modules/swigtcl.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/************************************************************************** + * class TCL + * + * A Simple TCL implementation. + **************************************************************************/ + +class TCL : public Language { +private: + char interp_name[256]; + char *prefix; // Package prefix + char *module; // Name of the module + char *tcl_path; + char *init_name; + int Plugin; + int nspace; + char *safe_name; + void get_pointer(char *iname, char *srcname, char *src, char *dest, DataType *t, + String &f, char *ret); + char *char_result; + char *usage_string(char *, DataType *, ParmList *); + char *usage_func(char *, DataType *, ParmList *); + char *usage_var(char *, DataType *); + char *usage_const(char *, DataType *, char *); + + // C++ handling + + int have_constructor; + int have_destructor; + int have_methods; + int have_config; + int have_cget; + String config; + String cget; + String methods; + String options; + String config_options; + String methodnames; + String postinit; + int shadow; + char *class_name; + char *class_type; + char *real_classname; + char *base_class; + Hash hash; + Hash repeatcmd; + + // C++ Code generation strings + + String delcmd; + String methodcmd; + String objcmd; + +public : + TCL() { + prefix = 0; + module = 0; + init_name = 0; + nspace = 0; + shadow = 1; + char_result = "TCL_VOLATILE"; + tcl_path = "tcl"; + sprintf(interp_name,"interp"); + class_name = 0; + class_type = 0; + real_classname = 0; + base_class = 0; + }; + void parse_args(int, char *argv[]); + void parse(); + void create_function(char *, char *, DataType *, ParmList *); + void link_variable(char *, char *, DataType *); + void declare_const(char *, char *, DataType *, char *); + void initialize(void); + void headers(void); + void close(void); + void set_module(char *,char **); + void set_init(char *); + void add_native(char *, char *); + void pragma(char *,char *, char *); + void create_command(char *, char *); + + // Stubs for processing C++ classes in Tcl + + void cpp_open_class(char *classname, char *rename, char *ctype, int strip); + void cpp_close_class(); + void cpp_member_func(char *name, char *iname, DataType *t, ParmList *l); + void cpp_variable(char *name, char *iname, DataType *t); + void cpp_constructor(char *name, char *iname, ParmList *l); + void cpp_destructor(char *name, char *newname); + void cpp_inherit(char **baseclass, int mode = INHERIT_ALL); + void cpp_declare_const(char *name, char *iname, DataType *type, char *value); + void cpp_class_decl(char *, char *, char *); + void add_typedef(DataType *, char *); +}; + + + + + + diff --git a/wxPython/wxSWIG/Modules/tcl.cxx b/wxPython/wxSWIG/Modules/tcl.cxx new file mode 100644 index 0000000000..14920490cb --- /dev/null +++ b/wxPython/wxSWIG/Modules/tcl.cxx @@ -0,0 +1,1472 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/*********************************************************************** + * $Header$ + * + * tcl.cxx + * + * Definitions for creating a simple, stand-alone TCL implementation. + * + ***********************************************************************/ + +#include "swig.h" +#include "swigtcl.h" +#include + +static char *Tcl_config="swigtcl.swg"; +static char *usage = "\ +Tcl Options (available with -tcl)\n\ + -module name - Set name of module\n\ + -prefix name - Set a prefix to be appended to all names\n\ + -namespace - Build module into a Tcl8 namespace. \n\ + -noobject - Omit code for object oriented interface.\n\ + -old - Use old SWIG interface (same as -noobject).\n\n"; + + +static char *ns_name = 0; +static String mod_init; +static String mod_extern; + +// --------------------------------------------------------------------- +// TCL::parse_args(int argc, char *argv[]) +// +// Parse tcl specific command line options +// --------------------------------------------------------------------- + +void TCL::parse_args(int argc, char *argv[]) { + + int i = 1; + sprintf(LibDir,"%s",tcl_path); + + // Look for certain command line options + + for (i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i],"-prefix") == 0) { + if (argv[i+1]) { + prefix = new char[strlen(argv[i+1])+2]; + strcpy(prefix, argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-module") == 0) { + if (argv[i+1]) { + set_module(argv[i+1],0); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-namespace") == 0) { + nspace = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-old") == 0) { + shadow = 0; + mark_arg(i); + } else if (strcmp(argv[i],"-noobject") == 0) { + shadow = 0; + mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + } + } + } + + // If a package has been specified, make sure it ends with a '_' + + if (prefix) { + ns_name = copy_string(prefix); + if (prefix[strlen(prefix)] != '_') { + prefix[strlen(prefix)+1] = 0; + prefix[strlen(prefix)] = '_'; + } + } else + prefix = ""; + + // Create a symbol SWIGTCL + + add_symbol("SWIGTCL",0,0); + typemap_lang = "tcl"; + + // Attempt to load up the C++ configuration files + + get_file("delcmd.swg",delcmd); + get_file("methodcmd.swg",methodcmd); + get_file("objcmd.swg",objcmd); + +} + +// --------------------------------------------------------------------- +// void TCL::parse() +// +// Start parsing an interface file for Tcl. +// --------------------------------------------------------------------- + +void TCL::parse() { + + fprintf(stderr,"Making wrappers for Tcl\n"); + + // Print out TCL specific headers + + headers(); + + // Run the parser + + yyparse(); + +} + +// --------------------------------------------------------------------- +// TCL::set_module(char *mod_name,char **mod_list) +// +// Sets the module name. +// Does nothing if it's already set (so it can be overridden as a command +// line option). +// +// mod_list is a NULL-terminated list of additional modules. This +// is really only useful when building static executables and other +// things. +//---------------------------------------------------------------------- + +void TCL::set_module(char *mod_name, char **mod_list) { + + char temp[256], *c; + int i; + + if (module) return; + + module = new char[strlen(mod_name)+1]; + strcpy(module,mod_name); + + // Fix capitalization for Tcl + + c = module; + while (*c) { + *c = (char) tolower(*c); + c++; + } + + // Now create an initialization function + + sprintf(temp,"%s_Init", module); + init_name = new char[strlen(temp) + 1]; + strcpy(init_name, temp); + *init_name = toupper(*init_name); + + if (!ns_name) ns_name = copy_string(module); + + // If namespaces have been specified, set the prefix to the module name + + if ((nspace) && (strlen(prefix) < 1)) { + prefix = new char[strlen(module)+2]; + strcpy(prefix,module); + prefix[strlen(module)] = '_'; + prefix[strlen(module)+1] = 0; + } + + // If additional modules have been specified, create some code for + // initializing them. + + if (mod_list) { + i = 0; + while (mod_list[i]) { + c = mod_list[i]; + while (*c) { + *c = (char) tolower(*c); + c++; + } + sprintf(temp,"%s_Init",mod_list[i]); + temp[0] = toupper(temp[0]); + + // Dump out some initialization code + + mod_init << tab4 << "if (" << temp << "(" << interp_name << ") == TCL_ERROR) {\n" + << tab8 << "return TCL_ERROR;\n" + << tab4 << "}\n\n"; + mod_extern << "extern int " << temp << "(Tcl_Interp *);\n"; + i++; + } + } +} + + +// --------------------------------------------------------------------- +// TCL::set_init(char *iname) +// +// Sets the initialization function name. +// Does nothing if it's already set +// +//---------------------------------------------------------------------- + +void TCL::set_init(char *iname) { + + if (init_name) return; + + init_name = new char[strlen(iname)+1]; + strcpy(init_name, iname); + +} + +// --------------------------------------------------------------------- +// TCL::headers(void) +// +// Generate the appropriate header files for TCL interface. +// ---------------------------------------------------------------------- + +void TCL::headers(void) +{ + + emit_banner(f_header); + fprintf(f_header,"/* Implementation : TCL 7.x */\n\n"); + fprintf(f_header,"#include \n"); + fprintf(f_header,"#include \n"); + fprintf(f_header,"#include \n"); + fprintf(f_header,"#define SWIGTCL\n"); + + if (NoInclude) { + fprintf(f_header,"#define SWIG_NOINCLUDE\n"); + } + + if (insert_file("swigtcl.swg", f_header) == -1) { + fprintf(stderr,"Unable to find 'swigtcl.swg'. Possible installation problem.\n"); + SWIG_exit(1); + } +} + +// -------------------------------------------------------------------- +// TCL::initialize(void) +// +// Produces an initialization function. Assumes that the init function +// name has already been specified. +// --------------------------------------------------------------------- + +void TCL::initialize() +{ + + if ((!ns_name) && (nspace)) { + fprintf(stderr,"Tcl error. Must specify a namespace.\n"); + SWIG_exit(1); + } + + if (!init_name) { + init_name = "Swig_Init"; + fprintf(stderr,"SWIG : *** Warning. No module name specified.\n"); + } + + fprintf(f_header,"#define SWIG_init %s\n", init_name); + if (!module) module = "swig"; + fprintf(f_header,"#define SWIG_name \"%s\"\n", module); + if (nspace) { + fprintf(f_header,"#define SWIG_prefix \"%s::\"\n", ns_name); + fprintf(f_header,"#define SWIG_namespace \"%s\"\n\n", ns_name); + } else { + fprintf(f_header,"#define SWIG_prefix \"%s\"\n", prefix); + fprintf(f_header,"#define SWIG_namespace \"\"\n\n"); + } + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"extern \"C\" {\n"); + fprintf(f_header,"#endif\n"); + fprintf(f_header,"#ifdef MAC_TCL\n"); + fprintf(f_header,"#pragma export on\n"); + fprintf(f_header,"#endif\n"); + fprintf(f_header,"SWIGEXPORT(int) %s(Tcl_Interp *);\n", init_name); + fprintf(f_header,"#ifdef MAC_TCL\n"); + fprintf(f_header,"#pragma export off\n"); + fprintf(f_header,"#endif\n"); + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"}\n"); + fprintf(f_header,"#endif\n"); + + fprintf(f_init,"SWIGEXPORT(int) %s(Tcl_Interp *%s) {\n", init_name, interp_name); + + fprintf(f_init,"\t if (%s == 0) \n", interp_name); + fprintf(f_init,"\t\t return TCL_ERROR;\n"); + + /* Check to see if other initializations need to be performed */ + + if (strlen(mod_extern.get())) { + fprintf(f_init,"%s\n",mod_init.get()); + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"extern \"C\" {\n"); + fprintf(f_header,"#endif\n"); + fprintf(f_header,"%s\n",mod_extern.get()); + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"}\n"); + fprintf(f_header,"#endif\n"); + } + + /* Check to see if we're adding support for Tcl8 nspaces */ + if (nspace) { + fprintf(f_init,"#if (TCL_MAJOR_VERSION >= 8)\n"); + fprintf(f_init,"\t Tcl_Eval(%s,\"namespace eval %s { }\");\n", interp_name, ns_name); + fprintf(f_init,"#endif\n"); + } +} + +// --------------------------------------------------------------------- +// TCL::close(void) +// +// Wrap things up. Close initialization function. +// --------------------------------------------------------------------- + +void TCL::close(void) +{ + + // Dump the pointer equivalency table + + emit_ptr_equivalence(f_init); + + // Close the init file and quit + fprintf(f_init,"%s",postinit.get()); + fprintf(f_init,"\t return TCL_OK;\n"); + fprintf(f_init,"}\n"); +} + +// ---------------------------------------------------------------------- +// TCL::get_pointer(char *iname, char *srcname, char *src, char *dest, +// DataType *t, String &f, char *ret) +// +// iname = name of function or variable +// srcname = name of source +// src = source variable in wrapper code +// dest = destination variable in wrapper code +// t = Datatype +// f = String where output is going to go +// ret = Return action +// ---------------------------------------------------------------------- + +void TCL::get_pointer(char *iname, char *srcname, char *src, char *dest, + DataType *t, String &f, char *ret) { + + // Pointers are read as hex-strings with encoded type information + + f << tab4 << "if (SWIG_GetPtr(" << src << ",(void **) &" << dest << ","; + + if (t->type == T_VOID) f << "(char *) 0)) {\n"; + else + f << "\"" << t->print_mangle() << "\")) {\n"; + + // Now emit code according to the level of strictness desired + + switch(TypeStrict) { + case 0: // No type checking + f << tab4 << "}\n"; + break; + case 1: // Warning message only + f << tab8 << "fprintf(stderr,\"Warning : type mismatch in " << srcname + << " of " << iname << ". Expected " << t->print_mangle() + << ", received %s\\n\"," << src << ");\n" + << tab4 << "}\n"; + case 2: // Super strict mode. + f << tab8 << "Tcl_SetResult(interp, \"Type error in " << srcname << " of " << iname + << ". Expected " << t->print_mangle() << ", received \", TCL_STATIC);\n" + << tab8 << "Tcl_AppendResult(interp, " << src << ", (char *) NULL);\n" + << tab8 << ret << ";\n" + << tab4 << "}\n"; + break; + default : + fprintf(stderr,"Unknown strictness level\n"); + break; + } +} + +// ---------------------------------------------------------------------- +// TCL::create_command(char *cname, char *iname) +// +// Creates a Tcl command from a C function. +// ---------------------------------------------------------------------- + +void TCL::create_command(char *cname, char *iname) { + + + char *wname = name_wrapper(cname,prefix); + + fprintf(f_init,"\t Tcl_CreateCommand(%s,SWIG_prefix \"%s\",%s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n", interp_name, iname, wname); + + // Add interpreter name to repeatcmd hash table. This hash is used in C++ code + // generation to try and find repeated wrapper functions. + + repeatcmd.add(iname,copy_string(wname)); +} + +// ---------------------------------------------------------------------- +// TCL::create_function(char *name, char *iname, DataType *d, ParmList *l) +// +// Create a function declaration and register it with the interpreter. +// ---------------------------------------------------------------------- + +void TCL::create_function(char *name, char *iname, DataType *d, ParmList *l) +{ + Parm *p; + int pcount,i,j; + char *wname; + char *usage = 0; + char source[256], target[256], argnum[32], *tm; + String cleanup, outarg; + int numopt; + int have_build = 0; // Status indicating build typemap + String build; + + WrapperFunction f; + + // Make a wrapper name for this function + + wname = name_wrapper(iname,prefix); + + // Now write the wrapper function itself....this is pretty ugly + + f.def << "static int " << wname << "(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {\n"; + f.code << tab4 << "clientData = clientData; argv = argv;\n"; + + // Print out variables for storing arguments. + + pcount = emit_args(d, l, f); + + // Get number of optional arguments + + numopt = l->numopt(); + + // Check the number of arguments + + usage = usage_func(iname,d,l); // Create a usage string + f.code << tab4 << "if ((argc < " << (pcount-numopt) +1 << ") || (argc > " << l->numarg()+1 << ")) {\n" + << tab8 << "Tcl_SetResult(interp, \"Wrong # args. " << usage << "\",TCL_STATIC);\n" + << tab8 << "return TCL_ERROR;\n" + << tab4 << "}\n"; + + // Extract parameters. This case statement should be used to extract + // Function parameters. Add more cases if you want to do more. + + i = 0; + j = 0; + p = l->get_first(); + while (p != 0) { + // Produce string representations of the source and target arguments + sprintf(source,"argv[%d]",j+1); + sprintf(target,"_arg%d",i); + sprintf(argnum,"%d",j+1); + + // See if this argument is being ignored + + if (!p->ignore) { + if (j >= (pcount-numopt)) + f.code << tab4 << "if (argc >" << j+1 << ") { \n"; + + // See if there is a type-mapping + + if ((tm = typemap_lookup("in","tcl",p->t,p->name,source,target,&f))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + f.code.replace("$argnum",argnum); + f.code.replace("$arg",source); + } else { + + if (!p->t->is_pointer) { + + // Extract a parameter by value. + + switch(p->t->type) { + + // Signed Integers + + case T_BOOL: + case T_INT: + case T_SINT: + case T_SHORT: + case T_SSHORT: + case T_LONG: + case T_SLONG: + case T_SCHAR: + f.code << tab4 << "_arg" << i << " = " << p->t->print_cast() << " atol(argv[" << j+1 << "]);\n"; + break; + + // Unsigned Integers + + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + f.code << tab4 << "_arg" << i << " = " << p->t->print_cast() << " strtoul(argv[" << j+1 + << "],(char **) NULL,0);\n"; + break; + + // Floating point + + case T_FLOAT: + case T_DOUBLE: + f.code << tab4 << "_arg" << i << " = " << p->t->print_cast() << " atof(argv[" << j+1 << "]);\n"; + break; + + // A single character + + case T_CHAR : + f.code << tab4 << "_arg" << i << " = *argv[" << j+1 << "];\n"; + break; + + // Void.. Do nothing. + + case T_VOID : + break; + + // User defined. This is an error. + + case T_USER: + + // Unsupported data type + + default : + fprintf(stderr,"%s : Line %d: Unable to use type %s as a function argument.\n", + input_file, line_number, p->t->print_type()); + break; + } + } else { /* Pointer type */ + + // Function argument is some sort of pointer + // Look for a string. Otherwise, just pull off a pointer. + + if ((p->t->type == T_CHAR) && (p->t->is_pointer == 1)) { + f.code << tab4 << "_arg" << i << " = argv[" << j+1 << "];\n"; + } else { + + // Have a generic pointer type here. Read it in as + // a hex-string + + char arg_temp[256]; + sprintf(arg_temp,"argument %d",j+1); + get_pointer(iname,arg_temp,source,target,p->t,f.code,"return TCL_ERROR"); + } + } + } + if (j >= (pcount-numopt)) + f.code << tab4 << "} \n"; + j++; + } + + // Check to see if there is any sort of "build" typemap (highly complicated) + + if ((tm = typemap_lookup("build","tcl",p->t,p->name,source,target))) { + build << tm << "\n"; + have_build = 1; + } + + // Check to see if there was any sort of a constaint typemap + if ((tm = typemap_lookup("check","tcl",p->t,p->name,source,target))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + f.code.replace("$argnum",argnum); + f.code.replace("$arg",source); + } + + // Check if there was any cleanup code (save it for later) + if ((tm = typemap_lookup("freearg","tcl",p->t,p->name,target,"interp->result"))) { + // Yep. Use it instead of the default + cleanup << tm << "\n"; + cleanup.replace("$argnum",argnum); + cleanup.replace("$arg",source); + } + if ((tm = typemap_lookup("argout","tcl",p->t,p->name,target,"interp->result"))) { + // Yep. Use it instead of the default + outarg << tm << "\n"; + outarg.replace("$argnum",argnum); + outarg.replace("$arg",source); + } + p = l->get_next(); // Get next parameter and continue + i++; + } + + // If there was a "build" typemap, we need to go in and perform a serious hack + + if (have_build) { + char temp1[32]; + char temp2[256]; + l->sub_parmnames(build); // Replace all parameter names + j = 1; + for (i = 0; i < l->nparms; i++) { + p = l->get(i); + if (strlen(p->name) > 0) { + sprintf(temp1,"_in_%s", p->name); + } else { + sprintf(temp1,"_in_arg%d", i); + } + sprintf(temp2,"argv[%d]",j); + build.replaceid(temp1,temp2); + if (!p->ignore) + j++; + } + f.code << build; + } + + // Now write code to make the function call + + emit_func_call(name,d,l,f); + + // Return value if necessary + + if ((tm = typemap_lookup("out","tcl",d,name,"_result","interp->result"))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + } else if ((d->type != T_VOID) || (d->is_pointer)) { + // Normal SWIG mappings + + if (!d->is_pointer) { + + // Function returns a "value" + + switch(d->type) { + // Is a signed integer + case T_BOOL: + case T_INT: + case T_SINT: + case T_SHORT: + case T_SSHORT: + case T_LONG : + case T_SLONG: + case T_SCHAR: + f.code << tab4 << "sprintf(interp->result,\"%ld\", (long) _result);\n"; + break; + + // Is an unsigned integer + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + f.code << tab4 << "sprintf(interp->result,\"%lu\", (unsigned long) _result);\n"; + break; + + // Is a single character. Assume we return it as a string + case T_CHAR : + f.code << tab4 << "sprintf(interp->result,\"%c\", _result);\n"; + break; + + // Floating point number + case T_DOUBLE : + case T_FLOAT : + f.code << tab4 << "Tcl_PrintDouble(interp,(double) _result, interp->result);\n"; + //sprintf(interp->result,\"%0.17f\",(double) _result);\n"; + break; + + // User defined type + case T_USER : + + // Okay. We're returning malloced memory at this point. + // Probably dangerous, but what the hell + + d->is_pointer++; + f.code << tab4 << "SWIG_MakePtr(interp->result, (void *) _result,\"" << d->print_mangle() + << "\");\n"; + d->is_pointer--; + break; + + // Unknown type + default : + fprintf(stderr,"%s : Line %d: Unable to use return type %s in function %s.\n", + input_file, line_number, d->print_type(), name); + break; + } + } else { + + // Is a pointer return type + + if ((d->type == T_CHAR) && (d->is_pointer == 1)) { + // Return a character string + f.code << tab4 << "Tcl_SetResult(interp, (char *) _result, " << char_result << ");\n"; + } else { + f.code << tab4 << "SWIG_MakePtr(interp->result, (void *) _result,\"" << d->print_mangle() << "\");\n"; + } + } + } + + // Dump argument output code; + f.code << outarg; + + // Dump the argument cleanup code + f.code << cleanup; + + // Look for any remaining cleanup + + if (NewObject) { + if ((tm = typemap_lookup("newfree","tcl",d,iname,"_result",""))) { + f.code << tm << "\n"; + } + } + + if ((tm = typemap_lookup("ret","tcl",d,name,"_result",""))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + } + + // Wrap things up (in a manner of speaking) + + f.code << tab4 << "return TCL_OK;\n}"; + + // Substitute the cleanup code + f.code.replace("$cleanup",cleanup); + f.code.replace("$name",iname); + + // Dump out the function + + f.print(f_wrappers); + + // Add interpreter name to repeatcmd hash table. This hash is used in C++ code + // generation to try and find repeated wrapper functions. + + fprintf(f_init,"\t Tcl_CreateCommand(%s, SWIG_prefix \"%s\", %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n", interp_name, iname, wname); + + // If there's a documentation entry, produce a usage string + + if (doc_entry) { + + static DocEntry *last_doc_entry = 0; + + // Use usage as description + doc_entry->usage << usage; + + // Set the cinfo field to specific a return type + + if (last_doc_entry != doc_entry) { + doc_entry->cinfo << "returns " << d->print_type(); + last_doc_entry = doc_entry; + } + } +} + +// ----------------------------------------------------------------------- +// TCL::link_variable(char *name, char *iname, DataType *t, +// int ex) +// +// Create a TCL link to a variable. +// ----------------------------------------------------------------------- + +void TCL::link_variable(char *name, char *iname, DataType *t) +{ + + String s; + char *tm,*tm1; + String realname; + + + // See if there were any typemaps + + tm = typemap_lookup("varin","tcl",t,name,"",""); + tm1 = typemap_lookup("varout","tcl",t,name,"",""); + if (tm || tm1) { + fprintf(stderr,"%s : Line %d. Warning. varin/varout typemap methods not supported.", + input_file, line_number); + } + + // Check the datatype. Must be a valid Tcl type (there aren't many) + + if (((t->type == T_INT) && (!t->is_pointer)) || + ((t->type == T_UINT) && (!t->is_pointer)) || + ((t->type == T_SINT) && (!t->is_pointer)) || + ((t->type == T_DOUBLE) && (!t->is_pointer)) || + ((t->type == T_BOOL) && (!t->is_pointer)) || + ((t->type == T_CHAR) && (t->is_pointer == 1))) { + + // This is a valid TCL type. + + if (t->type == T_UINT) + fprintf(stderr,"%s : Line %d : ** Warning. Linkage of unsigned type may be unsafe.\n", + input_file, line_number); + + // Now add symbol to the TCL interpreter + + switch(t->type) { + case T_CHAR : + if (t->arraystr) { + // Is an array. We have to do something different + fprintf(f_wrappers,"static char *tclvar%s = %s;\n",name,name); + s << "(char *) &tclvar" << name << ", TCL_LINK_STRING"; + } else { + s << "(char *) &" << name << ", TCL_LINK_STRING"; + } + break; + case T_BOOL: + case T_INT : + case T_UINT: + case T_SINT: + s << "(char *) &" << name << ", TCL_LINK_INT"; + break; + case T_DOUBLE : + s << "(char *) &" << name << ", TCL_LINK_DOUBLE"; + break; + default : + fprintf(f_init,"Fatal error. Internal error (Tcl:link_variable)\n"); + break; + } + + if (Status & STAT_READONLY) + s << " | TCL_LINK_READ_ONLY);\n"; + else + s << ");\n"; + + fprintf(f_init,"\t Tcl_LinkVar(%s, SWIG_prefix \"%s\", %s",interp_name, iname, s.get()); + + // Make a usage string for it + + if (doc_entry) { + doc_entry->usage << usage_var(iname,t); + doc_entry->cinfo = ""; + doc_entry->cinfo << "Global : " << t->print_type() << " " << name; + } + } else { + + // Have some sort of "other" type. + // We're going to emit some functions to set/get it's value instead + + emit_set_get(name,iname, t); + if (doc_entry) { + doc_entry->cinfo = ""; + doc_entry->cinfo << "Global : " << t->print_type() << " " << iname; + } + + // If shadow classes are enabled and we have a user-defined type + // that we know about, create a command for it. + + if (shadow) { + if ((t->type == T_USER) && (t->is_pointer < 1)) { + // See if the datatype is in our hash table + if (hash.lookup(t->name)) { + // Yep. Try to create a command for it + // postinit << tab4 << "Tcl_CreateCommand(interp, SWIG_prefix \"" << iname << "\",Tcl" << (char *) hash.lookup(t->name) + // << "MethodCmd, (ClientData)"; + + postinit << tab4 << "{\n" + << tab8 << "char cmd[] = \"" + << (char *) hash.lookup(t->name) << " " << iname << " -this [" + << iname << "_get ]\";\n" + << tab8 << "Tcl_GlobalEval(interp,cmd);\n" + << tab4 << "}\n"; + + // postinit << tab4 << "Tcl_GlobalEval(interp,\"set " << iname << " [" << iname << "_get ];" + // << (char *) hash.lookup(t->name) << " -this $" << iname << "\");\n"; + + } + } + } + } +} + +// ----------------------------------------------------------------------- +// TCL::declare_const(char *name, char *iname, DataType *type, char *value) +// +// Makes a constant. Really just creates a variable and links to it. +// Tcl variable linkage allows read-only variables so we'll use that +// instead of just creating a Tcl variable. +// ------------------------------------------------------------------------ + +void TCL::declare_const(char *name, char *, DataType *type, char *value) { + + int OldStatus = Status; // Save old status flags + DataType *t; + char var_name[256]; + char *tm; + String rvalue; + + Status = STAT_READONLY; // Enable readonly mode. + + // Make a static variable; + + sprintf(var_name,"_wrap_const_%s",name); + + // See if there's a typemap + + rvalue = value; + if ((type->type == T_CHAR) && (type->is_pointer == 1)) { + rvalue << "\""; + "\"" >> rvalue; + } + if ((type->type == T_CHAR) && (type->is_pointer == 0)) { + rvalue << "'"; + "'" >> rvalue; + } + if ((tm = typemap_lookup("const","tcl",type,name,rvalue.get(),name))) { + // Yep. Use it instead of the default + fprintf(f_init,"%s\n",tm); + } else { + + // Create variable and assign it a value + + if (type->is_pointer == 0) { + switch(type->type) { + case T_BOOL: case T_INT: case T_SINT: case T_DOUBLE: + fprintf(f_header,"static %s %s = %s;\n", type->print_type(), var_name, value); + link_variable(var_name,name,type); + break; + case T_SHORT: + case T_LONG: + case T_SSHORT: + case T_SCHAR: + case T_SLONG: + fprintf(f_header,"static %s %s = %s;\n", type->print_type(), var_name, value); + fprintf(f_header,"static char *%s_char;\n", var_name); + if (CPlusPlus) + fprintf(f_init,"\t %s_char = new char[32];\n",var_name); + else + fprintf(f_init,"\t %s_char = (char *) malloc(32);\n",var_name); + + fprintf(f_init,"\t sprintf(%s_char,\"%%ld\", (long) %s);\n", var_name, var_name); + sprintf(var_name,"%s_char",var_name); + t = new DataType(T_CHAR); + t->is_pointer = 1; + link_variable(var_name,name,t); + delete t; + break; + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + fprintf(f_header,"static %s %s = %s;\n", type->print_type(), var_name, value); + fprintf(f_header,"static char *%s_char;\n", var_name); + if (CPlusPlus) + fprintf(f_init,"\t %s_char = new char[32];\n",var_name); + else + fprintf(f_init,"\t %s_char = (char *) malloc(32);\n",var_name); + + fprintf(f_init,"\t sprintf(%s_char,\"%%lu\", (unsigned long) %s);\n", var_name, var_name); + sprintf(var_name,"%s_char",var_name); + t = new DataType(T_CHAR); + t->is_pointer = 1; + link_variable(var_name,name,t); + delete t; + break; + case T_FLOAT: + type->type = T_DOUBLE; + strcpy(type->name,"double"); + fprintf(f_header,"static %s %s = %s (%s);\n", type->print_type(), var_name, type->print_cast(), value); + link_variable(var_name,name,type); + break; + + case T_CHAR: + type->is_pointer++; + fprintf(f_header,"static %s %s = \"%s\";\n", type->print_type(), var_name, value); + link_variable(var_name,name,type); + type->is_pointer--; + break; + default: + fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); + break; + } + } else { + // Have some sort of pointer value here + if ((type->type == T_CHAR) && (type->is_pointer == 1)) { + // Character string + fprintf(f_header,"static %s %s = \"%s\";\n", type->print_type(), var_name, value); + link_variable(var_name,name,type); + } else { + // Something else. Some sort of pointer value + fprintf(f_header,"static %s %s = %s;\n", type->print_type(), var_name, value); + fprintf(f_header,"static char *%s_char;\n", var_name); + if (CPlusPlus) + fprintf(f_init,"\t %s_char = new char[%d];\n",var_name,(int) strlen(type->print_mangle())+ 20); + else + fprintf(f_init,"\t %s_char = (char *) malloc(%d);\n",var_name,(int) strlen(type->print_mangle())+ 20); + + t = new DataType(T_CHAR); + t->is_pointer = 1; + fprintf(f_init,"\t SWIG_MakePtr(%s_char, (void *) %s,\"%s\");\n", + var_name, var_name, type->print_mangle()); + sprintf(var_name,"%s_char",var_name); + link_variable(var_name,name,t); + delete t; + } + } + } + + // Create a documentation entry for this + + if (doc_entry) { + doc_entry->usage = ""; // Destroy any previous information from linking + doc_entry->usage << usage_const(name, type, value); + doc_entry->cinfo = ""; + doc_entry->cinfo << "Constant : " << type->print_type(); + } + Status = OldStatus; +} + +// ---------------------------------------------------------------------- +// TCL::usage_var(char *iname, DataType *t, char **s) +// +// Produces a usage string for a tcl variable. Stores it in s +// ---------------------------------------------------------------------- + +char *TCL::usage_var(char *iname, DataType *t) { + + static String temp; + + temp = ""; + if (!nspace) { + temp << "$" << prefix << iname; + } else { + temp << ns_name << "::" << iname; + } + if (!(((t->type == T_INT) && (!t->is_pointer)) || + ((t->type == T_UINT) && (!t->is_pointer)) || + ((t->type == T_DOUBLE) && (!t->is_pointer)) || + ((t->type == T_BOOL) && (!t->is_pointer)) || + ((t->type == T_CHAR) && (t->is_pointer)))) { + /* We emitted a pair of set/get functions instead. Doc will be generated for that */ + return temp; + } + return temp; +} + + +// --------------------------------------------------------------------------- +// char *TCL::usage_string(char *iname, DataType *t, ParmList *l), +// +// Generates a generic usage string for a Tcl function. +// --------------------------------------------------------------------------- + +char * TCL::usage_string(char *iname, DataType *, ParmList *l) { + + static String temp; + Parm *p; + int i, numopt,pcount; + + temp = ""; + temp << iname << " "; + + /* Now go through and print parameters */ + i = 0; + pcount = l->nparms; + numopt = l->numopt(); + p = l->get_first(); + while (p != 0) { + + // Only print an argument if not ignored + + if (!typemap_check("ignore","tcl",p->t,p->name)) { + if (i >= (pcount-numopt)) + temp << "?"; + + /* If parameter has been named, use that. Otherwise, just print a type */ + + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + if (strlen(p->name) > 0) { + temp << p->name; + } + else { + temp << "{ " << p->t->print_type() << " }"; + } + } + if (i >= (pcount-numopt)) + temp << "?"; + temp << " "; + i++; + } + p = l->get_next(); + } + return temp; +} + +// --------------------------------------------------------------------------- +// char *TCL::usage_func(char *iname, DataType *t, ParmList *l), +// +// Produces a usage string for a function in Tcl +// --------------------------------------------------------------------------- + +char * TCL::usage_func(char *iname, DataType *t, ParmList *l) { + + String temp; + + if (nspace) { + temp << ns_name << "::" << iname; + } else { + temp << prefix << iname; + } + return usage_string(temp,t,l); +} + +// ----------------------------------------------------------------- +// TCL::usage_const(char *name, DataType *type, char *value) +// char **s) +// +// Makes a usage string and returns it +// ----------------------------------------------------------------- + +char *TCL::usage_const(char *name, DataType *, char *value) { + static String temp; + temp = ""; + if (nspace) { + temp << ns_name << "::" << name << " = " << value; + } else { + temp << "$" << prefix << name << " = " << value; + } + return temp; +} + +// ------------------------------------------------------------------- +// TCL::add_native(char *name, char *funcname) +// +// This adds an already written Tcl wrapper function to our +// initialization function. +// ------------------------------------------------------------------- + + +void TCL::add_native(char *name, char *funcname) { + + fprintf(f_init,"\t Tcl_CreateCommand(%s, SWIG_prefix \"%s\", %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",interp_name, name, funcname); + + if (doc_entry) { + if (nspace) + doc_entry->usage << ns_name << "::" << name << " args"; + else + doc_entry->usage << prefix << name << " args"; + + doc_entry->cinfo << "Native method : " << funcname; + } + +} + +// ------------------------------------------------------------------- +// TCL::pragma(char *lname, char *name, char *value) +// +// This is an experimental %pragma handler. Officially unsupported +// in this release, but requested in e-mail. +// -------------------------------------------------------------------- + +void TCL::pragma(char *lname, char *name, char *) { + + if (strcmp(lname,"tcl") == 0) { + if (strcmp(name,"dynamic") == 0) { + char_result = "TCL_DYNAMIC"; + } else if (strcmp(name,"static") == 0) { + char_result = "TCL_STATIC"; + } else if (strcmp(name,"volatile") == 0) { + char_result = "TCL_VOLATILE"; + } + } +} + + +// --------------------------------------------------------------------- +// C++ Handling +// +// The following functions provide some support for C++ classes and +// C structs. +// --------------------------------------------------------------------- + +void TCL::cpp_open_class(char *classname, char *rename, char *ctype, int strip) { + char temp[256]; + this->Language::cpp_open_class(classname,rename,ctype,strip); + + if (shadow) { + + config = ""; + cget = ""; + methods = ""; + options = ""; + config_options = ""; + methodnames = ""; + + have_constructor = 0; + have_destructor = 0; + have_methods = 0; + have_config = 0; + have_cget = 0; + + if (rename) + class_name = copy_string(rename); + else + class_name = copy_string(classname); + + base_class = (char *) 0; + if (!strip) { + class_type = new char[strlen(ctype)+2]; + sprintf(class_type,"%s ", ctype); + } else + class_type = ""; + + real_classname = copy_string(classname); + + // Build up the hash table + + hash.add(real_classname,copy_string(class_name)); + sprintf(temp,"%s %s", class_type, real_classname); + hash.add(temp,copy_string(class_name)); + } +} + +void TCL::cpp_close_class() { + String code; + DataType *t; + String temp; + + this->Language::cpp_close_class(); + if (shadow) { + + t = new DataType; + sprintf(t->name,"%s%s", class_type, real_classname); + t->type = T_USER; + t->is_pointer = 1; + + // Note : The object oriented interface is defined by three files + // delcmd.swg - Object deletion wrapper + // methodcmd.swg - Method invocation command + // objcmd.swg - Command to create a new object + // + // These files are located in the SWIG library. This module + // grabs the files and performs marker replacements to + // build the wrapper function. + + // Generate a Tcl function for object destruction + + if (have_destructor) { + code << delcmd; + } + + // Dump out method code + code << methodcmd; + + // Dump out object creation command + code << objcmd; + + // Now perform marker replacements + code.replace("@CLASS@",class_name); + temp = ""; + temp << name_destroy(class_name); + code.replace("@DESTRUCTOR@",temp); + code.replace("@CLASSTYPE@",t->print_type()); + "configure " >> methodnames; + "cget " >> methodnames; + code.replace("@METHODLIST@", methodnames); + code.replace("@CLASSMANGLE@",t->print_mangle()); + code.replace("@METHODS@",methods); + code.replace("@CONFIGMETHODS@",config); + code.replace("@CGETMETHODS@",cget); + if (have_constructor) { + temp = ""; + temp << name_wrapper(name_construct(class_name),prefix); + } else { + temp = "0"; + } + code.replace("@TCLCONSTRUCTOR@",temp); + code.replace("@CONFIGLIST@",config_options); + code.replace("@CGETLIST@",options); + if (have_destructor) { + temp = "TclDelete"; + temp << class_name; + } else { + temp = "0"; + } + code.replace("@TCLDESTRUCTOR@",temp); + fprintf(f_wrappers,"%s\n", code.get()); + fprintf(f_init,"\t Tcl_CreateCommand(interp, SWIG_prefix \"%s\",Tcl%sCmd, (ClientData) NULL, NULL);\n", class_name, class_name); + } +} + +void TCL::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) { + + char *realname; + String temp; + char *rname; + + this->Language::cpp_member_func(name,iname,t,l); + + if (shadow) { + if (iname) + realname = iname; + else + realname = name; + + // Add stubs for this member to our class handler function + + if (have_methods) + methods << tab4 << "else "; + else + methods << tab4; + + // Try to figure out if there is a wrapper for this function + + temp = ""; + temp << name_member(realname,class_name); + + rname = (char *) repeatcmd.lookup(temp); + + if (!rname) + rname = name_wrapper(temp.get(),prefix); + + methods << "if (strcmp(argv[1],\"" << realname << "\") == 0) {\n" + << tab4 << tab4 << "cmd = " << rname << ";\n" + << tab4 << "}"; + + have_methods = 1; + methodnames << realname << " "; + + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << usage_string(realname,t,l); + } + } +} + +void TCL::cpp_variable(char *name, char *iname, DataType *t) { + char *realname; + String temp, temp1; + char *rname; + + this->Language::cpp_variable(name, iname, t); + + if (shadow) { + if (iname) + realname = iname; + else + realname = name; + + // Write config code + + char *bc = class_name; + + if (!(Status & STAT_READONLY)) { + if (!have_config) { + config << tab8 << tab8; + } else { + config << " else "; + } + + temp = ""; + temp << name_set(name_member(realname,bc)); + rname = (char *) repeatcmd.lookup(temp); + if (!rname) + rname = name_wrapper(temp.get(),prefix); + + config << "if (strcmp(argv[i],\"-" << realname << "\") == 0) {\n" + << tab8 << tab8 << tab4 << "cmd = " << rname << ";\n" + << tab8 << tab8 << "} "; + + have_config = 1; + } + + // Write cget code + + if (!have_cget) { + cget << tab8 << tab8; + } else { + cget << " else "; + } + + // Try to figure out if there is a wrapper for this function + temp = ""; + temp << name_get(name_member(realname,bc)); + rname = (char *) repeatcmd.lookup(temp); + if (!rname) + rname = name_wrapper(temp.get(),prefix); + + cget << "if (strcmp(argv[2],\"-" << realname << "\") == 0) {\n" + << tab8 << tab8 << tab4 << "cmd = " << rname << ";\n" + << tab8 << tab8 << "} "; + have_cget = 1; + + options << "-" << realname << " "; + if (!(Status & STAT_READONLY)) { + config_options << "-" << realname << " "; + } + if (doc_entry){ + doc_entry->usage = ""; + doc_entry->usage << "-" << realname << "\n"; + } + } +} + +void TCL::cpp_constructor(char *name, char *iname, ParmList *l) { + this->Language::cpp_constructor(name,iname,l); + + if (shadow) { + if ((!have_constructor) && (doc_entry)) { + doc_entry->usage = ""; + doc_entry->usage << class_name << usage_string(" name",0,l); + } + have_constructor = 1; + } +} +void TCL::cpp_destructor(char *name, char *newname) { + this->Language::cpp_destructor(name,newname); + if (shadow) { + if (!have_destructor) { + if (doc_entry) { + doc_entry->usage = "rename obj {}"; + } + } + have_destructor = 1; + } +} + +void TCL::cpp_inherit(char **baseclass, int) { + this->Language::cpp_inherit(baseclass); +} + +void TCL::cpp_declare_const(char *name, char *iname, DataType *type, char *value) { + this->Language::cpp_declare_const(name,iname,type,value); +} + + +// -------------------------------------------------------------------------------- +// TCL::add_typedef(DataType *t, char *name) +// +// This is called whenever a typedef is encountered. When shadow classes are +// used, this function lets us discovered hidden uses of a class. For example : +// +// struct FooBar { +// ... +// } +// +// typedef FooBar *FooBarPtr; +// +// -------------------------------------------------------------------------------- + +void TCL::add_typedef(DataType *t, char *name) { + + if (!shadow) return; + + // First check to see if there aren't too many pointers + + if (t->is_pointer > 1) return; + if (hash.lookup(name)) return; // Already added + + // Now look up the datatype in our shadow class hash table + + if (hash.lookup(t->name)) { + + // Yep. This datatype is in the hash + // Put this types 'new' name into the hash + hash.add(name,copy_string((char *) hash.lookup(t->name))); + } +} + +// ----------------------------------------------------------------------- +// TCL::cpp_class_decl(char *name, char *rename, char *type) +// +// Treatment of an empty class definition. Used to handle +// shadow classes across modules. +// ----------------------------------------------------------------------- + +void TCL::cpp_class_decl(char *name, char *rename, char *type) { + char temp[256]; + this->Language::cpp_class_decl(name,rename, type); + if (shadow) { + hash.add(name,copy_string(rename)); + // Add full name of datatype to the hash table + if (strlen(type) > 0) { + sprintf(temp,"%s %s", type, name); + hash.add(temp,copy_string(rename)); + } + } +} diff --git a/wxPython/wxSWIG/Modules/tcl8.cxx b/wxPython/wxSWIG/Modules/tcl8.cxx new file mode 100644 index 0000000000..f0911d9d9b --- /dev/null +++ b/wxPython/wxSWIG/Modules/tcl8.cxx @@ -0,0 +1,1499 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/*********************************************************************** + * $Header$ + * + * tcl8.cxx + * + * Module for creating Tcl 8.0 native wrapper functions. Older SWIG + * modules will work with Tcl 8.0, but this one provides a significant + * boost in performance. + ***********************************************************************/ + +#include "swig.h" +#include "tcl8.h" +#include + +static char *Tcl_config="swigtcl.swg"; +static char *usage = "\ +Tcl 8.0 Options (available with -tcl)\n\ + -module name - Set name of module\n\ + -prefix name - Set a prefix to be appended to all names\n\ + -namespace - Build module into a Tcl 8 namespace. \n\ + -noobject - Omit code for object oriented interface.\n\ + -old - Use old SWIG interface (same as -noobject).\n\n"; + +static char *ns_name = 0; + +static String mod_init; +static String mod_extern; + +// --------------------------------------------------------------------- +// TCL8::parse_args(int argc, char *argv[]) +// +// Parse tcl specific command line options +// --------------------------------------------------------------------- + +void TCL8::parse_args(int argc, char *argv[]) { + + int i = 1; + sprintf(LibDir,"%s",tcl_path); + + // Look for certain command line options + + for (i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i],"-prefix") == 0) { + if (argv[i+1]) { + prefix = new char[strlen(argv[i+1])+2]; + strcpy(prefix, argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-module") == 0) { + if (argv[i+1]) { + set_module(argv[i+1],0); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-namespace") == 0) { + nspace = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-old") == 0) { + shadow = 0; + mark_arg(i); + } else if (strcmp(argv[i],"-noobject") == 0) { + shadow = 0; + mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + } + } + } + + // If a package has been specified, make sure it ends with a '_' + + if (prefix) { + ns_name = copy_string(prefix); + if (prefix[strlen(prefix)] != '_') { + prefix[strlen(prefix)+1] = 0; + prefix[strlen(prefix)] = '_'; + } + } else + prefix = ""; + + // Create a symbol SWIGTCL + + add_symbol("SWIGTCL",0,0); + add_symbol("SWIGTCL8",0,0); + + // Set name of typemaps + + typemap_lang = "tcl8"; + + // Attempt to load up the C++ configuration files + + get_file("delcmd8.swg",delcmd); + get_file("methodcmd8.swg",methodcmd); + get_file("objcmd8.swg",objcmd); + +} + +// --------------------------------------------------------------------- +// void TCL8::parse() +// +// Start parsing an interface file for Tcl. +// --------------------------------------------------------------------- + +void TCL8::parse() { + + fprintf(stderr,"Making wrappers for Tcl 8.x\n"); + + // Print out TCL specific headers + + headers(); + + // Run the parser + + yyparse(); + +} + +// --------------------------------------------------------------------- +// TCL8::set_module(char *mod_name,char **mod_list) +// +// Sets the module name. +// Does nothing if it's already set (so it can be overridden as a command +// line option). +// +// mod_list is a NULL-terminated list of additional modules. This +// is really only useful when building static executables and other +// things. +//---------------------------------------------------------------------- + +void TCL8::set_module(char *mod_name, char **mod_list) { + + char temp[256], *c; + int i; + + if (module) return; + + module = new char[strlen(mod_name)+1]; + strcpy(module,mod_name); + + // Fix capitalization for Tcl + + c = module; + while (*c) { + *c = (char) tolower(*c); + c++; + } + + // Now create an initialization function + + sprintf(temp,"%s_Init", module); + init_name = new char[strlen(temp) + 1]; + strcpy(init_name, temp); + *init_name = toupper(*init_name); + + if (!ns_name) ns_name = copy_string(module); + + // If namespaces have been specified, set the prefix to the module name + + if ((nspace) && (strlen(prefix) < 1)) { + prefix = new char[strlen(module)+2]; + strcpy(prefix,module); + prefix[strlen(module)] = '_'; + prefix[strlen(module)+1] = 0; + } + + // If additional modules have been specified, create some code for + // initializing them. + + if (mod_list) { + i = 0; + while (mod_list[i]) { + c = mod_list[i]; + while (*c) { + *c = (char) tolower(*c); + c++; + } + sprintf(temp,"%s_Init",mod_list[i]); + temp[0] = toupper(temp[0]); + + // Dump out some initialization code + + mod_init << tab4 << "if (" << temp << "(" << interp_name << ") == TCL_ERROR) {\n" + << tab8 << "return TCL_ERROR;\n" + << tab4 << "}\n\n"; + mod_extern << "extern int " << temp << "(Tcl_Interp *);\n"; + i++; + } + } +} + + +// --------------------------------------------------------------------- +// TCL8::set_init(char *iname) +// +// Sets the initialization function name. +// Does nothing if it's already set +// +//---------------------------------------------------------------------- + +void TCL8::set_init(char *iname) { + + if (init_name) return; + init_name = new char[strlen(iname)+1]; + strcpy(init_name, iname); + +} + +// --------------------------------------------------------------------- +// TCL8::headers(void) +// +// Generate the appropriate header files for TCL interface. +// ---------------------------------------------------------------------- + +void TCL8::headers(void) +{ + + emit_banner(f_header); + fprintf(f_header,"/* Implementation : TCL 8.0 */\n\n"); + fprintf(f_header,"#include \n"); + fprintf(f_header,"#include \n"); + fprintf(f_header,"#include \n"); + fprintf(f_header,"#define SWIGTCL\n"); + fprintf(f_header,"#define SWIGTCL8\n"); + + // Include a Tcl configuration file for Unix,Mac,Wintel. + + if (NoInclude) { + fprintf(f_header,"#define SWIG_NOINCLUDE\n"); + } + + if (insert_file("swigtcl8.swg",f_header) == -1) { + fprintf(stderr,"SWIG : Fatal error. Unable to locate 'swigtcl8.swg' in SWIG library.\n"); + SWIG_exit(1); + } +} + +// -------------------------------------------------------------------- +// TCL8::initialize(void) +// +// Produces an initialization function. Assumes that the init function +// name has already been specified. +// --------------------------------------------------------------------- + +void TCL8::initialize() +{ + + if ((!ns_name) && (nspace)) { + fprintf(stderr,"Tcl error. Must specify a namespace.\n"); + SWIG_exit(1); + } + + if (!init_name) { + init_name = "Swig_Init"; + fprintf(stderr,"SWIG : *** Warning. No module name specified.\n"); + } + + fprintf(f_header,"#define SWIG_init %s\n", init_name); + if (!module) module = "swig"; + fprintf(f_header,"#define SWIG_name \"%s\"\n", module); + if (nspace) { + fprintf(f_header,"#define SWIG_prefix \"%s::\"\n", ns_name); + fprintf(f_header,"#define SWIG_namespace \"%s\"\n\n", ns_name); + } else { + fprintf(f_header,"#define SWIG_prefix \"%s\"\n", prefix); + fprintf(f_header,"#define SWIG_namespace \"\"\n\n"); + } + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"extern \"C\" {\n"); + fprintf(f_header,"#endif\n"); + fprintf(f_header,"#ifdef MAC_TCL\n"); + fprintf(f_header,"#pragma export on\n"); + fprintf(f_header,"#endif\n"); + fprintf(f_header,"SWIGEXPORT(int) %s(Tcl_Interp *);\n", init_name); + fprintf(f_header,"#ifdef MAC_TCL\n"); + fprintf(f_header,"#pragma export off\n"); + fprintf(f_header,"#endif\n"); + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"}\n"); + fprintf(f_header,"#endif\n"); + + + fprintf(f_init,"SWIGEXPORT(int) %s(Tcl_Interp *%s) {\n", init_name, interp_name); + if (nspace) { + fprintf(f_init,"#ifdef ITCL_NAMESPACES\n"); + fprintf(f_init,"\t Itcl_Namespace spaceId;\n"); + fprintf(f_init,"#endif\n"); + } + + fprintf(f_init,"\t if (%s == 0) \n", interp_name); + fprintf(f_init,"\t\t return TCL_ERROR;\n"); + + /* Set up SwigPtrType table */ + + fprintf(f_init,"\t SWIG_RegisterType();\n"); + + /* Check to see if other initializations need to be performed */ + + if (strlen(mod_extern.get())) { + fprintf(f_init,"%s\n",mod_init.get()); + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"extern \"C\" {\n"); + fprintf(f_header,"#endif\n"); + fprintf(f_header,"%s\n",mod_extern.get()); + fprintf(f_header,"#ifdef __cplusplus\n"); + fprintf(f_header,"}\n"); + fprintf(f_header,"#endif\n"); + } + + + /* Check to see if we're adding support for Tcl8 nspaces */ + if (nspace) { + fprintf(f_init,"#if (TCL_MAJOR_VERSION >= 8)\n"); + fprintf(f_init,"\t Tcl_Eval(%s,\"namespace eval %s { }\");\n", interp_name, ns_name); + fprintf(f_init,"#endif\n"); + } +} + +// --------------------------------------------------------------------- +// TCL8::close(void) +// +// Wrap things up. Close initialization function. +// --------------------------------------------------------------------- + +void TCL8::close(void) +{ + + // Dump the pointer equivalency table + + emit_ptr_equivalence(f_init); + + // Close the init file and quit + + fprintf(f_init,"%s",postinit.get()); + fprintf(f_init,"\t return TCL_OK;\n"); + fprintf(f_init,"}\n"); + +} + +// ---------------------------------------------------------------------- +// TCL8::get_pointer(char *iname, char *srcname, char *src, char *dest, +// DataType *t, String &f, char *ret) +// +// iname = name of function or variable +// srcname = name of source +// src = source variable in wrapper code +// dest = destination variable in wrapper code +// t = Datatype +// f = String where output is going to go +// ret = Return action +// ---------------------------------------------------------------------- + +void TCL8::get_pointer(char *iname, char *srcname, char *src, char *dest, + DataType *t, String &f, char *ret) { + + // Pointers are read as hex-strings with encoded type information + + f << tab4 << "if ((rettype = SWIG_GetPointerObj(interp," << src << ",(void **) &" << dest << ","; + + if (t->type == T_VOID) f << "(char *) 0))) {\n"; + else + f << "\"" << t->print_mangle() << "\"))) {\n"; + + // Now emit code according to the level of strictness desired + + switch(TypeStrict) { + case 0: // No type checking + f << tab4 << "}\n"; + break; + case 1: // Warning message only + f << tab8 << "fprintf(stderr,\"Warning : type mismatch in " << srcname + << " of " << iname << ". Expected " << t->print_mangle() + << ", received %s\\n\", rettype);\n" + << tab4 << "}\n"; + case 2: // Super strict mode. + f << tab8 << "Tcl_SetStringObj(tcl_result, \"Type error in " << srcname << " of " << iname + << ". Expected " << t->print_mangle() << ", received \", -1);\n" + << tab8 << "Tcl_AppendToObj(tcl_result, rettype, -1);\n" + << tab8 << ret << ";\n" + << tab4 << "}\n"; + break; + default : + fprintf(stderr,"Unknown strictness level\n"); + break; + } +} + + +// ---------------------------------------------------------------------- +// TCL8::create_command(char *cname, char *iname) +// +// Creates a Tcl command from a C function. +// ---------------------------------------------------------------------- + +void TCL8::create_command(char *cname, char *iname) { + + char *wname = name_wrapper(cname,prefix); + + fprintf(f_init,"\t Tcl_CreateObjCommand(%s, SWIG_prefix \"%s\",%s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n", interp_name, iname, wname); + + // Add interpreter name to repeatcmd hash table. This hash is used in C++ code + // generation to try and find repeated wrapper functions. + + repeatcmd.add(iname,copy_string(wname)); +} + +// ---------------------------------------------------------------------- +// TCL8::create_function(char *name, char *iname, DataType *d, ParmList *l) +// +// Create a function declaration and register it with the interpreter. +// ---------------------------------------------------------------------- + +void TCL8::create_function(char *name, char *iname, DataType *d, ParmList *l) +{ + Parm *p; + int pcount,i,j; + char *wname; + char *usage = 0, *tm; + char source[64]; + char target[64]; + char argnum[32]; + WrapperFunction f; + String cleanup, outarg, build; + int numopt= 0; + int have_build = 0; + + // Make a wrapper name for this function + + wname = name_wrapper(iname,prefix); + + // Now write the wrapper function itself....this is pretty ugly + + f.def << "static int " << wname << "(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {\n"; + + f.code << tab4 << "clientData = clientData; objv = objv;\n"; + + // Print out variables for storing arguments. + + pcount = emit_args(d, l, f); + numopt = l->numopt(); + + // Create a local variable for holding the interpreter result value + + f.add_local("Tcl_Obj *", "tcl_result"); + + // Extract the tcl result object + + f.code << tab4 << "tcl_result = Tcl_GetObjResult(interp);\n"; + + // Check the number of arguments + + usage = usage_func(iname,d,l); // Create a usage string + f.code << tab4 << "if ((objc < " << (pcount-numopt) +1 << ") || (objc > " << l->numarg()+1 << ")) {\n" + << tab8 << "Tcl_SetStringObj(tcl_result,\"Wrong # args. " << usage << "\",-1);\n" + << tab8 << "return TCL_ERROR;\n" + << tab4 << "}\n"; + + // Extract parameters. This case statement should be used to extract + // Function parameters. Add more cases if you want to do more. + + i = 0; + j = 0; + p = l->get_first(); + while (p != 0) { + // Produce string representations of the source and target arguments + sprintf(source,"objv[%d]",j+1); + sprintf(target,"_arg%d",i); + sprintf(argnum,"%d",j+1); + + // See if this argument is being ignored + + if (!p->ignore) { + if (j >= (pcount-numopt)) + f.code << tab4 << "if (objc >" << j+1 << ") { \n"; + + if ((tm = typemap_lookup("in","tcl8",p->t,p->name,source,target,&f))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + f.code.replace("$argnum",argnum); + f.code.replace("$arg",source); + } else { + if (!p->t->is_pointer) { + + // Extract a parameter by value. + + switch(p->t->type) { + + // Signed Integers + + case T_BOOL: + case T_INT: + case T_SINT: + case T_SHORT: + case T_SSHORT: + case T_LONG: + case T_SLONG: + case T_SCHAR: + + // Unsigned integers + + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + f.add_local("int","tempint"); + f.code << tab4 << "if (Tcl_GetIntFromObj(interp,objv[" << j+1 << "],&tempint) == TCL_ERROR) return TCL_ERROR;\n"; + f.code << tab4 << "_arg" << i << " = " << p->t->print_cast() << " tempint;\n"; + break; + + // Floating point + + case T_FLOAT: + case T_DOUBLE: + f.add_local("double","tempdouble"); + f.add_local("Tcl_Obj *", "dupobj"); + f.code << tab4 << "dupobj = Tcl_DuplicateObj(objv[" << j+1 << "]);\n" + << tab4 << "if (Tcl_GetDoubleFromObj(interp,dupobj,&tempdouble) == TCL_ERROR) {\n" + << tab8 << "Tcl_DecrRefCount(dupobj);\n" + << tab8 << "return TCL_ERROR;\n" + << tab4 << "}\n" + << tab4 << "Tcl_DecrRefCount(dupobj);\n" + << tab4 << "_arg" << i << " = " << p->t->print_cast() << " tempdouble;\n"; + break; + + // A single character + + case T_CHAR : + f.add_local("char *","tempstr"); + f.add_local("int","templength"); + f.code << tab4 << "if ((tempstr = Tcl_GetStringFromObj(objv[" << j+1 << "],&templength)) == NULL) return TCL_ERROR;\n" + << tab4 << "_arg" << i << " = *tempstr;\n"; + break; + + // Void.. Do nothing. + + case T_VOID : + break; + + // User defined. This is an error. + + case T_USER: + + // Unsupported data type + + default : + fprintf(stderr,"%s : Line %d: Unable to use type %s as a function argument.\n", + input_file, line_number, p->t->print_type()); + break; + } + } else { + + // Function argument is some sort of pointer + // Look for a string. Otherwise, just pull off a pointer. + + if ((p->t->type == T_CHAR) && (p->t->is_pointer == 1)) { + f.add_local("int","templength"); + f.code << tab4 << "if ((_arg" << i << " = Tcl_GetStringFromObj(objv[" << j+1 << "], &templength)) == NULL) return TCL_ERROR;\n"; + } else { + + // Have a generic pointer type here. Read it in as + // a hex-string + char arg_temp[256]; + + // Try to parse pointer value directly + +#ifdef OLD + f.add_local("char *", "tempstr"); + f.add_local("int","templength"); + f.code << tab4 << "if ((tempstr = Tcl_GetStringFromObj(objv[" << j+1 << "],&templength)) == NULL) return TCL_ERROR;\n"; + get_pointer(iname,arg_temp,"tempstr",target,p->t,f.code,"return TCL_ERROR"); +#endif + sprintf(arg_temp,"argument %d",j+1); + f.add_local("char *", "rettype"); + get_pointer(iname,arg_temp,source,target,p->t,f.code,"return TCL_ERROR"); + } + } + } + if (j >= (pcount-numopt)) + f.code << tab4 << "}\n"; + j++; + } + + + // Check to see if there is any sort of "build" typemap (highly complicated) + + if ((tm = typemap_lookup("build","tcl8",p->t,p->name,source,target))) { + build << tm << "\n"; + have_build = 1; + } + + // Check to see if there was any sort of a constaint typemap + if ((tm = typemap_lookup("check","tcl8",p->t,p->name,source,target))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + f.code.replace("$argnum",argnum); + f.code.replace("$arg",source); + } + + // Check if there was any cleanup code (save it for later) + if ((tm = typemap_lookup("freearg","tcl8",p->t,p->name,target,"tcl_result"))) { + // Yep. Use it instead of the default + cleanup << tm << "\n"; + cleanup.replace("$argnum",argnum); + cleanup.replace("$arg",source); + } + // Look for output arguments + if ((tm = typemap_lookup("argout","tcl8",p->t,p->name,target,"tcl_result"))) { + outarg << tm << "\n"; + outarg.replace("$argnum",argnum); + outarg.replace("$arg",source); + } + i++; + p = l->get_next(); // Get next parameter and continue + } + + + // If there was a "build" typemap, we need to go in and perform a serious hack + + if (have_build) { + char temp1[32]; + char temp2[256]; + l->sub_parmnames(build); // Replace all parameter names + j = 1; + for (i = 0; i < l->nparms; i++) { + p = l->get(i); + if (strlen(p->name) > 0) { + sprintf(temp1,"_in_%s", p->name); + } else { + sprintf(temp1,"_in_arg%d", i); + } + sprintf(temp2,"argv[%d]",j); + build.replaceid(temp1,temp2); + if (!p->ignore) + j++; + } + f.code << build; + } + + // Now write code to make the function call + + emit_func_call(name,d,l,f); + + // Extract the tcl result object + + f.code << tab4 << "tcl_result = Tcl_GetObjResult(interp);\n"; + + + // Return value if necessary + + if ((tm = typemap_lookup("out","tcl8",d,name,"_result","tcl_result"))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + } else if ((d->type != T_VOID) || (d->is_pointer)) { + if (!d->is_pointer) { + + // Function returns a "value" + + switch(d->type) { + // Is an integer + case T_BOOL: + case T_INT: + case T_SINT: + case T_SHORT: + case T_SSHORT: + case T_LONG : + case T_SLONG: + case T_SCHAR: + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + f.code << tab4 << "Tcl_SetIntObj(tcl_result,(long) _result);\n"; + break; + + // Is a single character. Assume we return it as a string + case T_CHAR : + f.code << tab4 << "Tcl_SetStringObj(tcl_result,&_result,1);\n"; + break; + + // Floating point number + case T_DOUBLE : + case T_FLOAT : + f.code << tab4 << "Tcl_SetDoubleObj(tcl_result,(double) _result);\n"; + break; + + // User defined type + case T_USER : + + // Okay. We're returning malloced memory at this point. + // Probably dangerous, but who said safety was a good thing? + + // f.add_local("char","resultchar[256]"); + d->is_pointer++; +#ifdef OLD + f.code << tab4 << "SWIG_MakePtr(resultchar, (void *) _result,\"" << d->print_mangle() << "\");\n" + << tab4 << "Tcl_SetStringObj(tcl_result,resultchar,-1);\n"; +#endif + f.code << tab4 << "SWIG_SetPointerObj(tcl_result,(void *) _result,\"" << d->print_mangle() << "\");\n"; + + d->is_pointer--; + break; + + // Unknown type + default : + fprintf(stderr,"%s : Line %d: Unable to use return type %s in function %s.\n", + input_file, line_number, d->print_type(), name); + break; + } + } else { + + // Is a pointer return type + + if ((d->type == T_CHAR) && (d->is_pointer == 1)) { + // Return a character string + f.code << tab4 << "Tcl_SetStringObj(tcl_result,_result,-1);\n"; + } else { +#ifdef OLD + f.add_local("char","resultchar[256]"); + f.code << tab4 << "SWIG_MakePtr(resultchar, (void *) _result,\"" << d->print_mangle() << "\");\n" + << tab4 << "Tcl_SetStringObj(tcl_result,resultchar,-1);\n"; +#endif + + f.code << tab4 << "SWIG_SetPointerObj(tcl_result,(void *) _result,\"" << d->print_mangle() << "\");\n"; + } + } + } + + + // Dump output argument code + f.code << outarg; + + // Dump the argument cleanup code + f.code << cleanup; + + // Look for any remaining cleanup + + if (NewObject) { + if ((tm = typemap_lookup("newfree","tcl8",d,iname,"_result",""))) { + f.code << tm << "\n"; + } + } + + if ((tm = typemap_lookup("ret","tcl8",d,name,"_result",""))) { + // Yep. Use it instead of the default + f.code << tm << "\n"; + } + + // Wrap things up (in a manner of speaking) + + f.code << tab4 << "return TCL_OK;\n}"; + + // Substitute the cleanup code + f.code.replace("$cleanup",cleanup); + f.code.replace("$name",iname); + + // Dump out the function + + f.print(f_wrappers); + + // Now register the function with Tcl + + fprintf(f_init,"\t Tcl_CreateObjCommand(%s, SWIG_prefix \"%s\", %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",interp_name, iname, wname); + + // If there's a documentation entry, produce a usage string + + if (doc_entry) { + + static DocEntry *last_doc_entry = 0; + + // Use usage as description + doc_entry->usage << usage; + + // Set the cinfo field to specific a return type + + if (last_doc_entry != doc_entry) { + doc_entry->cinfo << "returns " << d->print_type(); + last_doc_entry = doc_entry; + } + } +} + +// ----------------------------------------------------------------------- +// TCL8::link_variable(char *name, char *iname, DataType *t, +// int ex) +// +// Create a TCL link to a variable. +// ----------------------------------------------------------------------- + +void TCL8::link_variable(char *name, char *iname, DataType *t) +{ + + String s; + char *tm, *tm1; + + // See if there were any typemaps + + tm = typemap_lookup("varin","tcl8",t,name,"",""); + tm1 = typemap_lookup("varout","tcl8",t,name,"",""); + if (tm || tm1) { + fprintf(stderr,"%s : Line %d. Warning. varin/varout typemap methods not supported.", + input_file, line_number); + } + + // Check the datatype. Must be a valid Tcl type (there aren't many) + + if (((t->type == T_INT) && (!t->is_pointer)) || + ((t->type == T_UINT) && (!t->is_pointer)) || + ((t->type == T_SINT) && (!t->is_pointer)) || + ((t->type == T_DOUBLE) && (!t->is_pointer)) || + ((t->type == T_BOOL) && (!t->is_pointer)) || + ((t->type == T_CHAR) && (t->is_pointer == 1))) { + + // This is a valid TCL type. + + if (t->type == T_UINT) + fprintf(stderr,"%s : Line %d : ** Warning. Linkage of unsigned type may be unsafe.\n", + input_file, line_number); + + // Now add symbol to the TCL interpreter + + switch(t->type) { + case T_CHAR : + if (t->arraystr) { + // Is an array. We have to do something different + fprintf(f_wrappers,"static char *tclvar%s = %s;\n",name,name); + s << "(char *) &tclvar" << name << ", TCL_LINK_STRING"; + } else { + s << "(char *) &" << name << ", TCL_LINK_STRING"; + } + break; + case T_BOOL: + case T_INT : + case T_UINT: + case T_SINT: + s << "(char *) &" << name << ", TCL_LINK_INT"; + break; + case T_DOUBLE : + s << "(char *) &" << name << ", TCL_LINK_DOUBLE"; + break; + default : + fprintf(f_init,"Fatal error. Internal error (Tcl:link_variable)\n"); + break; + } + + if (Status & STAT_READONLY) + s << " | TCL_LINK_READ_ONLY);\n"; + else + s << ");\n"; + + fprintf(f_init,"\t Tcl_LinkVar(%s, SWIG_prefix \"%s\", %s",interp_name, iname, s.get()); + + // Make a usage string for it + + if (doc_entry) { + doc_entry->usage << usage_var(iname,t); + doc_entry->cinfo = ""; + doc_entry->cinfo << "Global : " << t->print_type() << " " << name; + } + } else { + + // Have some sort of "other" type. + // We're going to emit some functions to set/get it's value instead + + emit_set_get(name,iname, t); + if (doc_entry) { + doc_entry->cinfo = ""; + doc_entry->cinfo << "Global : " << t->print_type() << " " << iname; + } + + // If shadow classes are enabled and we have a user-defined type + // that we know about, create a command for it. + + if (shadow) { + if ((t->type == T_USER) && (t->is_pointer < 1)) { + // See if the datatype is in our hash table + if (hash.lookup(t->name)) { + // Yep. Try to create a command for it + + postinit << tab4 << "{\n" + << tab8 << "char cmd[] = \"" + << (char *) hash.lookup(t->name) << " " << iname << " -this [" + << iname << "_get ]\";\n" + << tab8 << "Tcl_GlobalEval(interp,cmd);\n" + << tab4 << "}\n"; + } + } + } + } +} + +// ----------------------------------------------------------------------- +// TCL8::declare_const(char *name, char *iname, DataType *type, char *value) +// +// Makes a constant. Really just creates a variable and links to it. +// Tcl variable linkage allows read-only variables so we'll use that +// instead of just creating a Tcl variable. +// ------------------------------------------------------------------------ + +void TCL8::declare_const(char *name, char *, DataType *type, char *value) { + + int OldStatus = Status; // Save old status flags + DataType *t; + char var_name[256]; + char *tm; + String rvalue; + Status = STAT_READONLY; // Enable readonly mode. + + // Make a static variable; + + sprintf(var_name,"_wrap_const_%s",name); + + // See if there's a typemap + rvalue = value; + if ((type->type == T_CHAR) && (type->is_pointer == 1)) { + rvalue << "\""; + "\"" >> rvalue; + } + if ((type->type == T_CHAR) && (type->is_pointer == 0)) { + rvalue << "'"; + "'" >> rvalue; + } + if ((tm = typemap_lookup("const","tcl8",type,name,rvalue.get(),name))) { + // Yep. Use it instead of the default + fprintf(f_init,"%s\n",tm); + } else { + + // Create variable and assign it a value + + if (type->is_pointer == 0) { + switch(type->type) { + case T_BOOL: case T_INT: case T_SINT: case T_DOUBLE: + fprintf(f_header,"static %s %s = %s;\n", type->print_type(), var_name, value); + link_variable(var_name,name,type); + break; + case T_SHORT: + case T_LONG: + case T_SSHORT: + case T_SCHAR: + case T_SLONG: + fprintf(f_header,"static %s %s = %s;\n", type->print_type(), var_name, value); + fprintf(f_header,"static char *%s_char;\n", var_name); + if (CPlusPlus) + fprintf(f_init,"\t %s_char = new char[32];\n",var_name); + else + fprintf(f_init,"\t %s_char = (char *) malloc(32);\n",var_name); + + fprintf(f_init,"\t sprintf(%s_char,\"%%ld\", (long) %s);\n", var_name, var_name); + sprintf(var_name,"%s_char",var_name); + t = new DataType(T_CHAR); + t->is_pointer = 1; + link_variable(var_name,name,t); + delete t; + break; + case T_UINT: + case T_USHORT: + case T_ULONG: + case T_UCHAR: + fprintf(f_header,"static %s %s = %s;\n", type->print_type(), var_name, value); + fprintf(f_header,"static char *%s_char;\n", var_name); + if (CPlusPlus) + fprintf(f_init,"\t %s_char = new char[32];\n",var_name); + else + fprintf(f_init,"\t %s_char = (char *) malloc(32);\n",var_name); + + fprintf(f_init,"\t sprintf(%s_char,\"%%lu\", (unsigned long) %s);\n", var_name, var_name); + sprintf(var_name,"%s_char",var_name); + t = new DataType(T_CHAR); + t->is_pointer = 1; + link_variable(var_name,name,t); + delete t; + break; + case T_FLOAT: + type->type = T_DOUBLE; + strcpy(type->name,"double"); + fprintf(f_header,"static %s %s = %s (%s);\n", type->print_type(), var_name, type->print_cast(), value); + link_variable(var_name,name,type); + break; + + case T_CHAR: + type->is_pointer++; + fprintf(f_header,"static %s %s = \"%s\";\n", type->print_type(), var_name, value); + link_variable(var_name,name,type); + type->is_pointer--; + break; + default: + fprintf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number); + break; + } + } else { + // Have some sort of pointer value here + if ((type->type == T_CHAR) && (type->is_pointer == 1)) { + // Character string + fprintf(f_header,"static %s %s = \"%s\";\n", type->print_type(), var_name, value); + link_variable(var_name,name,type); + } else { + // Something else. Some sort of pointer value + fprintf(f_header,"static %s %s = %s;\n", type->print_type(), var_name, value); + fprintf(f_header,"static char *%s_char;\n", var_name); + if (CPlusPlus) + fprintf(f_init,"\t %s_char = new char[%d];\n",var_name,(int) strlen(type->print_mangle())+ 20); + else + fprintf(f_init,"\t %s_char = (char *) malloc(%d);\n",var_name, (int) strlen(type->print_mangle())+ 20); + + t = new DataType(T_CHAR); + t->is_pointer = 1; + fprintf(f_init,"\t SWIG_MakePtr(%s_char, (void *) %s,\"%s\");\n", + var_name, var_name, type->print_mangle()); + sprintf(var_name,"%s_char",var_name); + link_variable(var_name,name,t); + delete t; + } + } + } + + // Create a documentation entry for this + + if (doc_entry) { + doc_entry->usage = ""; // Destroy any previous information from linking + doc_entry->usage << usage_const(name, type, value); + doc_entry->cinfo = ""; + doc_entry->cinfo << "Constant : " << type->print_type(); + } + + Status = OldStatus; +} + +// ---------------------------------------------------------------------- +// TCL8::usage_var(char *iname, DataType *t, char **s) +// +// Produces a usage string for a tcl variable. Stores it in s +// ---------------------------------------------------------------------- + +char *TCL8::usage_var(char *iname, DataType *t) { + + static char temp[1024]; + + if (!nspace) { + sprintf(temp,"$%s%s", prefix, iname); + } else { + sprintf(temp,"%s::%s", ns_name, iname); + } + if (!(((t->type == T_INT) && (!t->is_pointer)) || + ((t->type == T_UINT) && (!t->is_pointer)) || + ((t->type == T_DOUBLE) && (!t->is_pointer)) || + ((t->type == T_BOOL) && (!t->is_pointer)) || + ((t->type == T_CHAR) && (t->is_pointer)))) { + /* We emitted a pair of set/get functions instead. Doc will be generated for that */ + return temp; + } + return temp; +} + + + +// --------------------------------------------------------------------------- +// char *TCL8::usage_string(char *iname, DataType *t, ParmList *l), +// +// Generates a generic usage string for a Tcl function. +// --------------------------------------------------------------------------- + +char * TCL8::usage_string(char *iname, DataType *, ParmList *l) { + + static String temp; + Parm *p; + int i, numopt,pcount; + + temp = ""; + temp << iname << " "; + + /* Now go through and print parameters */ + i = 0; + pcount = l->nparms; + numopt = l->numopt(); + p = l->get_first(); + while (p != 0) { + + // Only print an argument if not ignored + + if (!typemap_check("ignore","tcl8",p->t,p->name)) { + if (i >= (pcount-numopt)) + temp << "?"; + + /* If parameter has been named, use that. Otherwise, just print a type */ + + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + if (strlen(p->name) > 0) { + temp << p->name; + } + else { + temp << "{ " << p->t->print_type() << " }"; + } + } + if (i >= (pcount-numopt)) + temp << "?"; + temp << " "; + i++; + } + p = l->get_next(); + } + return temp; +} + +// --------------------------------------------------------------------------- +// char *TCL8::usage_func(char *iname, DataType *t, ParmList *l), +// +// Produces a usage string for a function in Tcl +// --------------------------------------------------------------------------- + +char * TCL8::usage_func(char *iname, DataType *t, ParmList *l) { + + String temp; + + if (nspace) { + temp << ns_name << "::" << iname; + } else { + temp << prefix << iname; + } + return usage_string(temp,t,l); +} + +// ----------------------------------------------------------------- +// TCL8::usage_const(char *name, DataType *type, char *value) +// char **s) +// +// Makes a usage string and returns it +// ----------------------------------------------------------------- + +char *TCL8::usage_const(char *name, DataType *, char *value) { + static String temp; + temp = ""; + if (nspace) { + temp << ns_name << "::" << name << " = " << value; + } else { + temp << "$" << prefix << name << " = " << value; + } + return temp.get(); +} + +// ------------------------------------------------------------------- +// TCL8::add_native(char *name, char *funcname) +// +// This adds an already written Tcl wrapper function to our +// initialization function. +// ------------------------------------------------------------------- + + +void TCL8::add_native(char *name, char *funcname) { + + fprintf(f_init,"\t Tcl_CreateCommand(%s, SWIG_prefix \"%s\", %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",interp_name, name, funcname); + + if (doc_entry) { + if (nspace) + doc_entry->usage << ns_name << "::" << name << " args"; + else + doc_entry->usage << prefix << name << " args"; + + doc_entry->cinfo << "Native method : " << funcname; + } + +} + +// ------------------------------------------------------------------- +// TCL8::pragma(char *lname, char *name, char *value) +// +// Handle pragmas. +// -------------------------------------------------------------------- + +void TCL8::pragma(char *, char *, char *) { + +} + +// --------------------------------------------------------------------- +// C++ Handling +// +// The following functions provide some support for C++ classes and +// C structs. +// --------------------------------------------------------------------- + +void TCL8::cpp_open_class(char *classname, char *rename, char *ctype, int strip) { + + this->Language::cpp_open_class(classname,rename,ctype,strip); + + if (shadow) { + + config = ""; + cget = ""; + methods = ""; + options = ""; + config_options = ""; + methodnames = ""; + + have_constructor = 0; + have_destructor = 0; + have_methods = 0; + have_config = 0; + have_cget = 0; + + if (rename) + class_name = copy_string(rename); + else + class_name = copy_string(classname); + + base_class = (char *) 0; + if (!strip) { + class_type = new char[strlen(ctype)+2]; + sprintf(class_type,"%s ", ctype); + } else + class_type = ""; + + real_classname = copy_string(classname); + } +} + +void TCL8::cpp_close_class() { + String code,temp; + DataType *t; + + this->Language::cpp_close_class(); + if (shadow) { + + t = new DataType; + sprintf(t->name,"%s%s", class_type, real_classname); + t->type = T_USER; + t->is_pointer = 1; + + // Note : The object oriented interface is defined by three files + // delcmd8.swg - Object deletion wrapper + // methodcmd8.swg - Method invocation command + // objcmd8.swg - Command to create a new object + // + // These files are located in the SWIG library. This module + // grabs the files and performs marker replacements to + // build the wrapper function. + + // Generate a Tcl function for object destruction + + if (have_destructor) { + code << delcmd; + } + + // Dump out method code + code << methodcmd; + + // Dump out object creation command + code << objcmd; + + // Now perform marker replacements + code.replace("@CLASS@",class_name); + temp = ""; + temp << name_destroy(class_name); + code.replace("@DESTRUCTOR@",temp); + code.replace("@CLASSTYPE@",t->print_type()); + "configure " >> methodnames; + "cget " >> methodnames; + code.replace("@METHODLIST@", methodnames); + code.replace("@CLASSMANGLE@",t->print_mangle()); + code.replace("@METHODS@",methods); + code.replace("@CONFIGMETHODS@",config); + code.replace("@CGETMETHODS@",cget); + if (have_constructor) { + temp = ""; + temp << name_wrapper(name_construct(class_name),prefix); + } else { + temp = "0"; + } + code.replace("@TCLCONSTRUCTOR@",temp); + code.replace("@CONFIGLIST@",config_options); + code.replace("@CGETLIST@",options); + if (have_destructor) { + temp = "TclDelete"; + temp << class_name; + } else { + temp = "0"; + } + code.replace("@TCLDESTRUCTOR@",temp); + fprintf(f_wrappers,"%s\n", code.get()); + + fprintf(f_init,"\t Tcl_CreateObjCommand(interp,SWIG_prefix \"%s\",Tcl%sCmd, (ClientData) NULL, NULL);\n", class_name, class_name); + } +} + +void TCL8::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) { + + char *realname; + String temp; + char *rname; + + this->Language::cpp_member_func(name,iname,t,l); + + if (shadow) { + if (iname) + realname = iname; + else + realname = name; + + // Add stubs for this member to our class handler function + + if (have_methods) + methods << tab4 << "else "; + else + methods << tab4; + + temp = ""; + temp << name_member(realname,class_name); + rname = (char *) repeatcmd.lookup(temp); + if (!rname) + rname = name_wrapper(temp.get(),prefix); + + methods << "if (strcmp(_str,\"" << realname << "\") == 0) {\n" + << tab4 << tab4 << "cmd = " << rname << ";\n" + << tab4 << "}"; + + have_methods = 1; + methodnames << realname << " "; + + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->usage << usage_string(realname,t,l); + } + } +} + +void TCL8::cpp_variable(char *name, char *iname, DataType *t) { + char *realname; + String temp; + char *rname; + + this->Language::cpp_variable(name, iname, t); + + if (shadow) { + if (iname) + realname = iname; + else + realname = name; + + char *bc = class_name; + + // Write config code + + if (!(Status & STAT_READONLY)) { + if (!have_config) { + config << tab8 << tab8; + } else { + config << " else "; + } + + // Try to figure out if there is already a wrapper for this + + temp = ""; + temp << name_set(name_member(realname,bc)); + rname = (char *) repeatcmd.lookup(temp); + if (!rname) + rname = name_wrapper(temp.get(),prefix); + + config << "if (strcmp(_str,\"-" << realname << "\") == 0) {\n" + << tab8 << tab8 << tab4 << "cmd = " << rname << ";\n" + << tab8 << tab8 << "} "; + + have_config = 1; + } + + // Write cget code + + if (!have_cget) { + cget << tab8 << tab8; + } else { + cget << " else "; + } + + + // Try to figure out if there is a wrapper for this function + temp = ""; + temp << name_get(name_member(realname,bc)); + rname = (char *) repeatcmd.lookup(temp); + if (!rname) + rname = name_wrapper(temp.get(),prefix); + + cget << "if (strcmp(_str,\"-" << realname << "\") == 0) {\n" + << tab8 << tab8 << tab4 << "cmd = " << rname << ";\n" + << tab8 << tab8 << "} "; + have_cget = 1; + + options << "-" << realname << " "; + if (!(Status & STAT_READONLY)) { + config_options << "-" << realname << " "; + } + if (doc_entry){ + doc_entry->usage = ""; + doc_entry->usage << "-" << realname << "\n"; + } + } +} + +void TCL8::cpp_constructor(char *name, char *iname, ParmList *l) { + this->Language::cpp_constructor(name,iname,l); + + if (shadow) { + if ((!have_constructor) && (doc_entry)) { + doc_entry->usage = ""; + doc_entry->usage << class_name << usage_string(" name",0,l); + } + have_constructor = 1; + } +} +void TCL8::cpp_destructor(char *name, char *newname) { + this->Language::cpp_destructor(name,newname); + if (shadow) { + if (!have_destructor) { + if (doc_entry) { + doc_entry->usage = "rename obj {}"; + } + } + have_destructor = 1; + } +} + +void TCL8::cpp_inherit(char **baseclass, int) { + this->Language::cpp_inherit(baseclass); +} + +void TCL8::cpp_declare_const(char *name, char *iname, DataType *type, char *value) { + this->Language::cpp_declare_const(name,iname,type,value); +} + +// -------------------------------------------------------------------------------- +// TCL8::add_typedef(DataType *t, char *name) +// +// This is called whenever a typedef is encountered. When shadow classes are +// used, this function lets us discovered hidden uses of a class. For example : +// +// struct FooBar { +// ... +// } +// +// typedef FooBar *FooBarPtr; +// +// -------------------------------------------------------------------------------- + +void TCL8::add_typedef(DataType *t, char *name) { + + if (!shadow) return; + + // First check to see if there aren't too many pointers + + if (t->is_pointer > 1) return; + if (hash.lookup(name)) return; // Already added + + // Now look up the datatype in our shadow class hash table + + if (hash.lookup(t->name)) { + + // Yep. This datatype is in the hash + // Put this types 'new' name into the hash + hash.add(name,copy_string((char *) hash.lookup(t->name))); + } +} + +// ----------------------------------------------------------------------- +// TCL8::cpp_class_decl(char *name, char *rename, char *type) +// +// Treatment of an empty class definition. Used to handle +// shadow classes across modules. +// ----------------------------------------------------------------------- + +void TCL8::cpp_class_decl(char *name, char *rename, char *type) { + char temp[256]; + this->Language::cpp_class_decl(name,rename, type); + + if (shadow) { + hash.add(name,copy_string(rename)); + // Add full name of datatype to the hash table + if (strlen(type) > 0) { + sprintf(temp,"%s %s", type, name); + hash.add(temp,copy_string(rename)); + } + } +} diff --git a/wxPython/wxSWIG/Modules/tcl8.h b/wxPython/wxSWIG/Modules/tcl8.h new file mode 100644 index 0000000000..962b866406 --- /dev/null +++ b/wxPython/wxSWIG/Modules/tcl8.h @@ -0,0 +1,115 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/************************************************************************** + * class TCL8 + * + * A TCL implementation for Tcl 8.0. Basically the same as the other + * Tcl module, but with different code generation. + **************************************************************************/ + +class TCL8 : public Language { +private: + char interp_name[256]; + char *prefix; // Package prefix + char *module; // Name of the module + char *tcl_path; + char *init_name; + int nspace; + void get_pointer(char *iname, char *srcname, char *src, char *dest, DataType *t, + String &f, char *ret); + char *char_result; + char *usage_func(char *, DataType *, ParmList *); + char *usage_string(char *, DataType *, ParmList *); + char *usage_var(char *, DataType *); + char *usage_const(char *, DataType *, char *); + + // C++ handling + + int have_constructor; + int have_destructor; + int have_methods; + int have_config; + int have_cget; + String config; + String cget; + String methods; + String options; + String config_options; + String methodnames; + String postinit; + int shadow; + char *class_name; + char *class_type; + char *real_classname; + char *base_class; + Hash hash; + Hash repeatcmd; + + // Code generation options + + String delcmd; + String methodcmd; + String objcmd; + +public : + TCL8() { + prefix = 0; + module = 0; + init_name = 0; + nspace = 0; + shadow = 1; + char_result = "TCL_VOLATILE"; + tcl_path = "tcl"; + sprintf(interp_name,"interp"); + class_name = 0; + class_type = 0; + real_classname = 0; + base_class = 0; + }; + void parse_args(int, char *argv[]); + void parse(); + void create_function(char *, char *, DataType *, ParmList *); + void link_variable(char *, char *, DataType *); + void declare_const(char *, char *, DataType *, char *); + void initialize(void); + void headers(void); + void close(void); + void set_module(char *,char **); + void set_init(char *); + void add_native(char *, char *); + void pragma(char *,char *, char *); + void create_command(char *, char *); + + // Stubs for processing C++ classes in Tcl + + void cpp_open_class(char *classname, char *rename, char *ctype, int strip); + void cpp_close_class(); + void cpp_member_func(char *name, char *iname, DataType *t, ParmList *l); + void cpp_variable(char *name, char *iname, DataType *t); + void cpp_constructor(char *name, char *iname, ParmList *l); + void cpp_destructor(char *name, char *newname); + void cpp_inherit(char **baseclass, int mode = INHERIT_ALL); + void cpp_declare_const(char *name, char *iname, DataType *type, char *value); + void add_typedef(DataType *, char *); + void cpp_class_decl(char *, char *, char *); + +}; + + + + + + diff --git a/wxPython/wxSWIG/Modules/wrap.h b/wxPython/wxSWIG/Modules/wrap.h new file mode 100644 index 0000000000..9730c3293a --- /dev/null +++ b/wxPython/wxSWIG/Modules/wrap.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ +/*********************************************************************** + * $Header$ + * + * wrap.h + ***********************************************************************/ + +#include "swig.h" + +#ifndef SWIG_LIB +#define SWIG_LIB getSwigLib() /*"./swig_lib"*/ +#endif + +#ifndef SWIG_LANG +#define SWIG_LANG PYTHON +#endif + +#ifndef SWIG_DOC +#define SWIG_DOC ASCII +#endif + + + + + diff --git a/wxPython/wxSWIG/README b/wxPython/wxSWIG/README new file mode 100644 index 0000000000..c0641e3dd1 --- /dev/null +++ b/wxPython/wxSWIG/README @@ -0,0 +1,381 @@ +SWIG (Simplified Wrapper and Interface Generator) +Version 1.1 (Maintenance) + +Copyright (C) 1995-1999 +University of Utah and the Regents of the University of California + +August 8, 1999 + +1. Introduction +--------------- +SWIG is a compiler that attempts to make it easy to integrate C, C++, +or Objective-C code with scripting languages including Perl, Tcl, and +Python. In a nutshell, you give it a bunch of ANSI C/C++ declarations +and it generates an interface between C and your favorite scripting +language. However, this is only scratching the surface of what SWIG +can do--some of its more advanced features include automatic +documentation generation, module and library management, extensive +customization options, and more. + +SWIG is entirely the product of users who have used the system and +suggested new ideas. There are far too many people to thank +individually, but without this support, SWIG would be not be nearly as +powerful or fun to use as it is now. Many thanks! + +2. Currently Supported Languages +---------------------------------- + +To use SWIG, you will need at least one of the following scripting +languages : + + Tcl7.3, Tk3.6 (and all newer versions) + Tcl8.0, Tk8.0 (somewhat experimental) + Python1.3 (or newer) + Perl5.003 (or newer) + Perl4 + FSF Guile 1.0 (experimental) + +If you don't have any of these, SWIG will still compile, but it won't +be particularly useful. Note : it is not necessary to have *all* of +these languages installed to use SWIG--only the scripting languages you +want to use. + +3. Installation (Unix) +------------------------ + +To compile and use SWIG, you will need the following on your machine: + + A C++ compiler (ie. g++) + An ANSI C compiler (ie. gcc) + yacc or bison (only needed if you are going to rebuild the SWIG parser) + +To compile and install SWIG, type the following : + + ./configure + make + make runtime (optional. see below) + make install + +The configuration script will attempt to locate various packages on +your machine, including Tcl, Perl5, and Python. Don't panic if +you get 'not found' messages--SWIG does not need these packages +to compile or run. The configure script is actually looking for +these packages so that you can try out the SWIG examples contained +in the 'Examples' directory without having to hack Makefiles. +See the Examples section below for more details. + +The 'make runtime' option is an optional step that can be used to +build the SWIG runtime libraries. These libraries are only used with +larger packages and are not necessary for learning SWIG or trying +the examples (please refer to the "Advanced topics" section of the +SWIG Users manual for more details about this). + +Typing 'make test' will run a rather extensive series of tests +and can be run before running 'make install' (if you are paranoid). + +There are a number of configuration options that you can give to +'configure' : + + --prefix=/usr/local + + Set the installation prefix. SWIG installs into + /usr/local by default. + + --exec_prefix=/usr/local + + Set the prefix used to install platform specific + files (binaries and libraries). Use this if the + location is different than that given with --prefix. + + --with-lang={TCL,TCL8,PYTHON,PERL5,PERL4,GUILE} + + This lets you choose the default SWIG target language. + By default, SWIG chooses TCL, but you can select + another as shown : + + ./configure --with-lang=PYTHON + + --with-doc={ASCII,LATEX,HTML,NODOC} + + This lets you choose the default SWIG documentation + method. By default, SWIG chooses ASCII. + + +4. Site specific installation +------------------------------- + +While not required for compiling SWIG, the configuration script looks +for various packages in order to create a makefile for compiling the +examples. This makefile is also installed with the SWIG package. +The following configuration options can be used to set the location +of various packages. + +--with-tcl=pathname - Set root directory of Tcl installation. + SWIG will use $pathname/include and + $pathname/lib. + +--with-tclincl=pathname - Set exact location of Tcl include files + +--with-tcllib=pathname - Set exact location of Tcl library files + +--with-itcl=pathname - Same as above but for [incr Tcl] + +--with-itclincl=pathname - Location of [incr Tcl] include files + +--with-itcllib=pathname - Location of [incr Tcl] libraries + +--with-py=pathname - Set package location of Python. This is usually + something like /usr/local. configure will attempt + to locate the appropriate include and library files. + +--with-pyincl=pathname - Set location of Python include files + (for example, /usr/local/include) + +--with-pylib=pathname - Set location of Python library files + (for example, /usr/local/lib) + +--with-perl5=executable - Specify your perl5 executable. SWIG will figure + out where files are by running this version of + Perl and grabbing its configuration data. + + +Other options : + +--without-yacc - Try to compile SWIG using a pregenerated YACC + file generated by Berkeley YACC (byacc). Only recommended + if you get compiler errors when trying to compile parser.y + or parser.cxx. + +Changing the C++ compiler: + +By default, SWIG will look for g++. You can change the C++ compile as follows : + + env CXX=CC configure --prefix=/usr/local ... etc... + + or + + setenv CXX=CC + ./configure ... etc ... + +SWIG has been successfully compiled and tested under g++, the SGI C++ +compiler, and the SunPro C++ compiler. + +5. Testing +----------- +The SWIG parser and language modules can be tested by typing 'make test'. +Be forewarned, this runs a large collection of tests on all of SWIG's +language modules and documentation methods. The tests may take 5-10 +minutes to run, but a report of errors will be written to 'test.log'. +If this exists, it will contain error messages for failed tests. If +the file is missing, it means all tests were considered successful. + +The testing process requires approximately 30-40 Mbytes of disk space. +After testing, you may wish to type 'make testclean' which will +return the testing directory to its original state. + +Note : The testing procedure requires both 'sh' and 'perl'. If you +don't have these installed, some of the tests won't work. + +6. Installation for Windows 95 and NT +------------------------------------- + +The Win directory contains makefiles for Microsoft Visual C++ 4.x/5.x and +Borland C++. See the README.txt file in the Win directory for specific +build instructions. Many thanks to Kevin Butler (butler@cs.byu.edu) +and Pier Giorgio Esposito for supplying these Makefiles. + +7. Installation for Macintosh +----------------------------- + +A Macintosh version of SWIG is available separately as a PowerPC +executable. A source version is also available, but is somewhat +complicated to build due to dependencies on other packages +including Tcl 8.0. Please refer to the SWIG homepage for more +information. + +8. Examples +------------ + +The 'Examples' directory contains examples for all of the supported +scripting languages. All of the examples rely on the file +'Makefile.template' located in the top-level directory. This makefile +is created by 'configure', but the configuration process is not +foolproof. To check this Makefile type + + make testbuild + +This will attempt to build various kinds of extensions and report its +success or failure. If this fails, you may need to edit the file +'Makefile.template' by hand. This usually isn't difficult--just +follow the instructions contained within the file. Once the 'make +testbuild' works for the language you are interested in using, you +should be able to build the examples. + +The examples will not compile properly if you have not installed SWIG. +If you would like to try the examples before installation, set the +SWIG_LIB environment variable as follows : + + setenv SWIG_LIB ${pathname}/SWIG1.1/swig_lib + +Where ${pathname} the location of the SWIG source. + +*** NOTE *** If you are replacing an older version of SWIG with a new +one, the examples may not compile correctly unless you set the +above environment variable or do a 'make install' first. + +9. Resources +-------------- + +Up-to-date SWIG related information can be found at + + http://www.swig.org + +SWIG source code and software updates are also available via anonymous +ftp at + + ftp://ftp.swig.org + + +You can join the SWIG mailing list by going to the following location: + + http://www.cs.uchicago.edu/mailman/listinfo/swig + +The SWIG mailing list is a forum for discussing various applications +of SWIG, installation problems, ideas for system improvements and +future work. + +*** NEWSFLASH *** SWIG development has moved to the Univerity of +Chicago. Developer information can be found at + + http://swig.cs.uchicago.edu + +10. Installation Problems +------------------------- + +As far as I know the installation works on the following platforms : + + - SunOS 4.1.3 + - Solaris + - Irix 5.3 + - Irix 6.2 + - HPUX + - AIX 4.1 + - Linux + - MkLinux + - MachTen + - UNICOS + - Windows 95 + - Windows NT 4.0 + - MacOS System 7.5.3 + +SWIG development takes place primarily on Linux and Solaris 2.6. I've +tested most of the examples on these platforms. I have also tested +SWIG under Win95 and MacOS, but that is still somewhat experimental. + +If you've tried everything and can't get SWIG to compile, please send +me e-mail at beazley@cs.uchicago.edu, and we'll try to figure it out. +I try to answer all e-mail that I receive. However, occasionally I +receive messages with bad return addresses and can't respond. If you +don't hear back within a few days, try sending a message to +'swig@cs.uchicago.edu'. + +11. Documentation +----------------- + +Over 300 pages of documentation describing almost every aspect of SWIG +is available in the Doc directory. Don't let the amount of +documentation scare you--SWIG is easy enough to use that you can +probably start using it by only looking at a few simple examples. +However, at some point you will probably want to know more so I hope +that the manual will come in useful. Besides, I hate black boxes... + +The documentation is distributed in Adobe PDF format and can be viewed +using the Adobe Acrobat Reader. Acrobat is available for virtually +all machines and can be freely obtained from Adobe at www.adobe.com. +Postscript and HTML versions of the manual are also available from the +SWIG FTP site. + +12. Incompatibilities +--------------------- + +This release should be mostly compatible with SWIG 1.0 +(Final). However, the SWIG documentation system has been completely +rewritten and the C API has been changed greatly. It is unlikely that +any custom SWIG language modules written in C++ for 1.0 will work with +1.1. While porting to 1.1 is not that difficult, there are a number +of important changes. See the file 'Doc/Porting' for a list of +changes to the C++ API and how to convert an older SWIG module to work +with 1.1. + +13. Bug Reports +---------------- + +Bug reports should be submitted to the online bug-tracking system +which is available at : + + http://swig.cs.uchicago.edu/cgi-bin/swig + +Before submitting a bug, please check this site to see if it has +already been reported. If not, provide as much information as +possible including the SWIG version number, operating system, and +compiler being used. Note : I tend to fix bugs in batches and may +only respond to a bug report when it has actually been fixed---posting +to the mailing list is often a better way to get an immediate response +to a problem. + +14. Legal Stuff +--------------- +SWIG is completely free and non-proprietary. You can do whatever you +want with it (including distribution), provided that you follow these +rules, 1) Keep all of the copyright notices intact, 2) don't claim +that you wrote it, and 3) Don't sue anyone if it breaks. Otherwise, +have fun. + +15. Disclaimer +---------------- + +While I believe that SWIG is reasonably stable, I'm always tinkering +with it and trying to make it better. There may be a few bugs hiding +around so if you experience any problems let me know. If you think +that SWIG is missing some capability that would be useful to have +have, post a message on the SWIG mailing list. Most of the previous +suggestions have already been incorporated into this release. + +16. Acknowledgments +--------------------- + +SWIG would not be possible without the contributions of people who +tried out the beta versions and offered feedback and bug reports. +While there are far too many people to list at point, I'd like to +especially acknowledge the following individuals and organizations +for supporting SWIG and making major contributions : + +David Ascher, Erik Bierwagen, Kurtis Bleeker, John Buckman, Kevin +Butler, Pier Giorgio Esposito, David Fletcher, Mark Hammond, Mark +Harrison, Brad Holian, Gary Holt, Chris Johnson, Peter Lomdahl, Mark +Lutz, Chris Myers, Paul Saxe, John Schmidt, Tom Schwaller, Peter-Pike +Sloan, Patrick Tullmann, Larry Virden, Tser-Yuan Yang, Shujia Zhou. + +and + +Los Alamos National Laboratory +Lawrence Livermore National Laboratory +Cornell Theory Center +University of Utah +The Scientific Computing and Imaging Group (University of Utah) + +(My apologies to anyone I missed...) + +If you find SWIG to be useful, I'd like to know about it. + +Enjoy! + +Dave Beazley +Department of Computer Science +University of Chicago +Chicago, IL 60637 +beazley@cs.uchicago.edu + + + + diff --git a/wxPython/wxSWIG/README.1st b/wxPython/wxSWIG/README.1st new file mode 100644 index 0000000000..250f64e7fe --- /dev/null +++ b/wxPython/wxSWIG/README.1st @@ -0,0 +1,19 @@ + +This directory contains a copy of SWIG 1.1p5-883 that has been heavily +patched to do some things specific for wxPython. You do not need to +build this version of SWIG if you do not plan on making any changes to +wxPython's *.i files. However, if you set USE_SWIG=1 in setup.py then +you *will* need to build this version of SWIG. To do so, just run: + + Unix: + configure + make + + Win32: + nmake -f makefile.vc + +The executable created *does not* need to be installed as wxPython's +setup.py expects to find it here in this directory. Also, the name of +the executable has been renamed to wxswig to simplify having both +versions of SWIG on the system. + diff --git a/wxPython/wxSWIG/Runtime/Makefile b/wxPython/wxSWIG/Runtime/Makefile new file mode 100644 index 0000000000..17f6489827 --- /dev/null +++ b/wxPython/wxSWIG/Runtime/Makefile @@ -0,0 +1,131 @@ +# Generated automatically from Makefile.in by configure. +# Makefile for producing SWIG runtime libraries. +# +# The SWIG runtime library consists of the pointer-type checker +# and other support functions. Multi-file SWIG modules +# generally link with these libraries. +# +# By default, the installation processs will attempt to +# build shared libraries. If that doesn't work, a static +# library is built instead. + +prefix = /usr/local +exec_prefix = ${prefix} +CC = cc +AR = ar +RANLIB = ranlib +SO = .so +CCSHARED = +LDSHARED = ld -G +DYN_LIBS = libswigtcl8$(SO) libswigtcl$(SO) libswigpl$(SO) libswigpy$(SO) +STATIC_LIBS = libswigtcl8.a libswigtcl.a libswigpl.a libswigpy.a +LIBS = $(STATIC_LIBS) $(DYN_LIBS) +LIB_DIR = $(exec_prefix)/lib + +INSTALL_DATA = ../install-sh -c -m 644 +INSTALL_SHLB = ../install-sh -c -m 555 + +all: + @sh make.sh + + +install: + @echo "Installing runtime libraries" + @for i in $(STATIC_LIBS); \ + do \ + if [ -f $$i ]; then \ + echo "Installing $$i in $(LIB_DIR)/$$i"; \ + $(INSTALL_DATA) $$i $(LIB_DIR)/$$i; \ + fi; \ + done; + @for i in $(DYN_LIBS); \ + do \ + if [ -f $$i ]; then \ + echo "Installing $$i in $(LIB_DIR)/$$i"; \ + $(INSTALL_SHLB) $$i $(LIB_DIR)/$$i; \ + fi; \ + done; + + +clean:: + rm -rf *.o *.a *$(SO) *.c *.swg *~ core + +# ---------------------------------------------------------------------- +# Tcl runtime library +# ---------------------------------------------------------------------- + +TCL_INCLUDE = -I/usr/local/include +TCL_LIB = -L/usr/local/lib + +# Tcl 7.x shared + +tcl_shared: + ../swig -tcl -co -o libtcl.c -I../swig_lib swigtcl.swg + $(CC) $(CCSHARED) -c -DSWIG_GLOBAL libtcl.c + $(LDSHARED) libtcl.o -o libswigtcl$(SO) + +# Tcl 7.x library + +tcl_lib: + ../swig -tcl -co -o libtcl.c -I../swig_lib swigtcl.swg + $(CC) -c -DSWIG_GLOBAL libtcl.c + $(AR) cr libswigtcl.a libtcl.o + +# Tcl 8.x shared + +tcl8_shared: + ../swig -tcl -co -o libtcl8.c -I../swig_lib swigtcl8.swg + $(CC) $(CCSHARED) -c -DSWIG_GLOBAL $(TCL_INCLUDE) libtcl8.c + $(LDSHARED) libtcl8.o -o libswigtcl8$(SO) + +tcl8_lib: + ../swig -tcl -co -o libtcl8.c -I../swig_lib swigtcl8.swg + $(CC) -c -DSWIG_GLOBAL $(TCL_INCLUDE) libtcl8.c + $(AR) cr libswigtcl8.a libtcl8.o + +# ---------------------------------------------------------------------- +# Python run-time library +# ---------------------------------------------------------------------- + +PYTHON_INCLUDE= -DHAVE_CONFIG_H -I/usr/local/include/python1.5 -I/usr/local/lib/python1.5/config +PYTHON_LIB = /usr/local/lib/python1.5/config + +# Python shared + +py_shared: + ../swig -python -co -o libpy.c -I../swig_lib python.swg + $(CC) $(CCSHARED) -c -DSWIG_RUNTIME -DSWIG_GLOBAL $(PYTHON_INCLUDE) libpy.c + $(LDSHARED) libpy.o -o libswigpy$(SO) + +# Python library + +py_lib: + ../swig -python -co -o libpy.c -I../swig_lib python.swg + $(CC) -c -DSWIG_RUNTIME -DSWIG_GLOBAL $(PYTHON_INCLUDE) libpy.c + $(AR) cr libswigpy.a libpy.o + +# ---------------------------------------------------------------------- +# Perl run-time library +# ---------------------------------------------------------------------- + +PERL5_INCLUDE= -I/usr/local/lib/perl5/5.00503/sun4-solaris/CORE + +# Perl shared + +perl_shared: + rm -f libperl.c libperl.swg + ../swig -perl5 -co -o libperl.swg -I../swig_lib perl5.swg + cat perlrun.h >> libperl.c + cat libperl.swg >> libperl.c + $(CC) $(CCSHARED) -c -Dexplicit= -Dbool=char -DSWIG_GLOBAL $(PERL5_INCLUDE) libperl.c + $(LDSHARED) libperl.o -o libswigpl$(SO) + +# Perl library + +perl_lib: + rm -f libperl.c libperl.swg + ../swig -perl5 -co -o libperl.swg -I../swig_lib perl5.swg + cat perlrun.h >> libperl.c + cat libperl.swg >> libperl.c + $(CC) -c -Dexplicit= -Dbool=char -DSWIG_GLOBAL $(PERL5_INCLUDE) libperl.c + $(AR) cr libswigpl.a libperl.o diff --git a/wxPython/wxSWIG/Runtime/Makefile.in b/wxPython/wxSWIG/Runtime/Makefile.in new file mode 100644 index 0000000000..45c7207bc8 --- /dev/null +++ b/wxPython/wxSWIG/Runtime/Makefile.in @@ -0,0 +1,130 @@ +# Makefile for producing SWIG runtime libraries. +# +# The SWIG runtime library consists of the pointer-type checker +# and other support functions. Multi-file SWIG modules +# generally link with these libraries. +# +# By default, the installation processs will attempt to +# build shared libraries. If that doesn't work, a static +# library is built instead. + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +CC = @CC@ +AR = @AR@ +RANLIB = @RANLIB@ +SO = @SO@ +CCSHARED = @CCSHARED@ +LDSHARED = @LDSHARED@ +DYN_LIBS = libswigtcl8$(SO) libswigtcl$(SO) libswigpl$(SO) libswigpy$(SO) +STATIC_LIBS = libswigtcl8.a libswigtcl.a libswigpl.a libswigpy.a +LIBS = $(STATIC_LIBS) $(DYN_LIBS) +LIB_DIR = $(exec_prefix)/lib + +INSTALL_DATA = ../install-sh -c -m 644 +INSTALL_SHLB = ../install-sh -c -m 555 + +all: + @sh make.sh + + +install: + @echo "Installing runtime libraries" + @for i in $(STATIC_LIBS); \ + do \ + if [ -f $$i ]; then \ + echo "Installing $$i in $(LIB_DIR)/$$i"; \ + $(INSTALL_DATA) $$i $(LIB_DIR)/$$i; \ + fi; \ + done; + @for i in $(DYN_LIBS); \ + do \ + if [ -f $$i ]; then \ + echo "Installing $$i in $(LIB_DIR)/$$i"; \ + $(INSTALL_SHLB) $$i $(LIB_DIR)/$$i; \ + fi; \ + done; + + +clean:: + rm -rf *.o *.a *$(SO) *.c *.swg *~ core + +# ---------------------------------------------------------------------- +# Tcl runtime library +# ---------------------------------------------------------------------- + +TCL_INCLUDE = @TCLINCLUDE@ +TCL_LIB = @TCLLIB@ + +# Tcl 7.x shared + +tcl_shared: + ../swig -tcl -co -o libtcl.c -I../swig_lib swigtcl.swg + $(CC) $(CCSHARED) -c -DSWIG_GLOBAL libtcl.c + $(LDSHARED) libtcl.o -o libswigtcl$(SO) + +# Tcl 7.x library + +tcl_lib: + ../swig -tcl -co -o libtcl.c -I../swig_lib swigtcl.swg + $(CC) -c -DSWIG_GLOBAL libtcl.c + $(AR) cr libswigtcl.a libtcl.o + +# Tcl 8.x shared + +tcl8_shared: + ../swig -tcl -co -o libtcl8.c -I../swig_lib swigtcl8.swg + $(CC) $(CCSHARED) -c -DSWIG_GLOBAL $(TCL_INCLUDE) libtcl8.c + $(LDSHARED) libtcl8.o -o libswigtcl8$(SO) + +tcl8_lib: + ../swig -tcl -co -o libtcl8.c -I../swig_lib swigtcl8.swg + $(CC) -c -DSWIG_GLOBAL $(TCL_INCLUDE) libtcl8.c + $(AR) cr libswigtcl8.a libtcl8.o + +# ---------------------------------------------------------------------- +# Python run-time library +# ---------------------------------------------------------------------- + +PYTHON_INCLUDE= -DHAVE_CONFIG_H @PYINCLUDE@ +PYTHON_LIB = @PYLIB@ + +# Python shared + +py_shared: + ../swig -python -co -o libpy.c -I../swig_lib python.swg + $(CC) $(CCSHARED) -c -DSWIG_RUNTIME -DSWIG_GLOBAL $(PYTHON_INCLUDE) libpy.c + $(LDSHARED) libpy.o -o libswigpy$(SO) + +# Python library + +py_lib: + ../swig -python -co -o libpy.c -I../swig_lib python.swg + $(CC) -c -DSWIG_RUNTIME -DSWIG_GLOBAL $(PYTHON_INCLUDE) libpy.c + $(AR) cr libswigpy.a libpy.o + +# ---------------------------------------------------------------------- +# Perl run-time library +# ---------------------------------------------------------------------- + +PERL5_INCLUDE= -I@PERL5EXT@ + +# Perl shared + +perl_shared: + rm -f libperl.c libperl.swg + ../swig -perl5 -co -o libperl.swg -I../swig_lib perl5.swg + cat perlrun.h >> libperl.c + cat libperl.swg >> libperl.c + $(CC) $(CCSHARED) -c -Dexplicit= -Dbool=char -DSWIG_GLOBAL $(PERL5_INCLUDE) libperl.c + $(LDSHARED) libperl.o -o libswigpl$(SO) + +# Perl library + +perl_lib: + rm -f libperl.c libperl.swg + ../swig -perl5 -co -o libperl.swg -I../swig_lib perl5.swg + cat perlrun.h >> libperl.c + cat libperl.swg >> libperl.c + $(CC) -c -Dexplicit= -Dbool=char -DSWIG_GLOBAL $(PERL5_INCLUDE) libperl.c + $(AR) cr libswigpl.a libperl.o diff --git a/wxPython/wxSWIG/Runtime/libperl.c b/wxPython/wxSWIG/Runtime/libperl.c new file mode 100644 index 0000000000..ca2132cf10 --- /dev/null +++ b/wxPython/wxSWIG/Runtime/libperl.c @@ -0,0 +1,364 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +/* Definitions for compiling Perl extensions on a variety of machines */ + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# if defined(_MSC_VER) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# if defined(__BORLANDC__) +# define SWIGEXPORT(a) a _export +# else +# define SWIGEXPORT(a) a +# endif +# endif +#else +# define SWIGEXPORT(a) a +#endif + +#ifdef PERL_OBJECT +#define MAGIC_PPERL CPerlObj *pPerl = (CPerlObj *) this; +#define MAGIC_CAST (int (CPerlObj::*)(SV *, MAGIC *)) +#define SWIGCLASS_STATIC +#else +#define MAGIC_PPERL +#define MAGIC_CAST +#define SWIGCLASS_STATIC static +#endif + +#if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE) +#define PerlIO_exportFILE(fh,fl) (FILE*)(fh) +#endif + +/* Modifications for newer Perl 5.005 releases */ + +#if !defined(PERL_REVISION) || ((PERL_REVISION >= 5) && ((PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION < 50)))) +#ifndef PL_sv_yes +#define PL_sv_yes sv_yes +#endif +#ifndef PL_sv_undef +#define PL_sv_undef sv_undef +#endif +#ifndef PL_na +#define PL_na na +#endif +#endif + +/****************************************************************************** + * Pointer type-checking code + *****************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SWIG_NOINCLUDE +extern void SWIG_MakePtr(char *, void *, char *); +#ifndef PERL_OBJECT +extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); +#else +#define SWIG_RegisterMapping(a,b,c) _SWIG_RegisterMapping(pPerl,a,b,c); +extern void _SWIG_RegisterMapping(CPerlObj *,char *, char *, void *(*)(void *),int); +#endif +#ifndef PERL_OBJECT +extern char *SWIG_GetPtr(SV *, void **, char *); +#else +extern char *_SWIG_GetPtr(CPerlObj *, SV *, void **, char *); +#define SWIG_GetPtr(a,b,c) _SWIG_GetPtr(pPerl,a,b,c) +#endif + +#else + +#ifdef SWIG_GLOBAL +#define SWIGSTATICRUNTIME(a) SWIGEXPORT(a) +#else +#define SWIGSTATICRUNTIME(a) static a +#endif + +/* These are internal variables. Should be static */ + +typedef struct SwigPtrType { + char *name; + int len; + void *(*cast)(void *); + struct SwigPtrType *next; +} SwigPtrType; + +/* Pointer cache structure */ + +typedef struct { + int stat; /* Status (valid) bit */ + SwigPtrType *tp; /* Pointer to type structure */ + char name[256]; /* Given datatype name */ + char mapped[256]; /* Equivalent name */ +} SwigCacheType; + +static int SwigPtrMax = 64; /* Max entries that can be currently held */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ +static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ +static int SwigStart[256]; /* Table containing starting positions */ + +/* Cached values */ + +#define SWIG_CACHESIZE 8 +#define SWIG_CACHEMASK 0x7 +static SwigCacheType SwigCache[SWIG_CACHESIZE]; +static int SwigCacheIndex = 0; +static int SwigLastCache = 0; + +/* Sort comparison function */ +static int swigsort(const void *data1, const void *data2) { + SwigPtrType *d1 = (SwigPtrType *) data1; + SwigPtrType *d2 = (SwigPtrType *) data2; + return strcmp(d1->name,d2->name); +} + +/* Binary Search function */ +static int swigcmp(const void *key, const void *data) { + char *k = (char *) key; + SwigPtrType *d = (SwigPtrType *) data; + return strncmp(k,d->name,d->len); +} + +/* Register a new datatype with the type-checker */ + +#ifndef PERL_OBJECT +SWIGSTATICRUNTIME(void) +SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { +#else +#define SWIG_RegisterMapping(a,b,c) _SWIG_RegisterMapping(pPerl, a,b,c) +SWIGSTATICRUNTIME(void) +_SWIG_RegisterMapping(CPerlObj *pPerl, char *origtype, char *newtype, void *(*cast)(void *)) { +#endif + + int i; + SwigPtrType *t = 0, *t1; + + if (!SwigPtrTable) { + SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); + SwigPtrN = 0; + } + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTable = (SwigPtrType *) realloc(SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); + } + for (i = 0; i < SwigPtrN; i++) + if (strcmp(SwigPtrTable[i].name,origtype) == 0) { + t = &SwigPtrTable[i]; + break; + } + if (!t) { + t = &SwigPtrTable[SwigPtrN]; + t->name = origtype; + t->len = strlen(t->name); + t->cast = 0; + t->next = 0; + SwigPtrN++; + } + while (t->next) { + if (strcmp(t->name,newtype) == 0) { + if (cast) t->cast = cast; + return; + } + t = t->next; + } + t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + t1->name = newtype; + t1->len = strlen(t1->name); + t1->cast = cast; + t1->next = 0; + t->next = t1; + SwigPtrSort = 0; +} + +/* Make a pointer value string */ + +SWIGSTATICRUNTIME(void) +SWIG_MakePtr(char *_c, const void *_ptr, char *type) { + static char _hex[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + unsigned long _p, _s; + char _result[20], *_r; /* Note : a 64-bit hex number = 16 digits */ + _r = _result; + _p = (unsigned long) _ptr; + if (_p > 0) { + while (_p > 0) { + _s = _p & 0xf; + *(_r++) = _hex[_s]; + _p = _p >> 4; + } + *_r = '_'; + while (_r >= _result) + *(_c++) = *(_r--); + } else { + strcpy (_c, "NULL"); + } + if (_ptr) + strcpy (_c, type); +} + +/* Function for getting a pointer value */ + +#ifndef PERL_OBJECT +SWIGSTATICRUNTIME(char *) +SWIG_GetPtr(SV *sv, void **ptr, char *_t) +#else +#define SWIG_GetPtr(a,b,c) _SWIG_GetPtr(pPerl,a,b,c) +SWIGSTATICRUNTIME(char *) +_SWIG_GetPtr(CPerlObj *pPerl, SV *sv, void **ptr, char *_t) +#endif +{ + char temp_type[256]; + char *name,*_c; + int len,i,start,end; + IV tmp; + SwigPtrType *sp,*tp; + SwigCacheType *cache; + + /* If magical, apply more magic */ + + if (SvGMAGICAL(sv)) + mg_get(sv); + + /* Check to see if this is an object */ + if (sv_isobject(sv)) { + SV *tsv = (SV*) SvRV(sv); + if ((SvTYPE(tsv) == SVt_PVHV)) { + MAGIC *mg; + if (SvMAGICAL(tsv)) { + mg = mg_find(tsv,'P'); + if (mg) { + SV *rsv = mg->mg_obj; + if (sv_isobject(rsv)) { + tmp = SvIV((SV*)SvRV(rsv)); + } + } + } else { + return "Not a valid pointer value"; + } + } else { + tmp = SvIV((SV*)SvRV(sv)); + } + if (!_t) { + *(ptr) = (void *) tmp; + return (char *) 0; + } + } else if (! SvOK(sv)) { /* Check for undef */ + *(ptr) = (void *) 0; + return (char *) 0; + } else if (SvTYPE(sv) == SVt_RV) { /* Check for NULL pointer */ + *(ptr) = (void *) 0; + if (!SvROK(sv)) + return (char *) 0; + else + return "Not a valid pointer value"; + } else { /* Don't know what it is */ + *(ptr) = (void *) 0; + return "Not a valid pointer value"; + } + if (_t) { + /* Now see if the types match */ + + if (!sv_isa(sv,_t)) { + _c = HvNAME(SvSTASH(SvRV(sv))); + if (!SwigPtrSort) { + qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); + for (i = 0; i < 256; i++) { + SwigStart[i] = SwigPtrN; + } + for (i = SwigPtrN-1; i >= 0; i--) { + SwigStart[SwigPtrTable[i].name[0]] = i; + } + for (i = 255; i >= 1; i--) { + if (SwigStart[i-1] > SwigStart[i]) + SwigStart[i-1] = SwigStart[i]; + } + SwigPtrSort = 1; + for (i = 0; i < SWIG_CACHESIZE; i++) + SwigCache[i].stat = 0; + } + /* First check cache for matches. Uses last cache value as starting point */ + cache = &SwigCache[SwigLastCache]; + for (i = 0; i < SWIG_CACHESIZE; i++) { + if (cache->stat) { + if (strcmp(_t,cache->name) == 0) { + if (strcmp(_c,cache->mapped) == 0) { + cache->stat++; + *ptr = (void *) tmp; + if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); + return (char *) 0; + } + } + } + SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; + if (!SwigLastCache) cache = SwigCache; + else cache++; + } + + start = SwigStart[_t[0]]; + end = SwigStart[_t[0]+1]; + sp = &SwigPtrTable[start]; + while (start < end) { + if (swigcmp(_t,sp) == 0) break; + sp++; + start++; + } + if (start > end) sp = 0; + while (start <= end) { + if (swigcmp(_t,sp) == 0) { + name = sp->name; + len = sp->len; + tp = sp->next; + while(tp) { + if (tp->len >= 255) { + return _c; + } + strcpy(temp_type,tp->name); + strncat(temp_type,_t+len,255-tp->len); + if (sv_isa(sv,temp_type)) { + /* Get pointer value */ + *ptr = (void *) tmp; + if (tp->cast) *ptr = (*(tp->cast))(*ptr); + + strcpy(SwigCache[SwigCacheIndex].mapped,_c); + strcpy(SwigCache[SwigCacheIndex].name,_t); + SwigCache[SwigCacheIndex].stat = 1; + SwigCache[SwigCacheIndex].tp = tp; + SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; + return (char *) 0; + } + tp = tp->next; + } + } + sp++; + start++; + } + /* Didn't find any sort of match for this data. + Get the pointer value and return the received type */ + *ptr = (void *) tmp; + return _c; + } else { + /* Found a match on the first try. Return pointer value */ + *ptr = (void *) tmp; + return (char *) 0; + } + } + *ptr = (void *) tmp; + return (char *) 0; +} + +#endif +#ifdef __cplusplus +} +#endif + + + + + + diff --git a/wxPython/wxSWIG/Runtime/libperl.swg b/wxPython/wxSWIG/Runtime/libperl.swg new file mode 100644 index 0000000000..0eecbd28dc --- /dev/null +++ b/wxPython/wxSWIG/Runtime/libperl.swg @@ -0,0 +1,361 @@ +/* Definitions for compiling Perl extensions on a variety of machines */ + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# if defined(_MSC_VER) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# if defined(__BORLANDC__) +# define SWIGEXPORT(a) a _export +# else +# define SWIGEXPORT(a) a +# endif +# endif +#else +# define SWIGEXPORT(a) a +#endif + +#ifdef PERL_OBJECT +#define MAGIC_PPERL CPerlObj *pPerl = (CPerlObj *) this; +#define MAGIC_CAST (int (CPerlObj::*)(SV *, MAGIC *)) +#define SWIGCLASS_STATIC +#else +#define MAGIC_PPERL +#define MAGIC_CAST +#define SWIGCLASS_STATIC static +#endif + +#if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE) +#define PerlIO_exportFILE(fh,fl) (FILE*)(fh) +#endif + +/* Modifications for newer Perl 5.005 releases */ + +#if !defined(PERL_REVISION) || ((PERL_REVISION >= 5) && ((PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION < 50)))) +#ifndef PL_sv_yes +#define PL_sv_yes sv_yes +#endif +#ifndef PL_sv_undef +#define PL_sv_undef sv_undef +#endif +#ifndef PL_na +#define PL_na na +#endif +#endif + +/****************************************************************************** + * Pointer type-checking code + *****************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SWIG_NOINCLUDE +extern void SWIG_MakePtr(char *, void *, char *); +#ifndef PERL_OBJECT +extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); +#else +#define SWIG_RegisterMapping(a,b,c) _SWIG_RegisterMapping(pPerl,a,b,c); +extern void _SWIG_RegisterMapping(CPerlObj *,char *, char *, void *(*)(void *),int); +#endif +#ifndef PERL_OBJECT +extern char *SWIG_GetPtr(SV *, void **, char *); +#else +extern char *_SWIG_GetPtr(CPerlObj *, SV *, void **, char *); +#define SWIG_GetPtr(a,b,c) _SWIG_GetPtr(pPerl,a,b,c) +#endif + +#else + +#ifdef SWIG_GLOBAL +#define SWIGSTATICRUNTIME(a) SWIGEXPORT(a) +#else +#define SWIGSTATICRUNTIME(a) static a +#endif + +/* These are internal variables. Should be static */ + +typedef struct SwigPtrType { + char *name; + int len; + void *(*cast)(void *); + struct SwigPtrType *next; +} SwigPtrType; + +/* Pointer cache structure */ + +typedef struct { + int stat; /* Status (valid) bit */ + SwigPtrType *tp; /* Pointer to type structure */ + char name[256]; /* Given datatype name */ + char mapped[256]; /* Equivalent name */ +} SwigCacheType; + +static int SwigPtrMax = 64; /* Max entries that can be currently held */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ +static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ +static int SwigStart[256]; /* Table containing starting positions */ + +/* Cached values */ + +#define SWIG_CACHESIZE 8 +#define SWIG_CACHEMASK 0x7 +static SwigCacheType SwigCache[SWIG_CACHESIZE]; +static int SwigCacheIndex = 0; +static int SwigLastCache = 0; + +/* Sort comparison function */ +static int swigsort(const void *data1, const void *data2) { + SwigPtrType *d1 = (SwigPtrType *) data1; + SwigPtrType *d2 = (SwigPtrType *) data2; + return strcmp(d1->name,d2->name); +} + +/* Binary Search function */ +static int swigcmp(const void *key, const void *data) { + char *k = (char *) key; + SwigPtrType *d = (SwigPtrType *) data; + return strncmp(k,d->name,d->len); +} + +/* Register a new datatype with the type-checker */ + +#ifndef PERL_OBJECT +SWIGSTATICRUNTIME(void) +SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { +#else +#define SWIG_RegisterMapping(a,b,c) _SWIG_RegisterMapping(pPerl, a,b,c) +SWIGSTATICRUNTIME(void) +_SWIG_RegisterMapping(CPerlObj *pPerl, char *origtype, char *newtype, void *(*cast)(void *)) { +#endif + + int i; + SwigPtrType *t = 0, *t1; + + if (!SwigPtrTable) { + SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); + SwigPtrN = 0; + } + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTable = (SwigPtrType *) realloc(SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); + } + for (i = 0; i < SwigPtrN; i++) + if (strcmp(SwigPtrTable[i].name,origtype) == 0) { + t = &SwigPtrTable[i]; + break; + } + if (!t) { + t = &SwigPtrTable[SwigPtrN]; + t->name = origtype; + t->len = strlen(t->name); + t->cast = 0; + t->next = 0; + SwigPtrN++; + } + while (t->next) { + if (strcmp(t->name,newtype) == 0) { + if (cast) t->cast = cast; + return; + } + t = t->next; + } + t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + t1->name = newtype; + t1->len = strlen(t1->name); + t1->cast = cast; + t1->next = 0; + t->next = t1; + SwigPtrSort = 0; +} + +/* Make a pointer value string */ + +SWIGSTATICRUNTIME(void) +SWIG_MakePtr(char *_c, const void *_ptr, char *type) { + static char _hex[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + unsigned long _p, _s; + char _result[20], *_r; /* Note : a 64-bit hex number = 16 digits */ + _r = _result; + _p = (unsigned long) _ptr; + if (_p > 0) { + while (_p > 0) { + _s = _p & 0xf; + *(_r++) = _hex[_s]; + _p = _p >> 4; + } + *_r = '_'; + while (_r >= _result) + *(_c++) = *(_r--); + } else { + strcpy (_c, "NULL"); + } + if (_ptr) + strcpy (_c, type); +} + +/* Function for getting a pointer value */ + +#ifndef PERL_OBJECT +SWIGSTATICRUNTIME(char *) +SWIG_GetPtr(SV *sv, void **ptr, char *_t) +#else +#define SWIG_GetPtr(a,b,c) _SWIG_GetPtr(pPerl,a,b,c) +SWIGSTATICRUNTIME(char *) +_SWIG_GetPtr(CPerlObj *pPerl, SV *sv, void **ptr, char *_t) +#endif +{ + char temp_type[256]; + char *name,*_c; + int len,i,start,end; + IV tmp; + SwigPtrType *sp,*tp; + SwigCacheType *cache; + + /* If magical, apply more magic */ + + if (SvGMAGICAL(sv)) + mg_get(sv); + + /* Check to see if this is an object */ + if (sv_isobject(sv)) { + SV *tsv = (SV*) SvRV(sv); + if ((SvTYPE(tsv) == SVt_PVHV)) { + MAGIC *mg; + if (SvMAGICAL(tsv)) { + mg = mg_find(tsv,'P'); + if (mg) { + SV *rsv = mg->mg_obj; + if (sv_isobject(rsv)) { + tmp = SvIV((SV*)SvRV(rsv)); + } + } + } else { + return "Not a valid pointer value"; + } + } else { + tmp = SvIV((SV*)SvRV(sv)); + } + if (!_t) { + *(ptr) = (void *) tmp; + return (char *) 0; + } + } else if (! SvOK(sv)) { /* Check for undef */ + *(ptr) = (void *) 0; + return (char *) 0; + } else if (SvTYPE(sv) == SVt_RV) { /* Check for NULL pointer */ + *(ptr) = (void *) 0; + if (!SvROK(sv)) + return (char *) 0; + else + return "Not a valid pointer value"; + } else { /* Don't know what it is */ + *(ptr) = (void *) 0; + return "Not a valid pointer value"; + } + if (_t) { + /* Now see if the types match */ + + if (!sv_isa(sv,_t)) { + _c = HvNAME(SvSTASH(SvRV(sv))); + if (!SwigPtrSort) { + qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); + for (i = 0; i < 256; i++) { + SwigStart[i] = SwigPtrN; + } + for (i = SwigPtrN-1; i >= 0; i--) { + SwigStart[SwigPtrTable[i].name[0]] = i; + } + for (i = 255; i >= 1; i--) { + if (SwigStart[i-1] > SwigStart[i]) + SwigStart[i-1] = SwigStart[i]; + } + SwigPtrSort = 1; + for (i = 0; i < SWIG_CACHESIZE; i++) + SwigCache[i].stat = 0; + } + /* First check cache for matches. Uses last cache value as starting point */ + cache = &SwigCache[SwigLastCache]; + for (i = 0; i < SWIG_CACHESIZE; i++) { + if (cache->stat) { + if (strcmp(_t,cache->name) == 0) { + if (strcmp(_c,cache->mapped) == 0) { + cache->stat++; + *ptr = (void *) tmp; + if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); + return (char *) 0; + } + } + } + SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; + if (!SwigLastCache) cache = SwigCache; + else cache++; + } + + start = SwigStart[_t[0]]; + end = SwigStart[_t[0]+1]; + sp = &SwigPtrTable[start]; + while (start < end) { + if (swigcmp(_t,sp) == 0) break; + sp++; + start++; + } + if (start > end) sp = 0; + while (start <= end) { + if (swigcmp(_t,sp) == 0) { + name = sp->name; + len = sp->len; + tp = sp->next; + while(tp) { + if (tp->len >= 255) { + return _c; + } + strcpy(temp_type,tp->name); + strncat(temp_type,_t+len,255-tp->len); + if (sv_isa(sv,temp_type)) { + /* Get pointer value */ + *ptr = (void *) tmp; + if (tp->cast) *ptr = (*(tp->cast))(*ptr); + + strcpy(SwigCache[SwigCacheIndex].mapped,_c); + strcpy(SwigCache[SwigCacheIndex].name,_t); + SwigCache[SwigCacheIndex].stat = 1; + SwigCache[SwigCacheIndex].tp = tp; + SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; + return (char *) 0; + } + tp = tp->next; + } + } + sp++; + start++; + } + /* Didn't find any sort of match for this data. + Get the pointer value and return the received type */ + *ptr = (void *) tmp; + return _c; + } else { + /* Found a match on the first try. Return pointer value */ + *ptr = (void *) tmp; + return (char *) 0; + } + } + *ptr = (void *) tmp; + return (char *) 0; +} + +#endif +#ifdef __cplusplus +} +#endif + + + + + + diff --git a/wxPython/wxSWIG/Runtime/libpy.c b/wxPython/wxSWIG/Runtime/libpy.c new file mode 100644 index 0000000000..9fca855598 --- /dev/null +++ b/wxPython/wxSWIG/Runtime/libpy.c @@ -0,0 +1,417 @@ +/*********************************************************************** + * $Header$ + * swig_lib/python/python.cfg + * + * Contains variable linking and pointer type-checking code. + ************************************************************************/ + +#include +#include + +#include "Python.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Definitions for Windows/Unix exporting */ +#if defined(_WIN32) || defined(__WIN32__) +# if defined(_MSC_VER) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# if defined(__BORLANDC__) +# define SWIGEXPORT(a) a _export +# else +# define SWIGEXPORT(a) a +# endif +# endif +#else +# define SWIGEXPORT(a) a +#endif + +#ifdef SWIG_GLOBAL +#define SWIGSTATICRUNTIME(a) SWIGEXPORT(a) +#else +#define SWIGSTATICRUNTIME(a) static a +#endif + +typedef struct { + char *name; + PyObject *(*get_attr)(void); + int (*set_attr)(PyObject *); +} swig_globalvar; + +typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar **vars; + int nvars; + int maxvars; +} swig_varlinkobject; + +/* ---------------------------------------------------------------------- + swig_varlink_repr() + + Function for python repr method + ---------------------------------------------------------------------- */ + +static PyObject * +swig_varlink_repr(swig_varlinkobject *v) +{ + v = v; + return PyString_FromString(""); +} + +/* --------------------------------------------------------------------- + swig_varlink_print() + + Print out all of the global variable names + --------------------------------------------------------------------- */ + +static int +swig_varlink_print(swig_varlinkobject *v, FILE *fp, int flags) +{ + + int i = 0; + flags = flags; + fprintf(fp,"Global variables { "); + while (v->vars[i]) { + fprintf(fp,"%s", v->vars[i]->name); + i++; + if (v->vars[i]) fprintf(fp,", "); + } + fprintf(fp," }\n"); + return 0; +} + +/* -------------------------------------------------------------------- + swig_varlink_getattr + + This function gets the value of a variable and returns it as a + PyObject. In our case, we'll be looking at the datatype and + converting into a number or string + -------------------------------------------------------------------- */ + +static PyObject * +swig_varlink_getattr(swig_varlinkobject *v, char *n) +{ + int i = 0; + char temp[128]; + + while (v->vars[i]) { + if (strcmp(v->vars[i]->name,n) == 0) { + return (*v->vars[i]->get_attr)(); + } + i++; + } + sprintf(temp,"C global variable %s not found.", n); + PyErr_SetString(PyExc_NameError,temp); + return NULL; +} + +/* ------------------------------------------------------------------- + swig_varlink_setattr() + + This function sets the value of a variable. + ------------------------------------------------------------------- */ + +static int +swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) +{ + char temp[128]; + int i = 0; + while (v->vars[i]) { + if (strcmp(v->vars[i]->name,n) == 0) { + return (*v->vars[i]->set_attr)(p); + } + i++; + } + sprintf(temp,"C global variable %s not found.", n); + PyErr_SetString(PyExc_NameError,temp); + return 1; +} + +statichere PyTypeObject varlinktype = { +/* PyObject_HEAD_INIT(&PyType_Type) Note : This doesn't work on some machines */ + PyObject_HEAD_INIT(0) + 0, + "varlink", /* Type name */ + sizeof(swig_varlinkobject), /* Basic size */ + 0, /* Itemsize */ + 0, /* Deallocator */ + (printfunc) swig_varlink_print, /* Print */ + (getattrfunc) swig_varlink_getattr, /* get attr */ + (setattrfunc) swig_varlink_setattr, /* Set attr */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_mapping*/ + 0, /* tp_hash */ +}; + +/* Create a variable linking object for use later */ + +SWIGSTATICRUNTIME(PyObject *) +SWIG_newvarlink(void) +{ + swig_varlinkobject *result = 0; + result = PyMem_NEW(swig_varlinkobject,1); + varlinktype.ob_type = &PyType_Type; /* Patch varlinktype into a PyType */ + result->ob_type = &varlinktype; + /* _Py_NewReference(result); Does not seem to be necessary */ + result->nvars = 0; + result->maxvars = 64; + result->vars = (swig_globalvar **) malloc(64*sizeof(swig_globalvar *)); + result->vars[0] = 0; + result->ob_refcnt = 0; + Py_XINCREF((PyObject *) result); + return ((PyObject*) result); +} + +SWIGSTATICRUNTIME(void) +SWIG_addvarlink(PyObject *p, char *name, + PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) +{ + swig_varlinkobject *v; + v= (swig_varlinkobject *) p; + + if (v->nvars >= v->maxvars -1) { + v->maxvars = 2*v->maxvars; + v->vars = (swig_globalvar **) realloc(v->vars,v->maxvars*sizeof(swig_globalvar *)); + if (v->vars == NULL) { + fprintf(stderr,"SWIG : Fatal error in initializing Python module.\n"); + exit(1); + } + } + v->vars[v->nvars] = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + v->vars[v->nvars]->name = (char *) malloc(strlen(name)+1); + strcpy(v->vars[v->nvars]->name,name); + v->vars[v->nvars]->get_attr = get_attr; + v->vars[v->nvars]->set_attr = set_attr; + v->nvars++; + v->vars[v->nvars] = 0; +} + +/* ----------------------------------------------------------------------------- + * Pointer type-checking + * ----------------------------------------------------------------------------- */ + +/* SWIG pointer structure */ +typedef struct SwigPtrType { + char *name; /* Datatype name */ + int len; /* Length (used for optimization) */ + void *(*cast)(void *); /* Pointer casting function */ + struct SwigPtrType *next; /* Linked list pointer */ +} SwigPtrType; + +/* Pointer cache structure */ +typedef struct { + int stat; /* Status (valid) bit */ + SwigPtrType *tp; /* Pointer to type structure */ + char name[256]; /* Given datatype name */ + char mapped[256]; /* Equivalent name */ +} SwigCacheType; + +static int SwigPtrMax = 64; /* Max entries that can be currently held */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ +static int SwigStart[256]; /* Starting positions of types */ +static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ + +/* Cached values */ +#define SWIG_CACHESIZE 8 +#define SWIG_CACHEMASK 0x7 +static SwigCacheType SwigCache[SWIG_CACHESIZE]; +static int SwigCacheIndex = 0; +static int SwigLastCache = 0; + +/* Sort comparison function */ +static int swigsort(const void *data1, const void *data2) { + SwigPtrType *d1 = (SwigPtrType *) data1; + SwigPtrType *d2 = (SwigPtrType *) data2; + return strcmp(d1->name,d2->name); +} + +/* Register a new datatype with the type-checker */ +SWIGSTATICRUNTIME(void) +SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { + int i; + SwigPtrType *t = 0,*t1; + + /* Allocate the pointer table if necessary */ + if (!SwigPtrTable) { + SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); + } + + /* Grow the table */ + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTable = (SwigPtrType *) realloc((char *) SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); + } + for (i = 0; i < SwigPtrN; i++) { + if (strcmp(SwigPtrTable[i].name,origtype) == 0) { + t = &SwigPtrTable[i]; + break; + } + } + if (!t) { + t = &SwigPtrTable[SwigPtrN++]; + t->name = origtype; + t->len = strlen(t->name); + t->cast = 0; + t->next = 0; + } + + /* Check for existing entries */ + while (t->next) { + if ((strcmp(t->name,newtype) == 0)) { + if (cast) t->cast = cast; + return; + } + t = t->next; + } + t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + t1->name = newtype; + t1->len = strlen(t1->name); + t1->cast = cast; + t1->next = 0; + t->next = t1; + SwigPtrSort = 0; +} + +/* Make a pointer value string */ +SWIGSTATICRUNTIME(void) +SWIG_MakePtr(char *c, const void *ptr, char *type) { + static char hex[17] = "0123456789abcdef"; + unsigned long p, s; + char result[24], *r; + r = result; + p = (unsigned long) ptr; + if (p > 0) { + while (p > 0) { + s = p & 0xf; + *(r++) = hex[s]; + p = p >> 4; + } + *r = '_'; + while (r >= result) + *(c++) = *(r--); + strcpy (c, type); + } else { + strcpy (c, "NULL"); + } +} + +/* Function for getting a pointer value */ +SWIGSTATICRUNTIME(char *) +SWIG_GetPtr(char *c, void **ptr, char *t) +{ + unsigned long p; + char temp_type[256], *name; + int i, len, start, end; + SwigPtrType *sp,*tp; + SwigCacheType *cache; + register int d; + + p = 0; + /* Pointer values must start with leading underscore */ + if (*c != '_') { + *ptr = (void *) 0; + if (strcmp(c,"NULL") == 0) return (char *) 0; + else c; + } + c++; + /* Extract hex value from pointer */ + while (d = *c) { + if ((d >= '0') && (d <= '9')) + p = (p << 4) + (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + p = (p << 4) + (d - ('a'-10)); + else + break; + c++; + } + *ptr = (void *) p; + if ((!t) || (strcmp(t,c)==0)) return (char *) 0; + + if (!SwigPtrSort) { + qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); + for (i = 0; i < 256; i++) SwigStart[i] = SwigPtrN; + for (i = SwigPtrN-1; i >= 0; i--) SwigStart[(int) (SwigPtrTable[i].name[1])] = i; + for (i = 255; i >= 1; i--) { + if (SwigStart[i-1] > SwigStart[i]) + SwigStart[i-1] = SwigStart[i]; + } + SwigPtrSort = 1; + for (i = 0; i < SWIG_CACHESIZE; i++) SwigCache[i].stat = 0; + } + /* First check cache for matches. Uses last cache value as starting point */ + cache = &SwigCache[SwigLastCache]; + for (i = 0; i < SWIG_CACHESIZE; i++) { + if (cache->stat && (strcmp(t,cache->name) == 0) && (strcmp(c,cache->mapped) == 0)) { + cache->stat++; + if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); + return (char *) 0; + } + SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; + if (!SwigLastCache) cache = SwigCache; + else cache++; + } + /* Type mismatch. Look through type-mapping table */ + start = SwigStart[(int) t[1]]; + end = SwigStart[(int) t[1]+1]; + sp = &SwigPtrTable[start]; + + /* Try to find a match */ + while (start <= end) { + if (strncmp(t,sp->name,sp->len) == 0) { + name = sp->name; + len = sp->len; + tp = sp->next; + /* Try to find entry for our given datatype */ + while(tp) { + if (tp->len >= 255) { + return c; + } + strcpy(temp_type,tp->name); + strncat(temp_type,t+len,255-tp->len); + if (strcmp(c,temp_type) == 0) { + strcpy(SwigCache[SwigCacheIndex].mapped,c); + strcpy(SwigCache[SwigCacheIndex].name,t); + SwigCache[SwigCacheIndex].stat = 1; + SwigCache[SwigCacheIndex].tp = tp; + SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; + /* Get pointer value */ + *ptr = (void *) p; + if (tp->cast) *ptr = (*(tp->cast))(*ptr); + return (char *) 0; + } + tp = tp->next; + } + } + sp++; + start++; + } + return c; +} + +/* New object-based GetPointer function. This uses the Python abstract + * object interface to automatically dereference the 'this' attribute + * of shadow objects. */ + +SWIGSTATICRUNTIME(char *) +SWIG_GetPtrObj(PyObject *obj, void **ptr, char *type) { + PyObject *sobj = obj; + char *str; + if (!PyString_Check(obj)) { + sobj = PyObject_GetAttrString(obj,"this"); + if (!sobj) return ""; + } + str = PyString_AsString(sobj); + return SWIG_GetPtr(str,ptr,type); +} + +#ifdef __cplusplus +} +#endif + + diff --git a/wxPython/wxSWIG/Runtime/libtcl.c b/wxPython/wxSWIG/Runtime/libtcl.c new file mode 100644 index 0000000000..9aedd4ad32 --- /dev/null +++ b/wxPython/wxSWIG/Runtime/libtcl.c @@ -0,0 +1,249 @@ +/* + * $Header$ + * + * swigtcl.swg + */ + +#if defined(_WIN32) || defined(__WIN32__) +# if defined(_MSC_VER) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# if defined(__BORLANDC__) +# define SWIGEXPORT(a) a _export +# else +# define SWIGEXPORT(a) a +# endif +# endif +#else +# define SWIGEXPORT(a) a +#endif + +/***************************************************************************** + * $Header$ + * + * swigptr.swg + *****************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SWIG_NOINCLUDE +extern void SWIG_MakePtr(char *, void *, char *); +extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); +extern char *SWIG_GetPtr(char *, void **, char *); +#else + +#ifdef SWIG_GLOBAL +#define SWIGSTATICRUNTIME(a) SWIGEXPORT(a) +#else +#define SWIGSTATICRUNTIME(a) static a +#endif + +/* SWIG pointer structure */ +typedef struct SwigPtrType { + char *name; /* Datatype name */ + int len; /* Length (used for optimization) */ + void *(*cast)(void *); /* Pointer casting function */ + struct SwigPtrType *next; /* Linked list pointer */ +} SwigPtrType; + +/* Pointer cache structure */ +typedef struct { + int stat; /* Status (valid) bit */ + SwigPtrType *tp; /* Pointer to type structure */ + char name[256]; /* Given datatype name */ + char mapped[256]; /* Equivalent name */ +} SwigCacheType; + +static int SwigPtrMax = 64; /* Max entries that can be currently held */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ +static int SwigStart[256]; /* Starting positions of types */ +static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ + +/* Cached values */ +#define SWIG_CACHESIZE 8 +#define SWIG_CACHEMASK 0x7 +static SwigCacheType SwigCache[SWIG_CACHESIZE]; +static int SwigCacheIndex = 0; +static int SwigLastCache = 0; + +/* Sort comparison function */ +static int swigsort(const void *data1, const void *data2) { + SwigPtrType *d1 = (SwigPtrType *) data1; + SwigPtrType *d2 = (SwigPtrType *) data2; + return strcmp(d1->name,d2->name); +} + +/* Register a new datatype with the type-checker */ +SWIGSTATICRUNTIME(void) +SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { + int i; + SwigPtrType *t = 0,*t1; + + /* Allocate the pointer table if necessary */ + if (!SwigPtrTable) { + SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); + } + + /* Grow the table */ + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTable = (SwigPtrType *) realloc((char *) SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); + } + for (i = 0; i < SwigPtrN; i++) { + if (strcmp(SwigPtrTable[i].name,origtype) == 0) { + t = &SwigPtrTable[i]; + break; + } + } + if (!t) { + t = &SwigPtrTable[SwigPtrN++]; + t->name = origtype; + t->len = strlen(t->name); + t->cast = 0; + t->next = 0; + } + + /* Check for existing entries */ + while (t->next) { + if ((strcmp(t->name,newtype) == 0)) { + if (cast) t->cast = cast; + return; + } + t = t->next; + } + t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + t1->name = newtype; + t1->len = strlen(t1->name); + t1->cast = cast; + t1->next = 0; + t->next = t1; + SwigPtrSort = 0; +} + +/* Make a pointer value string */ +SWIGSTATICRUNTIME(void) +SWIG_MakePtr(char *c, const void *ptr, char *type) { + static char hex[17] = "0123456789abcdef"; + unsigned long p, s; + char result[24], *r; + r = result; + p = (unsigned long) ptr; + if (p > 0) { + while (p > 0) { + s = p & 0xf; + *(r++) = hex[s]; + p = p >> 4; + } + *r = '_'; + while (r >= result) + *(c++) = *(r--); + strcpy (c, type); + } else { + strcpy (c, "NULL"); + } +} + +/* Function for getting a pointer value */ +SWIGSTATICRUNTIME(char *) +SWIG_GetPtr(char *c, void **ptr, char *t) +{ + unsigned long p; + char temp_type[256], *name; + int i, len, start, end; + SwigPtrType *sp,*tp; + SwigCacheType *cache; + register int d; + + p = 0; + /* Pointer values must start with leading underscore */ + if (*c != '_') { + *ptr = (void *) 0; + if (strcmp(c,"NULL") == 0) return (char *) 0; + else c; + } + c++; + /* Extract hex value from pointer */ + while (d = *c) { + if ((d >= '0') && (d <= '9')) + p = (p << 4) + (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + p = (p << 4) + (d - ('a'-10)); + else + break; + c++; + } + *ptr = (void *) p; + if ((!t) || (strcmp(t,c)==0)) return (char *) 0; + + if (!SwigPtrSort) { + qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); + for (i = 0; i < 256; i++) SwigStart[i] = SwigPtrN; + for (i = SwigPtrN-1; i >= 0; i--) SwigStart[(int) (SwigPtrTable[i].name[1])] = i; + for (i = 255; i >= 1; i--) { + if (SwigStart[i-1] > SwigStart[i]) + SwigStart[i-1] = SwigStart[i]; + } + SwigPtrSort = 1; + for (i = 0; i < SWIG_CACHESIZE; i++) SwigCache[i].stat = 0; + } + /* First check cache for matches. Uses last cache value as starting point */ + cache = &SwigCache[SwigLastCache]; + for (i = 0; i < SWIG_CACHESIZE; i++) { + if (cache->stat && (strcmp(t,cache->name) == 0) && (strcmp(c,cache->mapped) == 0)) { + cache->stat++; + if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); + return (char *) 0; + } + SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; + if (!SwigLastCache) cache = SwigCache; + else cache++; + } + /* Type mismatch. Look through type-mapping table */ + start = SwigStart[(int) t[1]]; + end = SwigStart[(int) t[1]+1]; + sp = &SwigPtrTable[start]; + + /* Try to find a match */ + while (start <= end) { + if (strncmp(t,sp->name,sp->len) == 0) { + name = sp->name; + len = sp->len; + tp = sp->next; + /* Try to find entry for our given datatype */ + while(tp) { + if (tp->len >= 255) { + return c; + } + strcpy(temp_type,tp->name); + strncat(temp_type,t+len,255-tp->len); + if (strcmp(c,temp_type) == 0) { + strcpy(SwigCache[SwigCacheIndex].mapped,c); + strcpy(SwigCache[SwigCacheIndex].name,t); + SwigCache[SwigCacheIndex].stat = 1; + SwigCache[SwigCacheIndex].tp = tp; + SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; + /* Get pointer value */ + *ptr = (void *) p; + if (tp->cast) *ptr = (*(tp->cast))(*ptr); + return (char *) 0; + } + tp = tp->next; + } + } + sp++; + start++; + } + return c; +} + +#endif + +#ifdef __cplusplus +} +#endif + diff --git a/wxPython/wxSWIG/Runtime/libtcl8.c b/wxPython/wxSWIG/Runtime/libtcl8.c new file mode 100644 index 0000000000..96f1d1af7a --- /dev/null +++ b/wxPython/wxSWIG/Runtime/libtcl8.c @@ -0,0 +1,367 @@ +/************************************************************************** + * $Header$ + * + * swigtcl8.swg + * + * This file provides type-checked pointer support to Tcl 8.0. + **********************************************************************/ + +#if defined(_WIN32) || defined(__WIN32__) +# if defined(_MSC_VER) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# if defined(__BORLANDC__) +# define SWIGEXPORT(a) a _export +# else +# define SWIGEXPORT(a) a +# endif +# endif +#else +# define SWIGEXPORT(a) a +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SWIG_GLOBAL +#include +#define SWIGSTATICRUNTIME(a) SWIGEXPORT(a) +#else +#define SWIGSTATICRUNTIME(a) static a +#endif + +#ifdef SWIG_NOINCLUDE +extern void SWIG_SetPointerObj(Tcl_Obj *, void *, char *); +extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); +extern char *SWIG_GetPointerObj(Tcl_Interp *, Tcl_Obj *, void **, char *); +extern int SWIG_MakePtr(char *, const void *, char *); +extern void SWIG_RegisterType(); +#else + +/* These are internal variables. Should be static */ + +typedef struct SwigPtrType { + char *name; + int len; + void *(*cast)(void *); + struct SwigPtrType *next; +} SwigPtrType; + +/* Pointer cache structure */ + +typedef struct { + int stat; /* Status (valid) bit */ + SwigPtrType *tp; /* Pointer to type structure */ + char name[256]; /* Given datatype name */ + char mapped[256]; /* Equivalent name */ +} SwigCacheType; + +static int SwigPtrMax = 64; /* Max entries that can be currently held */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ +static int SwigStart[256]; /* Array containing start locations (for searching) */ +static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ + +/* Cached values */ + +#define SWIG_CACHESIZE 8 +#define SWIG_CACHEMASK 0x7 +static SwigCacheType SwigCache[SWIG_CACHESIZE]; +static int SwigCacheIndex = 0; +static int SwigLastCache = 0; + +/* Sort comparison function */ +static int swigsort(const void *data1, const void *data2) { + SwigPtrType *d1 = (SwigPtrType *) data1; + SwigPtrType *d2 = (SwigPtrType *) data2; + return strcmp(d1->name,d2->name); +} + +/* Binary Search function */ +static int swigcmp(const void *key, const void *data) { + char *k = (char *) key; + SwigPtrType *d = (SwigPtrType *) data; + return strncmp(k,d->name,d->len); +} + + +/*--------------------------------------------------------------------- + * SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) + * + * Register a new type-mapping with the type-checking system. + *---------------------------------------------------------------------*/ + +SWIGSTATICRUNTIME(void) +SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { + + int i; + SwigPtrType *t = 0, *t1; + + if (!SwigPtrTable) { + SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); + SwigPtrN = 0; + } + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTable = (SwigPtrType *) realloc(SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); + } + for (i = 0; i < SwigPtrN; i++) + if (strcmp(SwigPtrTable[i].name,origtype) == 0) { + t = &SwigPtrTable[i]; + break; + } + if (!t) { + t = &SwigPtrTable[SwigPtrN]; + t->name = origtype; + t->len = strlen(origtype); + t->cast = 0; + t->next = 0; + SwigPtrN++; + } + while (t->next) { + if (strcmp(t->name,newtype) == 0) { + if (cast) t->cast = cast; + return; + } + t = t->next; + } + t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + t1->name = newtype; + t1->len = strlen(newtype); + t1->cast = cast; + t1->next = 0; + t->next = t1; + SwigPtrSort = 0; +} + + +/*--------------------------------------------------------------------- + * void SWIG_SetPointerObj(Tcl_Obj *objPtr, void *ptr, char *type) + * + * Sets a Tcl object to a pointer value. + * ptr = void pointer value + * type = string representing type + * + *---------------------------------------------------------------------*/ + +SWIGSTATICRUNTIME(void) +SWIG_SetPointerObj(Tcl_Obj *objPtr, void *_ptr, char *type) { + static char _hex[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + unsigned long _p, _s; + char _result[20], *_r; /* Note : a 64-bit hex number = 16 digits */ + char _temp[20], *_c; + _r = _result; + _p = (unsigned long) _ptr; + if (_p > 0) { + while (_p > 0) { + _s = _p & 0xf; + *(_r++) = _hex[_s]; + _p = _p >> 4; + } + *_r = '_'; + _c = &_temp[0]; + while (_r >= _result) + *(_c++) = *(_r--); + *_c = 0; + Tcl_SetStringObj(objPtr,_temp,-1); + } else { + Tcl_SetStringObj(objPtr,"NULL",-1); + } + if (_ptr) + Tcl_AppendToObj(objPtr,type,-1); +} + +/* This is for backwards compatibility */ + +SWIGSTATICRUNTIME(int) +SWIG_MakePtr(char *_c, const void *_ptr, char *type) +{ + static char _hex[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + unsigned long _p, _s; + char _result[20], *_r; + int l = 0; + _r = _result; + _p = (unsigned long) _ptr; + if (_p > 0) { + while (_p > 0) { + _s = _p & 0xf; + *(_r++) = _hex[_s]; + _p = _p >> 4; + l++; + } + *_r = '_'; + l++; + while (_r >= _result) + *(_c++) = *(_r--); + _r = type; + while (*_r) + *(_c++) = *(_r++); + *(_c) = 0; + } else { + strcpy (_c, "NULL"); + } + return l; +} + +/*--------------------------------------------------------------------- + * char *SWIG_GetPointerObj(Tcl_Interp *interp, Tcl_Obj *objPtr, void **ptr, char *type) + * + * Attempts to extract a pointer value from our pointer type. + * Upon failure, returns a string corresponding to the actual datatype. + * Upon success, returns NULL and sets the pointer value in ptr. + *---------------------------------------------------------------------*/ + +SWIGSTATICRUNTIME(char *) +SWIG_GetPointerObj(Tcl_Interp *interp, Tcl_Obj *objPtr, void **ptr, char *_t) { + unsigned long _p; + char temp_type[256]; + char *name; + int i, len; + SwigPtrType *sp,*tp; + SwigCacheType *cache; + int start, end; + char *_c; + _p = 0; + + /* Extract the pointer value as a string */ + _c = Tcl_GetStringFromObj(objPtr, &i); + + /* Pointer values must start with leading underscore */ + if (*_c == '_') { + _c++; + /* Extract hex value from pointer */ + while (*_c) { + if ((*_c >= '0') && (*_c <= '9')) + _p = (_p << 4) + (*_c - '0'); + else if ((*_c >= 'a') && (*_c <= 'f')) + _p = (_p << 4) + ((*_c - 'a') + 10); + else + break; + _c++; + } + + if (_t) { + if (strcmp(_t,_c)) { + if (!SwigPtrSort) { + qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); + for (i = 0; i < 256; i++) { + SwigStart[i] = SwigPtrN; + } + for (i = SwigPtrN-1; i >= 0; i--) { + SwigStart[(int) (SwigPtrTable[i].name[1])] = i; + } + for (i = 255; i >= 1; i--) { + if (SwigStart[i-1] > SwigStart[i]) + SwigStart[i-1] = SwigStart[i]; + } + SwigPtrSort = 1; + for (i = 0; i < SWIG_CACHESIZE; i++) + SwigCache[i].stat = 0; + } + + /* First check cache for matches. Uses last cache value as starting point */ + cache = &SwigCache[SwigLastCache]; + for (i = 0; i < SWIG_CACHESIZE; i++) { + if (cache->stat) { + if (strcmp(_t,cache->name) == 0) { + if (strcmp(_c,cache->mapped) == 0) { + cache->stat++; + *ptr = (void *) _p; + if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); + return (char *) 0; + } + } + } + SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; + if (!SwigLastCache) cache = SwigCache; + else cache++; + } + /* We have a type mismatch. Will have to look through our type + mapping table to figure out whether or not we can accept this datatype */ + + start = SwigStart[(int) _t[1]]; + end = SwigStart[(int) _t[1]+1]; + sp = &SwigPtrTable[start]; + while (start < end) { + if (swigcmp(_t,sp) == 0) break; + sp++; + start++; + } + if (start > end) sp = 0; + /* Try to find a match for this */ + while (start <= end) { + if (swigcmp(_t,sp) == 0) { + name = sp->name; + len = sp->len; + tp = sp->next; + /* Try to find entry for our given datatype */ + while(tp) { + if (tp->len >= 255) { + return _c; + } + strcpy(temp_type,tp->name); + strncat(temp_type,_t+len,255-tp->len); + if (strcmp(_c,temp_type) == 0) { + + strcpy(SwigCache[SwigCacheIndex].mapped,_c); + strcpy(SwigCache[SwigCacheIndex].name,_t); + SwigCache[SwigCacheIndex].stat = 1; + SwigCache[SwigCacheIndex].tp = tp; + SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; + + /* Get pointer value */ + *ptr = (void *) _p; + if (tp->cast) *ptr = (*(tp->cast))(*ptr); + return (char *) 0; + } + tp = tp->next; + } + } + sp++; + start++; + } + /* Didn't find any sort of match for this data. + Get the pointer value and return the received type */ + *ptr = (void *) _p; + return _c; + } else { + /* Found a match on the first try. Return pointer value */ + *ptr = (void *) _p; + return (char *) 0; + } + } else { + /* No type specified. Good luck */ + *ptr = (void *) _p; + return (char *) 0; + } + } else { + if (strcmp (_c, "NULL") == 0) { + *ptr = (void *) 0; + return (char *) 0; + } + *ptr = (void *) 0; + return _c; + } +} + +/*--------------------------------------------------------------------- + * void SWIG_RegisterType() + * + * Registers our new datatype with an interpreter. + *---------------------------------------------------------------------*/ + +SWIGSTATICRUNTIME(void) +SWIG_RegisterType() { + /* Does nothing at the moment */ +} + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/wxPython/wxSWIG/Runtime/make.sh b/wxPython/wxSWIG/Runtime/make.sh new file mode 100644 index 0000000000..1d0b46f378 --- /dev/null +++ b/wxPython/wxSWIG/Runtime/make.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +necho() { + if [ "`echo -n`" = "-n" ]; then + echo "${@}\c" + else + echo -n "${@}" + fi +} + +# Script that attempts to produce different run-time libraries + +TARGET='perl_lib perl_shared py_lib py_shared tcl_lib tcl_shared tcl8_lib tcl8_shared' + +echo "Building the SWIG runtime libraries..." +echo "" +echo "*** Note : Some builds may fail due to uninstalled packages or" +echo "unsupported features such as dynamic loading (don't panic)." +echo "" + +for i in ${TARGET}; do +necho " Building ${i}"; +if make ${i} >/dev/null 2>&1; then +# See if SWIG generated any errors at all + echo " ....... OK."; +else + echo " ....... failed."; +fi; +done + diff --git a/wxPython/wxSWIG/Runtime/makefile.vc b/wxPython/wxSWIG/Runtime/makefile.vc new file mode 100644 index 0000000000..b81ff1d2e1 --- /dev/null +++ b/wxPython/wxSWIG/Runtime/makefile.vc @@ -0,0 +1,99 @@ +# Modified for use with Microsoft Developer Studio V6.0 +# Bob Techentin, February 10, 1999 +# +# Makefile for producing SWIG runtime libraries. +# +# The SWIG runtime library consists of the pointer-type checker +# and other support functions. Multi-file SWIG modules +# generally link with these libraries. +# +# The Windows version of the runtime libraries are static. +# Note the "-" command prefix ignores errors during compiles +# and links, because you might not have all languages. + +!include <..\make_win.in> + +SWIG_RUNTIME = $(prefix)/lib +dSWIG_RUNTIME = $(dprefix)\lib + +AR = lib.exe + + +all: tcl_lib tcl8_lib py_lib perl_lib + + +install: + @echo "Installing runtime libraries" + @if not exist $(dSWIG_RUNTIME) mkdir $(dSWIG_RUNTIME) + if exist swigtcl.lib copy swigtcl.lib $(dSWIG_RUNTIME) + if exist swigtcl8.lib copy swigtcl8.lib $(dSWIG_RUNTIME) + if exist swigpy.lib copy swigpy.lib $(dSWIG_RUNTIME) + if exist swigpl.lib copy swigpl.lib $(dSWIG_RUNTIME) + +install95: + @echo "Installing runtime libraries" + @if not exist $(dSWIG_RUNTIME) mkdir $(dSWIG_RUNTIME) + if exist swigtcl.lib copy swigtcl.lib $(dSWIG_RUNTIME) /Y + if exist swigtcl8.lib copy swigtcl8.lib $(dSWIG_RUNTIME) /Y + if exist swigpy.lib copy swigpy.lib $(dSWIG_RUNTIME) /Y + if exist swigpl.lib copy swigpl.lib $(dSWIG_RUNTIME) /Y + +clean:: + del /f *.obj + del /f *.lib + del /f *.c + del /f *.swg + del /f core + +# ---------------------------------------------------------------------- +# Tcl runtime library +# ---------------------------------------------------------------------- + +TCL_INCLUDE = -Ic:\apps\TclPro1.1\include + +# Tcl 7.x library + +tcl_lib: + -..\swig.exe -tcl -co -o libtcl.c -I..\swig_lib swigtcl.swg + -$(CC) -c -DSWIG_GLOBAL libtcl.c + -$(AR) /out:swigtcl.lib libtcl.obj + +tcl8_lib: + -..\swig.exe -tcl -co -o libtcl8.c -I..\swig_lib swigtcl8.swg + -$(CC) -c -DSWIG_GLOBAL $(TCL_INCLUDE) libtcl8.c + -$(AR) /out:swigtcl8.lib libtcl8.obj + +# ---------------------------------------------------------------------- +# Python run-time library +# ---------------------------------------------------------------------- + +PYTHON_INCLUDE = -Ic:\apps\python-1.5\Include -Ic:\apps\python-1.5 -Ic:\apps\python-1.5\PC + +# Python library + +py_lib: + -..\swig.exe -python -co -o libpy.c -I../swig_lib python.swg + -$(CC) -c -DSWIG_GLOBAL $(PYTHON_INCLUDE) libpy.c + -$(AR) /out:swigpy.lib libpy.obj + +# ---------------------------------------------------------------------- +# Perl run-time library +# ---------------------------------------------------------------------- + +# These are for Perl5.004 +PERL_INCLUDE = -Ic:\apps\perl\lib\CORE +PERLFLAGS = /DWIN32 /DMSWIN32 /DWIN32IO_IS_STDIO + +# Uncomment the following if you are using ActiveWare Perl for Win32 +#PERL_INCLUDE =-Id:\perl315 -Id:\perl315\inc +#PERLFLAGS = /DWIN32 /DMSWIN32 /DPERL_OBJECT + +# Perl library + +perl_lib: + -del /f libperl.c libperl.swg + -..\swig.exe -perl5 -co -o libperl.swg -I..\swig_lib perl5.swg + -copy perlrun.h+libperl.swg libperl.c + -$(CC) -c -Dexplicit= -Dbool=char -DSWIG_GLOBAL $(PERFLAGS) $(PERL_INCLUDE) libperl.c + -$(AR) /out:swigpl.lib libperl.obj + diff --git a/wxPython/wxSWIG/Runtime/perlrun.h b/wxPython/wxSWIG/Runtime/perlrun.h new file mode 100644 index 0000000000..b1c12a38db --- /dev/null +++ b/wxPython/wxSWIG/Runtime/perlrun.h @@ -0,0 +1,3 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" diff --git a/wxPython/wxSWIG/SWIG/Makefile.in b/wxPython/wxSWIG/SWIG/Makefile.in new file mode 100644 index 0000000000..0def1ef8ec --- /dev/null +++ b/wxPython/wxSWIG/SWIG/Makefile.in @@ -0,0 +1,126 @@ +####################################################################### +# $Header$ +# Simplified Wrapper and Interface Generator (SWIG) +# +# Makefile for version 1.0 Final +# Dave Beazley +# August 1, 1996 +# +# This makefile is now mostly constructed by ./configure. +# +# $Log$ +# Revision 1.1 2002/04/29 19:56:48 RD +# Since I have made several changes to SWIG over the years to accomodate +# special cases and other things in wxPython, and since I plan on making +# several more, I've decided to put the SWIG sources in wxPython's CVS +# instead of relying on maintaining patches. This effectivly becomes a +# fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still +# doesn't have some things I rely on in 1.1, not to mention that my +# custom patches would all have to be redone, I felt that this is the +# easier road to take. +# +# Revision 1.1.1.1 1999/02/28 02:00:51 beazley +# Swig1.1 +# +# Revision 1.1 1996/08/12 01:55:02 dmb +# Initial revision +# +####################################################################### + +#.KEEP_STATE: + + +srcdir = @srcdir@ +VPATH = @srcdir@ + +# Set your C++ compiler here. g++ works on most machines, +# but you might have to change it depending on your installation. +# +CC = @CXX@ + +# +# Set the prefix below to indicate where you want SWIG to install its +# files. Normally this is /usr/local +# + +prefix = @prefix@ + +# Location of the SWIG library. Is normally put in /usr/local/lib/swig_lib +# The SWIG library contains configuration files and library modules +# so you should install it someplace where it can be easily accessed. + +SWIG_LIB = $(prefix)/lib/swig_lib + +# YACC parser. Use bison by default. if this doesn't work, switch +# it over to yacc. If that still doesn't work, let me know... + +YACC = @YACC@ + +# Comment out the following line if you're on an SGI or don't have ranlib! +RANLIB = @RANLIB@ +AR = @AR@ + +######################################################################## +# Normally, you shouldn't have to change anything below this point # +######################################################################## + +LIBOBJS = main.o scanner.o symbol.o include.o types.o parms.o emit.o newdoc.o ascii.o \ + html.o latex.o cplus.o lang.o hash.o sstring.o wrapfunc.o getopt.o comment.o \ + typemap.o naming.o + +LIBSRCS = main.cxx scanner.cxx symbol.cxx include.cxx types.cxx parms.cxx emit.cxx \ + newdoc.cxx ascii.cxx html.cxx latex.cxx cplus.cxx lang.cxx hash.cxx \ + sstring.cxx wrapfunc.cxx getopt.cxx comment.cxx typemap.cxx naming.cxx + +LIBHEADERS = internal.h ../Include/swig.h latex.h ascii.h html.h nodoc.h +LIB = ../libswig.a +PARSER = parser.y +INCLUDE = -I../Include +##-DSWIG_LIB='"$(SWIG_LIB)"' +CFLAGS = @CFLAGS@ -DSWIG_CC='"$(CC)"' @DEFS@ +SHELL = /bin/sh + +# +# +# +# Rules for creation of a .o file from .cxx +.SUFFIXES: .cxx +.cxx.o: + $(CC) $(INCLUDE) $(CFLAGS) -c -o $*.o $< + +all: $(LIB) + +$(LIB): parser.o $(LIBOBJS) + @echo "Building library" + $(AR) cr $(LIB) $(LIBOBJS) parser.o + $(RANLIB) $(LIB) + +parser.o: parser.cxx $(LIBHEADERS) + $(CC) $(INCLUDE) $(CFLAGS) parser.cxx -c -o parser.o + +parser.cxx: $(PARSER) + $(YACC) @YACCFLAGS@ + @cp y.tab.h parser.h + @cp y.tab.c parser.cxx + +parser:: + @cp y.tab.c.bison parser.cxx + @cp y.tab.h.bison parser.h + @cp y.tab.h.bison y.tab.h + $(CC) $(CFLAGS) parser.cxx -c -o parser.o + +Makefile: $(srcdir)/Makefile.in ../config.status + (cd ..; CONFIG_FILES=SWIG/Makefile $(SHELL) config.status) + +.PRECIOUS: Makefile + +clean:: + rm -f *.o libswig.a y.tab.c y.tab.h + +nuke:: + rm -f Makefile *~ #* core a.out + +wc:: + wc $(LIBSRCS) *.h parser.y + + diff --git a/wxPython/wxSWIG/SWIG/ascii.cxx b/wxPython/wxSWIG/SWIG/ascii.cxx new file mode 100644 index 0000000000..9028d0b87d --- /dev/null +++ b/wxPython/wxSWIG/SWIG/ascii.cxx @@ -0,0 +1,464 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "swig.h" +#include "ascii.h" +#include + +/******************************************************************************* + * $Header$ + * + * File : ascii.cxx + * + * Module for producing ASCII documentation. + * + *******************************************************************************/ + +// ----------------------------------------------------------------------------- +// ASCII::ASCII() +// +// Constructor. Initializes the ASCII module. +// +// Inputs : None +// +// Output : Documentation module object +// +// Side Effects : +// Sets page-width and indentation. +// ----------------------------------------------------------------------------- + +ASCII::ASCII() { + sect_count = 0; + indent = 8; + columns = 70; +} + +// ----------------------------------------------------------------------------- +// void ASCII::print_string(char *s, int margin, int mode) +// +// Prints a string to the documentation file. Performs line wrapping and +// other formatting. +// +// Inputs : +// s = NULL terminate ASCII string +// margin = Number of characters to be inserted on left side +// mode = If set, text will be reformatted. Otherwise, it's +// printed verbatim (with indentation). +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void ASCII::print_string(char *s, int margin, int mode) { + + char *c; + int i; + int lbreak = 0; + int col; + + c = s; + + if (!s) return; + // Apply indentation + + for (i = 0; i < margin; i++) + fputc(' ',f_doc); + + col = margin; + if (mode) { + + // Dump out text in formatted mode + + // Strip leading white-space + + while ((*c) && (isspace(*c))) { + c++; + } + while (*c) { + switch(*c) { + case '\n': + case '\\': + if (lbreak) { + col = margin; + fputc('\n',f_doc); + for (i = 0; i < margin; i++) + fputc(' ',f_doc); + lbreak = 0; + } else { + if ((*c) == '\n') { + col++; + } + lbreak++; + } + break; + case ' ': + case '\t': + case '\r': + case '\f': + if (col > columns) { + fputc('\n',f_doc); + for (i = 0; i < margin; i++) + fputc(' ',f_doc); + col = margin; + } else { + fputc(' ',f_doc); + col++; + } + // Skip over rest of white space found + while ((*c) && isspace(*c)) c++; + c--; + lbreak = 0; + break; + default : + if (lbreak) fputc(' ',f_doc); + lbreak = 0; + fputc(*c,f_doc); + col++; + break; + } + c++; + } + } else { + // Dump out text in pre-formatted mode + while (*c) { + switch(*c) { + case '\n': + fputc('\n',f_doc); + for (i = 0; i < margin; i++) + fputc(' ',f_doc); + break; + default : + fputc(*c,f_doc); + col++; + break; + } + c++; + } + } +} + +// ----------------------------------------------------------------------------- +// void ASCII::print_decl(DocEntry *de) +// +// Prints the documentation entry corresponding to a declaration +// +// Inputs : +// de = Documentation entry (which should be for a declaration) +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void ASCII::print_decl(DocEntry *de) { + + int i; + char *c; + + c = de->usage.get(); + fprintf(f_doc,"%s\n",c); + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + for (i = 0; i < indent; i++) + fputc(' ',f_doc); + fprintf(f_doc,"[ "); + print_string(c,0,1); + fprintf(f_doc," ]\n"); + } + } + + c = de->text.get(); + if (strlen(c) > 0) { + print_string(c,indent,de->format); + fprintf(f_doc,"\n"); + if (de->format) fputc('\n',f_doc); + } else { + fprintf(f_doc,"\n"); + } +} + +// ----------------------------------------------------------------------------- +// void ASCII::print_text(DocEntry *de) +// +// Prints the documentation for a block of text. Will strip any leading white +// space from the text block. +// +// Inputs : +// de = Documentation entry of text +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void ASCII::print_text(DocEntry *de) { + char *c; + c = de->text.get(); + if (strlen(c) > 0) { + while ((*c == '\n')) c++; + print_string(c,0,de->format); + fprintf(f_doc,"\n\n"); + } +} + +// ----------------------------------------------------------------------------- +// void ASCII::title(DocEntry *de) +// +// Sets the title of the documentation file. +// +// Inputs : +// de = Documentation entry of the title. +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void ASCII::title(DocEntry *de) { + char *c; + + c = de->usage.get(); + if (strlen(c) > 0) { + fprintf(f_doc,"%s\n\n",c); + } + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + fprintf(f_doc,"[ "); + print_string(c,0,1); + fprintf(f_doc," ]\n"); + } + } + + c = de->text.get(); + if (strlen(c)) { + print_string(c,0,de->format); + } + fprintf(f_doc,"\n\n"); +} + +// ----------------------------------------------------------------------------- +// void ASCII::newsection(DocEntry *de, int sectnum) +// +// Starts a new section. Will underline major sections and subsections, but +// not minor subsections. +// +// Inputs : +// de = Documentation entry of the section +// sectnum = Section number. +// +// Output : None +// +// Side Effects : +// Forces a new subsection to be created within the ASCII module. +// ----------------------------------------------------------------------------- + +void ASCII::newsection(DocEntry *de,int sectnum) { + int i,len = 0; + char temp[256]; + char *c; + + sect_num[sect_count] = sectnum; + sect_count++; + for (i = 0; i < sect_count; i++) { + sprintf(temp,"%d.",sect_num[i]); + fprintf(f_doc,"%s",temp); + len += strlen(temp); + } + c = de->usage.get(); + fprintf(f_doc," %s\n", c); + len += strlen(c) + 2; + + // Print an underline if this is a major category + + if (sect_count <= 1) { + for (i = 0; i < len; i++) + fputc('=',f_doc); + fputc('\n',f_doc); + } else if (sect_count == 2) { + for (i = 0; i < len; i++) + fputc('-',f_doc); + fputc('\n',f_doc); + } else { + fputc('\n',f_doc); + } + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + fprintf(f_doc,"[ "); + print_string(c,0,1); + fprintf(f_doc," ]\n\n"); + } + } + + // If there is a description text. Print it + + c = de->text.get(); + if (strlen(c) > 0) { + print_string(c,0,de->format); + fprintf(f_doc,"\n"); + } + fprintf(f_doc,"\n"); +} + +// ----------------------------------------------------------------------------- +// void ASCII::endsection() +// +// Ends the current section. It is an error to call this without having first +// called newsection(). +// +// Inputs : None +// +// Output : None +// +// Side Effects : +// Pops out of the current section, moving back into the parent section +// ----------------------------------------------------------------------------- + +void ASCII::endsection() { + if (sect_count > 0) sect_count--; +} + +// ----------------------------------------------------------------------------- +// void ASCII::separator() +// +// Prints a small dashed line that is used to designate the end of C++ class +// subsections. +// +// Inputs : None +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void ASCII::separator() { + int i; + for (i = 0; i < 10; i++) + fputc('-',f_doc); + fprintf(f_doc,"\n\n"); +} + +// ----------------------------------------------------------------------------- +// void ASCII::init(char *filename) +// +// Initializes the documentation module and opens up the documentation file. +// +// Inputs : filename = name of documentation file (without suffix) +// +// Output : None +// +// Side Effects : Opens the documentation file. +// ----------------------------------------------------------------------------- + +void ASCII::init(char *filename) { + char f[256]; + + sprintf(f,"%s.doc",filename); + sprintf(fn,"%s",filename); + f_doc = fopen(f,"w"); + if (f_doc == NULL) { + fprintf(stderr, "Unable to open %s\n", fn); + SWIG_exit(1); + } + +} + +// ----------------------------------------------------------------------------- +// void ASCII::close() +// +// Closes the documentation module. This function should only be called once +// +// Inputs : None +// +// Output : None +// +// Side Effects : Closes the documentation file. +// ----------------------------------------------------------------------------- + +void ASCII::close(void) { + + fclose(f_doc); + if (Verbose) + fprintf(stderr,"Documentation written to %s.doc\n", fn); + +} + +// ----------------------------------------------------------------------------- +// void ASCII::style(char *name, char *value) +// +// Looks for style parameters that the user might have supplied using the +// %style directive. Unrecognized options are simply ignored. +// +// Inputs : +// name = name of the style parameter +// value = value of the style parameter (optional) +// +// Output : None +// +// Side Effects : Can change internal settings of 'indent' and 'columns' members. +// ----------------------------------------------------------------------------- + +void ASCII::style(char *name, char *value) { + if (strcmp(name,"ascii_indent") == 0) { + if (value) { + indent = atoi(value); + } + } else if (strcmp(name,"ascii_columns") == 0) { + if (value) { + columns = atoi(value); + } + } +} + +// ----------------------------------------------------------------------------- +// void ASCII::parse_args(int argc, char **argv) +// +// Function for processing options supplied on the SWIG command line. +// +// Inputs : +// argc = Number of arguments +// argv = Argument strings +// +// Output : None +// +// Side Effects : May set various internal parameters. +// ----------------------------------------------------------------------------- + +static char *ascii_usage = "\ +ASCII Documentation Options (available with -dascii)\n\ + None available.\n\n"; + +void ASCII::parse_args(int argc, char **argv) { + int i; + + for (i = 0; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i],"-help") == 0) { + fputs(ascii_usage,stderr); + } + } + } +} + + diff --git a/wxPython/wxSWIG/SWIG/ascii.h b/wxPython/wxSWIG/SWIG/ascii.h new file mode 100644 index 0000000000..05794b621f --- /dev/null +++ b/wxPython/wxSWIG/SWIG/ascii.h @@ -0,0 +1,64 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ +/*********************************************************************** + * $Header$ + * + * ascii.h + * + * ASCII specific functions for producing documentation. Basically + * prints things out as 80 column ASCII. + ***********************************************************************/ + +class ASCII : public Documentation { +private: + FILE *f_doc; + char fn[256]; + void print_string(char *s,int indent,int mode); + int indent; // Indentation (for formatting) + int columns; // Number of columns (for formatting) + int sect_count; // Section counter + int sect_num[20]; // Section numbers + // Style parameters +public: + ASCII(); + void parse_args(int argc, char **argv); + void title(DocEntry *de); + void newsection(DocEntry *de, int sectnum); + void endsection(); + void print_decl(DocEntry *de); + void print_text(DocEntry *de); + void separator(); + void init(char *filename); + void close(void); + void style(char *name, char *value); +}; + + + + + + + + + + + + + + + + + + diff --git a/wxPython/wxSWIG/SWIG/comment.cxx b/wxPython/wxSWIG/SWIG/comment.cxx new file mode 100644 index 0000000000..5aade8c17f --- /dev/null +++ b/wxPython/wxSWIG/SWIG/comment.cxx @@ -0,0 +1,697 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" + +/******************************************************************************* + * $Header$ + * + * File : comment.cxx + * + * This is a semi-magical module for associating C/C++ comments with + * documentation entries. While this sounds like it might be easy, + * there are a number of subtle problems getting things to associate + * correctly. + * + * Here's the general idea : + * + * 1. The parser and scanner feed both C comments and documentation + * entries to this class. These may show up in really bizarre + * orders (not necessarily the order seen in an interface file). + * + * 2. We maintain separate lists of comments and documentation + * entries. + * + * 3. Periodically, we go through the list of documentation entries + * and see if we can associate any comments. + * + * 4. Upon completion of parsing, it's critical that we cleanup + * the lists using the cleanup() method. + * + *******************************************************************************/ + +// ----------------------------------------------------------------------------- +// struct Comment +// +// Structure used to maintain a linked list of comments for later use. +// ----------------------------------------------------------------------------- + +class Comment { +public: + String *text; // Text of the comment + int first_line; // First line of the comment + int last_line; // Last line of the comment + int column; // First column of comment + char *file; // Name of the file that it was in + Comment *next; // Next comment (when in a linked list) + Comment *prev; // Previous comment + static Comment *comment_list; // List of all comments + + Comment(char *t, int line, int col, char *f); + ~Comment(); + static Comment *find(DocEntry *de, CommentHandler *ch); + void attach(DocEntry *de, CommentHandler *ch); +}; + + +// ----------------------------------------------------------------------- +// Create a new comment. Automatically puts it on the linked list +// ----------------------------------------------------------------------- +Comment::Comment(char *t, int line, int col, char *f) { + int nlines = 0; + char *c; + + text = new String(t); + c = t; + while (*c) { + if (*c == '\n') nlines++; + c++; + } + first_line = line; + column = col; + last_line = line + nlines - 1; + file = copy_string(f); + if (comment_list) { + comment_list->prev = this; + } + next = comment_list; + comment_list = this; + prev = 0; +} + +// ----------------------------------------------------------------------- +// Destroy a comment +// ----------------------------------------------------------------------- +Comment::~Comment() { + delete text; + delete file; + // Remove from linked list (if applicable) + if (prev) { + prev->next = next; + } + if (next) { + next->prev = prev; + } + if (this == comment_list) comment_list = next; +} +// ----------------------------------------------------------------------- +// find(DocEntry *de, CommentHandler *ch) +// +// This function tries to a find a comment matching the search criteria +// of a given comment handler and documentation entry. +// ----------------------------------------------------------------------- + +Comment *Comment::find(DocEntry *de, CommentHandler *ch) { + Comment *c; + + c = comment_list; + + // Start walking down our list of stored comments + + while (c) { + // printf("Searching %x : %s\n", c, c->text->get()); + if (strcmp(de->file,c->file) == 0) { + + // At least comment is in the right file. Now check line numbers + + if (ch->location == BEFORE) { + + // Check to see if the last line of the comment is close + // enough to our declaration. + + if ((c->last_line <= de->line_number) && + ((de->line_number - c->last_line) <= ch->skip_lines)) { + return c; + } + } else { // AFTER mode + // Check to see if the first line of the comment is close + // enough to our declaration. + + if ((c->first_line >= de->end_line) && + ((c->first_line - de->end_line) <= ch->skip_lines)) { + return c; + } + } + // Check to see if the line numbers are too small. Comments + // are processed in order so there's no sense in checking + // all entries. + + if (c->last_line < de->line_number) + return 0; + + } + c = c->next; + } + return 0; +} + +// ----------------------------------------------------------------------- +// void attach(DocEntry *de, CommentHandler *ch) +// +// This function attachs a comment to a documentation entry and applies +// all of the style information in the comment handler. +// ----------------------------------------------------------------------- +void Comment::attach(DocEntry *de, CommentHandler *ch) { + int nlines = 0; + char **split = 0; + char *c; + int i,lnum,el; + if (!de) return; + + // If we're ignoring comments, forget it + if (ch->ignore) { + return; + } + + // If the comment is formatted, no style processing is applied + + if (de->format) { + de->text << *text; + return; + } + + // Untabify the comment + + if (ch->untabify) text->untabify(); + + // Count how many lines we have + + c = text->get(); + while (*c) { + if (*c == '\n') nlines++; + c++; + } + + if (nlines == 0) return; + + // Tokenize the documentation string into lines + + split = new char*[nlines+1]; + c = text->get(); + i = 0; + split[i] = c; + while (*c) { + if (*c == '\n') { + *(c++) = 0; + split[++i] = c; + } else c++; + } + lnum = 0; + + // Now process the chop_top and chop_bottom values + // if nlines < (chop_top + chop_bottom), then we do nothing + + if (nlines > (ch->chop_top + ch->chop_bottom)) { + lnum += ch->chop_top; + el = nlines-ch->chop_bottom; + } else { + el = nlines; + } + + // Now process in-between lines + + while (lnum < el) { + /* Chop line */ + if (split[lnum]) { + if (strlen(split[lnum]) > (unsigned) (ch->chop_left+ch->chop_right)) { + if (ch->chop_right > 0) + split[lnum][strlen(split[lnum]) - ch->chop_right] = 0; + de->text << &split[lnum][ch->chop_left]; + } + } + lnum++; + de->text << "\n"; + } + + // printf("*** ATTACHING %s : %s\n", de->usage.get(), de->text.get()); + delete split; +} + + +CommentHandler *comment_handler = 0; +Comment *Comment::comment_list = 0; + +// ------------------------------------------------------------------------ +// struct DocEntryList +// +// This structure manages a linked list of documentation entries that +// haven't had comments attached to them yet. +// +// As a general rule, this list tends to remain rather short. +// ------------------------------------------------------------------------ + +struct DocEntryList { + DocEntry *de; + CommentHandler *ch; + DocEntryList *next; + DocEntryList *prev; + static DocEntryList *doc_list; + + // ----------------------------------------------------------------------- + // Create a new list entry + // ----------------------------------------------------------------------- + DocEntryList(DocEntry *d, CommentHandler *c) { + + de = d; + ch = c; + next = doc_list; + prev = 0; + if (doc_list) + doc_list->prev = this; + doc_list = this; + + // Only allow a few doc entries to survive + + if (this->next) { + if (this->next->next) { + delete this->next->next; + } + } + } + + // ----------------------------------------------------------------------- + // Destroy a list entry + // ----------------------------------------------------------------------- + ~DocEntryList() { + if (prev) { + prev->next = next; + } + if (next) { + next->prev = prev; + } + if (this == doc_list) doc_list = next; + }; + + // ----------------------------------------------------------------------- + // static check() + // + // Checks the list of documentation entries to see if any can be associated. + // ----------------------------------------------------------------------- + + static void check() { + + DocEntryList *dl, *dl_temp; + Comment *cmt; + + // printf ("Checking\n"); + dl = doc_list; + while (dl) { + cmt = Comment::find(dl->de,dl->ch); + if (cmt) { + // Okay, we found a matching comment. Attach it to this + // documentation entry. + cmt->attach(dl->de,dl->ch); + + // Destroy the comment and doc list entry + delete cmt; + + // Declarations are always coming in order so we're going + // to blow away all of them past this point + + dl_temp = dl->next; + delete dl; + dl = dl_temp; + } else { + dl = dl->next; + } + } + } +}; + + +DocEntryList *DocEntryList::doc_list = 0; + +// ----------------------------------------------------------------------------- +// CommentHandler::CommentHandler() +// +// Constructor. Creates a new comment handler. Sets up some default values +// for comment handling. +// +// Inputs : None +// +// Output : New CommentHandler object. +// +// Side Effects : Sets default comment handling parameters. +// ----------------------------------------------------------------------------- + +CommentHandler::CommentHandler() { + skip_lines = 1; + location = AFTER; + chop_top = 0; + chop_bottom = 0; + chop_left = 3; + chop_right = 0; + untabify = 1; + ignore = 0; +} + +// ----------------------------------------------------------------------------- +// CommentHandler::CommentHandler(CommentHandler *c) +// +// Constructor. Creates a new comment handler, but copies attributes from +// another handler. +// +// Inputs : +// c = A different comment handler. +// +// Output : A new CommentHandler object. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +CommentHandler::CommentHandler(CommentHandler *c) { + skip_lines = c->skip_lines; + location = c->location; + chop_top = c->chop_top; + chop_bottom = c->chop_bottom; + chop_left = c->chop_left; + chop_right = c->chop_right; + untabify = c->untabify; + ignore = c->ignore; +} + +// ----------------------------------------------------------------------------- +// CommentHandler::~CommentHandler() +// +// Destructor. Destroys a comment handler. Does nothing interesting at the +// moment. +// +// Inputs : None +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +CommentHandler::~CommentHandler() { +} + +// ----------------------------------------------------------------------------- +// void CommentHandler::add_comment(char *text, int line_num, int col, char *file) +// +// This function takes a character string as comment text and appends +// it to the current comment string (which is held in Comment::comment_list) +// +// 1. If two comments appear in successive lines, they are +// concatenated. This is to handle C++ style comments like the +// one surrounding this text. +// +// 2. If a new comment appears, we simply create a new one +// +// Inputs : +// text = Text of the comment +// line_num = Starting line number of the comment +// col = Starting column of the comment +// file = File in which the comment was located. +// +// Output : None +// +// Side Effects : +// Saves the comment in an internal linked list. +// If multiple comments appear in succession, some may end up +// in our comment list permanently (ie. never attached to any +// particular declaration). +// ----------------------------------------------------------------------------- + +void CommentHandler::add_comment(char *text, int line_num, int col, char *file) { + + char *c; + int nlines = 0; + Comment *cmt; + + // printf("line_num = %d, %s\n", line_num,text); + + // Count up how many lines are in this comment + + c = text; + while (*c) { + if (*c == '\n') nlines++; + c++; + } + + // Check to see if this comment is in a successive line to the last one + + cmt = Comment::comment_list; + + if (cmt) { + + // Check for column alignment + if ((cmt->column == col) && (line_num == (cmt->last_line + 1)) && + (nlines <= 1)) { + *(cmt->text) << text; + cmt->last_line = line_num + nlines - 1; + } else { + // This is a new comment, add it to our list + cmt = new Comment(text,line_num,col,file); + } + } else { + cmt = new Comment(text,line_num,col,file); + } +} + +// ----------------------------------------------------------------------------- +// void CommentHanlder::set_entry(DocEntry *d) +// +// This grabs a DocEntry and hangs onto it. +// +// We will place the doc entry into our documentation list and then +// check it to see if any comments are sitting around. +// +// Inputs : d = Documentation Entry +// +// Output : None +// +// Side Effects : +// May attach comments to the documentation entry. In this case, +// comments and DocEntries may be removed from internal lists. +// ----------------------------------------------------------------------------- + +void CommentHandler::set_entry(DocEntry *d) { + + // printf("Set entry : file: %s, line %d, %s\n", d->file, d->line_number, d->usage.get()); + + // Create a new list entry and save it + + new DocEntryList(d,this); + + // Check all of the documentation entries to see if they can be placed + + DocEntryList::check(); + +} + +// ----------------------------------------------------------------------------- +// static void CommentHandler::cleanup() +// +// Checks all documentation entries and sees if there are any comments available. +// If so, they are attached. This function is usually only called upon completion +// of parsing. +// +// Inputs : None +// +// Output : None +// +// Side Effects : +// Removes documentation entries and comments from internal lists. +// +// ----------------------------------------------------------------------------- + +void CommentHandler::cleanup() { + int nc, nd; + Comment *c; + DocEntryList *d; + + DocEntryList::check(); + + // Figure out how bad we're doing on memory + + nc = 0; + nd = 0; + c = Comment::comment_list; + while (c) { + nc++; + c = c->next; + } + + d = DocEntryList::doc_list; + while(d) { + nd++; + d = d->next; + } + + if (Verbose) { + printf("%d unprocessed comments, %d unprocessed doc entries.\n",nc,nd); + } +} + +// ----------------------------------------------------------------------------- +// void CommentHandler::style(char *name, char *value) +// +// Processes comment handling style parameters. The following parameters +// are available : +// +// after - Comments appear after a declaration +// before - Comments appear before a declaration +// skip - Number of blank lines between comment and decl. +// chop_top - Number of lines to chop from top of a comment +// chop_bottom - Number of lines to chop from bottom of a comment +// chop_left - Number of characters to chop from left +// chop_right - Number of characters to chop from right +// tabify - Leave tabs in comment text +// untabify - Strip tabs and convert them into spaces. +// ignore - Ignore comments +// enable - Enable comments +// +// Inputs : +// name - Name of style parameter +// value - Optional parameter value +// +// Output : None +// +// Side Effects : Changes style of comment handler object. +// +// ----------------------------------------------------------------------------- + +void CommentHandler::style(char *name, char *value) { + + if (strcmp(name,"before") == 0) { + location = BEFORE; + } else if (strcmp(name,"after") == 0) { + location = AFTER; + } else if (strcmp(name,"skip") == 0) { + if (value) + skip_lines = atoi(value); + } else if (strcmp(name,"chop_top") == 0) { + if (value) + chop_top = atoi(value); + } else if (strcmp(name,"chop_bottom") == 0) { + if (value) + chop_bottom = atoi(value); + } else if (strcmp(name,"chop_left") == 0) { + if (value) + chop_left = atoi(value); + } else if (strcmp(name,"chop_right") == 0) { + if (value) + chop_right = atoi(value); + } else if (strcmp(name,"tabify") == 0) { + untabify = 0; + } else if (strcmp(name,"untabify") == 0) { + untabify = 1; + } else if (strcmp(name,"ignore") == 0) { + ignore = 1; + } else if (strcmp(name,"enable") == 0) { + ignore = 0; + } +} + +// ----------------------------------------------------------------------------- +// void CommentHandler::parse_args(int argc, char **argv) +// +// Function for processing command line options given on the SWIG command line. +// See the help string below for available options. +// +// Inputs : +// argc = Argument count +// argv = Argument strings +// +// Output : None +// +// Side Effects : +// Changes various style parameters for the top-level CommentHandler. +// ----------------------------------------------------------------------------- + +static char *comment_usage = "\ +Comment Style Options : \n\ + -Safter - Use comments after a declaration.\n\ + -Sbefore - Use comments before a declaration.\n\ + -Schop_bottom n - Chop n lines from bottom of comments.\n\ + -Schop_left n - Chop n characters from left of a comment.\n\ + -Schop_right n - Chop n characters from right of a comment.\n\ + -Schop_top n - Chop n lines from top of comments.\n\ + -Signore - Ignore comments.\n\ + -Sskip n - Max lines between comment and declaration.\n\ + -Stabify - Do not convert tabs.\n\ + -Suntabify - Convert tabs into spaces (the default).\n\n"; + +void CommentHandler::parse_args(int argc, char **argv) { + int i; + + for (i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i],"-Sbefore") == 0) { + this->style("before",0); + mark_arg(i); + } else if (strcmp(argv[i],"-Safter") == 0) { + this->style("after",0); + mark_arg(i); + } else if (strcmp(argv[i],"-Schop_top") == 0) { + if (argv[i+1]) { + this->style("chop_top",argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-Schop_bottom") == 0) { + if (argv[i+1]) { + this->style("chop_bottom",argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-Schop_left") == 0) { + if (argv[i+1]) { + this->style("chop_left",argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-Schop_right") == 0) { + if (argv[i+1]) { + this->style("chop_right",argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-Sskip") == 0) { + if (argv[i+1]) { + this->style("skip",argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-Suntabify") == 0) { + this->style("untabify",0); + mark_arg(i); + } else if (strcmp(argv[i],"-Stabify") == 0) { + this->style("tabify",0); + mark_arg(i); + } else if (strcmp(argv[i],"-Signore") == 0) { + this->style("ignore",0); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(comment_usage,stderr); + } + } + } +} diff --git a/wxPython/wxSWIG/SWIG/cplus.cxx b/wxPython/wxSWIG/SWIG/cplus.cxx new file mode 100644 index 0000000000..c2a20d12a2 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/cplus.cxx @@ -0,0 +1,2682 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" + +/******************************************************************************* + * $Header$ + * + * File : cplus.cxx + * + * This module defines parser entry points for supporting C++. Primarily + * this module is in charge of keeping track of the contents of C++ classes, + * organizing inheritance, and other things. + * + * Eventually this module will be merged with the type handling mechanism + * in SWIG 2.0 so it's a little messy right now. + * + * General comments : + * + * 1. The words "simple" and "C++" are rarely used in the same + * sentence. Therefore this module is going to be some sort + * of compromise. + * + * 2. I'm using the "Annotated C++ Reference Manual" (ARM) as my + * reference for handling certain cases. Of course, there + * is a high probability that I have misinterpreted or overlooked + * certain cases. + * + * 3. It is not my intent to write a full C++ compiler. + * + * My goals are simple : + * - Support simple ANSI C-like class member functions and data. + * - Support constructors and destructors. + * - static member functions. + * - basic inheritance. + * - virtual functions. + * - References + * + * I do not plan to support the following anytime in the near future + * - Operator overloading + * - templates + * + * Caution : + * + * The control flow in this module is completely insane. But here's the + * rough outline. + * + * Stage 1 : SWIG Parsing + * cplus_open_class() - Open up a new class + * cplus_* - Add members to class + * cplus_inherit() - Inherit from base classes + * cplus_class_close() - Close class + * + * ... + * cplus_open_class() + * ... + * cplus_class_close() + * + * ... and so on, until the end of the file + * + * After stage 1, all classes have been read, but nothing has been + * sent to the language module yet. + * + * Stage 2 : Code generation + * For each class we've saved, do this : + * lang->cpp_open_class() - Open class + * lang->cpp_* - Emit members + * lang->cpp_inherit() - Inherit + * lang->cpp_close_class() - Close class + * + * This two-stage approach solves a number of problems related to working + * with multiple files, mutually referenced classes, add adding methods. + * Just keep in mind that all C++ code is emitted *after* an entire SWIG + * file has been parsed. + * + * Improved code generation and inheritance of added methods (2/18/97): + * + * Each C++ declaration now has an associated function name attached to it. + * For example : + * + * class Foo { + * void bar(); + * } + * + * Generates a member function "bar()" with a accessor function named + * "Foo_bar()". We will use this recorded accessor function to generate + * better code for inheritance. For example : + * + * class Foo2 : public Foo { + * + * ... + * } + * + * Will create a function called "Foo2_bar()" that is really mapped + * onto the base-class method "Foo_bar()". This should improve + * code generation substantially. + * + * Tricky stuff : + * - Each target language is responsible for naming wrapper + * functions. + * + *******************************************************************************/ + +// Some status variables + +static int Inherit_mode = 0; // Set if we're inheriting members +static char *ccode = 0; // Set to optional C code (if available) +static Hash *localtypes; // Localtype hash +static int abstract =0; // Status bit set during code generation + +static int cpp_id = 0; + +// Forward references + +void cplus_member_func(char *, char *, DataType *, ParmList *, int); +void cplus_constructor(char *, char *, ParmList *); +void cplus_destructor(char *, char *); +void cplus_variable(char *, char *, DataType *); +void cplus_static_func(char *, char *, DataType *, ParmList *); +void cplus_declare_const(char *, char *, DataType *, char *); +void cplus_static_var(char *, char *, DataType *); +void cplus_inherit_decl(char **); + +// ----------------------------------------------------------------------------- +// void add_local_type(char *type, char *classname) +// void add_local_type(DataType *type, char *classname) +// +// Adds a new datatype to the local datatype hash. This is used to handle +// datatypes defined within a class. +// +// Inputs : Datatype to place in hash +// +// Output : None +// +// Side Effects : Updates localtypes hash. +// ----------------------------------------------------------------------------- + +static void add_local_type(char *type, char *classname) { + String str; + + if (!localtypes) return; // No hash table initialized, ignore this + + str << classname << "::" << type; + localtypes->add(type,copy_string(str)); +} + +void add_local_type(DataType *type, char *classname) { + add_local_type(type->name,classname); +} + +// ----------------------------------------------------------------------------- +// void update_local_type(DataType *type) +// +// Checks to see whether this datatype is part of a class definition. If so, +// we update the type-name by appending the class prefix to it. Uses the +// name stored in current_class unless unavailable. +// +// Inputs : type = Datatype +// +// Output : type is updated with a new name. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +static void update_local_type(DataType *type) { + + char *newname = 0; + + // Lookup the datatype in the hash table + + if (!localtypes) return; + + newname = (char *) localtypes->lookup(type->name); + if (newname) { + strcpy(type->name, newname); + } +} + +// ----------------------------------------------------------------------------- +// void update_parms(ParmList *l) +// +// Updates all of the parameters in a parameter list with the proper C++ prefix +// (if neccessary). +// +// Inputs : l = Parameter list +// +// Output : Parameter list l is updated (make sure its a copy!) +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +static void update_parms(ParmList *l) { + Parm *p; + p = l->get_first(); + while (p) { + update_local_type(p->t); + + // Check for default arguments + + if ((p->defvalue) && (localtypes)) { + char *s; + s = (char *) localtypes->lookup(p->defvalue); + if (s) { + delete p->defvalue; + p->defvalue = copy_string(s); + } + } + p = l->get_next(); + } +} + +// ----------------------------------------------------------------------- +// class CPP_member +// +// Base class for various kinds of C++ members +// ----------------------------------------------------------------------- +class CPP_member { +public: + char *name; // Name of the member + char *iname; // Name of member in the interpreter + int is_static; // Is this a static member? + int new_method; // Is this a new method (added by SWIG)? + int line; // What line number was this member on + char *file; // What file was this in? + char *code; // Was there any supplied code? + char *base; // Base class where this was defined + int inherited; // Was this member inherited? + DocEntry *de; // Documentation entry + CPP_member *next; // Next member (for building linked lists) + int id; // type id when created + + virtual void inherit(int) { }; // Inheritance rule (optional) + virtual void emit() = 0; // Emit rule +}; + +// ---------------------------------------------------------------------- +// class CPP_function : public CPP_member +// +// Structure for handling a C++ member function +// ---------------------------------------------------------------------- + +class CPP_function : public CPP_member { +public: + DataType *ret_type; + ParmList *parms; + int new_object; + int is_virtual; + + CPP_function(char *n, char *i, DataType *t, ParmList *l, int s, int v = 0) { + name = copy_string(n); + iname = copy_string(i); + ret_type = new DataType(t); + parms = new ParmList(l); + is_static = s; + is_virtual = v; + new_method = AddMethods; + new_object = NewObject; + inherited = Inherit_mode; + de = 0; + next = 0; + line = line_number; + file = input_file; + if (Inherit_mode) { + id = cpp_id; + } else { + id = type_id; + } + if (AddMethods) { + if (strlen(CCode.get())) + code = copy_string(CCode.get()); + else + code = 0; + } else { + code = 0; + } + } + void inherit(int mode) { + doc_entry = 0; // No documentation for an inherited member + if (mode & INHERIT_FUNC) { + // Set up the proper addmethods mode and provide C code (if provided) + int oldaddmethods = AddMethods; + int oldnewobject = NewObject; + AddMethods = new_method; + NewObject = new_object; + CCode = code; + if (is_static) { + cplus_static_func(name, iname, ret_type, parms); + } else { + cplus_member_func(name, iname, ret_type, parms, is_virtual); + } + AddMethods = oldaddmethods; + NewObject = oldnewobject; + CCode = ""; + } + } + void emit() { + ParmList *l; + DataType *t; + AddMethods = new_method; + NewObject = new_object; + doc_entry = de; // Restore documentation entry + line_number = line; // Restore line and file + input_file = file; + ccode = code; + + // Make a copy of the parameter list and upgrade its types + + l = new ParmList(parms); + t = new DataType(ret_type); + update_parms(l); + update_local_type(t); + if (is_static) { + lang->cpp_static_func(name, iname, t, l); + } else { + lang->cpp_member_func(name, iname, t, l); + } + l->check_defined(); + t->check_defined(); + delete l; + delete t; + } +}; + +// -------------------------------------------------------------------------- +// class CPP_constructor : public CPP_member +// +// Class for holding a C++ constructor definition. +// -------------------------------------------------------------------------- + +class CPP_constructor : public CPP_member { +public: + ParmList *parms; + CPP_constructor(char *n, char *i, ParmList *l) { + name = copy_string(n); + iname = copy_string(i); + parms = new ParmList(l); + new_method = AddMethods; + inherited = 0; + de = 0; + next = 0; + line = line_number; + file = input_file; + id = type_id; + if (AddMethods) { + if (strlen(CCode.get())) + code = copy_string(CCode.get()); + else + code = 0; + } else { + code = 0; + } + } + void emit() { + if (1) { + ParmList *l; + AddMethods = new_method; + doc_entry = de; + line_number = line; + input_file = file; + ccode = code; + + // Make a copy of the parameter list and upgrade its types + + l = new ParmList(parms); + update_parms(l); + lang->cpp_constructor(name,iname,l); + l->check_defined(); + delete l; + } else { + if (Verbose) { + fprintf(stderr,"%s:%d: Constructor for abstract base class ignored.\n", + file,line); + } + } + } +}; + + +// -------------------------------------------------------------------------- +// class CPP_destructor : public CPP_member +// +// Class for holding a destructor definition +// -------------------------------------------------------------------------- + +class CPP_destructor : public CPP_member { +public: + + CPP_destructor(char *n, char *i) { + name = copy_string(n); + iname = copy_string(i); + new_method = AddMethods; + de = 0; + next = 0; + inherited = 0; + line = line_number; + file = input_file; + id = type_id; + if (AddMethods) { + if (strlen(CCode.get())) + code = copy_string(CCode.get()); + else + code = 0; + } else { + code = 0; + } + + } + void emit() { + AddMethods = new_method; + doc_entry = de; + line_number = line; + input_file = file; + ccode = code; + lang->cpp_destructor(name, iname); + } +}; + +// ------------------------------------------------------------------------- +// class CPP_variable : public CPP_member +// +// Class for a managing a data member +// ------------------------------------------------------------------------- + +class CPP_variable : public CPP_member { +public: + DataType *type; + int status; + CPP_variable(char *n, char *i, DataType *t, int s) { + name = copy_string(n); + iname = copy_string(i); + type = new DataType(t); + is_static = s; + status = Status; + de = 0; + next = 0; + new_method = AddMethods; + line = line_number; + file = input_file; + if (Inherit_mode) { + id = cpp_id; + } else { + id = type_id; + } + code = 0; + inherited = 0; + } + + // Emit code for this + + void emit() { + DataType *t; + int old_status = Status; + doc_entry = de; + AddMethods = new_method; + Status = status; + line_number = line; + input_file = file; + ccode = code; + + t = new DataType(type); + if (t->qualifier) { + // if (strcmp(t->qualifier,"const") == 0) Status = Status | STAT_READONLY; + } + update_local_type(t); + if (!is_static) { + lang->cpp_variable(name,iname,t); + } else { + lang->cpp_static_var(name,iname,t); + } + t->check_defined(); + Status = old_status; + delete t; + } + + // Inherit into another class + + void inherit(int mode) { + int oldstatus = Status; + Status = status; + doc_entry = 0; + if (mode & INHERIT_VAR) { + if (!is_static) { + int oldaddmethods = AddMethods; + AddMethods = new_method; + CCode = code; + cplus_variable(name,iname,type); + AddMethods = oldaddmethods; + CCode = ""; + } else { + cplus_static_var(name,iname,type); + } + } + Status = oldstatus; + } +}; + +// ------------------------------------------------------------------------- +// class CPP_constant : public CPP_member +// +// Class for managing constant values +// ------------------------------------------------------------------------- + +class CPP_constant : public CPP_member { +public: + char *value; + DataType *type; + CPP_constant(char *n, char *i, DataType *t, char *v) { + name = copy_string(n); + iname = copy_string(i); + type = new DataType(t); + value = copy_string(v); + de = 0; + new_method = AddMethods; + next = 0; + line = line_number; + file = input_file; + if (Inherit_mode) + id = cpp_id; + else + id = type_id; + code = 0; + inherited = 0; + } + + void emit() { + doc_entry = de; + AddMethods = new_method; + line_number = line; + input_file = file; + ccode = code; + lang->cpp_declare_const(name,iname,type,value); + type->check_defined(); + } + + void inherit(int mode) { + doc_entry = 0; + if (mode & INHERIT_CONST) + cplus_declare_const(name, iname, type, value); + } +}; + +// ---------------------------------------------------------------------- +// class CPP_class +// +// Class for managing class members (internally) +// ---------------------------------------------------------------------- + +static char *inherit_base_class = 0; + +class CPP_class { +public: + char *classname; // Real class name + char *classrename; // New name of class (if applicable) + char *classtype; // class type (struct, union, class) + int strip; // Strip off class declarator + int wextern; // Value of extern wrapper variable for this class + int have_constructor; // Status bit indicating if we've seen a constructor + int have_destructor; // Status bit indicating if a destructor has been seen + int is_abstract; // Status bit indicating if this is an abstract class + int generate_default; // Generate default constructors + int objective_c; // Set if this is an objective C class + int error; // Set if this class can't be generated + int line; // Line number + char **baseclass; // Base classes (if any) + Hash *local; // Hash table for local types + Hash *scope; // Local scope hash table + DocEntry *de; // Documentation entry of class + CPP_member *members; // Linked list of members + CPP_class *next; // Next class + static CPP_class *classlist; // List of all classes stored + Pragma *pragmas; // Class pragmas + + CPP_class(char *name, char *ctype) { + CPP_class *c; + classname = copy_string(name); + classtype = copy_string(ctype); + classrename = 0; + baseclass = 0; + de = doc_entry; + local = new Hash; // Create hash table for storing local datatypes + scope = 0; + error = 0; + pragmas = 0; + line = line_number; + + // Walk down class list and add to end + + c = classlist; + if (c) { + while (c->next) { + c = c->next; + } + c->next = this; + } else { + classlist = this; + } + next = 0; + members = 0; + strip = 0; + wextern = WrapExtern; + have_constructor = 0; + have_destructor = 0; + is_abstract = 0; + generate_default = GenerateDefault; + objective_c = ObjCClass; + } + + // ------------------------------------------------------------------------------ + // Add a new C++ member to this class + // ------------------------------------------------------------------------------ + + void add_member(CPP_member *m) { + CPP_member *cm; + + // Set base class where this was defined + if (inherit_base_class) + m->base = inherit_base_class; + else + m->base = classname; + if (!members) { + members = m; + return; + } + cm = members; + while (cm->next) { + cm = cm->next; + } + cm->next = m; + } + // ------------------------------------------------------------------------------ + // Search for a member with the given name. Returns the member on success, 0 on failure + // ------------------------------------------------------------------------------ + + CPP_member *search_member(char *name) { + CPP_member *m; + char *c; + m = members; + while (m) { + c = m->iname ? m->iname : m->name; + if (strcmp(c,name) == 0) return m; + m = m->next; + } + return 0; + } + + // ------------------------------------------------------------------------------ + // Inherit. Put all the declarations associated with this class into the current + // ------------------------------------------------------------------------------ + + void inherit_decls(int mode) { + CPP_member *m; + m = members; + while (m) { + inherit_base_class = m->base; + cpp_id = m->id; + m->inherit(mode); + m = m->next; + } + inherit_base_class = 0; + } + + // ------------------------------------------------------------------------------ + // Emit all of the declarations associated with this class + // ------------------------------------------------------------------------------ + + void emit_decls() { + CPP_member *m = members; + int last_scope = name_scope(0); + abstract = is_abstract; + while (m) { + cpp_id = m->id; + name_scope(cpp_id); // Set proper naming scope + m->emit(); + m = m->next; + } + name_scope(last_scope); + } + + // ------------------------------------------------------------------------------ + // Search for a given class in the list + // ------------------------------------------------------------------------------ + + static CPP_class *search(char *name) { + CPP_class *c; + c = classlist; + if (!name) return 0; + while (c) { + if (strcmp(name,c->classname) == 0) return c; + c = c->next; + } + return 0; + } + + // ------------------------------------------------------------------------------ + // Add default constructors and destructors + // + // ------------------------------------------------------------------------------ + + void create_default() { + if (!generate_default) return; + + // Try to generate a constructor if not available. + CCode = ""; + AddMethods = 0; + if ((!have_constructor) && (1)) { + ParmList *l; + l = new ParmList(); + doc_entry = new DocDecl(classname,this->de); + cplus_constructor(classname,0,l); + }; + + if (!have_destructor) { + doc_entry = new DocDecl(classname,this->de); + cplus_destructor(classname,0); + } + } + + // ------------------------------------------------------------------------------ + // Dump *all* of the classes saved out to the various + // language modules (this does what cplus_close_class used to do) + // ------------------------------------------------------------------------------ + static void create_all(); +}; + +CPP_class *CPP_class::classlist = 0; +static CPP_class *current_class; + +void CPP_class::create_all() { + CPP_class *c; + c = classlist; + while (c) { + if (!c->error) { + current_class = c; + localtypes = c->local; + if ((!c->wextern) && (c->classtype)) { + ObjCClass = c->objective_c; + doc_entry = c->de; + lang->cpp_open_class(c->classname,c->classrename,c->classtype,c->strip); + lang->cpp_pragma(c->pragmas); + c->create_default(); + if (c->baseclass) + cplus_inherit_decl(c->baseclass); + c->emit_decls(); + doc_entry = c->de; + lang->cpp_close_class(); + } + } + c = c->next; + } +} + +// ----------------------------------------------------------------------------- +// char *cplus_base_class(char *name) +// +// Given a member name, return the base class that it belongs to. +// ----------------------------------------------------------------------------- + +char *cplus_base_class(char *name) { + CPP_member *m = current_class->search_member(name); + if (m) { + return m->base; + } + return 0; +} + +// ----------------------------------------------------------------------------- +// void cplus_open_class(char *name, char *rname, char *ctype) +// +// Opens up a new C++ class. If rname is given, we'll be renaming the +// class. This also sets up some basic type equivalence for the +// type checker. +// +// Inputs : +// name = Name of the class +// rname = New name of the class (using %name() directive) +// ctype = Class type ("class","struct", or "union") +// +// Output : None +// +// Side Effects : +// Creates a new class obect internally. +// Added type-mappings to the SWIG type-checker module. +// Sets a number of internal state variables for later use. +// +// ----------------------------------------------------------------------------- + +void cplus_open_class(char *name, char *rname, char *ctype) { + + extern void typeeq_derived(char *, char *, char *cast=0); + char temp[256]; + CPP_class *c; + + // Add some symbol table management here + + // Search for a previous class definition + + c = CPP_class::search(name); + if (c) { + if (c->classtype) { + // Hmmm. We already seem to have defined this class so we'll + // create a new class object for whatever reason + current_class = new CPP_class(name, ctype); + } else { + // Looks like a reference was made to this class earlier + // somehow, but no other information is known. We'll + // make it our current class and fix it up a bit + current_class = c; + c->classtype = copy_string(ctype); + } + } else { + // Create a new class + current_class = new CPP_class(name, ctype); + current_class->de = doc_entry; + } + + // Set localtypes hash to our current class + + localtypes = current_class->local; + + // If renaming the class, set the new name + + if (rname) { + current_class->classrename = copy_string(rname); + } + + // Make a typedef for both long and short versions of this datatype + + if (name) { + if (strlen(name)) { + if (strlen(ctype) > 0 && strcmp(ctype, "class") != 0) { + sprintf(temp,"%s %s", ctype, name); + typeeq_derived(temp,name); // Map "struct foo" to "foo" + typeeq_derived(name,temp); // Map "foo" to "struct foo" + } + } + } + + AddMethods = 0; // Reset add methods flag + +} + +// ----------------------------------------------------------------------------- +// DocEntry *cplus_set_class(char *name) +// +// This function sets the current class to a given name. If the class +// doesn't exist, this function will create one. If it already exists, +// we'll just use that. +// +// This function is used primarily to add or manipulate an already +// existing class, but in a different location. For example : +// +// %include "class.h" // Grab some classes +// ... +// %addmethods MyClass { // Add some members for shadow classes +// ... members ... +// } +// +// Sounds weird, but returns the documentation entry to class if it exists. +// The parser needs this so we can generate documentation correctly. +// +// Inputs : name = Name of the class +// +// Output : Documentation entry of class or NULL if it doesn't exist. +// The parser needs the documentation entry to properly associate +// new members. +// +// Side Effects : +// Changes the current class object. Resets a number of internal +// state variables. Should not be called inside of a open class +// declaration. +// ----------------------------------------------------------------------------- + +DocEntry *cplus_set_class(char *name) { + + CPP_class *c; + + // Look for a previous class definition + + c = CPP_class::search(name); + if (c) { + current_class = c; + localtypes = c->local; + return c->de; + } else { + fprintf(stderr,"%s:%d: Warning class %s undefined.\n",input_file,line_number,name); + current_class = new CPP_class(name,0); + localtypes = current_class->local; + return 0; + } +}; + +// This function closes a class open with cplus_set_class() + +void cplus_unset_class() { + current_class = 0; +} + +// ----------------------------------------------------------------------------- +// void cplus_class_close(char *name) +// +// Close a C++ class definition. Up to this point, we've only been collecting +// member definitions. This function merely closes the class object and +// stores it in a list. All classes are dumped after processing has completed. +// +// If name is non-null, it means that the name of the class has actually been +// set after all of the definitions. For example : +// +// typedef struct { +// double x,y,z +// } Vector; +// +// If this is the case, we'll use that as our classname and datatype. +// Otherwise, we'll just go with the classname and classtype set earlier. +// +// Inputs : name = optional "new name" for the class. +// +// Output : None +// +// Side Effects : Resets internal variables. Saves class in internal list. +// Registers the class with the language module, but doesn't +// emit any code. +// ----------------------------------------------------------------------------- + +void cplus_class_close(char *name) { + + if (name) { + // The name of our class suddenly changed by typedef. Fix things up + current_class->classname = copy_string(name); + + // This flag indicates that the class needs to have it's type stripped off + current_class->strip = 1; + } + + // If we're in C++ or Objective-C mode. We're going to drop the class specifier + + if ((CPlusPlus) || (ObjCClass)) { + current_class->strip = 1; + } + + // Register our class with the target language module, but otherwise + // don't do anything yet. + + char *iname; + if (current_class->classrename) iname = current_class->classrename; + else iname = current_class->classname; + + lang->cpp_class_decl(current_class->classname, iname, current_class->classtype); + + // Clear current class variable and reset + current_class = 0; + localtypes = 0; + +} + +// ----------------------------------------------------------------------------- +// void cplus_abort(void) +// +// Voids the current class--some kind of unrecoverable parsing error occurred. +// ----------------------------------------------------------------------------- + +void cplus_abort(void) { + current_class->error = 1; + current_class = 0; + localtypes = 0; +} + +// ----------------------------------------------------------------------------- +// void cplus_cleanup(void) +// +// This function is called after all parsing has been completed. It dumps all +// of the stored classes out to the language module. +// +// Inputs : None +// +// Output : None +// +// Side Effects : Emits all C++ wrapper code. +// ----------------------------------------------------------------------------- + +void cplus_cleanup(void) { + + // Dump all classes created at once (yikes!) + + CPP_class::create_all(); + lang->cpp_cleanup(); +} + +// ----------------------------------------------------------------------------- +// void cplus_inherit(int count, char **baseclass) +// +// Inherit from a baseclass. This function only really registers +// the inheritance, but doesn't do anything with it yet. +// +// Inputs : baseclass = A NULL terminated array of strings with the names +// of baseclasses. For multiple inheritance, there +// will be multiple entries in this list. +// +// Output : None +// +// Side Effects : Sets the baseclass variable of the current class. +// ----------------------------------------------------------------------------- + +void cplus_inherit(int count, char **baseclass) { + int i; + + // printf("Inheriting : count = %d, baseclass = %x\n",count,baseclass); + // If there are baseclasses, make copy of them + if (count) { + current_class->baseclass = (char **) new char*[count+1]; + for (i = 0; i < count; i++) + current_class->baseclass[i] = copy_string(baseclass[i]); + current_class->baseclass[i] = 0; + } else { + baseclass = 0; + } +} + +// ----------------------------------------------------------------------------- +// cplus_generate_types(char **baseclass) +// +// Generates the type-mappings between the current class and any associated +// base classes. This is done by performing a depth first search of the +// class hierarchy. Functions for performing correct type-casting are +// generated for each base-derived class pair. +// +// Inputs : baseclass = NULL terminated list of base classes +// +// Output : None +// +// Side Effects : Emits pointer conversion functions. Registers type-mappings +// with the type checking module. +// +// ----------------------------------------------------------------------------- + +static Hash convert; // Hash table of conversion functions + +void cplus_generate_types(char **baseclass) { + CPP_class *bc; + int i; + String cfunc, temp1, temp2, temp3; + extern void typeeq_derived(char *, char *, char *); + + if (!baseclass) { + return; + } + + // Generate type-conversion functions and type-equivalence + + i = 0; + while(baseclass[i]) { + cfunc = ""; + + bc = CPP_class::search(baseclass[i]); + if (bc) { + // Generate a conversion function (but only for C++) + + if (!current_class->objective_c) { + temp3 = ""; + temp3 << "Swig" << current_class->classname << "To" << bc->classname; + + if (convert.add(temp3,(void *) 1) != -1) { + + // Write a function for casting derived type to parent class + + cfunc << "static void *Swig" << current_class->classname << "To" << bc->classname + << "(void *ptr) {\n" + << tab4 << current_class->classname << " *src;\n" + << tab4 << bc->classname << " *dest;\n" + << tab4 << "src = (" << current_class->classname << " *) ptr;\n" + << tab4 << "dest = (" << bc->classname << " *) src;\n" + // << tab4 << "printf(\"casting...\\n\");\n" + << tab4 << "return (void *) dest;\n" + << "}\n"; + + fprintf(f_wrappers,"%s\n",cfunc.get()); + } + } else { + temp3 = "0"; + } + + // Make a type-equivalence allowing derived classes to be used in functions of the + + if (strlen(current_class->classtype) > 0 && + strcmp(current_class->classtype, "class") != 0) { + temp1 = ""; + temp1 << current_class->classtype << " " << current_class->classname; + temp2 = ""; + temp2 << bc->classtype << " " << bc->classname; + // Add various equivalences to the pointer table + + typeeq_derived(bc->classname, current_class->classname,temp3.get()); + typeeq_derived(temp2.get(), current_class->classname,temp3.get()); + typeeq_derived(temp2.get(), temp1.get(),temp3.get()); + typeeq_derived(bc->classname, temp1.get(),temp3.get()); + } else { + typeeq_derived(bc->classname, current_class->classname,temp3.get()); + } + // Now traverse the hierarchy some more + cplus_generate_types(bc->baseclass); + } + i++; + } +} + +// ----------------------------------------------------------------------------- +// void cplus_inherit_decl(char **baseclass) +// +// This function is called internally to handle inheritance between classes. +// Basically, we're going to generate type-checking information and call +// out to the target language to handle the inheritance. +// +// This function is only called when emitting classes to the language modules +// (after all parsing has been complete). +// +// Inputs : baseclass = NULL terminated list of base-class names. +// +// Output : None +// +// Side Effects : Generates type-mappings. Calls the language-specific +// inheritance function. +// ----------------------------------------------------------------------------- + +void cplus_inherit_decl(char **baseclass) { + + // If not base-classes, bail out + + if (!baseclass) return; + + Inherit_mode = 1; + lang->cpp_inherit(baseclass); // Pass inheritance onto the various languages + Inherit_mode = 0; + + // Create type-information for class hierarchy + + cplus_generate_types(baseclass); +} +// ----------------------------------------------------------------------------- +// void cplus_inherit_members(char *baseclass, int mode) +// +// Inherits members from a class. This is called by specific language modules +// to bring in members from base classes. It may or may not be called. +// +// This function is called with a *single* base-class, not multiple classes +// like other functions. To do multiple inheritance, simply call this +// with each of the associated base classes. +// +// Inputs : +// baseclass = Name of baseclass +// mode = Inheritance handling flags +// INHERIT_FUNC - Import functions in base class +// INHERIT_VAR - Import variables in base class +// INHERIT_CONST - Inherit constants +// INHERIT_ALL - Inherit everything (grossly inefficient) +// +// Output : None +// +// Side Effects : Imports methods from base-classes into derived classes. +// +// ----------------------------------------------------------------------------- + +void cplus_inherit_members(char *baseclass, int mode) { + CPP_class *bc; + + bc = CPP_class::search(baseclass); + if (bc) { + bc->inherit_decls(mode); + } else { + fprintf(stderr,"%s:%d: Warning. Base class %s undefined (ignored).\n", input_file, current_class->line, baseclass); + } +} + +// ----------------------------------------------------------------------------- +// void cplus_member_func(char *name, char *iname, DataType *type, ParmList *, is_virtual) +// +// Parser entry point to creating a C++ member function. This function primarily +// just records the function and does a few symbol table checks. +// +// Inputs : +// name = Real name of the member function +// iname = Renamed version (may be NULL) +// type = Return datatype +// l = Parameter list +// is_virtual = Set if this is a pure virtual function (ignored) +// +// Output : None +// +// Side Effects : +// Adds member function to current class. +// ----------------------------------------------------------------------------- + +void cplus_member_func(char *name, char *iname, DataType *type, ParmList *l, + int is_virtual) { + + CPP_function *f; + char *temp_iname; + + // First, figure out if we're renaming this function or not + + if (!iname) + temp_iname = name; + else + temp_iname = iname; + + // If we're in inherit mode, we need to check for duplicates. + // Issue a warning. + + if (Inherit_mode) { + if (current_class->search_member(temp_iname)) { + return; + } + } + + // Add it to our C++ class list + + f = new CPP_function(name,temp_iname,type,l,0,is_virtual); + f->de = doc_entry; + current_class->add_member(f); + + // If this is a pure virtual function, the class is abstract + + if (is_virtual) + current_class->is_abstract = 1; + +} + +// ----------------------------------------------------------------------------- +// void cplus_constructor(char *name, char *iname, ParmList *l) +// +// Parser entry point for creating a constructor. +// +// Inputs : +// name = Real name of the constructor (usually the same as the class) +// iname = Renamed version (may be NULL) +// l = Parameter list +// +// Output : None +// +// Side Effects : +// Adds a constructor to the current class. +// ----------------------------------------------------------------------------- + +void cplus_constructor(char *name, char *iname, ParmList *l) { + + CPP_constructor *c; + + // May want to check the naming scheme here + + c = new CPP_constructor(name,iname,l); + c->de = doc_entry; + current_class->add_member(c); + current_class->have_constructor = 1; + +} + +// ----------------------------------------------------------------------------- +// void cplus_destructor(char *name, char *iname) +// +// Parser entry point for adding a destructor. +// +// Inputs : +// name = Real name of the destructor (usually same as class name) +// iname = Renamed version (may be NULL) +// +// Output : None +// +// Side Effects : +// Adds a destructor to the current class +// +// ----------------------------------------------------------------------------- + +void cplus_destructor(char *name, char *iname) { + + CPP_destructor *d; + + d = new CPP_destructor(name,iname); + d->de = doc_entry; + current_class->add_member(d); + current_class->have_destructor = 1; +} + +// ----------------------------------------------------------------------------- +// void cplus_variable(char *name, char *iname, DataType *t) +// +// Parser entry point for creating a new member variable. +// +// Inputs : +// name = name of the variable +// iname = Renamed version (may be NULL) +// t = Datatype +// +// Output : None +// +// Side Effects : +// Adds a member variable to the current class +// ----------------------------------------------------------------------------- + +void cplus_variable(char *name, char *iname, DataType *t) { + + CPP_variable *v; + char *temp_iname; + + // If we're in inherit mode, we need to check for duplicates. + + if (iname) + temp_iname = iname; + else + temp_iname = name; + + if (Inherit_mode) { + if (current_class->search_member(temp_iname)) { + return; + } + } + + v = new CPP_variable(name,iname,t,0); + v->de = doc_entry; + current_class->add_member(v); +} + +// ----------------------------------------------------------------------------- +// void cplus_static_func(char *name, char *iname, DataType *type, ParmList *l) +// +// Parser entry point for creating a new static member function. +// +// Inputs : +// name = Real name of the function +// iname = Renamed version (may be NULL) +// type = Return datatype +// l = Parameter list +// +// Output : None +// +// Side Effects : +// Adds a static function to the current class. +// +// ----------------------------------------------------------------------------- + +void cplus_static_func(char *name, char *iname, DataType *type, ParmList *l) { + + char *temp_iname; + + // If we're in inherit mode, we need to check for duplicates. + + if (iname) temp_iname = iname; + else temp_iname = name; + + if (Inherit_mode) { + if (current_class->search_member(iname)) { + // Have a duplication + return; + } + } + + CPP_function *f = new CPP_function(name, temp_iname, type, l, 1); + f->de = doc_entry; + current_class->add_member(f); +} + +// ----------------------------------------------------------------------------- +// void cplus_declare_const(char *name, char *iname, DataType *type, char *value) +// +// Parser entry point for creating a C++ constant (usually contained in an +// enum). +// +// Inputs : +// name = Real name of the constant +// iname = Renamed constant (may be NULL) +// type = Datatype of the constant +// value = String representation of the value +// +// Output : None +// +// Side Effects : +// Adds a constant to the current class. +// ----------------------------------------------------------------------------- + +void cplus_declare_const(char *name, char *iname, DataType *type, char *value) { + + char *temp_iname; + + if (iname) temp_iname = iname; + else temp_iname = name; + + // If we're in inherit mode, we need to check for duplicates. + // Possibly issue a warning or perhaps a remapping + + if (Inherit_mode) { + if (current_class->search_member(temp_iname)) { + return; + } + } + + CPP_constant *c = new CPP_constant(name, temp_iname, type, value); + c->de = doc_entry; + current_class->add_member(c); + + // Update this symbol in the symbol table + update_symbol(name, type, value); + + // Add this symbol to local scope of a class + add_local_type(name, current_class->classname); +} + +// ----------------------------------------------------------------------------- +// void cplus_static_var(char *name, char *iname, DataType *type) +// +// Parser entry point for adding a static variable +// +// Inputs : +// name = Name of the member +// iname = Renamed version (may be NULL) +// type = Datatype +// +// Output : None +// +// Side Effects : +// Adds a static variable to the current class. +// ----------------------------------------------------------------------------- + +void cplus_static_var(char *name, char *iname, DataType *type) { + + char *temp_iname; + + if (iname) temp_iname = iname; + else temp_iname = name; + + // If we're in inherit mode, we need to check for duplicates. + // Possibly issue a warning or perhaps a remapping + + if (Inherit_mode) { + if (current_class->search_member(temp_iname)) { + return; + } + } + + CPP_variable *v = new CPP_variable(name, temp_iname, type, 1); + v->de = doc_entry; + current_class->add_member(v); +} + +// ----------------------------------------------------------------------------- +// cplus_add_pragma(char *lang, char *name, char *value) +// +// Add a pragma to a class +// ----------------------------------------------------------------------------- + +void cplus_add_pragma(char *lang, char *name, char *value) +{ + Pragma *pp; + Pragma *p = new Pragma; + p->filename = input_file; + p->lineno = line_number; + p->lang = lang; + p->name = name; + p->value = value; + + if (!current_class->pragmas) { + current_class->pragmas = p; + return; + } + pp = current_class->pragmas; + while (pp->next) { + pp = pp->next; + } + pp->next = p; +} + +// ------------------------------------------------------------------------------ +// C++/Objective-C code generation functions +// +// The following functions are responsible for generating the wrapper functions +// for C++ and Objective-C methods and variables. These functions are usually +// called by specific language modules, but individual language modules can +// choose to do something else. +// +// The C++ module sets a number of internal state variables before emitting various +// pieces of code. These variables are often checked implicitly by these +// procedures even though nothing is passed on the command line. +// +// The code generator tries to be somewhat intelligent about what its doing. +// The member_hash Hash table keeps track of wrapped members and is used for +// sharing code between base and derived classes. +// ----------------------------------------------------------------------------- + +static Hash member_hash; // Hash wrapping member function wrappers to scripting wrappers + +// ----------------------------------------------------------------------------- +// void cplus_emit_member_func(char *classname, char *classtype, char *classrename, +// char *mname, char *mrename, DataType *type, +// ParmList *l, int mode) +// +// This is a generic function to produce a C wrapper around a C++ member function. +// This function does the following : +// +// 1. Create a C wrapper function +// 2. Wrap the C wrapper function like a normal C function in SWIG +// 3. Add the function to the scripting language +// 4. Fill in the documentation entry +// +// Specific languages can choose to provide a different mechanism, but this +// function is used to provide a low-level C++ interface. +// +// The mode variable determines whether to create a new function or only to +// add it to the interpreter. This is used to support the %addmethods directive +// +// mode = 0 : Create a wrapper and add it (the normal mode) +// mode = 1 : Assume wrapper was already made and add it to the +// interpreter (%addmethods mode) +// +// Wrapper functions are usually created as follows : +// +// class Foo { +// int bar(args) +// } +// +// becomes .... +// Foo_bar(Foo *obj, args) { +// obj->bar(args); +// } +// +// if %addmethods mode is set AND there is supporting C code detected, make +// a function from it. The object is always called 'obj'. +// +// Then we wrap Foo_bar(). The name "Foo_bar" is actually contained in the parameter +// cname. This is so language modules can provide their own names (possibly for +// function overloading). +// +// This function makes no internal checks of the SWIG symbol table. This is +// up to the caller. +// +// Objective-C support (added 5/24/97) : +// +// If the class member function is part of an objective-C interface, everything +// works the same except that we change the calling mechanism to issue an +// Objective-C message. +// +// Optimizations (added 12/31/97) : +// +// For automatically generated wrapper functions. We now generate macros such +// as +// #define Foo_bar(a,b,c) (a->bar(b,c)) +// +// This should make the wrappers a little faster as well as reducing the amount +// of wrapper code. +// +// Inputs : +// classname = Name of C++ class +// classtype = Type of class (struct, union, class) +// classrename = Renamed class (if any) +// mname = Member name +// mrename = Renamed member +// type = Return type of the function +// l = Parameter list +// mode = addmethods mode +// +// Output : None +// +// Side Effects : +// Creates C accessor function in the wrapper file. +// Calls the language module to create a wrapper function. +// ----------------------------------------------------------------------------- + +void cplus_emit_member_func(char *classname, char *classtype, char *classrename, + char *mname, char *mrename, DataType *type, ParmList *l, + int mode) { + Parm *p; + ParmList *newparms; + int i; + String wrap; + String cname,iname; + String key; + String argname; + char *prefix; + char *prev_wrap = 0; + char *temp_mname; + + cname = ""; + iname = ""; + key = ""; + + // First generate a proper name for the member function + + // Get the base class of this member + if (!mrename) temp_mname = mname; + else temp_mname = mrename; + + char *bc = cplus_base_class(temp_mname); + if (!bc) bc = classname; + if (strlen(bc) == 0) bc = classname; + + // Generate the name of the C wrapper function (is always the same, regardless + // of renaming). + + cname << name_member(mname,bc); + + // Generate the scripting name of this function + if (classrename) + prefix = classrename; + else + prefix = classname; + + if (mrename) + iname << name_member(mrename,prefix); + else + iname << name_member(mname,prefix); + + // Now check to see if we have already wrapped a function like this. + // If so, we'll just use the existing wrapper. + + key << cname << "+"; + l->print_types(key); + // printf("key = %s\n", (char *) key); + char *temp = copy_string(iname); + if ((member_hash.add(key,temp)) == -1) { + delete [] temp; + prev_wrap = (char *) member_hash.lookup(key); + } + + // Only generate code if an already existing wrapper doesn't exist + + if (!prev_wrap) { + + // If mode = 0: Then we go ahead and create a wrapper macro + + if (!mode) { + cname = ""; + cname << iname; + wrap << "#define " << cname << "(_swigobj"; + + // Walk down the parameter list and Spit out arguments + + i = 0; + p = l->get_first(); + while (p != 0) { + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + wrap << ",_swigarg" << i; + i++; + } + p = l->get_next(); + } + + wrap << ") ("; + + if (!ObjCClass) { + wrap << "_swigobj->" << mname << "("; // C++ invocation + } else { + wrap << "[ _swigobj " << mname; // Objective C invocation + } + i = 0; + p = l->get_first(); + while(p != 0) { + if (ObjCClass) wrap << " " << p->objc_separator; + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + wrap << "_swigarg" << i; + i++; + } + p = l->get_next(); + if ((p != 0) && (!ObjCClass)) + wrap << ","; + } + if (!ObjCClass) + wrap << "))\n"; + else + wrap << "])\n"; + + // Emit it + fprintf(f_wrappers,"%s",wrap.get()); + } else { + if (ccode) { + wrap << "static "; + if (type->is_reference) { + type->is_pointer--; + } + wrap << type->print_full(); + if (type->is_reference) { + wrap << "&"; + type->is_pointer++; + } + wrap << " " << cname << "(" << classtype << classname << " *self"; + + // Walk down the parameter list and Spit out arguments + + p = l->get_first(); + while (p != 0) { + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + wrap << ","; + if ((p->call_type & CALL_REFERENCE) || (p->t->is_reference)) { + p->t->is_pointer--; + } + wrap << p->t->print_full(); + if ((p->call_type & CALL_REFERENCE) || (p->t->is_reference)) { + p->t->is_pointer++; + if (p->t->is_reference) + wrap << "&"; + } + wrap << " " << p->name; + } + p = l->get_next(); + } + + wrap << ") " << ccode; + fprintf(f_wrappers,"%s\n",wrap.get()); + } + } + + // Now add a parameter to the beginning of the function and call + // a language specific function to add it. + + newparms = new ParmList(l); + p = new Parm(0,0); + p->t = new DataType; + p->t->type = T_USER; + p->t->is_pointer = 1; + p->t->id = cpp_id; + p->call_type = 0; + + sprintf(p->t->name,"%s%s", classtype,classname); + p->name = "self"; + newparms->insert(p,0); // Attach parameter to beginning of list + + // Now wrap the thing. The name of the function is iname + + lang->create_function(cname, iname, type, newparms); + delete newparms; + } else { + // Already wrapped this function. Just patch it up + lang->create_command(prev_wrap, iname); + } +} + + +// ----------------------------------------------------------------------------- +// void cplus_emit_static_func(char *classname, char *classtype, char *classrename, +// char *mname, char *mrename, DataType *type, +// ParmList *l, int mode) +// +// This is a generic function to produce a wrapper for a C++ static member function +// or an Objective-C class method. +// +// Specific languages can choose to provide a different mechanism, but this +// function is used to provide a low-level C++ interface. +// +// The mode variable determines whether to create a new function or only to +// add it to the interpreter. This is used to support the %addmethods directive +// +// mode = 0 : Create a wrapper and add it (the normal mode) +// mode = 1 : Assume wrapper was already made and add it to the +// interpreter (%addmethods mode) +// +// Wrapper functions are usually created as follows : +// +// class Foo { +// static int bar(args) +// } +// +// becomes a command called Foo_bar() +// +// if %addmethods mode is set AND there is supporting C code detected, make +// a function from it. +// +// Then we wrap Foo_bar(). The name "Foo_bar" is actually contained in the parameter +// cname. This is so language modules can provide their own names (possibly for +// function overloading). +// +// This function makes no internal checks of the SWIG symbol table. This is +// up to the caller. +// +// Inputs : +// classname = Name of C++ class +// classtype = Type of class (struct, union, class) +// classrename = Renamed version of class (optional) +// mname = Member name +// mrename = Renamed member (optional) +// type = Return type of the function +// l = Parameter list +// mode = addmethods mode +// +// Output : None +// +// ----------------------------------------------------------------------------- + +void cplus_emit_static_func(char *classname, char *, char *classrename, + char *mname, char *mrename, DataType *type, ParmList *l, + int mode) { + Parm *p; + String wrap; + String cname, iname, key; + int i; + char *prefix; + char *prev_wrap = 0; + char *temp_mname; + + cname = ""; + iname = ""; + key = ""; + + // Generate a function name for the member function + + if (!mrename) temp_mname = mname; + else temp_mname = mrename; + char *bc = cplus_base_class(temp_mname); + if (!bc) bc = classname; + if (strlen(bc) == 0) bc = classname; + + // Generate the name of the C wrapper function + if ((!mode) && (!ObjCClass)) { + cname << bc << "::" << mname; + } else { + cname << name_member(mname,bc); + } + + // Generate the scripting name of this function + if (classrename) + prefix = classrename; + else + prefix = classname; + + if (mrename) + iname << name_member(mrename,prefix); + else + iname << name_member(mname,prefix); + + // Perform a hash table lookup to see if we've wrapped anything like this before + + key << cname << "+"; + l->print_types(key); + char *temp = copy_string(iname); + if ((member_hash.add(key,temp)) == -1) { + delete [] temp; + prev_wrap = (char *) member_hash.lookup(key); + } + + if (!prev_wrap) { + if (!((mode) || (ObjCClass))) { + // Not an added method and not objective C, just wrap it + lang->create_function(cname,iname, type, l); + } else { + // This is either an added method or an objective C class function + // + // If there is attached code, use it. + // Otherwise, assume the function has been written already and + // wrap it. + + wrap << "static " << type->print_full() << " " << cname << "("; + + // Walk down the parameter list and Spit out arguments + p = l->get_first(); + while (p != 0) { + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + if (p->t->is_reference) { + p->t->is_pointer--; + } + wrap << p->t->print_full(); + if (p->t->is_reference) { + p->t->is_pointer++; + wrap << "&"; + } + wrap << " " << p->name; + } + p = l->get_next(); + if (p) wrap << ","; + } + wrap << ") "; + if ((mode) && (ccode)) { + wrap << ccode; + } else if (ObjCClass) { + // This is an objective-C method + + wrap << "{\n" << tab4; + + // Emit the function call. + + if ((type->type != T_VOID) || (type->is_pointer)) { + // Declare the return value + + if (type->is_reference) { + type->is_pointer--; + wrap << tab4 << type->print_full() << "& _result = "; + type->is_pointer++; + } else { + wrap << tab4 << type->print_type() << " _result = " << type->print_cast(); + } + } else { + wrap << tab4; + } + wrap << "[ " << classname << " " << mname; // Objective C invocation + i = 0; + p = l->get_first(); + while(p != 0) { + wrap << " " << p->objc_separator; + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + if (p->t->is_reference) { + wrap << "*"; + } + wrap << p->name; + i++; + } + p = l->get_next(); + } + wrap << "];\n"; + + if ((type->type != T_VOID) || (type->is_pointer)) { + if (type->is_reference) { + wrap << tab4 << "return " << type->print_cast() << " &_result;\n"; + } else { + wrap << tab4 << "return _result;\n"; + } + } + wrap << "}\n"; + } + if (ObjCClass || (mode && ccode)) + fprintf(f_wrappers,"%s\n",wrap.get()); + lang->create_function(cname,iname,type,l); + } + } else { + // Already wrapped this function. Just hook up to it. + lang->create_command(prev_wrap, iname); + } +} + +// ----------------------------------------------------------------------------- +// void cplus_emit_destructor(char *classname, char *classtype, char *classrename, +// char *mname, char *mrename, int mode) +// +// Emit a C wrapper around a C++ destructor. +// +// Usually this function is used to do the following : +// class Foo { +// ... +// ~Foo(); +// } +// +// becomes .... +// void delete_Foo(Foo *f) { +// delete f; +// } +// +// Then we wrap delete_Foo(). +// +// Inputs : +// classname = Name of the C++ class +// classtype = Type of class (struct,class,union) +// classrename = Renamed class (optional) +// mname = Name of the destructor +// mrename = Name of the function in the interpreter +// mode = addmethods mode (0 or 1) +// +// Output : None +// +// Side Effects : +// Creates a destructor function and wraps it. +// ----------------------------------------------------------------------------- + +void cplus_emit_destructor(char *classname, char *classtype, char *classrename, + char *mname, char *mrename, int mode) +{ + Parm *p; + DataType *type; + ParmList *l; + String wrap; + String cname,iname; + char *prefix; + + // Construct names for the function + + if (classrename) + prefix = classrename; + else + prefix = classname; + + cname << name_destroy(classname); + if (mrename) + iname << name_destroy(mrename); + else + iname << name_destroy(prefix); + + if (!mode) { + // Spit out a helper function for this member function + wrap << "#define " << cname << "(_swigobj) ("; + if (ObjCClass) { + wrap << "[_swigobj " << mname << "])\n"; // Name of the member is the destructor + } else if (CPlusPlus) + wrap << "delete _swigobj)\n"; + else + wrap << "free ((char *) _swigobj))\n"; + fprintf(f_wrappers,"%s", wrap.get()); + } else { + if (ccode) { + wrap << "static void " << cname << "(" << classtype << classname << " *self) " << ccode; + fprintf(f_wrappers,"%s\n",wrap.get()); + } + } + + // Make a parameter list for this function + + l = new ParmList; + p = new Parm(0,0); + p->t = new DataType; + p->t->type = T_USER; + p->t->is_pointer = 1; + p->t->id = cpp_id; + p->call_type = 0; + sprintf(p->t->name,"%s%s", classtype, classname); + p->name = "self"; + l->insert(p,0); + + type = new DataType; + type->type = T_VOID; + sprintf(type->name,"void"); + type->is_pointer = 0; + type->id = cpp_id; + + // iname is the desired name of the function in the target language + + lang->create_function(cname,iname,type,l); + + delete type; + delete l; + +} + +// ----------------------------------------------------------------------------- +// void cplus_emit_constructor(char *classname, char *classtype, char *classrename, +// char *mname, char *mrename, ParmList *l, int mode) +// +// Creates a C wrapper around a C++ constructor +// +// Inputs : +// classname = name of class +// classtype = type of class (struct,class,union) +// classrename = Renamed class (optional) +// mname = Name of constructor +// mrename = Renamed constructor (optional) +// l = Parameter list +// mode = addmethods mode +// +// Output : None +// +// Side Effects : +// Creates a C wrapper and calls the language module to wrap it. +// ----------------------------------------------------------------------------- + +void cplus_emit_constructor(char *classname, char *classtype, char *classrename, + char *mname, char *mrename, ParmList *l, int mode) +{ + Parm *p; + int i; + DataType *type; + String wrap; + String fcall,cname,iname,argname; + char *prefix; + + // Construct names for the function + + if (classrename) + prefix = classrename; + else + prefix = classname; + + cname << name_construct(classname); + if (mrename) + iname << name_construct(mrename); + else + iname << name_construct(prefix); + + // Create a return type + + type = new DataType; + type->type = T_USER; + sprintf(type->name,"%s%s", classtype,classname); + type->is_pointer = 1; + type->id = cpp_id; + + if (!mode) { + wrap << "#define " << iname << "("; + cname = ""; + cname << iname; + if (ObjCClass) { + fcall << type->print_cast() << "[" << classname << " " << mname; + } else if (CPlusPlus) { + fcall << "new " << classname << "("; + } else { + fcall << type->print_cast() << " calloc(1,sizeof(" + << classtype << classname << "))"; + } + + // Walk down the parameter list and spit out arguments + + i = 0; + p = l->get_first(); + while (p != 0) { + if (ObjCClass) fcall << " " << p->objc_separator; + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + wrap << "_swigarg" << i; + + // Emit an argument in the function call if in C++ mode + + if ((CPlusPlus) || (ObjCClass)) { + fcall << "_swigarg" << i; + } + } + i++; + p = l->get_next(); + if (p) { + wrap << ","; + if ((CPlusPlus) && (!ObjCClass)) + fcall << ","; + } + } + + wrap << ") "; + if (ObjCClass) fcall << "]"; + else if (CPlusPlus) fcall << ")"; + + wrap << "(" << fcall << ")\n"; + fprintf(f_wrappers,"%s",wrap.get()); + } else { + if (ccode) { + wrap << "static " << classtype << classname << " *" << cname << "("; + + // Walk down the parameter list and spit out arguments + + p = l->get_first(); + while (p != 0) { + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + if (p->call_type & CALL_REFERENCE) { + p->t->is_pointer--; + } + wrap << p->t->print_real(p->name); + if (p->call_type & CALL_REFERENCE) { + p->t->is_pointer++; + } + p = l->get_next(); + if (p) { + wrap << ","; + } + } else { + p = l->get_next(); + } + } + wrap << ") " << ccode << "\n"; + fprintf(f_wrappers,"%s\n",wrap.get()); + } + } + + // If we had any C++ references, get rid of them now + + if (!mode) { + p = l->get_first(); + while (p) { + // p->t->is_reference = 0; + p = l->get_next(); + } + } + + // We've now created a C wrapper. We're going to add it to the interpreter + + lang->create_function(cname, iname, type, l); + delete type; +} + +// ----------------------------------------------------------------------------- +// void cplus_emit_variable_get(char *classname, char *classtype, char *classrename, +// char *mname, char *mrename, DataType *type, int mode) +// +// Writes a C wrapper to extract a data member +// +// Usually this function works as follows : +// +// class Foo { +// double x; +// } +// +// becomes : +// +// double Foo_x_get(Foo *obj) { +// return obj->x; +// } +// +// Optimization : 12/31/97 +// +// Now emits a macro like this : +// +// #define Foo_x_get(obj) (obj->x) +// +// Inputs : +// classname = name of C++ class +// classtype = type of class (struct, class, union) +// classrename = Renamed class +// mname = Member name +// mrename = Renamed member +// type = Datatype of the member +// mode = Addmethods mode +// +// Output : None +// +// Side Effects : +// Creates a C accessor function and calls the language module +// to make a wrapper around it. +// ----------------------------------------------------------------------------- + +void cplus_emit_variable_get(char *classname, char *classtype, char *classrename, + char *mname, char *mrename, DataType *type, int mode) { + + Parm *p; + ParmList *l; + String wrap; + String cname, iname, key; + char *prefix; + char *tm; + String source; + char *temp_mname; + char *prev_wrap = 0; + + cname = ""; + iname = ""; + key = ""; + + // First generate a proper name for the get function + + // Get the base class of this member + if (!mrename) temp_mname = mname; + else temp_mname = mrename; + + char *bc = cplus_base_class(temp_mname); + if (!bc) bc = classname; + if (strlen(bc) == 0) bc = classname; + + // Generate the name of the C wrapper function (is always the same, regardless + // of renaming). + + cname << name_get(name_member(mname,bc)); + + // Generate the scripting name of this function + if (classrename) + prefix = classrename; + else + prefix = classname; + + if (mrename) + iname << name_get(name_member(mrename,prefix)); + else + iname << name_get(name_member(mname,prefix)); + + // Now check to see if we have already wrapped a variable like this. + + key << cname; + char *temp = copy_string(iname); + if ((member_hash.add(key,temp)) == -1) { + delete [] temp; + prev_wrap = (char *) member_hash.lookup(key); + } + + // Only generate code if already existing wrapper doesn't exist + if (!prev_wrap) { + if (!mode) { + // Get any sort of typemap that might exist + + source << "obj->" << mname; + + // Now write a function to get the value of the variable + + tm = typemap_lookup("memberout",typemap_lang,type,mname,source,"result"); + + if ((type->type == T_USER) && (!type->is_pointer)) { + type->is_pointer++; + if (tm) { + wrap << "static " << type->print_type() << " " << cname << "(" + << classtype << classname << " *obj) {\n" + << tab4 << type->print_type() << " result;\n" + << tm << "\n" + << tab4 << "return result;\n" + << "}\n"; + } else { + wrap << "#define " << cname << "(_swigobj) " + << "(&_swigobj->" << mname << ")\n"; + } + type->is_pointer--; + } else { + if (tm) { + wrap << "static " << type->print_type() << " " << cname << "(" + << classtype << classname << " *obj) {\n" + << tab4 << type->print_type() << " result;\n" + << tm << "\n" + << tab4 << "return result;\n" + << "}\n"; + } else { + wrap << "#define " << cname << "(_swigobj) ("; + if (!type->is_reference) wrap << type->print_cast(); + else + wrap << "&"; + wrap << " _swigobj->" << mname << ")\n"; + } + } + fprintf(f_wrappers,"%s",wrap.get()); + } + + // Wrap this function + + l = new ParmList; + p = new Parm(0,0); + p->t = new DataType; + p->t->type = T_USER; + p->t->is_pointer = 1; + p->t->id = cpp_id; + p->call_type = 0; + p->name = "self"; + sprintf(p->t->name,"%s%s", classtype,classname); + l->insert(p,0); + + if ((type->type == T_USER) && (!type->is_pointer)) { + type->is_pointer++; + lang->create_function(cname,iname, type, l); + type->is_pointer--; + } else { + int is_ref = type->is_reference; + type->is_reference = 0; + lang->create_function(cname,iname, type, l); + type->is_reference = is_ref; + } + delete l; + } else { + // Already wrapped this function. Just patch it up + lang->create_command(prev_wrap,iname); + } + +} + +// ----------------------------------------------------------------------------- +// void cplus_emit_variable_set(char *classname, char *classtype, char *mname, +// char *cname, char *iname, DataType *type, int mode) +// +// Writes a C wrapper to set a data member +// +// Usually this function works as follows : +// +// class Foo { +// double x; +// } +// +// becomes : +// +// double Foo_x_set(Foo *obj, double value) { +// return (obj->x = value); +// } +// +// Need to handle special cases for char * and for user defined types. +// +// 1. char * +// +// Will free previous contents (if any) and allocate +// new storage. Could be risky, but it's a reasonably +// natural thing to do. +// +// 2. User_Defined +// Will assign value from a pointer. +// Will return a pointer to current value. +// +// +// Optimization, now defined as a C preprocessor macro +// +// Inputs : +// classname = name of C++ class +// classtype = type of class (struct, class, union) +// mname = Member name +// cname = Name of the C function for this (ie. Foo_bar_get) +// iname = Interpreter name of ths function +// type = Datatype of the member +// mode = Addmethods mode +// +// Output : None +// +// Side Effects : +// Creates a C accessor function and calls the language module +// to wrap it. +// ----------------------------------------------------------------------------- + +void cplus_emit_variable_set(char *classname, char *classtype, char *classrename, + char *mname, char *mrename, DataType *type, int mode) { + + Parm *p; + ParmList *l; + String wrap; + int is_user = 0; + char *tm; + String target; + String cname, iname, key; + char *temp_mname; + char *prefix; + char *prev_wrap = 0; + + cname = ""; + iname = ""; + key = ""; + + // First generate a proper name for the get function + + // Get the base class of this member + if (!mrename) temp_mname = mname; + else temp_mname = mrename; + + char *bc = cplus_base_class(temp_mname); + if (!bc) bc = classname; + if (strlen(bc) == 0) bc = classname; + + // Generate the name of the C wrapper function (is always the same, regardless + // of renaming). + + cname << name_set(name_member(mname,bc)); + + // Generate the scripting name of this function + if (classrename) + prefix = classrename; + else + prefix = classname; + + if (mrename) + iname << name_set(name_member(mrename,prefix)); + else + iname << name_set(name_member(mname,prefix)); + + // Now check to see if we have already wrapped a variable like this. + + key << cname; + char *temp = copy_string(iname); + if ((member_hash.add(key,temp)) == -1) { + delete [] temp; + prev_wrap = (char *) member_hash.lookup(key); + } + + // Only generate code if already existing wrapper doesn't exist + + if (!prev_wrap) { + if (!mode) { + + target << "obj->" << mname; + + // Lookup any typemaps that might exist + tm = typemap_lookup("memberin",typemap_lang,type,mname,"val",target); + + // First write a function to set the variable + + if (tm) { + if ((type->type == T_USER) && (!type->is_pointer)) { + type->is_pointer++; + is_user = 1; + } + wrap << "static " << type->print_type() << " " << cname << "(" + << classtype << classname << " *obj, " << type->print_real("val") << ") {\n"; + if (is_user) { + type->is_pointer--; + } + wrap << tm << "\n"; + // Return the member + if (is_user) type->is_pointer++; + wrap << tab4 << "return " << type->print_cast() << " val;\n"; + if (is_user) type->is_pointer--; + wrap << "}\n"; + + } else { + if ((type->type != T_VOID) || (type->is_pointer)){ + if (!type->is_pointer) { + + wrap << "#define " << cname << "(_swigobj,_swigval) ("; + // Have a real value here (ie. not a pointer). + // If it's a user defined type, we'll do something special. + // Otherwise, just assign it. + + if (type->type != T_USER) { + wrap << "_swigobj->" << mname << " = _swigval"; + } else { + wrap << "_swigobj->" << mname << " = *(_swigval)"; + } + wrap << ",_swigval)\n"; + } else { + // Is a pointer type here. If string, we do something + // special. Otherwise. No problem. + if ((type->type == T_CHAR) && (type->is_pointer == 1)) { + String temp; + wrap << "static " << type->print_type() << " " << cname << "(" + << classtype << classname << " *obj, " << type->print_real("val") << ") {\n"; + temp << "obj->" << mname; + if (CPlusPlus) { + wrap << tab4 << "if (" << temp << ") delete [] " << temp << ";\n" + << tab4 << temp << " = new char[strlen(val)+1];\n" + << tab4 << "strcpy((char *)" << temp << ",val);\n"; + } else { + wrap << tab4 << "if (obj->" << mname << ") free(obj->" << mname << ");\n" + << tab4 << "obj->" << mname << " = (char *) malloc(strlen(val)+1);\n" + << tab4 << "strcpy((char *)obj->" << mname << ",val);\n"; + } + wrap << tab4 << "return (char *) val;\n"; + wrap << "}\n"; + } else { + // A normal pointer type of some sort + wrap << "#define " << cname << "(_swigobj,_swigval) ("; + if (type->is_reference) { + wrap << "_swigobj->" << mname << " = *_swigval, _swigval)\n"; + } else { + wrap << "_swigobj->" << mname << " = _swigval,_swigval)\n"; + } + } + } + } + } + } + fprintf(f_wrappers,"%s",wrap.get()); + // Now wrap it. + + l = new ParmList; + p = new Parm(0,0); + p->t = new DataType(type); + p->t->is_reference = 0; + p->call_type = 0; + p->t->id = cpp_id; + if ((type->type == T_USER) && (!type->is_pointer)) p->t->is_pointer++; + if (mrename) + p->name = mrename; + else + p->name = mname; + l->insert(p,0); + p = new Parm(0,0); + p->t = new DataType; + p->t->type = T_USER; + p->call_type = 0; + p->t->is_pointer = 1; + p->t->id = cpp_id; + sprintf(p->t->name,"%s%s", classtype,classname); + p->name = "self"; + l->insert(p,0); + + if ((type->type == T_USER) && (!type->is_pointer)) { + type->is_pointer++; + lang->create_function(cname,iname, type, l); + type->is_pointer--; + } else { + int is_ref = type->is_reference; + type->is_reference = 0; + lang->create_function(cname,iname, type, l); + type->is_reference = is_ref; + } + delete l; + } else { + lang->create_command(prev_wrap,iname); + } +} + +// ----------------------------------------------------------------------------- +// void cplus_support_doc(String &f) +// +// This function adds a supporting documentation entry to the +// end of a class. This should only be used if there is an +// alternative interface available or if additional information is needed. +// +// doc_entry should be set to the class entry before calling this. Otherwise, +// who knows where this text is going to end up! +// +// Inputs : f = String with additional text +// +// Output : None +// +// Side Effects : +// Adds a text block to the current documentation entry. +// +// ----------------------------------------------------------------------------- + +void cplus_support_doc(String &f) { + + DocEntry *de; + if (doc_entry) { + de = new DocText(f.get(),doc_entry); + de->format = 0; + } +} + +// ----------------------------------------------------------------------------- +// void cplus_register_type(char *typename) +// +// Registers a datatype name to be associated with the current class. This +// typename is placed into a local hash table for later use. For example : +// +// class foo { +// public: +// enum ENUM { ... }; +// typedef double Real; +// void bar(ENUM a, Real b); +// } +// +// Then we need to access bar using fully qualified type names such as +// +// void wrap_bar(foo::ENUM a, foo::Real b) { +// bar(a,b); +// } +// +// Inputs : name of the datatype. +// +// Output : None +// +// Side Effects : Adds datatype to localtypes. +// ----------------------------------------------------------------------------- + +void cplus_register_type(char *tname) { + if (current_class) + add_local_type(tname, current_class->classname); +}; + +// ----------------------------------------------------------------------------- +// void cplus_register_scope(Hash *h) +// +// Saves the scope associated with a particular class. It will be needed +// later if anything inherits from us. +// +// Inputs : Hash table h containing the scope +// +// Output : None +// +// Side Effects : Saves h with current class +// ----------------------------------------------------------------------------- + +void cplus_register_scope(Hash *h) { + if (current_class) { + current_class->scope = h; + } +} + +// ----------------------------------------------------------------------------- +// void cplus_inherit_scope(int count, char **baseclass) +// +// Given a list of base classes, this function extracts their former scopes +// and merges them with the current scope. This is needed to properly handle +// inheritance. +// +// Inputs : baseclass = NULL terminated array of base-class names +// +// Output : None +// +// Side Effects : Updates current scope with new symbols. +// +// Copies any special symbols if needed. +// ----------------------------------------------------------------------------- + +void cplus_inherit_scope(int count, char **baseclass) { + CPP_class *bc; + int i; + char *key, *val; + String str; + + if (count && current_class) { + for (i = 0; i < count; i++) { + bc = CPP_class::search(baseclass[i]); + if (bc) { + if (bc->scope) + DataType::merge_scope(bc->scope); + + if (bc->local) { + // Copy local symbol table + key = bc->local->firstkey(); + while (key) { + val = (char *) bc->local->lookup(key); + str = val; + // str.replace(bc->classname,current_class->classname); + localtypes->add(key,copy_string(str)); + key = bc->local->nextkey(); + } + } + } + } + } +} + diff --git a/wxPython/wxSWIG/SWIG/emit.cxx b/wxPython/wxSWIG/SWIG/emit.cxx new file mode 100644 index 0000000000..57f67af2e0 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/emit.cxx @@ -0,0 +1,829 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" +/******************************************************************************* + * $Header$ + * + * File : emit.cxx + * + * This file contains some useful functions for emitting code that would be + * common to all of the interface languages. Mainly this function deals with + * declaring functions external, creating lists of arguments, and making + * function calls. + *******************************************************************************/ + +// ----------------------------------------------------------------------------- +// void emit_banner(FILE *f) +// +// Emits the SWIG identifying banner in the wrapper file +// +// Inputs : f = FILE handle +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void emit_banner(FILE *f) { + + extern char *get_time(); + extern char fn_header[]; + + fprintf(f, +"/*\n\ + * FILE : %s\n\ + * \n\ + * This file was automatically generated by :\n\ + * Simplified Wrapper and Interface Generator (SWIG)\n\ + * Version %d.%d %s\n\ + * \n\ + * Portions Copyright (c) 1995-1998\n\ + * The University of Utah and The Regents of the University of California.\n\ + * Permission is granted to distribute this file in any manner provided\n\ + * this notice remains intact.\n\ + * \n\ + * Do not make changes to this file--changes will be lost!\n\ + *\n\ + */\n\n", fn_header, SWIG_MAJOR_VERSION, SWIG_MINOR_VERSION, SWIG_SPIN); + + fprintf(f,"\n#define SWIGCODE\n"); + +} + +// ----------------------------------------------------------------------------- +// emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f) +// +// Emits an external variables declaration. Extern_type defines the +// type of external declaration. Currently, only C/C++ declarations +// are allowed, but this might be extended to allow Fortran linkage +// someday +// +// Inputs : +// decl = Name of the declaration +// t = Datatype +// extern_type = Numeric code indicating type of extern +// 0 - No "extern" +// 1,2 - Normal extern (C/C++) +// f = FILE handle +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f) { + char *arr = 0; + + if (t->arraystr) arr = t->arraystr; + else arr = ""; + + switch(extern_type) { + + case 0: + // No extern. Just a forward reference + if (t->arraystr) + t->is_pointer--; + + if (t->is_reference) { + t->is_pointer--; + fprintf(f,"%s& %s%s; \n", t->print_full(), decl, arr); + t->is_pointer++; + } else { + fprintf(f,"%s %s%s; \n", t->print_full(), decl,arr); + } + if (t->arraystr) + t->is_pointer++; + break; + case 1: case 2: + if (t->arraystr) + t->is_pointer--; + + // Normal C/C++ extern +// fprintf(f,"#line %d \"%s\"\n", line_number, input_file); + if (t->is_reference) { + t->is_pointer--; + fprintf(f,"extern %s& %s%s; \n", t->print_full(), decl,arr); + t->is_pointer++; + } else { + fprintf(f,"extern %s %s%s; \n", t->print_full(), decl,arr); + } + if (t->arraystr) + t->is_pointer++; + + default: + break; + } +} + +// ----------------------------------------------------------------------------- +// emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type, +// FILE *f) +// +// Emits an external function declaration (similiar to emit_extern_var). +// +// Inputs : +// decl = Name of declaration +// t = Return datatype +// L = parameter list +// extern_type = Type of extern +// 0 - No "extern" +// 1 - extern +// 2 - extern "C" +// 3 - Function declaration (with arg names) +// f = FILE Handle +// +// Output : None +// +// Side Effects : None +// +// ----------------------------------------------------------------------------- + +void emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type, FILE *f) { + + switch(extern_type) { + case 0: + if (t->is_reference) { + t->is_pointer--; + fprintf(f,"%s&", t->print_full()); + t->is_pointer++; + } else { + fprintf(f,"%s", t->print_full()); + } + + fprintf(f,"%s(", decl); + L->print_types(f); + fprintf(f,");\n"); + break; + case 1: + // Normal C/C++ extern +// fprintf(f,"#line %d \"%s\"\n", line_number, input_file); + if (t->is_reference) { + t->is_pointer--; + fprintf(f,"extern %s&", t->print_full()); + t->is_pointer++; + } else { + fprintf(f,"extern %s", t->print_full()); + } + fprintf(f,"%s(", decl); + L->print_types(f); + fprintf(f,");\n"); + break; + case 2: + // A C++ --- > C Extern +// fprintf(f,"#line %d \"%s\"\n", line_number, input_file); + if (t->is_reference) { + t->is_pointer--; + fprintf(f,"extern \"C\" %s&", t->print_full()); + t->is_pointer++; + } else { + fprintf(f,"extern \"C\" %s", t->print_full()); + } + fprintf(f,"%s(", decl); + L->print_types(f); + fprintf(f,");\n"); + break; + case 3: + // A function declaration (for inlining ) + if (t->is_reference) { + t->is_pointer--; + fprintf(f,"%s&", t->print_full()); + t->is_pointer++; + } else { + fprintf(f,"%s", t->print_full()); + } + + fprintf(f,"%s(", decl); + L->print_args(f); + fprintf(f,")\n"); + break; + default: + break; + } +} + +// ----------------------------------------------------------------------------- +// char *emit_local(int i) +// +// Returns the name of local variable for parameter i +// +// Inputs : i = Parameter number +// +// Output : NULL terminated ASCII string +// +// Side Effects : Result is left in a static local variable. +// ----------------------------------------------------------------------------- + +char *emit_local(int i) { + static char arg[64]; + + sprintf(arg,"_arg%d", i); + return arg; +} + +// ----------------------------------------------------------------------------- +// int emit_args(char *d, DataType *rt, ParmList *l, FILE *f) +// +// Creates a list of variable declarations for both the return value +// and function parameters. +// +// The return value is always called _result and arguments label as +// _arg0, _arg1, _arg2, etc... +// +// Returns the number of parameters associated with a function. +// +// Inputs : +// d = Name of function +// rt = Return type +// l = Parameter list +// f = FILE Handle +// +// Output : Number of function arguments +// +// Side Effects : None +// +// Note : This function is obsolete. Use emit_args below... +// ----------------------------------------------------------------------------- + +int emit_args(DataType *rt, ParmList *l, FILE *f) { + + Parm *p; + int i; + char temp[64]; + String def; + char *tm; + + // Declare the return variable + + if ((rt->type != T_VOID) || (rt->is_pointer)) { + if ((rt->type == T_USER) && (!rt->is_pointer)) { + + // Special case for return by "value" + + rt->is_pointer++; + fprintf(f,"\t %s _result;\n", rt->print_type()); + rt->is_pointer--; + } else { + + // Normal return value + + fprintf(f,"\t %s _result;\n", rt->print_type()); + } + } + + // Emit function arguments + + i = 0; + p = l->get_first(); + while (p != 0) { + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + sprintf(temp,"_arg%d", i); + if (p->defvalue) { + if ((p->t->is_reference) || ((p->t->type == T_USER) && (p->call_type == CALL_REFERENCE))) + fprintf(f,"\t %s _arg%d = &%s;\n", p->t->print_type(),i, p->defvalue); + else + fprintf(f,"\t %s _arg%d = %s;\n", p->t->print_type(),i, p->defvalue); + } else { + fprintf(f,"\t %s _arg%d;\n", p->t->print_type(),i); + tm = typemap_lookup("arginit", typemap_lang, p->t, p->name,"",temp); + if (tm) { + def << tm; + } + } + + // Check for ignore or default typemaps + + tm = typemap_lookup("default",typemap_lang,p->t,p->name,"",temp); + if (tm) + def << tm; + tm = typemap_lookup("ignore",typemap_lang,p->t,p->name,"",temp); + + if (tm) { + def << tm; + p->ignore = 1; + } + tm = typemap_check("build",typemap_lang,p->t,p->name); + if (tm) { + p->ignore = 1; + } + i++; + } + p = l->get_next(); + } + + fprintf(f,"%s",def.get()); + + // i now contains number of parameters + + return(i); + + } + + +// ----------------------------------------------------------------------------- +// int emit_args(char *d, DataType *rt, ParmList *l, WrapperFunction &f) +// +// Creates a list of variable declarations for both the return value +// and function parameters. +// +// The return value is always called _result and arguments label as +// _arg0, _arg1, _arg2, etc... +// +// Returns the number of parameters associated with a function. +// +// Inputs : +// d = Name of function +// rt = Return type +// l = Parameter list +// f = Wrapper function object +// +// Output : Number of function arguments +// +// Side Effects : None +// +// ----------------------------------------------------------------------------- + +int emit_args(DataType *rt, ParmList *l, WrapperFunction &f) { + + Parm *p; + int i; + char *tm; + + // Declare the return variable + + if ((rt->type != T_VOID) || (rt->is_pointer)) { + if ((rt->type == T_USER) && (!rt->is_pointer)) { + + // Special case for return by "value" + rt->is_pointer++; + f.add_local(rt->print_type(), "_result"); + rt->is_pointer--; + } else { + + // Normal return value + + f.add_local(rt->print_type(), "_result"); + } + } + + // Emit function arguments + + i = 0; + p = l->get_first(); + while (p != 0) { + if ((p->t->type != T_VOID) || (p->t->is_pointer)) { + char *temp = emit_local(i); + // Figure out default values + if (((p->t->is_reference) && (p->defvalue)) || + ((p->t->type == T_USER) && (p->call_type == CALL_REFERENCE) && (p->defvalue))) { + String deftmp; + deftmp << "(" << p->t->print_type() << ") &" << p->defvalue; + f.add_local(p->t->print_type(),temp,deftmp.get()); + } else { + String deftmp; + char *dv = 0; + if (p->defvalue) { + deftmp << "(" << p->t->print_type() << ") " << p->defvalue; + dv = deftmp.get(); + } + f.add_local(p->t->print_type(), temp, dv); + tm = typemap_lookup("arginit", typemap_lang, p->t,p->name,"",temp,&f); + if (tm) { + f.code << tm << "\n"; + } + } + // Check for ignore or default typemaps + tm = typemap_lookup("default",typemap_lang,p->t,p->name,"",temp,&f); + if (tm) + f.code << tm << "\n"; + tm = typemap_lookup("ignore",typemap_lang,p->t,p->name,"",temp,&f); + if (tm) { + f.code << tm << "\n"; + p->ignore = 1; + } + tm = typemap_check("build",typemap_lang,p->t,p->name); + if (tm) { + p->ignore = 1; + } + i++; + } + p = l->get_next(); + } + + // i now contains number of parameters + return(i); +} + +// ----------------------------------------------------------------------------- +// int emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f) +// +// Emits code for a function call. +// +// Inputs : +// decl = name of function +// t = Return datatype +// l = Parameter list +// f = FILE Handle +// +// Output : None +// +// Side Effects : None +// +// Note : This function is obsolete +// ----------------------------------------------------------------------------- + +void emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f) { + + int i; + Parm *p; + +// fprintf(f,"#line %d \"%s\"\n", line_number, input_file); + fprintf(f,"\t "); + + // First check if there is a return value + + if ((t->type != T_VOID) || (t->is_pointer)) { + if ((t->type == T_USER) && (!t->is_pointer)) { + + // Special case for return by "value" + // Caution : This *will* cause a memory leak if not + // used properly. + + if (CPlusPlus) { + fprintf(f,"_result = new %s(", t->print_type()); + } else { + t->is_pointer++; + fprintf(f,"_result = %s malloc(sizeof(", t->print_cast()); + t->is_pointer--; + fprintf(f,"%s));\n", t->print_type()); + fprintf(f,"\t*(_result) = "); + } + } else { + // Check if this is a C++ reference + if (t->is_reference) { + t->is_pointer--; + fprintf(f,"%s& _result_ref = ", t->print_full()); + t->is_pointer++; + } else { + + // Normal return values + fprintf(f,"_result = %s", t->print_cast()); + } + } + } + + // Now print out function call + + fprintf(f,"%s(",decl); + + i = 0; + p = l->get_first(); + while(p != 0) { + if ((p->t->type != T_VOID) || (p->t->is_pointer)){ + fprintf(f,"%s",p->t->print_arraycast()); + if ((!p->t->is_reference) && (p->call_type & CALL_VALUE)) fprintf(f,"&"); + if ((!(p->call_type & CALL_VALUE)) && + ((p->t->is_reference) || (p->call_type & CALL_REFERENCE))) + fprintf(f,"*"); + fprintf(f,"_arg%d",i); + i++; + } + p = l->get_next(); + if (p != 0) + fprintf(f,","); + } + + fprintf(f,")"); + if ((t->type == T_USER) && (!t->is_pointer)) { + if (CPlusPlus) { + fprintf(f,")"); + } + } + fprintf(f,";\n"); + if (t->is_reference) { + fprintf(f,"\t _result = %s &_result_ref;\n", t->print_cast()); + } +} + + + +// ----------------------------------------------------------------------------- +// int emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f) +// +// Emits code for a function call (new version). +// +// Exception handling support : +// +// - This function checks to see if any sort of exception mechanism +// has been defined. If so, we emit the function call in an exception +// handling block. +// +// Inputs : +// decl = name of function +// t = Return datatype +// l = Parameter list +// f = WrapperFunction object +// +// Output : None +// +// Side Effects : None +// +// ----------------------------------------------------------------------------- + +void emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f) { + + int i; + Parm *p; + String fcall; + String exc; + char *tm; + +// f.code << "#line " << line_number << " \"" << input_file << "\"\n"; + fcall << tab4; + + // First check if there is a return value + + if ((t->type != T_VOID) || (t->is_pointer)) { + if ((t->type == T_USER) && (!t->is_pointer)) { + + // Special case for return by "value" + // Caution : This *will* cause a memory leak if not + // used properly. + + if (CPlusPlus) { + fcall << "_result = new " << t->print_type() << "("; + } else { + t->is_pointer++; + fcall << "_result = " << t->print_cast() << " malloc(sizeof("; + t->is_pointer--; + fcall << t->print_type() << "));\n"; + fcall << tab4 << "*(_result) = "; + } + } else { + // Check if this is a C++ reference + if (t->is_reference) { + t->is_pointer--; + fcall << t->print_full() << "& _result_ref = "; + t->is_pointer++; + } else { + + // Normal return value + fcall << "_result = " << t->print_cast(); + } + } + } + + // Now print out function call + + fcall << decl << "("; + + i = 0; + p = l->get_first(); + while(p != 0) { + if ((p->t->type != T_VOID) || (p->t->is_pointer)){ + fcall << p->t->print_arraycast(); + if ((!p->t->is_reference) && (p->call_type & CALL_VALUE)) + fcall << "&"; + if ((!(p->call_type & CALL_VALUE)) && + ((p->t->is_reference) || (p->call_type & CALL_REFERENCE))) + fcall << "*"; + fcall << emit_local(i); + i++; + } + p = l->get_next(); + if (p != 0) + fcall << ","; + } + fcall << ")"; + + if ((t->type == T_USER) && (!t->is_pointer)) { + if (CPlusPlus) { + fcall << ")"; + } + } + fcall << ";\n"; + + if (t->is_reference) { + fcall << tab4 << "_result = "<< t->print_cast() << " &_result_ref;\n"; + } + // Check for exception handling + + if ((tm = typemap_lookup("except",typemap_lang,t,decl,"_result",""))) { + // Found a type-specific mapping + exc << tm; + exc.replace("$function",fcall); + exc.replace("$name",decl); + f.code << exc; + } else if ((tm = fragment_lookup("except",typemap_lang, t->id))) { + exc << tm; + exc.replace("$function",fcall); + exc.replace("$name",decl); + f.code << exc; + } else { + f.code << fcall; + } +} + +// ----------------------------------------------------------------------------- +// void emit_hex(FILE *f) +// +// Emits the default C-code to handle pointers. This is normally contained +// in the SWIG library file 'swigptr.swg' +// +// Inputs : f = FILE handle +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void emit_hex(FILE *f) { + + int stat; + + // Look for a pointer configuration file + + stat = insert_file("swigptr.swg", f); + + if (stat == -1) { + fprintf(stderr,"** Fatal error. Unable to locate 'swigptr.swg'\n"); + SWIG_exit(1); + } +} + +// ----------------------------------------------------------------------------- +// void emit_set_get(char *name, char *iname, DataType *type) +// +// Emits a pair of functions to set/get the value of a variable. +// This should be used as backup in case the target language can't +// provide variable linking. +// +// double foo; +// +// Gets translated into the following : +// +// double foo_set(double x) { +// return foo = x; +// } +// +// double foo_get() { +// return foo; +// } +// +// Need to handle special cases for char * and for user +// defined types. +// +// 1. char * +// +// Will free previous contents (if any) and allocate +// new storage. Could be risky, but it's a reasonably +// natural thing to do. +// +// 2. User_Defined +// Will assign value from a pointer. +// Will return a pointer to current value. +// +// +// Inputs : +// name = Name of variable +// iname = Renamed version of variable +// type = Datatype of the variable +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void emit_set_get(char *name, char *iname, DataType *t) { + + Parm *p; + ParmList *l; + String new_name; + String new_iname; + String wname; + + // First write a function to set the variable of the variable + + if (!(Status & STAT_READONLY)) { + if ((t->type == T_USER) && (!t->is_pointer)) { + t->is_pointer++; + fprintf(f_header,"static %s %s(%s val) {\n", + t->print_type(), name_set(name), t->print_type()); + t->is_pointer--; + } else { + fprintf(f_header,"static %s %s(%s val) {\n", + t->print_type(), name_set(name), t->print_type()); + } + + if ((t->type != T_VOID) || (t->is_pointer)) { + if (!t->is_pointer) { + + // Have a real value here + // If it's a user defined type, we'll do something special. + // Otherwise, just assign it. + + if (t->type != T_USER) { + fprintf(f_header,"\t return (%s) (%s = val);\n", t->print_type(), name); + } else { + fprintf(f_header,"\t %s = *(val);\n", name); + t->is_pointer++; + fprintf(f_header,"\t return (%s) &%s;\n", t->print_type(),name); + t->is_pointer--; + } + } else { + + // Is a pointer type here. If string, we do something + // special. Otherwise. No problem. + + if ((t->type == T_CHAR) && (t->is_pointer == 1)) { + if (CPlusPlus) { + fprintf(f_header,"\t if (%s) delete %s;\n", name,name); + fprintf(f_header,"\t %s = new char[strlen(val)+1];\n",name); + fprintf(f_header,"\t strcpy(%s,val);\n", name); + fprintf(f_header,"\t return %s;\n", name); + } else { + fprintf(f_header,"\t if (%s) free(%s);\n", name,name); + fprintf(f_header,"\t %s = (char *) malloc(strlen(val)+1);\n",name); + fprintf(f_header,"\t strcpy(%s,val);\n", name); + fprintf(f_header,"\t return %s;\n", name); + } + } else { + fprintf(f_header,"\t return (%s) (%s = val);\n", t->print_type(), name); + } + } + } + + fprintf(f_header,"}\n"); + + // Now wrap it. + + l = new ParmList; + p = new Parm(t,0); + if ((t->type == T_USER) && (!t->is_pointer)) p->t->is_pointer++; + p->name = new char[1]; + p->name[0] = 0; + l->append(p); + + new_name = name_set(name); + new_iname = name_set(iname); + + if ((t->type == T_USER) && (!t->is_pointer)) { + t->is_pointer++; + lang->create_function(new_name, new_iname, t, l); + t->is_pointer--; + } else { + lang->create_function(new_name, new_iname, t, l); + } + delete l; + delete p; + if (doc_entry) doc_entry->usage << "\n"; + } + + // Now write a function to get the value of the variable + + if ((t->type == T_USER) && (!t->is_pointer)) { + t->is_pointer++; + fprintf(f_header,"static %s %s() { \n", + t->print_type(), name_get(name)); + fprintf(f_header,"\t return (%s) &%s;\n", t->print_type(), name); + t->is_pointer--; + } else { + fprintf(f_header,"static %s %s() { \n", + t->print_type(), name_get(name)); + fprintf(f_header,"\t return (%s) %s;\n", t->print_type(), name); + } + + fprintf(f_header,"}\n"); + + // Wrap this function + + l = new ParmList; + + new_name = name_get(name); + new_iname = name_get(iname); + + if ((t->type == T_USER) && (!t->is_pointer)) { + t->is_pointer++; + lang->create_function(new_name, new_iname, t, l); + t->is_pointer--; + } else { + lang->create_function(new_name, new_iname, t, l); + } + delete l; +} + + + + diff --git a/wxPython/wxSWIG/SWIG/getopt.cxx b/wxPython/wxSWIG/SWIG/getopt.cxx new file mode 100644 index 0000000000..725eb61aa3 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/getopt.cxx @@ -0,0 +1,141 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" + +/******************************************************************************* + * $Header$ + * + * File : getopt.cxx + * + * This file defines a few functions for handling command line arguments. + * C++ makes this really funky---especially since each language module + * may want to extract it's own command line arguments. + * + * My own special version of getopt. This is a bit weird, because we + * don't know what the options are in advance (they could be determined + * by a language module). + *******************************************************************************/ + +static char **args; +static int numargs; +static int *marked; + +// ----------------------------------------------------------------------------- +// void init_args(int argc, char **argv) +// +// Initializes the argument list. +// +// Inputs : +// argc = Argument count +// argv = Argument array +// +// Output : None +// +// Side Effects : Saves local copy of argc and argv +// ----------------------------------------------------------------------------- + +void +init_args(int argc, char **argv) +{ + int i; + numargs = argc; + args = argv; + marked = new int[numargs]; + for (i = 0; i < argc; i++) { + marked[i] = 0; + } + marked[0] = 1; +} + +// ----------------------------------------------------------------------------- +// void mark_arg(int n) +// +// Marks an argument as being parsed. All modules should do this whenever they +// parse a command line option. +// +// Inputs : n = Argument number +// +// Output : None +// +// Side Effects : Sets a status bit internally +// ----------------------------------------------------------------------------- + +void +mark_arg(int n) { + if (marked) + marked[n] = 1; +} + +// ----------------------------------------------------------------------------- +// void check_options() +// +// Checks for unparsed command line options. If so, issues an error and exits. +// +// Inputs : None +// +// Output : None +// +// Side Effects : exits if there are unparsed options +// ----------------------------------------------------------------------------- + +void check_options() { + + int error = 0; + int i; + + if (!marked) { + fprintf(stderr,"Must specify an input file. Use -help for available options.\n"); + SWIG_exit(1); + } + for (i = 1; i < numargs-1; i++) { + if (!marked[i]) { + fprintf(stderr,"swig error : Unrecognized option %s\n", args[i]); + error=1; + } + } + + if (error) { + fprintf(stderr,"Use 'swig -help' for available options.\n"); + SWIG_exit(1); + } + + if (marked[numargs-1]) { + fprintf(stderr,"Must specify an input file. Use -help for available options.\n"); + SWIG_exit(1); + } +} + +// ----------------------------------------------------------------------------- +// void arg_error() +// +// Generates a generic error message and exits. +// +// Inputs : None +// +// Output : None +// +// Side Effects : Exits +// ----------------------------------------------------------------------------- + +void arg_error() { + fprintf(stderr,"SWIG : Unable to parse command line options.\n"); + fprintf(stderr,"Use 'swig -help' for available options.\n"); + SWIG_exit(1); +} + + + + diff --git a/wxPython/wxSWIG/SWIG/hash.cxx b/wxPython/wxSWIG/SWIG/hash.cxx new file mode 100644 index 0000000000..2bca615681 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/hash.cxx @@ -0,0 +1,359 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" + +/******************************************************************************* + * $Header$ + * + * File : hash.cxx + * + * A very simple Hash table class. Could probably make it more elegant with + * templates, but templates are pure evil... + *******************************************************************************/ + +#define INIT_SIZE 119 + +// ----------------------------------------------------------------------------- +// Hash::Hash() +// +// Constructor. Creates a new hash table. +// +// Inputs : None +// +// Output : New Hash object. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +Hash::Hash() { + int i; + hashsize = INIT_SIZE; + hashtable = new Node *[hashsize]; + for (i = 0; i < hashsize; i++) { + hashtable[i] = 0; + } + index = -1; + current = 0; +} + +// ----------------------------------------------------------------------------- +// Hash::~Hash() +// +// Destructor. +// +// Inputs : None +// +// Output : None +// +// Side Effects : Total destruction. +// ----------------------------------------------------------------------------- + +Hash::~Hash() { + int i; + Node *n,*next; + + for (i = 0; i < hashsize; i++) { + if (hashtable[i]) { + n = hashtable[i]; + while (n) { + next = n->next; + delete n; + n = next; + } + } + } + delete [] hashtable; +} + +// ----------------------------------------------------------------------------- +// int Hash::h1(const char *key) +// +// Hashing function. +// +// Inputs : ASCII character string. +// +// Output : Hash table index. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +int Hash::h1(const char *key) { + int h = 0; + const char *c; + + c = key; + while (*c) { + h = (128*h + *c) % hashsize; + c++; + } + return h; +} + +// ----------------------------------------------------------------------------- +// int Hash::add(const char *k, void *obj) +// +// Adds a new object to the hash table. +// +// Inputs : +// k = Hash key +// obj = Pointer to an object +// +// Output : 0 on success, -1 if item is already in hash table. +// +// Side Effects : +// Makes a new hash table entry. +// ----------------------------------------------------------------------------- + +int Hash::add(const char *k, void *obj) { + + int hv; + Node *n,*prev; + + hv = h1(k); // Get hash value + n = hashtable[hv]; + prev = n; + while (n) { + if (strcmp(n->key,k) == 0) return -1; // Already in hash table + prev = n; + n = n->next; + } + + // Safe to add this to the table + + n = new Node(k,obj,0); + if (prev) prev->next = n; + else hashtable[hv] = n; + return 0; +} + +// ----------------------------------------------------------------------------- +// int Hash::add(const char *k, void *obj, void (*d)(void *)) +// +// Adds a new object to the hash table. Allows additional specification of +// a callback function for object deletion. +// +// Inputs : +// k = Hash key +// obj = Object pointer +// d = Deletion function +// +// Output : 0 on success, -1 if item is already in hash table. +// +// Side Effects : +// Adds an entry to the hash table +// ----------------------------------------------------------------------------- + +int Hash::add(const char *k, void *obj, void (*d)(void *)) { + + int hv; + Node *n,*prev; + + hv = h1(k); // Get hash value + n = hashtable[hv]; + prev = n; + while (n) { + if (strcmp(n->key,k) == 0) return -1; // Already in hash table + prev = n; + n = n->next; + } + + // Safe to add this to the table + + n = new Node(k,obj,d); + if (prev) prev->next = n; + else hashtable[hv] = n; + return 0; +} + +// ----------------------------------------------------------------------------- +// void *Hash::lookup(const char *k) +// +// Looks up a value in the hash table. Returns a pointer to the object if found. +// +// Inputs : k = key value +// +// Output : Pointer to object or NULL if not found. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void *Hash::lookup(const char *k) { + int hv; + Node *n; + + hv = h1(k); // Get hash value + n = hashtable[hv]; + + while (n) { + if (strcmp(n->key,k) == 0) return n->object; + n = n->next; + } + + return 0; +} + +// ----------------------------------------------------------------------------- +// void Hash::remove(const char *k) +// +// Removes an item from the hash table. Does nothing if item isn't in the +// hash table to begin with. +// +// Inputs : k = Key value +// +// Output : None +// +// Side Effects : Deletes item from hash table. +// ----------------------------------------------------------------------------- + +void Hash::remove(const char *k) { + + int hv; + Node *n,*prev; + + hv = h1(k); // Get hash value + n = hashtable[hv]; + prev = 0; + while (n) { + if (strcmp(n->key,k) == 0) { + // Found it, kill the thing + if (prev) { + prev->next = n->next; + } else { + hashtable[hv] = n->next; + } + delete n; + return; + } + prev = n; + n = n->next; + } +} + +// ----------------------------------------------------------------------------- +// void *Hash::first() +// +// Gets the first item from the hash table or NULL if empty. +// +// Inputs : None +// +// Output : First object in hash table or NULL if hash table is empty. +// +// Side Effects : Resets an internal iterator variable on the hash table. +// ----------------------------------------------------------------------------- + +void *Hash::first() { + index = 0; + current = 0; + + while (!hashtable[index] && (index < hashsize)) + index++; + + if (index >= hashsize) return 0; + current = hashtable[index]; + return current->object; +} + + +// ----------------------------------------------------------------------------- +// char *Hash::firstkey() +// +// Gets the first key from the hash table or NULL if empty. +// +// Inputs : None +// +// Output : First key in hash table or NULL if hash table is empty. +// +// Side Effects : Resets an internal iterator variable on the hash table. +// ----------------------------------------------------------------------------- + +char *Hash::firstkey() { + index = 0; + current = 0; + + while ((index < hashsize) && (!hashtable[index])) + index++; + + if (index >= hashsize) return 0; + current = hashtable[index]; + return current->key; +} + +// ----------------------------------------------------------------------------- +// void *Hash::next() +// +// Returns the next item in the hash table or NULL if there are no more entries. +// A call to first() should generally be made before using this function. +// +// Inputs : None +// +// Output : Pointer to next object or NULL if there are no more objects. +// +// Side Effects : Updates an iterator variable private to the hash table. +// ----------------------------------------------------------------------------- + +void *Hash::next() { + if (index < 0) return first(); + + // Try to move to the next entry + + current = current->next; + + if (current) { + return current->object; + } else { + index++; + while ((index < hashsize) && (!hashtable[index])) + index++; + if (index >= hashsize) return 0; + current = hashtable[index]; + return current->object; + } +} + + +// ----------------------------------------------------------------------------- +// char *Hash::nextkey() +// +// Returns the next key in the hash table or NULL if there are no more entries. +// A call to firstkey() should generally be made before using this function. +// +// Inputs : None +// +// Output : Pointer to next key or NULL if there are no more objects. +// +// Side Effects : Updates an iterator variable private to the hash table. +// ----------------------------------------------------------------------------- + +char *Hash::nextkey() { + if (index < 0) return firstkey(); + + // Try to move to the next entry + + current = current->next; + + if (current) { + return current->key; + } else { + index++; + while (!hashtable[index] && (index < hashsize)) + index++; + if (index >= hashsize) return 0; + current = hashtable[index]; + return current->key; + } +} + + diff --git a/wxPython/wxSWIG/SWIG/html.cxx b/wxPython/wxSWIG/SWIG/html.cxx new file mode 100644 index 0000000000..5930852b93 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/html.cxx @@ -0,0 +1,598 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "swig.h" +#include "html.h" + +/******************************************************************************* + * $Header$ + * + * File : html.cxx + * + * HTML specific functions for producing documentation. + *******************************************************************************/ + +#define PRE 0 +#define FORMAT 1 + +// ----------------------------------------------------------------------------- +// HTML::HTML() +// +// Constructor. Creates a new HTML documentation module object. +// +// Inputs : None +// +// Output : HTML Object +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +HTML::HTML() { + sect_count = 0; + last_section = 0; + + // Initialize default tags for various parts of the documentation + + tag_body = ":"; + tag_title = "

:

"; + tag_contents = "

:

"; + tag_section = "

:

"; + tag_subsection = "

:

"; + tag_subsubsection = "

:

"; + tag_usage = "

:"; + tag_descrip = "

:
"; + tag_text = "

"; + tag_cinfo = ""; + tag_preformat = "

:
"; +} + +// ----------------------------------------------------------------------------- +// char *HTML::start_tag(char *tag) +// +// Utility function for returning the first part of an HTML tag variable. +// A tag must look like this : +// +// ":" +// +// The start tag for this would be "" +// +// Inputs : tag = HTML tag string +// +// Output : Staring portion of the tag variable. +// +// Side Effects : None. +// ----------------------------------------------------------------------------- + +char *HTML::start_tag(char *tag) { + static String stag; + char *c; + + stag = ""; + c = tag; + while ((*c) && (*c != ':')) { + stag << *c; + c++; + } + return stag.get(); +} + +// ----------------------------------------------------------------------------- +// char *HTML::end_tag(char *tag) +// +// Utility for returning an end-tag. The counterpart to start_tag(). +// +// Inputs : tag = HTML tag string +// +// Output : Ending portion of tag variable. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +char *HTML::end_tag(char *tag) { + static String etag; + char *c; + + etag = ""; + c = tag; + while ((*c) && (*c != ':')) { + c++; + } + if (*c) { + c++; + while (*c) { + etag << *c; + c++; + } + } + return etag.get(); +} + +// ----------------------------------------------------------------------------- +// void HTML::print_string(char *s, String &str, int mode) +// +// Outputs the contents of string s into String str. If mode is 1, we +// will reformat the text and apply a few common HTML character +// substitutions. +// +// Inputs : s = Documentation text string +// mode = Formatting mode (0 = preformat, 1 = formatted) +// +// Output : str = Output is append to str. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void HTML::print_string(char *s, String &str,int mode) { + char *c; + c = s; + while (*c) { + switch(*c) { + case '\"': + str << """; + break; + case '&': + str << "&"; + break; + case '<': + if (mode == PRE) + str << "<"; + else + str << (char) *c; + break; + case '>': + if (mode == PRE) + str << ">"; + else + str << (char) *c; + break; + default : + str << (char ) *c; + break; + } + c++; + } +} + +// ----------------------------------------------------------------------------- +// void HTML::print_decl(DocEntry *de) +// +// Generates documentation for a declaration. +// +// Inputs : de = Documentation entry +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void HTML::print_decl(DocEntry *de) { + + char *c; + c = de->usage.get(); + while ((*c) && ((*c == ' ') || (*c == '\t') || (*c == '\n'))) c++; + if (c) { + s_doc << start_tag(tag_usage); + print_string(c,s_doc,PRE); + s_doc << end_tag(tag_usage) << "\n"; + } else return; + + // Only print this if there is information + + if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) { + s_doc << start_tag(tag_descrip); + if (!de->format) + s_doc << start_tag(tag_preformat); + } + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + s_doc << start_tag(tag_cinfo); + s_doc << "[ "; + print_string(c,s_doc,PRE); + s_doc << " ]" << end_tag(tag_cinfo) << "\n"; + if (de->format) s_doc << "
"; + } + } + + c = de->text.get(); + if (strlen(c) > 0) { + print_string(c,s_doc,de->format); + } + + if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) { + if (!de->format) s_doc << end_tag(tag_preformat); + s_doc << end_tag(tag_descrip) << "\n"; + } + + s_doc << "\n"; +} + +// ----------------------------------------------------------------------------- +// void HTML::print_text(DocEntry *de) +// +// Generates documentation for a text-block. Strips any leading whitespace. +// +// Inputs : de = Documentation entry +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void HTML::print_text(DocEntry *de) { + char *c; + c = de->text.get(); + if (strlen(c) > 0) { + s_doc << start_tag(tag_text); + if (!de->format) + s_doc << start_tag(tag_preformat); + print_string(c,s_doc,de->format); + if (!de->format) + s_doc << end_tag(tag_preformat) << "\n"; + s_doc << end_tag(tag_text) << "\n"; + } +} + +// ----------------------------------------------------------------------------- +// void HTML::title(DocEntry *de) +// +// Generates the title for an HTML document. +// +// Inputs : de = Title documentation entry +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void HTML::title(DocEntry *de) { + char *c; + c = de->usage.get(); + if (strlen(c) > 0) { + s_title << "\n" + << "\n"; + print_string(c,s_title,PRE); + s_title << "\n" + << start_tag(tag_body) << "\n"; + + s_title << start_tag(tag_title); + print_string(c,s_title,PRE); + s_title << end_tag(tag_title) << "\n"; + } + + if (!de->format) + s_title << start_tag(tag_preformat); + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + s_title << start_tag(tag_cinfo) << "[ "; + print_string(c,s_title,de->format); + s_title << " ]" << end_tag(tag_cinfo); + if (de->format) + s_title << "
\n"; + else + s_title << "\n"; + } + } + + c = de->text.get(); + if (strlen(c)) { + print_string(c,s_title,de->format); + } + if (!de->format) + s_title << end_tag(tag_preformat) << "\n"; +} + +// ----------------------------------------------------------------------------- +// void HTML::newsection(DocEntry *de, int sectnum) +// +// Creates a new section. sect_count is used to determine the formatting of +// the header. Also fills in a table of contents +// +// Inputs : +// de = Documentation Entry +// sectnum = Section number +// +// Output : None +// +// Side Effects : +// Creates a new subsection. Updates HTML table of contents. +// ----------------------------------------------------------------------------- + +void HTML::newsection(DocEntry *de,int sectnum) { + int i,f; + char *c; + + char *tag; + + sect_num[sect_count] = sectnum; + sect_count++; + + f = sect_count + 1; + if (f > 5) f = 5; + + // Form table of contents + // if sect_count > last_section. We need to indent + // if sect_count < last_section. We need to pop out + + if (sect_count > last_section) { + for (i = 0; i < sect_count - last_section; i++) + contents << "
    "; + } else if (sect_count < last_section) { + for (i = 0; i < last_section - sect_count; i++) + contents << "
"; + } + + last_section = sect_count; + contents << "
  • "; + + // Figure out the tag fields + + switch(f) { + case 1: + tag = tag_title; + break; + case 2: + tag = tag_section; + break; + case 3: + tag = tag_subsection; + break; + case 4: + tag = tag_subsubsection; + break; + default: + tag = tag_subsubsection; + } + + s_doc << "\">\n" + << start_tag(tag); + + for (i = 0; i < sect_count; i++) { + s_doc << sect_num[i] << "."; + contents << sect_num[i] << "."; + } + c = de->usage.get(); + s_doc << " "; + contents << " "; + print_string(c,s_doc,PRE); + print_string(c,contents,PRE); + s_doc << end_tag(tag) << "\n"; + contents << "\n"; + + if (!de->format) + s_doc << start_tag(tag_preformat); + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + s_doc << start_tag(tag_cinfo) << "[ "; + print_string(c,s_doc,de->format); + s_doc << " ]" << end_tag(tag_cinfo); + if (de->format) + s_doc << "
    \n"; + else + s_doc << "\n"; + } + } + + // If there is a description text. Print it + + c = de->text.get(); + if (strlen(c) > 0) { + print_string(c,s_doc,de->format); + s_doc << "\n"; + } + if (!de->format) + s_doc << end_tag(tag_preformat) << "\n"; + +} + +// ----------------------------------------------------------------------------- +// void HTML::endsection() +// +// Ends a subsection. It is an error to call this without first calling +// newsection previously. +// +// Inputs : None +// +// Output : None +// +// Side Effects : Closes current section and goes back to parent. +// +// ----------------------------------------------------------------------------- + +void HTML::endsection() { + if (sect_count > 0) sect_count--; +} + +// ----------------------------------------------------------------------------- +// void HTML::separator() +// +// Prints a separator after the declaration of a C++ class. Currently +// does nothing in HTML mode. +// +// Inputs : None +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void HTML::separator() { +} + +// ----------------------------------------------------------------------------- +// void HTML::init(char *filename) +// +// Initializes the HTML module and opens up the documentation file. +// +// Inputs : filename = Name of documentation file (without a suffix) +// +// Output : None +// +// Side Effects : Opens documentation file. +// ----------------------------------------------------------------------------- + +void HTML::init(char *filename) { + char f[256]; + + sprintf(f,"%s.html",filename); + f_doc = fopen(f,"w"); + if (f_doc == NULL) { + fprintf(stderr,"Unable to open %s\n",f); + SWIG_exit(1); + } + /* Print a HTML banner */ + fprintf(f_doc,"\n"); + +} + +// ----------------------------------------------------------------------------- +// void HTML::close(void) +// +// Dumps the table of contents and forms the final documentation file. Closes +// the documentation file upon completion. +// +// Inputs : None +// +// Output : None +// +// Side Effects : Closes documentation file. +// ----------------------------------------------------------------------------- + +void HTML::close(void) { + + int i; + for (i = 0; i < last_section; i++) + contents << "\n"; + + fprintf(f_doc,"%s\n",s_title.get()); + if (last_section) { + fprintf(f_doc,"%s Contents %s\n",start_tag(tag_contents),end_tag(tag_contents)); + fprintf(f_doc,"%s\n",contents.get()); + } + fprintf(f_doc,"%s\n",s_doc.get()); + fprintf(f_doc,"%s\n", end_tag(tag_body)); + fprintf(f_doc,"\n"); + fclose(f_doc); +} + +// ----------------------------------------------------------------------------- +// void HTML::style(char *name, char *value) +// +// Process parameters given with the %style directive. Does nothing if an +// unrecognized parameter is given. +// +// Inputs : +// name = name of style parameter +// value = ASCII string with value of parameter. +// +// Output : None +// +// Side Effects : Updates internal style parameters. +// ----------------------------------------------------------------------------- + +void HTML::style(char *name, char *value) { + if (strcmp(name,"html_title") == 0) { + if (value) + tag_title = copy_string(value); + } else if (strcmp(name,"html_contents") == 0) { + if (value) + tag_contents = copy_string(value); + } else if (strcmp(name,"html_section") == 0) { + if (value) + tag_section = copy_string(value); + } else if (strcmp(name,"html_subsection") == 0) { + if (value) + tag_subsection = copy_string(value); + } else if (strcmp(name,"html_subsubsection") == 0) { + if (value) + tag_subsubsection = copy_string(value); + } else if (strcmp(name,"html_usage") == 0) { + if (value) + tag_usage = copy_string(value); + } else if (strcmp(name,"html_descrip") == 0) { + if (value) + tag_descrip = copy_string(value); + } else if (strcmp(name,"html_text") == 0) { + if (value) + tag_text = copy_string(value); + } else if (strcmp(name,"html_cinfo") == 0) { + if (value) + tag_cinfo = copy_string(value); + } else if (strcmp(name,"html_preformat") == 0) { + if (value) + tag_preformat = copy_string(value); + } else if (strcmp(name,"html_body") == 0) { + if (value) + tag_body = copy_string(value); + } +} + +// ----------------------------------------------------------------------------- +// void HTML::parse_args(int argc, char **argv) +// +// Parse command line options given on the SWIG command line. +// +// Inputs : +// argc = argument count +// argv = argument array +// +// Output : None +// +// Side Effects : Marks arguments as being parsed. +// ----------------------------------------------------------------------------- + +static char *html_usage = "\ +HTML Documentation Options (available with -dhtml)\n\ + None available.\n\n"; + +void HTML::parse_args(int argc, char **argv) { + int i; + + for (i = 0; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i],"-help") == 0) { + fputs(html_usage,stderr); + } + } + } +} + + + + + + + + + + + + diff --git a/wxPython/wxSWIG/SWIG/html.h b/wxPython/wxSWIG/SWIG/html.h new file mode 100644 index 0000000000..2dfc0cab54 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/html.h @@ -0,0 +1,76 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/*********************************************************************** + * $Header$ + * + * html.h + * + * HTML specific functions for producing documentation. + ***********************************************************************/ + +class HTML : public Documentation { +private: + FILE *f_doc; + void print_string(char *s, String &str, int mode); + char *start_tag(char *); + char *end_tag(char *); + int sect_count; + int sect_num[20]; + int last_section; + String s_doc; + String s_title; + String contents; + char *tag_body; + char *tag_title; + char *tag_contents; + char *tag_section; + char *tag_subsection; + char *tag_subsubsection; + char *tag_usage; + char *tag_descrip; + char *tag_text; + char *tag_cinfo; + char *tag_preformat; +public: + HTML(); + void parse_args(int argc, char **argv); + void title(DocEntry *de); + void newsection(DocEntry *de, int sectnum); + void endsection(); + void print_decl(DocEntry *de); + void print_text(DocEntry *de); + void separator(); + void init(char *filename); + void close(void); + void style(char *name, char *value); +}; + + + + + + + + + + + + + + + + + diff --git a/wxPython/wxSWIG/SWIG/include.cxx b/wxPython/wxSWIG/SWIG/include.cxx new file mode 100644 index 0000000000..f0bbe48280 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/include.cxx @@ -0,0 +1,586 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" +#include +#include +#include + +/******************************************************************************* + * $Header$ + * + * File : include.cxx + * + * Code for including files into a wrapper file. + * + *******************************************************************************/ + +/* Delimeter used in accessing files and directories */ + +#ifdef MACSWIG +#define DELIMETER ':' +#else +#define DELIMETER '/' +#endif + +/* Linked list containing search directories */ + +struct Dnode { + char *dirname; + Dnode *next; +}; + +Dnode ihead, iz; +int include_init = 0; + +/* Linked list containing included files */ + +struct Inode { + char *name; + Inode *next; +}; + +Inode *include_list = 0; + +// ----------------------------------------------------------------------------- +// void add_directory(char *dirname) +// +// Adds a directory to the SWIG search path. +// +// Inputs : dirname = Pathname +// +// Output : None +// +// Side Effects : Adds dirname to linked list of pathnames. +// ----------------------------------------------------------------------------- + +void add_directory(char *dirname) { + Dnode *d; + + if (!include_init) { + ihead.next = &iz; + iz.next = &iz; + iz.dirname = new char[2]; + iz.dirname[0] = 0; + include_init = 1; + } + + d = new Dnode; + d->dirname = new char[strlen(dirname)+1]; + strcpy(d->dirname,dirname); + d->next = ihead.next; + ihead.next = d; + +} + +// ----------------------------------------------------------------------------- +// int add_iname(char *name) +// +// Adds an include file to the list of processed files. If already present, +// returns 1. +// +// Inputs : name = filename +// +// Output : 0 on success, 1 on failure. +// +// Side Effects : Adds name to linked list. +// ----------------------------------------------------------------------------- + +int add_iname(char *name) { + + Inode *newi, *i; + + // if (WrapExtern) return 0; // Still thinking about this patch. + if (include_list) { + /* Search list */ + i = include_list; + while (i) { + if (strcmp(i->name, name) == 0) return 1; + i = i->next; + } + } + + newi = new Inode; + newi->name = new char[strlen(name)+1]; + strcpy(newi->name, name); + newi->next = include_list; + include_list = newi; + return 0; +} + +// ----------------------------------------------------------------------------- +// void check_suffix(char *name) +// +// Checks the suffix of an include file to see if we need to handle it +// differently. C and C++ source files need a little extra help. +// +// Inputs : name = include file name. +// +// Output : None +// +// Side Effects : +// Sets ForceExtern status variable if a C/C++ source file +// is detected. +// +// ----------------------------------------------------------------------------- + +void check_suffix(char *name) { + char *c; + + if (!name) return; + if (strlen(name) == 0) return; + c = name+strlen(name)-1; + while (c != name) { + if (*c == '.') break; + c--; + } + if (c == name) return; + + /* Check suffixes */ + + if (strcmp(c,".c") == 0) { + ForceExtern = 1; + } else if (strcmp(c,".C") == 0) { + ForceExtern = 1; + } else if (strcmp(c,".cc") == 0) { + ForceExtern = 1; + } else if (strcmp(c,".cxx") == 0) { + ForceExtern = 1; + } else if (strcmp(c,".c++") == 0) { + ForceExtern = 1; + } else if (strcmp(c,".cpp") == 0) { + ForceExtern = 1; + } else { + ForceExtern = 0; + } +} +// ----------------------------------------------------------------------------- +// int include_file(char *name) +// +// Includes a new SWIG wrapper file. Returns -1 if file not found. +// +// Inputs : name = filename +// +// Output : 0 on success. -1 on failure. +// +// Side Effects : sets scanner to read from new file. +// ----------------------------------------------------------------------------- + +int include_file(char *name) { + + FILE *f; + char filename[256]; + int found = 0; + Dnode *d; + extern void scanner_file(FILE *); + + if (!include_init) return -1; // Not initialized yet + if (add_iname(name)) { + if (Verbose) fprintf(stderr,"file %s already included.\n", name); + return -1; // Already included this file + } + + if (Verbose) { + fprintf(stderr,"Wrapping %s...\n", name); + fprintf(stderr,"Looking for ./%s\n", name); + } + + if ((f = fopen(name,"r")) != NULL) { + input_file = new char[strlen(name)+1]; + strcpy(input_file,name); + scanner_file(f); + check_suffix(name); + return 0; + } + + // Now start searching libraries + + d = ihead.next; // Start of search list + while (d != &iz) { + // Look for the wrap file in language directory + sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name); + if (Verbose) fprintf(stderr,"Looking for %s\n", filename); + if((f = fopen(filename,"r")) != NULL) { + found = 1; + } else { + sprintf(filename,"%s%c%s", d->dirname, DELIMETER,name); + if (Verbose) fprintf(stderr,"Looking for %s\n", filename); + if ((f = fopen(filename,"r")) != NULL) { + found = 1; + } + } + if (found) { + // Found it, open it up for input + input_file = new char[strlen(filename)+1]; + strcpy(input_file,filename); + scanner_file(f); + check_suffix(name); + return 0; + } + d = d->next; + } + + if (!found) fprintf(stderr,"%s : Line %d. Unable to find include file %s (ignored).\n",input_file, line_number, name); + + return -1; +} + + +static char buffer[1024]; + +// ----------------------------------------------------------------------------- +// void copy_data(FILE *f1, FILE *f2) +// +// Copies data from file f1 to file f2. +// +// Inputs : f1 = FILE 1 +// f2 = FILE 2 +// +// Output : None +// +// Side Effects : Closes file f1 upon exit. +// ----------------------------------------------------------------------------- + +void copy_data(FILE *f1, FILE *f2) { + + while (fgets(buffer,1023,f1)) { + fputs(buffer, f2); + } + fclose(f1); +} + +// ----------------------------------------------------------------------------- +// void copy_data(FILE *f1, String *s2) +// +// Copies data from file f1 to String s2. +// +// Inputs : f1 = FILE 1 +// s2 = String +// +// Output : None +// +// Side Effects : Closes file f1 upon exit. +// ----------------------------------------------------------------------------- + +void copy_data(FILE *f1, String &s2) { + + while (fgets(buffer,1023,f1)) { + s2 << buffer; + } + fclose(f1); +} + +// ----------------------------------------------------------------------------- +// int insert_file(char *name, FILE *f) +// +// Looks for a file and inserts into file f. +// +// Inputs : name = filename +// f = FILE +// +// Output : 0 on success, -1 on failure. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +int insert_file(char *name, FILE *f_out) { + + FILE *f; + char filename[256]; + int found = 0; + Dnode *d; + + if (!include_init) return -1; // Not initialized yet + if (add_iname(name)) { + if (Verbose) fprintf(stderr,"file %s already included.\n", name); + return -1; // Already included this file + } + + if (Verbose) fprintf(stderr,"Looking for ./%s\n", name); + if ((f = fopen(name,"r")) != NULL) { + copy_data(f,f_out); + return 0; + } + + // Now start searching libraries + + d = ihead.next; // Start of search list + while (d != &iz) { + // Look for the wrap file in language directory + sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name); + if (Verbose) fprintf(stderr,"Looking for %s\n", filename); + if((f = fopen(filename,"r")) != NULL) { + found = 1; + } else { + sprintf(filename,"%s%c%s", d->dirname, DELIMETER, name); + if (Verbose) fprintf(stderr,"Looking for %s\n", filename); + if ((f = fopen(filename,"r")) != NULL) { + found = 1; + } + } + if (found) { + copy_data(f,f_out); + return 0; + } + d = d->next; + } + + if ((!found) && (Verbose)) fprintf(stderr,"unable to find %s. (Ignored)\n",name); + return -1; +} + +// ----------------------------------------------------------------------------- +// void swig_append(char *filename, FILE *f) +// +// Appends the contents of filename to stream f. +// +// Inputs : +// filename = File to append +// f = FILE handle +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void swig_append(char *filename, FILE *f) { + + FILE *in_file; + + if ((in_file = fopen(filename,"r")) == NULL) { + fprintf(stderr,"** SWIG ERROR ** file %s not found.\n",filename); + FatalError(); + return; + } + while (fgets(buffer,1023,in_file)) { + fputs(buffer, f); + } + fclose(in_file); +} + + +// ----------------------------------------------------------------------------- +// int get_file(char *name, String &str) +// +// Looks for a file and converts it into a String. +// +// Inputs : name = filename +// str = String +// +// Output : 0 on success, -1 on failure. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +int get_file(char *name, String &str) { + + FILE *f; + char filename[256]; + int found = 0; + Dnode *d; + + if (!include_init) return -1; // Not initialized yet + + if (Verbose) fprintf(stderr,"Looking for %s\n", name); + if ((f = fopen(name,"r")) != NULL) { + copy_data(f,str); + return 0; + } + + // Now start searching libraries + + d = ihead.next; // Start of search list + while (d != &iz) { + // Look for the wrap file in language directory + sprintf(filename,"%s%c%s%c%s", d->dirname,DELIMETER,LibDir,DELIMETER,name); + if (Verbose) fprintf(stderr,"Looking for %s\n", filename); + if((f = fopen(filename,"r")) != NULL) { + found = 1; + } else { + sprintf(filename,"%s%c%s", d->dirname, DELIMETER, name); + if (Verbose) fprintf(stderr,"Looking for %s\n", filename); + if ((f = fopen(filename,"r")) != NULL) { + found = 1; + } + } + if (found) { + copy_data(f,str); + return 0; + } + d = d->next; + } + + if ((!found)) fprintf(stderr,"SWIG Error. Unable to find %s. Possible installation problem.\n",name); + FatalError(); + return -1; +} + +static char *libs[1000]; +static int nlibs = 0; + +// ----------------------------------------------------------------------------- +// void library_add(char *name) +// +// Adds a filename to the list of libraries. This is usually only called by +// the SWIG main program. +// +// Inputs : name = library name +// +// Outputs: None +// +// Side Effects : Adds the library name to the libs array above +// ----------------------------------------------------------------------------- + +void library_add(char *name) { + int i; + + // Check to make sure it's not already added + + if (!(*name)) return; + + for (i = 0; i < nlibs; i++) { + if (strcmp(libs[i],name) == 0) return; + } + + libs[nlibs] = copy_string(name); + nlibs++; +} + +// ----------------------------------------------------------------------------- +// void library_insert() +// +// Starts parsing all of the SWIG library files. +// +// Inputs : None +// +// Output : None +// +// Side Effects : Opens and attaches all of the specified library files to +// the scanner. +// +// Bugs : Opens all of the files. Will fail if there are too many open files. +// +// ----------------------------------------------------------------------------- + +void library_insert() { + int i; + + i = nlibs-1; + while (i >= 0) { + include_file(libs[i]); + i--; + } +} + +// ----------------------------------------------------------------------------- +// int checkout(char *filename,char *dest) +// +// Tries to check a file out of the SWIG library. If found, it will save it in +// the current directory. This is a useful mechanism for using SWIG as a code +// manager and for extracting library files. +// +// Inputs : filename = Library file +// dest = Destination file +// +// Output : 0 on success +// -1 on failure. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +int checkout_file(char *filename,char *dest) { + + FILE *f1; + char tempn[256]; + + // First check to see if the file already exists in current directory + f1 = fopen(dest,"r"); + if (f1) { + if (Verbose) + fprintf(stderr,"Warning. Unable to check-out %s. File already exists.\n", filename); + fclose(f1); + return -1; + } + + while (!f1) { + sprintf(tempn,"%s%d",dest,rand()); + f1 = fopen(tempn,"r"); + if (f1) { + fclose(f1); + f1 = 0; + } else { + f1 = fopen(tempn,"w"); + if (!f1) { + fprintf(stderr,"Unable to open %s for writing\n", tempn); + return -1; + } + } + } + + // Now try to insert the library file into the destination file + if ((insert_file(filename,f1)) == -1) { + fprintf(stderr,"Unable to check-out '%s'. File does not exist in SWIG library.\n",filename); + fclose(f1); + remove(tempn); // Unsuccessful, remove file we created + return -1; + } + fclose(f1); + // Now move the file + rename(tempn,dest); + return 0; +} + + +// ----------------------------------------------------------------------------- +// int checkin_file(char *dir, char *lang, char *source,char *dest) +// +// Attempts to check a file into the SWIG library. +// +// Inputs : dir = Location of the SWIG library. +// lang = Language specific subdirectory. +// source = Source file. +// dest = Destination file. +// +// Output : 0 on success +// -1 on failure. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +int checkin_file(char *dir, char *lang, char *source, char *dest) { + + FILE *f1; + char tempn[256]; + String s; + + // First check to see if the file exists + + f1 = fopen(source,"r"); + if (!f1) return -1; + + copy_data(f1,s); + + // Now try to open the destination file + sprintf(tempn,"%s/%s/%s", dir,lang,dest); + f1 = fopen(tempn,"w"); + if (!f1) return -1; + fprintf(f1,"%s",s.get()); + fclose(f1); + return 0; +} + + + + diff --git a/wxPython/wxSWIG/SWIG/internal.h b/wxPython/wxSWIG/SWIG/internal.h new file mode 100644 index 0000000000..900d937aee --- /dev/null +++ b/wxPython/wxSWIG/SWIG/internal.h @@ -0,0 +1,215 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/*********************************************************************** + * $Header$ + * + * internals.h + * + * Contains global variables used in libswig, but which are otherwise + * inaccessible to the user. + * + ***********************************************************************/ + +#include "swig.h" + +// ------------------------------------------------------------------- +// class DocTitle : public DocEntry +// +// Top level class for managing documentation. Prints out a title, +// date, etc... +// ------------------------------------------------------------------- + +class DocTitle : public DocEntry { +public: + DocTitle(char *title, DocEntry *_parent); // Create a new title + void output(Documentation *d); // Output documentation +}; + +// -------------------------------------------------------------------- +// class DocSection : public DocEntry +// +// Documentation entry for a section +// -------------------------------------------------------------------- + +class DocSection : public DocEntry { +public: + DocSection(char *section, DocEntry *_parent); + void output(Documentation *d); +}; + +// -------------------------------------------------------------------- +// class DocFunction : public DocEntry +// +// Documentation entry for generic sorts of declarations +// -------------------------------------------------------------------- + +class DocDecl : public DocEntry { +public: + DocDecl(char *fname, DocEntry *_parent); + DocDecl(DocEntry *de, DocEntry *_parent); + void output(Documentation *d); +}; + +// -------------------------------------------------------------------- +// class DocClass : public DocEntry +// +// Documentation entry for a C++ class or C struct +// -------------------------------------------------------------------- + +class DocClass : public DocEntry { +public: + DocClass(char *classname, DocEntry *_parent); + void output(Documentation *d); +}; + +// -------------------------------------------------------------------- +// class DocText : public DocEntry +// +// Documentation entry for some plain ole text. Declared using +// the %text %{,%} directive. +// -------------------------------------------------------------------- + +class DocText : public DocEntry { +public: + DocText(char *_text, DocEntry *_parent); + void output(Documentation *d); +}; + +// -------------------------------------------------------------------- +// class CommentHandler +// +// Class for managing comment processing. +// -------------------------------------------------------------------- + +class CommentHandler { +public: + CommentHandler(); + CommentHandler(CommentHandler *c); + ~CommentHandler(); + void add_comment(char *text, int line_num, int col, char *file); // Add a comment + void set_entry(DocEntry *d); // Set documentation entry + static void cleanup(); // Clean-up everything before quitting + void style(char *name, char *value); + void parse_args(int argc, char **argv); // Parse command line options + + // Comment handling style parameters + int skip_lines; // # blank lines before comment is throw away + int location; // Comment location (BEFORE or AFTER) + int chop_top; // Lines to chop from the top of a comment + int chop_bottom; // Lines to chop from the bottom + int chop_left; // Characters to chop from left + int chop_right; // Characters to chop from right + int untabify; // Expand tabs + int ignore; // Ignore comments +}; + +#define BEFORE 0 +#define AFTER 1 + + +extern int include_file(char *); // Insert library file +extern char category[256]; +extern char title[256]; +extern DocEntry *doc_entry; +extern DocEntry *doctitle; // The very first docentry +extern DocEntry *doc_stack[256]; // Stack of documentation entries +extern CommentHandler *handler_stack[256]; // Stack of comment handlers +extern int doc_stack_top; // Top of stack + +extern Language *lang; +extern Documentation *doc; +extern CommentHandler *comment_handler; // Comment handling system +extern void swig_append(char *, FILE *); +extern int Stat_func, Stat_var, Stat_const; +extern int IgnoreDoc; +extern int ForceExtern; +extern int WrapExtern; +extern String CCode; +extern int GenerateDefault; +extern int type_id; +extern char *ConfigFile; +extern char *objc_construct; +extern char *objc_destruct; +extern int DocOnly; + +// Structure for holding typemap parameters +// A typemap parameter consists of a single parameter (type + name) +// and an optional list of arguments corresponding to local variables. +// Has an optional link for building linked lists of parameter lists + +struct TMParm { + Parm *p; + ParmList *args; + TMParm *next; + TMParm() { + next = 0; + } +}; + +/* Global variables. Needs to be cleaned up */ + +#ifdef WRAP + + FILE *f_header; // Some commonly used + FILE *f_wrappers; // FILE pointers + FILE *f_init; + FILE *f_input; + char InitName[256]; + char LibDir[512]; // Library directory + char **InitNames = 0; + int Status; + int TypeStrict; // Type checking strictness + int Verbose; + char category[256]; // Variables for documentation + char title[256]; + DocEntry *doc_entry = 0; // Current documentation entry + DocEntry *doctitle = 0; // First doc entry + DocEntry *doc_stack[256]; // Stack of documentation entries + CommentHandler *handler_stack[256]; // Stack of comment handlers + int doc_stack_top = 0; // Top of stack + + Language *lang; // Language method + Documentation *doc; // Documentation method + int Stat_func = 0; + int Stat_var = 0; + int Stat_const = 0; + int CPlusPlus = 0; + int ObjC = 0; + int ObjCClass = 0; + int AddMethods = 0; // AddMethods flag + int NewObject = 0; // NewObject flag + int Inline = 0; // Inline mode + int Stats = 0; + int IgnoreDoc = 0; // Ignore documentation mode + int ForceExtern = 0; // Force extern mode + int WrapExtern = 0; + int GenerateDefault = 0; // Generate default constructors + char *Config = 0; + int NoInclude = 0; + char *typemap_lang = 0; // Typemap name + int type_id = 0; // Type identifier + int error_count = 0; // Error count + char *ConfigFile = 0; + int DocOnly = 0; // Only produce documentation + +#endif + +/* Number of initialization names that can be used */ + +#define NI_NAMES 512 + +extern void type_undefined_check(void); + diff --git a/wxPython/wxSWIG/SWIG/lang.cxx b/wxPython/wxSWIG/SWIG/lang.cxx new file mode 100644 index 0000000000..d1d7228535 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/lang.cxx @@ -0,0 +1,621 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" +#include + + +// ----------------------------------------------------------------------- +// $Header$ +// +// lang.cxx +// +// This file contains some default methods for the SWIG language class. +// Default C++ handling is implemented here as well as a few utility functions. +// +// ----------------------------------------------------------------------- + + +// ----------------------------------------------------------------- +// void Language::set_init(char *iname) +// +// Called to make an initialization function by %init (obsolete) +// ----------------------------------------------------------------- + +void Language::set_init(char *iname) { + set_module(iname,0); +} + +// ----------------------------------------------------------------- +// void Language::create_command(char *cname, char *iname +// +// Method for adding a previous wrapped C function. +// ----------------------------------------------------------------- + +void Language::create_command(char *, char *) { + fprintf(stderr,"SWIG Warning. No command creation procedure defined.\n"); + fprintf(stderr,"C++ inheritance may not work correctly.\n"); +} + +// ----------------------------------------------------------------- +// void Language::add_native(char *targetlang, char *funcname) +// +// Method for adding a native function +// ----------------------------------------------------------------- + +void +Language::add_native(char *, char *funcname) { + + fprintf(stderr,"%s : Line %d. Adding native function %s not supported (ignored).\n", input_file, line_number, funcname); + +} + +static char *ClassName = 0; // This is the real name of the current class +static char *ClassRename = 0; // This is non-NULL if the class has been renamed +static char *ClassType = 0; // Type of class (ie. union, struct, class) + +// --------------------------------------------------------------------------------- +// void Language::cpp_open_class(char *classname, char *classrename, char *ctype, int strip) +// +// Open a new C++ class. +// +// INPUTS: +// classname = Real name of the C++ class +// classrename = New name of the class (if %name was used) +// ctype = Class type (struct, class, union, etc...) +// strip = Flag indicating whether we should strip the class type off +// +// This function is in charge of creating a new class. The SWIG parser has +// already processed the entire class definition prior to calling this +// function (which should simplify things considerably). +// +// --------------------------------------------------------------------------------- + +void Language::cpp_open_class(char *classname, char *classrename, char *ctype, int strip) { + + // Copy the class name + + if (ClassName) delete ClassName; + ClassName = copy_string(classname); + + // Copy the class renaming + + if (ClassRename) delete ClassRename; + if (classrename) { + ClassRename = copy_string(classrename); + } else { + ClassRename = 0; // No renaming + } + + // Make the class type + + if (ClassType) delete ClassType; + ClassType = new char[strlen(ctype)+2]; + if (strip) ClassType[0] = 0; + else sprintf(ClassType,"%s ",ctype); + + if (doc_entry) { + doc_entry->usage = ""; + doc_entry->name = copy_string(classname); + doc_entry->usage << "class "; + if (ClassRename) doc_entry->usage << ClassRename; + else doc_entry->usage << ClassName; + doc_entry->cinfo << "created from " << ctype + << " " << classname; + } +} + +// --------------------------------------------------------------------------------- +// void Language::cpp_close_class() +// +// Close the current class +// --------------------------------------------------------------------------------- + +void Language::cpp_close_class() { + + + // Doesn't really do anything +} + +// --------------------------------------------------------------------------------- +// void Language::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) +// +// Method for adding C++ member function +// +// INPUTS: +// name - name of the member function +// iname - renaming (if given) +// t - Return datatype +// l - Parameter list +// +// By default, we're going to create a function of the form : +// +// Foo_bar(this,args) +// +// Where Foo is the classname, bar is the member name and the this pointer is +// explicitly attached to the beginning. +// +// The renaming only applies to the member function part, not the full classname. +// +// --------------------------------------------------------------------------------- + +void Language::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) { + char cname[256]; // Name of the C function + char new_name[256]; + char *prefix; + + // Generate the C wrapper function name and interpreter name of this function + + // Set the classname prefix + if (ClassRename) { + prefix = ClassRename; + } else { + prefix = ClassName; + } + + // Generate the C wrapper name for this method + + if (AddMethods) { + char *bc = cplus_base_class(name); // Get base class name of this method + if (bc) + strcpy(cname, name_member(name,bc)); + else + strcpy(cname, name_member(name,ClassName)); + } else { + strcpy(cname, name_member(name,ClassName)); + } + + // Create the actual function name + + if (iname) { + strcpy(new_name, name_member(iname, prefix)); + } else { + strcpy(new_name, name_member(name,prefix)); + } + + // Now do a symbol table lookup on it : + + if (add_symbol(new_name, 0,0)) { + fprintf(stderr,"%s : Line %d. Function %s (member %s) multiply defined (2nd definition ignored).\n", + input_file, line_number, cname, name); + return; + } + + // Now produce the resulting wrapper function + if (doc_entry) { + doc_entry->cinfo << "Member : "; + } + cplus_emit_member_func(ClassName, ClassType, ClassRename, name, iname, t, l, AddMethods); +} + +// --------------------------------------------------------------------------------- +// void Language::cpp_constructor(char *name, char *iname, ParmList *l) +// +// Method for adding C++ member constructor +// +// INPUTS: +// name - Name of the constructor (usually same as classname) +// iname - Renamed version +// l - parameters +// --------------------------------------------------------------------------------- + +void Language::cpp_constructor(char *name, char *iname, ParmList *l) { + + char *prefix, *cname; + + if ((strcmp(name,ClassName)) && (!ObjCClass)) { + fprintf(stderr,"%s : Line %d. Function %s must have a return type.\n", + input_file, line_number, name); + return; + } + + // Set the prefix + + if (ClassRename) + prefix = ClassRename; + else + prefix = ClassName; + + if (iname) + cname = name_construct(iname); + else + cname = name_construct(prefix); + + // Add this function to the SWIG symbol table + + if (add_symbol(cname, 0,0)) { + fprintf(stderr,"%s : Line %d. Constructor %s multiply defined (2nd definition ignored).\n", + input_file, line_number, cname); + return; + } + + // Attach a note to the cinfo field. + + if (doc_entry) + doc_entry->cinfo << "Constructor: "; + + // Call our default method + + cplus_emit_constructor(ClassName, ClassType, ClassRename, name, iname, l, AddMethods); + +} + +// --------------------------------------------------------------------------------- +// void Language::cpp_destructor(char *name, char *iname) +// +// Method for adding C++ member destructor +// +// INPUT: +// name - Name of the destructor (classname) +// iname - Renamed destructor +// +// --------------------------------------------------------------------------------- + +void Language::cpp_destructor(char *name, char *iname) { + + char *cname; + + if (ClassRename) + cname = name_destroy(ClassRename); + else + cname = name_destroy(ClassName); + + // Add this function to the SWIG symbol table + + if (add_symbol(cname, 0,0)) { + fprintf(stderr,"%s : Line %d. Destructor %s multiply defined (2nd definition ignored).\n", + input_file, line_number, cname); + return; + } + + + // Attach a note to the description + + if (doc_entry) + doc_entry->cinfo << "Destructor: "; + + // Call our default method + + cplus_emit_destructor(ClassName, ClassType, ClassRename, name, iname, AddMethods); + +} + +// --------------------------------------------------------------------------------- +// void Language::cleanup() +// +// Perform any necessary cleanup after reaching end of interface file +// --------------------------------------------------------------------------------- + +void Language::cpp_cleanup() { + + // This doesn't do anything (well, not be default) + +} + +// --------------------------------------------------------------------------------- +// void Language::cpp_inherit(char **baseclass, int mode) +// +// Inherit attributes from given baseclass. +// +// INPUT: +// baseclass = NULL terminate list of baseclasses +// +// --------------------------------------------------------------------------------- + +void Language::cpp_inherit(char **baseclass, int mode) { + + extern void cplus_inherit_members(char *, int); + int i = 0; + + if (!baseclass) return; + while (baseclass[i]) { + cplus_inherit_members(baseclass[i],mode); + i++; + } +} + +// --------------------------------------------------------------------------------- +// void Language::cpp_variable(char *name, char *iname, DataType *t) +// +// Wrap a C++ data member +// +// INPUTS : +// name = Name of the C++ member +// iname = Name as used in the interpreter +// t = Datatype +// +// This creates a pair of functions to set/get the variable of a member. +// --------------------------------------------------------------------------------- + +void Language::cpp_variable(char *name, char *iname, DataType *t) { + char *prefix, *cname; + + // Set the class prefix + + if (ClassRename) { + prefix = ClassRename; + } else { + prefix = ClassName; + } + + if (iname) + cname = name_get(name_member(iname,prefix)); + else + cname = name_get(name_member(name,prefix)); + + // Check the symbol table + + if (add_symbol(cname,(DataType *) 0,(char *) 0)) { + fprintf(stderr,"%s : Line %d. Variable %s multiply defined (2nd definition ignored).\n", input_file, line_number, cname); + return; + } + + // Attach a c descriptor + + if (doc_entry) + doc_entry->cinfo << "Member data: "; + + // Create a function to set the value of the variable + + if (!(Status & STAT_READONLY)) { + cplus_emit_variable_set(ClassName, ClassType, ClassRename, name, iname, t, AddMethods); + // Add a new line to the documentation entry + if (doc_entry) doc_entry->usage << "\n"; + } + + // Create a function to get the value of a variable + + cplus_emit_variable_get(ClassName,ClassType, ClassRename, name, iname, t, AddMethods); + +} + +// --------------------------------------------------------------------------------- +// void Language::cpp_static_func(char *name, char *iname, DataType *t, ParmList *l) +// +// Wrap a static C++ function +// +// INPUTS: +// name = Real name of the function +// iname = New name in interpreter +// t = Return datatype +// l = Parameters +// --------------------------------------------------------------------------------- + +void Language::cpp_static_func(char *name, char *iname, DataType *t, ParmList *l) { + + char *prefix; + char *mname; + char *cname; + + // Set the classname prefix + + if (ClassRename) + prefix = ClassRename; + else + prefix = ClassName; + + // Set the member function name + + if (iname) + mname = iname; + else + mname = name; + + cname = name_member(mname,prefix); + + // Now do a symbol table lookup on it : + + if (add_symbol(cname, 0,0)) { + if (ObjCClass) + fprintf(stderr,"%s : Line %d. class function %s multiply defined (2nd definition ignored).\n", + input_file, line_number, cname); + else + fprintf(stderr,"%s : Line %d. static function %s multiply defined (2nd definition ignored).\n", + input_file, line_number, cname); + return; + } + + if (doc_entry) { + if (ObjCClass) + doc_entry->cinfo << "Class method : "; + else + doc_entry->cinfo << "Static member : "; + } + + cplus_emit_static_func(ClassName,ClassType, ClassRename, name, iname, t, l, AddMethods); + +} + +// --------------------------------------------------------------------------------- +// void Language::cpp_declare_const(char *name, char *iname, DataType *t, char *value) +// +// Create a C++ constant +// +// INPUTS : +// name = Real name of the constant +// iname = new name +// t = Datatype +// value = value as a string +// +// --------------------------------------------------------------------------------- + +void Language::cpp_declare_const(char *name, char *iname, DataType *type, char *value) +{ + + char *cname; + char mname[256]; + char *new_value; + char *prefix; + + // Set the classname prefix + + if (ClassRename) { + prefix = ClassRename; + } else { + prefix = ClassName; + } + + // Set the constant name + + if (iname) + cname = name_member(iname,prefix); + else + cname = name_member(name,prefix); + + // Now do a symbol table lookup on it : + + if (add_symbol(cname, 0,0)) { + fprintf(stderr,"%s : Line %d. Constant %s (member %s) multiply defined (2nd definition ignored).\n", + input_file, line_number, cname, name); + return; + } + + // Form correct C++ name + + sprintf(mname,"%s::%s",ClassName,name); + + // Declare a constant + if (!value) { + new_value = new char[strlen(ClassName)+strlen(name)+3]; + sprintf(new_value,"%s::%s",ClassName,name); + } else { + new_value = value; + } + + lang->declare_const(cname,cname,type, new_value); + + if (!value) { + delete new_value; + } +} + +// --------------------------------------------------------------------------------- +// void Language::cpp_static_var(char *name, char *iname, DataType *t) +// +// Wrap a static C++ variable +// +// INPUT : +// name = name of the variable +// iname = interpreter name +// t = Datatype +// +// --------------------------------------------------------------------------------- + +void Language::cpp_static_var(char *name, char *iname, DataType *t) { + + char *cname; + char mname[256]; + char *prefix; + + // Set the classname prefix + + if (ClassRename) { + prefix = ClassRename; + } else { + prefix = ClassName; + } + + // Create the variable name + + if (iname) + cname = name_member(iname,prefix); + else + cname = name_member(name,prefix); + + // Now do a symbol table lookup on it : + + if (add_symbol(cname, 0,0)) { + fprintf(stderr,"%s : Line %d. Variable %s (member %s) multiply defined (2nd definition ignored).\n", + input_file, line_number, cname, name); + return; + } + + // Form correct C++ name + + sprintf(mname,"%s::%s",ClassName,name); + + if (doc_entry) + doc_entry->cinfo << "Static member : "; + + // Link with this variable + + lang->link_variable(mname,cname,t); +} + +// --------------------------------------------------------------------------------- +// void Language::cpp_class_decl(char *classtype, char *classrename, char *classname) +// +// A forward class declaration +// --------------------------------------------------------------------------------- + +void Language::cpp_class_decl(char *, char *, char *) { + + // Does nothing by default + +} + +// ----------------------------------------------------------------------------- +// void Language::cpp_pragma(Pragma *plist) +// +// Handler C++ pragmas +// ----------------------------------------------------------------------------- + +void Language::cpp_pragma(Pragma *) { + // Does nothing by default +} + +// --------------------------------------------------------------------------------- +// void Language::add_typedef(DataType *t, char *name) +// +// Process a typedef declaration. +// --------------------------------------------------------------------------------- + +void Language::add_typedef(DataType *, char *) { + +} + + +// --------------------------------------------------------------------------------- +// void Language::pragma(char *target, char *var, char *value) +// +// A pragma declaration +// --------------------------------------------------------------------------------- + +void Language::pragma(char *, char *, char *) { + + // Does nothing by default + +} + +// --------------------------------------------------------------------------------- +// void Language::import(char *filename) +// +// An import directive +// --------------------------------------------------------------------------------- + +void Language::import(char *) { + + // Does nothing by default + +} + + + + + + + + + diff --git a/wxPython/wxSWIG/SWIG/latex.cxx b/wxPython/wxSWIG/SWIG/latex.cxx new file mode 100644 index 0000000000..37cb998357 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/latex.cxx @@ -0,0 +1,490 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/*********************************************************************** + * $Header$ + * + * latex.c + * + * Latex specific functions for producing documentation. + * + ***********************************************************************/ + +#include "swig.h" +#include "latex.h" + +// ------------------------------------------------------------------- +// LATEX::LATEX() +// +// Create new LaTeX handler +// ------------------------------------------------------------------- + +LATEX::LATEX() { + sect_count = 0; + + tag_pagestyle = "\\pagestyle{headings}"; + tag_parindent = "0.0in"; + tag_textwidth = "6.5in"; + tag_documentstyle = "[11pt]{article}"; + tag_oddsidemargin = "0.0in"; + tag_title = "{\\Large \\bf : }"; + tag_preformat = "{\\small \\begin{verbatim}:\\end{verbatim}}"; + tag_usage = "{\\tt \\bf : }"; + tag_descrip = "\\\\\n\\makebox[0.5in]{}\\begin{minipage}[t]{6in}:\n\\end{minipage}\\\\\n"; + tag_text = ":\\\\"; + tag_cinfo = "{\\tt : }\\\\"; + tag_section = "\\section{:}"; + tag_subsection="\\subsection{:}"; + tag_subsubsection="\\subsubsection{:}"; +} + +// ------------------------------------------------------------------- +// char *start_tag(char *tag) { +// +// Returns the start of a tag +// ------------------------------------------------------------------- + +char *LATEX::start_tag(char *tag) { + static String stag; + char *c; + + stag = ""; + c = tag; + while ((*c) && (*c != ':')) { + stag << *c; + c++; + } + return stag.get(); +} + +// ------------------------------------------------------------------- +// char *end_tag(char *tag) { +// +// Returns the end of a tag +// ------------------------------------------------------------------- + +char *LATEX::end_tag(char *tag) { + static String etag; + char *c; + + etag = ""; + c = tag; + while ((*c) && (*c != ':')) { + c++; + } + if (*c) { + c++; + while (*c) { + etag << *c; + c++; + } + } + return etag.get(); +} + +// ------------------------------------------------------------------- +// LATEX::print_string(char *s, String &str) +// +// Dumps string s to str, but performs some LaTeX character replacements +// ------------------------------------------------------------------- + +void LATEX::print_string(char *s, String &str) { + + char *c; + c = s; + while (*c) { + switch(*c) { + case '*': + case '<': + case '>': + case '+': + case '=': + case '|': + str << "$" << *c << "$"; + break; + case '\\': + str << "\\\\"; + break; + case '_': + str << "\\_"; + break; + case '%': + str << "\\%"; + break; + case '$': + str << "\\$"; + break; + case '&': + str << "\\&"; + break; + case '#': + str << "\\#"; + break; + case '\n': + str << "\\\\\n"; + break; + default : + str << *c; + break; + } + c++; + } +} + +// -------------------------------------------------------------- +// LATEX::print_decl(DocEntry *) +// +// Print a documentation entry +// -------------------------------------------------------------- + +void LATEX::print_decl(DocEntry *de) { + + char *c; + + c = de->usage.get(); + + if (c) { + s_doc << start_tag(tag_usage); + print_string(c,s_doc); + s_doc << end_tag(tag_usage) << "\n"; + } + + // Check to see if there any information available + + if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) { + + // There is additional information now. If we're in preformatting mode, + // we need to handle things differently + + s_doc << start_tag(tag_descrip) << "\n"; + + if (!de->format) { + // Verbatim mode + s_doc << start_tag(tag_preformat) << "\n"; + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + s_doc << "[ " << c << " ]\n"; + } + } + c = de->text.get(); + if (strlen(c) > 0) { + s_doc << c; + } + s_doc << end_tag(tag_preformat) << "\n"; + } else { + // We are in format mode now + // We need to emit some stubs for the description format + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + s_doc << start_tag(tag_cinfo) << "[ "; + print_string(c,s_doc); + s_doc << " ] " << end_tag(tag_cinfo) << "\n"; + } + } + // Print out descriptive text (if any). + c = de->text.get(); + if (strlen(c) > 0) { + s_doc << c << "\\\\\n"; + } + } + s_doc << end_tag(tag_descrip) << "\n"; + } else { + s_doc << "\\\\\n"; // No description available, move to next line + } +} + +// -------------------------------------------------------------- +// LATEX::print_text(DocEntry *de) +// +// Print out some text. We use verbatim mode because of formatting +// problems. +// -------------------------------------------------------------- + +void LATEX::print_text(DocEntry *de) { + char *c; + c = de->text.get(); + if (strlen(c) > 0) { + if (de->format) { + s_doc << start_tag(tag_text) << "\n"; + s_doc << c; + s_doc << end_tag(tag_text) << "\n\n"; + } else { + s_doc << start_tag(tag_preformat) << "\n"; + s_doc << c; + s_doc << end_tag(tag_preformat) << "\n\n"; + } + } +} + +void LATEX::title(DocEntry *de) { + char *c; + + c = de->usage.get(); + if (strlen(c) > 0) { + s_doc << start_tag(tag_title) << " "; + print_string(c,s_doc); + s_doc << end_tag(tag_title) << "\\\\\n"; + } + + // Print out any C annotation and descriptive text + // Check to see if there any information available + + if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) { + + // There is additional information now. If we're in preformatting mode, + // we need to handle things differently + + if (!de->format) { + // Verbatim mode + s_doc << start_tag(tag_preformat) << "\n"; + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + s_doc << "[ " << c << " ]\n"; + } + } + + c = de->text.get(); + if (strlen(c) > 0) { + s_doc << c; + } + s_doc << end_tag(tag_preformat) << "\n\n"; + } else { + // We are in format mode now + // We need to emit some stubs for the description format + s_doc << start_tag(tag_text); + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + s_doc << start_tag(tag_cinfo) << "[ "; + print_string(c,s_doc); + s_doc << " ] " << end_tag(tag_cinfo) << "\n"; + } + } + // Print out descriptive text (if any). + c = de->text.get(); + if (strlen(c) > 0) { + s_doc << c; + } + s_doc << end_tag(tag_text); + } + } +} + +void LATEX::newsection(DocEntry *de,int sectnum) { + char *c; + char *tag; + + sect_num[sect_count] = sectnum; + sect_count++; + switch (sect_count) { + case 1: /* Section */ + tag = tag_section; + break; + case 2: /* Subsection */ + tag = tag_subsection; + break; + default: /* subsubsection */ + tag = tag_subsubsection; + break; + } + + s_doc << start_tag(tag); + c = de->usage.get(); + print_string(c,s_doc); + s_doc << end_tag(tag); + + + // Print out any C annotation and descriptive text + // Check to see if there any information available + + if ((strlen(de->cinfo.get()) && de->print_info) || strlen(de->text.get())) { + + // There is additional information now. If we're in preformatting mode, + // we need to handle things differently + + if (!de->format) { + // Verbatim mode + s_doc << start_tag(tag_preformat) << "\n"; + + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + s_doc << "[ " << c << " ]\n"; + } + } + + c = de->text.get(); + if (strlen(c) > 0) { + s_doc << c; + } + s_doc << end_tag(tag_preformat) << "\n\n"; + } else { + // We are in format mode now + // We need to emit some stubs for the description format + + s_doc << start_tag(tag_text); + // If there is any C annotation, print that + if (de->print_info) { + c = de->cinfo.get(); + if (strlen(c) > 0) { + s_doc << start_tag(tag_cinfo) << "[ "; + print_string(c,s_doc); + s_doc << " ] " << end_tag(tag_cinfo) << "\n"; + } + } + // Print out descriptive text (if any). + c = de->text.get(); + if (strlen(c) > 0) { + s_doc << c; + } + s_doc << end_tag(tag_text); + } + } +} + + +void LATEX::endsection() { + if (sect_count > 0) sect_count--; +} + +void LATEX::separator() { +} + +void LATEX::init(char *filename) { + char f[256]; + + sprintf(f,"%s.tex",filename); + sprintf(fn,"%s",filename); + f_doc = fopen(f,"w"); + if (f_doc == NULL) { + fprintf(stderr, "Unable to open %s\n", fn); + SWIG_exit(1); + } +} + +void LATEX::close(void) { + + fprintf(f_doc,"\\documentstyle%s\n",tag_documentstyle); + fprintf(f_doc,"\\setlength{\\parindent}{%s}\n",tag_parindent); + fprintf(f_doc,"\\setlength{\\textwidth}{%s}\n",tag_textwidth); + fprintf(f_doc,"\\setlength{\\oddsidemargin}{%s}\n",tag_oddsidemargin); + fprintf(f_doc,"%s\n",tag_pagestyle); + fprintf(f_doc,"\\begin{document}\n"); + fprintf(f_doc,"%s\n",s_doc.get()); + fprintf(f_doc,"\\end{document}\n"); + fclose(f_doc); + if (Verbose) + fprintf(stderr,"Documentation written to %s.tex\n", fn); +} + +// ------------------------------------------------------------------- +// LATEX::style(char *name, char *value) +// +// Process style parameters +// ------------------------------------------------------------------- + +void LATEX::style(char *name, char *value) { + if (strcmp(name,"latex_title") == 0) { + if (value) + tag_title = copy_string(value); + } else if (strcmp(name,"latex_pagestyle") == 0) { + if (value) + tag_pagestyle = copy_string(value); + } else if (strcmp(name,"latex_section") == 0) { + if (value) + tag_section = copy_string(value); + } else if (strcmp(name,"latex_subsection") == 0) { + if (value) + tag_subsection = copy_string(value); + } else if (strcmp(name,"latex_subsubsection") == 0) { + if (value) + tag_subsubsection = copy_string(value); + } else if (strcmp(name,"latex_usage") == 0) { + if (value) + tag_usage = copy_string(value); + } else if (strcmp(name,"latex_descrip") == 0) { + if (value) + tag_descrip = copy_string(value); + } else if (strcmp(name,"latex_text") == 0) { + if (value) + tag_text = copy_string(value); + } else if (strcmp(name,"latex_cinfo") == 0) { + if (value) + tag_cinfo = copy_string(value); + } else if (strcmp(name,"latex_preformat") == 0) { + if (value) + tag_preformat = copy_string(value); + } else if (strcmp(name,"latex_parindent") == 0) { + if (value) + tag_parindent = copy_string(value); + } else if (strcmp(name,"latex_textwidth") == 0) { + if (value) + tag_textwidth = copy_string(value); + } else if (strcmp(name,"latex_documentstyle") == 0) { + if (value) + tag_documentstyle = copy_string(value); + } else if (strcmp(name,"latex_oddsidemargin") == 0) { + if (value) + tag_oddsidemargin = copy_string(value); + } +} + +// ------------------------------------------------------------------- +// LATEX::parse_args(int argc, char **argv) +// +// Parse command line options +// ------------------------------------------------------------------- + +static char *latex_usage = "\ +LATEX Documentation Options (available with -dlatex)\n\ + None available.\n\n"; + +void LATEX::parse_args(int argc, char **argv) { + int i; + + for (i = 0; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i],"-help") == 0) { + fputs(latex_usage,stderr); + } + } + } +} + + + + + + + + + + + + + + diff --git a/wxPython/wxSWIG/SWIG/latex.h b/wxPython/wxSWIG/SWIG/latex.h new file mode 100644 index 0000000000..6f65cc07b0 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/latex.h @@ -0,0 +1,79 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ +/*********************************************************************** + * $Header$ + * + * latex.h + * + * Latex specific functions for producing documentation. + ***********************************************************************/ +class LATEX : public Documentation { +private: + FILE *f_doc; + String s_doc; + char fn[256]; + char *start_tag(char *); + char *end_tag(char *); + void print_string(char *s, String &str); + int sect_count; // Section counter + int sect_num[20]; // Section numbers + // Style parameters + + char *tag_parindent; + char *tag_textwidth; + char *tag_documentstyle; + char *tag_oddsidemargin; + char *tag_title; + char *tag_preformat; + char *tag_usage; + char *tag_descrip; + char *tag_text; + char *tag_cinfo; + char *tag_pagestyle; + char *tag_section; + char *tag_subsection; + char *tag_subsubsection; + +public: + LATEX(); + void parse_args(int argc, char **argv); + void title(DocEntry *de); + void newsection(DocEntry *de, int sectnum); + void endsection(); + void print_decl(DocEntry *de); + void print_text(DocEntry *de); + void separator(); + void init(char *filename); + void close(void); + void style(char *name, char *value); +}; + + + + + + + + + + + + + + + + + + diff --git a/wxPython/wxSWIG/SWIG/main.cxx b/wxPython/wxSWIG/SWIG/main.cxx new file mode 100644 index 0000000000..28ca20a17e --- /dev/null +++ b/wxPython/wxSWIG/SWIG/main.cxx @@ -0,0 +1,643 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ +/*********************************************************************** + * $Header$ + * + * main.cxx + * + * The main program. + * + ***********************************************************************/ + +#define WRAP + +#include "internal.h" +#include "ascii.h" +#include "latex.h" +#include "html.h" +#include "nodoc.h" +#include +#include +#include +#include + +class SwigException {}; + +static char *usage = "\ +\nDocumentation Options\n\ + -dascii - ASCII documentation.\n\ + -dhtml - HTML documentation.\n\ + -dlatex - LaTeX documentation.\n\ + -dnone - No documentation.\n\n\ +General Options\n\ + -c - Produce raw wrapper code (omit support code)\n\ + -c++ - Enable C++ processing\n\ + -ci - Check a file into the SWIG library\n\ + -co - Check a file out of the SWIG library\n\ + -d docfile - Set name of the documentation file.\n\ + -Dsymbol - Define a symbol (for conditional compilation)\n\ + -I - Look for SWIG files in \n\ + -l - Include SWIG library file.\n\ + -make_default - Create default constructors/destructors\n\ + -nocomment - Ignore all comments (for documentation).\n\ + -o outfile - Set name of the output file.\n\ + -objc - Enable Objective C processing\n\ + -stat - Print statistics\n\ + -strict n - Set pointer type-checking strictness\n\ + -swiglib - Report location of SWIG library and exit\n\ + -t typemap_file - Use a typemap file.\n\ + -v - Run in verbose mode\n\ + -version - Print SWIG version number\n\ + -help - This output.\n\n"; + +//----------------------------------------------------------------- +// main() +// +// Main program. Initializes the files and starts the parser. +//----------------------------------------------------------------- + +char infilename[256]; +char filename[256]; +char fn_header[256]; +char fn_wrapper[256]; +char fn_init[256]; +char output_dir[512]; + +#ifdef MACSWIG +FILE *swig_log; +#endif + +char *SwigLib; + +//char** __argv; +//int __argc; + +int SWIG_main(int argc, char *argv[], Language *l, Documentation *d) { + + int i; + char *c; + extern FILE *LEX_in; + extern void add_directory(char *); + extern char *get_time(); + char temp[512]; + char infile[512]; + + char *outfile_name = 0; + extern int add_iname(char *); + int help = 0; + int ignorecomments = 0; + int checkout = 0; + int checkin = 0; + char *typemap_file = 0; + char *includefiles[256]; + int includecount = 0; + extern void check_suffix(char *); + extern void scanner_file(FILE *); + +#ifdef MACSWIG + try { +#endif + + f_wrappers = 0; + f_init = 0; + f_header = 0; + + //__argc = argc; + //__argv = argv; + lang = l; + doc = d; + Status = 0; + TypeStrict = 2; // Very strict type checking + Verbose = 0; + char *doc_file = 0; + + DataType::init_typedef(); // Initialize the type handler + + // Set up some default symbols (available in both SWIG interface files + // and C files) + + add_symbol("SWIG",0,0); // Define the SWIG symbol +#ifdef MACSWIG + add_symbol("SWIGMAC",0,0); +#endif +#ifdef SWIGWIN32 + add_symbol("SWIGWIN32",0,0); +#endif + + strcpy(LibDir, getSwigLib()); + SwigLib = copy_string(LibDir); // Make a copy of the real library location +#ifdef MACSWIG + sprintf(temp,"%s:config", LibDir); + add_directory(temp); + add_directory(":swig_lib:config"); + add_directory(LibDir); + add_directory(":swig_lib"); +#else + sprintf(temp,"%s/config", LibDir); + add_directory(temp); + add_directory("./swig_lib/config"); + add_directory(LibDir); + add_directory("./swig_lib"); + sprintf(InitName,"init_wrap"); +#endif + + sprintf(InitName,"init_wrap"); + + // Get options + for (i = 1; i < argc; i++) { + if (argv[i]) { + if (strncmp(argv[i],"-I",2) == 0) { + // Add a new directory search path + includefiles[includecount++] = copy_string(argv[i]+2); + mark_arg(i); + } else if (strncmp(argv[i],"-D",2) == 0) { + // Create a symbol + add_symbol(argv[i]+2, (DataType *) 0, (char *) 0); + mark_arg(i); + } else if (strcmp(argv[i],"-strict") == 0) { + if (argv[i+1]) { + TypeStrict = atoi(argv[i+1]); + mark_arg(i); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if ((strcmp(argv[i],"-verbose") == 0) || (strcmp(argv[i],"-v") == 0)) { + Verbose = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-dascii") == 0) { + doc = new ASCII; + mark_arg(i); + } else if (strcmp(argv[i],"-dnone") == 0) { + doc = new NODOC; + mark_arg(i); + } else if (strcmp(argv[i],"-dhtml") == 0) { + doc = new HTML; + mark_arg(i); + } else if (strcmp(argv[i],"-dlatex") == 0) { + doc = new LATEX; + mark_arg(i); + } else if (strcmp(argv[i],"-nocomment") == 0) { + ignorecomments = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-stat") == 0) { + Stats=1; + mark_arg(i); + } else if (strcmp(argv[i],"-c++") == 0) { + CPlusPlus=1; + mark_arg(i); + } else if (strcmp(argv[i],"-objc") == 0) { + ObjC = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-c") == 0) { + NoInclude=1; + mark_arg(i); + } else if (strcmp(argv[i],"-make_default") == 0) { + GenerateDefault = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-swiglib") == 0) { + printf("%s\n", LibDir); + SWIG_exit(0); + } else if (strcmp(argv[i],"-o") == 0) { + mark_arg(i); + if (argv[i+1]) { + outfile_name = copy_string(argv[i+1]); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-d") == 0) { + mark_arg(i); + if (argv[i+1]) { + doc_file = copy_string(argv[i+1]); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-t") == 0) { + mark_arg(i); + if (argv[i+1]) { + typemap_file = copy_string(argv[i+1]); + mark_arg(i+1); + i++; + } else { + arg_error(); + } + } else if (strcmp(argv[i],"-version") == 0) { + fprintf(stderr,"\nSWIG Version %d.%d %s\n", SWIG_MAJOR_VERSION, + SWIG_MINOR_VERSION, SWIG_SPIN); + fprintf(stderr,"Copyright (c) 1995-98\n"); + fprintf(stderr,"University of Utah and the Regents of the University of California\n"); + fprintf(stderr,"\nCompiled with %s\n", SWIG_CC); + SWIG_exit(0); + } else if (strncmp(argv[i],"-l",2) == 0) { + // Add a new directory search path + library_add(argv[i]+2); + mark_arg(i); + } else if (strcmp(argv[i],"-co") == 0) { + checkout = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-ci") == 0) { + checkin = 1; + mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + mark_arg(i); + help = 1; + } + } + } + + while (includecount > 0) { + add_directory(includefiles[--includecount]); + } + + // Create a new documentation handler + + if (doc == 0) doc = new ASCII; + + // Open up a comment handler + + comment_handler = new CommentHandler(); + comment_handler->parse_args(argc,argv); + if (ignorecomments) comment_handler->style("ignore",0); + + // Create a new documentation entry + + doctitle = new DocTitle("",0); + doctitle->parse_args(argc,argv); + doc_entry = doctitle; + + // Handle documentation module options + + doc->parse_args(argc,argv); + + // Parse language dependent options + + lang->parse_args(argc,argv); + + if (help) SWIG_exit(0); // Exit if we're in help mode + + // Check all of the options to make sure we're cool. + + check_options(); + + // If we made it this far, looks good. go for it.... + + // Create names of temporary files that are created + + sprintf(infilename,"%s", argv[argc-1]); + input_file = new char[strlen(infilename)+1]; + strcpy(input_file, infilename); + + // If the user has requested to check out a file, handle that + + if (checkout) { + int stat; + char *outfile = input_file; + if (outfile_name) + outfile = outfile_name; + stat = checkout_file(input_file,outfile); + if (!stat) { + fprintf(stderr,"%s checked out from the SWIG library\n",input_file); + } else { + FILE * f = fopen(input_file,"r"); + if (f) { + fprintf(stderr,"Unable to check-out %s. File already exists.\n", input_file); + fclose(f); + } else { + fprintf(stderr,"Unable to check-out %s\n", input_file); + } + } + } else if (checkin) { + // Try to check-in a file to the SWIG library + int stat; + char *outname = input_file; + if (outfile_name) + outname = outfile_name; + stat = checkin_file(SwigLib, LibDir, input_file, outname); + if (!stat) { + fprintf(stderr,"%s checked-in to %s/%s/%s\n", input_file, SwigLib, LibDir, outname); + } else { + fprintf(stderr,"Unable to check-in %s to %s/%s\n", input_file, SwigLib, LibDir); + } + } else { + doctitle->file = copy_string(input_file); + doctitle->line_number = -1000; + doctitle->end_line = -1000; + + // Check the suffix for a .c file. If so, we're going to + // declare everything we see as "extern" + + check_suffix(infilename); + + // Strip off suffix + + c = infilename + strlen(infilename); + while (c != infilename) { + if (*c == '.') { + *c = 0; + break; + } else { + c--; + } + } + + if (!outfile_name) { + sprintf(fn_header,"%s_wrap.c",infilename); + strcpy(infile,infilename); + strcpy(output_dir,""); + } else { + sprintf(fn_header,"%s",outfile_name); + // Try to identify the output directory + char *cc = outfile_name; + char *lastc = outfile_name; + while (*cc) { +#ifdef MACSWIG + if (*cc == ':') lastc = cc+1; +#else + if (*cc == '/') lastc = cc+1; +#endif + cc++; + } + cc = outfile_name; + char *dd = output_dir; + while (cc != lastc) { + *dd = *cc; + dd++; + cc++; + } + *dd = 0; + // Patch up the input filename + cc = infilename + strlen(infilename); + while (cc != infilename) { +#ifdef MACSWIG + if (*cc == ':') { + cc++; + break; + } +#else + if (*cc == '/') { + cc++; + break; + } +#endif + cc--; + } + strcpy(infile,cc); + } + + sprintf(fn_wrapper,"%s%s_wrap.wrap",output_dir,infile); + sprintf(fn_init,"%s%s_wrap.init",output_dir,infile); + + sprintf(title,"%s", fn_header); + + // Open up files + + if ((f_input = fopen(input_file,"r")) == 0) { + // Okay. File wasn't found right away. Let's see if we can + // extract it from the SWIG library instead. + if ((checkout_file(input_file,input_file)) == -1) { + fprintf(stderr,"Unable to open %s\n", input_file); + SWIG_exit(0); + } else { + // Successfully checked out a file from the library, print a warning and + // continue + checkout = 1; + fprintf(stderr,"%s checked out from the SWIG library.\n",input_file); + if ((f_input = fopen(input_file,"r")) == 0) { + fprintf(stderr,"Unable to open %s\n", input_file); + SWIG_exit(0); + } + } + } + + // Add to the include list + + add_iname(infilename); + + // Initialize the scanner + + LEX_in = f_input; + scanner_file(LEX_in); + +// printf("fn_header = %s\n", fn_header); +// printf("fn_wrapper = %s\n", fn_wrapper); +// printf("fn_init = %s\n", fn_init); + + if((f_header = fopen(fn_header,"w")) == 0) { + fprintf(stderr,"Unable to open %s\n", fn_header); + exit(0); + } + if((f_wrappers = fopen(fn_wrapper,"w")) == 0) { + fprintf(stderr,"Unable to open %s\n",fn_wrapper); + exit(0); + } + if ((f_init = fopen(fn_init,"w")) == 0) { + fprintf(stderr,"Unable to open %s\n",fn_init); + exit(0); + } + + // Open up documentation + + if (doc_file) { + doc->init(doc_file); + } else { + doc_file = new char[strlen(infile)+strlen(output_dir)+8]; + sprintf(doc_file,"%s%s_wrap",output_dir,infile); + doc->init(doc_file); + } + + // Set up the typemap for handling new return strings + { + DataType *temp_t = new DataType(T_CHAR); + temp_t->is_pointer++; + if (CPlusPlus) + typemap_register("newfree",typemap_lang,temp_t,"","delete [] $source;\n",0); + else + typemap_register("newfree",typemap_lang,temp_t,"","free($source);\n",0); + + delete temp_t; + } + + // Define the __cplusplus symbol + if (CPlusPlus) + add_symbol("__cplusplus",0,0); + + + // Load up the typemap file if given + + if (typemap_file) { + if (include_file(typemap_file) == -1) { + fprintf(stderr,"Unable to locate typemap file %s. Aborting.\n", typemap_file); + SWIG_exit(1); + } + } + + // If in Objective-C mode. Load in a configuration file + + if (ObjC) { + // Add the 'id' object type as a void * + /* DataType *t = new DataType(T_VOID); + t->is_pointer = 1; + t->implicit_ptr = 0; + t->typedef_add("id"); + delete t; + */ + } + + // Pass control over to the specific language interpreter + + lang->parse(); + + fclose(f_wrappers); + fclose(f_init); + + swig_append(fn_wrapper,f_header); + swig_append(fn_init,f_header); + + fclose(f_header); + + // Print out documentation. Due to tree-like nature of documentation, + // printing out the title prints out everything. + + while(doctitle) { + doctitle->output(doc); + doctitle = doctitle->next; + } + + doc->close(); + + // Remove temporary files + + remove(fn_wrapper); + remove(fn_init); + + // If only producing documentation, remove the wrapper file as well + + if (DocOnly) + remove(fn_header); + + // Check for undefined types that were used. + + if (Verbose) + type_undefined_check(); + + if (Stats) { + fprintf(stderr,"Wrapped %d functions\n", Stat_func); + fprintf(stderr,"Wrapped %d variables\n", Stat_var); + fprintf(stderr,"Wrapped %d constants\n", Stat_const); + type_undefined_check(); + } + + if (checkout) { + // File was checked out from the SWIG library. Remove it now + remove(input_file); + } + } +#ifdef MACSWIG + fclose(swig_log); + } catch (SwigException) { + fclose(swig_log); + } +#else + exit(error_count); +#endif + return(error_count); +} + +// -------------------------------------------------------------------------- +// SWIG_exit() +// +// Fatal parser error. Exit and cleanup +// -------------------------------------------------------------------------- + +void SWIG_exit(int) { + + if (f_wrappers) { + fclose(f_wrappers); + remove(fn_wrapper); + } + if (f_header) { + fclose(f_header); + remove(fn_header); + } + if (f_init) { + fclose(f_init); + remove(fn_init); + } +#ifndef MACSWIG + exit(1); +#else + throw SwigException(); +#endif +} + + +// -------------------------------------------------------------------------- +// swig_pragma(char *name, char *value) +// +// Handle pragma directives. Not many supported right now +// -------------------------------------------------------------------------- + +void swig_pragma(char *name, char *value) { + + if (strcmp(name,"make_default") == 0) { + GenerateDefault = 1; + } + if (strcmp(name,"no_default") == 0) { + GenerateDefault = 0; + } + if (strcmp(name,"objc_new") == 0) { + objc_construct = copy_string(value); + } + if (strcmp(name,"objc_delete") == 0) { + objc_destruct = copy_string(value); + } +} + + + +char* getSwigLib() { + char* c; + char* rv; + + // Check for SWIG_LIB environment variable + if ((c = getenv("SWIG_LIB")) != (char *) 0) { + rv = c; + } else { +#ifdef SWIG_LIB + rv = SWIG_LIB; +#else + // use executable location + static char path[256]; + char* last; + strcpy(path, __argv[0]); + last = strrchr(path, '/'); + if (! last) last = strrchr(path, '\\'); + if (last) + strcpy(last+1, "swig_lib"); + else + strcpy(path, "swig_lib"); + rv = path; +#endif + } + printf("Using swig lib at: %s\n", rv); + return rv; +} + diff --git a/wxPython/wxSWIG/SWIG/makefile.vc b/wxPython/wxSWIG/SWIG/makefile.vc new file mode 100644 index 0000000000..4f1dc55e59 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/makefile.vc @@ -0,0 +1,107 @@ +# Modified from automatic creation by Kevin Butler (butler@byu.edu) +# for Microsoft Visual C++ (11/22/96) +# +####################################################################### +# $Header$ +# Simplified Wrapper and Interface Generator (SWIG) +# +# Makefile for version 1.1 +# Dave Beazley +# March 12, 1997 +# +# This makefile is now mostly constructed by ./configure. +# +# $Log$ +# Revision 1.1 2002/04/29 19:56:48 RD +# Since I have made several changes to SWIG over the years to accomodate +# special cases and other things in wxPython, and since I plan on making +# several more, I've decided to put the SWIG sources in wxPython's CVS +# instead of relying on maintaining patches. This effectivly becomes a +# fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still +# doesn't have some things I rely on in 1.1, not to mention that my +# custom patches would all have to be redone, I felt that this is the +# easier road to take. +# +# Revision 1.1.1.1 1999/02/28 02:00:52 beazley +# Swig1.1 +# +# Revision 1.1 1996/08/12 01:55:02 dmb +# Initial revision +# +####################################################################### + +#.KEEP_STATE: + +rootdir = .. +!include <..\make_win.in> + + +######################################################################## +# Normally, you shouldn't have to change anything below this point # +######################################################################## + +LIBOBJS = main.obj scanner.obj symbol.obj include.obj types.obj parms.obj emit.obj newdoc.obj ascii.obj \ + html.obj latex.obj cplus.obj lang.obj hash.obj sstring.obj wrapfunc.obj getopt.obj comment.obj typemap.obj naming.obj + +LIBSRCS = main.cxx scanner.cxx symbol.cxx include.cxx types.cxx parms.cxx emit.cxx \ + newdoc.cxx ascii.cxx html.cxx latex.cxx cplus.cxx lang.cxx hash.cxx \ + sstring.cxx wrapfunc.cxx getopt.cxx comment.cxx typemap.cxx naming.cxx + +LIBHEADERS = internal.h $(rootdir)/Include/swig.h latex.h ascii.h html.h nodoc.h +LIBNAME = $(rootdir)\libswig.lib + + +# +# Rules for creation of a .obj file from .cxx +.SUFFIXES: .cxx +.cxx.obj: + $(CC) $(INCFLAGS) $(CFLAGS) -c -o $*.obj $< + +all: $(LIBNAME) + +$(LIBNAME): parser.obj $(LIBOBJS) + @echo "Building library" + @$(LD) $(LD_FLAGS) -out:$(LIBNAME) $(LIBOBJS) parser.obj + +parser.obj: parser.cxx $(LIBHEADERS) + $(CC) $(INCFLAGS) $(CFLAGS) parser.cxx -c -o parser.obj + +parser.cxx: $(PARSER) + @echo "Must rebuild the parser with yacc" + +parser:: + @cp y.tab.c.bison parser.cxx + @cp y.tab.h.bison parser.h + @cp y.tab.h.bison y.tab.h + $(CC) $(CFLAGS) parser.cxx -c -o parser.obj + +main.obj: main.cxx +scanner.obj: scanner.cxx +wrapper.obj: wrapper.cxx +include.obj: include.cxx +types.obj: types.cxx +emit.obj: emit.cxx +cplus.obj: cplus.cxx +misc.obj: misc.cxx +hash.obj: hash.cxx +sstring.obj: sstring.cxx +getopt.obj: getopt.cxx +wrapfunc.obj: wrapfunc.cxx +swigmain.obj: swigmain.cxx +symbol.obj: symbol.cxx +parms.obj: parms.cxx +newdoc.obj: newdoc.cxx +lang.obj: lang.cxx +comment.obj: comment.cxx +latex.obj: latex.cxx +ascii.obj: ascii.cxx +html.obj: html.cxx +typemap.obj: typemap.cxx +naming.obj: naming.cxx + +clean:: + @del *.obj + @del $(LIBNAME) + + + diff --git a/wxPython/wxSWIG/SWIG/naming.cxx b/wxPython/wxSWIG/SWIG/naming.cxx new file mode 100644 index 0000000000..9fdda94aaf --- /dev/null +++ b/wxPython/wxSWIG/SWIG/naming.cxx @@ -0,0 +1,299 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" +#include +#include + +// -------------------------------------------------------------------------------- +// $Header$ +// +// naming.cxx +// +// SWIG naming service. +// +// This module provides universal naming services for manufacturing function names. +// All language modules use this so it provides a convenient centralized +// mechanism for producing names. +// -------------------------------------------------------------------------------- + +// Structure for holding names + +struct NamingScheme { + char *format; + int first; // Scoping information + int last; // Scoping information + NamingScheme *next; + NamingScheme(char *n) { + format = copy_string(n); + first = type_id; + last = INT_MAX; + next = 0; + }; +}; + +// Hash table containing naming data + +static Hash naming_hash; + +// Variable indicating naming scope + +static int naming_scope = -1; + +//----------------------------------------------------------------- +// make_wrap_name(char *s) +// +// Takes the name at src, and converts it into a syntactically +// valid identifier name. This is a hack to get the wrapper +// generator to support class member functions and other things. +// +// ie. We can define a function name as obj->foo(), +// but we'll need to call the wrapper function something like +// _wrap_obj__foo() +//----------------------------------------------------------------- + +void make_wrap_name(char *s) { + + char *c1 = s; + int i; + + for (i = 0; i < (int) strlen(s); i++, c1++) { + if(!isalnum(*c1)) *c1 = '_'; + } +} + +// -------------------------------------------------------------------------------- +// int name_scope(int scope) +// +// Set the scope variable. This is used to determine what naming scheme to +// use. Returns the current value of the scope. +// -------------------------------------------------------------------------------- + +int name_scope(int scope) { + int s = naming_scope; + naming_scope = scope; + return s; +} + +// -------------------------------------------------------------------------------- +// void name_register(char *method, char *format) +// +// Registers a new naming scheme. +// -------------------------------------------------------------------------------- + +void name_register(char *method, char *format) { + NamingScheme *ns, *nns; + + ns = (NamingScheme *) naming_hash.lookup(method); + if (ns) { + naming_hash.remove(method); + } + + nns = new NamingScheme(format); // Create a new naming scheme + if (ns) ns->last = type_id; + nns->next = ns; + + naming_hash.add(method,nns); +}; + +// -------------------------------------------------------------------------------- +// char *name_getformat(char *method) +// +// Looks up a naming scheme in the hash table. The scope of the name should have +// been set prior to calling this. If not set, we just use the last name entered. +// Returns the format string or NULL if no name has been set. +// -------------------------------------------------------------------------------- + +static char *name_getformat(char *method) { + + NamingScheme *ns; + int scope; + if (naming_scope == -1) scope = type_id; + else scope = naming_scope; + + ns = (NamingScheme *) naming_hash.lookup(method); + while (ns) { + if ((ns->first <= scope) && (scope < ns->last)) + return ns->format; + ns = ns->next; + } + return 0; +} + +// -------------------------------------------------------------------------------- +// char *name_wrapper(char *fname, char *prefix, int suppress) +// +// Returns the name of a wrapper function. The following variables are +// available : +// +// %f -> fname +// %p -> prefix +// %l -> language +// +// By default a wrapper function gets the name _wrap_prefixfname. +// +// -------------------------------------------------------------------------------- + +char *name_wrapper(char *fname, char *prefix, int suppress) { + static String fmt; + char *f; + + f = name_getformat("wrapper"); + if (!f) { + f = "_wrap_%p%f"; // Default wrapper name + } + fmt = f; + fmt.replace("%f",fname); + fmt.replace("%l",typemap_lang); + fmt.replace("%p",prefix); + if (!suppress) + make_wrap_name(fmt); + return fmt; +} + + +// -------------------------------------------------------------------------------- +// char *name_member(char *fname, char *classname, int suppress) +// +// Returns the name of a method function. The following variables are +// available : +// +// %f -> fname +// %c -> classname +// %l -> language +// +// By default, the name of a method is given as Classname_method. +// -------------------------------------------------------------------------------- + +char *name_member(char *fname, char *classname, int suppress) { + static String fmt; + char *f; + + f = name_getformat("member"); + if (!f) { + f = "%c_%f"; + } + fmt = f; + fmt.replace("%f",fname); + fmt.replace("%l",typemap_lang); + fmt.replace("%c",classname); + if (!suppress) + make_wrap_name(fmt); + return fmt; +} + + +// -------------------------------------------------------------------------------- +// char *name_get(char *vname, int suppress) +// +// Returns the name of the accessor function used to get a variable. +// +// %v -> variable name +// +// -------------------------------------------------------------------------------- + +char *name_get(char *vname, int suppress) { + static String fmt; + char *f; + + f = name_getformat("get"); + if (!f) { + f = "%v_get"; + } + fmt = f; + fmt.replace("%v",vname); + if (!suppress) + make_wrap_name(fmt); + return fmt; +} + +// -------------------------------------------------------------------------------- +// char *name_set(char *vname, int suppress) +// +// Returns the name of the accessor function used to set a variable. +// +// %v -> variable name +// -------------------------------------------------------------------------------- + +char *name_set(char *vname, int suppress) { + static String fmt; + char *f; + + f = name_getformat("set"); + if (!f) { + f = "%v_set"; + } + fmt = f; + fmt.replace("%v",vname); + if (!suppress) + make_wrap_name(fmt); + return fmt; +} + + +// -------------------------------------------------------------------------------- +// char *name_construct(char *classname, int suppress) +// +// Returns the name of the accessor function used to create an object. +// By default this is "new_classname" +// +// %c -> classname +// %l -> language +// +// -------------------------------------------------------------------------------- + +char *name_construct(char *classname, int suppress) { + static String fmt; + char *f; + + f = name_getformat("construct"); + if (!f) { + f = "new_%c"; + } + fmt = f; + fmt.replace("%l",typemap_lang); + fmt.replace("%c",classname); + if (!suppress) + make_wrap_name(fmt); + return fmt; +} + + +// -------------------------------------------------------------------------------- +// char *name_destroy(char *classname, int suppress) +// +// Returns the name of the accessor function used to destroy an object. +// By default this is "delete_classname" +// +// %c -> classname +// %l -> language +// +// -------------------------------------------------------------------------------- + +char *name_destroy(char *classname, int suppress) { + static String fmt; + char *f; + + f = name_getformat("destroy"); + if (!f) { + f = "delete_%c"; + } + fmt = f; + fmt.replace("%l",typemap_lang); + fmt.replace("%c",classname); + if (!suppress) + make_wrap_name(fmt); + return fmt; +} diff --git a/wxPython/wxSWIG/SWIG/newdoc.cxx b/wxPython/wxSWIG/SWIG/newdoc.cxx new file mode 100644 index 0000000000..bc4347f985 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/newdoc.cxx @@ -0,0 +1,607 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ +/*********************************************************************** + * $Header$ + * + * newdoc.cxx + * + * SWIG Documentation system. (2nd attempt) + * + * SWIG organizes documentation as a tree structure where each node is a + * documentation entry (DocEntry) of some kind. To generate documentation, + * we simply traverse the tree and call output methods. + * + * A sample documentation tree looks something like the following : + * + * TITLE ----> SECTION 1 ----> func1 + * ----> func2 + * ----> func3 + * ----> class ---> func1 + * ---> func2 + * ---> var1 + * ----> func4 + * + * ----> SECTION 2 ----> func1 + * ----> var1 + * + * and so on. + * + * This structure makes it possible to organize C++ classes and more + * complicated structures. Hopefully this will provide enough structure + * for later versions of SWIG. + * + *************************************************************************/ + +#include "internal.h" +#include + +extern char *get_time(); +static char *last_name = 0; + +DocEntry *DocEntry::dead_entries = 0; + +// Utility function for converting a string to upper case + +static void str_toupper(char *str) { + char *c; + c = str; + while (*c) { + *c = toupper(*c); + c++; + } +} + +// -------------------------------------------------------------------- +// DocEntry::~DocEntry +// +// Destroy a documentation entry. Destroys this entry and all of +// its children. +// -------------------------------------------------------------------- + +DocEntry::~DocEntry() { + DocEntry *de, *de1; + + if (name) delete name; + + // Now kill all of the children (well, figuratively speaking) + + de = child; + while (de) { + de1 = de->next; + delete de; + de = de1; + } +} + +// -------------------------------------------------------------------- +// void DocEntry::sort_children() +// +// Sort children by name (not height). This function gathers all +// of the children up into an array of pointers. Then we do an +// insertion sort on it and place the children back in order. +// -------------------------------------------------------------------- + +void DocEntry::sort_children() { + + int count = 0; + int i,j; + DocEntry *d; + DocEntry **list; + DocEntry *v; + + if (!child) return; // Nothing to sort + + d = child; + while (d) { + count++; + d = d->next; + } + + // allocate a temporary array for sorting everything + + list = new DocEntry *[count+2]; + + // Now put pointers into list + + d = child; + i = 0; + while (d) { + list[i] = d; + d = d->next; + i++; + } + + // Do an insertion sort by name + + for (i = 1; i < count; i++) { + v = list[i]; + j = i; + while((j > 0) && (strcmp(list[j-1]->name,v->name) > 0)) { + list[j] = list[j-1]; + j--; + } + list[j] = v; + } + + // Now, we're going to reorganize the children in order + + list[count] = 0; + child = list[0]; // Our child is the first one in the list + d = child; + for (i = 0; i < count; i++) { + d->next = list[i+1]; + d = d->next; + } + delete list; +} + +// -------------------------------------------------------------------- +// void DocEntry::output() +// +// Output this entry +// -------------------------------------------------------------------- + +void DocEntry::output(Documentation *) { + fprintf(stderr,"SWIG (internal) : No output method defined for DocEntry.\n"); +} + +// -------------------------------------------------------------------- +// DocEntry::add(DocEntry *de) +// +// Adds a new DocEntry as a sibling. Basically we just walk down the +// linked list and append ourselves to the end. The documentation +// Entry we're adding may, in fact, have siblings too, but this function +// Should still work. +// -------------------------------------------------------------------- + +void DocEntry::add(DocEntry *de) { + DocEntry *d,*d1; + d = next; + d1 = this; + while (d) { + d1 = d; + d = d->next; + } + d1->next = de; + de->previous = d1; // Set up the previous list member +} + + +// -------------------------------------------------------------------- +// DocEntry::addchild(DocEntry *de) +// +// Adds a new DocEntry as a child. If we're in Ignore mode, the +// documentation entry is still created, but we simply abandon it. +// -------------------------------------------------------------------- + +void DocEntry::addchild(DocEntry *de) { + if (!IgnoreDoc) { + if (child) child->add(de); + else child = de; + } else { + if (dead_entries) dead_entries->add(de); + else dead_entries = de; + } +} + +// ------------------------------------------------------------------- +// DocEntry::remove() +// +// Removes a documentation entry from the tree and places it on +// the dead_entries list +// ------------------------------------------------------------------- + +void DocEntry::remove() { + + if (previous) { + if (next) + previous->next = next; // Take out of the linked list + else + previous->next = 0; + } else { // Make sure our parent isn't pointing to us + if (parent) + parent->child = next; + } + + previous = 0; + next = 0; + + if (!dead_entries) dead_entries = this; + else dead_entries->add(this); + +} + +// ------------------------------------------------------------------- +// void DocEntry::style(char *name, char *value) +// +// Set style parameters of a documentation entry +// ------------------------------------------------------------------- + +void DocEntry::style(char *pname, char *) { + if (strcmp(pname,"sort") == 0) { + sorted = 1; + } else if (strcmp(pname,"nosort") == 0) { + sorted = 0; + } else if (strcmp(pname,"info") == 0) { + print_info = 1; + } else if (strcmp(pname,"noinfo") == 0) { + print_info = 0; + } else if (strcmp(pname,"pre") == 0) { + format = 0; + } else if (strcmp(pname,"format") == 0) { + format = 1; + } +} + +// ------------------------------------------------------------------- +// void DocEntry::parse_args(int argc, char **argv) +// +// Take command line options and process them. This really only +// applies to the top-level documentation entry. +// ------------------------------------------------------------------- + +static char *doc_usage = "\ +Documentation Processing : \n\ + -Sformat - Reformat comment text\n\ + -Sinfo - Print C formatting information (the default)\n\ + -Snoinfo - Omit C formatting information.\n\ + -Snosort - Print everything in order (the default)\n\ + -Spre - Assume comments are pre-formatted (the default)\n\ + -Ssort - Sort documentation alphabetically\n\n"; + +void DocEntry::parse_args(int argc, char **argv) { + int i; + for (i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i],"-Ssort") == 0) { + this->style("sort",0); + mark_arg(i); + } else if (strcmp(argv[i],"-Snosort") == 0) { + this->style("nosort",0); + mark_arg(i); + } else if (strcmp(argv[i],"-Sinfo") == 0) { + this->style("info",0); + mark_arg(i); + } else if (strcmp(argv[i],"-Snoinfo") == 0) { + this->style("noinfo",0); + mark_arg(i); + } else if (strcmp(argv[i],"-Spre") == 0) { + this->style("pre",0); + mark_arg(i); + } else if (strcmp(argv[i],"-Sformat") == 0) { + this->style("format",0); + mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(doc_usage,stderr); + } + } + } +} + + +// ------------------------------------------------------------------- +// DocTitle::DocTitle(char *title, DocEntry *_parent); +// +// Create a new title documentation entry. The name of the entry +// is the title. +// +// The body text is optional, but may be filled in with a description +// as well. +// ------------------------------------------------------------------- + +DocTitle::DocTitle(char *title, DocEntry *_parent) { + name = copy_string(title); + str_toupper(name); + parent = _parent; + child = 0; + next = 0; + previous = 0; + usage << title << "\n"; + counter = 1; + is_separator = 1; + line_number = ::start_line; + end_line = ::line_number; + file = copy_string(input_file); + if (_parent) { + sorted = _parent->sorted; + format = _parent->format; + print_info = _parent->print_info; + } else { + sorted = SWIGDEFAULT_SORT; + format = SWIGDEFAULT_FORMAT; + print_info = SWIGDEFAULT_INFO; + } + comment_handler->set_entry(this); + if (last_name) delete last_name; + last_name = 0; +} +// -------------------------------------------------------------------- +// DocTitle::output(Documentation *d) +// +// Output a title to the Documentation module +// -------------------------------------------------------------------- + +void DocTitle::output(Documentation *d) { + DocEntry *de; + + d->title(this); + if (sorted) { + sort_children(); + } + + // Now output my children + + de = child; + while (de) { + de->output(d); + de = de->next; + } +} + +// ------------------------------------------------------------------- +// DocSection::DocSection(char *section, DocEntry *_parent); +// +// Create a new documentation section. The name and description is +// set to the name of the section. The text field is optional +// but could contain a more complete description. +// +// The sorted field indicates whether members of this section are +// sorted or not. +// ------------------------------------------------------------------- + +DocSection::DocSection(char *section, DocEntry *_parent) { + name = copy_string(section); + str_toupper(name); + parent = _parent; + child = 0; + next = 0; + previous = 0; + usage << section; + counter = 1; + is_separator = 1; + if (_parent) _parent->addchild(this); + line_number = ::start_line; + end_line = ::line_number; + file = copy_string(input_file); + if (_parent) { + sorted = _parent->sorted; + format = _parent->format; + print_info = _parent->print_info; + } else { + sorted = SWIGDEFAULT_SORT; + format = SWIGDEFAULT_FORMAT; + print_info = SWIGDEFAULT_INFO; + } + comment_handler->set_entry(this); + if (last_name) delete last_name; + last_name = 0; +} + +// -------------------------------------------------------------------- +// DocSection::output(Documentation *d) +// +// Output a section to the documentation module +// -------------------------------------------------------------------- + +void DocSection::output(Documentation *d) { + DocEntry *de; + + // Make a new section + + d->newsection(this,this->parent->counter++); // Make a new section + + // Sort the children if necessary + + if (sorted) { + sort_children(); + } + + // Now output my children + + de = child; + while (de) { + de->output(d); + de = de->next; + } + + // End this section + + d->endsection(); + +} + + +// ------------------------------------------------------------------- +// DocDecl::DocDecl(char *fname, DocEntry *_parent); +// +// Create documentation for a function declaration. +// ------------------------------------------------------------------- + +DocDecl::DocDecl(char *fname, DocEntry *_parent) { + name = copy_string(fname); + str_toupper(name); + parent = _parent; + child = 0; + next = 0; + previous = 0; + is_separator = 0; + if (_parent) _parent->addchild(this); + line_number = ::start_line; + end_line = ::line_number; + file = copy_string(input_file); + if (_parent) { + sorted = _parent->sorted; + format = _parent->format; + print_info = _parent->print_info; + } else { + sorted = SWIGDEFAULT_SORT; + format = SWIGDEFAULT_FORMAT; + print_info = SWIGDEFAULT_INFO; + } + comment_handler->set_entry(this); + if (last_name) delete last_name; + last_name = copy_string(name); +} + + +// -------------------------------------------------------------------- +// DocDecl::DocDecl(DocEntry *de, DocEntry *_parent) +// +// Make a new declaration entry, but copy attributes from someone else +// -------------------------------------------------------------------- + +DocDecl::DocDecl(DocEntry *de, DocEntry *_parent) { + name = copy_string(de->name); + usage = de->usage.get(); + cinfo = de->cinfo.get(); + text = de->text.get(); + line_number = de->line_number; + end_line = de->end_line; + file = copy_string(de->file); + print_info = de->print_info; + format = de->format; + if (_parent) { + _parent->addchild(this); + } +} + +// -------------------------------------------------------------------- +// DocDecl::output(Documentation *d) +// +// Output a function to the documentation module +// -------------------------------------------------------------------- + +void DocDecl::output(Documentation *d) { + d->print_decl(this); +} + +// ------------------------------------------------------------------- +// DocClass::DocClass(char *classname, DocEntry *_parent); +// +// Create a new class section. Classes are created as funny sorts of +// sections. +// +// The sorted field indicates whether members of this section are +// sorted or not. +// ------------------------------------------------------------------- + +DocClass::DocClass(char *classname, DocEntry *_parent) { + name = copy_string(classname); + str_toupper(name); + parent = _parent; + child = 0; + next = 0; + previous = 0; + usage << classname<< "\n"; + counter = 1; + is_separator = 1; + if (_parent) _parent->addchild(this); + line_number = ::start_line; + end_line = ::line_number; + file = copy_string(input_file); + if (_parent) { + sorted = _parent->sorted; + format = _parent->format; + print_info = _parent->print_info; + } else { + sorted = SWIGDEFAULT_SORT; + format = SWIGDEFAULT_FORMAT; + print_info = SWIGDEFAULT_INFO; + } + comment_handler->set_entry(this); + if (last_name) delete last_name; + last_name = copy_string(name); + +} + +// -------------------------------------------------------------------- +// DocClass::output(Documentation *d) +// +// Output a section to the documentation module +// -------------------------------------------------------------------- + +void DocClass::output(Documentation *d) { + DocEntry *de; + + // Make a new section + + d->newsection(this,this->parent->counter++); // Make a subsection for this + + // Sort the children if necessary + + if (sorted) { + sort_children(); + } + + // Now output my children + + de = child; + while (de) { + de->output(d); + de = de->next; + } + + // End this section + + d->endsection(); + + // We now check to see if the next thing is a separator. If not, we'll + // emit a separator + + if (next) { + if (!next->is_separator) + d->separator(); + } +} + +// ------------------------------------------------------------------- +// DocText::DocText(char *_text, DocEntry *_parent); +// +// Create documentation for a function declaration. +// ------------------------------------------------------------------- + +DocText::DocText(char *_text, DocEntry *_parent) { + if (!last_name) + name = copy_string(""); // There is no name for text + else + name = copy_string(last_name); + parent = _parent; + child = 0; + next = 0; + previous = 0; + text << _text; + is_separator = 0; + if (_parent) _parent->addchild(this); + if (_parent) { + sorted = _parent->sorted; + format = _parent->format; + print_info = _parent->print_info; + } else { + sorted = SWIGDEFAULT_SORT; + format = SWIGDEFAULT_FORMAT; + print_info = SWIGDEFAULT_INFO; + } +} + +// -------------------------------------------------------------------- +// DocText::output(Documentation *d) +// +// Output a function to the documentation module +// -------------------------------------------------------------------- + +void DocText::output(Documentation *d) { + d->print_text(this); +} + diff --git a/wxPython/wxSWIG/SWIG/nodoc.h b/wxPython/wxSWIG/SWIG/nodoc.h new file mode 100644 index 0000000000..086e5dc71f --- /dev/null +++ b/wxPython/wxSWIG/SWIG/nodoc.h @@ -0,0 +1,54 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ +/*********************************************************************** + * $Header$ + * + * nodoc.h + * + * A null documentation header. Does nothing. + ***********************************************************************/ + +class NODOC : public Documentation { +private: +public: + NODOC() { }; + void parse_args(int, char **) { }; + void title(DocEntry *) { }; + void newsection(DocEntry *, int) { }; + void endsection() { }; + void print_decl(DocEntry *) { }; + void print_text(DocEntry *) { }; + void separator() { }; + void init(char *) { }; + void close(void) { }; + void style(char *, char *) { }; +}; + + + + + + + + + + + + + + + + + diff --git a/wxPython/wxSWIG/SWIG/parms.cxx b/wxPython/wxSWIG/SWIG/parms.cxx new file mode 100644 index 0000000000..a23b831c05 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/parms.cxx @@ -0,0 +1,478 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/* ------------------------------------------------------------------------ + $Header$ + + parms.cxx + + This file is used to manage function parameters and parameter lists. + Rewritten (10/27) to solve a bunch of problems with memory management + and proper cleanup of things. + ------------------------------------------------------------------------ */ + +#include "swig.h" + +// ------------------------------------------------------------------------ +// Parm::Parm(DataType *type, char *n) +// +// Create a new parameter from datatype 'type' and name 'n'. +// Copies will be made of type and n, unless they aren't specified. +// ------------------------------------------------------------------------ + +Parm::Parm(DataType *type, char *n) { + if (type) { + t = new DataType(type); + } else { + t = 0; + } + name = copy_string(n); + call_type = 0; + defvalue = 0; + ignore = 0; + objc_separator = 0; +} + +// ------------------------------------------------------------------------ +// Parm::Parm(Parm *p) +// +// Make a copy of a parameter +// ------------------------------------------------------------------------ + +Parm::Parm(Parm *p) { + if (p->t) t = new DataType(p->t); + name = copy_string(p->name); + call_type = p->call_type; + defvalue = copy_string(p->defvalue); + ignore = p->ignore; + objc_separator = copy_string(p->objc_separator); +} + +// ------------------------------------------------------------------------ +// Parm::~Parm() +// +// Destroy a parameter +// ------------------------------------------------------------------------ + +Parm::~Parm() { + if (t) delete t; + if (name) delete name; + if (defvalue) delete defvalue; + if (objc_separator) delete objc_separator; +} + +/******************************************************************** + class ParmList + + These functions are used to manipulate lists of parameters + ********************************************************************/ + +// ------------------------------------------------------------------ +// ParmList::ParmList() +// +// Create a new (empty) parameter list +// ------------------------------------------------------------------ + +ParmList::ParmList() { + + nparms = 0; + maxparms = MAXPARMS; + parms = new Parm *[maxparms]; // Create an array of parms + for (int i = 0; i < MAXPARMS; i++) + parms[i] = (Parm *) 0; +} + +// ------------------------------------------------------------------ +// ParmList::ParmList(ParmList *l) +// +// Make a copy of parameter list +// ------------------------------------------------------------------ + +ParmList::ParmList(ParmList *l) { + int i; + + if (l) { + nparms = l->nparms; + maxparms = l->maxparms; + parms = new Parm *[maxparms]; + + for (i = 0; i < maxparms; i++) { + if (l->parms[i]) + parms[i] = new Parm(l->parms[i]); + else + parms[i] = 0; + } + + } else { + nparms = 0; + maxparms = MAXPARMS; + parms = new Parm *[maxparms]; // Create an array of parms + + for (i = 0; i < MAXPARMS; i++) + parms[i] = (Parm *) 0; + } +} + +// ------------------------------------------------------------------ +// ParmList::~ParmList() +// +// Delete a parameter list +// ------------------------------------------------------------------ + +ParmList::~ParmList() { + for (int i = 0; i < maxparms; i++) { + if (parms[i]) delete parms[i]; + } +} + + +// ------------------------------------------------------------------ +// void ParmList::moreparms() (PRIVATE) +// +// Doubles the amount of parameter memory available. +// ------------------------------------------------------------------ + +void ParmList::moreparms() { + Parm **newparms; + int i; + + newparms = new Parm *[maxparms*2]; + for (i = 0; i < 2*maxparms; i++) + newparms[i] = (Parm *) 0; + for (i = 0; i < maxparms; i++) { + newparms[i] = parms[i]; + } + maxparms = 2*maxparms; + delete parms; + parms = newparms; +} + +// ------------------------------------------------------------------ +// void ParmList::append(Parm *p) +// +// Add a new parameter to the end of a parameter list +// ------------------------------------------------------------------ + +void ParmList::append(Parm *p) { + + if (nparms == maxparms) moreparms(); + + // Add parm onto the end + + parms[nparms] = new Parm(p); + nparms++; +} + +// ------------------------------------------------------------------ +// void ParmList::insert(Parm *p, int pos) +// +// Inserts a parameter at position pos. Parameters are inserted +// *before* any existing parameter at position pos. +// ------------------------------------------------------------------ + +void ParmList::insert(Parm *p, int pos) { + + // If pos is out of range, we'd better fix it + + if (pos < 0) pos = 0; + if (pos > nparms) pos = nparms; + + // If insertion is going to need more memory, take care of that now + + if (nparms >= maxparms) moreparms(); + + // Now shift all of the existing parms to the right + + for (int i = nparms; i > pos; i--) { + parms[i] = parms[i-1]; + } + + // Set new parameter + + parms[pos] = new Parm(p); + nparms++; + +} + +// ------------------------------------------------------------------ +// void ParmList::del(int pos) +// +// Deletes the parameter at position pos. +// ------------------------------------------------------------------ + +void ParmList::del(int pos) { + + if (nparms <= 0) return; + if (pos < 0) pos = 0; + if (pos >= nparms) pos = nparms-1; + + // Delete the parameter (if it exists) + + if (parms[pos]) delete parms[pos]; + + // Now slide all of the parameters to the left + + for (int i = pos; i < nparms-1; i++) { + parms[i] = parms[i+1]; + } + nparms--; + +} + +// ------------------------------------------------------------------ +// Parm *ParmList::get(int pos) +// +// Gets the parameter at location pos. Returns 0 if invalid +// position. +// ------------------------------------------------------------------ + +Parm *ParmList::get(int pos) { + + if ((pos < 0) || (pos >= nparms)) return 0; + return parms[pos]; +} + +// ------------------------------------------------------------------ +// int ParmList::numopt() +// +// Gets the number of optional arguments. +// ------------------------------------------------------------------ +int ParmList::numopt() { + int n = 0; + int state = 0; + + for (int i = 0; i < nparms; i++) { + if (parms[i]->defvalue) { + n++; + state = 1; + } else if (typemap_check("default",typemap_lang,parms[i]->t,parms[i]->name)) { + n++; + state = 1; + } else if (typemap_check("ignore",typemap_lang,parms[i]->t,parms[i]->name)) { + n++; + } else if (typemap_check("build",typemap_lang,parms[i]->t,parms[i]->name)) { + n++; + } else { + if (state) { + fprintf(stderr,"%s : Line %d. Argument %d must have a default value!\n", input_file,line_number,i+1); + } + } + } + return n; +} + +// ------------------------------------------------------------------ +// int ParmList::numarg() +// +// Gets the number of arguments +// ------------------------------------------------------------------ +int ParmList::numarg() { + int n = 0; + + for (int i = 0; i < nparms; i++) { + if (!parms[i]->ignore) + n++; + } + return n; +} + +// ------------------------------------------------------------------ +// Parm &ParmList::operator[](int n) +// +// Returns parameter n in the parameter list. May generate +// an error if that parameter is out of range. +// ------------------------------------------------------------------ + +Parm &ParmList::operator[](int n) { + + if ((n < 0) || (n >= nparms)) { + fprintf(stderr,"ParmList : Fatal error. subscript out of range in ParmList.operator[]\n"); + SWIG_exit(1); + } + + return *parms[n]; +} + +// --------------------------------------------------------------------- +// Parm * ParmList::get_first() +// +// Returns the first item on a parameter list. +// --------------------------------------------------------------------- + +Parm *ParmList::get_first() { + current_parm = 0; + if (nparms > 0) return parms[current_parm++]; + else return (Parm *) 0; +} + +// ---------------------------------------------------------------------- +// Parm *ParmList::get_next() +// +// Returns the next item on the parameter list. +// ---------------------------------------------------------------------- + +Parm * ParmList::get_next() { + if (current_parm >= nparms) return 0; + else return parms[current_parm++]; +} + +// --------------------------------------------------------------------- +// void ParmList::print_types(FILE *f) +// +// Prints a comma separated list of all of the parameter types. +// This is for generating valid C prototypes. Has to do some +// manipulation of pointer types depending on how the call_type +// variable has been set. +// ---------------------------------------------------------------------- + +void ParmList::print_types(FILE *f) { + + int is_pointer; + int pn; + pn = 0; + while(pn < nparms) { + is_pointer = parms[pn]->t->is_pointer; + if (parms[pn]->t->is_reference) { + if (parms[pn]->t->is_pointer) { + parms[pn]->t->is_pointer--; + fprintf(f,"%s&", parms[pn]->t->print_real()); + parms[pn]->t->is_pointer++; + } else { + fprintf(f,"%s&", parms[pn]->t->print_real()); + } + } else { + if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++; + if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--; + fprintf(f,"%s", parms[pn]->t->print_real()); + parms[pn]->t->is_pointer = is_pointer; + } + pn++; + if (pn < nparms) + fprintf(f,","); + } +} + + +// --------------------------------------------------------------------- +// void ParmList::print_types(String &f) +// +// Generates a comma separated list of function types. Is used in +// C++ code generation when generating hash keys and for function overloading. +// ---------------------------------------------------------------------- + +void ParmList::print_types(String &f) { + + int is_pointer; + int pn; + pn = 0; + while(pn < nparms) { + is_pointer = parms[pn]->t->is_pointer; + if (parms[pn]->t->is_reference) { + if (parms[pn]->t->is_pointer) { + parms[pn]->t->is_pointer--; + f << parms[pn]->t->print_real() << "&"; + parms[pn]->t->is_pointer++; + } else { + f << parms[pn]->t->print_real() << "&"; + } + } else { + if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++; + if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--; + f << parms[pn]->t->print_real(); + parms[pn]->t->is_pointer = is_pointer; + } + pn++; + if (pn < nparms) + f << ","; + } +} + + +// --------------------------------------------------------------------- +// void ParmList::print_args(FILE *f) +// +// Prints a comma separated list of all of the parameter arguments. +// ---------------------------------------------------------------------- + +void ParmList::print_args(FILE *f) { + + int is_pointer; + int pn; + pn = 0; + while(pn < nparms) { + is_pointer = parms[pn]->t->is_pointer; + if (parms[pn]->t->is_reference) { + if (parms[pn]->t->is_pointer) { + parms[pn]->t->is_pointer--; + fprintf(f,"%s&", parms[pn]->t->print_full()); + parms[pn]->t->is_pointer++; + } else { + fprintf(f,"%s&", parms[pn]->t->print_full()); + } + } else { + if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++; + if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--; + fprintf(f,"%s", parms[pn]->t->print_full()); + parms[pn]->t->is_pointer = is_pointer; + } + fprintf(f,"%s",parms[pn]->name); + pn++; + if (pn < nparms) + fprintf(f,","); + } +} + +// ------------------------------------------------------------------- +// int check_defined() +// +// Checks to see if all of the datatypes are defined. +// ------------------------------------------------------------------- + +int ParmList::check_defined() { + int a = 0; + int i; + for (i = 0; i < nparms; i++) { + if (parms[i]) { + a+=parms[i]->t->check_defined(); + } + } + if (a) return 1; + else return 0; +} + + +// ------------------------------------------------------------------- +// void ParmList::sub_parmnames(String &s) +// +// Given a string, this function substitutes all of the parameter +// names with their internal representation. Used in very special +// kinds of typemaps. +// ------------------------------------------------------------------- + +void ParmList::sub_parmnames(String &s) { + Parm *p; + extern char *emit_local(int i); + for (int i = 0; i < nparms; i++) { + p = get(i); + if (strlen(p->name) > 0) { + s.replaceid(p->name, emit_local(i)); + } + } +} + + + + + diff --git a/wxPython/wxSWIG/SWIG/parser.cxx b/wxPython/wxSWIG/SWIG/parser.cxx new file mode 100644 index 0000000000..30a6d39b5a --- /dev/null +++ b/wxPython/wxSWIG/SWIG/parser.cxx @@ -0,0 +1,6730 @@ + +/* A Bison parser, made from parser.y + by GNU Bison version 1.25 + */ + +#define YYBISON 1 /* Identify Bison output. */ + +#define ID 258 +#define HBLOCK 259 +#define WRAPPER 260 +#define POUND 261 +#define STRING 262 +#define NUM_INT 263 +#define NUM_FLOAT 264 +#define CHARCONST 265 +#define NUM_UNSIGNED 266 +#define NUM_LONG 267 +#define NUM_ULONG 268 +#define TYPEDEF 269 +#define TYPE_INT 270 +#define TYPE_UNSIGNED 271 +#define TYPE_SHORT 272 +#define TYPE_LONG 273 +#define TYPE_FLOAT 274 +#define TYPE_DOUBLE 275 +#define TYPE_CHAR 276 +#define TYPE_VOID 277 +#define TYPE_SIGNED 278 +#define TYPE_BOOL 279 +#define TYPE_TYPEDEF 280 +#define LPAREN 281 +#define RPAREN 282 +#define COMMA 283 +#define SEMI 284 +#define EXTERN 285 +#define INIT 286 +#define LBRACE 287 +#define RBRACE 288 +#define DEFINE 289 +#define PERIOD 290 +#define CONST 291 +#define STRUCT 292 +#define UNION 293 +#define EQUAL 294 +#define SIZEOF 295 +#define MODULE 296 +#define LBRACKET 297 +#define RBRACKET 298 +#define WEXTERN 299 +#define ILLEGAL 300 +#define READONLY 301 +#define READWRITE 302 +#define NAME 303 +#define RENAME 304 +#define INCLUDE 305 +#define CHECKOUT 306 +#define ADDMETHODS 307 +#define PRAGMA 308 +#define CVALUE 309 +#define COUT 310 +#define ENUM 311 +#define ENDDEF 312 +#define MACRO 313 +#define CLASS 314 +#define PRIVATE 315 +#define PUBLIC 316 +#define PROTECTED 317 +#define COLON 318 +#define STATIC 319 +#define VIRTUAL 320 +#define FRIEND 321 +#define OPERATOR 322 +#define THROW 323 +#define TEMPLATE 324 +#define NATIVE 325 +#define INLINE 326 +#define IFDEF 327 +#define IFNDEF 328 +#define ENDIF 329 +#define ELSE 330 +#define UNDEF 331 +#define IF 332 +#define DEFINED 333 +#define ELIF 334 +#define RAW_MODE 335 +#define ALPHA_MODE 336 +#define TEXT 337 +#define DOC_DISABLE 338 +#define DOC_ENABLE 339 +#define STYLE 340 +#define LOCALSTYLE 341 +#define TYPEMAP 342 +#define EXCEPT 343 +#define IMPORT 344 +#define ECHO 345 +#define NEW 346 +#define APPLY 347 +#define CLEAR 348 +#define DOCONLY 349 +#define TITLE 350 +#define SECTION 351 +#define SUBSECTION 352 +#define SUBSUBSECTION 353 +#define LESSTHAN 354 +#define GREATERTHAN 355 +#define USERDIRECTIVE 356 +#define OC_INTERFACE 357 +#define OC_END 358 +#define OC_PUBLIC 359 +#define OC_PRIVATE 360 +#define OC_PROTECTED 361 +#define OC_CLASS 362 +#define OC_IMPLEMENT 363 +#define OC_PROTOCOL 364 +#define OR 365 +#define XOR 366 +#define AND 367 +#define LSHIFT 368 +#define RSHIFT 369 +#define PLUS 370 +#define MINUS 371 +#define STAR 372 +#define SLASH 373 +#define UMINUS 374 +#define NOT 375 +#define LNOT 376 +#define DCOLON 377 + +#line 1 "parser.y" + +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ +/*********************************************************************** + * $Header$ + * + * parser.y + * + * YACC parser for parsing function declarations. + * + * *** DISCLAIMER *** + * + * This is the most ugly, incredibly henious, and completely unintelligible + * file in SWIG. While it started out simple, it has grown into a + * monster that is almost unmaintainable. A complete parser rewrite is + * currently in progress that should make this file about 1/4 the size + * that it is now. Needless to say, don't modify this file or even look + * at it for that matter! + ***********************************************************************/ + +#define yylex yylex + +extern "C" int yylex(); +void yyerror (char *s); + +extern int line_number; +extern int start_line; +extern void skip_brace(void); +extern void skip_define(void); +extern void skip_decl(void); +extern int skip_cond(int); +extern void skip_to_end(void); +extern void skip_template(void); +extern void scanner_check_typedef(void); +extern void scanner_ignore_typedef(void); +extern void scanner_clear_start(void); +extern void start_inline(char *, int); +extern void format_string(char *); +extern void swig_pragma(char *, char *); + +#include "internal.h" + +#ifdef NEED_ALLOC +void *alloca(unsigned n) { + return((void *) malloc(n)); +} +#else +// This redefinition is apparently needed on a number of machines, +// particularly HPUX +#undef alloca +#define alloca malloc +#endif + +// Initialization flags. These indicate whether or not certain +// features have been initialized. These were added to allow +// interface files without the block (required in previous +// versions). + +static int module_init = 0; /* Indicates whether the %module name was given */ +static int title_init = 0; /* Indicates whether %title directive has been given */ +static int doc_init = 0; + +static int lang_init = 0; /* Indicates if the language has been initialized */ + +static int i; + int Error = 0; +static char temp_name[128]; +static DataType *temp_typeptr, temp_type; +static char yy_rename[256]; +static int Rename_true = 0; +static DataType *Active_type = 0; // Used to support variable lists +static int Active_extern = 0; // Whether or not list is external +static int Active_static = 0; +static DataType *Active_typedef = 0; // Used for typedef lists +static int InArray = 0; // Used when an array declaration is found +static int in_then = 0; +static int in_else = 0; +static int allow = 1; // Used during conditional compilation +static int doc_scope = 0; // Documentation scoping +static String ArrayString; // Array type attached to parameter names +static String ArrayBackup; // Array backup string +static char *DefArg = 0; // Default argument hack +static char *ConstChar = 0; // Used to store raw character constants +static ParmList *tm_parm = 0; // Parameter list used to hold typemap parameters +static Hash name_hash; // Hash table containing renamings + char *objc_construct = "new"; // Objective-C constructor + char *objc_destruct = "free"; // Objective-C destructor + +/* Some macros for building constants */ + +#define E_BINARY(TARGET, SRC1, SRC2, OP) \ + TARGET = new char[strlen(SRC1) + strlen(SRC2) +strlen(OP)+1];\ + sprintf(TARGET,"%s%s%s",SRC1,OP,SRC2); + +/* C++ modes */ + +#define CPLUS_PUBLIC 1 +#define CPLUS_PRIVATE 2 +#define CPLUS_PROTECTED 3 + +int cplus_mode; + +// Declarations of some functions for handling C++ + +extern void cplus_open_class(char *name, char *rname, char *ctype); +extern void cplus_member_func(char *, char *, DataType *, ParmList *, int); +extern void cplus_constructor(char *, char *, ParmList *); +extern void cplus_destructor(char *, char *); +extern void cplus_variable(char *, char *, DataType *); +extern void cplus_static_func(char *, char *, DataType *, ParmList *); +extern void cplus_declare_const(char *, char *, DataType *, char *); +extern void cplus_class_close(char *); +extern void cplus_inherit(int, char **); +extern void cplus_cleanup(void); +extern void cplus_static_var(char *, char *, DataType *); +extern void cplus_register_type(char *); +extern void cplus_register_scope(Hash *); +extern void cplus_inherit_scope(int, char **); +extern void cplus_add_pragma(char *, char *, char *); +extern DocEntry *cplus_set_class(char *); +extern void cplus_unset_class(); +extern void cplus_abort(); + +// ---------------------------------------------------------------------- +// static init_language() +// +// Initialize the target language. +// Does nothing if this function has already been called. +// ---------------------------------------------------------------------- + +static void init_language() { + if (!lang_init) { + lang->initialize(); + + // Initialize the documentation system + + if (!doctitle) { + doctitle = new DocTitle(title,0); + } + if (!doc_init) + doctitle->usage = title; + + doc_stack[0] = doctitle; + doc_stack_top = 0; + + int oldignore = IgnoreDoc; + IgnoreDoc = 1; + if (ConfigFile) { + include_file(ConfigFile); + } + IgnoreDoc = oldignore; + } + lang_init = 1; + title_init = 1; +} + +// ---------------------------------------------------------------------- +// int promote(int t1, int t2) +// +// Promote types (for constant expressions) +// ---------------------------------------------------------------------- + +int promote(int t1, int t2) { + + if ((t1 == T_ERROR) || (t2 == T_ERROR)) return T_ERROR; + if ((t1 == T_DOUBLE) || (t2 == T_DOUBLE)) return T_DOUBLE; + if ((t1 == T_FLOAT) || (t2 == T_FLOAT)) return T_FLOAT; + if ((t1 == T_ULONG) || (t2 == T_ULONG)) return T_ULONG; + if ((t1 == T_LONG) || (t2 == T_LONG)) return T_LONG; + if ((t1 == T_UINT) || (t2 == T_UINT)) return T_UINT; + if ((t1 == T_INT) || (t2 == T_INT)) return T_INT; + if ((t1 == T_USHORT) || (t2 == T_USHORT)) return T_SHORT; + if ((t1 == T_SHORT) || (t2 == T_SHORT)) return T_SHORT; + if ((t1 == T_UCHAR) || (t2 == T_UCHAR)) return T_UCHAR; + if (t1 != t2) { + fprintf(stderr,"%s : Line %d. Type mismatch in constant expression\n", + input_file, line_number); + FatalError(); + } + return t1; +} + +/* Generate the scripting name of an object. Takes %name directive into + account among other things */ + +static char *make_name(char *name) { + // Check to see if the name is in the hash + char *nn = (char *) name_hash.lookup(name); + if (nn) return nn; // Yep, return it. + + if (Rename_true) { + Rename_true = 0; + return yy_rename; + } else { + // Now check to see if the name contains a $ + if (strchr(name,'$')) { + static String temp; + temp = ""; + temp << name; + temp.replace("$","_S_"); + return temp; + } else { + return name; + } + } +} + +/* Return the parent of a documentation entry. If wrapping externally, this is 0 */ + +static DocEntry *doc_parent() { + if (!WrapExtern) + return doc_stack[doc_stack_top]; + else + return 0; +} + +// ---------------------------------------------------------------------- +// create_function(int ext, char *name, DataType *t, ParmList *l) +// +// Creates a function and manages documentation creation. Really +// only used internally to the parser. +// ---------------------------------------------------------------------- + +void create_function(int ext, char *name, DataType *t, ParmList *l) { + if (Active_static) return; // Static declaration. Ignore + + init_language(); + if (WrapExtern) return; // External wrapper file. Ignore + + char *iname = make_name(name); + + // Check if symbol already exists + + if (add_symbol(iname, t, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Function %s multiply defined (2nd definition ignored).\n", + input_file, line_number, iname); + } else { + Stat_func++; + if (Verbose) { + fprintf(stderr,"Wrapping function : "); + emit_extern_func(name, t, l, 0, stderr); + } + + // If extern, make an extern declaration in the SWIG wrapper file + + if (ext) + emit_extern_func(name, t, l, ext, f_header); + else if (ForceExtern) { + emit_extern_func(name, t, l, 1, f_header); + } + + // If this function has been declared inline, produce a function + + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + lang->create_function(name, iname, t, l); + l->check_defined(); + t->check_defined(); + } + scanner_clear_start(); +} + +// ------------------------------------------------------------------- +// create_variable(int ext, char *name, DataType *t) +// +// Create a link to a global variable. +// ------------------------------------------------------------------- + +void create_variable(int ext, char *name, DataType *t) { + + if (WrapExtern) return; // External wrapper file. Ignore + int oldstatus = Status; + + if (Active_static) return; // If static ignore + + init_language(); + + char *iname = make_name(name); + if (add_symbol(iname, t, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Variable %s multiply defined (2nd definition ignored).\n", + input_file, line_number, iname); + } else { + Stat_var++; + if (Verbose) { + fprintf(stderr,"Wrapping variable : "); + emit_extern_var(name, t, 0, stderr); + } + + // If externed, output an external declaration + + if (ext) + emit_extern_var(name, t, ext, f_header); + else if (ForceExtern) { + emit_extern_var(name, t, 1, f_header); + } + + // If variable datatype is read-only, we'll force it to be readonly + if (t->status & STAT_READONLY) Status = Status | STAT_READONLY; + + // Now dump it out + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + lang->link_variable(name, iname, t); + t->check_defined(); + Status = oldstatus; + } + scanner_clear_start(); +} + +// ------------------------------------------------------------------ +// create_constant(char *name, DataType *type, char *value) +// +// Creates a new constant. +// ------------------------------------------------------------------- + +void create_constant(char *name, DataType *type, char *value) { + + if (Active_static) return; + if (WrapExtern) return; // External wrapper file. Ignore + init_language(); + + if (Rename_true) { + fprintf(stderr,"%s : Line %d. %%name directive ignored with #define\n", + input_file, line_number); + Rename_true = 0; + } + + if ((type->type == T_CHAR) && (!type->is_pointer)) + type->is_pointer++; + + if (!value) value = copy_string(name); + sprintf(temp_name,"const:%s", name); + if (add_symbol(temp_name, type, value)) { + fprintf(stderr,"%s : Line %d. Constant %s multiply defined. (2nd definition ignored)\n", + input_file, line_number, name); + } else { + // Update symbols value if already defined. + update_symbol(name, type, value); + + if (!WrapExtern) { // Only wrap the constant if not in %extern mode + Stat_const++; + if (Verbose) + fprintf(stderr,"Creating constant %s = %s\n", name, value); + + doc_entry = new DocDecl(name,doc_stack[doc_stack_top]); + lang->declare_const(name, name, type, value); + type->check_defined(); + } + } + scanner_clear_start(); +} + + +/* Print out array brackets */ +void print_array() { + int i; + for (i = 0; i < InArray; i++) + fprintf(stderr,"[]"); +} + +/* manipulate small stack for managing if-then-else */ + +static int then_data[100]; +static int else_data[100]; +static int allow_data[100]; +static int te_index = 0; +static int prev_allow = 1; + +void if_push() { + then_data[te_index] = in_then; + else_data[te_index] = in_else; + allow_data[te_index] = allow; + prev_allow = allow; + te_index++; + if (te_index >= 100) { + fprintf(stderr,"SWIG. Internal parser error. if-then-else stack overflow.\n"); + SWIG_exit(1); + } +} + +void if_pop() { + if (te_index > 0) { + te_index--; + in_then = then_data[te_index]; + in_else = else_data[te_index]; + allow = allow_data[te_index]; + if (te_index > 0) { + prev_allow = allow_data[te_index-1]; + } else { + prev_allow = 1; + } + } +} + +// Structures for handling code fragments built for nested classes + +struct Nested { + String code; // Associated code fragment + int line; // line number where it starts + char *name; // Name associated with this nested class + DataType *type; // Datatype associated with the name + Nested *next; // Next code fragment in list +}; + +// Some internal variables for saving nested class information + +static Nested *nested_list = 0; + +// Add a function to the nested list + +static void add_nested(Nested *n) { + Nested *n1; + if (!nested_list) nested_list = n; + else { + n1 = nested_list; + while (n1->next) n1 = n1->next; + n1->next = n; + } +} + +// Dump all of the nested class declarations to the inline processor +// However. We need to do a few name replacements and other munging +// first. This function must be called before closing a class! + +static void dump_nested(char *parent) { + Nested *n,*n1; + n = nested_list; + int oldstatus = Status; + + Status = STAT_READONLY; + while (n) { + // Token replace the name of the parent class + n->code.replace("$classname",parent); + + // Fix up the name of the datatype (for building typedefs and other stuff) + sprintf(n->type->name,"%s_%s",parent,n->name); + + // Add the appropriate declaration to the C++ processor + doc_entry = new DocDecl(n->name,doc_stack[doc_stack_top]); + cplus_variable(n->name,(char *) 0, n->type); + + // Dump the code to the scanner + if (Verbose) + fprintf(stderr,"Splitting from %s : (line %d) \n%s\n", parent,n->line, n->code.get()); + + fprintf(f_header,"\n%s\n", n->code.get()); + start_inline(n->code.get(),n->line); + + n1 = n->next; + delete n; + n = n1; + } + nested_list = 0; + Status = oldstatus; +} + + +#line 475 "parser.y" +typedef union { + char *id; + struct Declaration { + char *id; + int is_pointer; + int is_reference; + } decl; + struct InitList { + char **names; + int count; + } ilist; + struct DocList { + char **names; + char **values; + int count; + } dlist; + struct Define { + char *id; + int type; + } dtype; + DataType *type; + Parm *p; + TMParm *tmparm; + ParmList *pl; + int ivalue; +} YYSTYPE; +#include + +#ifndef __cplusplus +#ifndef __STDC__ +#define const +#endif +#endif + + + +#define YYFINAL 907 +#define YYFLAG -32768 +#define YYNTBASE 123 + +#define YYTRANSLATE(x) ((unsigned)(x) <= 377 ? yytranslate[x] : 258) + +static const char 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 +}; + +#if YYDEBUG != 0 +static const short yyprhs[] = { 0, + 0, 1, 4, 7, 9, 12, 15, 18, 21, 23, + 24, 32, 37, 38, 46, 51, 52, 62, 70, 71, + 80, 88, 96, 97, 107, 109, 111, 116, 121, 122, + 126, 127, 133, 141, 153, 157, 161, 165, 169, 171, + 173, 175, 178, 180, 182, 185, 188, 191, 194, 197, + 199, 203, 207, 211, 214, 217, 218, 227, 228, 229, + 240, 249, 256, 265, 272, 283, 292, 298, 302, 308, + 311, 317, 320, 322, 324, 326, 328, 334, 336, 338, + 341, 344, 346, 348, 350, 351, 357, 368, 380, 381, + 388, 392, 396, 398, 401, 404, 406, 408, 411, 414, + 419, 422, 425, 433, 437, 444, 446, 447, 454, 455, + 464, 467, 469, 472, 474, 476, 479, 482, 485, 487, + 491, 493, 495, 498, 501, 505, 509, 518, 522, 525, + 528, 530, 532, 535, 539, 542, 545, 547, 549, 551, + 554, 556, 558, 561, 564, 567, 570, 574, 579, 581, + 583, 585, 588, 591, 593, 595, 597, 599, 601, 604, + 607, 610, 613, 616, 619, 623, 626, 629, 631, 634, + 637, 639, 641, 643, 645, 647, 650, 653, 656, 659, + 662, 664, 666, 669, 672, 674, 676, 678, 681, 684, + 686, 688, 690, 691, 694, 696, 698, 702, 704, 706, + 708, 712, 714, 716, 717, 722, 725, 727, 729, 731, + 733, 735, 737, 739, 741, 746, 751, 753, 757, 761, + 765, 769, 773, 777, 781, 785, 789, 793, 796, 799, + 803, 805, 807, 808, 817, 818, 819, 831, 832, 833, + 843, 848, 858, 865, 871, 873, 874, 881, 884, 887, + 889, 892, 893, 894, 902, 903, 907, 909, 916, 924, + 930, 937, 944, 945, 951, 956, 957, 963, 971, 974, + 977, 980, 985, 986, 990, 991, 999, 1001, 1003, 1005, + 1009, 1011, 1013, 1015, 1019, 1026, 1027, 1034, 1035, 1041, + 1045, 1049, 1053, 1057, 1059, 1061, 1063, 1065, 1067, 1069, + 1071, 1073, 1074, 1080, 1081, 1088, 1091, 1094, 1097, 1102, + 1105, 1109, 1111, 1113, 1117, 1123, 1131, 1134, 1136, 1139, + 1141, 1143, 1147, 1149, 1152, 1156, 1159, 1163, 1165, 1167, + 1169, 1171, 1173, 1175, 1177, 1182, 1184, 1188, 1192, 1195, + 1197, 1199, 1203, 1208, 1212, 1214, 1218, 1219, 1229, 1230, + 1240, 1242, 1244, 1249, 1253, 1256, 1258, 1260, 1263, 1264, + 1268, 1269, 1273, 1274, 1278, 1279, 1283, 1285, 1289, 1292, + 1296, 1297, 1304, 1308, 1313, 1315, 1318, 1319, 1325, 1326, + 1333, 1334, 1338, 1340, 1346, 1352, 1354, 1356, 1360, 1365, + 1367, 1371, 1373, 1378, 1380, 1382, 1385, 1389, 1394, 1396, + 1399, 1402, 1404, 1406, 1408, 1411, 1415, 1417, 1420, 1424, + 1428, 1437, 1440, 1441, 1446, 1447, 1451, 1453, 1457, 1459, + 1461, 1463, 1469, 1472, 1475, 1478, 1481 +}; + +static const short yyrhs[] = { -1, + 124, 125, 0, 125, 126, 0, 257, 0, 50, 254, + 0, 44, 254, 0, 89, 254, 0, 51, 254, 0, + 6, 0, 0, 149, 163, 159, 162, 156, 127, 145, + 0, 149, 164, 26, 117, 0, 0, 64, 163, 159, + 162, 156, 128, 145, 0, 64, 164, 26, 117, 0, + 0, 149, 163, 159, 26, 151, 27, 213, 129, 145, + 0, 149, 163, 159, 26, 151, 27, 150, 0, 0, + 149, 159, 26, 151, 27, 213, 130, 145, 0, 64, + 163, 159, 26, 151, 27, 150, 0, 71, 163, 159, + 26, 151, 27, 150, 0, 0, 64, 163, 159, 26, + 151, 27, 213, 131, 145, 0, 46, 0, 47, 0, + 48, 26, 3, 27, 0, 49, 3, 3, 29, 0, + 0, 91, 132, 126, 0, 0, 48, 26, 27, 133, + 177, 0, 70, 26, 3, 27, 149, 3, 29, 0, + 70, 26, 3, 27, 149, 163, 159, 26, 151, 27, + 29, 0, 95, 7, 244, 0, 96, 7, 244, 0, + 97, 7, 244, 0, 98, 7, 244, 0, 81, 0, + 80, 0, 137, 0, 82, 4, 0, 138, 0, 4, + 0, 5, 4, 0, 31, 4, 0, 71, 4, 0, + 90, 4, 0, 90, 7, 0, 94, 0, 31, 3, + 170, 0, 41, 3, 170, 0, 34, 3, 148, 0, + 34, 58, 0, 76, 3, 0, 0, 149, 56, 171, + 32, 134, 172, 33, 29, 0, 0, 0, 14, 56, + 171, 32, 135, 172, 33, 3, 136, 141, 0, 87, + 26, 3, 28, 246, 27, 247, 32, 0, 87, 26, + 246, 27, 247, 32, 0, 87, 26, 3, 28, 246, + 27, 247, 29, 0, 87, 26, 246, 27, 247, 29, + 0, 87, 26, 3, 28, 246, 27, 247, 39, 249, + 29, 0, 87, 26, 246, 27, 247, 39, 249, 29, + 0, 92, 249, 32, 247, 33, 0, 93, 247, 29, + 0, 88, 26, 3, 27, 32, 0, 88, 32, 0, + 88, 26, 3, 27, 29, 0, 88, 29, 0, 29, + 0, 177, 0, 219, 0, 1, 0, 30, 7, 32, + 125, 33, 0, 142, 0, 144, 0, 85, 243, 0, + 86, 243, 0, 255, 0, 83, 0, 84, 0, 0, + 14, 163, 159, 139, 141, 0, 14, 163, 26, 117, + 155, 27, 26, 151, 27, 29, 0, 14, 163, 160, + 26, 117, 155, 27, 26, 151, 27, 29, 0, 0, + 14, 163, 159, 161, 140, 141, 0, 28, 159, 141, + 0, 28, 159, 161, 0, 257, 0, 72, 3, 0, + 73, 3, 0, 75, 0, 74, 0, 77, 143, 0, + 79, 143, 0, 78, 26, 3, 27, 0, 78, 3, + 0, 121, 143, 0, 53, 26, 3, 28, 3, 245, + 27, 0, 53, 3, 245, 0, 53, 26, 3, 27, + 3, 245, 0, 29, 0, 0, 28, 159, 162, 156, + 146, 145, 0, 0, 28, 159, 26, 151, 27, 213, + 147, 145, 0, 168, 57, 0, 57, 0, 1, 57, + 0, 30, 0, 257, 0, 30, 7, 0, 213, 32, + 0, 153, 152, 0, 257, 0, 28, 153, 152, 0, + 257, 0, 154, 0, 158, 154, 0, 163, 155, 0, + 163, 160, 155, 0, 163, 112, 155, 0, 163, 26, + 160, 155, 27, 26, 151, 27, 0, 35, 35, 35, + 0, 3, 156, 0, 3, 161, 0, 161, 0, 257, + 0, 39, 168, 0, 39, 112, 3, 0, 39, 32, + 0, 63, 8, 0, 257, 0, 54, 0, 55, 0, + 158, 157, 0, 157, 0, 3, 0, 160, 3, 0, + 112, 3, 0, 117, 257, 0, 117, 160, 0, 42, + 43, 162, 0, 42, 176, 43, 162, 0, 161, 0, + 257, 0, 15, 0, 17, 167, 0, 18, 167, 0, + 21, 0, 24, 0, 19, 0, 20, 0, 22, 0, + 23, 165, 0, 16, 166, 0, 25, 223, 0, 3, + 223, 0, 36, 163, 0, 212, 3, 0, 3, 122, + 3, 0, 122, 3, 0, 56, 3, 0, 15, 0, + 17, 167, 0, 18, 167, 0, 21, 0, 24, 0, + 19, 0, 20, 0, 22, 0, 23, 165, 0, 16, + 166, 0, 25, 223, 0, 36, 163, 0, 212, 3, + 0, 257, 0, 15, 0, 17, 167, 0, 18, 167, + 0, 21, 0, 257, 0, 15, 0, 17, 167, 0, + 18, 167, 0, 21, 0, 15, 0, 257, 0, 0, + 169, 176, 0, 7, 0, 10, 0, 170, 28, 3, + 0, 257, 0, 3, 0, 257, 0, 172, 28, 173, + 0, 173, 0, 3, 0, 0, 3, 39, 174, 175, + 0, 142, 173, 0, 257, 0, 176, 0, 10, 0, + 8, 0, 9, 0, 11, 0, 12, 0, 13, 0, + 40, 26, 163, 27, 0, 26, 164, 27, 176, 0, + 3, 0, 3, 122, 3, 0, 176, 115, 176, 0, + 176, 116, 176, 0, 176, 117, 176, 0, 176, 118, + 176, 0, 176, 112, 176, 0, 176, 110, 176, 0, + 176, 111, 176, 0, 176, 113, 176, 0, 176, 114, + 176, 0, 116, 176, 0, 120, 176, 0, 26, 176, + 27, 0, 178, 0, 184, 0, 0, 149, 212, 3, + 208, 32, 179, 187, 33, 0, 0, 0, 14, 212, + 3, 208, 32, 180, 187, 33, 159, 181, 141, 0, + 0, 0, 14, 212, 32, 182, 187, 33, 159, 183, + 141, 0, 149, 212, 3, 29, 0, 149, 163, 159, + 122, 3, 26, 151, 27, 29, 0, 149, 163, 159, + 122, 3, 29, 0, 149, 163, 159, 122, 67, 0, + 69, 0, 0, 52, 3, 32, 185, 186, 33, 0, + 191, 187, 0, 237, 233, 0, 257, 0, 191, 187, + 0, 0, 0, 52, 32, 188, 187, 33, 189, 187, + 0, 0, 1, 190, 187, 0, 257, 0, 163, 159, + 26, 151, 27, 204, 0, 65, 163, 159, 26, 151, + 27, 205, 0, 3, 26, 151, 27, 214, 0, 120, + 3, 26, 151, 27, 204, 0, 65, 120, 3, 26, + 27, 204, 0, 0, 163, 159, 156, 192, 201, 0, + 163, 159, 161, 156, 0, 0, 64, 163, 159, 193, + 201, 0, 64, 163, 159, 26, 151, 27, 204, 0, + 61, 63, 0, 60, 63, 0, 62, 63, 0, 48, + 26, 3, 27, 0, 0, 91, 194, 191, 0, 0, + 56, 171, 32, 195, 206, 33, 29, 0, 46, 0, + 47, 0, 66, 0, 163, 200, 67, 0, 142, 0, + 138, 0, 196, 0, 53, 3, 245, 0, 53, 26, + 3, 27, 3, 245, 0, 0, 212, 3, 32, 197, + 199, 29, 0, 0, 212, 32, 198, 159, 29, 0, + 212, 3, 29, 0, 163, 160, 26, 0, 164, 26, + 117, 0, 3, 26, 117, 0, 137, 0, 29, 0, + 159, 0, 257, 0, 160, 0, 112, 0, 257, 0, + 29, 0, 0, 28, 159, 156, 202, 201, 0, 0, + 28, 159, 161, 156, 203, 201, 0, 213, 29, 0, + 213, 32, 0, 213, 29, 0, 213, 39, 168, 29, + 0, 213, 32, 0, 206, 28, 207, 0, 207, 0, + 3, 0, 3, 39, 175, 0, 48, 26, 3, 27, + 3, 0, 48, 26, 3, 27, 3, 39, 175, 0, + 142, 207, 0, 257, 0, 63, 209, 0, 257, 0, + 210, 0, 209, 28, 210, 0, 3, 0, 65, 3, + 0, 65, 211, 3, 0, 211, 3, 0, 211, 65, + 3, 0, 61, 0, 60, 0, 62, 0, 59, 0, + 37, 0, 38, 0, 36, 0, 68, 26, 151, 27, + 0, 257, 0, 213, 215, 29, 0, 213, 215, 32, + 0, 63, 216, 0, 257, 0, 217, 0, 216, 28, + 217, 0, 3, 26, 218, 27, 0, 3, 26, 27, + 0, 176, 0, 218, 28, 176, 0, 0, 102, 3, + 222, 220, 32, 224, 33, 233, 103, 0, 0, 102, + 3, 26, 3, 27, 223, 221, 233, 103, 0, 108, + 0, 109, 0, 107, 3, 170, 29, 0, 63, 3, + 223, 0, 223, 257, 0, 99, 0, 257, 0, 229, + 224, 0, 0, 104, 225, 224, 0, 0, 105, 226, + 224, 0, 0, 106, 227, 224, 0, 0, 1, 228, + 224, 0, 257, 0, 230, 232, 29, 0, 163, 159, + 0, 163, 159, 161, 0, 0, 48, 26, 3, 27, + 231, 230, 0, 28, 159, 232, 0, 28, 159, 161, + 232, 0, 257, 0, 237, 233, 0, 0, 52, 32, + 234, 233, 33, 0, 0, 48, 26, 3, 27, 235, + 233, 0, 0, 1, 236, 233, 0, 257, 0, 116, + 239, 3, 241, 238, 0, 115, 239, 3, 241, 238, + 0, 29, 0, 32, 0, 26, 163, 27, 0, 26, + 163, 160, 27, 0, 257, 0, 26, 153, 27, 0, + 257, 0, 241, 242, 240, 3, 0, 257, 0, 63, + 0, 3, 63, 0, 3, 245, 244, 0, 244, 28, + 3, 245, 0, 257, 0, 39, 8, 0, 39, 7, + 0, 257, 0, 3, 0, 36, 0, 249, 248, 0, + 28, 249, 248, 0, 257, 0, 163, 250, 0, 163, + 160, 250, 0, 163, 112, 250, 0, 163, 26, 160, + 250, 27, 26, 151, 27, 0, 3, 253, 0, 0, + 3, 161, 251, 253, 0, 0, 161, 252, 253, 0, + 253, 0, 26, 151, 27, 0, 257, 0, 3, 0, + 7, 0, 101, 26, 151, 27, 256, 0, 101, 256, + 0, 3, 29, 0, 7, 29, 0, 32, 33, 0, + 0 +}; + +#endif + +#if YYDEBUG != 0 +static const short yyrline[] = { 0, + 559, 568, 582, 586, 590, 601, 618, 636, 646, 657, + 684, 688, 696, 702, 708, 717, 729, 733, 746, 755, + 759, 774, 797, 806, 812, 819, 825, 833, 842, 844, + 850, 856, 862, 874, 895, 943, 973, 1009, 1046, 1054, + 1062, 1066, 1075, 1079, 1090, 1100, 1109, 1119, 1125, 1132, + 1138, 1160, 1176, 1195, 1202, 1208, 1208, 1223, 1223, 1233, + 1243, 1256, 1275, 1287, 1305, 1320, 1341, 1352, 1369, 1376, + 1383, 1388, 1394, 1395, 1396, 1397, 1415, 1416, 1420, 1424, + 1440, 1453, 1459, 1473, 1492, 1504, 1508, 1530, 1554, 1570, + 1583, 1595, 1606, 1626, 1652, 1675, 1694, 1704, 1730, 1759, + 1768, 1775, 1781, 1789, 1793, 1801, 1802, 1828, 1829, 1839, + 1842, 1845, 1848, 1856, 1857, 1858, 1870, 1879, 1885, 1888, + 1893, 1896, 1901, 1916, 1942, 1961, 1973, 1984, 1994, 2003, + 2008, 2014, 2021, 2022, 2028, 2032, 2034, 2037, 2038, 2041, + 2044, 2051, 2055, 2060, 2070, 2071, 2075, 2079, 2086, 2089, + 2097, 2100, 2103, 2106, 2109, 2112, 2115, 2118, 2121, 2125, + 2129, 2140, 2155, 2160, 2165, 2174, 2180, 2190, 2193, 2196, + 2199, 2202, 2205, 2208, 2211, 2214, 2218, 2222, 2226, 2231, + 2240, 2243, 2249, 2255, 2261, 2271, 2274, 2280, 2286, 2292, + 2300, 2301, 2304, 2304, 2310, 2317, 2329, 2335, 2345, 2346, + 2352, 2353, 2357, 2362, 2362, 2369, 2370, 2373, 2385, 2396, + 2400, 2404, 2408, 2412, 2416, 2421, 2426, 2438, 2445, 2451, + 2457, 2464, 2471, 2482, 2494, 2506, 2518, 2530, 2537, 2547, + 2558, 2559, 2562, 2596, 2633, 2667, 2730, 2734, 2757, 2793, + 2796, 2809, 2830, 2850, 2858, 2866, 2876, 2884, 2885, 2886, + 2889, 2890, 2892, 2894, 2895, 2905, 2906, 2909, 2933, 2956, + 2977, 2997, 3017, 3068, 3070, 3101, 3120, 3124, 3144, 3155, + 3166, 3177, 3185, 3187, 3192, 3192, 3210, 3215, 3221, 3229, + 3235, 3240, 3244, 3249, 3252, 3275, 3276, 3301, 3302, 3326, + 3333, 3338, 3343, 3348, 3349, 3352, 3353, 3356, 3357, 3358, + 3361, 3362, 3386, 3387, 3412, 3415, 3418, 3421, 3422, 3423, + 3426, 3427, 3430, 3445, 3461, 3476, 3492, 3493, 3496, 3499, + 3505, 3518, 3527, 3532, 3537, 3546, 3555, 3566, 3567, 3568, + 3572, 3573, 3574, 3577, 3578, 3579, 3584, 3587, 3590, 3591, + 3594, 3595, 3598, 3599, 3602, 3603, 3611, 3627, 3644, 3655, + 3660, 3661, 3662, 3677, 3678, 3682, 3688, 3693, 3694, 3696, + 3697, 3699, 3700, 3702, 3703, 3716, 3717, 3720, 3727, 3749, + 3771, 3774, 3776, 3796, 3818, 3821, 3822, 3824, 3827, 3830, + 3831, 3844, 3845, 3848, 3868, 3889, 3890, 3893, 3896, 3900, + 3908, 3912, 3920, 3926, 3931, 3932, 3943, 3953, 3960, 3967, + 3970, 3973, 3983, 3986, 3991, 3997, 4001, 4004, 4017, 4031, + 4044, 4059, 4063, 4066, 4072, 4075, 4082, 4088, 4091, 4096, + 4097, 4103, 4104, 4107, 4108, 4109, 4141 +}; +#endif + + +#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) + +static const char * const yytname[] = { "$","error","$undefined.","ID","HBLOCK", +"WRAPPER","POUND","STRING","NUM_INT","NUM_FLOAT","CHARCONST","NUM_UNSIGNED", +"NUM_LONG","NUM_ULONG","TYPEDEF","TYPE_INT","TYPE_UNSIGNED","TYPE_SHORT","TYPE_LONG", +"TYPE_FLOAT","TYPE_DOUBLE","TYPE_CHAR","TYPE_VOID","TYPE_SIGNED","TYPE_BOOL", +"TYPE_TYPEDEF","LPAREN","RPAREN","COMMA","SEMI","EXTERN","INIT","LBRACE","RBRACE", +"DEFINE","PERIOD","CONST","STRUCT","UNION","EQUAL","SIZEOF","MODULE","LBRACKET", +"RBRACKET","WEXTERN","ILLEGAL","READONLY","READWRITE","NAME","RENAME","INCLUDE", +"CHECKOUT","ADDMETHODS","PRAGMA","CVALUE","COUT","ENUM","ENDDEF","MACRO","CLASS", +"PRIVATE","PUBLIC","PROTECTED","COLON","STATIC","VIRTUAL","FRIEND","OPERATOR", +"THROW","TEMPLATE","NATIVE","INLINE","IFDEF","IFNDEF","ENDIF","ELSE","UNDEF", +"IF","DEFINED","ELIF","RAW_MODE","ALPHA_MODE","TEXT","DOC_DISABLE","DOC_ENABLE", +"STYLE","LOCALSTYLE","TYPEMAP","EXCEPT","IMPORT","ECHO","NEW","APPLY","CLEAR", +"DOCONLY","TITLE","SECTION","SUBSECTION","SUBSUBSECTION","LESSTHAN","GREATERTHAN", +"USERDIRECTIVE","OC_INTERFACE","OC_END","OC_PUBLIC","OC_PRIVATE","OC_PROTECTED", +"OC_CLASS","OC_IMPLEMENT","OC_PROTOCOL","OR","XOR","AND","LSHIFT","RSHIFT","PLUS", +"MINUS","STAR","SLASH","UMINUS","NOT","LNOT","DCOLON","program","@1","command", +"statement","@2","@3","@4","@5","@6","@7","@8","@9","@10","@11","doc_enable", +"typedef_decl","@12","@13","typedeflist","cond_compile","cpp_const_expr","pragma", +"stail","@14","@15","definetail","extern","func_end","parms","ptail","parm", +"parm_type","pname","def_args","parm_specifier","parm_specifier_list","declaration", +"stars","array","array2","type","strict_type","opt_signed","opt_unsigned","opt_int", +"definetype","@16","initlist","ename","enumlist","edecl","@17","etype","expr", +"cpp","cpp_class","@18","@19","@20","@21","@22","cpp_other","@23","added_members", +"cpp_members","@24","@25","@26","cpp_member","@27","@28","@29","@30","cpp_pragma", +"@31","@32","nested_decl","type_extra","cpp_tail","@33","@34","cpp_end","cpp_vend", +"cpp_enumlist","cpp_edecl","inherit","base_list","base_specifier","access_specifier", +"cpptype","cpp_const","ctor_end","ctor_initializer","mem_initializer_list","mem_initializer", +"expr_list","objective_c","@35","@36","objc_inherit","objc_protolist","objc_data", +"@37","@38","@39","@40","objc_vars","objc_var","@41","objc_vartail","objc_methods", +"@42","@43","@44","objc_method","objc_end","objc_ret_type","objc_arg_type","objc_args", +"objc_separator","stylelist","styletail","stylearg","tm_method","tm_list","tm_tail", +"typemap_parm","typemap_name","@45","@46","typemap_args","idstring","user_directive", +"uservalue","empty", NULL +}; +#endif + +static const short yyr1[] = { 0, + 124, 123, 125, 125, 126, 126, 126, 126, 126, 127, + 126, 126, 128, 126, 126, 129, 126, 126, 130, 126, + 126, 126, 131, 126, 126, 126, 126, 126, 132, 126, + 133, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 134, 126, 135, 136, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 137, 137, 139, 138, 138, 138, 140, 138, + 141, 141, 141, 142, 142, 142, 142, 142, 142, 143, + 143, 143, 144, 144, 144, 145, 146, 145, 147, 145, + 148, 148, 148, 149, 149, 149, 150, 151, 151, 152, + 152, 153, 153, 154, 154, 154, 154, 154, 155, 155, + 155, 155, 156, 156, 156, 156, 156, 157, 157, 158, + 158, 159, 159, 159, 160, 160, 161, 161, 162, 162, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, + 165, 165, 165, 165, 165, 166, 166, 166, 166, 166, + 167, 167, 169, 168, 168, 168, 170, 170, 171, 171, + 172, 172, 173, 174, 173, 173, 173, 175, 175, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, + 177, 177, 179, 178, 180, 181, 178, 182, 183, 178, + 184, 184, 184, 184, 184, 185, 184, 186, 186, 186, + 187, 188, 189, 187, 190, 187, 187, 191, 191, 191, + 191, 191, 192, 191, 191, 193, 191, 191, 191, 191, + 191, 191, 194, 191, 195, 191, 191, 191, 191, 191, + 191, 191, 191, 196, 196, 197, 196, 198, 196, 196, + 196, 196, 196, 196, 196, 199, 199, 200, 200, 200, + 201, 202, 201, 203, 201, 204, 204, 205, 205, 205, + 206, 206, 207, 207, 207, 207, 207, 207, 208, 208, + 209, 209, 210, 210, 210, 210, 210, 211, 211, 211, + 212, 212, 212, 213, 213, 213, 214, 214, 215, 215, + 216, 216, 217, 217, 218, 218, 220, 219, 221, 219, + 219, 219, 219, 222, 222, 223, 223, 224, 225, 224, + 226, 224, 227, 224, 228, 224, 224, 229, 230, 230, + 231, 230, 232, 232, 232, 233, 234, 233, 235, 233, + 236, 233, 233, 237, 237, 238, 238, 239, 239, 239, + 240, 240, 241, 241, 242, 242, 243, 244, 244, 245, + 245, 245, 246, 246, 247, 248, 248, 249, 249, 249, + 249, 250, 251, 250, 252, 250, 250, 253, 253, 254, + 254, 255, 255, 256, 256, 256, 257 +}; + +static const short yyr2[] = { 0, + 0, 2, 2, 1, 2, 2, 2, 2, 1, 0, + 7, 4, 0, 7, 4, 0, 9, 7, 0, 8, + 7, 7, 0, 9, 1, 1, 4, 4, 0, 3, + 0, 5, 7, 11, 3, 3, 3, 3, 1, 1, + 1, 2, 1, 1, 2, 2, 2, 2, 2, 1, + 3, 3, 3, 2, 2, 0, 8, 0, 0, 10, + 8, 6, 8, 6, 10, 8, 5, 3, 5, 2, + 5, 2, 1, 1, 1, 1, 5, 1, 1, 2, + 2, 1, 1, 1, 0, 5, 10, 11, 0, 6, + 3, 3, 1, 2, 2, 1, 1, 2, 2, 4, + 2, 2, 7, 3, 6, 1, 0, 6, 0, 8, + 2, 1, 2, 1, 1, 2, 2, 2, 1, 3, + 1, 1, 2, 2, 3, 3, 8, 3, 2, 2, + 1, 1, 2, 3, 2, 2, 1, 1, 1, 2, + 1, 1, 2, 2, 2, 2, 3, 4, 1, 1, + 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 3, 2, 2, 1, 2, 2, + 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, + 1, 1, 0, 2, 1, 1, 3, 1, 1, 1, + 3, 1, 1, 0, 4, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 4, 4, 1, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, + 1, 1, 0, 8, 0, 0, 11, 0, 0, 9, + 4, 9, 6, 5, 1, 0, 6, 2, 2, 1, + 2, 0, 0, 7, 0, 3, 1, 6, 7, 5, + 6, 6, 0, 5, 4, 0, 5, 7, 2, 2, + 2, 4, 0, 3, 0, 7, 1, 1, 1, 3, + 1, 1, 1, 3, 6, 0, 6, 0, 5, 3, + 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 5, 0, 6, 2, 2, 2, 4, 2, + 3, 1, 1, 3, 5, 7, 2, 1, 2, 1, + 1, 3, 1, 2, 3, 2, 3, 1, 1, 1, + 1, 1, 1, 1, 4, 1, 3, 3, 2, 1, + 1, 3, 4, 3, 1, 3, 0, 9, 0, 9, + 1, 1, 4, 3, 2, 1, 1, 2, 0, 3, + 0, 3, 0, 3, 0, 3, 1, 3, 2, 3, + 0, 6, 3, 4, 1, 2, 0, 5, 0, 6, + 0, 3, 1, 5, 5, 1, 1, 3, 4, 1, + 3, 1, 4, 1, 1, 2, 3, 4, 1, 2, + 2, 1, 1, 1, 2, 3, 1, 2, 3, 3, + 8, 2, 0, 4, 0, 3, 1, 3, 1, 1, + 1, 5, 2, 2, 2, 2, 0 +}; + +static const short yydefact[] = { 1, + 427, 0, 4, 76, 44, 0, 9, 0, 73, 114, + 0, 0, 0, 0, 25, 26, 0, 0, 0, 0, + 0, 0, 0, 245, 0, 0, 0, 0, 97, 96, + 0, 0, 0, 40, 39, 0, 83, 84, 0, 0, + 0, 0, 0, 0, 29, 0, 0, 50, 0, 0, + 0, 0, 0, 0, 0, 351, 352, 3, 41, 43, + 78, 79, 0, 74, 231, 232, 75, 82, 115, 45, + 427, 151, 427, 427, 427, 156, 157, 154, 158, 427, + 155, 427, 0, 332, 333, 427, 331, 0, 0, 0, + 116, 427, 46, 0, 54, 427, 420, 421, 6, 0, + 0, 5, 8, 0, 427, 0, 151, 427, 427, 427, + 156, 157, 154, 158, 427, 155, 427, 0, 0, 0, + 0, 0, 0, 47, 0, 0, 94, 95, 55, 0, + 0, 98, 99, 42, 427, 80, 81, 0, 0, 72, + 70, 7, 48, 49, 0, 427, 0, 0, 427, 427, + 427, 427, 427, 0, 0, 427, 0, 423, 427, 427, + 427, 427, 0, 427, 0, 0, 0, 0, 0, 356, + 0, 162, 357, 187, 427, 427, 190, 160, 186, 191, + 152, 192, 153, 182, 427, 427, 185, 159, 181, 161, + 163, 167, 0, 200, 166, 142, 0, 85, 0, 164, + 238, 427, 51, 198, 0, 195, 196, 112, 53, 0, + 0, 52, 0, 31, 0, 246, 0, 104, 402, 0, + 160, 152, 153, 159, 161, 163, 167, 427, 0, 164, + 0, 0, 164, 101, 0, 102, 427, 403, 404, 0, + 0, 30, 427, 427, 0, 427, 427, 415, 408, 417, + 419, 0, 68, 0, 405, 407, 35, 399, 36, 37, + 38, 424, 425, 0, 138, 139, 0, 427, 122, 141, + 0, 427, 119, 426, 0, 0, 347, 427, 0, 0, + 144, 146, 145, 427, 143, 427, 0, 164, 165, 188, + 189, 183, 184, 58, 427, 427, 89, 0, 0, 0, + 320, 0, 0, 0, 113, 111, 217, 210, 211, 212, + 213, 214, 0, 0, 0, 0, 194, 27, 427, 28, + 427, 401, 400, 0, 0, 427, 149, 427, 150, 15, + 427, 427, 0, 397, 0, 0, 0, 427, 413, 412, + 0, 427, 427, 0, 410, 409, 427, 0, 427, 0, + 0, 0, 0, 118, 121, 123, 140, 427, 0, 427, + 124, 427, 131, 132, 0, 427, 0, 355, 353, 56, + 0, 427, 0, 427, 12, 241, 0, 427, 0, 0, + 86, 93, 427, 427, 323, 329, 328, 330, 0, 319, + 321, 0, 235, 255, 427, 0, 295, 277, 278, 0, + 0, 0, 427, 0, 0, 0, 0, 0, 279, 273, + 0, 294, 282, 281, 427, 0, 0, 0, 283, 0, + 257, 77, 197, 0, 168, 427, 427, 427, 173, 174, + 171, 175, 427, 172, 427, 0, 0, 0, 0, 0, + 228, 229, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 114, 0, 32, 427, 427, 0, 0, 0, + 250, 427, 427, 0, 193, 0, 13, 137, 0, 0, + 100, 403, 0, 0, 71, 69, 427, 418, 0, 147, + 427, 416, 67, 406, 427, 128, 422, 427, 129, 130, + 427, 126, 125, 427, 354, 0, 427, 427, 0, 0, + 244, 10, 233, 203, 427, 0, 202, 207, 0, 427, + 90, 0, 324, 0, 0, 326, 0, 0, 0, 427, + 0, 252, 427, 0, 0, 270, 269, 271, 0, 0, + 0, 0, 0, 299, 427, 298, 0, 300, 0, 0, + 251, 164, 288, 218, 177, 169, 170, 176, 178, 179, + 0, 230, 180, 0, 224, 225, 223, 226, 227, 219, + 220, 221, 222, 0, 116, 0, 0, 0, 0, 390, + 0, 247, 248, 381, 0, 0, 249, 0, 383, 105, + 0, 427, 135, 0, 133, 136, 0, 427, 0, 427, + 0, 64, 62, 0, 414, 0, 148, 398, 120, 0, + 349, 365, 0, 359, 361, 363, 0, 0, 0, 427, + 367, 0, 334, 0, 19, 336, 427, 427, 243, 0, + 0, 204, 206, 427, 0, 427, 91, 92, 0, 325, + 322, 327, 0, 256, 293, 0, 0, 0, 284, 0, + 275, 266, 0, 0, 274, 427, 427, 263, 427, 291, + 280, 292, 239, 290, 286, 0, 216, 215, 427, 0, + 164, 0, 427, 427, 0, 0, 377, 376, 103, 21, + 23, 134, 0, 106, 14, 33, 0, 22, 0, 0, + 0, 427, 0, 0, 0, 0, 0, 0, 0, 369, + 0, 358, 0, 0, 375, 0, 427, 0, 18, 16, + 0, 11, 0, 0, 201, 59, 0, 427, 0, 427, + 272, 0, 0, 427, 427, 0, 0, 427, 0, 0, + 0, 265, 427, 427, 0, 388, 0, 0, 394, 0, + 382, 0, 0, 117, 0, 427, 427, 63, 61, 0, + 66, 0, 427, 0, 366, 0, 360, 362, 364, 370, + 0, 427, 368, 57, 0, 20, 0, 0, 234, 209, + 205, 208, 427, 0, 0, 236, 427, 260, 253, 427, + 313, 0, 427, 0, 312, 318, 0, 0, 301, 267, + 427, 0, 427, 427, 264, 240, 296, 0, 297, 289, + 389, 0, 386, 387, 395, 385, 427, 384, 379, 0, + 24, 427, 427, 0, 0, 411, 0, 350, 371, 348, + 427, 373, 335, 17, 242, 60, 87, 0, 427, 0, + 0, 340, 0, 285, 0, 0, 317, 427, 0, 427, + 427, 262, 0, 427, 261, 258, 287, 396, 0, 0, + 392, 0, 378, 0, 107, 0, 65, 127, 0, 374, + 88, 237, 0, 339, 341, 337, 338, 254, 314, 0, + 311, 276, 268, 302, 427, 306, 307, 259, 0, 0, + 393, 380, 427, 0, 34, 372, 0, 0, 0, 0, + 304, 308, 310, 193, 391, 109, 108, 344, 345, 0, + 342, 315, 303, 0, 0, 0, 343, 0, 0, 305, + 309, 110, 346, 316, 0, 0, 0 +}; + +static const short yydefgoto[] = { 905, + 1, 2, 58, 620, 587, 757, 698, 735, 145, 319, + 497, 378, 763, 412, 413, 296, 383, 381, 414, 132, + 62, 675, 874, 896, 209, 63, 670, 341, 354, 268, + 269, 361, 467, 270, 271, 165, 166, 363, 328, 272, + 416, 188, 178, 181, 210, 211, 203, 193, 506, 507, + 704, 761, 762, 64, 65, 621, 518, 819, 302, 723, + 66, 321, 458, 417, 638, 823, 519, 418, 721, 716, + 532, 714, 419, 724, 656, 788, 537, 780, 880, 894, + 832, 868, 774, 775, 300, 390, 391, 392, 126, 833, + 768, 821, 854, 855, 890, 67, 367, 684, 277, 172, + 608, 687, 688, 689, 685, 609, 610, 849, 694, 577, + 733, 842, 665, 578, 796, 569, 840, 728, 797, 136, + 257, 218, 240, 148, 255, 149, 249, 477, 347, 250, + 99, 68, 158, 273 +}; + +static const short yypact[] = {-32768, +-32768, 916,-32768,-32768,-32768, 52,-32768, 1863,-32768, 64, + 408, 29, 136, 200,-32768,-32768, 115, 201, 200, 200, + 231, 328, 1887,-32768, 218, 1747, 266, 281,-32768,-32768, + 283, 122, 122,-32768,-32768, 307,-32768,-32768, 321, 321, + 313, 586, 200, 39,-32768, 1911, 1911,-32768, 351, 363, + 394, 396, 397, 417, 432,-32768,-32768,-32768,-32768,-32768, +-32768,-32768, 1702,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 293,-32768, 555, 431, 431,-32768,-32768,-32768,-32768, 567, +-32768, 364, 1911,-32768,-32768, 489,-32768, 491, 50, 187, + 441,-32768,-32768, 554,-32768,-32768,-32768,-32768,-32768, 251, + 499,-32768,-32768, 506, 501, 547, 528, 555, 431, 431, + 530, 534, 549, 557, 567, 569, 364, 1911, 587, 54, + 576, 603, 626,-32768, 54, 628,-32768,-32768,-32768, 393, + 122,-32768,-32768,-32768, 501,-32768,-32768, 217, 633,-32768, +-32768,-32768,-32768,-32768, 1180, 80, 590, 613, 616,-32768, +-32768,-32768,-32768, 620, 622, 1657, 623,-32768, 130,-32768, + 32, 489, 649, 536, 629, 654, 54, 635, 656,-32768, + 662,-32768,-32768,-32768, 431, 431,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768, 431, 431,-32768,-32768,-32768,-32768, +-32768, 634, 636,-32768,-32768,-32768, 552, 625, 407, 147, +-32768,-32768, 643,-32768, 615,-32768,-32768,-32768,-32768, 618, + 117, 643, 646,-32768, 650,-32768, 551,-32768,-32768, 541, + 652, 655, 663, 667, 668, 682,-32768, 238, 563, 684, + 685, 695,-32768,-32768, 679,-32768,-32768, 683,-32768, 697, + 699,-32768, 279, 1587, 1849, 237, 237,-32768,-32768,-32768, +-32768, 1911,-32768, 1911,-32768,-32768, 700,-32768, 700, 700, + 700,-32768,-32768, 692,-32768,-32768, 703, 706,-32768,-32768, + 1657, 348,-32768,-32768, 735, 739,-32768,-32768, 550, 713, +-32768,-32768,-32768, 1657,-32768, 58, 630, 457,-32768,-32768, +-32768,-32768,-32768,-32768, 152, 718,-32768, 632, 326, 720, +-32768, 1290, 1070, 747,-32768,-32768, 631,-32768,-32768,-32768, +-32768,-32768, 1999, 730, 117, 117, 939,-32768, 422,-32768, + 1421,-32768,-32768, 754, 756, 1657,-32768, 226,-32768,-32768, + 733, 1657, 737, 700, 232, 1911, 399, 1657,-32768,-32768, + 738, 237, 625, 930,-32768,-32768, 734, 746, 616, 764, + 749, 337, 1657,-32768,-32768,-32768,-32768, 409, 536, 152, +-32768, 152,-32768,-32768, 743, 364, 755,-32768,-32768,-32768, + 759, 1657, 36, 226,-32768,-32768, 757, 474, 761, 54, +-32768,-32768, 718, 152,-32768,-32768,-32768,-32768, 28, 762, +-32768, 45,-32768,-32768, 110, 1911,-32768,-32768,-32768, 765, + 763, 444, 489, 731, 736, 740, 1911, 1771,-32768,-32768, + 790,-32768,-32768,-32768, 99, 772, 767, 1290,-32768, 259, +-32768,-32768,-32768, 798,-32768, 555, 431, 431,-32768,-32768, +-32768,-32768, 567,-32768, 364, 1911, 777, 789, 802, 1911, +-32768,-32768, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 468, 799, 1911,-32768, 783, 783, 778, 1290, 248, +-32768, 501, 501, 786, 23, 806,-32768,-32768, 1935, 788, +-32768,-32768, 792, 22,-32768,-32768, 734,-32768, 793,-32768, + 625,-32768,-32768,-32768, 501,-32768,-32768, 706,-32768,-32768, + 152,-32768,-32768, 364,-32768, 1367, 474, 202, 796, 453, +-32768,-32768,-32768, 785, 474, 338,-32768,-32768, 791, 439, +-32768, 801,-32768, 822, 326,-32768, 823, 1290, 1290, 1632, + 828,-32768, 501, 829, 804,-32768,-32768,-32768, 54, 831, + 54, 1510, 811, 649, 336, 475, 771,-32768, 722, 54, +-32768, 595,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 117,-32768,-32768, 813, 588, 602, 660, 523, 523, 517, + 517,-32768,-32768, 373,-32768, 54, 839, 1911, 840,-32768, + 842,-32768,-32768,-32768, 820, 817,-32768, 240,-32768,-32768, + 824, 202,-32768, 847,-32768,-32768, 564, -5, 54, 202, + 1911,-32768,-32768, 1911,-32768, 826,-32768,-32768,-32768, 827, +-32768,-32768, 830,-32768,-32768,-32768, 54, 825, 1367, 832, +-32768, 385,-32768, 833,-32768,-32768, 202, 1657,-32768, 564, + 1290,-32768,-32768, 474, 850, 1657,-32768,-32768, 835,-32768, +-32768,-32768, 834,-32768,-32768, 836, 838, 1290,-32768, 841, +-32768, 843, 844, 848,-32768, 1657, 1657,-32768, 226,-32768, +-32768,-32768,-32768,-32768,-32768, 54,-32768,-32768, 810, 753, + 15, -2,-32768,-32768, 240, 852,-32768,-32768,-32768,-32768, + 845,-32768, 54,-32768,-32768,-32768, 853,-32768, 845, 482, + 849, 1657, 855, 265, 1367, 859, 1367, 1367, 1367, 625, + 265,-32768, 54, 856,-32768, 857, 1657, 564,-32768, 845, + 860,-32768, 851, 56,-32768,-32768, 861, 1657, 54, 202, +-32768, 858, 873, 526, 1657, 585, 862, 1657, 863, 866, + 585,-32768, 718, 54, 865,-32768, 868, 287,-32768, 287, +-32768, 869, 248,-32768, 564, 380, 1657,-32768,-32768, 1911, +-32768, 870, 1657, 779,-32768, 881,-32768,-32768,-32768,-32768, + 808, 470,-32768,-32768, 882,-32768, 564, 883,-32768,-32768, +-32768, 939, 718, 884, 887,-32768, 879,-32768,-32768, 501, + 876, 892, 526, 504,-32768,-32768, 896, 54,-32768,-32768, + 202, 897, 202, 202,-32768,-32768,-32768, 899,-32768,-32768, +-32768, 880,-32768,-32768,-32768,-32768, 900,-32768,-32768, 911, +-32768, 1657, 226, 898, 919,-32768, 902,-32768,-32768,-32768, + 832,-32768,-32768,-32768,-32768,-32768,-32768, 920, 718, 948, + 481,-32768, 1290,-32768, 56, 952,-32768, 526, 927, 202, + 409,-32768, 496, 202,-32768,-32768,-32768,-32768, 1657, 955, +-32768, 240,-32768, 932,-32768, 941,-32768,-32768, 1817,-32768, +-32768,-32768, 935, 943,-32768,-32768,-32768,-32768,-32768, 954, +-32768,-32768,-32768,-32768, 226,-32768,-32768,-32768, 494, 956, +-32768,-32768, 202, 564,-32768,-32768, 728, 948, 976, 585, +-32768,-32768,-32768, 532,-32768,-32768,-32768,-32768, 939, 619, +-32768, 945,-32768, 585, 953, 564,-32768, 117, 56,-32768, +-32768,-32768, 939,-32768, 994, 1015,-32768 +}; + +static const short yypgoto[] = {-32768, +-32768, 814, 874,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768, 20, 25,-32768,-32768, -370, 19, -7, +-32768, -507,-32768,-32768,-32768, -269, -448, -111, 533, -351, + 751, -261, -346, 760,-32768, 88, -66, -60, -283, 289, + -14, -101, -92, 72, -460,-32768, -55, -147, 529, -487, +-32768, -806, -6, 701,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768, -407,-32768,-32768,-32768, -314,-32768,-32768, +-32768,-32768,-32768,-32768,-32768,-32768,-32768, -692,-32768,-32768, + -524,-32768,-32768, -710, -282,-32768, 512, 641, 12, -365, +-32768,-32768,-32768, 154,-32768,-32768,-32768,-32768,-32768, -40, + -413,-32768,-32768,-32768,-32768,-32768, 185,-32768, -714, -538, +-32768,-32768,-32768, 714, 306, 580,-32768, 375,-32768, 1018, + 71, -125, 724, -244, 711, -42, -210,-32768,-32768, -226, + 365,-32768, 709, -1 +}; + + +#define YYLAST 2119 + + +static const short yytable[] = { 3, + 69, 488, 374, 147, 585, 377, 459, 348, 121, 237, + 541, 489, 511, 224, 280, 221, 340, 623, 859, 90, + 61, 59, 199, 676, 726, 133, 60, 502, 785, 206, + 513, 94, 207, 379, 122, 345, 346, 812, 500, 668, + 212, 190, 143, 376, 267, 144, -427, 516, 168, 454, + 592, 573, 196, 593, 583, 70, 196, -142, 307, 480, + 594, 469, 827, 308, 309, 760, 310, 311, 312, 173, + 91, 179, 182, 182, 169, 197, 225, 299, 189, 247, + 173, 313, 243, 372, 194, 248, 95, 386, 387, 388, + 204, 474, 904, 170, 204, 314, 850, 282, 492, 245, + 493, 196, 501, 219, 279, 244, 179, 182, 182, 517, + 633, 634, 702, 189, 164, 173, 171, 861, 278, 307, + 482, 245, 512, 236, 308, 309, 731, 310, 311, 312, + 170, 479, 615, 219, 584, 520, 705, 297, 96, 627, + 100, 678, 313, 69, 251, 744, 183, 256, 258, 258, + 258, 258, 751, 171, 358, 275, 314, 173, 204, 173, + 194, 163, 283, 61, 59, 163, 164, 327, 699, 60, + 164, 315, 371, 182, 182, 316, 198, 342, -427, 373, + 222, 223, 339, 182, 182, 248, 248, 893, 648, 200, + 756, 246, 276, 245, 800, 692, 164, 597, 301, 130, + 3, 900, 97, 101, 317, 362, 98, 228, 170, 299, + 534, 349, 232, 703, 464, 164, 671, 645, 201, 238, + 470, 259, 260, 261, 679, 327, 329, 801, 170, 600, + 712, 171, 315, 104, 472, 258, 316, 613, 344, 243, + 574, 251, 131, 123, 251, 251, 290, 291, 574, 814, + 595, 700, 239, 213, 286, 525, 292, 293, 835, 836, + 499, 542, 338, 326, 465, 574, 355, 239, 127, 614, + 364, 745, -427, 747, 748, 749, 368, 214, 245, 245, + -427, 248, 327, 128, 329, 129, 301, 575, 466, 792, + 543, 576, 491, 364, 382, 575, 89, 490, 437, 576, + 421, 69, 722, 872, 338, 863, 438, 334, 441, 442, + 134, 120, 575, 420, 125, 793, 576, 69, 794, 461, + 245, 61, 59, 135, 439, 495, 468, 60, 385, 69, + 105, 548, 420, 545, 146, 146, 580, 581, 138, 154, + 251, 329, -427, 155, 767, 251, 680, 256, 536, 795, + 358, 167, 786, 106, 456, 457, 468, 150, 364, 598, + 364, 647, 456, 457, 173, 624, 887, -427, 157, 151, + 625, 191, 468, 359, 465, 659, 508, 245, 377, 456, + 457, 382, 364, 102, 103, 386, 387, 388, 902, 245, + 389, 170, 816, 173, 549, 234, 505, 639, 466, 154, + 152, 194, 153, 155, 201, 802, 226, 142, 636, 285, + 92, 93, 624, 538, 171, 858, 421, 696, 235, 159, + 327, 245, 156, 895, 179, 182, 182, 475, 157, 420, + 476, 189, 298, 173, 160, 452, 555, 556, 557, 558, + 559, 560, 561, 562, 563, 180, 523, 465, 852, 628, + 245, 453, 803, 601, 570, 570, 845, 421, 579, 360, + 219, 219, 170, 564, 164, 567, 380, 510, 869, 524, + 420, 466, 202, 21, 649, 251, 504, 285, 618, 329, + 245, 619, -180, 219, 864, 376, 355, 870, -427, 364, + 24, 192, 173, 195, 611, 508, 616, 693, 546, 547, + 650, 215, 535, 508, 84, 85, 701, 886, 382, 856, + 738, 245, 857, 739, 707, 505, 421, 421, 881, 299, + 740, 219, 882, 505, 866, 883, 87, 867, 771, 420, + 420, 828, 884, 468, 719, 720, 829, 216, 206, 217, + 146, 207, 146, 420, 657, 27, 28, 29, 30, 220, + 32, 681, 33, -168, 205, -173, -193, 322, 323, -174, + 206, -193, -193, 207, -193, -193, -193, 324, 325, 174, + 742, 175, 176, 772, -171, 177, 579, 304, 369, -193, + 616, 184, -175, 185, 186, 755, 173, 187, 616, 227, + 415, 673, 674, -193, -172, 727, 765, 27, 28, 29, + 30, 229, 32, 777, 33, 230, 782, 611, 695, 415, + 208, 139, 778, 779, 140, 616, 642, 141, 644, 421, + -180, 252, 508, 654, 146, 804, 655, 653, 231, 750, + 233, 807, 420, 450, 451, 241, 421, 448, 449, 450, + 451, 253, 505, 254, 824, 897, 898, 468, 262, 420, + 263, 281, 164, 660, 284, 274, 285, 301, 288, 301, + 287, 729, 729, 579, 289, -199, 245, 294, 295, -193, + 304, 305, 318, -193, 306, 327, 677, -177, 320, 330, + -169, 333, 579, 611, 89, 611, 611, 611, -170, 579, + 844, 811, -176, -178, 690, 529, 531, 805, 444, 445, + 446, 447, 448, 449, 450, 451, 415, -179, 616, -180, + 335, 331, 776, 445, 446, 447, 448, 449, 450, 451, + 332, 382, 789, 336, 550, 337, 351, 350, 554, 352, + 307, 579, 773, 353, 329, 308, 309, 365, 310, 311, + 312, 366, 566, 725, 370, 380, 375, 415, 384, 423, + 695, 393, 424, 313, 888, 440, 462, 589, 463, 338, + 736, 382, 453, 471, 478, 822, 485, 314, 219, 494, + 865, 776, 446, 447, 448, 449, 450, 451, 483, 616, + 752, 616, 616, 486, 607, 498, 496, 509, 503, 515, + 521, 773, 533, 526, 522, 841, 766, 539, 527, 540, + 544, 468, 528, 551, 553, 565, 415, 415, 568, 695, + 572, 787, 582, 586, 590, 552, 626, 382, 591, 596, + 415, 421, 617, 622, 630, 632, 776, 629, 616, 468, + 637, 640, 616, 643, 420, 641, 646, 651, 652, 658, + 579, 661, 663, 315, 664, 666, 773, 316, 667, 672, + 669, 682, 706, 683, 732, 686, 662, 691, 697, 693, + 708, 746, 710, 468, 711, 831, 709, 713, 715, 717, + 889, 616, 299, 718, 373, 770, 734, 741, 737, 146, + 743, 808, 146, 759, 753, 754, 758, 764, 781, 783, + 769, 903, 784, 790, 791, 799, 806, 607, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 809, 813, 415, + 810, 815, 817, 818, 825, -2, 4, 826, -427, 5, + 6, 7, 830, 834, 846, 839, 415, 837, 848, 8, + -427, -427, -427, -427, -427, -427, -427, -427, -427, -427, + -427, 820, 838, 843, 9, 10, 11, 847, 851, 12, + 853, -427, -427, -427, 860, 862, 13, 871, 873, 14, + 877, 15, 16, 17, 18, 19, 20, 21, 22, 875, + 878, -427, 481, 607, -427, 607, 607, 607, 892, 23, + 879, 901, 885, 899, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 906, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 907, 303, 53, 54, 242, 455, + 599, 356, 55, 56, 57, 612, 631, -427, 146, 514, + 357, 891, -427, 876, 460, 798, 571, -427, 730, 443, + 444, 445, 446, 447, 448, 449, 450, 451, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 137, 473, 484, + 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, -427, 5, 6, 7, 0, 0, 0, 0, + 0, 0, 0, 8, -427, -427, -427, -427, -427, -427, + -427, -427, -427, -427, -427, 0, 0, 0, 9, 10, + 11, 0, 422, 12, 0, -427, -427, -427, 0, 0, + 13, 415, 0, 14, 0, 15, 16, 17, 18, 19, + 20, 21, 22, 0, 0, -427, 0, 0, -427, 0, + 0, 0, 0, 23, 0, 0, 0, 607, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 0, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 0, 0, + 53, 54, 0, 0, 0, 0, 55, 56, 57, 0, + 4, -427, -427, 5, 6, 7, -427, 0, 0, 0, + 0, -427, 0, 8, -427, -427, -427, -427, -427, -427, + -427, -427, -427, -427, -427, 0, 0, 0, 9, 10, + 11, 0, 0, 12, 0, -427, -427, -427, 0, 0, + 13, 0, 0, 14, 0, 15, 16, 17, 18, 19, + 20, 21, 22, 0, 0, -427, 0, 0, -427, 0, + 0, 0, 0, 23, 0, 0, 0, 0, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 0, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 0, 0, + 53, 54, 0, 0, 0, 0, 55, 56, 57, 0, + 394, -427, 395, 0, 0, 0, -427, 0, 0, 0, + 0, -427, 0, 396, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 0, 0, 0, 397, 0, + 0, 0, -427, 0, 0, 118, 84, 85, 0, 0, + 0, 0, 0, 0, 0, 398, 399, 400, 0, 0, + 0, 401, 402, 0, 0, 403, 0, 0, 87, 404, + 405, 406, 0, 407, 408, 409, 0, 0, 0, 0, + 0, 27, 28, 29, 30, 0, 32, 602, 33, 71, + 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, + 410, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 0, 0, 0, 0, 0, 0, 0, -427, + 0, 0, 83, 84, 85, 0, 0, 0, 0, 411, + 0, 88, 0, 0, 603, 0, 0, 0, 0, 0, + 0, 0, 119, 395, 0, 87, 0, 0, 0, 0, + 0, 0, 0, 0, 396, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 0, 0, 0, 397, + 0, 0, 0, 0, 0, 0, 118, 84, 85, 0, + 0, 0, 0, 0, 0, 0, 398, 399, 400, 0, + 604, 605, 606, 402, 0, 0, 403, 0, 0, 87, + 404, 405, 406, 0, 407, 408, 409, 0, 88, 0, + 0, 0, 27, 28, 29, 30, 0, 32, 0, 33, + 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, + 0, 410, 395, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 396, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 456, 457, 0, 397, 0, + 411, 0, 88, 0, 0, 118, 84, 85, 0, 0, + 0, 0, 0, 0, 0, 398, 399, 400, 0, 0, + 0, 0, 402, 0, 0, 403, 0, 0, 87, 404, + 405, 406, 0, 407, 408, 409, 0, 0, 0, 0, + 0, 27, 28, 29, 30, 0, 32, 0, 33, 71, + 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, + 410, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 264, 83, 84, 85, 0, 0, 0, 0, 411, + 0, 88, 0, 0, 71, 0, 0, 0, 0, 0, + 265, 266, 119, 0, 0, 87, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 0, 0, 71, + 0, 0, 0, 0, 0, 0, 264, 83, 84, 85, + 0, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 0, 0, 0, 265, 266, 119, 0, 0, + 87, 264, 83, 84, 85, 0, 0, 0, 0, 0, + 0, 0, 0, 164, 161, 0, 0, 0, 88, 0, + 265, 266, 119, 0, 0, 87, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 118, 84, 85, + 0, 0, 0, 0, 0, 0, 0, 0, 635, 71, + 124, 0, 0, 88, 0, 0, 0, 162, 0, 0, + 87, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 0, 71, 0, 0, 0, 0, 88, 0, + 0, 0, 83, 84, 85, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 0, 0, 0, 0, + 0, 0, 119, 0, 0, 87, 83, 84, 85, 0, + 0, 0, 0, 163, 0, 0, 0, 0, 164, 71, + 0, 0, 0, 88, 0, 0, 119, 0, 0, 87, + 0, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 307, 83, 84, 85, 0, 308, 309, 0, 310, + 311, 312, 0, 0, 603, 71, 0, 0, 88, 0, + 0, 0, 119, 0, 313, 87, 0, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 314, 71, + 530, 343, 88, 0, 0, 0, 0, 0, 83, 84, + 85, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 0, 71, 0, 0, 0, 0, 86, 0, + 0, 87, 118, 84, 85, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 0, 588, 88, 0, + 0, 0, 119, 0, 0, 87, 83, 84, 85, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 0, 0, 0, 0, 315, 0, 119, 0, 316, 87, + 83, 84, 85, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, + 119, 0, 0, 87, 0, 0, 0, 0, 0, 0, + 0, 307, 0, 0, 0, 0, 308, 309, 88, 310, + 311, 312, 0, 425, 426, 427, 428, 429, 430, 431, + 432, 433, 434, 435, 313, 0, 0, 0, 0, 0, + 0, 0, 88, 0, 436, 84, 85, 0, 314, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 88, 87, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 315, 0, 0, 0, 316 +}; + +static const short yycheck[] = { 1, + 2, 353, 286, 46, 465, 288, 321, 252, 23, 135, + 418, 358, 383, 115, 162, 108, 243, 505, 825, 8, + 2, 2, 89, 29, 27, 33, 2, 374, 721, 7, + 3, 3, 10, 295, 23, 246, 247, 752, 3, 578, + 96, 82, 4, 29, 156, 7, 32, 3, 63, 319, + 29, 459, 3, 32, 32, 4, 3, 26, 3, 343, + 39, 331, 773, 8, 9, 10, 11, 12, 13, 71, + 7, 73, 74, 75, 63, 26, 117, 63, 80, 146, + 82, 26, 3, 26, 86, 146, 58, 60, 61, 62, + 92, 336, 899, 99, 96, 40, 811, 164, 360, 42, + 362, 3, 67, 105, 160, 26, 108, 109, 110, 65, + 518, 519, 620, 115, 117, 117, 122, 828, 159, 3, + 347, 42, 384, 131, 8, 9, 665, 11, 12, 13, + 99, 342, 498, 135, 112, 26, 624, 198, 3, 510, + 26, 590, 26, 145, 146, 684, 75, 149, 150, 151, + 152, 153, 691, 122, 3, 26, 40, 159, 160, 161, + 162, 112, 164, 145, 145, 112, 117, 228, 617, 145, + 117, 116, 284, 175, 176, 120, 89, 244, 32, 122, + 109, 110, 243, 185, 186, 246, 247, 880, 535, 3, + 698, 112, 63, 42, 733, 609, 117, 481, 200, 78, + 202, 894, 3, 3, 211, 272, 7, 120, 99, 63, + 112, 254, 125, 621, 326, 117, 582, 532, 32, 3, + 332, 151, 152, 153, 590, 286, 228, 735, 99, 491, + 638, 122, 116, 3, 3, 237, 120, 36, 245, 3, + 1, 243, 121, 26, 246, 247, 175, 176, 1, 757, + 477, 617, 36, 3, 167, 403, 185, 186, 783, 784, + 372, 3, 26, 26, 39, 1, 268, 36, 3, 68, + 272, 685, 33, 687, 688, 689, 278, 27, 42, 42, + 33, 342, 343, 3, 286, 3, 288, 48, 63, 3, + 32, 52, 359, 295, 296, 48, 8, 358, 313, 52, + 302, 303, 649, 842, 26, 830, 313, 237, 315, 316, + 4, 23, 48, 302, 26, 29, 52, 319, 32, 321, + 42, 303, 303, 3, 313, 366, 328, 303, 3, 331, + 3, 433, 321, 426, 46, 47, 462, 463, 26, 3, + 342, 343, 103, 7, 710, 347, 591, 349, 415, 63, + 3, 63, 723, 26, 115, 116, 358, 7, 360, 485, + 362, 26, 115, 116, 366, 28, 874, 103, 32, 7, + 33, 83, 374, 26, 39, 3, 378, 42, 661, 115, + 116, 383, 384, 19, 20, 60, 61, 62, 896, 42, + 65, 99, 763, 395, 435, 3, 378, 523, 63, 3, + 7, 403, 7, 7, 32, 26, 118, 43, 520, 3, + 3, 4, 28, 415, 122, 823, 418, 33, 26, 3, + 481, 42, 26, 884, 426, 427, 428, 29, 32, 418, + 32, 433, 26, 435, 3, 14, 443, 444, 445, 446, + 447, 448, 449, 450, 451, 15, 3, 39, 819, 510, + 42, 30, 736, 494, 456, 457, 803, 459, 460, 112, + 462, 463, 99, 452, 117, 454, 28, 380, 834, 26, + 459, 63, 32, 52, 535, 477, 3, 3, 26, 481, + 42, 29, 26, 485, 831, 29, 488, 839, 32, 491, + 69, 3, 494, 3, 496, 497, 498, 28, 427, 428, + 26, 3, 415, 505, 37, 38, 618, 873, 510, 29, + 29, 42, 32, 32, 626, 497, 518, 519, 865, 63, + 39, 523, 29, 505, 29, 32, 59, 32, 3, 518, + 519, 28, 39, 535, 646, 647, 33, 32, 7, 39, + 252, 10, 254, 532, 551, 72, 73, 74, 75, 3, + 77, 594, 79, 26, 1, 26, 3, 7, 8, 26, + 7, 8, 9, 10, 11, 12, 13, 27, 28, 15, + 682, 17, 18, 48, 26, 21, 578, 28, 29, 26, + 582, 15, 26, 17, 18, 697, 588, 21, 590, 3, + 302, 28, 29, 40, 26, 662, 708, 72, 73, 74, + 75, 26, 77, 715, 79, 3, 718, 609, 610, 321, + 57, 26, 28, 29, 29, 617, 529, 32, 531, 621, + 26, 32, 624, 29, 336, 737, 32, 540, 3, 690, + 3, 743, 621, 117, 118, 3, 638, 115, 116, 117, + 118, 29, 624, 28, 770, 27, 28, 649, 29, 638, + 29, 3, 117, 566, 26, 33, 3, 659, 3, 661, + 26, 663, 664, 665, 3, 32, 42, 32, 117, 116, + 28, 57, 27, 120, 57, 736, 589, 26, 29, 117, + 26, 3, 684, 685, 396, 687, 688, 689, 26, 691, + 802, 752, 26, 26, 607, 407, 408, 740, 111, 112, + 113, 114, 115, 116, 117, 118, 418, 26, 710, 26, + 28, 27, 714, 112, 113, 114, 115, 116, 117, 118, + 26, 723, 724, 27, 436, 27, 35, 28, 440, 27, + 3, 733, 714, 28, 736, 8, 9, 3, 11, 12, + 13, 3, 454, 656, 32, 28, 117, 459, 117, 3, + 752, 32, 122, 26, 27, 26, 3, 469, 3, 26, + 673, 763, 30, 27, 27, 767, 3, 40, 770, 27, + 831, 773, 113, 114, 115, 116, 117, 118, 33, 781, + 693, 783, 784, 35, 496, 27, 32, 27, 32, 28, + 26, 773, 3, 63, 32, 797, 709, 26, 63, 33, + 3, 803, 63, 27, 3, 7, 518, 519, 26, 811, + 33, 724, 27, 8, 27, 27, 26, 819, 27, 27, + 532, 823, 27, 39, 3, 3, 828, 27, 830, 831, + 3, 3, 834, 3, 823, 32, 26, 67, 117, 27, + 842, 3, 3, 116, 3, 26, 828, 120, 32, 3, + 27, 26, 3, 27, 3, 26, 568, 33, 26, 28, + 26, 3, 27, 865, 27, 778, 33, 27, 26, 26, + 877, 873, 63, 26, 122, 3, 32, 29, 26, 591, + 26, 103, 594, 33, 29, 29, 27, 27, 27, 27, + 33, 898, 27, 29, 27, 27, 27, 609, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 27, 27, 621, + 103, 29, 29, 27, 39, 0, 1, 26, 3, 4, + 5, 6, 27, 27, 27, 26, 638, 29, 27, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 63, 63, 33, 29, 30, 31, 29, 29, 34, + 3, 36, 37, 38, 3, 29, 41, 3, 27, 44, + 26, 46, 47, 48, 49, 50, 51, 52, 53, 29, + 28, 56, 43, 685, 59, 687, 688, 689, 3, 64, + 27, 29, 27, 39, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 0, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 0, 202, 101, 102, 145, 319, + 488, 271, 107, 108, 109, 497, 515, 112, 740, 389, + 271, 878, 117, 849, 321, 730, 457, 122, 664, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 40, 335, 349, + 352, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, -1, 3, 4, 5, 6, -1, -1, -1, -1, + -1, -1, -1, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, -1, -1, -1, 29, 30, + 31, -1, 33, 34, -1, 36, 37, 38, -1, -1, + 41, 823, -1, 44, -1, 46, 47, 48, 49, 50, + 51, 52, 53, -1, -1, 56, -1, -1, 59, -1, + -1, -1, -1, 64, -1, -1, -1, 849, 69, 70, + 71, 72, 73, 74, 75, 76, 77, -1, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, -1, -1, + 101, 102, -1, -1, -1, -1, 107, 108, 109, -1, + 1, 112, 3, 4, 5, 6, 117, -1, -1, -1, + -1, 122, -1, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, -1, -1, -1, 29, 30, + 31, -1, -1, 34, -1, 36, 37, 38, -1, -1, + 41, -1, -1, 44, -1, 46, 47, 48, 49, 50, + 51, 52, 53, -1, -1, 56, -1, -1, 59, -1, + -1, -1, -1, 64, -1, -1, -1, -1, 69, 70, + 71, 72, 73, 74, 75, 76, 77, -1, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, -1, -1, + 101, 102, -1, -1, -1, -1, 107, 108, 109, -1, + 1, 112, 3, -1, -1, -1, 117, -1, -1, -1, + -1, 122, -1, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, -1, -1, -1, 29, -1, + -1, -1, 33, -1, -1, 36, 37, 38, -1, -1, + -1, -1, -1, -1, -1, 46, 47, 48, -1, -1, + -1, 52, 53, -1, -1, 56, -1, -1, 59, 60, + 61, 62, -1, 64, 65, 66, -1, -1, -1, -1, + -1, 72, 73, 74, 75, -1, 77, 1, 79, 3, + -1, -1, 83, 84, -1, -1, -1, -1, -1, -1, + 91, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, -1, -1, -1, -1, -1, -1, -1, 33, + -1, -1, 36, 37, 38, -1, -1, -1, -1, 120, + -1, 122, -1, -1, 48, -1, -1, -1, -1, -1, + -1, -1, 56, 3, -1, 59, -1, -1, -1, -1, + -1, -1, -1, -1, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, -1, -1, -1, 29, + -1, -1, -1, -1, -1, -1, 36, 37, 38, -1, + -1, -1, -1, -1, -1, -1, 46, 47, 48, -1, + 104, 105, 106, 53, -1, -1, 56, -1, -1, 59, + 60, 61, 62, -1, 64, 65, 66, -1, 122, -1, + -1, -1, 72, 73, 74, 75, -1, 77, -1, 79, + -1, -1, -1, 83, 84, -1, -1, -1, -1, -1, + -1, 91, 3, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 115, 116, -1, 29, -1, + 120, -1, 122, -1, -1, 36, 37, 38, -1, -1, + -1, -1, -1, -1, -1, 46, 47, 48, -1, -1, + -1, -1, 53, -1, -1, 56, -1, -1, 59, 60, + 61, 62, -1, 64, 65, 66, -1, -1, -1, -1, + -1, 72, 73, 74, 75, -1, 77, -1, 79, 3, + -1, -1, 83, 84, -1, -1, -1, -1, -1, -1, + 91, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 35, 36, 37, 38, -1, -1, -1, -1, 120, + -1, 122, -1, -1, 3, -1, -1, -1, -1, -1, + 54, 55, 56, -1, -1, 59, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, -1, -1, 3, + -1, -1, -1, -1, -1, -1, 35, 36, 37, 38, + -1, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, -1, -1, -1, 54, 55, 56, -1, -1, + 59, 35, 36, 37, 38, -1, -1, -1, -1, -1, + -1, -1, -1, 117, 3, -1, -1, -1, 122, -1, + 54, 55, 56, -1, -1, 59, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 36, 37, 38, + -1, -1, -1, -1, -1, -1, -1, -1, 117, 3, + 4, -1, -1, 122, -1, -1, -1, 56, -1, -1, + 59, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, -1, 3, -1, -1, -1, -1, 122, -1, + -1, -1, 36, 37, 38, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, + -1, -1, 56, -1, -1, 59, 36, 37, 38, -1, + -1, -1, -1, 112, -1, -1, -1, -1, 117, 3, + -1, -1, -1, 122, -1, -1, 56, -1, -1, 59, + -1, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3, 36, 37, 38, -1, 8, 9, -1, 11, + 12, 13, -1, -1, 48, 3, -1, -1, 122, -1, + -1, -1, 56, -1, 26, 59, -1, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 40, 3, + 120, 43, 122, -1, -1, -1, -1, -1, 36, 37, + 38, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, -1, 3, -1, -1, -1, -1, 56, -1, + -1, 59, 36, 37, 38, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, -1, 3, 122, -1, + -1, -1, 56, -1, -1, 59, 36, 37, 38, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + -1, -1, -1, -1, 116, -1, 56, -1, 120, 59, + 36, 37, 38, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 122, -1, -1, -1, -1, -1, + 56, -1, -1, 59, -1, -1, -1, -1, -1, -1, + -1, 3, -1, -1, -1, -1, 8, 9, 122, 11, + 12, 13, -1, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, -1, -1, -1, -1, -1, + -1, -1, 122, -1, 36, 37, 38, -1, 40, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 122, 59, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 116, -1, -1, -1, 120 +}; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "/usr/local/share/bison.simple" + +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +#ifndef alloca +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) +#include +#else /* not sparc */ +#if defined (MSDOS) && !defined (__TURBOC__) +#include +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include + #pragma alloca +#else /* not MSDOS, __TURBOC__, or _AIX */ +#ifdef __hpux +#ifdef __cplusplus +extern "C" { +void *alloca (unsigned int); +}; +#else /* not __cplusplus */ +void *alloca (); +#endif /* not __cplusplus */ +#endif /* __hpux */ +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc. */ +#endif /* not GNU C. */ +#endif /* alloca not defined. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT return(0) +#define YYABORT return(1) +#define YYERROR goto yyerrlab1 +/* 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); \ + yychar1 = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +#ifndef YYPURE +#define YYLEX yylex() +#endif + +#ifdef YYPURE +#ifdef YYLSP_NEEDED +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval, &yylloc) +#endif +#else /* not YYLSP_NEEDED */ +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval) +#endif +#endif /* not YYLSP_NEEDED */ +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef YYPURE + +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ + +#ifdef YYLSP_NEEDED +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ +#endif + +int yynerrs; /* number of parse errors so far */ +#endif /* not YYPURE */ + +#if YYDEBUG != 0 +int yydebug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif + +/* YYINITDEPTH indicates the initial size of the parser's stacks */ + +#ifndef YYINITDEPTH +#define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#if YYMAXDEPTH == 0 +#undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 10000 +#endif + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +int yyparse (void); +#endif + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (to, from, count) + char *to; + char *from; + int count; +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#else /* __cplusplus */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (char *to, char *from, int count) +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#endif +#endif + +#line 196 "/usr/local/share/bison.simple" + +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef YYPARSE_PARAM +#ifdef __cplusplus +#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#else /* not __cplusplus */ +#define YYPARSE_PARAM_ARG YYPARSE_PARAM +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +#endif /* not __cplusplus */ +#else /* not YYPARSE_PARAM */ +#define YYPARSE_PARAM_ARG +#define YYPARSE_PARAM_DECL +#endif /* not YYPARSE_PARAM */ + +int +yyparse(YYPARSE_PARAM_ARG) + YYPARSE_PARAM_DECL +{ + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + +#ifdef YYLSP_NEEDED + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + +#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#else +#define YYPOPSTACK (yyvsp--, yyssp--) +#endif + + int yystacksize = YYINITDEPTH; + +#ifdef YYPURE + int yychar; + YYSTYPE yylval; + int yynerrs; +#ifdef YYLSP_NEEDED + YYLTYPE yylloc; +#endif +#endif + + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int yylen; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Starting parse\n"); +#endif + + 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 - 1; + yyvsp = yyvs; +#ifdef YYLSP_NEEDED + yylsp = yyls; +#endif + +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: + + *++yyssp = yystate; + + if (yyssp >= yyss + yystacksize - 1) + { + /* 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; + short *yyss1 = yyss; +#ifdef YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; +#endif + + /* Get the current used size of the three stacks, in elements. */ + int size = yyssp - yyss + 1; + +#ifdef yyoverflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef YYLSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yyls1, size * sizeof (*yylsp), + &yystacksize); +#else + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yystacksize); +#endif + + yyss = yyss1; yyvs = yyvs1; +#ifdef YYLSP_NEEDED + yyls = yyls1; +#endif +#else /* no yyoverflow */ + /* Extend the stack our own way. */ + if (yystacksize >= YYMAXDEPTH) + { + yyerror("parser stack overflow"); + return 2; + } + yystacksize *= 2; + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); + __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); + __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp)); +#ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); + __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp)); +#endif +#endif /* no yyoverflow */ + + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; +#ifdef YYLSP_NEEDED + yylsp = yyls + size - 1; +#endif + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yystacksize); +#endif + + if (yyssp >= yyss + yystacksize - 1) + YYABORT; + } + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); +#endif + + goto yybackup; + yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (yychar == YYEMPTY) + { +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Reading a token: "); +#endif + yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); +#endif + } + else + { + yychar1 = YYTRANSLATE(yychar); + +#if YYDEBUG != 0 + if (yydebug) + { + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); +#endif + fprintf (stderr, ")\n"); + } +#endif + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); +#endif + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; + + yystate = yyn; + goto yynewstate; + +/* Do the default action for the current state. */ +yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + +/* Do a reduction. yyn is the number of a rule to reduce with. */ +yyreduce: + yylen = yyr2[yyn]; + if (yylen > 0) + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + +#if YYDEBUG != 0 + if (yydebug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); + + /* Print the symbols being reduced, and their result. */ + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", yytname[yyrhs[i]]); + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } +#endif + + + switch (yyn) { + +case 1: +#line 559 "parser.y" +{ + { + int ii; + for (ii = 0; ii < 256; ii++) { + handler_stack[ii] = 0; + } + handler_stack[0] = comment_handler; + } + doc_stack[0] = doctitle; + ; + break;} +case 2: +#line 568 "parser.y" +{ + CommentHandler::cleanup(); + cplus_cleanup(); + doc_entry = doctitle; + if (lang_init) { + lang->close(); + } + if (te_index) { + fprintf(stderr,"%s : EOF. Missing #endif detected.\n", input_file); + FatalError(); + } + ; + break;} +case 3: +#line 582 "parser.y" +{ + scanner_clear_start(); + Error = 0; + ; + break;} +case 4: +#line 586 "parser.y" +{ + ; + break;} +case 5: +#line 590 "parser.y" +{ + if (allow) { +// init_language(); + doc_entry = 0; + // comment_handler->clear(); + include_file(yyvsp[0].id); + } + ; + break;} +case 6: +#line 601 "parser.y" +{ + if (allow) { + int oldextern = WrapExtern; +// init_language(); + doc_entry = 0; + // comment_handler->clear(); + WrapExtern = 1; + if (include_file(yyvsp[0].id) >= 0) { + add_symbol("SWIGEXTERN",0,0); + } else { + WrapExtern = oldextern; + } + } + ; + break;} +case 7: +#line 618 "parser.y" +{ + if (allow) { + int oldextern = WrapExtern; + init_language(); + doc_entry = 0; + WrapExtern = 1; + if (include_file(yyvsp[0].id) >= 0) { + add_symbol("SWIGEXTERN",0,0); + lang->import(yyvsp[0].id); + } else { + WrapExtern = oldextern; + } + } + ; + break;} +case 8: +#line 636 "parser.y" +{ + if (allow) { + if ((checkout_file(yyvsp[0].id,yyvsp[0].id)) == 0) { + fprintf(stderr,"%s checked out from the SWIG library.\n",yyvsp[0].id); + } + } + ; + break;} +case 9: +#line 646 "parser.y" +{ + if (allow) { + doc_entry = 0; + if (Verbose) { + fprintf(stderr,"%s : Line %d. CPP %s ignored.\n", input_file, line_number,yyvsp[0].id); + } + } + ; + break;} +case 10: +#line 657 "parser.y" +{ + if (allow) { + init_language(); + if (Active_type) delete Active_type; + Active_type = new DataType(yyvsp[-3].type); + Active_extern = yyvsp[-4].ivalue; + yyvsp[-3].type->is_pointer += yyvsp[-2].decl.is_pointer; + if (yyvsp[-1].ivalue > 0) { + yyvsp[-3].type->is_pointer++; + yyvsp[-3].type->status = STAT_READONLY; + yyvsp[-3].type->arraystr = copy_string(ArrayString); + } + if (yyvsp[-2].decl.is_reference) { + fprintf(stderr,"%s : Line %d. Error. Linkage to C++ reference not allowed.\n", input_file, line_number); + FatalError(); + } else { + if (yyvsp[-3].type->qualifier) { + if ((strcmp(yyvsp[-3].type->qualifier,"const") == 0)) { + if (yyvsp[0].dtype.type != T_ERROR) + create_constant(yyvsp[-2].decl.id, yyvsp[-3].type, yyvsp[0].dtype.id); + } else + create_variable(yyvsp[-4].ivalue,yyvsp[-2].decl.id,yyvsp[-3].type); + } else + create_variable(yyvsp[-4].ivalue,yyvsp[-2].decl.id,yyvsp[-3].type); + } + } + delete yyvsp[-3].type; + ; + break;} +case 11: +#line 684 "parser.y" +{ ; + break;} +case 12: +#line 688 "parser.y" +{ + skip_decl(); + fprintf(stderr,"%s : Line %d. Function pointers not currently supported.\n", + input_file, line_number); + ; + break;} +case 13: +#line 696 "parser.y" +{ + if (Verbose) { + fprintf(stderr,"static variable %s ignored.\n",yyvsp[-2].decl.id); + } + Active_static = 1; + delete yyvsp[-3].type; + ; + break;} +case 14: +#line 702 "parser.y" +{ + Active_static = 0; + ; + break;} +case 15: +#line 708 "parser.y" +{ + skip_decl(); + fprintf(stderr,"%s : Line %d. Function pointers not currently supported.\n", + input_file, line_number); + ; + break;} +case 16: +#line 717 "parser.y" +{ + if (allow) { + init_language(); + if (Active_type) delete Active_type; + Active_type = new DataType(yyvsp[-5].type); + Active_extern = yyvsp[-6].ivalue; + yyvsp[-5].type->is_pointer += yyvsp[-4].decl.is_pointer; + yyvsp[-5].type->is_reference = yyvsp[-4].decl.is_reference; + create_function(yyvsp[-6].ivalue, yyvsp[-4].decl.id, yyvsp[-5].type, yyvsp[-2].pl); + } + delete yyvsp[-5].type; + delete yyvsp[-2].pl; + ; + break;} +case 17: +#line 729 "parser.y" +{ ; + break;} +case 18: +#line 733 "parser.y" +{ + if (allow) { + init_language(); + yyvsp[-5].type->is_pointer += yyvsp[-4].decl.is_pointer; + yyvsp[-5].type->is_reference = yyvsp[-4].decl.is_reference; + create_function(yyvsp[-6].ivalue, yyvsp[-4].decl.id, yyvsp[-5].type, yyvsp[-2].pl); + } + delete yyvsp[-5].type; + delete yyvsp[-2].pl; + ; + break;} +case 19: +#line 746 "parser.y" +{ + if (allow) { + init_language(); + DataType *t = new DataType(T_INT); + t->is_pointer += yyvsp[-4].decl.is_pointer; + t->is_reference = yyvsp[-4].decl.is_reference; + create_function(yyvsp[-5].ivalue,yyvsp[-4].decl.id,t,yyvsp[-2].pl); + delete t; + } + ; + break;} +case 20: +#line 755 "parser.y" +{ ; + break;} +case 21: +#line 759 "parser.y" +{ + if ((allow) && (Inline)) { + if (strlen(CCode.get())) { + init_language(); + yyvsp[-5].type->is_pointer += yyvsp[-4].decl.is_pointer; + yyvsp[-5].type->is_reference = yyvsp[-4].decl.is_reference; + create_function(0, yyvsp[-4].decl.id, yyvsp[-5].type, yyvsp[-2].pl); + } + } + delete yyvsp[-5].type; + delete yyvsp[-2].pl; + ; + break;} +case 22: +#line 774 "parser.y" +{ + if (allow) { + init_language(); + yyvsp[-5].type->is_pointer += yyvsp[-4].decl.is_pointer; + yyvsp[-5].type->is_reference = yyvsp[-4].decl.is_reference; + if (Inline) { + fprintf(stderr,"%s : Line %d. Repeated %%inline directive.\n",input_file,line_number); + FatalError(); + } else { + if (strlen(CCode.get())) { + fprintf(f_header,"static "); + emit_extern_func(yyvsp[-4].decl.id,yyvsp[-5].type,yyvsp[-2].pl,3,f_header); + fprintf(f_header,"%s\n",CCode.get()); + } + create_function(0, yyvsp[-4].decl.id, yyvsp[-5].type, yyvsp[-2].pl); + } + } + delete yyvsp[-5].type; + delete yyvsp[-2].pl; + ; + break;} +case 23: +#line 797 "parser.y" +{ + if (allow) { + if (Verbose) { + fprintf(stderr,"static function %s ignored.\n", yyvsp[-4].decl.id); + } + } + Active_static = 1; + delete yyvsp[-5].type; + delete yyvsp[-2].pl; + ; + break;} +case 24: +#line 806 "parser.y" +{ + Active_static = 0; + ; + break;} +case 25: +#line 812 "parser.y" +{ + if (allow) + Status = Status | STAT_READONLY; + ; + break;} +case 26: +#line 819 "parser.y" +{ + if (allow) + Status = Status & ~STAT_READONLY; + ; + break;} +case 27: +#line 825 "parser.y" +{ + if (allow) { + strcpy(yy_rename,yyvsp[-1].id); + Rename_true = 1; + } + ; + break;} +case 28: +#line 833 "parser.y" +{ + if (name_hash.lookup(yyvsp[-2].id)) { + name_hash.remove(yyvsp[-2].id); + } + name_hash.add(yyvsp[-2].id,copy_string(yyvsp[-1].id)); + ; + break;} +case 29: +#line 842 "parser.y" +{ + NewObject = 1; + ; + break;} +case 30: +#line 844 "parser.y" +{ + NewObject = 0; + ; + break;} +case 31: +#line 850 "parser.y" +{ + if (allow) { + fprintf(stderr,"%s : Lind %d. Empty %%name() is no longer supported.\n", + input_file, line_number); + FatalError(); + } + ; + break;} +case 32: +#line 856 "parser.y" +{ + Rename_true = 0; + ; + break;} +case 33: +#line 862 "parser.y" +{ + if (allow && (!WrapExtern)) { + init_language(); + if (add_symbol(yyvsp[-4].id,(DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Name of native function %s conflicts with previous declaration (ignored)\n", + input_file, line_number, yyvsp[-4].id); + } else { + doc_entry = new DocDecl(yyvsp[-4].id,doc_stack[doc_stack_top]); + lang->add_native(yyvsp[-4].id,yyvsp[-1].id); + } + } + ; + break;} +case 34: +#line 874 "parser.y" +{ + if (allow && (!WrapExtern)) { + init_language(); + yyvsp[-5].type->is_pointer += yyvsp[-4].decl.is_pointer; + if (add_symbol(yyvsp[-8].id,(DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Name of native function %s conflicts with previous declaration (ignored)\n", + input_file, line_number, yyvsp[-8].id); + } else { + if (yyvsp[-6].ivalue) { + emit_extern_func(yyvsp[-4].decl.id, yyvsp[-5].type, yyvsp[-2].pl, yyvsp[-6].ivalue, f_header); + } + doc_entry = new DocDecl(yyvsp[-8].id,doc_stack[doc_stack_top]); + lang->add_native(yyvsp[-8].id,yyvsp[-4].decl.id); + } + } + delete yyvsp[-5].type; + delete yyvsp[-2].pl; + ; + break;} +case 35: +#line 895 "parser.y" +{ + if (allow && (!WrapExtern)) { + if (!title_init) { + title_init = 1; + doc_init = 1; + if (!comment_handler) { + comment_handler = new CommentHandler(); + } + { + int ii; + for (ii = 0; ii < yyvsp[0].dlist.count; ii++) { + comment_handler->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + } + } + // Create a new title for documentation + { + int temp = line_number; + line_number = yyvsp[-2].ivalue; + if (!doctitle) + doctitle = new DocTitle(yyvsp[-1].id,0); + else { + doctitle->name = copy_string(title); + doctitle->line_number = yyvsp[-2].ivalue; + doctitle->end_line = yyvsp[-2].ivalue; + } + line_number = temp; + } + doctitle->usage = yyvsp[-1].id; + doc_entry = doctitle; + doc_stack[0] = doc_entry; + doc_stack_top = 0; + handler_stack[0] = comment_handler; + { + int ii; + for (ii = 0; ii < yyvsp[0].dlist.count; ii++) { + doc_stack[doc_stack_top]->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + } + } + + } else { + // Ignore it + } + } + ; + break;} +case 36: +#line 943 "parser.y" +{ + if (allow && (!WrapExtern) && (!IgnoreDoc)) { + // Copy old comment handler + // if (handler_stack[1]) delete handler_stack[1]; + handler_stack[1] = new CommentHandler(handler_stack[0]); + comment_handler = handler_stack[1]; + { + int ii; + for (ii = 0; ii < yyvsp[0].dlist.count; ii++) { + comment_handler->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + } + } + { + int temp = line_number; + line_number = yyvsp[-2].ivalue; + doc_entry = new DocSection(yyvsp[-1].id,doc_stack[0]); + line_number = temp; + } + doc_stack_top = 1; + doc_stack[1] = doc_entry; + { + int ii; + for (ii = 0; ii < yyvsp[0].dlist.count; ii++) { + doc_stack[doc_stack_top]->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + } + } + } + ; + break;} +case 37: +#line 973 "parser.y" +{ + if (allow && (!WrapExtern) && (!IgnoreDoc)) { + if (doc_stack_top < 1) { + fprintf(stderr,"%s : Line %d. Can't apply %%subsection here.\n", input_file,line_number); + FatalError(); + } else { + + // Copy old comment handler + // if (handler_stack[2]) delete handler_stack[2]; + handler_stack[2] = new CommentHandler(handler_stack[1]); + comment_handler = handler_stack[2]; + { + int ii; + for (ii = 0; ii < yyvsp[0].dlist.count; ii++) { + comment_handler->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + } + } + { + int temp = line_number; + line_number = yyvsp[-2].ivalue; + doc_entry = new DocSection(yyvsp[-1].id,doc_stack[1]); + line_number = temp; + } + doc_stack_top = 2; + doc_stack[2] = doc_entry; + { + int ii; + for (ii = 0; ii < yyvsp[0].dlist.count; ii++) { + doc_stack[doc_stack_top]->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + } + } + } + } + ; + break;} +case 38: +#line 1009 "parser.y" +{ + if (allow && (!WrapExtern) && (!IgnoreDoc)) { + if (doc_stack_top < 2) { + fprintf(stderr,"%s : Line %d. Can't apply %%subsubsection here.\n", input_file,line_number); + FatalError(); + } else { + + // Copy old comment handler + + // if (handler_stack[3]) delete handler_stack[3]; + handler_stack[3] = new CommentHandler(handler_stack[2]); + comment_handler = handler_stack[3]; + { + int ii; + for (ii = 0; ii < yyvsp[0].dlist.count; ii++) { + comment_handler->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + } + } + { + int temp = line_number; + line_number = yyvsp[-2].ivalue; + doc_entry = new DocSection(yyvsp[-1].id,doc_stack[2]); + line_number = temp; + } + doc_stack_top = 3; + doc_stack[3] = doc_entry; + { + int ii; + for (ii = 0; ii < yyvsp[0].dlist.count; ii++) { + doc_stack[doc_stack_top]->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + } + } + } + } + ; + break;} +case 39: +#line 1046 "parser.y" +{ + if (allow && (!WrapExtern)) { + fprintf(stderr,"%%alpha directive is obsolete. Use '%%style sort' instead.\n"); + handler_stack[0]->style("sort",0); + doc_stack[0]->style("sort",0); + } + ; + break;} +case 40: +#line 1054 "parser.y" +{ + if (allow && (!WrapExtern)) { + fprintf(stderr,"%%raw directive is obsolete. Use '%%style nosort' instead.\n"); + handler_stack[0]->style("nosort",0); + doc_stack[0]->style("nosort",0); + } + ; + break;} +case 41: +#line 1062 "parser.y" +{ ; + break;} +case 42: +#line 1066 "parser.y" +{ + if (allow && (!WrapExtern)) { + yyvsp[0].id[strlen(yyvsp[0].id) - 1] = 0; + doc_entry = new DocText(yyvsp[0].id,doc_stack[doc_stack_top]); + doc_entry = 0; + } + ; + break;} +case 43: +#line 1075 "parser.y" +{ ; + break;} +case 44: +#line 1079 "parser.y" +{ + if (allow && (!WrapExtern)) { + init_language(); + yyvsp[0].id[strlen(yyvsp[0].id) - 1] = 0; +// fprintf(f_header,"#line %d \"%s\"\n", start_line, input_file); + fprintf(f_header, "%s\n", yyvsp[0].id); + } + ; + break;} +case 45: +#line 1090 "parser.y" +{ + if (allow && (!WrapExtern)) { + init_language(); + yyvsp[0].id[strlen(yyvsp[0].id) - 1] = 0; + fprintf(f_wrappers,"%s\n",yyvsp[0].id); + } + ; + break;} +case 46: +#line 1100 "parser.y" +{ + if (allow && (!WrapExtern)) { + init_language(); + yyvsp[0].id[strlen(yyvsp[0].id) -1] = 0; + fprintf(f_init,"%s\n", yyvsp[0].id); + } + ; + break;} +case 47: +#line 1109 "parser.y" +{ + if (allow && (!WrapExtern)) { + init_language(); + yyvsp[0].id[strlen(yyvsp[0].id) - 1] = 0; + fprintf(f_header, "%s\n", yyvsp[0].id); + start_inline(yyvsp[0].id,start_line); + } + ; + break;} +case 48: +#line 1119 "parser.y" +{ + if (allow && (!WrapExtern)) { + fprintf(stderr,"%s\n", yyvsp[0].id); + } + ; + break;} +case 49: +#line 1125 "parser.y" +{ + if (allow && (!WrapExtern)) { + fprintf(stderr,"%s\n", yyvsp[0].id); + } + ; + break;} +case 50: +#line 1132 "parser.y" +{ + DocOnly = 1; + ; + break;} +case 51: +#line 1138 "parser.y" +{ + if (allow) { + if (!module_init) { + lang->set_init(yyvsp[-1].id); + module_init = 1; + init_language(); + } else { + if (Verbose) + fprintf(stderr,"%s : Line %d. %%init %s ignored.\n", + input_file, line_number, yyvsp[-1].id); + } + if (yyvsp[0].ilist.count > 0) { + fprintf(stderr,"%s : Line %d. Warning. Init list no longer supported.\n", + input_file,line_number); + } + } + for (i = 0; i < yyvsp[0].ilist.count; i++) + if (yyvsp[0].ilist.names[i]) delete [] yyvsp[0].ilist.names[i]; + delete [] yyvsp[0].ilist.names; + ; + break;} +case 52: +#line 1160 "parser.y" +{ + if (allow) { + if (yyvsp[0].ilist.count) + lang->set_module(yyvsp[-1].id,yyvsp[0].ilist.names); + else + lang->set_module(yyvsp[-1].id,0); + module_init = 1; + init_language(); + } + for (i = 0; i < yyvsp[0].ilist.count; i++) + if (yyvsp[0].ilist.names[i]) delete [] yyvsp[0].ilist.names[i]; + delete [] yyvsp[0].ilist.names; + ; + break;} +case 53: +#line 1176 "parser.y" +{ + if (allow) { + if ((yyvsp[0].dtype.type != T_ERROR) && (yyvsp[0].dtype.type != T_SYMBOL)) { + init_language(); + temp_typeptr = new DataType(yyvsp[0].dtype.type); + create_constant(yyvsp[-1].id, temp_typeptr, yyvsp[0].dtype.id); + delete temp_typeptr; + } else if (yyvsp[0].dtype.type == T_SYMBOL) { + // Add a symbol to the SWIG symbol table + if (add_symbol(yyvsp[-1].id,(DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Warning. Symbol %s already defined.\n", + input_file,line_number, yyvsp[-1].id); + } + } + } + ; + break;} +case 54: +#line 1195 "parser.y" +{ + if (Verbose) { + fprintf(stderr,"%s : Line %d. CPP Macro ignored.\n", input_file, line_number); + } + ; + break;} +case 55: +#line 1202 "parser.y" +{ + remove_symbol(yyvsp[0].id); + ; + break;} +case 56: +#line 1208 "parser.y" +{ scanner_clear_start(); ; + break;} +case 57: +#line 1208 "parser.y" +{ + if (allow) { + init_language(); + if (yyvsp[-5].id) { + temp_type.type = T_INT; + temp_type.is_pointer = 0; + temp_type.implicit_ptr = 0; + sprintf(temp_type.name,"int"); + temp_type.typedef_add(yyvsp[-5].id,1); + } + } + ; + break;} +case 58: +#line 1223 "parser.y" +{ scanner_clear_start(); ; + break;} +case 59: +#line 1223 "parser.y" +{ + if (allow) { + init_language(); + temp_type.type = T_INT; + temp_type.is_pointer = 0; + temp_type.implicit_ptr = 0; + sprintf(temp_type.name,"int"); + Active_typedef = new DataType(&temp_type); + temp_type.typedef_add(yyvsp[0].id,1); + } + ; + break;} +case 60: +#line 1233 "parser.y" +{ ; + break;} +case 61: +#line 1243 "parser.y" +{ + TMParm *p; + skip_brace(); + p = yyvsp[-1].tmparm; + while (p) { + typemap_register(yyvsp[-3].id,yyvsp[-5].id,p->p->t,p->p->name,CCode,p->args); + p = p->next; + } + delete yyvsp[-5].id; + delete yyvsp[-3].id; + ; + break;} +case 62: +#line 1256 "parser.y" +{ + if (!typemap_lang) { + fprintf(stderr,"SWIG internal error. No typemap_lang specified.\n"); + fprintf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number); + FatalError(); + } else { + TMParm *p; + skip_brace(); + p = yyvsp[-1].tmparm; + while (p) { + typemap_register(yyvsp[-3].id,typemap_lang,p->p->t,p->p->name,CCode,p->args); + p = p->next; + } + } + delete yyvsp[-3].id; + ; + break;} +case 63: +#line 1275 "parser.y" +{ + TMParm *p; + p = yyvsp[-1].tmparm; + while (p) { + typemap_clear(yyvsp[-3].id,yyvsp[-5].id,p->p->t,p->p->name); + p = p->next; + } + delete yyvsp[-5].id; + delete yyvsp[-3].id; + ; + break;} +case 64: +#line 1287 "parser.y" +{ + if (!typemap_lang) { + fprintf(stderr,"SWIG internal error. No typemap_lang specified.\n"); + fprintf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number); + FatalError(); + } else { + TMParm *p; + p = yyvsp[-1].tmparm; + while (p) { + typemap_clear(yyvsp[-3].id,typemap_lang,p->p->t,p->p->name); + p = p->next; + } + } + delete yyvsp[-3].id; + ; + break;} +case 65: +#line 1305 "parser.y" +{ + TMParm *p; + p = yyvsp[-3].tmparm; + while (p) { + typemap_copy(yyvsp[-5].id,yyvsp[-7].id,yyvsp[-1].tmparm->p->t,yyvsp[-1].tmparm->p->name,p->p->t,p->p->name); + p = p->next; + } + delete yyvsp[-7].id; + delete yyvsp[-5].id; + delete yyvsp[-1].tmparm->p; + delete yyvsp[-1].tmparm; + ; + break;} +case 66: +#line 1320 "parser.y" +{ + if (!typemap_lang) { + fprintf(stderr,"SWIG internal error. No typemap_lang specified.\n"); + fprintf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number); + FatalError(); + } else { + TMParm *p; + p = yyvsp[-3].tmparm; + while (p) { + typemap_copy(yyvsp[-5].id,typemap_lang,yyvsp[-1].tmparm->p->t,yyvsp[-1].tmparm->p->name,p->p->t,p->p->name); + p = p->next; + } + } + delete yyvsp[-5].id; + delete yyvsp[-1].tmparm->p; + delete yyvsp[-1].tmparm; + ; + break;} +case 67: +#line 1341 "parser.y" +{ + TMParm *p; + p = yyvsp[-1].tmparm; + while(p) { + typemap_apply(yyvsp[-3].tmparm->p->t,yyvsp[-3].tmparm->p->name,p->p->t,p->p->name); + p = p->next; + } + delete yyvsp[-1].tmparm; + delete yyvsp[-3].tmparm->args; + delete yyvsp[-3].tmparm; + ; + break;} +case 68: +#line 1352 "parser.y" +{ + TMParm *p; + p = yyvsp[-1].tmparm; + while (p) { + typemap_clear_apply(p->p->t, p->p->name); + p = p->next; + } + ; + break;} +case 69: +#line 1369 "parser.y" +{ + skip_brace(); + fragment_register("except",yyvsp[-2].id, CCode); + delete yyvsp[-2].id; + ; + break;} +case 70: +#line 1376 "parser.y" +{ + skip_brace(); + fragment_register("except",typemap_lang, CCode); + ; + break;} +case 71: +#line 1383 "parser.y" +{ + fragment_clear("except",yyvsp[-2].id); + ; + break;} +case 72: +#line 1388 "parser.y" +{ + fragment_clear("except",typemap_lang); + ; + break;} +case 73: +#line 1394 "parser.y" +{ ; + break;} +case 74: +#line 1395 "parser.y" +{ ; + break;} +case 75: +#line 1396 "parser.y" +{ ; + break;} +case 76: +#line 1397 "parser.y" +{ + if (!Error) { + { + static int last_error_line = -1; + if (last_error_line != line_number) { + fprintf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); + FatalError(); + last_error_line = line_number; + // Try to make some kind of recovery. + skip_decl(); + } + Error = 1; + } + } + ; + break;} +case 77: +#line 1415 "parser.y" +{ ; + break;} +case 78: +#line 1416 "parser.y" +{ ; + break;} +case 79: +#line 1420 "parser.y" +{ ; + break;} +case 80: +#line 1424 "parser.y" +{ + { + int ii,jj; + for (ii = 0; ii < yyvsp[0].dlist.count; ii++) { + comment_handler->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + for (jj = 0; jj < doc_stack_top; jj++) + doc_stack[jj]->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + if (doctitle) + doctitle->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + doc->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + } + } + ; + break;} +case 81: +#line 1440 "parser.y" +{ + { + int ii; + for (ii = 0; ii < yyvsp[0].dlist.count; ii++) { + comment_handler = new CommentHandler(comment_handler); + handler_stack[doc_stack_top] = comment_handler; + comment_handler->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + doc_stack[doc_stack_top]->style(yyvsp[0].dlist.names[ii],yyvsp[0].dlist.values[ii]); + } + } + ; + break;} +case 82: +#line 1453 "parser.y" +{ ; + break;} +case 83: +#line 1459 "parser.y" +{ + if (allow) { + if (IgnoreDoc) { + /* Already in a disabled documentation */ + doc_scope++; + } else { + if (Verbose) + fprintf(stderr,"%s : Line %d. Documentation disabled.\n", input_file, line_number); + IgnoreDoc = 1; + doc_scope = 1; + } + } + ; + break;} +case 84: +#line 1473 "parser.y" +{ + if (allow) { + if (IgnoreDoc) { + if (doc_scope > 1) { + doc_scope--; + } else { + if (Verbose) + fprintf(stderr,"%s : Line %d. Documentation enabled.\n", input_file, line_number); + IgnoreDoc = 0; + doc_scope = 0; + } + } + } + ; + break;} +case 85: +#line 1492 "parser.y" +{ + if (allow) { + init_language(); + /* Add a new typedef */ + Active_typedef = new DataType(yyvsp[-1].type); + yyvsp[-1].type->is_pointer += yyvsp[0].decl.is_pointer; + yyvsp[-1].type->typedef_add(yyvsp[0].decl.id); + /* If this is %typedef, add it to the header */ + if (yyvsp[-2].ivalue) + fprintf(f_header,"typedef %s %s;\n", yyvsp[-1].type->print_full(), yyvsp[0].decl.id); + cplus_register_type(yyvsp[0].decl.id); + } + ; + break;} +case 86: +#line 1504 "parser.y" +{ ; + break;} +case 87: +#line 1508 "parser.y" +{ + if (allow) { + init_language(); + /* Typedef'd pointer */ + if (yyvsp[-9].ivalue) { + sprintf(temp_name,"(*%s)",yyvsp[-5].id); + fprintf(f_header,"typedef "); + emit_extern_func(temp_name, yyvsp[-8].type,yyvsp[-2].pl,0,f_header); + } + strcpy(yyvsp[-8].type->name,""); + yyvsp[-8].type->type = T_USER; + yyvsp[-8].type->is_pointer = 1; + yyvsp[-8].type->typedef_add(yyvsp[-5].id,1); + cplus_register_type(yyvsp[-5].id); + } + delete yyvsp[-8].type; + delete yyvsp[-5].id; + delete yyvsp[-2].pl; + ; + break;} +case 88: +#line 1530 "parser.y" +{ + if (allow) { + init_language(); + if (yyvsp[-10].ivalue) { + yyvsp[-9].type->is_pointer += yyvsp[-8].ivalue; + sprintf(temp_name,"(*%s)",yyvsp[-5].id); + fprintf(f_header,"typedef "); + emit_extern_func(temp_name, yyvsp[-9].type,yyvsp[-2].pl,0,f_header); + } + + /* Typedef'd pointer */ + strcpy(yyvsp[-9].type->name,""); + yyvsp[-9].type->type = T_USER; + yyvsp[-9].type->is_pointer = 1; + yyvsp[-9].type->typedef_add(yyvsp[-5].id,1); + cplus_register_type(yyvsp[-5].id); + } + delete yyvsp[-9].type; + delete yyvsp[-5].id; + delete yyvsp[-2].pl; + ; + break;} +case 89: +#line 1554 "parser.y" +{ + if (allow) { + init_language(); + Active_typedef = new DataType(yyvsp[-2].type); + // This datatype is going to be readonly + + yyvsp[-2].type->status = STAT_READONLY | STAT_REPLACETYPE; + yyvsp[-2].type->is_pointer += yyvsp[-1].decl.is_pointer; + // Turn this into a "pointer" corresponding to the array + yyvsp[-2].type->is_pointer++; + yyvsp[-2].type->arraystr = copy_string(ArrayString); + yyvsp[-2].type->typedef_add(yyvsp[-1].decl.id); + fprintf(stderr,"%s : Line %d. Warning. Array type %s will be read-only without a typemap\n",input_file,line_number, yyvsp[-1].decl.id); + cplus_register_type(yyvsp[-1].decl.id); + + } + ; + break;} +case 90: +#line 1570 "parser.y" +{ ; + break;} +case 91: +#line 1583 "parser.y" +{ + if (allow) { + if (Active_typedef) { + DataType *t; + t = new DataType(Active_typedef); + t->is_pointer += yyvsp[-1].decl.is_pointer; + t->typedef_add(yyvsp[-1].decl.id); + cplus_register_type(yyvsp[-1].decl.id); + delete t; + } + } + ; + break;} +case 92: +#line 1595 "parser.y" +{ + DataType *t; + t = new DataType(Active_typedef); + t->status = STAT_READONLY | STAT_REPLACETYPE; + t->is_pointer += yyvsp[-1].decl.is_pointer + 1; + t->arraystr = copy_string(ArrayString); + t->typedef_add(yyvsp[-1].decl.id); + cplus_register_type(yyvsp[-1].decl.id); + delete t; + fprintf(stderr,"%s : Line %d. Warning. Array type %s will be read-only without a typemap.\n",input_file,line_number, yyvsp[-1].decl.id); + ; + break;} +case 93: +#line 1606 "parser.y" +{ ; + break;} +case 94: +#line 1626 "parser.y" +{ + /* Push old if-then-else status */ + if_push(); + /* Look a symbol up in the symbol table */ + if (lookup_symbol(yyvsp[0].id)) { + in_then = 1; + in_else = 0; + allow = 1 & prev_allow; + } else { + /* Condition is false. Skip over whatever is in this block */ + in_else = skip_cond(1); + if (in_else == -1) { + /* Unrecoverable error */ + SWIG_exit(1); + } + if (!in_else) { + if_pop(); // Pop out. Reached end of block + } else { + allow = prev_allow; + in_then = 0; + } + } + ; + break;} +case 95: +#line 1652 "parser.y" +{ + if_push(); + if (lookup_symbol(yyvsp[0].id)) { + /* Condition is false. Skip over whatever is in this block */ + in_else = skip_cond(1); + if (in_else == -1) { + /* Unrecoverable error */ + SWIG_exit(1); + } + if (!in_else) { + if_pop(); // Pop out. Reached end of block + } else { + allow = prev_allow; + in_then = 0; + } + } else { + in_then = 1; + in_else = 0; + allow = 1 & prev_allow; + } + ; + break;} +case 96: +#line 1675 "parser.y" +{ + if ((!in_then) || (in_else)) { + fprintf(stderr,"%s : Line %d. Misplaced else\n", input_file, line_number); + FatalError(); + } else { + in_then = 0; + in_else = 1; + if (allow) { + allow = 0; + /* Skip over rest of the conditional */ + skip_cond(0); + if_pop(); + } else { + allow = 1; + } + allow = allow & prev_allow; + } + ; + break;} +case 97: +#line 1694 "parser.y" +{ + if ((!in_then) && (!in_else)) { + fprintf(stderr,"%s : Line %d. Misplaced endif\n", input_file, line_number); + FatalError(); + } else { + if_pop(); + } + ; + break;} +case 98: +#line 1704 "parser.y" +{ + /* Push old if-then-else status */ + if_push(); + if (yyvsp[0].ivalue) { + in_then = 1; + in_else = 0; + allow = 1 & prev_allow; + } else { + /* Condition is false. Skip over whatever is in this block */ + in_else = skip_cond(1); + if (in_else == -1) { + /* Unrecoverable error */ + SWIG_exit(1); + } + if (!in_else) { + if_pop(); // Pop out. Reached end of block + } else { + allow = prev_allow; + in_then = 0; + } + } + ; + break;} +case 99: +#line 1730 "parser.y" +{ + /* have to pop old if clause off */ + if_pop(); + + /* Push old if-then-else status */ + if_push(); + if (yyvsp[0].ivalue) { + in_then = 1; + in_else = 0; + allow = 1 & prev_allow; + } else { + /* Condition is false. Skip over whatever is in this block */ + in_else = skip_cond(1); + if (in_else == -1) { + /* Unrecoverable error */ + SWIG_exit(1); + } + if (!in_else) { + if_pop(); // Pop out. Reached end of block + } else { + allow = prev_allow; + in_then = 0; + } + } + ; + break;} +case 100: +#line 1759 "parser.y" +{ + + /* Look ID up in the symbol table */ + if (lookup_symbol(yyvsp[-1].id)) { + yyval.ivalue = 1; + } else { + yyval.ivalue = 0; + } + ; + break;} +case 101: +#line 1768 "parser.y" +{ + if (lookup_symbol(yyvsp[0].id)) { + yyval.ivalue = 1; + } else { + yyval.ivalue = 0; + } + ; + break;} +case 102: +#line 1775 "parser.y" +{ + if (yyvsp[0].ivalue) yyval.ivalue = 0; + else yyval.ivalue = 1; + ; + break;} +case 103: +#line 1781 "parser.y" +{ + if (allow && (!WrapExtern)) + lang->pragma(yyvsp[-4].id,yyvsp[-2].id,yyvsp[-1].id); + fprintf(stderr,"%s : Line %d. Warning. '%%pragma(lang,opt=value)' syntax is obsolete.\n", + input_file,line_number); + fprintf(stderr," Use '%%pragma(lang) opt=value' instead.\n"); + ; + break;} +case 104: +#line 1789 "parser.y" +{ + if (allow && (!WrapExtern)) + swig_pragma(yyvsp[-1].id,yyvsp[0].id); + ; + break;} +case 105: +#line 1793 "parser.y" +{ + if (allow && (!WrapExtern)) + lang->pragma(yyvsp[-3].id,yyvsp[-1].id,yyvsp[0].id); + ; + break;} +case 106: +#line 1801 "parser.y" +{ ; + break;} +case 107: +#line 1802 "parser.y" +{ + if (allow) { + init_language(); + temp_typeptr = new DataType(Active_type); + temp_typeptr->is_pointer += yyvsp[-2].decl.is_pointer; + if (yyvsp[-1].ivalue > 0) { + temp_typeptr->is_pointer++; + temp_typeptr->status = STAT_READONLY; + temp_typeptr->arraystr = copy_string(ArrayString); + } + if (yyvsp[-2].decl.is_reference) { + fprintf(stderr,"%s : Line %d. Error. Linkage to C++ reference not allowed.\n", input_file, line_number); + FatalError(); + } else { + if (temp_typeptr->qualifier) { + if ((strcmp(temp_typeptr->qualifier,"const") == 0)) { + /* Okay. This is really some sort of C++ constant here. */ + if (yyvsp[0].dtype.type != T_ERROR) + create_constant(yyvsp[-2].decl.id, temp_typeptr, yyvsp[0].dtype.id); + } else + create_variable(Active_extern,yyvsp[-2].decl.id, temp_typeptr); + } else + create_variable(Active_extern, yyvsp[-2].decl.id, temp_typeptr); + } + delete temp_typeptr; + } + ; + break;} +case 108: +#line 1828 "parser.y" +{ ; + break;} +case 109: +#line 1829 "parser.y" +{ + if (allow) { + init_language(); + temp_typeptr = new DataType(Active_type); + temp_typeptr->is_pointer += yyvsp[-4].decl.is_pointer; + temp_typeptr->is_reference = yyvsp[-4].decl.is_reference; + create_function(Active_extern, yyvsp[-4].decl.id, temp_typeptr, yyvsp[-2].pl); + delete temp_typeptr; + } + delete yyvsp[-2].pl; + ; + break;} +case 110: +#line 1839 "parser.y" +{ ; + break;} +case 111: +#line 1842 "parser.y" +{ + yyval.dtype = yyvsp[-1].dtype; + ; + break;} +case 112: +#line 1845 "parser.y" +{ + yyval.dtype.type = T_SYMBOL; + ; + break;} +case 113: +#line 1848 "parser.y" +{ + if (Verbose) + fprintf(stderr,"%s : Line %d. Warning. Unable to parse #define (ignored)\n", input_file, line_number); + yyval.dtype.type = T_ERROR; + ; + break;} +case 114: +#line 1856 "parser.y" +{ yyval.ivalue = 1; ; + break;} +case 115: +#line 1857 "parser.y" +{yyval.ivalue = 0; ; + break;} +case 116: +#line 1858 "parser.y" +{ + if (strcmp(yyvsp[0].id,"C") == 0) { + yyval.ivalue = 2; + } else { + fprintf(stderr,"%s : Line %d. Unrecognized extern type \"%s\" (ignored).\n", input_file, line_number, yyvsp[0].id); + FatalError(); + } + ; + break;} +case 117: +#line 1870 "parser.y" +{ skip_brace(); ; + break;} +case 118: +#line 1879 "parser.y" +{ + if ((yyvsp[-1].p->t->type != T_VOID) || (yyvsp[-1].p->t->is_pointer)) + yyvsp[0].pl->insert(yyvsp[-1].p,0); + yyval.pl = yyvsp[0].pl; + delete yyvsp[-1].p; + ; + break;} +case 119: +#line 1885 "parser.y" +{ yyval.pl = new ParmList;; + break;} +case 120: +#line 1888 "parser.y" +{ + yyvsp[0].pl->insert(yyvsp[-1].p,0); + yyval.pl = yyvsp[0].pl; + delete yyvsp[-1].p; + ; + break;} +case 121: +#line 1893 "parser.y" +{ yyval.pl = new ParmList;; + break;} +case 122: +#line 1896 "parser.y" +{ + yyval.p = yyvsp[0].p; + if (typemap_check("ignore",typemap_lang,yyval.p->t,yyval.p->name)) + yyval.p->ignore = 1; + ; + break;} +case 123: +#line 1901 "parser.y" +{ + yyval.p = yyvsp[0].p; + yyval.p->call_type = yyval.p->call_type | yyvsp[-1].ivalue; + if (InArray && (yyval.p->call_type & CALL_VALUE)) { + fprintf(stderr,"%s : Line %d. Error. Can't use %%val with an array.\n", input_file, line_number); + FatalError(); + } + if (!yyval.p->t->is_pointer) { + fprintf(stderr,"%s : Line %d. Error. Can't use %%val or %%out with a non-pointer argument.\n", input_file, line_number); + FatalError(); + } else { + yyval.p->t->is_pointer--; + } + ; + break;} +case 124: +#line 1916 "parser.y" +{ + if (InArray) { + yyvsp[-1].type->is_pointer++; + if (Verbose) { + fprintf(stderr,"%s : Line %d. Warning. Array %s", input_file, line_number, yyvsp[-1].type->print_type()); + print_array(); + fprintf(stderr," has been converted to %s.\n", yyvsp[-1].type->print_type()); + } + // Add array string to the type + yyvsp[-1].type->arraystr = copy_string(ArrayString.get()); + } + yyval.p = new Parm(yyvsp[-1].type,yyvsp[0].id); + yyval.p->call_type = 0; + yyval.p->defvalue = DefArg; + if ((yyvsp[-1].type->type == T_USER) && !(yyvsp[-1].type->is_pointer)) { + if (Verbose) + fprintf(stderr,"%s : Line %d. Warning : Parameter of type '%s'\nhas been remapped to '%s *' and will be called using *((%s *) ptr).\n", + input_file, line_number, yyvsp[-1].type->name, yyvsp[-1].type->name, yyvsp[-1].type->name); + + yyval.p->call_type = CALL_REFERENCE; + yyval.p->t->is_pointer++; + } + delete yyvsp[-1].type; + delete yyvsp[0].id; + ; + break;} +case 125: +#line 1942 "parser.y" +{ + yyval.p = new Parm(yyvsp[-2].type,yyvsp[0].id); + yyval.p->t->is_pointer += yyvsp[-1].ivalue; + yyval.p->call_type = 0; + yyval.p->defvalue = DefArg; + if (InArray) { + yyval.p->t->is_pointer++; + if (Verbose) { + fprintf(stderr,"%s : Line %d. Warning. Array %s", input_file, line_number, yyval.p->t->print_type()); + print_array(); + fprintf(stderr," has been converted to %s.\n", yyval.p->t->print_type()); + } + // Add array string to the type + yyval.p->t->arraystr = copy_string(ArrayString.get()); + } + delete yyvsp[-2].type; + delete yyvsp[0].id; + ; + break;} +case 126: +#line 1961 "parser.y" +{ + yyval.p = new Parm(yyvsp[-2].type,yyvsp[0].id); + yyval.p->t->is_reference = 1; + yyval.p->call_type = 0; + yyval.p->t->is_pointer++; + yyval.p->defvalue = DefArg; + if (!CPlusPlus) { + fprintf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); + } + delete yyvsp[-2].type; + delete yyvsp[0].id; + ; + break;} +case 127: +#line 1973 "parser.y" +{ + fprintf(stderr,"%s : Line %d. Error. Function pointer not allowed (remap with typedef).\n", input_file, line_number); + FatalError(); + yyval.p = new Parm(yyvsp[-7].type,yyvsp[-4].id); + yyval.p->t->type = T_ERROR; + yyval.p->name = copy_string(yyvsp[-4].id); + strcpy(yyval.p->t->name,""); + delete yyvsp[-7].type; + delete yyvsp[-4].id; + delete yyvsp[-1].pl; + ; + break;} +case 128: +#line 1984 "parser.y" +{ + fprintf(stderr,"%s : Line %d. Variable length arguments not supported (ignored).\n", input_file, line_number); + yyval.p = new Parm(new DataType(T_INT),"varargs"); + yyval.p->t->type = T_ERROR; + yyval.p->name = copy_string("varargs"); + strcpy(yyval.p->t->name,""); + FatalError(); + ; + break;} +case 129: +#line 1994 "parser.y" +{ + yyval.id = yyvsp[-1].id; + InArray = 0; + if (yyvsp[0].dtype.type == T_CHAR) + DefArg = copy_string(ConstChar); + else + DefArg = copy_string(yyvsp[0].dtype.id); + if (yyvsp[0].dtype.id) delete yyvsp[0].dtype.id; + ; + break;} +case 130: +#line 2003 "parser.y" +{ + yyval.id = yyvsp[-1].id; + InArray = yyvsp[0].ivalue; + DefArg = 0; + ; + break;} +case 131: +#line 2008 "parser.y" +{ + yyval.id = new char[1]; + yyval.id[0] = 0; + InArray = yyvsp[0].ivalue; + DefArg = 0; + ; + break;} +case 132: +#line 2014 "parser.y" +{ yyval.id = new char[1]; + yyval.id[0] = 0; + InArray = 0; + DefArg = 0; + ; + break;} +case 133: +#line 2021 "parser.y" +{ yyval.dtype = yyvsp[0].dtype; ; + break;} +case 134: +#line 2022 "parser.y" +{ + yyval.dtype.id = new char[strlen(yyvsp[0].id)+2]; + yyval.dtype.id[0] = '&'; + strcpy(&yyval.dtype.id[1], yyvsp[0].id); + yyval.dtype.type = T_USER; + ; + break;} +case 135: +#line 2028 "parser.y" +{ + skip_brace(); + yyval.dtype.id = 0; yyval.dtype.type = T_INT; + ; + break;} +case 136: +#line 2032 "parser.y" +{ + ; + break;} +case 137: +#line 2034 "parser.y" +{yyval.dtype.id = 0; yyval.dtype.type = T_INT;; + break;} +case 138: +#line 2037 "parser.y" +{ yyval.ivalue = CALL_VALUE; ; + break;} +case 139: +#line 2038 "parser.y" +{ yyval.ivalue = CALL_OUTPUT; ; + break;} +case 140: +#line 2041 "parser.y" +{ + yyval.ivalue = yyvsp[-1].ivalue | yyvsp[0].ivalue; + ; + break;} +case 141: +#line 2044 "parser.y" +{ + yyval.ivalue = yyvsp[0].ivalue; + ; + break;} +case 142: +#line 2051 "parser.y" +{ yyval.decl.id = yyvsp[0].id; + yyval.decl.is_pointer = 0; + yyval.decl.is_reference = 0; + ; + break;} +case 143: +#line 2055 "parser.y" +{ + yyval.decl.id = yyvsp[0].id; + yyval.decl.is_pointer = yyvsp[-1].ivalue; + yyval.decl.is_reference = 0; + ; + break;} +case 144: +#line 2060 "parser.y" +{ + yyval.decl.id = yyvsp[0].id; + yyval.decl.is_pointer = 1; + yyval.decl.is_reference = 1; + if (!CPlusPlus) { + fprintf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); + } + ; + break;} +case 145: +#line 2070 "parser.y" +{ yyval.ivalue = 1; ; + break;} +case 146: +#line 2071 "parser.y" +{ yyval.ivalue = yyvsp[0].ivalue + 1;; + break;} +case 147: +#line 2075 "parser.y" +{ + yyval.ivalue = yyvsp[0].ivalue + 1; + "[]" >> ArrayString; + ; + break;} +case 148: +#line 2079 "parser.y" +{ + yyval.ivalue = yyvsp[0].ivalue + 1; + "]" >> ArrayString; + yyvsp[-2].dtype.id >> ArrayString; + "[" >> ArrayString; + ; + break;} +case 149: +#line 2086 "parser.y" +{ + yyval.ivalue = yyvsp[0].ivalue; + ; + break;} +case 150: +#line 2089 "parser.y" +{ yyval.ivalue = 0; + ArrayString = ""; + ; + break;} +case 151: +#line 2097 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 152: +#line 2100 "parser.y" +{ + yyval.type = yyvsp[-1].type; + ; + break;} +case 153: +#line 2103 "parser.y" +{ + yyval.type = yyvsp[-1].type; + ; + break;} +case 154: +#line 2106 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 155: +#line 2109 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 156: +#line 2112 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 157: +#line 2115 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 158: +#line 2118 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 159: +#line 2121 "parser.y" +{ + if (yyvsp[0].type) yyval.type = yyvsp[0].type; + else yyval.type = yyvsp[-1].type; + ; + break;} +case 160: +#line 2125 "parser.y" +{ + if (yyvsp[0].type) yyval.type = yyvsp[0].type; + else yyval.type = yyvsp[-1].type; + ; + break;} +case 161: +#line 2129 "parser.y" +{ + yyval.type = yyvsp[-1].type; + if (strlen(yyvsp[0].id) > 0) { + if ((strlen(yyvsp[0].id) + strlen(yyval.type->name)) >= MAX_NAME) { + fprintf(stderr,"%s : Line %d. Fatal error. Type-name is too long!\n", + input_file, line_number); + } else { + strcat(yyval.type->name,yyvsp[0].id); + } + } + ; + break;} +case 162: +#line 2140 "parser.y" +{ + yyval.type = new DataType; + strcpy(yyval.type->name,yyvsp[-1].id); + yyval.type->type = T_USER; + /* Do a typedef lookup */ + yyval.type->typedef_resolve(); + if (strlen(yyvsp[0].id) > 0) { + if ((strlen(yyvsp[0].id) + strlen(yyval.type->name)) >= MAX_NAME) { + fprintf(stderr,"%s : Line %d. Fatal error. Type-name is too long!\n", + input_file, line_number); + } else { + strcat(yyval.type->name,yyvsp[0].id); + } + } + ; + break;} +case 163: +#line 2155 "parser.y" +{ + yyval.type = yyvsp[0].type; + yyval.type->qualifier = new char[6]; + strcpy(yyval.type->qualifier,"const"); + ; + break;} +case 164: +#line 2160 "parser.y" +{ + yyval.type = new DataType; + sprintf(yyval.type->name,"%s %s",yyvsp[-1].id, yyvsp[0].id); + yyval.type->type = T_USER; + ; + break;} +case 165: +#line 2165 "parser.y" +{ + yyval.type = new DataType; + sprintf(yyval.type->name,"%s::%s",yyvsp[-2].id,yyvsp[0].id); + yyval.type->type = T_USER; + yyval.type->typedef_resolve(); + ; + break;} +case 166: +#line 2174 "parser.y" +{ + yyval.type = new DataType; + sprintf(yyval.type->name,"%s", yyvsp[0].id); + yyval.type->type = T_USER; + yyval.type->typedef_resolve(1); + ; + break;} +case 167: +#line 2180 "parser.y" +{ + yyval.type = new DataType; + sprintf(yyval.type->name,"enum %s", yyvsp[0].id); + yyval.type->type = T_INT; + yyval.type->typedef_resolve(1); + ; + break;} +case 168: +#line 2190 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 169: +#line 2193 "parser.y" +{ + yyval.type = yyvsp[-1].type; + ; + break;} +case 170: +#line 2196 "parser.y" +{ + yyval.type = yyvsp[-1].type; + ; + break;} +case 171: +#line 2199 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 172: +#line 2202 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 173: +#line 2205 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 174: +#line 2208 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 175: +#line 2211 "parser.y" +{ + yyval.type = yyvsp[0].type; + ; + break;} +case 176: +#line 2214 "parser.y" +{ + if (yyvsp[0].type) yyval.type = yyvsp[0].type; + else yyval.type = yyvsp[-1].type; + ; + break;} +case 177: +#line 2218 "parser.y" +{ + if (yyvsp[0].type) yyval.type = yyvsp[0].type; + else yyval.type = yyvsp[-1].type; + ; + break;} +case 178: +#line 2222 "parser.y" +{ + yyval.type = yyvsp[-1].type; + strcat(yyval.type->name,yyvsp[0].id); + ; + break;} +case 179: +#line 2226 "parser.y" +{ + yyval.type = yyvsp[0].type; + yyval.type->qualifier = new char[6]; + strcpy(yyval.type->qualifier,"const"); + ; + break;} +case 180: +#line 2231 "parser.y" +{ + yyval.type = new DataType; + sprintf(yyval.type->name,"%s %s",yyvsp[-1].id, yyvsp[0].id); + yyval.type->type = T_USER; + ; + break;} +case 181: +#line 2240 "parser.y" +{ + yyval.type = (DataType *) 0; + ; + break;} +case 182: +#line 2243 "parser.y" +{ + yyval.type = yyvsp[0].type; + yyval.type->type = T_INT; + sprintf(temp_name,"signed %s",yyvsp[0].type->name); + strcpy(yyval.type->name,temp_name); + ; + break;} +case 183: +#line 2249 "parser.y" +{ + yyval.type = yyvsp[-1].type; + yyval.type->type = T_SHORT; + sprintf(temp_name,"signed %s",yyvsp[-1].type->name); + strcpy(yyval.type->name,temp_name); + ; + break;} +case 184: +#line 2255 "parser.y" +{ + yyval.type = yyvsp[-1].type; + yyval.type->type = T_LONG; + sprintf(temp_name,"signed %s",yyvsp[-1].type->name); + strcpy(yyval.type->name,temp_name); + ; + break;} +case 185: +#line 2261 "parser.y" +{ + yyval.type = yyvsp[0].type; + yyval.type->type = T_SCHAR; + sprintf(temp_name,"signed %s",yyvsp[0].type->name); + strcpy(yyval.type->name,temp_name); + ; + break;} +case 186: +#line 2271 "parser.y" +{ + yyval.type = (DataType *) 0; + ; + break;} +case 187: +#line 2274 "parser.y" +{ + yyval.type = yyvsp[0].type; + yyval.type->type = T_UINT; + sprintf(temp_name,"unsigned %s",yyvsp[0].type->name); + strcpy(yyval.type->name,temp_name); + ; + break;} +case 188: +#line 2280 "parser.y" +{ + yyval.type = yyvsp[-1].type; + yyval.type->type = T_USHORT; + sprintf(temp_name,"unsigned %s",yyvsp[-1].type->name); + strcpy(yyval.type->name,temp_name); + ; + break;} +case 189: +#line 2286 "parser.y" +{ + yyval.type = yyvsp[-1].type; + yyval.type->type = T_ULONG; + sprintf(temp_name,"unsigned %s",yyvsp[-1].type->name); + strcpy(yyval.type->name,temp_name); + ; + break;} +case 190: +#line 2292 "parser.y" +{ + yyval.type = yyvsp[0].type; + yyval.type->type = T_UCHAR; + sprintf(temp_name,"unsigned %s",yyvsp[0].type->name); + strcpy(yyval.type->name,temp_name); + ; + break;} +case 191: +#line 2300 "parser.y" +{ ; + break;} +case 192: +#line 2301 "parser.y" +{ ; + break;} +case 193: +#line 2304 "parser.y" +{ scanner_check_typedef(); ; + break;} +case 194: +#line 2304 "parser.y" +{ + yyval.dtype = yyvsp[0].dtype; + scanner_ignore_typedef(); + if (ConstChar) delete ConstChar; + ConstChar = 0; + ; + break;} +case 195: +#line 2310 "parser.y" +{ + yyval.dtype.id = yyvsp[0].id; + yyval.dtype.type = T_CHAR; + if (ConstChar) delete ConstChar; + ConstChar = new char[strlen(yyvsp[0].id)+3]; + sprintf(ConstChar,"\"%s\"",yyvsp[0].id); + ; + break;} +case 196: +#line 2317 "parser.y" +{ + yyval.dtype.id = yyvsp[0].id; + yyval.dtype.type = T_CHAR; + if (ConstChar) delete ConstChar; + ConstChar = new char[strlen(yyvsp[0].id)+3]; + sprintf(ConstChar,"'%s'",yyvsp[0].id); + ; + break;} +case 197: +#line 2329 "parser.y" +{ + yyval.ilist = yyvsp[-2].ilist; + yyval.ilist.names[yyval.ilist.count] = copy_string(yyvsp[0].id); + yyval.ilist.count++; + yyval.ilist.names[yyval.ilist.count] = (char *) 0; + ; + break;} +case 198: +#line 2335 "parser.y" +{ + yyval.ilist.names = new char *[NI_NAMES]; + yyval.ilist.count = 0; + for (i = 0; i < NI_NAMES; i++) + yyval.ilist.names[i] = (char *) 0; + ; + break;} +case 199: +#line 2345 "parser.y" +{ yyval.id = yyvsp[0].id; ; + break;} +case 200: +#line 2346 "parser.y" +{ yyval.id = (char *) 0;; + break;} +case 201: +#line 2352 "parser.y" +{; + break;} +case 202: +#line 2353 "parser.y" +{; + break;} +case 203: +#line 2357 "parser.y" +{ + temp_typeptr = new DataType(T_INT); + create_constant(yyvsp[0].id, temp_typeptr, yyvsp[0].id); + delete temp_typeptr; + ; + break;} +case 204: +#line 2362 "parser.y" +{ scanner_check_typedef();; + break;} +case 205: +#line 2362 "parser.y" +{ + temp_typeptr = new DataType(yyvsp[0].dtype.type); +// Use enum name instead of value +// OLD create_constant($1, temp_typeptr, $4.id); + create_constant(yyvsp[-3].id, temp_typeptr, yyvsp[-3].id); + delete temp_typeptr; + ; + break;} +case 206: +#line 2369 "parser.y" +{ ; + break;} +case 207: +#line 2370 "parser.y" +{ ; + break;} +case 208: +#line 2373 "parser.y" +{ + yyval.dtype = yyvsp[0].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)) { + fprintf(stderr,"%s : Lind %d. Type error. Expecting an int\n", + input_file, line_number); + FatalError(); + } + + ; + break;} +case 209: +#line 2385 "parser.y" +{ + yyval.dtype.id = yyvsp[0].id; + yyval.dtype.type = T_CHAR; + ; + break;} +case 210: +#line 2396 "parser.y" +{ + yyval.dtype.id = yyvsp[0].id; + yyval.dtype.type = T_INT; + ; + break;} +case 211: +#line 2400 "parser.y" +{ + yyval.dtype.id = yyvsp[0].id; + yyval.dtype.type = T_DOUBLE; + ; + break;} +case 212: +#line 2404 "parser.y" +{ + yyval.dtype.id = yyvsp[0].id; + yyval.dtype.type = T_UINT; + ; + break;} +case 213: +#line 2408 "parser.y" +{ + yyval.dtype.id = yyvsp[0].id; + yyval.dtype.type = T_LONG; + ; + break;} +case 214: +#line 2412 "parser.y" +{ + yyval.dtype.id = yyvsp[0].id; + yyval.dtype.type = T_ULONG; + ; + break;} +case 215: +#line 2416 "parser.y" +{ + yyval.dtype.id = new char[strlen(yyvsp[-1].type->name)+9]; + sprintf(yyval.dtype.id,"sizeof(%s)", yyvsp[-1].type->name); + yyval.dtype.type = T_INT; + ; + break;} +case 216: +#line 2421 "parser.y" +{ + yyval.dtype.id = new char[strlen(yyvsp[0].dtype.id)+strlen(yyvsp[-2].type->name)+3]; + sprintf(yyval.dtype.id,"(%s)%s",yyvsp[-2].type->name,yyvsp[0].dtype.id); + yyval.dtype.type = yyvsp[-2].type->type; + ; + break;} +case 217: +#line 2426 "parser.y" +{ + yyval.dtype.id = lookup_symvalue(yyvsp[0].id); + if (yyval.dtype.id == (char *) 0) + yyval.dtype.id = yyvsp[0].id; + else { + yyval.dtype.id = new char[strlen(yyval.dtype.id)+3]; + sprintf(yyval.dtype.id,"(%s)",lookup_symvalue(yyvsp[0].id)); + } + temp_typeptr = lookup_symtype(yyvsp[0].id); + if (temp_typeptr) yyval.dtype.type = temp_typeptr->type; + else yyval.dtype.type = T_INT; + ; + break;} +case 218: +#line 2438 "parser.y" +{ + yyval.dtype.id = new char[strlen(yyvsp[-2].id)+strlen(yyvsp[0].id)+3]; + sprintf(yyval.dtype.id,"%s::%s",yyvsp[-2].id,yyvsp[0].id); + yyval.dtype.type = T_INT; + delete yyvsp[-2].id; + delete yyvsp[0].id; + ; + break;} +case 219: +#line 2445 "parser.y" +{ + E_BINARY(yyval.dtype.id,yyvsp[-2].dtype.id,yyvsp[0].dtype.id,"+"); + yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); + delete yyvsp[-2].dtype.id; + delete yyvsp[0].dtype.id; + ; + break;} +case 220: +#line 2451 "parser.y" +{ + E_BINARY(yyval.dtype.id,yyvsp[-2].dtype.id,yyvsp[0].dtype.id,"-"); + yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); + delete yyvsp[-2].dtype.id; + delete yyvsp[0].dtype.id; + ; + break;} +case 221: +#line 2457 "parser.y" +{ + E_BINARY(yyval.dtype.id,yyvsp[-2].dtype.id,yyvsp[0].dtype.id,"*"); + yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); + delete yyvsp[-2].dtype.id; + delete yyvsp[0].dtype.id; + + ; + break;} +case 222: +#line 2464 "parser.y" +{ + E_BINARY(yyval.dtype.id,yyvsp[-2].dtype.id,yyvsp[0].dtype.id,"/"); + yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); + delete yyvsp[-2].dtype.id; + delete yyvsp[0].dtype.id; + + ; + break;} +case 223: +#line 2471 "parser.y" +{ + E_BINARY(yyval.dtype.id,yyvsp[-2].dtype.id,yyvsp[0].dtype.id,"&"); + yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); + if ((yyvsp[-2].dtype.type == T_DOUBLE) || (yyvsp[0].dtype.type == T_DOUBLE)) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + delete yyvsp[-2].dtype.id; + delete yyvsp[0].dtype.id; + + ; + break;} +case 224: +#line 2482 "parser.y" +{ + E_BINARY(yyval.dtype.id,yyvsp[-2].dtype.id,yyvsp[0].dtype.id,"|"); + yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); + if ((yyvsp[-2].dtype.type == T_DOUBLE) || (yyvsp[0].dtype.type == T_DOUBLE)) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + yyval.dtype.type = T_INT; + delete yyvsp[-2].dtype.id; + delete yyvsp[0].dtype.id; + + ; + break;} +case 225: +#line 2494 "parser.y" +{ + E_BINARY(yyval.dtype.id,yyvsp[-2].dtype.id,yyvsp[0].dtype.id,"^"); + yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); + if ((yyvsp[-2].dtype.type == T_DOUBLE) || (yyvsp[0].dtype.type == T_DOUBLE)) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + yyval.dtype.type = T_INT; + delete yyvsp[-2].dtype.id; + delete yyvsp[0].dtype.id; + + ; + break;} +case 226: +#line 2506 "parser.y" +{ + E_BINARY(yyval.dtype.id,yyvsp[-2].dtype.id,yyvsp[0].dtype.id,"<<"); + yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); + if ((yyvsp[-2].dtype.type == T_DOUBLE) || (yyvsp[0].dtype.type == T_DOUBLE)) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + yyval.dtype.type = T_INT; + delete yyvsp[-2].dtype.id; + delete yyvsp[0].dtype.id; + + ; + break;} +case 227: +#line 2518 "parser.y" +{ + E_BINARY(yyval.dtype.id,yyvsp[-2].dtype.id,yyvsp[0].dtype.id,">>"); + yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); + if ((yyvsp[-2].dtype.type == T_DOUBLE) || (yyvsp[0].dtype.type == T_DOUBLE)) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + yyval.dtype.type = T_INT; + delete yyvsp[-2].dtype.id; + delete yyvsp[0].dtype.id; + + ; + break;} +case 228: +#line 2530 "parser.y" +{ + yyval.dtype.id = new char[strlen(yyvsp[0].dtype.id)+2]; + sprintf(yyval.dtype.id,"-%s",yyvsp[0].dtype.id); + yyval.dtype.type = yyvsp[0].dtype.type; + delete yyvsp[0].dtype.id; + + ; + break;} +case 229: +#line 2537 "parser.y" +{ + yyval.dtype.id = new char[strlen(yyvsp[0].dtype.id)+2]; + sprintf(yyval.dtype.id,"~%s",yyvsp[0].dtype.id); + if (yyvsp[0].dtype.type == T_DOUBLE) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + yyval.dtype.type = yyvsp[0].dtype.type; + delete yyvsp[0].dtype.id; + ; + break;} +case 230: +#line 2547 "parser.y" +{ + yyval.dtype.id = new char[strlen(yyvsp[-1].dtype.id)+3]; + sprintf(yyval.dtype.id,"(%s)", yyvsp[-1].dtype.id); + yyval.dtype.type = yyvsp[-1].dtype.type; + delete yyvsp[-1].dtype.id; + ; + break;} +case 231: +#line 2558 "parser.y" +{ ; + break;} +case 232: +#line 2559 "parser.y" +{; + break;} +case 233: +#line 2565 "parser.y" +{ + char *iname; + if (allow) { + init_language(); + DataType::new_scope(); + + sprintf(temp_name,"CPP_CLASS:%s\n",yyvsp[-2].id); + if (add_symbol(temp_name, (DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Error. %s %s is multiply defined.\n", input_file, line_number, yyvsp[-3].id, yyvsp[-2].id); + FatalError(); + } + if ((!CPlusPlus) && (strcmp(yyvsp[-3].id,"class") == 0)) + fprintf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); + + iname = make_name(yyvsp[-2].id); + doc_entry = new DocClass(iname, doc_parent()); + if (iname == yyvsp[-2].id) + cplus_open_class(yyvsp[-2].id, 0, yyvsp[-3].id); + else + cplus_open_class(yyvsp[-2].id, iname, yyvsp[-3].id); + if (strcmp(yyvsp[-3].id,"class") == 0) + cplus_mode = CPLUS_PRIVATE; + else + cplus_mode = CPLUS_PUBLIC; + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + nested_list = 0; + // Merge in scope from base classes + cplus_inherit_scope(yyvsp[-1].ilist.count,yyvsp[-1].ilist.names); + } + ; + break;} +case 234: +#line 2596 "parser.y" +{ + if (allow) { + if (yyvsp[-4].ilist.names) { + if (strcmp(yyvsp[-6].id,"union") != 0) + cplus_inherit(yyvsp[-4].ilist.count, yyvsp[-4].ilist.names); + else { + fprintf(stderr,"%s : Line %d. Inheritance not allowed for unions.\n",input_file, line_number); + FatalError(); + } + } + // Clean up the inheritance list + if (yyvsp[-4].ilist.names) { + int j; + for (j = 0; j < yyvsp[-4].ilist.count; j++) { + if (yyvsp[-4].ilist.names[j]) delete [] yyvsp[-4].ilist.names[j]; + } + delete [] yyvsp[-4].ilist.names; + } + + // Dumped nested declarations (if applicable) + dump_nested(yyvsp[-5].id); + + // Save and collapse current scope + cplus_register_scope(DataType::collapse_scope(yyvsp[-5].id)); + + // Restore the original doc entry for this class + doc_entry = doc_stack[doc_stack_top]; + cplus_class_close((char *) 0); + doc_entry = 0; + // Bump the documentation stack back down + doc_stack_top--; + cplus_mode = CPLUS_PUBLIC; + } + ; + break;} +case 235: +#line 2633 "parser.y" +{ + if (allow) { + char *iname; + init_language(); + DataType::new_scope(); + + sprintf(temp_name,"CPP_CLASS:%s\n",yyvsp[-2].id); + if (add_symbol(temp_name, (DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Error. %s %s is multiply defined.\n", input_file, line_number, yyvsp[-3].id, yyvsp[-2].id); + FatalError(); + } + if ((!CPlusPlus) && (strcmp(yyvsp[-3].id,"class") == 0)) + fprintf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); + + iname = make_name(yyvsp[-2].id); + doc_entry = new DocClass(iname, doc_parent()); + if (yyvsp[-2].id == iname) + cplus_open_class(yyvsp[-2].id, 0, yyvsp[-3].id); + else + cplus_open_class(yyvsp[-2].id, iname, yyvsp[-3].id); + if (strcmp(yyvsp[-3].id,"class") == 0) + cplus_mode = CPLUS_PRIVATE; + else + cplus_mode = CPLUS_PUBLIC; + // Create a documentation entry for the class + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + nested_list = 0; + + // Merge in scope from base classes + cplus_inherit_scope(yyvsp[-1].ilist.count,yyvsp[-1].ilist.names); + + } + ; + break;} +case 236: +#line 2667 "parser.y" +{ + if (allow) { + if (yyvsp[-5].ilist.names) { + if (strcmp(yyvsp[-7].id,"union") != 0) + cplus_inherit(yyvsp[-5].ilist.count, yyvsp[-5].ilist.names); + else { + fprintf(stderr,"%s : Line %d. Inheritance not allowed for unions.\n",input_file, line_number); + FatalError(); + } + } + // Create a datatype for correctly processing the typedef + Active_typedef = new DataType(); + Active_typedef->type = T_USER; + sprintf(Active_typedef->name,"%s %s", yyvsp[-7].id,yyvsp[-6].id); + Active_typedef->is_pointer = 0; + Active_typedef->implicit_ptr = 0; + + // Clean up the inheritance list + if (yyvsp[-5].ilist.names) { + int j; + for (j = 0; j < yyvsp[-5].ilist.count; j++) { + if (yyvsp[-5].ilist.names[j]) delete [] yyvsp[-5].ilist.names[j]; + } + delete [] yyvsp[-5].ilist.names; + } + + if (yyvsp[0].decl.is_pointer > 0) { + fprintf(stderr,"%s : Line %d. typedef struct { } *id not supported properly. Winging it...\n", input_file, line_number); + + } + // Create dump nested class code + if (yyvsp[0].decl.is_pointer > 0) { + dump_nested(yyvsp[-6].id); + } else { + dump_nested(yyvsp[0].decl.id); + } + + // Collapse any datatypes created in the the class + + cplus_register_scope(DataType::collapse_scope(yyvsp[-6].id)); + + doc_entry = doc_stack[doc_stack_top]; + if (yyvsp[0].decl.is_pointer > 0) { + cplus_class_close(yyvsp[-6].id); + } else { + cplus_class_close(yyvsp[0].decl.id); + } + doc_stack_top--; + doc_entry = 0; + + // Create a typedef in global scope + + if (yyvsp[0].decl.is_pointer == 0) + Active_typedef->typedef_add(yyvsp[0].decl.id); + else { + DataType *t = new DataType(Active_typedef); + t->is_pointer += yyvsp[0].decl.is_pointer; + t->typedef_add(yyvsp[0].decl.id); + cplus_register_type(yyvsp[0].decl.id); + delete t; + } + cplus_mode = CPLUS_PUBLIC; + } + ; + break;} +case 237: +#line 2730 "parser.y" +{ ; + break;} +case 238: +#line 2734 "parser.y" +{ + char *iname; + if (allow) { + init_language(); + DataType::new_scope(); + if ((!CPlusPlus) && (strcmp(yyvsp[-1].id,"class") == 0)) + fprintf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); + + iname = make_name(""); + doc_entry = new DocClass(iname,doc_parent()); + if (strlen(iname)) + cplus_open_class("", iname, yyvsp[-1].id); + else + cplus_open_class("",0,yyvsp[-1].id); + if (strcmp(yyvsp[-1].id,"class") == 0) + cplus_mode = CPLUS_PRIVATE; + else + cplus_mode = CPLUS_PUBLIC; + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + nested_list = 0; + } + ; + break;} +case 239: +#line 2757 "parser.y" +{ + if (allow) { + if (yyvsp[0].decl.is_pointer > 0) { + fprintf(stderr,"%s : Line %d. typedef %s {} *%s not supported correctly. Will be ignored.\n", input_file, line_number, yyvsp[-5].id, yyvsp[0].decl.id); + cplus_abort(); + } else { + sprintf(temp_name,"CPP_CLASS:%s\n",yyvsp[0].decl.id); + if (add_symbol(temp_name, (DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Error. %s %s is multiply defined.\n", input_file, line_number, yyvsp[-5].id, yyvsp[0].decl.id); + FatalError(); + } + } + // Create a datatype for correctly processing the typedef + Active_typedef = new DataType(); + Active_typedef->type = T_USER; + sprintf(Active_typedef->name,"%s",yyvsp[0].decl.id); + Active_typedef->is_pointer = 0; + Active_typedef->implicit_ptr = 0; + + // Dump nested classes + if (yyvsp[0].decl.is_pointer == 0) + dump_nested(yyvsp[0].decl.id); + + // Go back to previous scope + + cplus_register_scope(DataType::collapse_scope((char *) 0)); + + doc_entry = doc_stack[doc_stack_top]; + // Change name of doc_entry + doc_entry->name = copy_string(yyvsp[0].decl.id); + if (yyvsp[0].decl.is_pointer == 0) + cplus_class_close(yyvsp[0].decl.id); + doc_entry = 0; + doc_stack_top--; + cplus_mode = CPLUS_PUBLIC; + } + ; + break;} +case 240: +#line 2793 "parser.y" +{ ; + break;} +case 241: +#line 2798 "parser.y" +{ + char *iname; + if (allow) { + init_language(); + iname = make_name(yyvsp[-1].id); + lang->cpp_class_decl(yyvsp[-1].id,iname,yyvsp[-2].id); + } + ; + break;} +case 242: +#line 2809 "parser.y" +{ + if (allow) { + init_language(); + if (!CPlusPlus) + fprintf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); + + yyvsp[-7].type->is_pointer += yyvsp[-6].decl.is_pointer; + yyvsp[-7].type->is_reference = yyvsp[-6].decl.is_reference; + // Fix up the function name + sprintf(temp_name,"%s::%s",yyvsp[-6].decl.id,yyvsp[-4].id); + if (!Rename_true) { + Rename_true = 1; + sprintf(yy_rename,"%s_%s",yyvsp[-6].decl.id,yyvsp[-4].id); + } + create_function(yyvsp[-8].ivalue, temp_name, yyvsp[-7].type, yyvsp[-2].pl); + } + delete yyvsp[-7].type; + delete yyvsp[-2].pl; + ; + break;} +case 243: +#line 2830 "parser.y" +{ + if (allow) { + init_language(); + if (!CPlusPlus) + fprintf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); + + yyvsp[-4].type->is_pointer += yyvsp[-3].decl.is_pointer; + // Fix up the function name + sprintf(temp_name,"%s::%s",yyvsp[-3].decl.id,yyvsp[-1].id); + if (!Rename_true) { + Rename_true = 1; + sprintf(yy_rename,"%s_%s",yyvsp[-3].decl.id,yyvsp[-1].id); + } + create_variable(yyvsp[-5].ivalue,temp_name, yyvsp[-4].type); + } + delete yyvsp[-4].type; + ; + break;} +case 244: +#line 2850 "parser.y" +{ + fprintf(stderr,"%s : Line %d. Operator overloading not supported (ignored).\n", input_file, line_number); + skip_decl(); + delete yyvsp[-3].type; + ; + break;} +case 245: +#line 2858 "parser.y" +{ + fprintf(stderr,"%s : Line %d. Templates not currently supported (ignored).\n", + input_file, line_number); + skip_decl(); + ; + break;} +case 246: +#line 2866 "parser.y" +{ + cplus_mode = CPLUS_PUBLIC; + doc_entry = cplus_set_class(yyvsp[-1].id); + if (!doc_entry) { + doc_entry = new DocClass(yyvsp[-1].id,doc_parent()); + }; + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + AddMethods = 1; + ; + break;} +case 247: +#line 2876 "parser.y" +{ + cplus_unset_class(); + doc_entry = 0; + doc_stack_top--; + AddMethods = 0; + ; + break;} +case 248: +#line 2884 "parser.y" +{ ; + break;} +case 249: +#line 2885 "parser.y" +{ ; + break;} +case 250: +#line 2886 "parser.y" +{ ; + break;} +case 251: +#line 2889 "parser.y" +{; + break;} +case 252: +#line 2890 "parser.y" +{ + AddMethods = 1; + ; + break;} +case 253: +#line 2892 "parser.y" +{ + AddMethods = 0; + ; + break;} +case 254: +#line 2894 "parser.y" +{ ; + break;} +case 255: +#line 2895 "parser.y" +{ + skip_decl(); + { + static int last_error_line = -1; + if (last_error_line != line_number) { + fprintf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); + FatalError(); + last_error_line = line_number; + } + } + ; + break;} +case 256: +#line 2905 "parser.y" +{ ; + break;} +case 257: +#line 2906 "parser.y" +{ ; + break;} +case 258: +#line 2909 "parser.y" +{ + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + Stat_func++; + yyvsp[-5].type->is_pointer += yyvsp[-4].decl.is_pointer; + yyvsp[-5].type->is_reference = yyvsp[-4].decl.is_reference; + if (Verbose) { + fprintf(stderr,"Wrapping member function : %s\n",yyvsp[-4].decl.id); + } + iname = make_name(yyvsp[-4].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-4].decl.id) iname = 0; + cplus_member_func(yyvsp[-4].decl.id, iname, yyvsp[-5].type,yyvsp[-2].pl,0); + } + scanner_clear_start(); + } + delete yyvsp[-5].type; + delete yyvsp[-2].pl; + ; + break;} +case 259: +#line 2933 "parser.y" +{ + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + Stat_func++; + yyvsp[-5].type->is_pointer += yyvsp[-4].decl.is_pointer; + yyvsp[-5].type->is_reference = yyvsp[-4].decl.is_reference; + if (Verbose) { + fprintf(stderr,"Wrapping virtual member function : %s\n",yyvsp[-4].decl.id); + } + iname = make_name(yyvsp[-4].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-4].decl.id) iname = 0; + cplus_member_func(yyvsp[-4].decl.id,iname,yyvsp[-5].type,yyvsp[-2].pl,1); + } + scanner_clear_start(); + } + delete yyvsp[-5].type; + delete yyvsp[-2].pl; + ; + break;} +case 260: +#line 2956 "parser.y" +{ + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + Stat_func++; + if (Verbose) { + fprintf(stderr,"Wrapping C++ constructor %s\n", yyvsp[-4].id); + } + iname = make_name(yyvsp[-4].id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-4].id) iname = 0; + cplus_constructor(yyvsp[-4].id,iname, yyvsp[-2].pl); + } + scanner_clear_start(); + } + delete yyvsp[-2].pl; + ; + break;} +case 261: +#line 2977 "parser.y" +{ + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + Stat_func++; + if (Verbose) { + fprintf(stderr,"Wrapping C++ destructor %s\n", yyvsp[-4].id); + } + iname = make_name(yyvsp[-4].id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-4].id) iname = 0; + cplus_destructor(yyvsp[-4].id,iname); + } + } + scanner_clear_start(); + ; + break;} +case 262: +#line 2997 "parser.y" +{ + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + Stat_func++; + if (Verbose) { + fprintf(stderr,"Wrapping C++ destructor %s\n", yyvsp[-3].id); + } + iname = make_name(yyvsp[-3].id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-3].id) iname = 0; + cplus_destructor(yyvsp[-3].id,iname); + } + } + scanner_clear_start(); + ; + break;} +case 263: +#line 3017 "parser.y" +{ + if (allow) { + char *iname; + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + if (Active_type) delete Active_type; + Active_type = new DataType(yyvsp[-2].type); + yyvsp[-2].type->is_pointer += yyvsp[-1].decl.is_pointer; + yyvsp[-2].type->is_reference = yyvsp[-1].decl.is_reference; + if (yyvsp[-2].type->qualifier) { + if ((strcmp(yyvsp[-2].type->qualifier,"const") == 0) && (yyvsp[-2].type->is_pointer == 0)) { + // Okay. This is really some sort of C++ constant here. + if (yyvsp[0].dtype.type != T_ERROR) { + iname = make_name(yyvsp[-1].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-1].decl.id) iname = 0; + cplus_declare_const(yyvsp[-1].decl.id,iname, yyvsp[-2].type, yyvsp[0].dtype.id); + } + } else { + int oldstatus = Status; + char *tm; + if (yyvsp[-2].type->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,yyvsp[-2].type,yyvsp[-1].decl.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name(yyvsp[-1].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-1].decl.id) iname = 0; + cplus_variable(yyvsp[-1].decl.id,iname,yyvsp[-2].type); + Status = oldstatus; + } + } else { + char *tm = 0; + int oldstatus = Status; + if (yyvsp[-2].type->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,yyvsp[-2].type,yyvsp[-1].decl.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name(yyvsp[-1].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-1].decl.id) iname = 0; + cplus_variable(yyvsp[-1].decl.id,iname,yyvsp[-2].type); + Status = oldstatus; + if (Verbose) { + fprintf(stderr,"Wrapping member data %s\n", yyvsp[-1].decl.id); + } + } + } + scanner_clear_start(); + } + delete yyvsp[-2].type; + ; + break;} +case 264: +#line 3068 "parser.y" +{ ; + break;} +case 265: +#line 3070 "parser.y" +{ + char *iname; + if (allow) { + int oldstatus = Status; + char *tm = 0; + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + if (Active_type) delete Active_type; + Active_type = new DataType(yyvsp[-3].type); + yyvsp[-3].type->is_pointer += yyvsp[-2].decl.is_pointer + 1; + yyvsp[-3].type->is_reference = yyvsp[-2].decl.is_reference; + yyvsp[-3].type->arraystr = copy_string(ArrayString); + if (!(tm = typemap_lookup("memberin",typemap_lang,yyvsp[-3].type,yyvsp[-2].decl.id,"",""))) + Status = STAT_READONLY; + + iname = make_name(yyvsp[-2].decl.id); + doc_entry = new DocDecl(iname, doc_stack[doc_stack_top]); + if (iname == yyvsp[-2].decl.id) iname = 0; + cplus_variable(yyvsp[-2].decl.id,iname,yyvsp[-3].type); + Status = oldstatus; + if (!tm) + fprintf(stderr,"%s : Line %d. Warning. Array member will be read-only.\n",input_file,line_number); + } + scanner_clear_start(); + } + delete yyvsp[-3].type; + ; + break;} +case 266: +#line 3101 "parser.y" +{ + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + yyvsp[-1].type->is_pointer += yyvsp[0].decl.is_pointer; + iname = make_name(yyvsp[0].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[0].decl.id) iname = 0; + cplus_static_var(yyvsp[0].decl.id,iname,yyvsp[-1].type); + if (Active_type) delete Active_type; + Active_type = new DataType(yyvsp[-1].type); + if (Verbose) { + fprintf(stderr,"Wrapping static member data %s\n", yyvsp[0].decl.id); + } + } + scanner_clear_start(); + } + delete yyvsp[-1].type; + ; + break;} +case 267: +#line 3120 "parser.y" +{ ; + break;} +case 268: +#line 3124 "parser.y" +{ + char *iname; + if (allow) { + yyvsp[-5].type->is_pointer += yyvsp[-4].decl.is_pointer; + yyvsp[-5].type->is_reference = yyvsp[-4].decl.is_reference; + if (cplus_mode == CPLUS_PUBLIC) { + iname = make_name(yyvsp[-4].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-4].decl.id) iname = 0; + cplus_static_func(yyvsp[-4].decl.id, iname, yyvsp[-5].type, yyvsp[-2].pl); + if (Verbose) + fprintf(stderr,"Wrapping static member function %s\n",yyvsp[-4].decl.id); + } + scanner_clear_start(); + } + delete yyvsp[-5].type; + delete yyvsp[-2].pl; + ; + break;} +case 269: +#line 3144 "parser.y" +{ + if (allow) { + cplus_mode = CPLUS_PUBLIC; + if (Verbose) + fprintf(stderr,"Public mode\n"); + scanner_clear_start(); + } + ; + break;} +case 270: +#line 3155 "parser.y" +{ + if (allow) { + cplus_mode = CPLUS_PRIVATE; + if (Verbose) + fprintf(stderr,"Private mode\n"); + scanner_clear_start(); + } + ; + break;} +case 271: +#line 3166 "parser.y" +{ + if (allow) { + cplus_mode = CPLUS_PROTECTED; + if (Verbose) + fprintf(stderr,"Protected mode\n"); + scanner_clear_start(); + } + ; + break;} +case 272: +#line 3177 "parser.y" +{ + if (allow) { + strcpy(yy_rename,yyvsp[-1].id); + Rename_true = 1; + } + ; + break;} +case 273: +#line 3185 "parser.y" +{ + NewObject = 1; + ; + break;} +case 274: +#line 3187 "parser.y" +{ + NewObject = 0; + ; + break;} +case 275: +#line 3192 "parser.y" +{scanner_clear_start();; + break;} +case 276: +#line 3192 "parser.y" +{ + + // if ename was supplied. Install it as a new integer datatype. + + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + if (yyvsp[-5].id) { + cplus_register_type(yyvsp[-5].id); + temp_type.type = T_INT; + temp_type.is_pointer = 0; + temp_type.implicit_ptr = 0; + sprintf(temp_type.name,"int"); + temp_type.typedef_add(yyvsp[-5].id,1); + } + } + } + ; + break;} +case 277: +#line 3210 "parser.y" +{ + if (allow) + Status = Status | STAT_READONLY; + scanner_clear_start(); + ; + break;} +case 278: +#line 3215 "parser.y" +{ + if (allow) + Status = Status & ~(STAT_READONLY); + scanner_clear_start(); + ; + break;} +case 279: +#line 3221 "parser.y" +{ + if (allow) + fprintf(stderr,"%s : Line %d. Friends are not allowed--members only! (ignored)\n", input_file, line_number); + skip_decl(); + scanner_clear_start(); + ; + break;} +case 280: +#line 3229 "parser.y" +{ + if (allow) + fprintf(stderr,"%s : Line %d. Operator overloading not supported (ignored).\n", input_file, line_number); + skip_decl(); + scanner_clear_start(); + ; + break;} +case 281: +#line 3235 "parser.y" +{ + scanner_clear_start(); + ; + break;} +case 282: +#line 3240 "parser.y" +{ ; + break;} +case 283: +#line 3244 "parser.y" +{ + scanner_clear_start(); + ; + break;} +case 284: +#line 3249 "parser.y" +{ + if (allow && (!WrapExtern)) { } + ; + break;} +case 285: +#line 3252 "parser.y" +{ + if (allow && (!WrapExtern)) + cplus_add_pragma(yyvsp[-3].id,yyvsp[-1].id,yyvsp[0].id); + ; + break;} +case 286: +#line 3275 "parser.y" +{ start_line = line_number; skip_brace(); + ; + break;} +case 287: +#line 3276 "parser.y" +{ + + if (cplus_mode == CPLUS_PUBLIC) { + cplus_register_type(yyvsp[-4].id); + if (yyvsp[-1].decl.id) { + if (strcmp(yyvsp[-5].id,"class") == 0) { + fprintf(stderr,"%s : Line %d. Warning. Nested classes not currently supported (ignored).\n", input_file, line_number); + /* Generate some code for a new class */ + } else { + Nested *n = new Nested; + n->code << "typedef " << yyvsp[-5].id << " " + << CCode.get() << " $classname_" << yyvsp[-1].decl.id << ";\n"; + n->name = copy_string(yyvsp[-1].decl.id); + n->line = start_line; + n->type = new DataType; + n->type->type = T_USER; + n->type->is_pointer = yyvsp[-1].decl.is_pointer; + n->type->is_reference = yyvsp[-1].decl.is_reference; + n->next = 0; + add_nested(n); + } + } + } + ; + break;} +case 288: +#line 3301 "parser.y" +{ start_line = line_number; skip_brace(); + ; + break;} +case 289: +#line 3302 "parser.y" +{ + if (cplus_mode == CPLUS_PUBLIC) { + if (strcmp(yyvsp[-4].id,"class") == 0) { + fprintf(stderr,"%s : Line %d. Warning. Nested classes not currently supported (ignored)\n", input_file, line_number); + /* Generate some code for a new class */ + } else { + /* Generate some code for a new class */ + + Nested *n = new Nested; + n->code << "typedef " << yyvsp[-4].id << " " + << CCode.get() << " $classname_" << yyvsp[-1].decl.id << ";\n"; + n->name = copy_string(yyvsp[-1].decl.id); + n->line = start_line; + n->type = new DataType; + n->type->type = T_USER; + n->type->is_pointer = yyvsp[-1].decl.is_pointer; + n->type->is_reference = yyvsp[-1].decl.is_reference; + n->next = 0; + add_nested(n); + + } + } + ; + break;} +case 290: +#line 3326 "parser.y" +{ + if (cplus_mode == CPLUS_PUBLIC) { + cplus_register_type(yyvsp[-1].id); + } + ; + break;} +case 291: +#line 3333 "parser.y" +{ + skip_decl(); + fprintf(stderr,"%s : Line %d. Function pointers not currently supported (ignored).\n", input_file, line_number); + + ; + break;} +case 292: +#line 3338 "parser.y" +{ + skip_decl(); + fprintf(stderr,"%s : Line %d. Function pointers not currently supported (ignored).\n", input_file, line_number); + + ; + break;} +case 293: +#line 3343 "parser.y" +{ + skip_decl(); + fprintf(stderr,"%s : Line %d. Function pointers not currently supported (ignored).\n", input_file, line_number); + + ; + break;} +case 294: +#line 3348 "parser.y" +{ ; + break;} +case 295: +#line 3349 "parser.y" +{ ; + break;} +case 296: +#line 3352 "parser.y" +{ yyval.decl = yyvsp[0].decl;; + break;} +case 297: +#line 3353 "parser.y" +{ yyval.decl.id = 0; ; + break;} +case 298: +#line 3356 "parser.y" +{; + break;} +case 299: +#line 3357 "parser.y" +{; + break;} +case 300: +#line 3358 "parser.y" +{; + break;} +case 301: +#line 3361 "parser.y" +{ ; + break;} +case 302: +#line 3362 "parser.y" +{ + if (allow) { + int oldstatus = Status; + char *tm; + + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + temp_typeptr = new DataType(Active_type); + temp_typeptr->is_pointer += yyvsp[-1].decl.is_pointer; + if (Verbose) { + fprintf(stderr,"Wrapping member variable : %s\n",yyvsp[-1].decl.id); + } + Stat_var++; + doc_entry = new DocDecl(yyvsp[-1].decl.id,doc_stack[doc_stack_top]); + if (temp_typeptr->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,temp_typeptr,yyvsp[-1].decl.id,"",""))) + Status = Status | STAT_READONLY; + } + cplus_variable(yyvsp[-1].decl.id,(char *) 0,temp_typeptr); + Status = oldstatus; + delete temp_typeptr; + } + scanner_clear_start(); + } + ; + break;} +case 303: +#line 3386 "parser.y" +{ ; + break;} +case 304: +#line 3387 "parser.y" +{ + if (allow) { + int oldstatus = Status; + char *tm; + + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + temp_typeptr = new DataType(Active_type); + temp_typeptr->is_pointer += yyvsp[-2].decl.is_pointer; + if (Verbose) { + fprintf(stderr,"Wrapping member variable : %s\n",yyvsp[-2].decl.id); + } + Stat_var++; + if (!(tm = typemap_lookup("memberin",typemap_lang,temp_typeptr,yyvsp[-2].decl.id,"",""))) + Status = Status | STAT_READONLY; + doc_entry = new DocDecl(yyvsp[-2].decl.id,doc_stack[doc_stack_top]); + if (temp_typeptr->status & STAT_READONLY) Status = Status | STAT_READONLY; + cplus_variable(yyvsp[-2].decl.id,(char *) 0,temp_typeptr); + Status = oldstatus; + if (!tm) + fprintf(stderr,"%s : Line %d. Warning. Array member will be read-only.\n",input_file,line_number); + delete temp_typeptr; + } + scanner_clear_start(); + } + ; + break;} +case 305: +#line 3412 "parser.y" +{ ; + break;} +case 306: +#line 3415 "parser.y" +{ + CCode = ""; + ; + break;} +case 307: +#line 3418 "parser.y" +{ skip_brace(); ; + break;} +case 308: +#line 3421 "parser.y" +{ CCode = ""; ; + break;} +case 309: +#line 3422 "parser.y" +{ CCode = ""; ; + break;} +case 310: +#line 3423 "parser.y" +{ skip_brace(); ; + break;} +case 311: +#line 3426 "parser.y" +{; + break;} +case 312: +#line 3427 "parser.y" +{; + break;} +case 313: +#line 3430 "parser.y" +{ + if (allow) { + if (cplus_mode == CPLUS_PUBLIC) { + if (Verbose) { + fprintf(stderr,"Creating enum value %s\n", yyvsp[0].id); + } + Stat_const++; + temp_typeptr = new DataType(T_INT); + doc_entry = new DocDecl(yyvsp[0].id,doc_stack[doc_stack_top]); + cplus_declare_const(yyvsp[0].id, (char *) 0, temp_typeptr, (char *) 0); + delete temp_typeptr; + scanner_clear_start(); + } + } + ; + break;} +case 314: +#line 3445 "parser.y" +{ + if (allow) { + if (cplus_mode == CPLUS_PUBLIC) { + if (Verbose) { + fprintf(stderr, "Creating enum value %s = %s\n", yyvsp[-2].id, yyvsp[0].dtype.id); + } + Stat_const++; + temp_typeptr = new DataType(T_INT); + doc_entry = new DocDecl(yyvsp[-2].id,doc_stack[doc_stack_top]); + cplus_declare_const(yyvsp[-2].id,(char *) 0, temp_typeptr,(char *) 0); +// OLD : Bug with value cplus_declare_const($1,(char *) 0, temp_typeptr,$3.id); + delete temp_typeptr; + scanner_clear_start(); + } + } + ; + break;} +case 315: +#line 3461 "parser.y" +{ + if (allow) { + if (cplus_mode == CPLUS_PUBLIC) { + if (Verbose) { + fprintf(stderr,"Creating enum value %s\n", yyvsp[0].id); + } + Stat_const++; + temp_typeptr = new DataType(T_INT); + doc_entry = new DocDecl(yyvsp[-2].id,doc_stack[doc_stack_top]); + cplus_declare_const(yyvsp[0].id, yyvsp[-2].id, temp_typeptr, (char *) 0); + delete temp_typeptr; + scanner_clear_start(); + } + } + ; + break;} +case 316: +#line 3476 "parser.y" +{ + if (allow) { + if (cplus_mode == CPLUS_PUBLIC) { + if (Verbose) { + fprintf(stderr, "Creating enum value %s = %s\n", yyvsp[-2].id, yyvsp[0].dtype.id); + } + Stat_const++; + temp_typeptr = new DataType(T_INT); + doc_entry = new DocDecl(yyvsp[-4].id,doc_stack[doc_stack_top]); + cplus_declare_const(yyvsp[-2].id,yyvsp[-4].id, temp_typeptr, (char *) 0); +// Old : bug with value cplus_declare_const($5,$3, temp_typeptr,$7.id); + delete temp_typeptr; + scanner_clear_start(); + } + } + ; + break;} +case 317: +#line 3492 "parser.y" +{ ; + break;} +case 318: +#line 3493 "parser.y" +{ ; + break;} +case 319: +#line 3496 "parser.y" +{ + yyval.ilist = yyvsp[0].ilist; + ; + break;} +case 320: +#line 3499 "parser.y" +{ + yyval.ilist.names = (char **) 0; + yyval.ilist.count = 0; + ; + break;} +case 321: +#line 3505 "parser.y" +{ + int i; + yyval.ilist.names = new char *[NI_NAMES]; + yyval.ilist.count = 0; + for (i = 0; i < NI_NAMES; i++){ + yyval.ilist.names[i] = (char *) 0; + } + if (yyvsp[0].id) { + yyval.ilist.names[yyval.ilist.count] = copy_string(yyvsp[0].id); + yyval.ilist.count++; + } + ; + break;} +case 322: +#line 3518 "parser.y" +{ + yyval.ilist = yyvsp[-2].ilist; + if (yyvsp[0].id) { + yyval.ilist.names[yyval.ilist.count] = copy_string(yyvsp[0].id); + yyval.ilist.count++; + } + ; + break;} +case 323: +#line 3527 "parser.y" +{ + fprintf(stderr,"%s : Line %d. No access specifier given for base class %s (ignored).\n", + input_file,line_number,yyvsp[0].id); + yyval.id = (char *) 0; + ; + break;} +case 324: +#line 3532 "parser.y" +{ + fprintf(stderr,"%s : Line %d. No access specifier given for base class %s (ignored).\n", + input_file,line_number,yyvsp[0].id); + yyval.id = (char *) 0; + ; + break;} +case 325: +#line 3537 "parser.y" +{ + if (strcmp(yyvsp[-1].id,"public") == 0) { + yyval.id = yyvsp[0].id; + } else { + fprintf(stderr,"%s : Line %d. %s inheritance not supported (ignored).\n", + input_file,line_number,yyvsp[-1].id); + yyval.id = (char *) 0; + } + ; + break;} +case 326: +#line 3546 "parser.y" +{ + if (strcmp(yyvsp[-1].id,"public") == 0) { + yyval.id = yyvsp[0].id; + } else { + fprintf(stderr,"%s : Line %d. %s inheritance not supported (ignored).\n", + input_file,line_number,yyvsp[-1].id); + yyval.id = (char *) 0; + } + ; + break;} +case 327: +#line 3555 "parser.y" +{ + if (strcmp(yyvsp[-2].id,"public") == 0) { + yyval.id = yyvsp[0].id; + } else { + fprintf(stderr,"%s : Line %d. %s inheritance not supported (ignored).\n", + input_file,line_number,yyvsp[-2].id); + yyval.id = (char *) 0; + } + ; + break;} +case 328: +#line 3566 "parser.y" +{ yyval.id = "public"; ; + break;} +case 329: +#line 3567 "parser.y" +{ yyval.id = "private"; ; + break;} +case 330: +#line 3568 "parser.y" +{ yyval.id = "protected"; ; + break;} +case 331: +#line 3572 "parser.y" +{ yyval.id = "class"; ; + break;} +case 332: +#line 3573 "parser.y" +{ yyval.id = "struct"; ; + break;} +case 333: +#line 3574 "parser.y" +{yyval.id = "union"; ; + break;} +case 334: +#line 3577 "parser.y" +{; + break;} +case 335: +#line 3578 "parser.y" +{ delete yyvsp[-1].pl;; + break;} +case 336: +#line 3579 "parser.y" +{; + break;} +case 337: +#line 3584 "parser.y" +{ + CCode = ""; + ; + break;} +case 338: +#line 3587 "parser.y" +{ skip_brace(); ; + break;} +case 339: +#line 3590 "parser.y" +{; + break;} +case 340: +#line 3591 "parser.y" +{; + break;} +case 341: +#line 3594 "parser.y" +{ ; + break;} +case 342: +#line 3595 "parser.y" +{ ; + break;} +case 343: +#line 3598 "parser.y" +{ ; + break;} +case 344: +#line 3599 "parser.y" +{ ; + break;} +case 345: +#line 3602 "parser.y" +{ ; + break;} +case 346: +#line 3603 "parser.y" +{ ; + break;} +case 347: +#line 3611 "parser.y" +{ + ObjCClass = 1; + init_language(); + cplus_mode = CPLUS_PROTECTED; + sprintf(temp_name,"CPP_CLASS:%s\n",yyvsp[-1].id); + if (add_symbol(temp_name,(DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. @interface %s is multiple defined.\n", + input_file,line_number,yyvsp[-1].id); + FatalError(); + } + // Create a new documentation entry + doc_entry = new DocClass(yyvsp[-1].id,doc_parent()); + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + cplus_open_class(yyvsp[-1].id, (char *) 0, ""); // Open up a new C++ class + ; + break;} +case 348: +#line 3627 "parser.y" +{ + if (yyvsp[-6].id) { + char *inames[1]; + inames[0] = yyvsp[-6].id; + cplus_inherit(1,inames); + } + // Restore original doc entry for this class + doc_entry = doc_stack[doc_stack_top]; + cplus_class_close(yyvsp[-7].id); + doc_entry = 0; + doc_stack_top--; + cplus_mode = CPLUS_PUBLIC; + ObjCClass = 0; + delete yyvsp[-7].id; + delete yyvsp[-6].id; + ; + break;} +case 349: +#line 3644 "parser.y" +{ + ObjCClass = 1; + init_language(); + cplus_mode = CPLUS_PROTECTED; + doc_entry = cplus_set_class(yyvsp[-4].id); + if (!doc_entry) { + doc_entry = new DocClass(yyvsp[-4].id,doc_parent()); + } + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + ; + break;} +case 350: +#line 3655 "parser.y" +{ + cplus_unset_class(); + doc_entry = 0; + doc_stack_top--; + ; + break;} +case 351: +#line 3660 "parser.y" +{ skip_to_end(); ; + break;} +case 352: +#line 3661 "parser.y" +{ skip_to_end(); ; + break;} +case 353: +#line 3662 "parser.y" +{ + char *iname = make_name(yyvsp[-2].id); + init_language(); + lang->cpp_class_decl(yyvsp[-2].id,iname,""); + for (int i = 0; i cpp_class_decl(yyvsp[-1].ilist.names[i],iname,""); + delete [] yyvsp[-1].ilist.names[i]; + } + } + delete [] yyvsp[-1].ilist.names; + ; + break;} +case 354: +#line 3677 "parser.y" +{ yyval.id = yyvsp[-1].id;; + break;} +case 355: +#line 3678 "parser.y" +{ yyval.id = 0; ; + break;} +case 356: +#line 3682 "parser.y" +{ skip_template(); + CCode.strip(); // Strip whitespace + CCode.replace("<","< "); + CCode.replace(">"," >"); + yyval.id = CCode.get(); + ; + break;} +case 357: +#line 3688 "parser.y" +{ + yyval.id = ""; + ; + break;} +case 358: +#line 3693 "parser.y" +{ ; + break;} +case 359: +#line 3694 "parser.y" +{ + cplus_mode = CPLUS_PUBLIC; + ; + break;} +case 360: +#line 3696 "parser.y" +{ ; + break;} +case 361: +#line 3697 "parser.y" +{ + cplus_mode = CPLUS_PRIVATE; + ; + break;} +case 362: +#line 3699 "parser.y" +{ ; + break;} +case 363: +#line 3700 "parser.y" +{ + cplus_mode = CPLUS_PROTECTED; + ; + break;} +case 364: +#line 3702 "parser.y" +{ ; + break;} +case 365: +#line 3703 "parser.y" +{ + if (!Error) { + skip_decl(); + { + static int last_error_line = -1; + if (last_error_line != line_number) { + fprintf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); + FatalError(); + last_error_line = line_number; + } + Error = 1; + } + } + ; + break;} +case 366: +#line 3716 "parser.y" +{ ; + break;} +case 367: +#line 3717 "parser.y" +{ ; + break;} +case 368: +#line 3720 "parser.y" +{ + + ; + break;} +case 369: +#line 3727 "parser.y" +{ + if (cplus_mode == CPLUS_PUBLIC) { + int oldstatus = Status; + char *tm; + char *iname; + if (Active_type) delete Active_type; + Active_type = new DataType(yyvsp[-1].type); + yyvsp[-1].type->is_pointer += yyvsp[0].decl.is_pointer; + yyvsp[-1].type->is_reference = yyvsp[0].decl.is_reference; + if (yyvsp[-1].type->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,yyvsp[-1].type,yyvsp[0].decl.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name(yyvsp[0].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[0].decl.id) iname = 0; + cplus_variable(yyvsp[0].decl.id,iname,yyvsp[-1].type); + Status = oldstatus; + } + scanner_clear_start(); + delete yyvsp[-1].type; + ; + break;} +case 370: +#line 3749 "parser.y" +{ + if (cplus_mode == CPLUS_PUBLIC) { + int oldstatus = Status; + char *tm, *iname; + if (Active_type) delete Active_type; + Active_type = new DataType(yyvsp[-2].type); + yyvsp[-2].type->is_pointer += yyvsp[-1].decl.is_pointer; + yyvsp[-2].type->is_reference = yyvsp[-1].decl.is_reference; + yyvsp[-2].type->arraystr = copy_string(ArrayString); + if (yyvsp[-2].type->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,yyvsp[-2].type,yyvsp[-1].decl.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name(yyvsp[-1].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-1].decl.id) iname = 0; + cplus_variable(yyvsp[-1].decl.id,iname,yyvsp[-2].type); + Status = oldstatus; + } + scanner_clear_start(); + delete yyvsp[-2].type; + ; + break;} +case 371: +#line 3771 "parser.y" +{ + strcpy(yy_rename,yyvsp[-1].id); + Rename_true = 1; + ; + break;} +case 372: +#line 3774 "parser.y" +{ ; + break;} +case 373: +#line 3776 "parser.y" +{ + if (cplus_mode == CPLUS_PUBLIC) { + int oldstatus = Status; + char *tm, *iname; + DataType *t = new DataType (Active_type); + t->is_pointer += yyvsp[-1].decl.is_pointer; + t->is_reference = yyvsp[-1].decl.is_reference; + if (t->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,t,yyvsp[-1].decl.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name(yyvsp[-1].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-1].decl.id) iname = 0; + cplus_variable(yyvsp[-1].decl.id,iname,t); + Status = oldstatus; + delete t; + } + scanner_clear_start(); + ; + break;} +case 374: +#line 3796 "parser.y" +{ + char *iname; + if (cplus_mode == CPLUS_PUBLIC) { + int oldstatus = Status; + char *tm; + DataType *t = new DataType (Active_type); + t->is_pointer += yyvsp[-2].decl.is_pointer; + t->is_reference = yyvsp[-2].decl.is_reference; + t->arraystr = copy_string(ArrayString); + if (t->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,t,yyvsp[-2].decl.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name(yyvsp[-2].decl.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-2].decl.id) iname = 0; + cplus_variable(yyvsp[-2].decl.id,iname,t); + Status = oldstatus; + delete t; + } + scanner_clear_start(); + ; + break;} +case 375: +#line 3818 "parser.y" +{ ; + break;} +case 376: +#line 3821 "parser.y" +{ ; + break;} +case 377: +#line 3822 "parser.y" +{ + AddMethods = 1; + ; + break;} +case 378: +#line 3824 "parser.y" +{ + AddMethods = 0; + ; + break;} +case 379: +#line 3827 "parser.y" +{ + strcpy(yy_rename,yyvsp[-1].id); + Rename_true = 1; + ; + break;} +case 380: +#line 3830 "parser.y" +{ ; + break;} +case 381: +#line 3831 "parser.y" +{ + skip_decl(); + if (!Error) { + { + static int last_error_line = -1; + if (last_error_line != line_number) { + fprintf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); + FatalError(); + last_error_line = line_number; + } + Error = 1; + } + } + ; + break;} +case 382: +#line 3844 "parser.y" +{ ; + break;} +case 383: +#line 3845 "parser.y" +{ ; + break;} +case 384: +#line 3848 "parser.y" +{ + char *iname; + // An objective-C instance function + // This is like a C++ member function + + if (strcmp(yyvsp[-2].id,objc_destruct) == 0) { + // This is an objective C destructor + doc_entry = new DocDecl(yyvsp[-2].id,doc_stack[doc_stack_top]); + cplus_destructor(yyvsp[-2].id,(char *) 0); + } else { + iname = make_name(yyvsp[-2].id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-2].id) iname = 0; + cplus_member_func(yyvsp[-2].id,iname,yyvsp[-3].type,yyvsp[-1].pl,0); + scanner_clear_start(); + delete yyvsp[-3].type; + delete yyvsp[-2].id; + delete yyvsp[-1].pl; + } + ; + break;} +case 385: +#line 3868 "parser.y" +{ + char *iname; + // An objective-C class function + // This is like a c++ static member function + if (strcmp(yyvsp[-2].id,objc_construct) == 0) { + // This is an objective C constructor + doc_entry = new DocDecl(yyvsp[-2].id,doc_stack[doc_stack_top]); + cplus_constructor(yyvsp[-2].id,0,yyvsp[-1].pl); + } else { + iname = make_name(yyvsp[-2].id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == yyvsp[-2].id) iname = 0; + cplus_static_func(yyvsp[-2].id,iname,yyvsp[-3].type,yyvsp[-1].pl); + } + scanner_clear_start(); + delete yyvsp[-3].type; + delete yyvsp[-2].id; + delete yyvsp[-1].pl; + ; + break;} +case 386: +#line 3889 "parser.y" +{ CCode = ""; ; + break;} +case 387: +#line 3890 "parser.y" +{ skip_brace(); ; + break;} +case 388: +#line 3893 "parser.y" +{ + yyval.type = yyvsp[-1].type; + ; + break;} +case 389: +#line 3896 "parser.y" +{ + yyval.type = yyvsp[-2].type; + yyval.type->is_pointer += yyvsp[-1].ivalue; + ; + break;} +case 390: +#line 3900 "parser.y" +{ /* Empty type means "id" type */ + yyval.type = new DataType(T_VOID); + sprintf(yyval.type->name,"id"); + yyval.type->is_pointer = 1; + yyval.type->implicit_ptr = 1; + ; + break;} +case 391: +#line 3908 "parser.y" +{ + yyval.type = new DataType(yyvsp[-1].p->t); + delete yyvsp[-1].p; + ; + break;} +case 392: +#line 3912 "parser.y" +{ + yyval.type = new DataType(T_VOID); + sprintf(yyval.type->name,"id"); + yyval.type->is_pointer = 1; + yyval.type->implicit_ptr = 1; + ; + break;} +case 393: +#line 3920 "parser.y" +{ + Parm *p= new Parm(yyvsp[-1].type,yyvsp[0].id); + p->objc_separator = yyvsp[-2].id; + yyval.pl = yyvsp[-3].pl; + yyval.pl->append(p); + ; + break;} +case 394: +#line 3926 "parser.y" +{ + yyval.pl = new ParmList; + ; + break;} +case 395: +#line 3931 "parser.y" +{ yyval.id = copy_string(":"); ; + break;} +case 396: +#line 3932 "parser.y" +{ yyval.id = new char[strlen(yyvsp[-1].id)+2]; + strcpy(yyval.id,yyvsp[-1].id); + strcat(yyval.id,":"); + delete yyvsp[-1].id; + ; + break;} +case 397: +#line 3943 "parser.y" +{ + yyval.dlist = yyvsp[0].dlist; + yyval.dlist.names[yyval.dlist.count] = copy_string(yyvsp[-2].id); + yyval.dlist.values[yyval.dlist.count] = copy_string(yyvsp[-1].id); + format_string(yyval.dlist.values[yyval.dlist.count]); + yyval.dlist.count++; + ; + break;} +case 398: +#line 3953 "parser.y" +{ + yyval.dlist = yyvsp[-3].dlist; + yyval.dlist.names[yyval.dlist.count] = copy_string(yyvsp[-1].id); + yyval.dlist.values[yyval.dlist.count] = copy_string(yyvsp[0].id); + format_string(yyval.dlist.values[yyval.dlist.count]); + yyval.dlist.count++; + ; + break;} +case 399: +#line 3960 "parser.y" +{ + yyval.dlist.names = new char *[NI_NAMES]; + yyval.dlist.values = new char *[NI_NAMES]; + yyval.dlist.count = 0; + ; + break;} +case 400: +#line 3967 "parser.y" +{ + yyval.id = yyvsp[0].id; + ; + break;} +case 401: +#line 3970 "parser.y" +{ + yyval.id = yyvsp[0].id; + ; + break;} +case 402: +#line 3973 "parser.y" +{ + yyval.id = 0; + ; + break;} +case 403: +#line 3983 "parser.y" +{ + yyval.id = yyvsp[0].id; + ; + break;} +case 404: +#line 3986 "parser.y" +{ + yyval.id = copy_string("const"); + ; + break;} +case 405: +#line 3991 "parser.y" +{ + yyval.tmparm = yyvsp[-1].tmparm; + yyval.tmparm->next = yyvsp[0].tmparm; + ; + break;} +case 406: +#line 3997 "parser.y" +{ + yyval.tmparm = yyvsp[-1].tmparm; + yyval.tmparm->next = yyvsp[0].tmparm; + ; + break;} +case 407: +#line 4001 "parser.y" +{ yyval.tmparm = 0;; + break;} +case 408: +#line 4004 "parser.y" +{ + if (InArray) { + yyvsp[-1].type->is_pointer++; + yyvsp[-1].type->arraystr = copy_string(ArrayString); + } + yyval.tmparm = new TMParm; + yyval.tmparm->p = new Parm(yyvsp[-1].type,yyvsp[0].id); + yyval.tmparm->p->call_type = 0; + yyval.tmparm->args = tm_parm; + delete yyvsp[-1].type; + delete yyvsp[0].id; + ; + break;} +case 409: +#line 4017 "parser.y" +{ + yyval.tmparm = new TMParm; + yyval.tmparm->p = new Parm(yyvsp[-2].type,yyvsp[0].id); + yyval.tmparm->p->t->is_pointer += yyvsp[-1].ivalue; + yyval.tmparm->p->call_type = 0; + if (InArray) { + yyval.tmparm->p->t->is_pointer++; + yyval.tmparm->p->t->arraystr = copy_string(ArrayString); + } + yyval.tmparm->args = tm_parm; + delete yyvsp[-2].type; + delete yyvsp[0].id; + ; + break;} +case 410: +#line 4031 "parser.y" +{ + yyval.tmparm = new TMParm; + yyval.tmparm->p = new Parm(yyvsp[-2].type,yyvsp[0].id); + yyval.tmparm->p->t->is_reference = 1; + yyval.tmparm->p->call_type = 0; + yyval.tmparm->p->t->is_pointer++; + if (!CPlusPlus) { + fprintf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); + } + yyval.tmparm->args = tm_parm; + delete yyvsp[-2].type; + delete yyvsp[0].id; + ; + break;} +case 411: +#line 4044 "parser.y" +{ + fprintf(stderr,"%s : Line %d. Error. Function pointer not allowed (remap with typedef).\n", input_file, line_number); + FatalError(); + yyval.tmparm = new TMParm; + yyval.tmparm->p = new Parm(yyvsp[-7].type,yyvsp[-4].id); + yyval.tmparm->p->t->type = T_ERROR; + yyval.tmparm->p->name = copy_string(yyvsp[-4].id); + strcpy(yyval.tmparm->p->t->name,""); + yyval.tmparm->args = tm_parm; + delete yyvsp[-7].type; + delete yyvsp[-4].id; + delete yyvsp[-1].pl; + ; + break;} +case 412: +#line 4059 "parser.y" +{ + yyval.id = yyvsp[-1].id; + InArray = 0; + ; + break;} +case 413: +#line 4063 "parser.y" +{ + ArrayBackup = ""; + ArrayBackup << ArrayString; + ; + break;} +case 414: +#line 4066 "parser.y" +{ + yyval.id = yyvsp[-3].id; + InArray = yyvsp[-2].ivalue; + ArrayString = ""; + ArrayString << ArrayBackup; + ; + break;} +case 415: +#line 4072 "parser.y" +{ + ArrayBackup = ""; + ArrayBackup << ArrayString; + ; + break;} +case 416: +#line 4075 "parser.y" +{ + yyval.id = new char[1]; + yyval.id[0] = 0; + InArray = yyvsp[-2].ivalue; + ArrayString = ""; + ArrayString << ArrayBackup; + ; + break;} +case 417: +#line 4082 "parser.y" +{ yyval.id = new char[1]; + yyval.id[0] = 0; + InArray = 0; + ; + break;} +case 418: +#line 4088 "parser.y" +{ + tm_parm = yyvsp[-1].pl; + ; + break;} +case 419: +#line 4091 "parser.y" +{ + tm_parm = 0; + ; + break;} +case 420: +#line 4096 "parser.y" +{yyval.id = yyvsp[0].id;; + break;} +case 421: +#line 4097 "parser.y" +{ yyval.id = yyvsp[0].id;; + break;} +case 422: +#line 4103 "parser.y" +{ ; + break;} +case 423: +#line 4104 "parser.y" +{ ; + break;} +case 424: +#line 4107 "parser.y" +{ ; + break;} +case 425: +#line 4108 "parser.y" +{ ; + break;} +case 426: +#line 4109 "parser.y" +{ ; + break;} +} + /* the action file gets copied in in place of this dollarsign */ +#line 498 "/usr/local/share/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +#ifdef YYLSP_NEEDED + yylsp -= yylen; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + + *++yyvsp = yyval; + +#ifdef YYLSP_NEEDED + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } +#endif + + /* 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 - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + +yyerrlab: /* here on detecting error */ + + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ + { + ++yynerrs; + +#ifdef YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (yyn > YYFLAG && yyn < YYLAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; + } + } + yyerror(msg); + free(msg); + } + else + yyerror ("parse error; also virtual memory exceeded"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror("parse error"); + } + + goto yyerrlab1; +yyerrlab1: /* here on error raised explicitly by an action */ + + if (yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (yychar == YYEOF) + YYABORT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); +#endif + + yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + +yyerrdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif + +yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; +#ifdef YYLSP_NEEDED + yylsp--; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + +yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting error token, "); +#endif + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + yystate = yyn; + goto yynewstate; +} +#line 4143 "parser.y" + + +void error_recover() { + int c; + c = yylex(); + while ((c > 0) && (c != SEMI)) + c = yylex(); +} + +/* Called by the parser (yyparse) when an error is found.*/ +void yyerror (char *) { + // Fprintf(stderr,"%s : Line %d. Syntax error.\n", input_file, line_number); + // error_recover(); +} + diff --git a/wxPython/wxSWIG/SWIG/parser.h b/wxPython/wxSWIG/SWIG/parser.h new file mode 100644 index 0000000000..e21f089932 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/parser.h @@ -0,0 +1,149 @@ +typedef union { + char *id; + struct Declaration { + char *id; + int is_pointer; + int is_reference; + } decl; + struct InitList { + char **names; + int count; + } ilist; + struct DocList { + char **names; + char **values; + int count; + } dlist; + struct Define { + char *id; + int type; + } dtype; + DataType *type; + Parm *p; + TMParm *tmparm; + ParmList *pl; + int ivalue; +} YYSTYPE; +#define ID 258 +#define HBLOCK 259 +#define WRAPPER 260 +#define POUND 261 +#define STRING 262 +#define NUM_INT 263 +#define NUM_FLOAT 264 +#define CHARCONST 265 +#define NUM_UNSIGNED 266 +#define NUM_LONG 267 +#define NUM_ULONG 268 +#define TYPEDEF 269 +#define TYPE_INT 270 +#define TYPE_UNSIGNED 271 +#define TYPE_SHORT 272 +#define TYPE_LONG 273 +#define TYPE_FLOAT 274 +#define TYPE_DOUBLE 275 +#define TYPE_CHAR 276 +#define TYPE_VOID 277 +#define TYPE_SIGNED 278 +#define TYPE_BOOL 279 +#define TYPE_TYPEDEF 280 +#define LPAREN 281 +#define RPAREN 282 +#define COMMA 283 +#define SEMI 284 +#define EXTERN 285 +#define INIT 286 +#define LBRACE 287 +#define RBRACE 288 +#define DEFINE 289 +#define PERIOD 290 +#define CONST 291 +#define STRUCT 292 +#define UNION 293 +#define EQUAL 294 +#define SIZEOF 295 +#define MODULE 296 +#define LBRACKET 297 +#define RBRACKET 298 +#define WEXTERN 299 +#define ILLEGAL 300 +#define READONLY 301 +#define READWRITE 302 +#define NAME 303 +#define RENAME 304 +#define INCLUDE 305 +#define CHECKOUT 306 +#define ADDMETHODS 307 +#define PRAGMA 308 +#define CVALUE 309 +#define COUT 310 +#define ENUM 311 +#define ENDDEF 312 +#define MACRO 313 +#define CLASS 314 +#define PRIVATE 315 +#define PUBLIC 316 +#define PROTECTED 317 +#define COLON 318 +#define STATIC 319 +#define VIRTUAL 320 +#define FRIEND 321 +#define OPERATOR 322 +#define THROW 323 +#define TEMPLATE 324 +#define NATIVE 325 +#define INLINE 326 +#define IFDEF 327 +#define IFNDEF 328 +#define ENDIF 329 +#define ELSE 330 +#define UNDEF 331 +#define IF 332 +#define DEFINED 333 +#define ELIF 334 +#define RAW_MODE 335 +#define ALPHA_MODE 336 +#define TEXT 337 +#define DOC_DISABLE 338 +#define DOC_ENABLE 339 +#define STYLE 340 +#define LOCALSTYLE 341 +#define TYPEMAP 342 +#define EXCEPT 343 +#define IMPORT 344 +#define ECHO 345 +#define NEW 346 +#define APPLY 347 +#define CLEAR 348 +#define DOCONLY 349 +#define TITLE 350 +#define SECTION 351 +#define SUBSECTION 352 +#define SUBSUBSECTION 353 +#define LESSTHAN 354 +#define GREATERTHAN 355 +#define USERDIRECTIVE 356 +#define OC_INTERFACE 357 +#define OC_END 358 +#define OC_PUBLIC 359 +#define OC_PRIVATE 360 +#define OC_PROTECTED 361 +#define OC_CLASS 362 +#define OC_IMPLEMENT 363 +#define OC_PROTOCOL 364 +#define OR 365 +#define XOR 366 +#define AND 367 +#define LSHIFT 368 +#define RSHIFT 369 +#define PLUS 370 +#define MINUS 371 +#define STAR 372 +#define SLASH 373 +#define UMINUS 374 +#define NOT 375 +#define LNOT 376 +#define DCOLON 377 + + +extern YYSTYPE yylval; diff --git a/wxPython/wxSWIG/SWIG/parser.y b/wxPython/wxSWIG/SWIG/parser.y new file mode 100644 index 0000000000..0aba5b670d --- /dev/null +++ b/wxPython/wxSWIG/SWIG/parser.y @@ -0,0 +1,4157 @@ +%{ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ +/*********************************************************************** + * $Header$ + * + * parser.y + * + * YACC parser for parsing function declarations. + * + * *** DISCLAIMER *** + * + * This is the most ugly, incredibly henious, and completely unintelligible + * file in SWIG. While it started out simple, it has grown into a + * monster that is almost unmaintainable. A complete parser rewrite is + * currently in progress that should make this file about 1/4 the size + * that it is now. Needless to say, don't modify this file or even look + * at it for that matter! + ***********************************************************************/ + +#define yylex yylex + +extern "C" int yylex(); +void yyerror (char *s); + +extern int line_number; +extern int start_line; +extern void skip_brace(void); +extern void skip_define(void); +extern void skip_decl(void); +extern int skip_cond(int); +extern void skip_to_end(void); +extern void skip_template(void); +extern void scanner_check_typedef(void); +extern void scanner_ignore_typedef(void); +extern void scanner_clear_start(void); +extern void start_inline(char *, int); +extern void format_string(char *); +extern void swig_pragma(char *, char *); + +#include "internal.h" + +#ifdef NEED_ALLOC +void *alloca(unsigned n) { + return((void *) malloc(n)); +} +#else +// This redefinition is apparently needed on a number of machines, +// particularly HPUX +#undef alloca +#define alloca malloc +#endif + +// Initialization flags. These indicate whether or not certain +// features have been initialized. These were added to allow +// interface files without the block (required in previous +// versions). + +static int module_init = 0; /* Indicates whether the %module name was given */ +static int title_init = 0; /* Indicates whether %title directive has been given */ +static int doc_init = 0; + +static int lang_init = 0; /* Indicates if the language has been initialized */ + +static int i; + int Error = 0; +static char temp_name[128]; +static DataType *temp_typeptr, temp_type; +static char yy_rename[256]; +static int Rename_true = 0; +static DataType *Active_type = 0; // Used to support variable lists +static int Active_extern = 0; // Whether or not list is external +static int Active_static = 0; +static DataType *Active_typedef = 0; // Used for typedef lists +static int InArray = 0; // Used when an array declaration is found +static int in_then = 0; +static int in_else = 0; +static int allow = 1; // Used during conditional compilation +static int doc_scope = 0; // Documentation scoping +static String ArrayString; // Array type attached to parameter names +static String ArrayBackup; // Array backup string +static char *DefArg = 0; // Default argument hack +static char *ConstChar = 0; // Used to store raw character constants +static ParmList *tm_parm = 0; // Parameter list used to hold typemap parameters +static Hash name_hash; // Hash table containing renamings + char *objc_construct = "new"; // Objective-C constructor + char *objc_destruct = "free"; // Objective-C destructor + +/* Some macros for building constants */ + +#define E_BINARY(TARGET, SRC1, SRC2, OP) \ + TARGET = new char[strlen(SRC1) + strlen(SRC2) +strlen(OP)+1];\ + sprintf(TARGET,"%s%s%s",SRC1,OP,SRC2); + +/* C++ modes */ + +#define CPLUS_PUBLIC 1 +#define CPLUS_PRIVATE 2 +#define CPLUS_PROTECTED 3 + +int cplus_mode; + +// Declarations of some functions for handling C++ + +extern void cplus_open_class(char *name, char *rname, char *ctype); +extern void cplus_member_func(char *, char *, DataType *, ParmList *, int); +extern void cplus_constructor(char *, char *, ParmList *); +extern void cplus_destructor(char *, char *); +extern void cplus_variable(char *, char *, DataType *); +extern void cplus_static_func(char *, char *, DataType *, ParmList *); +extern void cplus_declare_const(char *, char *, DataType *, char *); +extern void cplus_class_close(char *); +extern void cplus_inherit(int, char **); +extern void cplus_cleanup(void); +extern void cplus_static_var(char *, char *, DataType *); +extern void cplus_register_type(char *); +extern void cplus_register_scope(Hash *); +extern void cplus_inherit_scope(int, char **); +extern void cplus_add_pragma(char *, char *, char *); +extern DocEntry *cplus_set_class(char *); +extern void cplus_unset_class(); +extern void cplus_abort(); + +// ---------------------------------------------------------------------- +// static init_language() +// +// Initialize the target language. +// Does nothing if this function has already been called. +// ---------------------------------------------------------------------- + +static void init_language() { + if (!lang_init) { + lang->initialize(); + + // Initialize the documentation system + + if (!doctitle) { + doctitle = new DocTitle(title,0); + } + if (!doc_init) + doctitle->usage = title; + + doc_stack[0] = doctitle; + doc_stack_top = 0; + + int oldignore = IgnoreDoc; + IgnoreDoc = 1; + if (ConfigFile) { + include_file(ConfigFile); + } + IgnoreDoc = oldignore; + } + lang_init = 1; + title_init = 1; +} + +// ---------------------------------------------------------------------- +// int promote(int t1, int t2) +// +// Promote types (for constant expressions) +// ---------------------------------------------------------------------- + +int promote(int t1, int t2) { + + if ((t1 == T_ERROR) || (t2 == T_ERROR)) return T_ERROR; + if ((t1 == T_DOUBLE) || (t2 == T_DOUBLE)) return T_DOUBLE; + if ((t1 == T_FLOAT) || (t2 == T_FLOAT)) return T_FLOAT; + if ((t1 == T_ULONG) || (t2 == T_ULONG)) return T_ULONG; + if ((t1 == T_LONG) || (t2 == T_LONG)) return T_LONG; + if ((t1 == T_UINT) || (t2 == T_UINT)) return T_UINT; + if ((t1 == T_INT) || (t2 == T_INT)) return T_INT; + if ((t1 == T_USHORT) || (t2 == T_USHORT)) return T_SHORT; + if ((t1 == T_SHORT) || (t2 == T_SHORT)) return T_SHORT; + if ((t1 == T_UCHAR) || (t2 == T_UCHAR)) return T_UCHAR; + if (t1 != t2) { + fprintf(stderr,"%s : Line %d. Type mismatch in constant expression\n", + input_file, line_number); + FatalError(); + } + return t1; +} + +/* Generate the scripting name of an object. Takes %name directive into + account among other things */ + +static char *make_name(char *name) { + // Check to see if the name is in the hash + char *nn = (char *) name_hash.lookup(name); + if (nn) return nn; // Yep, return it. + + if (Rename_true) { + Rename_true = 0; + return yy_rename; + } else { + // Now check to see if the name contains a $ + if (strchr(name,'$')) { + static String temp; + temp = ""; + temp << name; + temp.replace("$","_S_"); + return temp; + } else { + return name; + } + } +} + +/* Return the parent of a documentation entry. If wrapping externally, this is 0 */ + +static DocEntry *doc_parent() { + if (!WrapExtern) + return doc_stack[doc_stack_top]; + else + return 0; +} + +// ---------------------------------------------------------------------- +// create_function(int ext, char *name, DataType *t, ParmList *l) +// +// Creates a function and manages documentation creation. Really +// only used internally to the parser. +// ---------------------------------------------------------------------- + +void create_function(int ext, char *name, DataType *t, ParmList *l) { + if (Active_static) return; // Static declaration. Ignore + + init_language(); + if (WrapExtern) return; // External wrapper file. Ignore + + char *iname = make_name(name); + + // Check if symbol already exists + + if (add_symbol(iname, t, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Function %s multiply defined (2nd definition ignored).\n", + input_file, line_number, iname); + } else { + Stat_func++; + if (Verbose) { + fprintf(stderr,"Wrapping function : "); + emit_extern_func(name, t, l, 0, stderr); + } + + // If extern, make an extern declaration in the SWIG wrapper file + + if (ext) + emit_extern_func(name, t, l, ext, f_header); + else if (ForceExtern) { + emit_extern_func(name, t, l, 1, f_header); + } + + // If this function has been declared inline, produce a function + + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + lang->create_function(name, iname, t, l); + l->check_defined(); + t->check_defined(); + } + scanner_clear_start(); +} + +// ------------------------------------------------------------------- +// create_variable(int ext, char *name, DataType *t) +// +// Create a link to a global variable. +// ------------------------------------------------------------------- + +void create_variable(int ext, char *name, DataType *t) { + + if (WrapExtern) return; // External wrapper file. Ignore + int oldstatus = Status; + + if (Active_static) return; // If static ignore + + init_language(); + + char *iname = make_name(name); + if (add_symbol(iname, t, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Variable %s multiply defined (2nd definition ignored).\n", + input_file, line_number, iname); + } else { + Stat_var++; + if (Verbose) { + fprintf(stderr,"Wrapping variable : "); + emit_extern_var(name, t, 0, stderr); + } + + // If externed, output an external declaration + + if (ext) + emit_extern_var(name, t, ext, f_header); + else if (ForceExtern) { + emit_extern_var(name, t, 1, f_header); + } + + // If variable datatype is read-only, we'll force it to be readonly + if (t->status & STAT_READONLY) Status = Status | STAT_READONLY; + + // Now dump it out + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + lang->link_variable(name, iname, t); + t->check_defined(); + Status = oldstatus; + } + scanner_clear_start(); +} + +// ------------------------------------------------------------------ +// create_constant(char *name, DataType *type, char *value) +// +// Creates a new constant. +// ------------------------------------------------------------------- + +void create_constant(char *name, DataType *type, char *value) { + + if (Active_static) return; + if (WrapExtern) return; // External wrapper file. Ignore + init_language(); + + if (Rename_true) { + fprintf(stderr,"%s : Line %d. %%name directive ignored with #define\n", + input_file, line_number); + Rename_true = 0; + } + + if ((type->type == T_CHAR) && (!type->is_pointer)) + type->is_pointer++; + + if (!value) value = copy_string(name); + sprintf(temp_name,"const:%s", name); + if (add_symbol(temp_name, type, value)) { + fprintf(stderr,"%s : Line %d. Constant %s multiply defined. (2nd definition ignored)\n", + input_file, line_number, name); + } else { + // Update symbols value if already defined. + update_symbol(name, type, value); + + if (!WrapExtern) { // Only wrap the constant if not in %extern mode + Stat_const++; + if (Verbose) + fprintf(stderr,"Creating constant %s = %s\n", name, value); + + doc_entry = new DocDecl(name,doc_stack[doc_stack_top]); + lang->declare_const(name, name, type, value); + type->check_defined(); + } + } + scanner_clear_start(); +} + + +/* Print out array brackets */ +void print_array() { + int i; + for (i = 0; i < InArray; i++) + fprintf(stderr,"[]"); +} + +/* manipulate small stack for managing if-then-else */ + +static int then_data[100]; +static int else_data[100]; +static int allow_data[100]; +static int te_index = 0; +static int prev_allow = 1; + +void if_push() { + then_data[te_index] = in_then; + else_data[te_index] = in_else; + allow_data[te_index] = allow; + prev_allow = allow; + te_index++; + if (te_index >= 100) { + fprintf(stderr,"SWIG. Internal parser error. if-then-else stack overflow.\n"); + SWIG_exit(1); + } +} + +void if_pop() { + if (te_index > 0) { + te_index--; + in_then = then_data[te_index]; + in_else = else_data[te_index]; + allow = allow_data[te_index]; + if (te_index > 0) { + prev_allow = allow_data[te_index-1]; + } else { + prev_allow = 1; + } + } +} + +// Structures for handling code fragments built for nested classes + +struct Nested { + String code; // Associated code fragment + int line; // line number where it starts + char *name; // Name associated with this nested class + DataType *type; // Datatype associated with the name + Nested *next; // Next code fragment in list +}; + +// Some internal variables for saving nested class information + +static Nested *nested_list = 0; + +// Add a function to the nested list + +static void add_nested(Nested *n) { + Nested *n1; + if (!nested_list) nested_list = n; + else { + n1 = nested_list; + while (n1->next) n1 = n1->next; + n1->next = n; + } +} + +// Dump all of the nested class declarations to the inline processor +// However. We need to do a few name replacements and other munging +// first. This function must be called before closing a class! + +static void dump_nested(char *parent) { + Nested *n,*n1; + n = nested_list; + int oldstatus = Status; + + Status = STAT_READONLY; + while (n) { + // Token replace the name of the parent class + n->code.replace("$classname",parent); + + // Fix up the name of the datatype (for building typedefs and other stuff) + sprintf(n->type->name,"%s_%s",parent,n->name); + + // Add the appropriate declaration to the C++ processor + doc_entry = new DocDecl(n->name,doc_stack[doc_stack_top]); + cplus_variable(n->name,(char *) 0, n->type); + + // Dump the code to the scanner + if (Verbose) + fprintf(stderr,"Splitting from %s : (line %d) \n%s\n", parent,n->line, n->code.get()); + + fprintf(f_header,"\n%s\n", n->code.get()); + start_inline(n->code.get(),n->line); + + n1 = n->next; + delete n; + n = n1; + } + nested_list = 0; + Status = oldstatus; +} + +%} + +/* The type of each node in the parse tree + must be one of the elements of the union + given below. This is used to derive the + C++ declaration for "yylval" that appears + in parser.tab.h. */ + +%union { + char *id; + struct Declaration { + char *id; + int is_pointer; + int is_reference; + } decl; + struct InitList { + char **names; + int count; + } ilist; + struct DocList { + char **names; + char **values; + int count; + } dlist; + struct Define { + char *id; + int type; + } dtype; + DataType *type; + Parm *p; + TMParm *tmparm; + ParmList *pl; + int ivalue; +}; + +%token ID +%token HBLOCK WRAPPER POUND +%token STRING +%token NUM_INT NUM_FLOAT CHARCONST NUM_UNSIGNED NUM_LONG NUM_ULONG +%token TYPEDEF +%token TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_TYPEDEF +%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE DEFINE PERIOD +%token CONST STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET +%token WEXTERN ILLEGAL +%token READONLY READWRITE NAME RENAME INCLUDE CHECKOUT ADDMETHODS PRAGMA +%token CVALUE COUT +%token ENUM ENDDEF MACRO +%token CLASS PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND OPERATOR THROW TEMPLATE +%token NATIVE INLINE +%token IFDEF IFNDEF ENDIF ELSE UNDEF IF DEFINED ELIF +%token RAW_MODE ALPHA_MODE TEXT DOC_DISABLE DOC_ENABLE STYLE LOCALSTYLE +%token TYPEMAP EXCEPT IMPORT ECHO NEW APPLY CLEAR DOCONLY +%token TITLE SECTION SUBSECTION SUBSUBSECTION +%token LESSTHAN GREATERTHAN +%token USERDIRECTIVE + +/* Objective C tokens */ + +%token OC_INTERFACE OC_END OC_PUBLIC OC_PRIVATE OC_PROTECTED OC_CLASS OC_IMPLEMENT OC_PROTOCOL + +%left OR +%left XOR +%left AND +%left LSHIFT RSHIFT +%left PLUS MINUS +%left STAR SLASH +%left UMINUS NOT LNOT +%left DCOLON + +%type extern array array2 parm_specifier parm_specifier_list; +%type parms ptail; +%type

    parm parm_type; +%type typemap_parm tm_list tm_tail; +%type pname cpptype base_specifier access_specifier typemap_name tm_method idstring; +%type type opt_signed opt_unsigned strict_type; +%type declaration nested_decl; +%type stars cpp_const_expr; +%type initlist base_list inherit; +%type definetype definetail def_args; +%type etype; +%type expr; +%type ename stylearg objc_inherit; +%type stylelist styletail; +%type objc_ret_type objc_arg_type; +%type objc_protolist objc_separator; +%type objc_args; + +%% + +/* The productions of the grammar with their + associated semantic actions. */ + +program : { + { + int ii; + for (ii = 0; ii < 256; ii++) { + handler_stack[ii] = 0; + } + handler_stack[0] = comment_handler; + } + doc_stack[0] = doctitle; + } command { + CommentHandler::cleanup(); + cplus_cleanup(); + doc_entry = doctitle; + if (lang_init) { + lang->close(); + } + if (te_index) { + fprintf(stderr,"%s : EOF. Missing #endif detected.\n", input_file); + FatalError(); + } + } + ; + +command : command statement { + scanner_clear_start(); + Error = 0; + } + | empty { + } + ; + +statement : INCLUDE idstring { + if (allow) { +// init_language(); + doc_entry = 0; + // comment_handler->clear(); + include_file($2); + } + } + +/* %extern directive */ + + | WEXTERN idstring { + if (allow) { + int oldextern = WrapExtern; +// init_language(); + doc_entry = 0; + // comment_handler->clear(); + WrapExtern = 1; + if (include_file($2) >= 0) { + add_symbol("SWIGEXTERN",0,0); + } else { + WrapExtern = oldextern; + } + } + } + +/* %import directive. Like %extern but calls out to a language module */ + + | IMPORT idstring { + if (allow) { + int oldextern = WrapExtern; + init_language(); + doc_entry = 0; + WrapExtern = 1; + if (include_file($2) >= 0) { + add_symbol("SWIGEXTERN",0,0); + lang->import($2); + } else { + WrapExtern = oldextern; + } + } + } + +/* %checkout directive. Like %include, but simply copies the file into the + current directory */ + + | CHECKOUT idstring { + if (allow) { + if ((checkout_file($2,$2)) == 0) { + fprintf(stderr,"%s checked out from the SWIG library.\n",$2); + } + } + } + +/* An unknown C preprocessor statement. Just throw it away */ + + | POUND { + if (allow) { + doc_entry = 0; + if (Verbose) { + fprintf(stderr,"%s : Line %d. CPP %s ignored.\n", input_file, line_number,$1); + } + } + } + +/* A variable declaration */ + + | extern type declaration array2 def_args { + if (allow) { + init_language(); + if (Active_type) delete Active_type; + Active_type = new DataType($2); + Active_extern = $1; + $2->is_pointer += $3.is_pointer; + if ($4 > 0) { + $2->is_pointer++; + $2->status = STAT_READONLY; + $2->arraystr = copy_string(ArrayString); + } + if ($3.is_reference) { + fprintf(stderr,"%s : Line %d. Error. Linkage to C++ reference not allowed.\n", input_file, line_number); + FatalError(); + } else { + if ($2->qualifier) { + if ((strcmp($2->qualifier,"const") == 0)) { + if ($5.type != T_ERROR) + create_constant($3.id, $2, $5.id); + } else + create_variable($1,$3.id,$2); + } else + create_variable($1,$3.id,$2); + } + } + delete $2; + } stail { } + +/* Global variable that smells like a function pointer */ + + | extern strict_type LPAREN STAR { + skip_decl(); + fprintf(stderr,"%s : Line %d. Function pointers not currently supported.\n", + input_file, line_number); + } + +/* A static variable declaration (Ignored) */ + + | STATIC type declaration array2 def_args { + if (Verbose) { + fprintf(stderr,"static variable %s ignored.\n",$3.id); + } + Active_static = 1; + delete $2; + } stail { + Active_static = 0; + } + +/* Global variable that smells like a function pointer */ + + | STATIC strict_type LPAREN STAR { + skip_decl(); + fprintf(stderr,"%s : Line %d. Function pointers not currently supported.\n", + input_file, line_number); + } + + +/* A function declaration */ + + | extern type declaration LPAREN parms RPAREN cpp_const { + if (allow) { + init_language(); + if (Active_type) delete Active_type; + Active_type = new DataType($2); + Active_extern = $1; + $2->is_pointer += $3.is_pointer; + $2->is_reference = $3.is_reference; + create_function($1, $3.id, $2, $5); + } + delete $2; + delete $5; + } stail { } + +/* A function declaration with code after it */ + + | extern type declaration LPAREN parms RPAREN func_end { + if (allow) { + init_language(); + $2->is_pointer += $3.is_pointer; + $2->is_reference = $3.is_reference; + create_function($1, $3.id, $2, $5); + } + delete $2; + delete $5; + }; + +/* A function declared without any return datatype */ + + | extern declaration LPAREN parms RPAREN cpp_const { + if (allow) { + init_language(); + DataType *t = new DataType(T_INT); + t->is_pointer += $2.is_pointer; + t->is_reference = $2.is_reference; + create_function($1,$2.id,t,$4); + delete t; + } + } stail { }; + +/* A static function declaration code after it */ + + | STATIC type declaration LPAREN parms RPAREN func_end { + if ((allow) && (Inline)) { + if (strlen(CCode.get())) { + init_language(); + $2->is_pointer += $3.is_pointer; + $2->is_reference = $3.is_reference; + create_function(0, $3.id, $2, $5); + } + } + delete $2; + delete $5; + }; + +/* A function with an explicit inline directive. Not safe to use inside a %inline block */ + + | INLINE type declaration LPAREN parms RPAREN func_end { + if (allow) { + init_language(); + $2->is_pointer += $3.is_pointer; + $2->is_reference = $3.is_reference; + if (Inline) { + fprintf(stderr,"%s : Line %d. Repeated %%inline directive.\n",input_file,line_number); + FatalError(); + } else { + if (strlen(CCode.get())) { + fprintf(f_header,"static "); + emit_extern_func($3.id,$2,$5,3,f_header); + fprintf(f_header,"%s\n",CCode.get()); + } + create_function(0, $3.id, $2, $5); + } + } + delete $2; + delete $5; + }; + +/* A static function declaration (ignored) */ + + | STATIC type declaration LPAREN parms RPAREN cpp_const { + if (allow) { + if (Verbose) { + fprintf(stderr,"static function %s ignored.\n", $3.id); + } + } + Active_static = 1; + delete $2; + delete $5; + } stail { + Active_static = 0; + } + +/* Enable Read-only mode */ + + | READONLY { + if (allow) + Status = Status | STAT_READONLY; + } + +/* Enable Read-write mode */ + + | READWRITE { + if (allow) + Status = Status & ~STAT_READONLY; + } + +/* New %name directive */ + | NAME LPAREN ID RPAREN { + if (allow) { + strcpy(yy_rename,$3); + Rename_true = 1; + } + } + +/* %rename directive */ + | RENAME ID ID SEMI { + if (name_hash.lookup($2)) { + name_hash.remove($2); + } + name_hash.add($2,copy_string($3)); + } + +/* %new directive */ + + | NEW { + NewObject = 1; + } statement { + NewObject = 0; + } + +/* Empty name directive. No longer allowed */ + + | NAME LPAREN RPAREN { + if (allow) { + fprintf(stderr,"%s : Lind %d. Empty %%name() is no longer supported.\n", + input_file, line_number); + FatalError(); + } + } cpp { + Rename_true = 0; + } + +/* A native wrapper function */ + + | NATIVE LPAREN ID RPAREN extern ID SEMI { + if (allow && (!WrapExtern)) { + init_language(); + if (add_symbol($3,(DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Name of native function %s conflicts with previous declaration (ignored)\n", + input_file, line_number, $3); + } else { + doc_entry = new DocDecl($3,doc_stack[doc_stack_top]); + lang->add_native($3,$6); + } + } + } + | NATIVE LPAREN ID RPAREN extern type declaration LPAREN parms RPAREN SEMI { + if (allow && (!WrapExtern)) { + init_language(); + $6->is_pointer += $7.is_pointer; + if (add_symbol($3,(DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Name of native function %s conflicts with previous declaration (ignored)\n", + input_file, line_number, $3); + } else { + if ($5) { + emit_extern_func($7.id, $6, $9, $5, f_header); + } + doc_entry = new DocDecl($3,doc_stack[doc_stack_top]); + lang->add_native($3,$7.id); + } + } + delete $6; + delete $9; + } + +/* %title directive */ + + | TITLE STRING styletail { + if (allow && (!WrapExtern)) { + if (!title_init) { + title_init = 1; + doc_init = 1; + if (!comment_handler) { + comment_handler = new CommentHandler(); + } + { + int ii; + for (ii = 0; ii < $3.count; ii++) { + comment_handler->style($3.names[ii],$3.values[ii]); + } + } + // Create a new title for documentation + { + int temp = line_number; + line_number = $1; + if (!doctitle) + doctitle = new DocTitle($2,0); + else { + doctitle->name = copy_string(title); + doctitle->line_number = $1; + doctitle->end_line = $1; + } + line_number = temp; + } + doctitle->usage = $2; + doc_entry = doctitle; + doc_stack[0] = doc_entry; + doc_stack_top = 0; + handler_stack[0] = comment_handler; + { + int ii; + for (ii = 0; ii < $3.count; ii++) { + doc_stack[doc_stack_top]->style($3.names[ii],$3.values[ii]); + } + } + + } else { + // Ignore it + } + } + } + + +/* %section directive */ + + | SECTION STRING styletail { + if (allow && (!WrapExtern) && (!IgnoreDoc)) { + // Copy old comment handler + // if (handler_stack[1]) delete handler_stack[1]; + handler_stack[1] = new CommentHandler(handler_stack[0]); + comment_handler = handler_stack[1]; + { + int ii; + for (ii = 0; ii < $3.count; ii++) { + comment_handler->style($3.names[ii],$3.values[ii]); + } + } + { + int temp = line_number; + line_number = $1; + doc_entry = new DocSection($2,doc_stack[0]); + line_number = temp; + } + doc_stack_top = 1; + doc_stack[1] = doc_entry; + { + int ii; + for (ii = 0; ii < $3.count; ii++) { + doc_stack[doc_stack_top]->style($3.names[ii],$3.values[ii]); + } + } + } + } + +/* %subsection directive */ + | SUBSECTION STRING styletail { + if (allow && (!WrapExtern) && (!IgnoreDoc)) { + if (doc_stack_top < 1) { + fprintf(stderr,"%s : Line %d. Can't apply %%subsection here.\n", input_file,line_number); + FatalError(); + } else { + + // Copy old comment handler + // if (handler_stack[2]) delete handler_stack[2]; + handler_stack[2] = new CommentHandler(handler_stack[1]); + comment_handler = handler_stack[2]; + { + int ii; + for (ii = 0; ii < $3.count; ii++) { + comment_handler->style($3.names[ii],$3.values[ii]); + } + } + { + int temp = line_number; + line_number = $1; + doc_entry = new DocSection($2,doc_stack[1]); + line_number = temp; + } + doc_stack_top = 2; + doc_stack[2] = doc_entry; + { + int ii; + for (ii = 0; ii < $3.count; ii++) { + doc_stack[doc_stack_top]->style($3.names[ii],$3.values[ii]); + } + } + } + } + } + +/* %subsubsection directive */ + | SUBSUBSECTION STRING styletail { + if (allow && (!WrapExtern) && (!IgnoreDoc)) { + if (doc_stack_top < 2) { + fprintf(stderr,"%s : Line %d. Can't apply %%subsubsection here.\n", input_file,line_number); + FatalError(); + } else { + + // Copy old comment handler + + // if (handler_stack[3]) delete handler_stack[3]; + handler_stack[3] = new CommentHandler(handler_stack[2]); + comment_handler = handler_stack[3]; + { + int ii; + for (ii = 0; ii < $3.count; ii++) { + comment_handler->style($3.names[ii],$3.values[ii]); + } + } + { + int temp = line_number; + line_number = $1; + doc_entry = new DocSection($2,doc_stack[2]); + line_number = temp; + } + doc_stack_top = 3; + doc_stack[3] = doc_entry; + { + int ii; + for (ii = 0; ii < $3.count; ii++) { + doc_stack[doc_stack_top]->style($3.names[ii],$3.values[ii]); + } + } + } + } + } + +/* %alpha directive (obsolete) */ + | ALPHA_MODE { + if (allow && (!WrapExtern)) { + fprintf(stderr,"%%alpha directive is obsolete. Use '%%style sort' instead.\n"); + handler_stack[0]->style("sort",0); + doc_stack[0]->style("sort",0); + } + } +/* %raw directive (obsolete) */ + | RAW_MODE { + if (allow && (!WrapExtern)) { + fprintf(stderr,"%%raw directive is obsolete. Use '%%style nosort' instead.\n"); + handler_stack[0]->style("nosort",0); + doc_stack[0]->style("nosort",0); + } + } + + | doc_enable { } + +/* %text directive */ + + | TEXT HBLOCK { + if (allow && (!WrapExtern)) { + $2[strlen($2) - 1] = 0; + doc_entry = new DocText($2,doc_stack[doc_stack_top]); + doc_entry = 0; + } + } + + + | typedef_decl { } + +/* Code insertion block */ + + | HBLOCK { + if (allow && (!WrapExtern)) { + init_language(); + $1[strlen($1) - 1] = 0; +// fprintf(f_header,"#line %d \"%s\"\n", start_line, input_file); + fprintf(f_header, "%s\n", $1); + } + } + +/* Super-secret undocumented for people who really know what's going on feature */ + + | WRAPPER HBLOCK { + if (allow && (!WrapExtern)) { + init_language(); + $2[strlen($2) - 1] = 0; + fprintf(f_wrappers,"%s\n",$2); + } + } + +/* Initialization code */ + + | INIT HBLOCK { + if (allow && (!WrapExtern)) { + init_language(); + $2[strlen($2) -1] = 0; + fprintf(f_init,"%s\n", $2); + } + } + +/* Inline block */ + | INLINE HBLOCK { + if (allow && (!WrapExtern)) { + init_language(); + $2[strlen($2) - 1] = 0; + fprintf(f_header, "%s\n", $2); + start_inline($2,start_line); + } + } + +/* Echo mode */ + | ECHO HBLOCK { + if (allow && (!WrapExtern)) { + fprintf(stderr,"%s\n", $2); + } + } + + | ECHO STRING { + if (allow && (!WrapExtern)) { + fprintf(stderr,"%s\n", $2); + } + } + +/* Disable code generation */ + | DOCONLY { + DocOnly = 1; + } + +/* Init directive--to avoid errors in other modules */ + + | INIT ID initlist { + if (allow) { + if (!module_init) { + lang->set_init($2); + module_init = 1; + init_language(); + } else { + if (Verbose) + fprintf(stderr,"%s : Line %d. %%init %s ignored.\n", + input_file, line_number, $2); + } + if ($3.count > 0) { + fprintf(stderr,"%s : Line %d. Warning. Init list no longer supported.\n", + input_file,line_number); + } + } + for (i = 0; i < $3.count; i++) + if ($3.names[i]) delete [] $3.names[i]; + delete [] $3.names; + } +/* Module directive */ + + | MODULE ID initlist { + if (allow) { + if ($3.count) + lang->set_module($2,$3.names); + else + lang->set_module($2,0); + module_init = 1; + init_language(); + } + for (i = 0; i < $3.count; i++) + if ($3.names[i]) delete [] $3.names[i]; + delete [] $3.names; + } + +/* #define directive */ + + | DEFINE ID definetail { + if (allow) { + if (($3.type != T_ERROR) && ($3.type != T_SYMBOL)) { + init_language(); + temp_typeptr = new DataType($3.type); + create_constant($2, temp_typeptr, $3.id); + delete temp_typeptr; + } else if ($3.type == T_SYMBOL) { + // Add a symbol to the SWIG symbol table + if (add_symbol($2,(DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Warning. Symbol %s already defined.\n", + input_file,line_number, $2); + } + } + } + } + +/* A CPP Macro. Ignore (hopefully) */ + + | DEFINE MACRO { + if (Verbose) { + fprintf(stderr,"%s : Line %d. CPP Macro ignored.\n", input_file, line_number); + } + } + +/* An undef directive */ + | UNDEF ID { + remove_symbol($2); + } + +/* Enumerations */ + + | extern ENUM ename LBRACE { scanner_clear_start(); } enumlist RBRACE SEMI { + if (allow) { + init_language(); + if ($3) { + temp_type.type = T_INT; + temp_type.is_pointer = 0; + temp_type.implicit_ptr = 0; + sprintf(temp_type.name,"int"); + temp_type.typedef_add($3,1); + } + } + } + +/* A typdef'd enum. Pretty common in C headers */ + + | TYPEDEF ENUM ename LBRACE { scanner_clear_start(); } enumlist RBRACE ID { + if (allow) { + init_language(); + temp_type.type = T_INT; + temp_type.is_pointer = 0; + temp_type.implicit_ptr = 0; + sprintf(temp_type.name,"int"); + Active_typedef = new DataType(&temp_type); + temp_type.typedef_add($8,1); + } + } typedeflist { } + +/* ----------------------------------------------------------------- + typemap support. + + These constructs are used to support type-maps. + ----------------------------------------------------------------- */ + +/* Create a new typemap */ + + | TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE { + TMParm *p; + skip_brace(); + p = $7; + while (p) { + typemap_register($5,$3,p->p->t,p->p->name,CCode,p->args); + p = p->next; + } + delete $3; + delete $5; + } + +/* Create a new typemap in current language */ + | TYPEMAP LPAREN tm_method RPAREN tm_list LBRACE { + if (!typemap_lang) { + fprintf(stderr,"SWIG internal error. No typemap_lang specified.\n"); + fprintf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number); + FatalError(); + } else { + TMParm *p; + skip_brace(); + p = $5; + while (p) { + typemap_register($3,typemap_lang,p->p->t,p->p->name,CCode,p->args); + p = p->next; + } + } + delete $3; + } + +/* Clear a typemap */ + + | TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list SEMI { + TMParm *p; + p = $7; + while (p) { + typemap_clear($5,$3,p->p->t,p->p->name); + p = p->next; + } + delete $3; + delete $5; + } +/* Clear a typemap in current language */ + + | TYPEMAP LPAREN tm_method RPAREN tm_list SEMI { + if (!typemap_lang) { + fprintf(stderr,"SWIG internal error. No typemap_lang specified.\n"); + fprintf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number); + FatalError(); + } else { + TMParm *p; + p = $5; + while (p) { + typemap_clear($3,typemap_lang,p->p->t,p->p->name); + p = p->next; + } + } + delete $3; + } + +/* Copy a typemap */ + + | TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list EQUAL typemap_parm SEMI { + TMParm *p; + p = $7; + while (p) { + typemap_copy($5,$3,$9->p->t,$9->p->name,p->p->t,p->p->name); + p = p->next; + } + delete $3; + delete $5; + delete $9->p; + delete $9; + } + +/* Copy typemap in current language */ + + | TYPEMAP LPAREN tm_method RPAREN tm_list EQUAL typemap_parm SEMI { + if (!typemap_lang) { + fprintf(stderr,"SWIG internal error. No typemap_lang specified.\n"); + fprintf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number); + FatalError(); + } else { + TMParm *p; + p = $5; + while (p) { + typemap_copy($3,typemap_lang,$7->p->t,$7->p->name,p->p->t,p->p->name); + p = p->next; + } + } + delete $3; + delete $7->p; + delete $7; + } +/* ----------------------------------------------------------------- + apply and clear support (for typemaps) + ----------------------------------------------------------------- */ + + | APPLY typemap_parm LBRACE tm_list RBRACE { + TMParm *p; + p = $4; + while(p) { + typemap_apply($2->p->t,$2->p->name,p->p->t,p->p->name); + p = p->next; + } + delete $4; + delete $2->args; + delete $2; + } + | CLEAR tm_list SEMI { + TMParm *p; + p = $2; + while (p) { + typemap_clear_apply(p->p->t, p->p->name); + p = p->next; + } + } + + +/* ----------------------------------------------------------------- + exception support + + These constructs are used to define exceptions + ----------------------------------------------------------------- */ + +/* An exception definition */ + | EXCEPT LPAREN ID RPAREN LBRACE { + skip_brace(); + fragment_register("except",$3, CCode); + delete $3; + } + +/* A Generic Exception (no language specified */ + | EXCEPT LBRACE { + skip_brace(); + fragment_register("except",typemap_lang, CCode); + } + +/* Clear an exception */ + + | EXCEPT LPAREN ID RPAREN SEMI { + fragment_clear("except",$3); + } + +/* Generic clear */ + | EXCEPT SEMI { + fragment_clear("except",typemap_lang); + } + +/* Miscellaenous stuff */ + + | SEMI { } + | cpp { } + | objective_c { } + | error { + if (!Error) { + { + static int last_error_line = -1; + if (last_error_line != line_number) { + fprintf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); + FatalError(); + last_error_line = line_number; + // Try to make some kind of recovery. + skip_decl(); + } + Error = 1; + } + } + } + +/* A an extern C type declaration. Does nothing, but is ignored */ + + | EXTERN STRING LBRACE command RBRACE { } + | cond_compile { } + +/* Officially, this directive doesn't exist yet */ + + | pragma { } + +/* %style directive. This applies to all current styles */ + + | STYLE stylelist { + { + int ii,jj; + for (ii = 0; ii < $2.count; ii++) { + comment_handler->style($2.names[ii],$2.values[ii]); + for (jj = 0; jj < doc_stack_top; jj++) + doc_stack[jj]->style($2.names[ii],$2.values[ii]); + if (doctitle) + doctitle->style($2.names[ii],$2.values[ii]); + doc->style($2.names[ii],$2.values[ii]); + } + } + } + +/* %localstyle directive. This applies only to the current style */ + + | LOCALSTYLE stylelist { + { + int ii; + for (ii = 0; ii < $2.count; ii++) { + comment_handler = new CommentHandler(comment_handler); + handler_stack[doc_stack_top] = comment_handler; + comment_handler->style($2.names[ii],$2.values[ii]); + doc_stack[doc_stack_top]->style($2.names[ii],$2.values[ii]); + } + } + } + +/* User defined directive */ + | user_directive{ } + ; + + +/* Dcumentation disable/enable */ + +doc_enable : DOC_DISABLE { + if (allow) { + if (IgnoreDoc) { + /* Already in a disabled documentation */ + doc_scope++; + } else { + if (Verbose) + fprintf(stderr,"%s : Line %d. Documentation disabled.\n", input_file, line_number); + IgnoreDoc = 1; + doc_scope = 1; + } + } + } +/* %enabledoc directive */ + | DOC_ENABLE { + if (allow) { + if (IgnoreDoc) { + if (doc_scope > 1) { + doc_scope--; + } else { + if (Verbose) + fprintf(stderr,"%s : Line %d. Documentation enabled.\n", input_file, line_number); + IgnoreDoc = 0; + doc_scope = 0; + } + } + } + } + ; + +/* Note : This really needs to be re-done */ + +/* A typedef with pointers */ +typedef_decl : TYPEDEF type declaration { + if (allow) { + init_language(); + /* Add a new typedef */ + Active_typedef = new DataType($2); + $2->is_pointer += $3.is_pointer; + $2->typedef_add($3.id); + /* If this is %typedef, add it to the header */ + if ($1) + fprintf(f_header,"typedef %s %s;\n", $2->print_full(), $3.id); + cplus_register_type($3.id); + } + } typedeflist { }; + +/* A rudimentary typedef involving function pointers */ + + | TYPEDEF type LPAREN STAR pname RPAREN LPAREN parms RPAREN SEMI { + if (allow) { + init_language(); + /* Typedef'd pointer */ + if ($1) { + sprintf(temp_name,"(*%s)",$5); + fprintf(f_header,"typedef "); + emit_extern_func(temp_name, $2,$8,0,f_header); + } + strcpy($2->name,""); + $2->type = T_USER; + $2->is_pointer = 1; + $2->typedef_add($5,1); + cplus_register_type($5); + } + delete $2; + delete $5; + delete $8; + } + +/* A typedef involving function pointers again */ + + | TYPEDEF type stars LPAREN STAR pname RPAREN LPAREN parms RPAREN SEMI { + if (allow) { + init_language(); + if ($1) { + $2->is_pointer += $3; + sprintf(temp_name,"(*%s)",$6); + fprintf(f_header,"typedef "); + emit_extern_func(temp_name, $2,$9,0,f_header); + } + + /* Typedef'd pointer */ + strcpy($2->name,""); + $2->type = T_USER; + $2->is_pointer = 1; + $2->typedef_add($6,1); + cplus_register_type($6); + } + delete $2; + delete $6; + delete $9; + } + +/* A typedef involving arrays */ + + | TYPEDEF type declaration array { + if (allow) { + init_language(); + Active_typedef = new DataType($2); + // This datatype is going to be readonly + + $2->status = STAT_READONLY | STAT_REPLACETYPE; + $2->is_pointer += $3.is_pointer; + // Turn this into a "pointer" corresponding to the array + $2->is_pointer++; + $2->arraystr = copy_string(ArrayString); + $2->typedef_add($3.id); + fprintf(stderr,"%s : Line %d. Warning. Array type %s will be read-only without a typemap\n",input_file,line_number, $3.id); + cplus_register_type($3.id); + + } + } typedeflist { } + ; + +/* ------------------------------------------------------------------------ + Typedef list + + The following rules are used to manage typedef lists. Only a temporary + hack until the SWIG 2.0 parser gets online. + + Active_typedef contains the datatype of the last typedef (if applicable) + ------------------------------------------------------------------------ */ + + +typedeflist : COMMA declaration typedeflist { + if (allow) { + if (Active_typedef) { + DataType *t; + t = new DataType(Active_typedef); + t->is_pointer += $2.is_pointer; + t->typedef_add($2.id); + cplus_register_type($2.id); + delete t; + } + } + } + | COMMA declaration array { + DataType *t; + t = new DataType(Active_typedef); + t->status = STAT_READONLY | STAT_REPLACETYPE; + t->is_pointer += $2.is_pointer + 1; + t->arraystr = copy_string(ArrayString); + t->typedef_add($2.id); + cplus_register_type($2.id); + delete t; + fprintf(stderr,"%s : Line %d. Warning. Array type %s will be read-only without a typemap.\n",input_file,line_number, $2.id); + } + | empty { } + ; + +/* ---------------------------------------------------------------------------------- + Conditional Compilation + + SWIG supports the following constructs + #ifdef + #ifndef + #else + #endif + #if defined(ID) + #if ! defined(ID) + #elif + + #if, and #elif are a little weak in this implementation + ---------------------------------------------------------------------------------- */ + + +/* #ifdef directive */ +cond_compile : IFDEF ID { + /* Push old if-then-else status */ + if_push(); + /* Look a symbol up in the symbol table */ + if (lookup_symbol($2)) { + in_then = 1; + in_else = 0; + allow = 1 & prev_allow; + } else { + /* Condition is false. Skip over whatever is in this block */ + in_else = skip_cond(1); + if (in_else == -1) { + /* Unrecoverable error */ + SWIG_exit(1); + } + if (!in_else) { + if_pop(); // Pop out. Reached end of block + } else { + allow = prev_allow; + in_then = 0; + } + } + } + +/* #ifndef directive */ + + | IFNDEF ID { + if_push(); + if (lookup_symbol($2)) { + /* Condition is false. Skip over whatever is in this block */ + in_else = skip_cond(1); + if (in_else == -1) { + /* Unrecoverable error */ + SWIG_exit(1); + } + if (!in_else) { + if_pop(); // Pop out. Reached end of block + } else { + allow = prev_allow; + in_then = 0; + } + } else { + in_then = 1; + in_else = 0; + allow = 1 & prev_allow; + } + } + +/* #else directive */ + | ELSE { + if ((!in_then) || (in_else)) { + fprintf(stderr,"%s : Line %d. Misplaced else\n", input_file, line_number); + FatalError(); + } else { + in_then = 0; + in_else = 1; + if (allow) { + allow = 0; + /* Skip over rest of the conditional */ + skip_cond(0); + if_pop(); + } else { + allow = 1; + } + allow = allow & prev_allow; + } + } +/* #endif directive */ + | ENDIF { + if ((!in_then) && (!in_else)) { + fprintf(stderr,"%s : Line %d. Misplaced endif\n", input_file, line_number); + FatalError(); + } else { + if_pop(); + } + } + +/* #if */ + | IF cpp_const_expr { + /* Push old if-then-else status */ + if_push(); + if ($2) { + in_then = 1; + in_else = 0; + allow = 1 & prev_allow; + } else { + /* Condition is false. Skip over whatever is in this block */ + in_else = skip_cond(1); + if (in_else == -1) { + /* Unrecoverable error */ + SWIG_exit(1); + } + if (!in_else) { + if_pop(); // Pop out. Reached end of block + } else { + allow = prev_allow; + in_then = 0; + } + } + } + +/* #elif. We treat this identical to an #if. Abit of a hack, but what + the hell. */ + + | ELIF cpp_const_expr { + /* have to pop old if clause off */ + if_pop(); + + /* Push old if-then-else status */ + if_push(); + if ($2) { + in_then = 1; + in_else = 0; + allow = 1 & prev_allow; + } else { + /* Condition is false. Skip over whatever is in this block */ + in_else = skip_cond(1); + if (in_else == -1) { + /* Unrecoverable error */ + SWIG_exit(1); + } + if (!in_else) { + if_pop(); // Pop out. Reached end of block + } else { + allow = prev_allow; + in_then = 0; + } + } + } + ; + +/* C preprocessor expression (only used for conditional compilation */ + +cpp_const_expr : DEFINED LPAREN ID RPAREN { + + /* Look ID up in the symbol table */ + if (lookup_symbol($3)) { + $$ = 1; + } else { + $$ = 0; + } + } + | DEFINED ID { + if (lookup_symbol($2)) { + $$ = 1; + } else { + $$ = 0; + } + } + | LNOT cpp_const_expr { + if ($2) $$ = 0; + else $$ = 1; + } + ; + +pragma : PRAGMA LPAREN ID COMMA ID stylearg RPAREN { + if (allow && (!WrapExtern)) + lang->pragma($3,$5,$6); + fprintf(stderr,"%s : Line %d. Warning. '%%pragma(lang,opt=value)' syntax is obsolete.\n", + input_file,line_number); + fprintf(stderr," Use '%%pragma(lang) opt=value' instead.\n"); + } + + | PRAGMA ID stylearg { + if (allow && (!WrapExtern)) + swig_pragma($2,$3); + } + | PRAGMA LPAREN ID RPAREN ID stylearg { + if (allow && (!WrapExtern)) + lang->pragma($3,$5,$6); + } + ; + +/* Allow lists of variables and functions to be built up */ + +stail : SEMI { } + | COMMA declaration array2 def_args { + if (allow) { + init_language(); + temp_typeptr = new DataType(Active_type); + temp_typeptr->is_pointer += $2.is_pointer; + if ($3 > 0) { + temp_typeptr->is_pointer++; + temp_typeptr->status = STAT_READONLY; + temp_typeptr->arraystr = copy_string(ArrayString); + } + if ($2.is_reference) { + fprintf(stderr,"%s : Line %d. Error. Linkage to C++ reference not allowed.\n", input_file, line_number); + FatalError(); + } else { + if (temp_typeptr->qualifier) { + if ((strcmp(temp_typeptr->qualifier,"const") == 0)) { + /* Okay. This is really some sort of C++ constant here. */ + if ($4.type != T_ERROR) + create_constant($2.id, temp_typeptr, $4.id); + } else + create_variable(Active_extern,$2.id, temp_typeptr); + } else + create_variable(Active_extern, $2.id, temp_typeptr); + } + delete temp_typeptr; + } + } stail { } + | COMMA declaration LPAREN parms RPAREN cpp_const { + if (allow) { + init_language(); + temp_typeptr = new DataType(Active_type); + temp_typeptr->is_pointer += $2.is_pointer; + temp_typeptr->is_reference = $2.is_reference; + create_function(Active_extern, $2.id, temp_typeptr, $4); + delete temp_typeptr; + } + delete $4; + } stail { } + ; + +definetail : definetype ENDDEF { + $$ = $1; + } + | ENDDEF { + $$.type = T_SYMBOL; + } + | error ENDDEF { + if (Verbose) + fprintf(stderr,"%s : Line %d. Warning. Unable to parse #define (ignored)\n", input_file, line_number); + $$.type = T_ERROR; + } + + ; + +extern : EXTERN { $$ = 1; } + | empty {$$ = 0; } + | EXTERN STRING { + if (strcmp($2,"C") == 0) { + $$ = 2; + } else { + fprintf(stderr,"%s : Line %d. Unrecognized extern type \"%s\" (ignored).\n", input_file, line_number, $2); + FatalError(); + } + } + ; + +/* End of a function declaration. Allows C++ "const" directive and inline code */ + +func_end : cpp_const LBRACE { skip_brace(); } +/* | LBRACE { skip_brace(); } */ + ; + +/* ------------------------------------------------------------------------------ + Function parameter lists + + ------------------------------------------------------------------------------ */ + +parms : parm ptail { + if (($1->t->type != T_VOID) || ($1->t->is_pointer)) + $2->insert($1,0); + $$ = $2; + delete $1; + } + | empty { $$ = new ParmList;} + ; + +ptail : COMMA parm ptail { + $3->insert($2,0); + $$ = $3; + delete $2; + } + | empty { $$ = new ParmList;} + ; + +parm : parm_type { + $$ = $1; + if (typemap_check("ignore",typemap_lang,$$->t,$$->name)) + $$->ignore = 1; + } + | parm_specifier_list parm_type { + $$ = $2; + $$->call_type = $$->call_type | $1; + if (InArray && ($$->call_type & CALL_VALUE)) { + fprintf(stderr,"%s : Line %d. Error. Can't use %%val with an array.\n", input_file, line_number); + FatalError(); + } + if (!$$->t->is_pointer) { + fprintf(stderr,"%s : Line %d. Error. Can't use %%val or %%out with a non-pointer argument.\n", input_file, line_number); + FatalError(); + } else { + $$->t->is_pointer--; + } + } + +parm_type : type pname { + if (InArray) { + $1->is_pointer++; + if (Verbose) { + fprintf(stderr,"%s : Line %d. Warning. Array %s", input_file, line_number, $1->print_type()); + print_array(); + fprintf(stderr," has been converted to %s.\n", $1->print_type()); + } + // Add array string to the type + $1->arraystr = copy_string(ArrayString.get()); + } + $$ = new Parm($1,$2); + $$->call_type = 0; + $$->defvalue = DefArg; + if (($1->type == T_USER) && !($1->is_pointer)) { + if (Verbose) + fprintf(stderr,"%s : Line %d. Warning : Parameter of type '%s'\nhas been remapped to '%s *' and will be called using *((%s *) ptr).\n", + input_file, line_number, $1->name, $1->name, $1->name); + + $$->call_type = CALL_REFERENCE; + $$->t->is_pointer++; + } + delete $1; + delete $2; + } + + | type stars pname { + $$ = new Parm($1,$3); + $$->t->is_pointer += $2; + $$->call_type = 0; + $$->defvalue = DefArg; + if (InArray) { + $$->t->is_pointer++; + if (Verbose) { + fprintf(stderr,"%s : Line %d. Warning. Array %s", input_file, line_number, $$->t->print_type()); + print_array(); + fprintf(stderr," has been converted to %s.\n", $$->t->print_type()); + } + // Add array string to the type + $$->t->arraystr = copy_string(ArrayString.get()); + } + delete $1; + delete $3; + } + + | type AND pname { + $$ = new Parm($1,$3); + $$->t->is_reference = 1; + $$->call_type = 0; + $$->t->is_pointer++; + $$->defvalue = DefArg; + if (!CPlusPlus) { + fprintf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); + } + delete $1; + delete $3; + } + | type LPAREN stars pname RPAREN LPAREN parms RPAREN { + fprintf(stderr,"%s : Line %d. Error. Function pointer not allowed (remap with typedef).\n", input_file, line_number); + FatalError(); + $$ = new Parm($1,$4); + $$->t->type = T_ERROR; + $$->name = copy_string($4); + strcpy($$->t->name,""); + delete $1; + delete $4; + delete $7; + } + | PERIOD PERIOD PERIOD { + fprintf(stderr,"%s : Line %d. Variable length arguments not supported (ignored).\n", input_file, line_number); + $$ = new Parm(new DataType(T_INT),"varargs"); + $$->t->type = T_ERROR; + $$->name = copy_string("varargs"); + strcpy($$->t->name,""); + FatalError(); + } + ; + +pname : ID def_args { + $$ = $1; + InArray = 0; + if ($2.type == T_CHAR) + DefArg = copy_string(ConstChar); + else + DefArg = copy_string($2.id); + if ($2.id) delete $2.id; + } + | ID array { + $$ = $1; + InArray = $2; + DefArg = 0; + } + | array { + $$ = new char[1]; + $$[0] = 0; + InArray = $1; + DefArg = 0; + } + | empty { $$ = new char[1]; + $$[0] = 0; + InArray = 0; + DefArg = 0; + } + ; + +def_args : EQUAL definetype { $$ = $2; } + | EQUAL AND ID { + $$.id = new char[strlen($3)+2]; + $$.id[0] = '&'; + strcpy(&$$.id[1], $3); + $$.type = T_USER; + } + | EQUAL LBRACE { + skip_brace(); + $$.id = 0; $$.type = T_INT; + } + | COLON NUM_INT { + } + | empty {$$.id = 0; $$.type = T_INT;} + ; + +parm_specifier : CVALUE { $$ = CALL_VALUE; } + | COUT { $$ = CALL_OUTPUT; } + ; + +parm_specifier_list : parm_specifier_list parm_specifier { + $$ = $1 | $2; + } + | parm_specifier { + $$ = $1; + } + ; + +/* Declaration must be an identifier, possibly preceded by a * for pointer types */ + +declaration : ID { $$.id = $1; + $$.is_pointer = 0; + $$.is_reference = 0; + } + | stars ID { + $$.id = $2; + $$.is_pointer = $1; + $$.is_reference = 0; + } + | AND ID { + $$.id = $2; + $$.is_pointer = 1; + $$.is_reference = 1; + if (!CPlusPlus) { + fprintf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); + } + } + ; + +stars : STAR empty { $$ = 1; } + | STAR stars { $$ = $2 + 1;} + ; + + +array : LBRACKET RBRACKET array2 { + $$ = $3 + 1; + "[]" >> ArrayString; + } + | LBRACKET expr RBRACKET array2 { + $$ = $4 + 1; + "]" >> ArrayString; + $2.id >> ArrayString; + "[" >> ArrayString; + } + ; +array2 : array { + $$ = $1; + } + | empty { $$ = 0; + ArrayString = ""; + } + ; + +/* Data type must be a built in type or an identifier for user-defined types + This type can be preceded by a modifier. */ + +type : TYPE_INT { + $$ = $1; + } + | TYPE_SHORT opt_int { + $$ = $1; + } + | TYPE_LONG opt_int { + $$ = $1; + } + | TYPE_CHAR { + $$ = $1; + } + | TYPE_BOOL { + $$ = $1; + } + | TYPE_FLOAT { + $$ = $1; + } + | TYPE_DOUBLE { + $$ = $1; + } + | TYPE_VOID { + $$ = $1; + } + | TYPE_SIGNED opt_signed { + if ($2) $$ = $2; + else $$ = $1; + } + | TYPE_UNSIGNED opt_unsigned { + if ($2) $$ = $2; + else $$ = $1; + } + | TYPE_TYPEDEF objc_protolist { + $$ = $1; + if (strlen($2) > 0) { + if ((strlen($2) + strlen($$->name)) >= MAX_NAME) { + fprintf(stderr,"%s : Line %d. Fatal error. Type-name is too long!\n", + input_file, line_number); + } else { + strcat($$->name,$2); + } + } + } + | ID objc_protolist { + $$ = new DataType; + strcpy($$->name,$1); + $$->type = T_USER; + /* Do a typedef lookup */ + $$->typedef_resolve(); + if (strlen($2) > 0) { + if ((strlen($2) + strlen($$->name)) >= MAX_NAME) { + fprintf(stderr,"%s : Line %d. Fatal error. Type-name is too long!\n", + input_file, line_number); + } else { + strcat($$->name,$2); + } + } + } + | CONST type { + $$ = $2; + $$->qualifier = new char[6]; + strcpy($$->qualifier,"const"); + } + | cpptype ID { + $$ = new DataType; + sprintf($$->name,"%s %s",$1, $2); + $$->type = T_USER; + } + | ID DCOLON ID { + $$ = new DataType; + sprintf($$->name,"%s::%s",$1,$3); + $$->type = T_USER; + $$->typedef_resolve(); + } +/* This declaration causes a shift-reduce conflict. Unresolved for now */ + + + | DCOLON ID { + $$ = new DataType; + sprintf($$->name,"%s", $2); + $$->type = T_USER; + $$->typedef_resolve(1); + } + | ENUM ID { + $$ = new DataType; + sprintf($$->name,"enum %s", $2); + $$->type = T_INT; + $$->typedef_resolve(1); + } + ; + +/* type specification without ID symbol. Used in some cases to prevent shift-reduce conflicts */ + +strict_type : TYPE_INT { + $$ = $1; + } + | TYPE_SHORT opt_int { + $$ = $1; + } + | TYPE_LONG opt_int { + $$ = $1; + } + | TYPE_CHAR { + $$ = $1; + } + | TYPE_BOOL { + $$ = $1; + } + | TYPE_FLOAT { + $$ = $1; + } + | TYPE_DOUBLE { + $$ = $1; + } + | TYPE_VOID { + $$ = $1; + } + | TYPE_SIGNED opt_signed { + if ($2) $$ = $2; + else $$ = $1; + } + | TYPE_UNSIGNED opt_unsigned { + if ($2) $$ = $2; + else $$ = $1; + } + | TYPE_TYPEDEF objc_protolist { + $$ = $1; + strcat($$->name,$2); + } + | CONST type { + $$ = $2; + $$->qualifier = new char[6]; + strcpy($$->qualifier,"const"); + } + | cpptype ID { + $$ = new DataType; + sprintf($$->name,"%s %s",$1, $2); + $$->type = T_USER; + } + ; + +/* Optional signed types */ + +opt_signed : empty { + $$ = (DataType *) 0; + } + | TYPE_INT { + $$ = $1; + $$->type = T_INT; + sprintf(temp_name,"signed %s",$1->name); + strcpy($$->name,temp_name); + } + | TYPE_SHORT opt_int { + $$ = $1; + $$->type = T_SHORT; + sprintf(temp_name,"signed %s",$1->name); + strcpy($$->name,temp_name); + } + | TYPE_LONG opt_int { + $$ = $1; + $$->type = T_LONG; + sprintf(temp_name,"signed %s",$1->name); + strcpy($$->name,temp_name); + } + | TYPE_CHAR { + $$ = $1; + $$->type = T_SCHAR; + sprintf(temp_name,"signed %s",$1->name); + strcpy($$->name,temp_name); + } + ; + +/* Optional unsigned types */ + +opt_unsigned : empty { + $$ = (DataType *) 0; + } + | TYPE_INT { + $$ = $1; + $$->type = T_UINT; + sprintf(temp_name,"unsigned %s",$1->name); + strcpy($$->name,temp_name); + } + | TYPE_SHORT opt_int { + $$ = $1; + $$->type = T_USHORT; + sprintf(temp_name,"unsigned %s",$1->name); + strcpy($$->name,temp_name); + } + | TYPE_LONG opt_int { + $$ = $1; + $$->type = T_ULONG; + sprintf(temp_name,"unsigned %s",$1->name); + strcpy($$->name,temp_name); + } + | TYPE_CHAR { + $$ = $1; + $$->type = T_UCHAR; + sprintf(temp_name,"unsigned %s",$1->name); + strcpy($$->name,temp_name); + } + ; + +opt_int : TYPE_INT { } + | empty { } + ; + +definetype : { scanner_check_typedef(); } expr { + $$ = $2; + scanner_ignore_typedef(); + if (ConstChar) delete ConstChar; + ConstChar = 0; + } + | STRING { + $$.id = $1; + $$.type = T_CHAR; + if (ConstChar) delete ConstChar; + ConstChar = new char[strlen($1)+3]; + sprintf(ConstChar,"\"%s\"",$1); + } + | CHARCONST { + $$.id = $1; + $$.type = T_CHAR; + if (ConstChar) delete ConstChar; + ConstChar = new char[strlen($1)+3]; + sprintf(ConstChar,"'%s'",$1); + } + ; + + +/* Initialization function links */ + +initlist : initlist COMMA ID { + $$ = $1; + $$.names[$$.count] = copy_string($3); + $$.count++; + $$.names[$$.count] = (char *) 0; + } + | empty { + $$.names = new char *[NI_NAMES]; + $$.count = 0; + for (i = 0; i < NI_NAMES; i++) + $$.names[i] = (char *) 0; + } + ; + +/* Some stuff for handling enums */ + +ename : ID { $$ = $1; } + | empty { $$ = (char *) 0;} + ; + +/* SWIG enum list. +*/ + +enumlist : enumlist COMMA edecl {} + | edecl {} + ; + + +edecl : ID { + temp_typeptr = new DataType(T_INT); + create_constant($1, temp_typeptr, $1); + delete temp_typeptr; + } + | ID EQUAL { scanner_check_typedef();} etype { + temp_typeptr = new DataType($4.type); +// Use enum name instead of value +// OLD create_constant($1, temp_typeptr, $4.id); + create_constant($1, temp_typeptr, $1); + delete temp_typeptr; + } + | cond_compile edecl { } + | empty { } + ; + +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)) { + fprintf(stderr,"%s : Lind %d. Type error. Expecting an int\n", + input_file, line_number); + FatalError(); + } + + } + | CHARCONST { + $$.id = $1; + $$.type = T_CHAR; + } + ; + +/* Arithmetic expressions. Used for constants and other cool stuff. + Really, we're not doing anything except string concatenation, but + this does allow us to parse many constant declarations. + */ + +expr : NUM_INT { + $$.id = $1; + $$.type = T_INT; + } + | NUM_FLOAT { + $$.id = $1; + $$.type = T_DOUBLE; + } + | NUM_UNSIGNED { + $$.id = $1; + $$.type = T_UINT; + } + | NUM_LONG { + $$.id = $1; + $$.type = T_LONG; + } + | NUM_ULONG { + $$.id = $1; + $$.type = T_ULONG; + } + | SIZEOF LPAREN type RPAREN { + $$.id = new char[strlen($3->name)+9]; + sprintf($$.id,"sizeof(%s)", $3->name); + $$.type = T_INT; + } + | LPAREN strict_type RPAREN expr %prec UMINUS { + $$.id = new char[strlen($4.id)+strlen($2->name)+3]; + sprintf($$.id,"(%s)%s",$2->name,$4.id); + $$.type = $2->type; + } + | ID { + $$.id = lookup_symvalue($1); + if ($$.id == (char *) 0) + $$.id = $1; + else { + $$.id = new char[strlen($$.id)+3]; + sprintf($$.id,"(%s)",lookup_symvalue($1)); + } + temp_typeptr = lookup_symtype($1); + if (temp_typeptr) $$.type = temp_typeptr->type; + else $$.type = T_INT; + } + | ID DCOLON ID { + $$.id = new char[strlen($1)+strlen($3)+3]; + sprintf($$.id,"%s::%s",$1,$3); + $$.type = T_INT; + delete $1; + delete $3; + } + | expr PLUS expr { + E_BINARY($$.id,$1.id,$3.id,"+"); + $$.type = promote($1.type,$3.type); + delete $1.id; + delete $3.id; + } + | expr MINUS expr { + E_BINARY($$.id,$1.id,$3.id,"-"); + $$.type = promote($1.type,$3.type); + delete $1.id; + delete $3.id; + } + | expr STAR expr { + E_BINARY($$.id,$1.id,$3.id,"*"); + $$.type = promote($1.type,$3.type); + delete $1.id; + delete $3.id; + + } + | expr SLASH expr { + E_BINARY($$.id,$1.id,$3.id,"/"); + $$.type = promote($1.type,$3.type); + delete $1.id; + delete $3.id; + + } + | expr AND expr { + E_BINARY($$.id,$1.id,$3.id,"&"); + $$.type = promote($1.type,$3.type); + if (($1.type == T_DOUBLE) || ($3.type == T_DOUBLE)) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + delete $1.id; + delete $3.id; + + } + | expr OR expr { + E_BINARY($$.id,$1.id,$3.id,"|"); + $$.type = promote($1.type,$3.type); + if (($1.type == T_DOUBLE) || ($3.type == T_DOUBLE)) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + $$.type = T_INT; + delete $1.id; + delete $3.id; + + } + | expr XOR expr { + E_BINARY($$.id,$1.id,$3.id,"^"); + $$.type = promote($1.type,$3.type); + if (($1.type == T_DOUBLE) || ($3.type == T_DOUBLE)) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + $$.type = T_INT; + delete $1.id; + delete $3.id; + + } + | expr LSHIFT expr { + E_BINARY($$.id,$1.id,$3.id,"<<"); + $$.type = promote($1.type,$3.type); + if (($1.type == T_DOUBLE) || ($3.type == T_DOUBLE)) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + $$.type = T_INT; + delete $1.id; + delete $3.id; + + } + | expr RSHIFT expr { + E_BINARY($$.id,$1.id,$3.id,">>"); + $$.type = promote($1.type,$3.type); + if (($1.type == T_DOUBLE) || ($3.type == T_DOUBLE)) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + $$.type = T_INT; + delete $1.id; + delete $3.id; + + } + | MINUS expr %prec UMINUS { + $$.id = new char[strlen($2.id)+2]; + sprintf($$.id,"-%s",$2.id); + $$.type = $2.type; + delete $2.id; + + } + | NOT expr { + $$.id = new char[strlen($2.id)+2]; + sprintf($$.id,"~%s",$2.id); + if ($2.type == T_DOUBLE) { + fprintf(stderr,"%s : Line %d. Type error in constant expression (expecting integers).\n", input_file, line_number); + FatalError(); + } + $$.type = $2.type; + delete $2.id; + } + | LPAREN expr RPAREN { + $$.id = new char[strlen($2.id)+3]; + sprintf($$.id,"(%s)", $2.id); + $$.type = $2.type; + delete $2.id; + } + ; +/****************************************************************/ +/* C++ Support */ +/****************************************************************/ + +cpp : cpp_class { } + | cpp_other {} + ; + +cpp_class : + +/* A class/struct/union definition */ + extern cpptype ID inherit LBRACE { + char *iname; + if (allow) { + init_language(); + DataType::new_scope(); + + sprintf(temp_name,"CPP_CLASS:%s\n",$3); + if (add_symbol(temp_name, (DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Error. %s %s is multiply defined.\n", input_file, line_number, $2, $3); + FatalError(); + } + if ((!CPlusPlus) && (strcmp($2,"class") == 0)) + fprintf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); + + iname = make_name($3); + doc_entry = new DocClass(iname, doc_parent()); + if (iname == $3) + cplus_open_class($3, 0, $2); + else + cplus_open_class($3, iname, $2); + if (strcmp($2,"class") == 0) + cplus_mode = CPLUS_PRIVATE; + else + cplus_mode = CPLUS_PUBLIC; + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + nested_list = 0; + // Merge in scope from base classes + cplus_inherit_scope($4.count,$4.names); + } + } cpp_members RBRACE { + if (allow) { + if ($4.names) { + if (strcmp($2,"union") != 0) + cplus_inherit($4.count, $4.names); + else { + fprintf(stderr,"%s : Line %d. Inheritance not allowed for unions.\n",input_file, line_number); + FatalError(); + } + } + // Clean up the inheritance list + if ($4.names) { + int j; + for (j = 0; j < $4.count; j++) { + if ($4.names[j]) delete [] $4.names[j]; + } + delete [] $4.names; + } + + // Dumped nested declarations (if applicable) + dump_nested($3); + + // Save and collapse current scope + cplus_register_scope(DataType::collapse_scope($3)); + + // Restore the original doc entry for this class + doc_entry = doc_stack[doc_stack_top]; + cplus_class_close((char *) 0); + doc_entry = 0; + // Bump the documentation stack back down + doc_stack_top--; + cplus_mode = CPLUS_PUBLIC; + } + } + +/* Class with a typedef */ + + | TYPEDEF cpptype ID inherit LBRACE { + if (allow) { + char *iname; + init_language(); + DataType::new_scope(); + + sprintf(temp_name,"CPP_CLASS:%s\n",$3); + if (add_symbol(temp_name, (DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Error. %s %s is multiply defined.\n", input_file, line_number, $2, $3); + FatalError(); + } + if ((!CPlusPlus) && (strcmp($2,"class") == 0)) + fprintf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); + + iname = make_name($3); + doc_entry = new DocClass(iname, doc_parent()); + if ($3 == iname) + cplus_open_class($3, 0, $2); + else + cplus_open_class($3, iname, $2); + if (strcmp($2,"class") == 0) + cplus_mode = CPLUS_PRIVATE; + else + cplus_mode = CPLUS_PUBLIC; + // Create a documentation entry for the class + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + nested_list = 0; + + // Merge in scope from base classes + cplus_inherit_scope($4.count,$4.names); + + } + } cpp_members RBRACE declaration { + if (allow) { + if ($4.names) { + if (strcmp($2,"union") != 0) + cplus_inherit($4.count, $4.names); + else { + fprintf(stderr,"%s : Line %d. Inheritance not allowed for unions.\n",input_file, line_number); + FatalError(); + } + } + // Create a datatype for correctly processing the typedef + Active_typedef = new DataType(); + Active_typedef->type = T_USER; + sprintf(Active_typedef->name,"%s %s", $2,$3); + Active_typedef->is_pointer = 0; + Active_typedef->implicit_ptr = 0; + + // Clean up the inheritance list + if ($4.names) { + int j; + for (j = 0; j < $4.count; j++) { + if ($4.names[j]) delete [] $4.names[j]; + } + delete [] $4.names; + } + + if ($9.is_pointer > 0) { + fprintf(stderr,"%s : Line %d. typedef struct { } *id not supported properly. Winging it...\n", input_file, line_number); + + } + // Create dump nested class code + if ($9.is_pointer > 0) { + dump_nested($3); + } else { + dump_nested($9.id); + } + + // Collapse any datatypes created in the the class + + cplus_register_scope(DataType::collapse_scope($3)); + + doc_entry = doc_stack[doc_stack_top]; + if ($9.is_pointer > 0) { + cplus_class_close($3); + } else { + cplus_class_close($9.id); + } + doc_stack_top--; + doc_entry = 0; + + // Create a typedef in global scope + + if ($9.is_pointer == 0) + Active_typedef->typedef_add($9.id); + else { + DataType *t = new DataType(Active_typedef); + t->is_pointer += $9.is_pointer; + t->typedef_add($9.id); + cplus_register_type($9.id); + delete t; + } + cplus_mode = CPLUS_PUBLIC; + } + } typedeflist { }; + +/* An unnamed struct with a typedef */ + + | TYPEDEF cpptype LBRACE { + char *iname; + if (allow) { + init_language(); + DataType::new_scope(); + if ((!CPlusPlus) && (strcmp($2,"class") == 0)) + fprintf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); + + iname = make_name(""); + doc_entry = new DocClass(iname,doc_parent()); + if (strlen(iname)) + cplus_open_class("", iname, $2); + else + cplus_open_class("",0,$2); + if (strcmp($2,"class") == 0) + cplus_mode = CPLUS_PRIVATE; + else + cplus_mode = CPLUS_PUBLIC; + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + nested_list = 0; + } + } cpp_members RBRACE declaration { + if (allow) { + if ($7.is_pointer > 0) { + fprintf(stderr,"%s : Line %d. typedef %s {} *%s not supported correctly. Will be ignored.\n", input_file, line_number, $2, $7.id); + cplus_abort(); + } else { + sprintf(temp_name,"CPP_CLASS:%s\n",$7.id); + if (add_symbol(temp_name, (DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. Error. %s %s is multiply defined.\n", input_file, line_number, $2, $7.id); + FatalError(); + } + } + // Create a datatype for correctly processing the typedef + Active_typedef = new DataType(); + Active_typedef->type = T_USER; + sprintf(Active_typedef->name,"%s",$7.id); + Active_typedef->is_pointer = 0; + Active_typedef->implicit_ptr = 0; + + // Dump nested classes + if ($7.is_pointer == 0) + dump_nested($7.id); + + // Go back to previous scope + + cplus_register_scope(DataType::collapse_scope((char *) 0)); + + doc_entry = doc_stack[doc_stack_top]; + // Change name of doc_entry + doc_entry->name = copy_string($7.id); + if ($7.is_pointer == 0) + cplus_class_close($7.id); + doc_entry = 0; + doc_stack_top--; + cplus_mode = CPLUS_PUBLIC; + } + } typedeflist { } + ; + +cpp_other :/* A dummy class name */ + + extern cpptype ID SEMI { + char *iname; + if (allow) { + init_language(); + iname = make_name($3); + lang->cpp_class_decl($3,iname,$2); + } + } + +/* A static C++ member function (declared out of scope) */ + + | extern type declaration DCOLON ID LPAREN parms RPAREN SEMI { + if (allow) { + init_language(); + if (!CPlusPlus) + fprintf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); + + $2->is_pointer += $3.is_pointer; + $2->is_reference = $3.is_reference; + // Fix up the function name + sprintf(temp_name,"%s::%s",$3.id,$5); + if (!Rename_true) { + Rename_true = 1; + sprintf(yy_rename,"%s_%s",$3.id,$5); + } + create_function($1, temp_name, $2, $7); + } + delete $2; + delete $7; + } + +/* A static C++ member data */ + | extern type declaration DCOLON ID SEMI { + if (allow) { + init_language(); + if (!CPlusPlus) + fprintf(stderr,"%s : Line %d. *** WARNING ***. C++ mode is disabled (enable using -c++)\n", input_file, line_number); + + $2->is_pointer += $3.is_pointer; + // Fix up the function name + sprintf(temp_name,"%s::%s",$3.id,$5); + if (!Rename_true) { + Rename_true = 1; + sprintf(yy_rename,"%s_%s",$3.id,$5); + } + create_variable($1,temp_name, $2); + } + delete $2; + } + +/* Operator overloading catch */ + + | extern type declaration DCOLON OPERATOR { + fprintf(stderr,"%s : Line %d. Operator overloading not supported (ignored).\n", input_file, line_number); + skip_decl(); + delete $2; + } + + +/* Template catch */ + | TEMPLATE { + fprintf(stderr,"%s : Line %d. Templates not currently supported (ignored).\n", + input_file, line_number); + skip_decl(); + } + +/* %addmethods directive used outside of a class definition */ + + | ADDMETHODS ID LBRACE { + cplus_mode = CPLUS_PUBLIC; + doc_entry = cplus_set_class($2); + if (!doc_entry) { + doc_entry = new DocClass($2,doc_parent()); + }; + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + AddMethods = 1; + } added_members RBRACE { + cplus_unset_class(); + doc_entry = 0; + doc_stack_top--; + AddMethods = 0; + } + ; + +added_members : cpp_member cpp_members { } + | objc_method objc_methods { } + | empty { } + ; + +cpp_members : cpp_member cpp_members {} + | ADDMETHODS LBRACE { + AddMethods = 1; + } cpp_members RBRACE { + AddMethods = 0; + } cpp_members { } + | error { + skip_decl(); + { + static int last_error_line = -1; + if (last_error_line != line_number) { + fprintf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); + FatalError(); + last_error_line = line_number; + } + } + } cpp_members { } + | empty { } + ; + +cpp_member : type declaration LPAREN parms RPAREN cpp_end { + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + Stat_func++; + $1->is_pointer += $2.is_pointer; + $1->is_reference = $2.is_reference; + if (Verbose) { + fprintf(stderr,"Wrapping member function : %s\n",$2.id); + } + iname = make_name($2.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $2.id) iname = 0; + cplus_member_func($2.id, iname, $1,$4,0); + } + scanner_clear_start(); + } + delete $1; + delete $4; + } + +/* Virtual member function */ + + | VIRTUAL type declaration LPAREN parms RPAREN cpp_vend { + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + Stat_func++; + $2->is_pointer += $3.is_pointer; + $2->is_reference = $3.is_reference; + if (Verbose) { + fprintf(stderr,"Wrapping virtual member function : %s\n",$3.id); + } + iname = make_name($3.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $3.id) iname = 0; + cplus_member_func($3.id,iname,$2,$5,1); + } + scanner_clear_start(); + } + delete $2; + delete $5; + } + +/* Possibly a constructor */ + | ID LPAREN parms RPAREN ctor_end { + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + Stat_func++; + if (Verbose) { + fprintf(stderr,"Wrapping C++ constructor %s\n", $1); + } + iname = make_name($1); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $1) iname = 0; + cplus_constructor($1,iname, $3); + } + scanner_clear_start(); + } + delete $3; + } + +/* A destructor (hopefully) */ + + | NOT ID LPAREN parms RPAREN cpp_end { + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + Stat_func++; + if (Verbose) { + fprintf(stderr,"Wrapping C++ destructor %s\n", $2); + } + iname = make_name($2); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $2) iname = 0; + cplus_destructor($2,iname); + } + } + scanner_clear_start(); + } + +/* A virtual destructor */ + + | VIRTUAL NOT ID LPAREN RPAREN cpp_end { + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + Stat_func++; + if (Verbose) { + fprintf(stderr,"Wrapping C++ destructor %s\n", $3); + } + iname = make_name($3); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $3) iname = 0; + cplus_destructor($3,iname); + } + } + scanner_clear_start(); + } + +/* Member data */ + + | type declaration def_args { + if (allow) { + char *iname; + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + if (Active_type) delete Active_type; + Active_type = new DataType($1); + $1->is_pointer += $2.is_pointer; + $1->is_reference = $2.is_reference; + if ($1->qualifier) { + if ((strcmp($1->qualifier,"const") == 0) && ($1->is_pointer == 0)) { + // Okay. This is really some sort of C++ constant here. + if ($3.type != T_ERROR) { + iname = make_name($2.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $2.id) iname = 0; + cplus_declare_const($2.id,iname, $1, $3.id); + } + } else { + int oldstatus = Status; + char *tm; + if ($1->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,$1,$2.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name($2.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $2.id) iname = 0; + cplus_variable($2.id,iname,$1); + Status = oldstatus; + } + } else { + char *tm = 0; + int oldstatus = Status; + if ($1->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,$1,$2.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name($2.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $2.id) iname = 0; + cplus_variable($2.id,iname,$1); + Status = oldstatus; + if (Verbose) { + fprintf(stderr,"Wrapping member data %s\n", $2.id); + } + } + } + scanner_clear_start(); + } + delete $1; + } cpp_tail { } + + | type declaration array def_args { + char *iname; + if (allow) { + int oldstatus = Status; + char *tm = 0; + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + if (Active_type) delete Active_type; + Active_type = new DataType($1); + $1->is_pointer += $2.is_pointer + 1; + $1->is_reference = $2.is_reference; + $1->arraystr = copy_string(ArrayString); + if (!(tm = typemap_lookup("memberin",typemap_lang,$1,$2.id,"",""))) + Status = STAT_READONLY; + + iname = make_name($2.id); + doc_entry = new DocDecl(iname, doc_stack[doc_stack_top]); + if (iname == $2.id) iname = 0; + cplus_variable($2.id,iname,$1); + Status = oldstatus; + if (!tm) + fprintf(stderr,"%s : Line %d. Warning. Array member will be read-only.\n",input_file,line_number); + } + scanner_clear_start(); + } + delete $1; + } + + +/* Static Member data */ + + | STATIC type declaration { + char *iname; + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + $2->is_pointer += $3.is_pointer; + iname = make_name($3.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $3.id) iname = 0; + cplus_static_var($3.id,iname,$2); + if (Active_type) delete Active_type; + Active_type = new DataType($2); + if (Verbose) { + fprintf(stderr,"Wrapping static member data %s\n", $3.id); + } + } + scanner_clear_start(); + } + delete $2; + } cpp_tail { } + +/* Static member function */ + + | STATIC type declaration LPAREN parms RPAREN cpp_end { + char *iname; + if (allow) { + $2->is_pointer += $3.is_pointer; + $2->is_reference = $3.is_reference; + if (cplus_mode == CPLUS_PUBLIC) { + iname = make_name($3.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $3.id) iname = 0; + cplus_static_func($3.id, iname, $2, $5); + if (Verbose) + fprintf(stderr,"Wrapping static member function %s\n",$3.id); + } + scanner_clear_start(); + } + delete $2; + delete $5; + } +/* Turn on public: mode */ + + | PUBLIC COLON { + if (allow) { + cplus_mode = CPLUS_PUBLIC; + if (Verbose) + fprintf(stderr,"Public mode\n"); + scanner_clear_start(); + } + } + +/* Turn on private: mode */ + + | PRIVATE COLON { + if (allow) { + cplus_mode = CPLUS_PRIVATE; + if (Verbose) + fprintf(stderr,"Private mode\n"); + scanner_clear_start(); + } + } + +/* Turn on protected mode */ + + | PROTECTED COLON { + if (allow) { + cplus_mode = CPLUS_PROTECTED; + if (Verbose) + fprintf(stderr,"Protected mode\n"); + scanner_clear_start(); + } + } + +/* This is the new style rename */ + + | NAME LPAREN ID RPAREN { + if (allow) { + strcpy(yy_rename,$3); + Rename_true = 1; + } + } + +/* New mode */ + | NEW { + NewObject = 1; + } cpp_member { + NewObject = 0; + } + +/* C++ Enum */ + | ENUM ename LBRACE {scanner_clear_start();} cpp_enumlist RBRACE SEMI { + + // if ename was supplied. Install it as a new integer datatype. + + if (allow) { + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + if ($2) { + cplus_register_type($2); + temp_type.type = T_INT; + temp_type.is_pointer = 0; + temp_type.implicit_ptr = 0; + sprintf(temp_type.name,"int"); + temp_type.typedef_add($2,1); + } + } + } + } + | READONLY { + if (allow) + Status = Status | STAT_READONLY; + scanner_clear_start(); + } + | READWRITE { + if (allow) + Status = Status & ~(STAT_READONLY); + scanner_clear_start(); + } +/* A friend : Illegal */ + | FRIEND { + if (allow) + fprintf(stderr,"%s : Line %d. Friends are not allowed--members only! (ignored)\n", input_file, line_number); + skip_decl(); + scanner_clear_start(); + } + +/* An operator: Illegal */ + | type type_extra OPERATOR { + if (allow) + fprintf(stderr,"%s : Line %d. Operator overloading not supported (ignored).\n", input_file, line_number); + skip_decl(); + scanner_clear_start(); + } + | cond_compile { + scanner_clear_start(); + } + +/* A typedef inside a class */ + | typedef_decl { } + +/* Pragma directive */ + + | cpp_pragma { + scanner_clear_start(); + } + + +cpp_pragma : PRAGMA ID stylearg { + if (allow && (!WrapExtern)) { } + } + | PRAGMA LPAREN ID RPAREN ID stylearg { + if (allow && (!WrapExtern)) + cplus_add_pragma($3,$5,$6); + } + ; + + + +/* ---------------------------------------------------------------------- + Nested structure. This is a big ugly "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 */ + + | cpptype ID LBRACE { start_line = line_number; skip_brace(); + } nested_decl SEMI { + + if (cplus_mode == CPLUS_PUBLIC) { + cplus_register_type($2); + if ($5.id) { + if (strcmp($1,"class") == 0) { + fprintf(stderr,"%s : Line %d. Warning. Nested classes not currently supported (ignored).\n", input_file, line_number); + /* Generate some code for a new class */ + } else { + Nested *n = new Nested; + n->code << "typedef " << $1 << " " + << CCode.get() << " $classname_" << $5.id << ";\n"; + n->name = copy_string($5.id); + n->line = start_line; + n->type = new DataType; + n->type->type = T_USER; + n->type->is_pointer = $5.is_pointer; + n->type->is_reference = $5.is_reference; + n->next = 0; + add_nested(n); + } + } + } + } +/* An unnamed structure definition */ + | cpptype LBRACE { start_line = line_number; skip_brace(); + } declaration SEMI { + if (cplus_mode == CPLUS_PUBLIC) { + if (strcmp($1,"class") == 0) { + fprintf(stderr,"%s : Line %d. Warning. Nested classes not currently supported (ignored)\n", input_file, line_number); + /* Generate some code for a new class */ + } else { + /* Generate some code for a new class */ + + Nested *n = new Nested; + n->code << "typedef " << $1 << " " + << CCode.get() << " $classname_" << $4.id << ";\n"; + n->name = copy_string($4.id); + n->line = start_line; + n->type = new DataType; + n->type->type = T_USER; + n->type->is_pointer = $4.is_pointer; + n->type->is_reference = $4.is_reference; + n->next = 0; + add_nested(n); + + } + } + } +/* An empty class declaration */ + | cpptype ID SEMI { + if (cplus_mode == CPLUS_PUBLIC) { + cplus_register_type($2); + } + } + +/* Other miscellaneous errors */ + | type stars LPAREN { + skip_decl(); + fprintf(stderr,"%s : Line %d. Function pointers not currently supported (ignored).\n", input_file, line_number); + + } + | strict_type LPAREN STAR { + skip_decl(); + fprintf(stderr,"%s : Line %d. Function pointers not currently supported (ignored).\n", input_file, line_number); + + } + | ID LPAREN STAR { + skip_decl(); + fprintf(stderr,"%s : Line %d. Function pointers not currently supported (ignored).\n", input_file, line_number); + + } + | doc_enable { } + | SEMI { } + ; + +nested_decl : declaration { $$ = $1;} + | empty { $$.id = 0; } + ; + +type_extra : stars {} + | AND {} + | empty {} + ; + +cpp_tail : SEMI { } + | COMMA declaration def_args { + if (allow) { + int oldstatus = Status; + char *tm; + + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + temp_typeptr = new DataType(Active_type); + temp_typeptr->is_pointer += $2.is_pointer; + if (Verbose) { + fprintf(stderr,"Wrapping member variable : %s\n",$2.id); + } + Stat_var++; + doc_entry = new DocDecl($2.id,doc_stack[doc_stack_top]); + if (temp_typeptr->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,temp_typeptr,$2.id,"",""))) + Status = Status | STAT_READONLY; + } + cplus_variable($2.id,(char *) 0,temp_typeptr); + Status = oldstatus; + delete temp_typeptr; + } + scanner_clear_start(); + } + } cpp_tail { } + | COMMA declaration array def_args { + if (allow) { + int oldstatus = Status; + char *tm; + + init_language(); + if (cplus_mode == CPLUS_PUBLIC) { + temp_typeptr = new DataType(Active_type); + temp_typeptr->is_pointer += $2.is_pointer; + if (Verbose) { + fprintf(stderr,"Wrapping member variable : %s\n",$2.id); + } + Stat_var++; + if (!(tm = typemap_lookup("memberin",typemap_lang,temp_typeptr,$2.id,"",""))) + Status = Status | STAT_READONLY; + doc_entry = new DocDecl($2.id,doc_stack[doc_stack_top]); + if (temp_typeptr->status & STAT_READONLY) Status = Status | STAT_READONLY; + cplus_variable($2.id,(char *) 0,temp_typeptr); + Status = oldstatus; + if (!tm) + fprintf(stderr,"%s : Line %d. Warning. Array member will be read-only.\n",input_file,line_number); + delete temp_typeptr; + } + scanner_clear_start(); + } + } cpp_tail { } + ; + +cpp_end : cpp_const SEMI { + CCode = ""; + } + | cpp_const LBRACE { skip_brace(); } + ; + +cpp_vend : cpp_const SEMI { CCode = ""; } + | cpp_const EQUAL definetype SEMI { CCode = ""; } + | cpp_const LBRACE { skip_brace(); } + ; + +cpp_enumlist : cpp_enumlist COMMA cpp_edecl {} + | cpp_edecl {} + ; + +cpp_edecl : ID { + if (allow) { + if (cplus_mode == CPLUS_PUBLIC) { + if (Verbose) { + fprintf(stderr,"Creating enum value %s\n", $1); + } + Stat_const++; + temp_typeptr = new DataType(T_INT); + doc_entry = new DocDecl($1,doc_stack[doc_stack_top]); + cplus_declare_const($1, (char *) 0, temp_typeptr, (char *) 0); + delete temp_typeptr; + scanner_clear_start(); + } + } + } + | ID EQUAL etype { + if (allow) { + if (cplus_mode == CPLUS_PUBLIC) { + if (Verbose) { + fprintf(stderr, "Creating enum value %s = %s\n", $1, $3.id); + } + Stat_const++; + temp_typeptr = new DataType(T_INT); + doc_entry = new DocDecl($1,doc_stack[doc_stack_top]); + cplus_declare_const($1,(char *) 0, temp_typeptr,(char *) 0); +// OLD : Bug with value cplus_declare_const($1,(char *) 0, temp_typeptr,$3.id); + delete temp_typeptr; + scanner_clear_start(); + } + } + } + | NAME LPAREN ID RPAREN ID { + if (allow) { + if (cplus_mode == CPLUS_PUBLIC) { + if (Verbose) { + fprintf(stderr,"Creating enum value %s\n", $5); + } + Stat_const++; + temp_typeptr = new DataType(T_INT); + doc_entry = new DocDecl($3,doc_stack[doc_stack_top]); + cplus_declare_const($5, $3, temp_typeptr, (char *) 0); + delete temp_typeptr; + scanner_clear_start(); + } + } + } + | NAME LPAREN ID RPAREN ID EQUAL etype { + if (allow) { + if (cplus_mode == CPLUS_PUBLIC) { + if (Verbose) { + fprintf(stderr, "Creating enum value %s = %s\n", $5, $7.id); + } + Stat_const++; + temp_typeptr = new DataType(T_INT); + doc_entry = new DocDecl($3,doc_stack[doc_stack_top]); + cplus_declare_const($5,$3, temp_typeptr, (char *) 0); +// Old : bug with value cplus_declare_const($5,$3, temp_typeptr,$7.id); + delete temp_typeptr; + scanner_clear_start(); + } + } + } + | cond_compile cpp_edecl { } + | empty { } + ; + +inherit : COLON base_list { + $$ = $2; + } + | empty { + $$.names = (char **) 0; + $$.count = 0; + } + ; + +base_list : base_specifier { + int i; + $$.names = new char *[NI_NAMES]; + $$.count = 0; + for (i = 0; i < NI_NAMES; i++){ + $$.names[i] = (char *) 0; + } + if ($1) { + $$.names[$$.count] = copy_string($1); + $$.count++; + } + } + + | base_list COMMA base_specifier { + $$ = $1; + if ($3) { + $$.names[$$.count] = copy_string($3); + $$.count++; + } + } + ; + +base_specifier : ID { + fprintf(stderr,"%s : Line %d. No access specifier given for base class %s (ignored).\n", + input_file,line_number,$1); + $$ = (char *) 0; + } + | VIRTUAL ID { + fprintf(stderr,"%s : Line %d. No access specifier given for base class %s (ignored).\n", + input_file,line_number,$2); + $$ = (char *) 0; + } + | VIRTUAL access_specifier ID { + if (strcmp($2,"public") == 0) { + $$ = $3; + } else { + fprintf(stderr,"%s : Line %d. %s inheritance not supported (ignored).\n", + input_file,line_number,$2); + $$ = (char *) 0; + } + } + | access_specifier ID { + if (strcmp($1,"public") == 0) { + $$ = $2; + } else { + fprintf(stderr,"%s : Line %d. %s inheritance not supported (ignored).\n", + input_file,line_number,$1); + $$ = (char *) 0; + } + } + | access_specifier VIRTUAL ID { + if (strcmp($1,"public") == 0) { + $$ = $3; + } else { + fprintf(stderr,"%s : Line %d. %s inheritance not supported (ignored).\n", + input_file,line_number,$1); + $$ = (char *) 0; + } + } + ; + +access_specifier : PUBLIC { $$ = "public"; } + | PRIVATE { $$ = "private"; } + | PROTECTED { $$ = "protected"; } + ; + + +cpptype : CLASS { $$ = "class"; } + | STRUCT { $$ = "struct"; } + | UNION {$$ = "union"; } + ; + +cpp_const : CONST {} + | THROW LPAREN parms RPAREN { delete $3;} + | empty {} + ; + +/* Constructor initializer */ + +ctor_end : cpp_const ctor_initializer SEMI { + CCode = ""; + } + | cpp_const ctor_initializer LBRACE { skip_brace(); } + ; + +ctor_initializer : COLON mem_initializer_list {} + | empty {} + ; + +mem_initializer_list : mem_initializer { } + | mem_initializer_list COMMA mem_initializer { } + ; + +mem_initializer : ID LPAREN expr_list RPAREN { } + | ID LPAREN RPAREN { } + ; + +expr_list : expr { } + | expr_list COMMA expr { } + ; + + +/**************************************************************/ +/* Objective-C parsing */ +/**************************************************************/ + +objective_c : OC_INTERFACE ID objc_inherit { + ObjCClass = 1; + init_language(); + cplus_mode = CPLUS_PROTECTED; + sprintf(temp_name,"CPP_CLASS:%s\n",$2); + if (add_symbol(temp_name,(DataType *) 0, (char *) 0)) { + fprintf(stderr,"%s : Line %d. @interface %s is multiple defined.\n", + input_file,line_number,$2); + FatalError(); + } + // Create a new documentation entry + doc_entry = new DocClass($2,doc_parent()); + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + cplus_open_class($2, (char *) 0, ""); // Open up a new C++ class + } LBRACE objc_data RBRACE objc_methods OC_END { + if ($3) { + char *inames[1]; + inames[0] = $3; + cplus_inherit(1,inames); + } + // Restore original doc entry for this class + doc_entry = doc_stack[doc_stack_top]; + cplus_class_close($2); + doc_entry = 0; + doc_stack_top--; + cplus_mode = CPLUS_PUBLIC; + ObjCClass = 0; + delete $2; + delete $3; + } +/* An obj-c category declaration */ + | OC_INTERFACE ID LPAREN ID RPAREN objc_protolist { + ObjCClass = 1; + init_language(); + cplus_mode = CPLUS_PROTECTED; + doc_entry = cplus_set_class($2); + if (!doc_entry) { + doc_entry = new DocClass($2,doc_parent()); + } + doc_stack_top++; + doc_stack[doc_stack_top] = doc_entry; + scanner_clear_start(); + } objc_methods OC_END { + cplus_unset_class(); + doc_entry = 0; + doc_stack_top--; + } + | OC_IMPLEMENT { skip_to_end(); } + | OC_PROTOCOL { skip_to_end(); } + | OC_CLASS ID initlist SEMI { + char *iname = make_name($2); + init_language(); + lang->cpp_class_decl($2,iname,""); + for (int i = 0; i <$3.count; i++) { + if ($3.names[i]) { + iname = make_name($3.names[i]); + lang->cpp_class_decl($3.names[i],iname,""); + delete [] $3.names[i]; + } + } + delete [] $3.names; + } + ; + +objc_inherit : COLON ID objc_protolist { $$ = $2;} + | objc_protolist empty { $$ = 0; } + ; + + +objc_protolist : LESSTHAN { skip_template(); + CCode.strip(); // Strip whitespace + CCode.replace("<","< "); + CCode.replace(">"," >"); + $$ = CCode.get(); + } + | empty { + $$ = ""; + } + ; + +objc_data : objc_vars objc_data { } + | OC_PUBLIC { + cplus_mode = CPLUS_PUBLIC; + } objc_data { } + | OC_PRIVATE { + cplus_mode = CPLUS_PRIVATE; + } objc_data { } + | OC_PROTECTED { + cplus_mode = CPLUS_PROTECTED; + } objc_data { } + | error { + if (!Error) { + skip_decl(); + { + static int last_error_line = -1; + if (last_error_line != line_number) { + fprintf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); + FatalError(); + last_error_line = line_number; + } + Error = 1; + } + } + } objc_data { } + | empty { } + ; + +objc_vars : objc_var objc_vartail SEMI { + + } + ; + +/* An objective-C member variable */ + +objc_var : type declaration { + if (cplus_mode == CPLUS_PUBLIC) { + int oldstatus = Status; + char *tm; + char *iname; + if (Active_type) delete Active_type; + Active_type = new DataType($1); + $1->is_pointer += $2.is_pointer; + $1->is_reference = $2.is_reference; + if ($1->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,$1,$2.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name($2.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $2.id) iname = 0; + cplus_variable($2.id,iname,$1); + Status = oldstatus; + } + scanner_clear_start(); + delete $1; + } + | type declaration array { + if (cplus_mode == CPLUS_PUBLIC) { + int oldstatus = Status; + char *tm, *iname; + if (Active_type) delete Active_type; + Active_type = new DataType($1); + $1->is_pointer += $2.is_pointer; + $1->is_reference = $2.is_reference; + $1->arraystr = copy_string(ArrayString); + if ($1->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,$1,$2.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name($2.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $2.id) iname = 0; + cplus_variable($2.id,iname,$1); + Status = oldstatus; + } + scanner_clear_start(); + delete $1; + } + | NAME LPAREN ID RPAREN { + strcpy(yy_rename,$3); + Rename_true = 1; + } objc_var { }; + +objc_vartail : COMMA declaration objc_vartail { + if (cplus_mode == CPLUS_PUBLIC) { + int oldstatus = Status; + char *tm, *iname; + DataType *t = new DataType (Active_type); + t->is_pointer += $2.is_pointer; + t->is_reference = $2.is_reference; + if (t->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,t,$2.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name($2.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $2.id) iname = 0; + cplus_variable($2.id,iname,t); + Status = oldstatus; + delete t; + } + scanner_clear_start(); + } + | COMMA declaration array objc_vartail { + char *iname; + if (cplus_mode == CPLUS_PUBLIC) { + int oldstatus = Status; + char *tm; + DataType *t = new DataType (Active_type); + t->is_pointer += $2.is_pointer; + t->is_reference = $2.is_reference; + t->arraystr = copy_string(ArrayString); + if (t->status & STAT_READONLY) { + if (!(tm = typemap_lookup("memberin",typemap_lang,t,$2.id,"",""))) + Status = Status | STAT_READONLY; + } + iname = make_name($2.id); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $2.id) iname = 0; + cplus_variable($2.id,iname,t); + Status = oldstatus; + delete t; + } + scanner_clear_start(); + } + | empty { } + ; + +objc_methods : objc_method objc_methods { }; + | ADDMETHODS LBRACE { + AddMethods = 1; + } objc_methods RBRACE { + AddMethods = 0; + } + | NAME LPAREN ID RPAREN { + strcpy(yy_rename,$3); + Rename_true = 1; + } objc_methods { } + | error { + skip_decl(); + if (!Error) { + { + static int last_error_line = -1; + if (last_error_line != line_number) { + fprintf(stderr,"%s : Line %d. Syntax error in input.\n", input_file, line_number); + FatalError(); + last_error_line = line_number; + } + Error = 1; + } + } + } objc_methods { } + | empty { } + ; + +objc_method : MINUS objc_ret_type ID objc_args objc_end { + char *iname; + // An objective-C instance function + // This is like a C++ member function + + if (strcmp($3,objc_destruct) == 0) { + // This is an objective C destructor + doc_entry = new DocDecl($3,doc_stack[doc_stack_top]); + cplus_destructor($3,(char *) 0); + } else { + iname = make_name($3); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $3) iname = 0; + cplus_member_func($3,iname,$2,$4,0); + scanner_clear_start(); + delete $2; + delete $3; + delete $4; + } + } + | PLUS objc_ret_type ID objc_args objc_end { + char *iname; + // An objective-C class function + // This is like a c++ static member function + if (strcmp($3,objc_construct) == 0) { + // This is an objective C constructor + doc_entry = new DocDecl($3,doc_stack[doc_stack_top]); + cplus_constructor($3,0,$4); + } else { + iname = make_name($3); + doc_entry = new DocDecl(iname,doc_stack[doc_stack_top]); + if (iname == $3) iname = 0; + cplus_static_func($3,iname,$2,$4); + } + scanner_clear_start(); + delete $2; + delete $3; + delete $4; + } + ; + +objc_end : SEMI { CCode = ""; } + | LBRACE { skip_brace(); } + ; + +objc_ret_type : LPAREN type RPAREN { + $$ = $2; + } + | LPAREN type stars RPAREN { + $$ = $2; + $$->is_pointer += $3; + } + | empty { /* Empty type means "id" type */ + $$ = new DataType(T_VOID); + sprintf($$->name,"id"); + $$->is_pointer = 1; + $$->implicit_ptr = 1; + } + ; + +objc_arg_type : LPAREN parm RPAREN { + $$ = new DataType($2->t); + delete $2; + } + | empty { + $$ = new DataType(T_VOID); + sprintf($$->name,"id"); + $$->is_pointer = 1; + $$->implicit_ptr = 1; + } + ; + +objc_args : objc_args objc_separator objc_arg_type ID { + Parm *p= new Parm($3,$4); + p->objc_separator = $2; + $$ = $1; + $$->append(p); + } + | empty { + $$ = new ParmList; + } + ; + +objc_separator : COLON { $$ = copy_string(":"); } + | ID COLON { $$ = new char[strlen($1)+2]; + strcpy($$,$1); + strcat($$,":"); + delete $1; + } + ; + +/* Miscellaneous stuff */ + +/* Documentation style list */ + +stylelist : ID stylearg styletail { + $$ = $3; + $$.names[$$.count] = copy_string($1); + $$.values[$$.count] = copy_string($2); + format_string($$.values[$$.count]); + $$.count++; + } + ; + + +styletail : styletail COMMA ID stylearg { + $$ = $1; + $$.names[$$.count] = copy_string($3); + $$.values[$$.count] = copy_string($4); + format_string($$.values[$$.count]); + $$.count++; + } + | empty { + $$.names = new char *[NI_NAMES]; + $$.values = new char *[NI_NAMES]; + $$.count = 0; + } + ; + +stylearg : EQUAL NUM_INT { + $$ = $2; + } + | EQUAL STRING { + $$ = $2; + } + | empty { + $$ = 0; + } + ; + + +/* -------------------------------------------------------------- + * Type-map parameters + * -------------------------------------------------------------- */ + +tm_method : ID { + $$ = $1; + } + | CONST { + $$ = copy_string("const"); + } + ; + +tm_list : typemap_parm tm_tail { + $$ = $1; + $$->next = $2; + } + ; + +tm_tail : COMMA typemap_parm tm_tail { + $$ = $2; + $$->next = $3; + } + | empty { $$ = 0;} + ; + +typemap_parm : type typemap_name { + if (InArray) { + $1->is_pointer++; + $1->arraystr = copy_string(ArrayString); + } + $$ = new TMParm; + $$->p = new Parm($1,$2); + $$->p->call_type = 0; + $$->args = tm_parm; + delete $1; + delete $2; + } + + | type stars typemap_name { + $$ = new TMParm; + $$->p = new Parm($1,$3); + $$->p->t->is_pointer += $2; + $$->p->call_type = 0; + if (InArray) { + $$->p->t->is_pointer++; + $$->p->t->arraystr = copy_string(ArrayString); + } + $$->args = tm_parm; + delete $1; + delete $3; + } + + | type AND typemap_name { + $$ = new TMParm; + $$->p = new Parm($1,$3); + $$->p->t->is_reference = 1; + $$->p->call_type = 0; + $$->p->t->is_pointer++; + if (!CPlusPlus) { + fprintf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); + } + $$->args = tm_parm; + delete $1; + delete $3; + } + | type LPAREN stars typemap_name RPAREN LPAREN parms RPAREN { + fprintf(stderr,"%s : Line %d. Error. Function pointer not allowed (remap with typedef).\n", input_file, line_number); + FatalError(); + $$ = new TMParm; + $$->p = new Parm($1,$4); + $$->p->t->type = T_ERROR; + $$->p->name = copy_string($4); + strcpy($$->p->t->name,""); + $$->args = tm_parm; + delete $1; + delete $4; + delete $7; + } + ; + +typemap_name : ID typemap_args { + $$ = $1; + InArray = 0; + } + | ID array { + ArrayBackup = ""; + ArrayBackup << ArrayString; + } typemap_args { + $$ = $1; + InArray = $2; + ArrayString = ""; + ArrayString << ArrayBackup; + } + | array { + ArrayBackup = ""; + ArrayBackup << ArrayString; + } typemap_args { + $$ = new char[1]; + $$[0] = 0; + InArray = $1; + ArrayString = ""; + ArrayString << ArrayBackup; + } + | typemap_args { $$ = new char[1]; + $$[0] = 0; + InArray = 0; + } + ; + +typemap_args : LPAREN parms RPAREN { + tm_parm = $2; + } + | empty { + tm_parm = 0; + } + ; + +idstring : ID {$$ = $1;} + | STRING { $$ = $1;} + ; + + +/* User defined directive */ + +user_directive : USERDIRECTIVE LPAREN parms RPAREN uservalue { } + | USERDIRECTIVE uservalue { } + ; + +uservalue : ID SEMI { } + | STRING SEMI { } + | LBRACE RBRACE { } + ; + + + +/* Parsing of expressions, but only for throw away code */ + +/* Might need someday +dummyexpr : NUM_INT { } + | NUM_FLOAT { } + | NUM_UNSIGNED { } + | NUM_LONG { } + | NUM_ULONG { } + | SIZEOF LPAREN type RPAREN { } + | ID { } + | dummyexpr PLUS dummyexpr { } + | dummyexpr MINUS dummyexpr { } + | dummyexpr STAR dummyexpr { } + | dummyexpr SLASH dummyexpr { } + | dummyexpr AND dummyexpr { } + | dummyexpr OR dummyexpr { } + | dummyexpr XOR dummyexpr { } + | dummyexpr LSHIFT dummyexpr { } + | dummyexpr RSHIFT dummyexpr { } + | MINUS dummyexpr %prec UMINUS { } + | NOT dummyexpr { } + | LPAREN dummyexpr RPAREN { } + ; + + */ + + +empty : ; + +%% + +void error_recover() { + int c; + c = yylex(); + while ((c > 0) && (c != SEMI)) + c = yylex(); +} + +/* Called by the parser (yyparse) when an error is found.*/ +void yyerror (char *) { + // Fprintf(stderr,"%s : Line %d. Syntax error.\n", input_file, line_number); + // error_recover(); +} + diff --git a/wxPython/wxSWIG/SWIG/scanner.cxx b/wxPython/wxSWIG/SWIG/scanner.cxx new file mode 100644 index 0000000000..8f88562f0b --- /dev/null +++ b/wxPython/wxSWIG/SWIG/scanner.cxx @@ -0,0 +1,1381 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/************************************************************************* + * $Header$ + * scanner.c + * + * Dave Beazley + * January 1996 + * + * Input scanner. This scanner finds and returns tokens + * for the wrapper generator. Since using lex/flex from + * C++ is so F'ed up, I've written this function to replace + * them entirely. It's not as fast, but hopefully it will + * eliminate alot of compilation problems. + * + *************************************************************************/ + + +#include "internal.h" +#include "parser.h" +#include +#include + +#define YYBSIZE 8192 + +struct InFile { + FILE *f; + int line_number; + char *in_file; + int extern_mode; + int force_extern; + struct InFile *prev; +}; + +// This structure is used for managing code fragments as +// might be used by the %inline directive and handling of +// nested structures. + +struct CodeFragment { + char *text; + int line_number; + CodeFragment *next; +}; + +InFile *in_head; + +FILE *LEX_in = NULL; + +static String header; +static String comment; + String CCode; // String containing C code +static char *yybuffer; +static int lex_pos = 0; +static int lex_len = 0; +static char *inline_yybuffer = 0; +static int inline_lex_pos = 0; +static int inline_lex_len = 0; +static int inline_line_number = 0; +static CodeFragment *fragments = 0; // Code fragments + +static +char yytext[YYBSIZE]; +static int yylen = 0; +int line_number = 1; +int column = 1; +int column_start = 1; +char *input_file; +int start_line = 0; +static int comment_start; +static int scan_init = 0; +static int num_brace = 0; +static int last_brace = 0; +static int in_define = 0; +static int define_first_id = 0; /* Set when looking for first identifier of a define */ +extern int Error; + + +/************************************************************** + * scanner_init() + * + * Initialize buffers + **************************************************************/ + +void scanner_init() { + + yybuffer = (char *) malloc(YYBSIZE); + scan_init = 1; +} + +/************************************************************** + * scanner_file(FILE *f) + * + * Start reading from new file + **************************************************************/ +void scanner_file(FILE *f) { + InFile *in; + + in = new InFile; + in->f = f; + in->in_file = input_file; + in->extern_mode = WrapExtern; + in->force_extern = ForceExtern; + if (in_head) in_head->line_number = line_number+1; + if (!in_head) in->prev = 0; + else in->prev = in_head; + in_head = in; + LEX_in = f; + line_number = 1; +} + +/************************************************************** + * scanner_close() + * + * Close current input file and go to next + **************************************************************/ + +void scanner_close() { + + InFile *p; + static int lib_insert = 0; + fclose(LEX_in); + if (!in_head) return; + p = in_head->prev; + if (p != 0) { + LEX_in = p->f; + line_number = p->line_number; + input_file = p->in_file; + WrapExtern = p->extern_mode; + if (!WrapExtern) remove_symbol("SWIGEXTERN"); + ForceExtern = p->force_extern; + } else { + LEX_in = NULL; + } + delete in_head; + in_head = p; + + // if LEX_in is NULL it means we're done with the interface file. We're now + // going to grab all of the library files. + + if ((!LEX_in) && (!lib_insert)) { + library_insert(); + lib_insert = 1; + } + +} + +/************************************************************** + * char nextchar() + * + * gets next character from input. + * If we're in inlining mode, we actually retrieve a character + * from inline_yybuffer instead. + **************************************************************/ + +char nextchar() { + + char c = 0; + + if (Inline) { + if (inline_lex_pos >= inline_lex_len) { + // Done with inlined code. Check to see if we have any + // new code fragments. If so, switch to them. + delete inline_yybuffer; + if (fragments) { + CodeFragment *f; + inline_yybuffer = fragments->text; + inline_lex_pos = 1; + inline_lex_len = strlen(fragments->text); + line_number = fragments->line_number; + f = fragments->next; + delete fragments; + fragments = f; + c = inline_yybuffer[0]; + } else { + c = 0; + Inline = 0; + line_number = inline_line_number; // Restore old line number + } + } else { + inline_lex_pos++; + c = inline_yybuffer[inline_lex_pos-1]; + } + } + if (!Inline) { + if (lex_pos >= lex_len) { + if (!LEX_in) { + SWIG_exit(1); + } + while(fgets(yybuffer, YYBSIZE, LEX_in) == NULL) { + scanner_close(); // Close current input file + if (!LEX_in) return 0; // No more, we're outta here + } + lex_len = strlen(yybuffer); + lex_pos = 0; + } + + lex_pos++; + c = yybuffer[lex_pos-1]; + } + + if (yylen >= YYBSIZE) { + fprintf(stderr,"** FATAL ERROR. Buffer overflow in scanner.cxx.\nReport this to swig@cs.utah.edu.\n"); + SWIG_exit(1); + } + yytext[yylen] = c; + yylen++; + if (c == '\n') { + line_number++; + column = 1; + } else { + column++; + } + return(c); +} + +void retract(int n) { + int i, j, c; + + for (i = 0; i < n; i++) { + if (Inline) { + inline_lex_pos--; + if (inline_lex_pos < 0) { + fprintf(stderr,"Internal scanner error. inline_lex_pos < 0\n"); + SWIG_exit(1); + } + } + else lex_pos--; + yylen--; + column--; + if (yylen >= 0) { + if (yytext[yylen] == '\n') { + line_number--; + // Figure out what column we're in + c = yylen-1; + j = 1; + while (c >= 0){ + if (yytext[c] == '\n') break; + j++; + c--; + } + column = j; + } + } + } + if (yylen < 0) yylen = 0; +} + +/************************************************************** + * start_inline(char *text, int line) + * + * This grabs a chunk of text and tries to inline it into + * the current file. (This is kind of wild, but cool when + * it works). + * + * If we're already in inlining mode, we will save the code + * as a new fragment. + **************************************************************/ + +void start_inline(char *text, int line) { + + if (Inline) { + + // Already processing a code fragment, simply hang on + // to this one for later. + + CodeFragment *f,*f1; + + // Add a new code fragment to our list + f = new CodeFragment; + f->text = copy_string(text); + f->line_number = line; + f->next = 0; + if (!fragments) fragments = f; + else { + f1 = fragments; + while (f1->next) f1 = f1->next; + f1->next = f; + } + } else { + + // Switch our scanner over to process text from a string. + // Save current line number and other information however. + + inline_yybuffer = copy_string(text); + inline_lex_len = strlen(text); + inline_lex_pos = 0; + inline_line_number = line_number; // Make copy of old line number + line_number = line; + Inline = 1; + } +} + +/************************************************************** + * yycomment(char *, int line) + * + * Inserts a comment into a documentation entry. + **************************************************************/ + +void yycomment(char *s, int line, int col) { + comment_handler->add_comment(s,line,col,input_file); +} + +/************************************************************** + * void skip_brace(void) + * + * Found a {. + * Skip all characters until we find a matching closed }. + * + * This function is used to skip over inlined C code and other + * garbage found in interface files. + ***************************************************************/ + +void skip_brace(void) { + + char c; + CCode = "{"; + while (num_brace > last_brace) { + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : Line %d. Missing '}'. Reached end of input.\n", + input_file, line_number); + FatalError(); + return; + } + CCode << c; + if (c == '{') num_brace++; + if (c == '}') num_brace--; + yylen = 0; + } +} + + +/************************************************************** + * void skip_template(void) + * + * Found a <. + * Skip all characters until we find a matching closed >. + * + * This function is used to skip over C++ templated types + * and objective-C protocols. + ***************************************************************/ + +void skip_template(void) { + + char c; + CCode = "<"; + int num_lt = 1; + while (num_lt > 0) { + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : Line %d. Missing '>'. Reached end of input.\n", + input_file, line_number); + FatalError(); + return; + } + CCode << c; + if (c == '<') num_lt++; + if (c == '>') num_lt--; + yylen = 0; + } +} + +/************************************************************** + * void skip_to_end(void) + * + * Skips to the @end directive in a Objective-C definition + **************************************************************/ + +void skip_to_end(void) { + char c; + int state = 0; + yylen = 0; + while ((c = nextchar())){ + switch(state) { + case 0: + if (c == '@') state = 1; + else yylen = 0; + break; + case 1: + if (isspace(c)) { + if (strncmp(yytext,"@end",4) == 0) return; + else { + yylen = 0; + state = 0; + } + } else { + state = 1; + } + break; + } + } + fprintf(stderr,"%s : EOF. Missing @end. Reached end of input.\n", + input_file); + FatalError(); + return; +} + +/************************************************************** + * void skip_decl(void) + * + * This tries to skip over an entire declaration. For example + * + * friend ostream& operator<<(ostream&, const char *s); + * + * or + * friend ostream& operator<<(ostream&, const char *s) { }; + * + **************************************************************/ + +void skip_decl(void) { + char c; + int done = 0; + while (!done) { + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : Line %d. Missing semicolon. Reached end of input.\n", + input_file, line_number); + FatalError(); + return; + } + if (c == '{') { + last_brace = num_brace; + num_brace++; + break; + } + yylen = 0; + if (c == ';') done = 1; + } + if (!done) { + while (num_brace > last_brace) { + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : Line %d. Missing '}'. Reached end of input.\n", + input_file, line_number); + FatalError(); + return; + } + if (c == '{') num_brace++; + if (c == '}') num_brace--; + yylen = 0; + } + } +} + +/************************************************************** + * void skip_define(void) + * + * Skips to the end of a #define statement. + * + **************************************************************/ + +void skip_define(void) { + char c; + while (in_define) { + if ((c = nextchar()) == 0) return; + if (c == '\\') in_define = 2; + if (c == '\n') { + if (in_define == 2) { + in_define = 1; + } else if (in_define == 1) { + in_define = 0; + } + } + yylen = 0; + } +} + +/************************************************************** + * int skip_cond(int inthen) + * + * Skips the false portion of an #ifdef directive. Looks + * for either a matching #else or #endif + * + * inthen is 0 or 1 depending on whether or not we're + * handling the "then" or "else" part of a conditional. + * + * Returns 1 if the else part of the #if-#endif block was + * reached. Returns 0 otherwise. Returns -1 on error. + **************************************************************/ + +int skip_cond(int inthen) { + int level = 0; /* Used to handled nested if-then-else */ + int state = 0; + char c; + int start_line; + char *file; + + file = copy_string(input_file); + start_line = line_number; + yylen = 0; + + while(1) { + switch(state) { + case 0 : + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : Line %d. Unterminated #if-else directive.\n", file, start_line); + FatalError(); + return -1; /* Error */ + } + if ((c == '#') || (c == '%')) { + state = 1; + } else if (isspace(c)) { + yylen =0; + state = 0; + } else { + /* Some non-whitespace character. Look for line end */ + yylen = 0; + state = 3; + } + break; + case 1: + /* Beginning of a C preprocessor statement */ + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : Line %d. Unterminated #if-else directive.\n", file, start_line); + FatalError(); + return -1; /* Error */ + } + if (c == '\n') { + state = 0; + yylen = 0; + } + else if (isspace(c)) { + state = 1; + yylen--; + } else { + state = 2; + } + break; + case 2: + /* CPP directive */ + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : Line %d. Unterminated #if-else directive.\n", file, start_line); + FatalError(); + return -1; /* Error */ + } + if ((c == ' ') || (c == '\t') || (c=='\n')) { + yytext[yylen-1] = 0; + if ((strcmp(yytext,"#ifdef") == 0) || (strcmp(yytext,"%ifdef") == 0)) { + level++; + state = 0; + } else if ((strcmp(yytext,"#ifndef") == 0) || (strcmp(yytext,"%ifndef") == 0)) { + level++; + state = 0; + } else if ((strcmp(yytext,"#if") == 0) || (strcmp(yytext,"%if") == 0)) { + level++; + state = 0; + } else if ((strcmp(yytext,"#else") == 0) || (strcmp(yytext,"%else") == 0)) { + if (level == 0) { /* Found matching else. exit */ + if (!inthen) { + /* Hmmm. We've got an "extra #else" directive here */ + fprintf(stderr,"%s : Line %d. Misplaced #else.\n", input_file, line_number); + FatalError(); + yylen = 0; + state = 0; + } else { + yylen = 0; + delete file; + return 1; + } + } else { + yylen = 0; + state = 0; + } + } else if ((strcmp(yytext,"#endif") == 0) || (strcmp(yytext,"%endif") == 0)) { + if (level <= 0) { /* Found matching endif. exit */ + yylen = 0; + delete file; + return 0; + } else { + state = 0; + yylen = 0; + level--; + } + } else if ((strcmp(yytext,"#elif") == 0) || (strcmp(yytext,"%elif") == 0)) { + if (level <= 0) { + // If we come across this, we pop it back onto the input queue and return + retract(6); + delete file; + return 0; + } else { + yylen = 0; + state = 0; + } + } else { + yylen = 0; + state = 0; + } + } + break; + case 3: + /* Non-white space. Look for line break */ + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : Line %d. Unterminated #if directive.\n", file, start_line); + FatalError(); + return -1; /* Error */ + } + if (c == '\n') { + yylen = 0; + state = 0; + } else { + yylen = 0; + state = 3; + } + break; + } + } +} + +/************************************************************** + * int yylook() + * + * Lexical scanner. + * See Aho,Sethi, and Ullman, pg. 106 + **************************************************************/ + +int yylook(void) { + + int state; + char c = 0; + + state = 0; + yylen = 0; + while(1) { + +/* printf("State = %d\n", state); */ + switch(state) { + + case 0 : + if((c = nextchar()) == 0) return(0); + + /* Process delimeters */ + + if (c == '\n') { + state = 0; + yylen = 0; + if (in_define == 1) { + in_define = 0; + return(ENDDEF); + } else if (in_define == 2) { + in_define = 1; + } + } else if (isspace(c)) { + state = 0; + yylen = 0; + } + + /* Look for single character symbols */ + + else if (c == '(') return (LPAREN); + else if (c == ')') return (RPAREN); + else if (c == ';') return (SEMI); + else if (c == ',') return (COMMA); + else if (c == '*') return (STAR); + else if (c == '}') { + num_brace--; + if (num_brace < 0) { + fprintf(stderr,"%s : Line %d. Error. Extraneous '}' (Ignored)\n", + input_file, line_number); + state = 0; + num_brace = 0; + } else { + return (RBRACE); + } + } + else if (c == '{') { + last_brace = num_brace; + num_brace++; + return (LBRACE); + } + else if (c == '=') return (EQUAL); + else if (c == '+') return (PLUS); + else if (c == '-') return (MINUS); + else if (c == '&') return (AND); + else if (c == '|') return (OR); + else if (c == '^') return (XOR); + else if (c == '<') state = 60; + else if (c == '>') state = 61; + else if (c == '~') return (NOT); + else if (c == '!') return (LNOT); + else if (c == '\\') { + if (in_define == 1) { + in_define = 2; + state = 0; + } else + state = 99; + } + else if (c == '[') return (LBRACKET); + else if (c == ']') return (RBRACKET); + + /* Look for multi-character sequences */ + + else if (c == '/') state = 1; // Comment (maybe) + else if (c == '\"') state = 2; // Possibly a string + else if (c == '#') state = 3; // CPP + else if (c == '%') state = 4; // Directive + else if (c == '@') state = 4; // Objective C keyword + else if (c == ':') state = 5; // maybe double colon + else if (c == '0') state = 83; // An octal or hex value + else if (c == '\'') state = 9; // A character constant + else if (c == '.') state = 100; // Maybe a number, maybe just a period + else if (isdigit(c)) state = 8; // A numerical value + else if ((isalpha(c)) || (c == '_') || (c == '$')) state = 7; + else state = 99; + break; + case 1: /* Comment block */ + if ((c = nextchar()) == 0) return(0); + if (c == '/') { + comment_start = line_number; + column_start = column; + comment = " "; + state = 10; // C++ style comment + } else if (c == '*') { + comment_start = line_number; + column_start = column; + comment = " "; + state = 11; // C style comment + } else { + retract(1); + return(SLASH); + } + break; + case 10: /* C++ style comment */ + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : EOF. Unterminated comment detected.\n",input_file); + FatalError(); + return 0; + } + if (c == '\n') { + comment << c; + // Add the comment to documentation + yycomment(comment.get(),comment_start, column_start); + yylen = 0; + state = 0; + if (in_define == 1) { + in_define = 0; + return(ENDDEF); + } + } else { + state = 10; + comment << c; + yylen = 0; + } + break; + case 11: /* C style comment block */ + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : EOF. Unterminated comment detected.\n", input_file); + FatalError(); + return 0; + } + if (c == '*') { + state = 12; + } else { + comment << c; + yylen = 0; + state = 11; + } + break; + case 12: /* Still in C style comment */ + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : EOF. Unterminated comment detected.\n", input_file); + FatalError(); + return 0; + } + if (c == '*') { + comment << c; + state = 12; + } else if (c == '/') { + comment << " \n"; + yycomment(comment.get(),comment_start,column_start); + yylen = 0; + state = 0; + } else { + comment << '*' << c; + yylen = 0; + state = 11; + } + break; + + case 2: /* Processing a string */ + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : EOF. Unterminated string detected.\n", input_file); + FatalError(); + return 0; + } + if (c == '\"') { + yytext[yylen-1] = 0; + yylval.id = copy_string(yytext+1); + return(STRING); + } else if (c == '\\') { + state = 21; /* Possibly an escape sequence. */ + break; + } else state = 2; + break; + case 21: /* An escape sequence. get next character, then go + back to processing strings */ + + if ((c = nextchar()) == 0) return 0; + state = 2; + break; + + case 3: /* a CPP directive */ + + if (( c= nextchar()) == 0) return 0; + if (c == '\n') { + retract(1); + yytext[yylen] = 0; + yylval.id = yytext; + return(POUND); + } else if ((c == ' ') || (c == '\t')) { // Ignore white space after # symbol + yytext[yylen] = 0; + yylen--; + state = 3; + } else { + yytext[yylen] = 0; + state = 31; + } + break; + case 31: + if ((c = nextchar()) == 0) return 0; + if ((c == ' ') || (c == '\t') || (c=='\n')) { + retract(1); + yytext[yylen] = 0; + if (strcmp(yytext,"#define") == 0) { + in_define = 1; + define_first_id = 1; + return(DEFINE); + } else if (strcmp(yytext,"#ifdef") == 0) { + return(IFDEF); + } else if (strcmp(yytext,"#ifndef") == 0) { + return(IFNDEF); + } else if (strcmp(yytext,"#else") == 0) { + return(ELSE); + } else if (strcmp(yytext,"#endif") == 0) { + return(ENDIF); + } else if (strcmp(yytext,"#undef") == 0) { + return(UNDEF); + } else if (strcmp(yytext,"#if") == 0) { + return(IF); + } else if (strcmp(yytext,"#elif") == 0) { + return(ELIF); + } else { + /* Some kind of "unknown CPP directive. Skip to end of the line */ + state = 32; + } + } + break; + case 32: + if ((c = nextchar()) == 0) return 0; + if (c == '\n') { + retract(1); + yytext[yylen] = 0; + yylval.id = yytext; + return(POUND); + } + state = 32; + break; + + case 4: /* A wrapper generator directive (maybe) */ + if (( c= nextchar()) == 0) return 0; + if (c == '{') { + state = 40; /* Include block */ + header = ""; + start_line = line_number; + } + else if ((isalpha(c)) || (c == '_')) state = 7; + else { + retract(1); + state = 99; + } + break; + + case 40: /* Process an include block */ + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : EOF. Unterminated include block detected.\n", input_file); + FatalError(); + return 0; + } + yylen = 0; + if (c == '%') state = 41; + else { + header << c; + yylen = 0; + state = 40; + } + break; + case 41: /* Still processing include block */ + if ((c = nextchar()) == 0) { + fprintf(stderr,"%s : EOF. Unterminated include block detected.\n", input_file); + FatalError(); + return 0; + } + if (c == '}') { + yylval.id = header.get(); + return(HBLOCK); + } else { + header << '%'; + header << c; + yylen = 0; + state = 40; + } + break; + + case 5: /* Maybe a double colon */ + + if (( c= nextchar()) == 0) return 0; + if ( c == ':') return DCOLON; + else { + retract(1); + return COLON; + } + + + case 60: /* shift operators */ + if ((c = nextchar()) == 0) return (0); + if (c == '<') return LSHIFT; + else { + retract(1); + return LESSTHAN; + } + break; + case 61: + if ((c = nextchar()) == 0) return (0); + if (c == '>') return RSHIFT; + else { + retract(1); + return GREATERTHAN; + } + break; + case 7: /* Identifier */ + if ((c = nextchar()) == 0) return(0); + if (isalnum(c) || (c == '_') || (c == '.') || (c == '$')) + // || (c == '.') || (c == '-')) + state = 7; + else if (c == '(') { + /* We might just be in a CPP macro definition. Better check */ + if ((in_define) && (define_first_id)) { + /* Yep. We're going to ignore the rest of it */ + skip_define(); + define_first_id = 0; + return (MACRO); + } else { + retract(1); + define_first_id = 0; + return(ID); + } + } else { + retract(1); + define_first_id = 0; + return(ID); + } + break; + case 8: /* A numerical digit */ + if ((c = nextchar()) == 0) return(0); + if (c == '.') {state = 81;} + else if ((c == 'e') || (c == 'E')) {state = 86;} + else if ((c == 'f') || (c == 'F')) { + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_FLOAT); + } + else if (isdigit(c)) { state = 8;} + else if ((c == 'l') || (c == 'L')) { + state = 87; + } else if ((c == 'u') || (c == 'U')) { + state = 88; + } else { + retract(1); + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_INT); + } + break; + case 81: /* A floating pointer number of some sort */ + if ((c = nextchar()) == 0) return(0); + if (isdigit(c)) state = 81; + else if ((c == 'e') || (c == 'E')) state = 82; + else if ((c == 'f') || (c == 'F') || (c == 'l') || (c == 'L')) { + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_FLOAT); + } else { + retract(1); + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_FLOAT); + } + break; + case 82: + if ((c = nextchar()) == 0) return(0); + if ((isdigit(c)) || (c == '-') || (c == '+')) state = 86; + else { + retract(2); + yytext[yylen-1] = 0; + yylval.id = copy_string(yytext); + return(NUM_INT); + } + break; + case 83: + /* Might be a hexidecimal or octal number */ + if ((c = nextchar()) == 0) return(0); + if (isdigit(c)) state = 84; + else if ((c == 'x') || (c == 'X')) state = 85; + else if (c == '.') state = 81; + else if ((c == 'l') || (c == 'L')) { + state = 87; + } else if ((c == 'u') || (c == 'U')) { + state = 88; + } else { + retract(1); + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_INT); + } + break; + case 84: + /* This is an octal number */ + if ((c = nextchar()) == 0) return (0); + if (isdigit(c)) state = 84; + else if ((c == 'l') || (c == 'L')) { + state = 87; + } else if ((c == 'u') || (c == 'U')) { + state = 88; + } else { + retract(1); + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_INT); + } + break; + case 85: + /* This is an hex number */ + if ((c = nextchar()) == 0) return (0); + if ((isdigit(c)) || (c=='a') || (c=='b') || (c=='c') || + (c=='d') || (c=='e') || (c=='f') || (c=='A') || + (c=='B') || (c=='C') || (c=='D') || (c=='E') || + (c=='F')) + state = 85; + else if ((c == 'l') || (c == 'L')) { + state = 87; + } else if ((c == 'u') || (c == 'U')) { + state = 88; + } else { + retract(1); + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_INT); + } + break; + + case 86: + /* Rest of floating point number */ + + if ((c = nextchar()) == 0) return (0); + if (isdigit(c)) state = 86; + else if ((c == 'f') || (c == 'F') || (c == 'l') || (c == 'L')) { + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_FLOAT); + } else { + retract(1); + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_FLOAT); + } + /* Parse a character constant. ie. 'a' */ + break; + + case 87 : + /* A long integer of some sort */ + if ((c = nextchar()) == 0) return (0); + if ((c == 'u') || (c == 'U')) { + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_ULONG); + } else { + retract(1); + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_LONG); + } + + case 88: + /* An unsigned integer of some sort */ + if ((c = nextchar()) == 0) return (0); + if ((c == 'l') || (c == 'L')) { + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_ULONG); + } else { + retract(1); + yytext[yylen] = 0; + yylval.id = copy_string(yytext); + return(NUM_UNSIGNED); + } + + case 9: + if ((c = nextchar()) == 0) return (0); + if (c == '\'') { + yytext[yylen-1] = 0; + yylval.id = copy_string(yytext+1); + return(CHARCONST); + } + break; + + case 100: + if ((c = nextchar()) == 0) return (0); + if (isdigit(c)) state = 81; + else { + retract(1); + return(PERIOD); + } + break; + default: + if (!Error) { + fprintf(stderr,"%s : Line %d ::Illegal character '%c'=%d.\n",input_file, line_number,c,c); + FatalError(); + } + state = 0; + Error = 1; + return(ILLEGAL); + } + } +} + +static int check_typedef = 0; + +void scanner_check_typedef() { + check_typedef = 1; +} + +void scanner_ignore_typedef() { + check_typedef = 0; +} + + +/************************************************************** + * int yylex() + * + * Gets the lexene and returns tokens. + *************************************************************/ + +extern "C" int yylex(void) { + + int l; + + if (!scan_init) { + scanner_init(); + // if (LEX_in == NULL) LEX_in = stdin; + // scanner_file(LEX_in); + } + + l = yylook(); + + /* We got some sort of non-white space object. We set the start_line + variable unless it has already been set */ + + if (!start_line) { + start_line = line_number; + } + + /* Copy the lexene */ + + yytext[yylen] = 0; + + /* Hack to support ignoring of CPP macros */ + + if (l != DEFINE) { + define_first_id = 0; + } + + switch(l) { + + case ID: + + /* Look for keywords now */ + + if (strcmp(yytext,"int") == 0) { + yylval.type = new DataType; + yylval.type->type = T_INT; + strcpy(yylval.type->name,yytext); + return(TYPE_INT); + } + if (strcmp(yytext,"double") == 0) { + yylval.type = new DataType; + yylval.type->type = T_DOUBLE; + strcpy(yylval.type->name,yytext); + return(TYPE_DOUBLE); + } + if (strcmp(yytext,"void") == 0) { + yylval.type = new DataType; + yylval.type->type = T_VOID; + strcpy(yylval.type->name,yytext); + return(TYPE_VOID); + } + if (strcmp(yytext,"char") == 0) { + yylval.type = new DataType; + yylval.type->type = T_CHAR; + strcpy(yylval.type->name,yytext); + return(TYPE_CHAR); + } + if (strcmp(yytext,"short") == 0) { + yylval.type = new DataType; + yylval.type->type = T_SHORT; + strcpy(yylval.type->name,yytext); + return(TYPE_SHORT); + } + if (strcmp(yytext,"long") == 0) { + yylval.type = new DataType; + yylval.type->type = T_LONG; + strcpy(yylval.type->name,yytext); + return(TYPE_LONG); + } + if (strcmp(yytext,"float") == 0) { + yylval.type = new DataType; + yylval.type->type = T_FLOAT; + strcpy(yylval.type->name,yytext); + return(TYPE_FLOAT); + } + if (strcmp(yytext,"signed") == 0) { + yylval.type = new DataType; + yylval.type->type = T_SINT; + strcpy(yylval.type->name,yytext); + return(TYPE_SIGNED); + } + if (strcmp(yytext,"unsigned") == 0) { + yylval.type = new DataType; + yylval.type->type = T_UINT; + strcpy(yylval.type->name,yytext); + return(TYPE_UNSIGNED); + } + if (strcmp(yytext,"bool") == 0) { + yylval.type = new DataType; + yylval.type->type = T_BOOL; + strcpy(yylval.type->name,yytext); + return(TYPE_BOOL); + } + // C++ keywords + + if (CPlusPlus) { + if (strcmp(yytext,"class") == 0) return(CLASS); + if (strcmp(yytext,"private") == 0) return(PRIVATE); + if (strcmp(yytext,"public") == 0) return(PUBLIC); + if (strcmp(yytext,"protected") == 0) return(PROTECTED); + if (strcmp(yytext,"friend") == 0) return(FRIEND); + if (strcmp(yytext,"virtual") == 0) return(VIRTUAL); + if (strcmp(yytext,"operator") == 0) return(OPERATOR); + if (strcmp(yytext,"throw") == 0) return(THROW); + if (strcmp(yytext,"inline") == 0) return(yylex()); + if (strcmp(yytext,"template") == 0) return(TEMPLATE); + } + + // Objective-C keywords + if (ObjC) { + if (strcmp(yytext,"@interface") == 0) return (OC_INTERFACE); + if (strcmp(yytext,"@end") == 0) return (OC_END); + if (strcmp(yytext,"@public") == 0) return (OC_PUBLIC); + if (strcmp(yytext,"@private") == 0) return (OC_PRIVATE); + if (strcmp(yytext,"@protected") == 0) return (OC_PROTECTED); + if (strcmp(yytext,"@class") == 0) return(OC_CLASS); + if (strcmp(yytext,"@implementation") == 0) return(OC_IMPLEMENT); + if (strcmp(yytext,"@protocol") == 0) return(OC_PROTOCOL); + } + + // Misc keywords + + if (strcmp(yytext,"static") == 0) return(STATIC); + if (strcmp(yytext,"extern") == 0) return(EXTERN); + if (strcmp(yytext,"const") == 0) return(CONST); + 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,"defined") == 0) return(DEFINED); + + // Ignored keywords + + if (strcmp(yytext,"volatile") == 0) return(yylex()); + + // SWIG directives + + if (strcmp(yytext,"%module") == 0) return(MODULE); + if (strcmp(yytext,"%init") == 0) return(INIT); + if (strcmp(yytext,"%wrapper") == 0) return(WRAPPER); + if (strcmp(yytext,"%readonly") == 0) return(READONLY); + if (strcmp(yytext,"%readwrite") == 0) return(READWRITE); + if (strcmp(yytext,"%name") == 0) return(NAME); + if (strcmp(yytext,"%rename") == 0) return(RENAME); + if (strcmp(yytext,"%include") == 0) return(INCLUDE); + if (strcmp(yytext,"%extern") == 0) return(WEXTERN); + if (strcmp(yytext,"%checkout") == 0) return(CHECKOUT); + if (strcmp(yytext,"%val") == 0) return(CVALUE); + if (strcmp(yytext,"%out") == 0) return(COUT); + + if (strcmp(yytext,"%section") == 0) { + yylval.ivalue = line_number; + return(SECTION); + } + if (strcmp(yytext,"%subsection") == 0) { + yylval.ivalue = line_number; + return(SUBSECTION); + } + if (strcmp(yytext,"%subsubsection") == 0) { + yylval.ivalue = line_number; + return (SUBSUBSECTION); + } + if (strcmp(yytext,"%title") == 0) { + yylval.ivalue = line_number; + return(TITLE); + } + if (strcmp(yytext,"%style") == 0) return(STYLE); + if (strcmp(yytext,"%localstyle") == 0) return(LOCALSTYLE); + if (strcmp(yytext,"%typedef") == 0) { + yylval.ivalue = 1; + return(TYPEDEF); + } + if (strcmp(yytext,"typedef") == 0) { + yylval.ivalue = 0; + return(TYPEDEF); + } + if (strcmp(yytext,"%alpha") == 0) return(ALPHA_MODE); + if (strcmp(yytext,"%raw") == 0) return(RAW_MODE); + if (strcmp(yytext,"%text") == 0) return(TEXT); + if (strcmp(yytext,"%native") == 0) return(NATIVE); + if (strcmp(yytext,"%disabledoc") == 0) return(DOC_DISABLE); + if (strcmp(yytext,"%enabledoc") == 0) return(DOC_ENABLE); + if (strcmp(yytext,"%ifdef") == 0) return(IFDEF); + if (strcmp(yytext,"%else") == 0) return(ELSE); + if (strcmp(yytext,"%ifndef") == 0) return(IFNDEF); + if (strcmp(yytext,"%endif") == 0) return(ENDIF); + if (strcmp(yytext,"%if") == 0) return(IF); + if (strcmp(yytext,"%elif") == 0) return(ELIF); + if (strcmp(yytext,"%pragma") == 0) return(PRAGMA); + if (strcmp(yytext,"%addmethods") == 0) return(ADDMETHODS); + if (strcmp(yytext,"%inline") == 0) return(INLINE); + if (strcmp(yytext,"%typemap") == 0) return(TYPEMAP); + if (strcmp(yytext,"%except") == 0) return(EXCEPT); + if (strcmp(yytext,"%import") == 0) return(IMPORT); + if (strcmp(yytext,"%echo") == 0) return(ECHO); + if (strcmp(yytext,"%new") == 0) return(NEW); + if (strcmp(yytext,"%apply") == 0) return(APPLY); + if (strcmp(yytext,"%clear") == 0) return(CLEAR); + if (strcmp(yytext,"%doconly") == 0) return(DOCONLY); + + // Have an unknown identifier, as a last step, we'll + // do a typedef lookup on it. + + if (check_typedef) { + if (DataType::is_typedef(yytext)) { + yylval.type = new DataType; + yylval.type->type = T_USER; + strcpy(yylval.type->name,yytext); + yylval.type->typedef_resolve(); + return(TYPE_TYPEDEF); + } + } + + yylval.id = copy_string(yytext); + return(ID); + default: + return(l); + } +} + +// -------------------------------------------------------------- +// scanner_clear_start() +// +// Clears the start of a declaration +// -------------------------------------------------------------- + +void scanner_clear_start() { + start_line = 0; +} diff --git a/wxPython/wxSWIG/SWIG/sstring.cxx b/wxPython/wxSWIG/SWIG/sstring.cxx new file mode 100644 index 0000000000..15046255c3 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/sstring.cxx @@ -0,0 +1,587 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" +#include + +//----------------------------------------------------------------------- +// char *copy_string(char *str) +// +// Makes a copy of string str. Returns a pointer to it. +//----------------------------------------------------------------------- + +char *copy_string(char *str) { + char *res = 0; + if (str) { + res = new char[strlen(str)+1]; + strcpy(res,str); + } + return res; +} + +//----------------------------------------------------------------------- +// void format_string(char *str) +// +// Replace all of the escape sequences in the string str. It is +// assumed that the new string is smaller than the original! +//----------------------------------------------------------------------- + +void format_string(char *str) { + char *newstr, *c,*c1; + int state; + if (!str) return; + newstr = copy_string(str); + c = newstr; + c1 = str; + state = 0; + while (*c) { + switch(state) { + case 0: + if (*c == '\\') + state = 1; + else { + *(c1++) = *c; + state = 0; + } + break; + case 1: + // We're in a simple escape sequence figure out what to do + switch(*c) { + case 'n': + *(c1++) = '\n'; + break; + case 'f': + *(c1++) = '\f'; + break; + case 'r': + *(c1++) = '\r'; + break; + case 't': + *(c1++) = '\t'; + break; + case '\\': + *(c1++) = '\\'; + break; + case '\"': + *(c1++) = '\"'; + break; + case '\'': + *(c1++) = '\''; + break; + default: + *(c1++) = '\\'; + *(c1++) = *c; + } + state = 0; + break; + default: + *(c1++) = *c; + state = 0; + } + c++; + } + *c1 = 0; + delete newstr; +} + +// --------------------------------------------------------------------------- +// $Header$ +// sstring.cxx +// +// SWIG String class. +// This class is used to construct long strings when writing +// wrapper functions. It also "mimicks" the C++ streams I/O +// library for creating strings. For example : +// +// str << "hi there" << 3 << "\n"; +// +// Will append the given strings to str. +// +// The idea here is to provide a mechanism for writing wrapper +// functions as strings before writing them out to a file. +// +// --------------------------------------------------------------------------- +#define INIT_MAXSIZE 64 + +// --------------------------------------------------------------- +// Pools. This is a list of available strings for memory allocation +// and deletion. +// --------------------------------------------------------------- + +struct StrMem { + char *str; + int len; +}; + +#define POOLSIZE 100 + +static StrMem pool[POOLSIZE]; +static int pool_index = 0; + +// Returns an item from the pool that can accomodate len +static char *get_pool(int len, int &newlen) { + int i,j; + char *nc; + if (pool_index < 1) { + newlen = len; + return new char[len]; + } + i = pool_index-1; + j = 0; + while(i >= 0) { + if ((pool[i].len >= len) && (pool[i].len <= 4*len)) { + nc = pool[i].str; + newlen = pool[i].len; + pool[i].str = pool[pool_index-1].str; + pool[i].len = pool[pool_index-1].len; + pool_index--; + return nc; + } + j++; + i--; + } + newlen = len; + return new char[len]; +} + +// Puts an item onto the pool + +static void put_pool(char *str, int len) { + if (len < INIT_MAXSIZE) { + delete [] str; + return; + } + if (pool_index == POOLSIZE) { + delete [] pool[pool_index-1].str; + pool_index--; + } + pool[pool_index].str = str; + pool[pool_index].len = len; + if (pool_index != POOLSIZE) + pool_index++; +} + +// --------------------------------------------------------------- +// String::String() +// +// Create a new string with nothing in it +// --------------------------------------------------------------- + +String::String() { + maxsize = INIT_MAXSIZE; + str = get_pool(maxsize,maxsize); // May return a pool that is larger + str[0] = 0; + len = 0; +} + +// --------------------------------------------------------------- +// String::String(const char *s) +// +// Create a new string copied from a normal C-style string +// --------------------------------------------------------------- + +String::String(const char *s) { + int max = INIT_MAXSIZE; + int l = 0; + if (s) { + l = (int) strlen(s); + if ((l+1) > max) max = l+1; + } + str = get_pool(max,maxsize); + if (s) { + strcpy(str,s); + len = l; + } else { + str[0] = 0; + len = 0; + } +} + +// --------------------------------------------------------------- +// String::~String(const char *s) +// +// Destroy a string +// --------------------------------------------------------------- + +String::~String() { + put_pool(str,maxsize); +} + +// --------------------------------------------------------------- +// String::add(const char *newstr) +// +// Concatenate newstr onto the current string +// --------------------------------------------------------------- + +void String::add(const char *newstr) { + int newlen; + char *nstr = 0; + int newmaxsize; + int l; + + l = (int) strlen(newstr); + newlen = len+l + 1; + if (newlen >= maxsize-1) { + newmaxsize = 2*maxsize; + if (newlen >= newmaxsize -1) newmaxsize = newlen + 1; + nstr = get_pool(newmaxsize,newmaxsize); + strcpy(nstr,str); + put_pool(str,maxsize); + maxsize = newmaxsize; + str = nstr; + } + strcpy(str+len,newstr); + len += l; +} + +// --------------------------------------------------------------- +// String::add(char) +// +// Adds a single character to the current string +// --------------------------------------------------------------- + +void String::add(char nc) { + int newlen; + char *nstr = 0; + int newmaxsize; + + newlen = len+ 1; + if (newlen >= maxsize-1) { + newmaxsize = 2*maxsize; + if (newlen >= newmaxsize -1) newmaxsize = newlen + 1; + nstr = get_pool(newmaxsize,newmaxsize); + strcpy(nstr,str); + put_pool(str,maxsize); + maxsize = newmaxsize; + str = nstr; + } + str[len++] = nc; + str[len] = 0; +} + +// ----------------------------------------------------------------- +// String::insert(const char *newstr) +// +// Inserts a string into the front of a string. (Primarily used +// for documentation generation) +// ----------------------------------------------------------------- + +void String::insert(const char *newstr) { + int newlen; + char *nstr = 0; + int newmaxsize; + int i,l; + + l = strlen(newstr); + newlen = len + l + 1; + if (newlen >= maxsize-1) { + newmaxsize = 2*maxsize; + if (newlen >= newmaxsize -1) newmaxsize = newlen + 1; + nstr = get_pool(newmaxsize,newmaxsize); + strcpy(nstr,str); + put_pool(str,maxsize); + maxsize = newmaxsize; + str = nstr; + } + + /* Shift all of the characters over */ + + for (i = len -1; i >= 0; i--) { + str[i+l] = str[i]; + } + + /* Now insert the new string */ + + strncpy(str,newstr,l); + len += l; + str[len] = 0; + +} + +// ----------------------------------------------------------------- +// char *String::get() +// +// Get the current value of the string +// ----------------------------------------------------------------- + +char *String::get() const { + return str; +} + +// ----------------------------------------------------------------- +// String &operator<<(...) +// +// Shorthand for appending to the end of a string +// ----------------------------------------------------------------- + +String &operator<<(String &t,const char *s) { + t.add(s); + return t; +} + + +String &operator<<(String &t,const char s) { + t.add(s); + return t; +} + +String &operator<<(String &t,const int a) { + char temp[64]; + sprintf(temp,"%d",a); + t.add(temp); + return t; +} + +String &operator<<(String &t, String &s) { + t.add(s.get()); + return t; +} + +String &String::operator=(const char *s) { + int newlen; + + if (s) { + newlen = strlen(s); + if ((newlen >= maxsize) && (str)) { + put_pool(str,maxsize); + str = get_pool(newlen+1,maxsize); + maxsize = newlen+1; + } + strcpy(str,s); + len = newlen; + } else { + str[0] = 0; + len = 0; + } + return *this; +} + +// ----------------------------------------------------------------- +// String &operator>>(...) +// +// Shorthand for inserting into the beginning of a string +// ----------------------------------------------------------------- + +String &operator>>(const char *s, String &t) { + t.insert(s); + return t; +} + +String &operator>>(String &s, String &t) { + t.insert(s.get()); + return t; +} + +// ----------------------------------------------------------------- +// void String::untabify() +// +// Expand all tabs into spaces. This is useful for producing +// documentation and other things. +// ----------------------------------------------------------------- + +void String::untabify() { + char *s; + char *c; + int pos; + int i; + int oldmaxsize; + // Copy the current string representation + + s = str; + oldmaxsize = maxsize; + + // Reset the internal state of this string + + len = 0; + str = get_pool(maxsize,maxsize); + str[0]= 0; + + // Now walk down the old string and expand tabs. Tabs are usually place + // every 8 characters. + + pos = 0; + c = s; + while (*c) { + if (*c == '\n') { + pos = -1; + } + if (*c == '\t') { + // Expand the character + for (i = 0; i < (8 - (pos % 8)); i++) { + this->add(' '); + } + pos+=(8-(pos % 8)); + } else { + this->add(*c); + pos++; + } + c++; + } + + // Blow away the old string + put_pool(s,oldmaxsize); +} + + +// ----------------------------------------------------------------- +// void String::replace(const char *token, const char *rep) +// +// Search for tokens in a string and replace them with rep. +// This probably isn't the fastest implementation, but fortunately +// SWIG rarely calls this function. +// ----------------------------------------------------------------- + +void String::replace(const char *token, const char *rep) { + char *s, *c, *t; + int oldmaxsize = maxsize; + // Copy the current string representation + + s = str; + + // Now walk down the old string and search for tokens + + c = s; + t = strstr(c,token); + if (t) { + len = 0; + str = get_pool(maxsize,maxsize); + while (t) { + // Found a token in string s + // Dump characters into our string + char temp; + temp = *t; + *t = 0; + this->add(c); + c = t; + *t = temp; + + // Now dump the replacement string into place + + this->add(rep); + + // Jump over the token + + c+=strlen(token); + t = strstr(c,token); + } + // Attach rest of the string + if (*c) + this->add(c); + put_pool(s,oldmaxsize); + } +} + + +// ----------------------------------------------------------------- +// void String::replaceid(char *token, char *rep) +// +// Searches for valid identifiers matching token and replaces +// them with rep. Unlike replace() tokens must be a valid C +// identifier (surrounded by whitespace). +// ----------------------------------------------------------------- + +void String::replaceid(const char *token, const char *rep) { + char *s, *c, *t; + int whitespace, tokenlen; + int oldmaxsize = maxsize; + // Copy the current string representation + + s = str; + + // Reset the internal state of this string + + tokenlen = strlen(token); + + // Now walk down the old string and search for tokens + + c = s; + t = strstr(c,token); + if (t) { + len = 0; + str = get_pool(maxsize,maxsize); + while (t) { + // Found a token in string s + // Dump characters into our string + + whitespace = 1; + while (c != t) { + this->add(*c); + if (!(isalpha(*c) || (*c == '_') || (*c == '$'))) whitespace = 1; + else whitespace = 0; + c++; + } + + if (whitespace) { + // Check to see if there is whitespace afterwards + if ((!c[tokenlen]) || (!(isalnum(c[tokenlen]) || (c[tokenlen] == '_') || (c[tokenlen] == '$')))) { + this->add(rep); + } else { + this->add(token); + } + c+=tokenlen; + } else { + this->add(*c); + c++; + } + t = strstr(c,token); + } + + // Attach rest of the string + if (*c) + this->add(c); + + // Delete the old string + put_pool(s,oldmaxsize); + } +} + + +// ----------------------------------------------------------------- +// void String::strip() +// +// Intelligently strips whitespace from a string. Will not strip +// whitespace if it is between two characters that are part of a +// legal C identifier. For example 'unsigned int'. +// ----------------------------------------------------------------- + +void String::strip() { + char *s = str; // Old pointer value + char *c, lastchar = 0; + int whitespace = 0; + int oldmaxsize = maxsize; + + str = get_pool(maxsize,maxsize); // Get a new string. + len = 0; + + c = s; + while(*c) { + if (!isspace(*c)) { + // See if this character doesn't violate our whitespace rules + if (whitespace) { + if (isalnum(lastchar) || (lastchar == '_') || (lastchar == '$')) { + if (isalnum(*c) || (*c == '_') || (*c == '$')) + this->add(' '); + } + } + this->add(*c); + lastchar = *c; + whitespace = 0; + } else { + whitespace = 1; + } + c++; + } + put_pool(s,oldmaxsize); +} diff --git a/wxPython/wxSWIG/SWIG/symbol.cxx b/wxPython/wxSWIG/SWIG/symbol.cxx new file mode 100644 index 0000000000..afc5784d22 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/symbol.cxx @@ -0,0 +1,196 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" + +/******************************************************************************* + * $Header$ + * + * File : symbol.cxx + * + * Symbol table management. + * + *******************************************************************************/ + +// ----------------------------------------------------------------------------- +// Symbol object +// ----------------------------------------------------------------------------- + +struct Symbol { + ~Symbol() { + if (name) delete name; + if (type) delete type; + if (value) delete value; + } + char *name; + DataType *type; // Optional datatype + char *value; // Optional value (for constant expressions) +}; + +static Hash SymHash; // SWIG Symbol table + +// ----------------------------------------------------------------------------- +// int add_symbol(char *name, DataType *type, char *value) +// +// Adds a symbol to the symbol table. Returns -1 if symbol is already in the +// table. +// +// Inputs : +// name = Symbol name +// type = Datatype (for constants). Optional. +// value = Value string. Optional. +// +// Output : 0 on success, -1 if symbol already exists. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +int add_symbol(char *name, DataType *type, char *value) { + + Symbol *s; + int ret; + + s = new Symbol; + s->name = copy_string(name); + if (type) + s->type = new DataType(type); + else s->type = (DataType *) 0; + if (value) + s->value = copy_string(value); + else s->value = (char *) 0; + + // Add this to the symbol table + + ret = SymHash.add(s->name, s); + if (ret == -1) { + delete s; + } + return ret; +} + +// ----------------------------------------------------------------------------- +// int lookup_symbol(char *name) +// +// Checks to see if a symbol is in the symbol table. +// +// Inputs : name = Symbol name +// +// Output : 0 if not found, 1 if found. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +int lookup_symbol(char *name) { + Symbol *s; + + s = (Symbol *) SymHash.lookup(name); + if (s) return 1; + else return 0; +} + +// ----------------------------------------------------------------------------- +// DataType *lookup_symtype(char *name) +// +// Returns the datatype of a symbol or NULL if not found. +// +// Inputs : name = Symbol name +// +// Output : Datatype of symbol, NULL if not found. +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +DataType *lookup_symtype(char *name) { + + Symbol *s; + + s = (Symbol *) SymHash.lookup(name); + if (s) return s->type; + else return (DataType *) 0; +} + +// ----------------------------------------------------------------------------- +// char *lookup_symvalue(char *name) +// +// Returns the value associate with a symbol. +// +// Inputs : name = Symbol name +// +// Output : Symbol value (or NULL if not present). +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +char *lookup_symvalue(char *name) { + + Symbol *s; + + s = (Symbol *) SymHash.lookup(name); + if (s) return s->value; + else return (char *) 0; +} + +// ----------------------------------------------------------------------------- +// int update_symbol(char *name, DataType *type, char *value) +// +// Updates a symbol (or create it) in the hash table. +// +// Inputs : +// name = Name of symbol +// type = Datatype of symbol (optional) +// value = Symbol value (optional) +// +// Output : 0 +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +int update_symbol(char *name, DataType *type, char *value) { + + Symbol *s; + + s = (Symbol *) SymHash.lookup(name); + if (s) { + if (s->type) delete s->type; + if (s->value) delete s->value; + if (type) + s->type = new DataType(type); + else + s->type = (DataType *) 0; + if (value) + s->value = copy_string(value); + else + s->value = (char *) 0; + return 0; + } else { + return add_symbol(name, type, value); + } +} + +// ----------------------------------------------------------------------------- +// void remove_symbol(char *name) +// +// Removes a symbol from the symbol table. +// +// Inputs : name = Symbol name. +// +// Output : None +// +// Side Effects : None +// ----------------------------------------------------------------------------- + +void remove_symbol(char *name) { + SymHash.remove(name); +} diff --git a/wxPython/wxSWIG/SWIG/typemap.cxx b/wxPython/wxSWIG/SWIG/typemap.cxx new file mode 100644 index 0000000000..bd6db74dde --- /dev/null +++ b/wxPython/wxSWIG/SWIG/typemap.cxx @@ -0,0 +1,1093 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +#include "internal.h" + +#include + +// ------------------------------------------------------------------------ +// $Header$ +// +// typemap.cxx +// +// This file provides universal support for typemaps. Typemaps are created +// using the following SWIG command in an interface file: +// +// %typemap(lang,operation) type { code } Make a new typemap +// %typemap(lang,operation) type; Clears any previous typemap +// +// lang is an identifier indicating the target language. The typemap will +// simply be ignored if its for a different language. The code is the +// corresponding C code for the mapping. An example typemap might look +// like this : +// +// %typemap(tcl,get) double { +// $target = atof($source); +// } +// %typemap(tcl,set) double { +// sprintf($target,"%0.17f",$source); +// } +// +// The variables $target and $source should be used in any type-mappings. +// Additional local variables can be created, but this should be done +// by enclosing the entire code fragment in an extra set of braces. +// +// The C++ API to the type-mapper is as follows : +// +// void typemap_register(char *op, char *lang, DataType *type, char *pname, String &getcode, ParmList *args) +// char *typemap_lookup(char *op, char *lang, DataType *type, char *pname, char *source, char *target); +// void typemap_clear(char *op, char *lang, DataType *type, char *pname); +// +// The lookup functions return a character string corresponding to the type-mapping +// code or NULL if none exists. The string return will have the source and target +// strings substituted for the strings "$source" and "$target" in the type-mapping code. +// +// (2/19/97) This module has been extended somewhat to provide generic mappings +// of other parts of the code--most notably exceptions. +// +// void fragment_register(char *op, char *lang, String &code) +// char fragment_lookup(char *op, char *lang, int age); +// char fragment_clear(char *op, char *lang); +// +// ------------------------------------------------------------------------ + +// Structure for holding a typemap + +struct TypeMap { + char *lang; + DataType *type; + String code; + int first; + int last; + TypeMap *next; + TypeMap *previous; // Previously defined typemap (if any) + ParmList *args; // Local variables (if any) + + TypeMap(char *l, DataType *t, String &c, ParmList *p = 0) { + lang = copy_string(l); + type = new DataType(t); + code << c; + first = type_id; + last = INT_MAX; + next = 0; + previous = 0; + if (p) { + args = new ParmList(p); + } else { + args = 0; + } + } + TypeMap(char *l, DataType *t, char *c, ParmList *p = 0) { + lang = copy_string(l); + type = new DataType(t); + code << c; + first = type_id; + last = INT_MAX; + next = 0; + previous = 0; + if (p) { + args = new ParmList(p); + } else { + args = 0; + } + } + TypeMap(char *l, char *c) { + lang = copy_string(l); + type = 0; + code << c; + first = type_id; + last = INT_MAX; + next = 0; + previous = 0; + args = 0; + } + TypeMap(TypeMap *t) { + lang = copy_string(t->lang); + type = new DataType(t->type); + code << t->code; + first = type_id; + last = INT_MAX; + next = 0; + previous = t->previous; + if (args) { + args = new ParmList(args); + } else { + args = 0; + } + } +}; + +// Hash tables for storing type-mappings + +static Hash typemap_hash; + +// Structure for holding "applications of a typemap" + +struct TmMethod { + char *name; // Typemap name; + DataType *type; // Typemap type + TmMethod *next; // Next method + TmMethod(char *n, DataType *t, TmMethod *m = 0) { + if (n) name = copy_string(n); + else name = 0; + if (t) { + type = new DataType(t); + } else { + type = 0; + } + next = m; + } +}; + +// Hash table for storing applications of a datatype + +static Hash application_hash; + +// ------------------------------------------------------------------------ +// void typemap_apply(DataType *tm_type, char *tm_name, DataType *type, char *pname) +// +// Attempts to apply a typemap given by (tm_type,tm_name) to (type,pname) +// Called by the %apply directive. +// ------------------------------------------------------------------------ + +void typemap_apply(DataType *tm_type, char *tm_name, DataType *type, char *pname) { + TmMethod *m,*m1; + char temp[512]; + + // Form the application name + if (!pname) pname = ""; + sprintf(temp,"%s$%s",type->print_type(),pname); + + // See if there is a method already defined + + m = (TmMethod *) application_hash.lookup(temp); + + if (!m) { + m = new TmMethod(temp,type,0); + application_hash.add(temp,m); + } + + // Check to see if an array typemap has been applied to a non-array type + + if ((tm_type->arraystr) && (!type->arraystr)) { + fprintf(stderr,"%s:%d: Warning. Array typemap has been applied to a non-array type.\n", + input_file,line_number); + } + + // If both are arrays, make sure they have the same dimension + + if ((tm_type->arraystr) && (type->arraystr)) { + char s[128],*t; + if (tm_type->array_dimensions() != type->array_dimensions()) { + fprintf(stderr,"%s:%d: Warning. Array types have different number of dimensions.\n", + input_file,line_number); + } else { + for (int i = 0; i < tm_type->array_dimensions(); i++) { + strcpy(s,tm_type->get_dimension(i)); + t = type->get_dimension(i); + if (strcmp(s,"ANY") != 0) { + if (strcmp(s,t)) + fprintf(stderr,"%s:%d: Warning. Array typemap applied to an array of different size.\n", + input_file, line_number); + } + } + } + } + + // Add a new mapping corresponding to the typemap + + m1 = new TmMethod(tm_name,tm_type,m->next); + m->next = m1; + +} +// ------------------------------------------------------------------------ +// void typemap_clear_apply(DataType *type, char *pname) +// +// Clears the application of a typemap. +// Called by the %clear directive. +// ------------------------------------------------------------------------ + +void typemap_clear_apply(DataType *type, char *pname) { + char temp[512]; + if (!pname) pname = ""; + sprintf(temp,"%s$%s", type->print_type(), pname); + application_hash.remove(temp); +} + +// ------------------------------------------------------------------------ +// char *typemap_string(char *lang, DataType *type, char *pname, char *ary, char *suffix) +// +// Produces a character string corresponding to a lang, datatype, and +// method. This string is used as the key for our typemap hash table. +// ------------------------------------------------------------------------ + +static char *typemap_string(char *lang, DataType *type, char *pname, char *ary, char *suffix) { + static String str; + + int old_status; + old_status = type->status; + type->status = 0; + str = ""; + + if (ary) + str << lang << type->print_type() << pname << ary << suffix; + else + str << lang << type->print_type() << pname << suffix; + + type->status = old_status; + return str; +} + +// ------------------------------------------------------------------------ +// void typemap_register(char *op, char *lang, DataType *type, char *pname, +// char *getcode, ParmList *args) +// +// Register a new mapping with the type-mapper. +// ------------------------------------------------------------------------ + +void typemap_register(char *op, char *lang, DataType *type, char *pname, + char *getcode, ParmList *args) { + + char *key; + TypeMap *tm,*tm_old; + char temp[256]; + int is_default = 0; + + // printf("Registering : %s %s %s %s\n%s\n", op, lang, type->print_type(), pname, getcode); + + + tm = new TypeMap(lang,type,getcode,args); + // If this is a default typemap, downgrade the type! + + if (strcmp(pname,"SWIG_DEFAULT_TYPE") == 0) { + tm->type->primitive(); + is_default = 1; + } + + key = typemap_string(lang,tm->type,pname,tm->type->arraystr, op); + + // Get any previous setting of the typemap + + tm_old = (TypeMap *) typemap_hash.lookup(key); + + if (tm_old) { + + // Perform a chaining operation, but only if the last typemap is + // active. + + if (type_id < tm_old->last) { + sprintf(temp,"$%s",op); + tm->code.replace(temp,tm_old->code); + } + + // If found, we need to attach the old version to the new one + + tm->previous = tm_old; + tm->next = tm_old; + tm_old->last = type_id; + + // Remove the old one from the hash + + typemap_hash.remove(key); + } + + // Add new typemap to the hash table + typemap_hash.add(key,(void *) tm); + + // Now try to perform default chaining operation (if available) + // if (!is_default) { + // sprintf(temp,"$%s",op); + // if (strstr(tm->code,temp)) { + // tm->code.replace(temp,typemap_resolve_default(op,lang,type)); + // } + // } + + // Just a sanity check to make sure args look okay. + + if (args) { + Parm *p; + p = tm->args->get_first(); + while (p) { + if (p->name) { + // printf(" %s %s\n", p->t->print_type(),p->name); + } else { + fprintf(stderr,"%s:%d: Typemap error. Local variables must have a name\n", + input_file, line_number); + } + // If a call by reference thingy, fix that + if (p->call_type & CALL_REFERENCE) { + p->t->is_pointer--; + p->call_type = 0; + } + p = tm->args->get_next(); + } + } +} + +// ------------------------------------------------------------------------ +// void typemap_register(char *op, char *lang, char *type, char *pname, +// char *getcode, ParmList *args) +// +// Register a new mapping with the type-mapper. Special version that uses a +// string instead of a datatype. +// ------------------------------------------------------------------------ + +void typemap_register(char *op, char *lang, char *type, char *pname, + char *getcode, ParmList *args) { + DataType temp; + strcpy(temp.name,type); + temp.is_pointer = 0; + temp.type = T_USER; + typemap_register(op,lang,&temp,pname,getcode,args); +} + + +// ------------------------------------------------------------------------ +// void typemap_register_default(char *op, char *lang, int type, int ptr, char *arraystr, +// char *code, ParmList *args) +// +// Registers a default typemap with the system using numerical type codes. +// type is the numerical code, ptr is the level of indirection. +// ------------------------------------------------------------------------ + +void typemap_register_default(char *op, char *lang, int type, int ptr, char *arraystr, + char *code, ParmList *args) { + + DataType *t = new DataType(type); + + // Create a raw datatype from the arguments + + t->is_pointer = ptr; + t->arraystr = copy_string(arraystr); + + // Now, go register this as a default type + + typemap_register(op,lang,t,"SWIG_DEFAULT_TYPE",code,args); + delete t; +} + + +// ------------------------------------------------------------------------ +// static TypeMap *typemap_search(char *key, int id) +// +// An internal function for searching for a particular typemap given +// a key value and datatype id. +// +// Basically this checks the hash table and then checks the id against +// first and last values, looking for a match. This is to properly +// handle scoping problems. +// ------------------------------------------------------------------------ + +TypeMap *typemap_search(char *key, int id) { + + TypeMap *tm; + + tm = (TypeMap *) typemap_hash.lookup(key); + while (tm) { + if ((id >= tm->first) && (id < tm->last)) return tm; + else tm = tm->next; + } + return tm; +} + +// ------------------------------------------------------------------------ +// TypeMap *typemap_search_array(char *op, char *lang, DataType *type, char *pname, String &str) +// +// Performs a typemap lookup on an array type. This is abit complicated +// because we need to look for ANY tags specifying that any array dimension +// is valid. The resulting code will be placed in str with dimension variables +// substituted. +// ------------------------------------------------------------------------ + +TypeMap *typemap_search_array(char *op, char *lang, DataType *type, char *pname, String &str) { + char *origarr = type->arraystr; + char *key; + int ndim,i,j,k,n; + TypeMap *tm; + char temp[10]; + + if (!type->arraystr) return 0; + + // First check to see if exactly this array has been mapped + + key = typemap_string(lang,type,pname,type->arraystr,op); + tm = typemap_search(key,type->id); + + // Check for unnamed array of specific dimensions + if (!tm) { + key = typemap_string(lang,type,"",type->arraystr,op); + tm = typemap_search(key,type->id); + } + + if (!tm) { + // We're going to go search for matches with the ANY tag + String tempastr; + ndim = type->array_dimensions(); // Get number of dimensions + j = (1 << ndim) - 1; // Status bits + for (i = 0; i < (1 << ndim); i++) { + // Form an array string + tempastr = ""; + k = j; + for (n = 0; n < ndim; n++) { + if (k & 1) { + tempastr << "[" << type->get_dimension(n) << "]"; + } else { + tempastr << "[ANY]"; + } + k = k >> 1; + } + // printf("checking (%s) : %s\n",origarr,tempastr.get()); + type->arraystr = tempastr.get(); + key = typemap_string(lang,type,pname,type->arraystr,op); + tm = typemap_search(key,type->id); + if (!tm) { + key = typemap_string(lang,type,"",type->arraystr,op); + tm = typemap_search(key,type->id); + } + type->arraystr = origarr; + if (tm) break; + j--; + } + } + + if (tm) { + str << tm->code; + ndim = type->array_dimensions(); + for (i = 0; i < ndim; i++) { + sprintf(temp,"$dim%d",i); + str.replace(temp,type->get_dimension(i)); + } + } + return tm; +} + +// ------------------------------------------------------------------------ +// static typemap_locals(Datatype *t, char *pname, String &s, ParmList *l, WrapperFunction &f) +// +// Takes a string, a parameter list and a wrapper function argument and +// starts creating local variables. +// +// Substitutes locals in the string with actual values used. +// ------------------------------------------------------------------------ + +static void typemap_locals(DataType *t, char *pname, String &s, ParmList *l, WrapperFunction &f) { + Parm *p; + char *new_name; + + p = l->get_first(); + while (p) { + if (p->name) { + if (strlen(p->name) > 0) { + String str; + DataType *tt; + + // If the user gave us $type as the name of the local variable, we'll use + // the passed datatype instead + + if (strcmp(p->t->name,"$type")==0 || strcmp(p->t->name,"$basetype")==0) { + tt = t; + } else { + tt = p->t; + } + + // Have a real parameter here + if (tt->arraystr) { + tt->is_pointer--; + str << p->name << tt->arraystr; + } + else { + str << p->name; + } + + // Substitute parameter names + str.replace("$arg",pname); + if (strcmp(p->t->name,"$basetype")==0) { + // use $basetype + char temp_ip = tt->is_pointer; + char temp_ip1 = tt->implicit_ptr; + tt->is_pointer = 0; + tt->implicit_ptr = 0; + new_name = f.new_local(tt->print_type(),str); + tt->is_pointer = temp_ip; + tt->implicit_ptr = temp_ip1; + } + else + new_name = f.new_local(tt->print_full(),str); + + if (tt->arraystr) tt->is_pointer++; + // Substitute + s.replaceid(p->name,new_name); + } + } + p = l->get_next(); + } + // If the original datatype was an array. We're going to go through and substitute + // it's array dimensions + + if (t->arraystr) { + char temp[10]; + for (int i = 0; i < t->array_dimensions(); i++) { + sprintf(temp,"$dim%d",i); + f.locals.replace(temp,t->get_dimension(i)); + } + } + +} + +// ------------------------------------------------------------------------ +// char *typemap_lookup(char *op, char *lang, DataType *type, char *pname, char *source, +// char *target, WrapperFunction *f) +// +// Looks up a "get" function in the type-map and returns a character string +// containing the appropriate translation code. +// +// op is string code for type of mapping +// lang is the target language string +// type is the datatype +// pname is an optional parameter name +// source is a string with the source variable +// target is a string containing the target value +// f is a wrapper function object (optional) +// +// Returns NULL if no mapping is found. +// +// Typemaps follow a few rules regarding naming and C pointers by checking +// declarations in this order. +// +// 1. type name [] - A named array (most specific) +// 2. type name - Named argument +// 3. type [] - Type with array +// 4. type - Ordinary type +// +// Array checking is only made if the datatype actally has an array specifier +// +// Array checking uses a special token "ANY" that indicates that any +// dimension will match. Since we are passed a real datatype here, we +// need to hack this a special case. +// +// Array dimensions are substituted into the variables $dim1, $dim2,...,$dim9 +// ------------------------------------------------------------------------ + +static DataType *realtype; // This is a gross hack +static char *realname = 0; // Real parameter name + +char *typemap_lookup_internal(char *op, char *lang, DataType *type, char *pname, char *source, + char *target, WrapperFunction *f) { + static String str; + char *key = 0; + TypeMap *tm = 0; + + if (!lang) { + return 0; + } + + // First check for named array + str = ""; + tm = typemap_search_array(op,lang,type,pname,str); + + // Check for named argument + if (!tm) { + key = typemap_string(lang,type,pname,0,op); + tm = typemap_search(key,type->id); + if (tm) + str << tm->code; + } + + // Check for unnamed type + if (!tm) { + key = typemap_string(lang,type,"",0,op); + tm = typemap_search(key,type->id); + if (tm) + str << tm->code; + } + if (!tm) return 0; + + // Now perform character replacements + + str.replace("$source",source); + str.replace("$target",target); + str.replace("$type", realtype->print_type()); + if (realname) { + str.replace("$parmname", realname); + } else { + str.replace("$parmname",""); + } + // Print base type (without any pointers) + { + char temp_ip = realtype->is_pointer; + char temp_ip1 = realtype->implicit_ptr; + realtype->is_pointer = 0; + realtype->implicit_ptr = 0; + char *bt = realtype->print_type(); + if (bt[strlen(bt)-1] == ' ') + bt[strlen(bt)-1] = 0; + str.replace("$basetype",bt); + str.replace("$basemangle",realtype->print_mangle()); + realtype->is_pointer = temp_ip; + realtype->implicit_ptr = temp_ip1; + } + + str.replace("$mangle",realtype->print_mangle()); + + // If there were locals and a wrapper function, replace + if ((tm->args) && f) { + typemap_locals(realtype, pname, str,tm->args,*f); + } + + // If there were locals and no wrapper function, print a warning + if ((tm->args) && !f) { + if (!pname) pname = ""; + fprintf(stderr,"%s:%d: Warning. '%%typemap(%s,%s) %s %s' being applied with ignored locals.\n", + input_file, line_number, lang,op, type->print_type(), pname); + } + + // Return character string + + return str; +} + +// ---------------------------------------------------------- +// Real function call that takes care of application mappings +// ---------------------------------------------------------- + +char *typemap_lookup(char *op, char *lang, DataType *type, char *pname, char *source, + char *target, WrapperFunction *f) { + TmMethod *m; + char temp[512]; + char *result; + char *ppname; + char *tstr; + + realtype = type; // The other half of the gross hack + realname = pname; + + // Try to apply typemap right away + + result = typemap_lookup_internal(op,lang,type,pname,source,target,f); + + // If not found, try to pick up anything that might have been + // specified with %apply + + if ((!result) && (pname)) { + int drop_pointer = 0; + ppname = pname; + if (!ppname) ppname = ""; + + // The idea : We're going to cycle through applications and + // drop pointers off until we get a match. + + while (drop_pointer <= (type->is_pointer - type->implicit_ptr)) { + type->is_pointer -= drop_pointer; + tstr = type->print_type(); + sprintf(temp,"%s$%s",tstr,ppname); + // No mapping was found. See if the name has been mapped with %apply + m = (TmMethod *) application_hash.lookup(temp); + if (!m) { + sprintf(temp,"%s$",tstr); + m = (TmMethod *) application_hash.lookup(temp); + } + if (m) { + m = m->next; + while (m) { + char *oldary = 0; + static String newarray; + if (*(m->name)) ppname = m->name; + else ppname = pname; + m->type->is_pointer += drop_pointer; + + // Copy old array string (just in case) + + oldary = m->type->arraystr; + + // If the mapping type is an array and has the 'ANY' keyword, we + // have to play some magic + + if ((m->type->arraystr) && (type->arraystr)) { + // Build up the new array string + newarray = ""; + for (int n = 0; n < m->type->array_dimensions(); n++) { + char *d = m->type->get_dimension(n); + if (strcmp(d,"ANY") == 0) { + newarray << "[" << type->get_dimension(n) << "]"; + } else { + newarray << "[" << d << "]"; + } + } + m->type->arraystr = newarray.get(); + } else if (type->arraystr) { + // If an array string is available for the current datatype, + // make it available. + m->type->arraystr = type->arraystr; + } + result = typemap_lookup_internal(op,lang,m->type,ppname,source,target,f); + m->type->arraystr = oldary; + m->type->is_pointer -= drop_pointer; + if (result) { + type->is_pointer += drop_pointer; + return result; + } + m = m->next; + } + } + type->is_pointer += drop_pointer; + drop_pointer++; + } + } + // Still no idea, try to find a default typemap + + if (!result) { + DataType *t = new DataType(type); + t->primitive(); // Knock it down to its basic type + result = typemap_lookup_internal(op,lang,t,"SWIG_DEFAULT_TYPE",source,target,f); + if (result) { + delete t; + return result; + } + if ((t->type == T_USER) || (t->is_pointer)) { + if ((t->type == T_CHAR) && (t->is_pointer == 1)) return 0; + + // Still no result, go even more primitive + t->type = T_USER; + t->is_pointer = 1; + if (t->arraystr) delete [] t->arraystr; + t->arraystr = 0; + t->primitive(); + result = typemap_lookup_internal(op,lang,t,"SWIG_DEFAULT_TYPE",source,target,f); + } + delete t; + } + return result; +} + +// ---------------------------------------------------------------------------- +// char *typemap_check(char *op, char *lang, DataType *type, char *pname) +// +// Checks to see if there is a typemap. Returns typemap string if found, NULL +// if not. +// ---------------------------------------------------------------------------- + +char *typemap_check_internal(char *op, char *lang, DataType *type, char *pname) { + static String str; + char *key = 0; + TypeMap *tm = 0; + + if (!lang) { + return 0; + } + // First check for named array + str = ""; + tm = typemap_search_array(op,lang,type,pname,str); + + // First check for named array + // + // if (type->arraystr) { + // key = typemap_string(lang,type,pname,type->arraystr,op); + // tm = typemap_search(key,type->id); + // } + + // Check for named argument + if (!tm) { + key = typemap_string(lang,type,pname,0,op); + tm = typemap_search(key,type->id); + } + + // Check for unnamed array + if ((!tm) && (type->arraystr)) { + key = typemap_string(lang,type,"",type->arraystr,op); + tm = typemap_search(key,type->id); + } + + // Check for unname type + if (!tm) { + key = typemap_string(lang,type,"",0,op); + tm = typemap_search(key,type->id); + } + if (!tm) return 0; + + str = ""; + str << tm->code; + + // Return character string + + return str; +} + +// Function for checking with applications + +char *typemap_check(char *op, char *lang, DataType *type, char *pname) { + TmMethod *m; + char temp[512]; + char *result; + char *ppname; + char *tstr; + // Try to apply typemap right away + + result = typemap_check_internal(op,lang,type,pname); + + if (!result) { + int drop_pointer = 0; + ppname = pname; + if (!ppname) ppname = ""; + + // The idea : We're going to cycle through applications and + // drop pointers off until we get a match. + + while (drop_pointer <= (type->is_pointer - type->implicit_ptr)) { + type->is_pointer -= drop_pointer; + tstr = type->print_type(); + sprintf(temp,"%s$%s",tstr,ppname); + // No mapping was found. See if the name has been mapped with %apply + m = (TmMethod *) application_hash.lookup(temp); + if (!m) { + sprintf(temp,"%s$",tstr); + m = (TmMethod *) application_hash.lookup(temp); + } + if (m) { + m = m->next; + while (m) { + char *oldary = 0; + static String newarray; + if (*(m->name)) ppname = m->name; + else ppname = pname; + m->type->is_pointer += drop_pointer; + oldary = m->type->arraystr; + + // If the mapping type is an array and has the 'ANY' keyword, we + // have to play some magic + + if ((m->type->arraystr) && (type->arraystr)) { + // Build up the new array string + newarray = ""; + for (int n = 0; n < m->type->array_dimensions(); n++) { + char *d = m->type->get_dimension(n); + if (strcmp(d,"ANY") == 0) { + newarray << "[" << type->get_dimension(n) << "]"; + } else { + newarray << "[" << d << "]"; + } + } + oldary = m->type->arraystr; + m->type->arraystr = newarray.get(); + } else if (type->arraystr) { + m->type->arraystr = type->arraystr; + } + result = typemap_check_internal(op,lang,m->type,ppname); + m->type->arraystr = oldary; + m->type->is_pointer -= drop_pointer; + if (result) { + type->is_pointer += drop_pointer; + return result; + } + m = m->next; + } + } + type->is_pointer += drop_pointer; + drop_pointer++; + } + } + + // If still no result, might have a default typemap + if (!result) { + DataType *t = new DataType(type); + t->primitive(); // Knock it down to its basic type + result = typemap_check_internal(op,lang,t,"SWIG_DEFAULT_TYPE"); + if (result) { + delete t; + return result; + } + if ((t->type == T_USER) || (t->is_pointer)) { + if ((t->type == T_CHAR) && (t->is_pointer == 1)) return 0; + // Still no result, go even more primitive + t->type = T_USER; + t->is_pointer = 1; + if (t->arraystr) delete [] t->arraystr; + t->arraystr = 0; + t->primitive(); + result = typemap_check_internal(op,lang,t,"SWIG_DEFAULT_TYPE"); + } + delete t; + } + return result; +} + +// ------------------------------------------------------------------------ +// void typemap_clear(char *op, char *lang, DataType *type, char *pname) +// +// Clears any previous typemap. This works like a stack. Clearing a +// typemap returns to any previous typemap in force. If there is no +// previous map, then don't worry about it. +// ------------------------------------------------------------------------ + +void typemap_clear(char *op, char *lang, DataType *type, char *pname) { + + char *key; + TypeMap *tm; + + key = typemap_string(lang,type,pname,type->arraystr,op); + + // Look for any previous version, simply set the last id if + // applicable. + + tm = (TypeMap *) typemap_hash.lookup(key); + if (tm) { + if (tm->last > type_id) tm->last = type_id; + } +} + +// ------------------------------------------------------------------------ +// void typemap_copy(char *op, char *lang, DataType *stype, char *sname, +// DataType *ttype, char *tname) +// +// Copies the code associate with a typemap +// ------------------------------------------------------------------------ + +void typemap_copy(char *op, char *lang, DataType *stype, char *sname, + DataType *ttype, char *tname) { + + char *key; + TypeMap *tm, *tk, *tn; + + // Try to locate a previous typemap + + key = typemap_string(lang,stype,sname,stype->arraystr,op); + tm = typemap_search(key,stype->id); + if (!tm) return; + if (strcmp(ttype->name,"PREVIOUS") == 0) { + // Pop back up to the previous typemap (if any) + tk = tm->next; + if (tk) { + tn = new TypeMap(tk); // Make a copy of the previous typemap + tn->next = tm; // Set up symlinks + typemap_hash.remove(key); // Remove old hash entry + typemap_hash.add(key,(void *) tn); + } + } else { + typemap_register(op,lang,ttype,tname,tm->code,tm->args); + } +} + +// ------------------------------------------------------------------------ +// char *fragment_string(char *op, char *lang) +// +// Produces a character string corresponding to a language and method +// This string is used as the key for our typemap hash table. +// ------------------------------------------------------------------------ + +static char *fragment_string(char *op, char *lang) { + static String str; + + str = ""; + + str << "fragment:" << lang << op; + return str; +} + +// ------------------------------------------------------------------------ +// void fragment_register(char *op, char *lang, char *code) +// +// Register a code fragment with the type-mapper. +// ------------------------------------------------------------------------ + +void fragment_register(char *op, char *lang, char *code) { + + char *key; + TypeMap *tm,*tm_old; + char temp[256]; + + tm = new TypeMap(lang,code); + key = fragment_string(op,lang); + + // Get any previous setting of the typemap + + tm_old = (TypeMap *) typemap_hash.lookup(key); + if (tm_old) { + // If found, we need to attach the old version to the new one + + // Perform a chaining operation + + sprintf(temp,"$%s",op); + if (type_id < tm_old->last) + tm->code.replace(temp,tm_old->code); + + tm->next = tm_old; + tm_old->last = type_id; + + // Remove the old one from the hash + + typemap_hash.remove(key); + } + + // Perform a default chaining operation if needed (defaults to nothing) + sprintf(temp,"$%s",op); + tm->code.replace(temp,""); + + // Add new typemap to the hash table + typemap_hash.add(key,(void *) tm); + +} + + +// ------------------------------------------------------------------------ +// char *fragment_lookup(char *op, char *lang, int age) +// +// op is string code for type of mapping +// lang is the target language string +// age is age of fragment. +// +// Returns NULL if no mapping is found. +// +// ------------------------------------------------------------------------ + +char *fragment_lookup(char *op, char *lang, int age) { + static String str; + char *key = 0; + TypeMap *tm = 0; + + if (!lang) { + return 0; + } + + str = ""; + key = fragment_string(op,lang); + tm = typemap_search(key,age); + + if (!tm) return 0; + + str << tm->code; + return str; +} + +// ------------------------------------------------------------------------ +// void fragment_clear(char *op, char *lang) +// +// Clears any previous fragment definition. Is a stack operation--will +// restore any previously declared typemap. +// ------------------------------------------------------------------------ + +void fragment_clear(char *op, char *lang) { + + char *key; + TypeMap *tm; + + key = fragment_string(op,lang); + + // Look for any previous version, simply set the last id if + // applicable. + + tm = (TypeMap *) typemap_hash.lookup(key); + if (tm) { + if (tm->last > type_id) tm->last = type_id; + } +} diff --git a/wxPython/wxSWIG/SWIG/types.cxx b/wxPython/wxSWIG/SWIG/types.cxx new file mode 100644 index 0000000000..e74a6e6d4a --- /dev/null +++ b/wxPython/wxSWIG/SWIG/types.cxx @@ -0,0 +1,1031 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +/*********************************************************************** + * $Header$ + * + * types.cxx + * + * This file contains functions for dealing with datatypes. This + * is a combination of the file typedef.cc (now obsolete) and functions + * that used to be in the swig.h header. + * + ***********************************************************************/ + +#include "internal.h" + +// ------------------------------------------------------------------- +// class DataType member functions. +// ------------------------------------------------------------------- + +DataType::DataType() { + type = 1; + name[0] = 0; + is_pointer = 0; + implicit_ptr = 0; + qualifier = 0; + is_reference = 0; + status = 0; + arraystr = 0; + id = type_id++; +} + +// Create a data type only from the type code (used to form constants) + +DataType::DataType(int t) { + switch(t) { + case T_BOOL: + strcpy(name,"bool"); + break; + case T_INT: case T_SINT: + strcpy(name,"int"); + break; + case T_UINT: + strcpy(name,"unsigned int"); + break; + case T_SHORT: case T_SSHORT: + strcpy(name,"short"); + break; + case T_USHORT: + strcpy(name,"unsigned short"); + break; + case T_LONG: case T_SLONG: + strcpy(name,"long"); + break; + case T_ULONG: + strcpy(name,"unsigned long"); + break; + case T_FLOAT: + strcpy(name, "float"); + break; + case T_DOUBLE: + strcpy(name, "double"); + break; + case T_CHAR: case T_SCHAR: + strcpy(name, "char"); + break; + case T_UCHAR: + strcpy(name,"unsigned char"); + break; + case T_VOID: + strcpy(name,"void"); + break; + case T_USER: + strcpy(name,"USER"); + break; + default : + strcpy(name,"UNKNOWN"); + break; + } + type = t; + is_pointer = 0; + implicit_ptr = 0; + qualifier = 0; + is_reference = 0; + status = 0; + arraystr = 0; + id = type_id++; +} + +DataType::DataType(DataType *t) { + type = t->type; + strcpy(name,t->name); + is_pointer = t->is_pointer; + implicit_ptr = t->implicit_ptr; + qualifier = copy_string(t->qualifier); + is_reference = t->is_reference; + status = t->status; + arraystr = copy_string(t->arraystr); + id = t->id; +} + +DataType::~DataType() { + if (qualifier) delete qualifier; + if (arraystr) delete arraystr; +} + +// -------------------------------------------------------------------- +// DataType::primitive() +// +// Turns a datatype into its bare-bones primitive type. Rarely used, +// but sometimes used for typemaps. Permanently alters the datatype! +// -------------------------------------------------------------------- + +void DataType::primitive() { + switch(type) { + case T_BOOL: + strcpy(name,"bool"); + break; + case T_INT: case T_SINT: + strcpy(name,"int"); + break; + case T_SHORT: case T_SSHORT: + strcpy(name,"short"); + break; + case T_LONG: case T_SLONG: + strcpy(name,"long"); + break; + case T_CHAR: + strcpy(name,"char"); + break; + case T_SCHAR: + strcpy(name,"signed char"); + break; + case T_UINT: + strcpy(name,"unsigned int"); + break; + case T_USHORT: + strcpy(name,"unsigned short"); + break; + case T_ULONG: + strcpy(name,"unsigned long"); + break; + case T_UCHAR: + strcpy(name,"unsigned char"); + break; + case T_FLOAT: + strcpy(name,"float"); + break; + case T_DOUBLE: + strcpy(name,"double"); + break; + case T_VOID: + strcpy(name,"void"); + break; + case T_USER: + strcpy(name,"USER"); + break; + default: + strcpy(name,"UNKNOWN"); + break; + } + // if (is_pointer) { + // if (!((is_pointer == 1) && (type == T_CHAR))) { + // is_pointer = 1; + // strcpy(name,"POINTER"); + // } + // } + + implicit_ptr = 0; // Gets rid of typedef'd pointers + + // Ditch qualifiers (const, volatile, etc...) + + if (qualifier) { + delete qualifier; + qualifier = 0; + } + qualifier = 0; + status = 0; +} + +// -------------------------------------------------------------------- +// char *print_type() +// +// Print the datatype, but without qualifiers (ie. const, volatile) +// Returns a string containing the result. +// +// If a datatype is marked as an implicit ptr it means that is_pointer +// is at least one, but we don't print '*'. +// +// If the type status is STAT_REPLACETYPE, it means that we can't +// use this type as a valid type. We'll substitute it's old name in. +// -------------------------------------------------------------------- + +char *DataType::print_type() { + static String result[8]; + static int ri = 0; + + DataType *t = this; + + if (status & STAT_REPLACETYPE) { + t = new DataType(this); + t->typedef_replace(); // Upgrade type + } + + ri = ri % 8; + result[ri] = ""; + result[ri] << t->name << " "; + for (int i = 0; i < (t->is_pointer-t->implicit_ptr); i++) + result[ri] << '*'; + + if (status & STAT_REPLACETYPE) { + delete t; + }; + + return result[ri++].get(); + +} + +// -------------------------------------------------------------------- +// char *print_full() +// +// Prints full type, with qualifiers. +// -------------------------------------------------------------------- + +char *DataType::print_full() { + static String result[8]; + static int ri = 0; + + ri = ri % 8; + result[ri] = ""; + if (qualifier) + result[ri] << qualifier << " " << print_type(); + else + result[ri] << print_type(); + + return result[ri++].get(); + +} + +// -------------------------------------------------------------------- +// char *print_real() +// +// Prints real type, with qualifiers and arrays if necessary. +// -------------------------------------------------------------------- + +char *DataType::print_real(char *local) { + static String result[8]; + static int ri = 0; + int oldstatus; + + oldstatus = status; + status = status & (~STAT_REPLACETYPE); + ri = ri % 8; + result[ri] = ""; + if (arraystr) is_pointer--; + result[ri] << print_full(); + if (local) result[ri] << local; + if (arraystr) { + result[ri] << arraystr; + is_pointer++; + } + status = oldstatus; + return result[ri++].get(); +} + +// -------------------------------------------------------------------- +// char *print_cast() +// +// Prints a cast. (Basically just a type but with parens added). +// -------------------------------------------------------------------- + +char *DataType::print_cast() { + static String result[8]; + static int ri = 0; + + ri = ri % 8; + result[ri] = ""; + result[ri] << "(" << print_type() << ")"; + return result[ri++].get(); + +} + +// -------------------------------------------------------------------- +// char *print_arraycast() +// +// Prints a cast, but for array datatypes. Super ugly, but necessary +// for multidimensional arrays. +// -------------------------------------------------------------------- + +char *DataType::print_arraycast() { + static String result[8]; + static int ri = 0; + int ndim; + char *c; + DataType *t; + + t = this; + if (status & STAT_REPLACETYPE) { + t = new DataType(this); + t->typedef_replace(); // Upgrade type + } + + ri = ri % 8; + result[ri] = ""; + + if (t->arraystr) { + ndim = 0; + c = t->arraystr; + while (*c) { + if (*c == '[') ndim++; + c++; + } + if (ndim > 1) { + // a Multidimensional array. Provide a special cast for it + int oldstatus = status; + t->status = t->status & (~STAT_REPLACETYPE); + t->is_pointer--; + result[ri] << "(" << t->print_type(); + t->is_pointer++; + t->status = oldstatus; + result[ri] << " (*)"; + c = t->arraystr; + while (*c) { + if (*c == ']') break; + c++; + } + if (*c) c++; + result[ri] << c << ")"; + } + } + if (status & STAT_REPLACETYPE) { + delete t; + } + return result[ri++].get(); +} + +// -------------------------------------------------------------------- +// char *print_mangle_default() +// +// Prints a mangled version of this datatype. Used for run-time type +// checking in order to print out a "language friendly" version (ie. no +// spaces and no weird characters). +// -------------------------------------------------------------------- + +char *DataType::print_mangle_default() { + static String result[8]; + static int ri = 0; + int i; + char *c; + + ri = ri % 8; + result[ri] = ""; + c = name; + + result[ri] << '_'; + for (; *c; c++) { + if (*c == ' ') result[ri] << '_'; + else result[ri] << *c; + } + if ((is_pointer-implicit_ptr)) result[ri] << '_'; + for (i = 0; i < (is_pointer-implicit_ptr); i++) + result[ri] << 'p'; + + return result[ri++].get(); +} + +// This is kind of ugly but needed for each language to support a +// custom name mangling mechanism. (ie. Perl5). + +char *DataType::print_mangle() { + + // Call into target language for name mangling. + return lang->type_mangle(this); +} + +// -------------------------------------------------------------------- +// int DataType::array_dimensions() +// +// Returns the number of dimensions in an array or 0 if not an array. +// -------------------------------------------------------------------- +int DataType::array_dimensions() { + char *c; + int ndim = 0; + + if (!arraystr) return 0; + c = arraystr; + while (*c) { + if (*c == '[') { + ndim++; + } + c++; + } + return ndim; +} + +// -------------------------------------------------------------------- +// char *DataType::get_dimension(int n) +// +// Returns a string containing the value specified for dimension n. +// -------------------------------------------------------------------- + +char *DataType::get_dimension(int n) { + static String dim; + char *c; + + dim = ""; + if (n >= array_dimensions()) return dim; + + // Attemp to locate the right dimension + + c = arraystr; + while ((*c) && (n >= 0)) { + if (*c == '[') n--; + c++; + } + + // c is now at start of array dimension + if (*c) { + while ((*c) && (*c != ']')) { + dim << *c; + c++; + } + } + return dim; +} + +// -------------------------------------------------------------------- +// char *DataType::get_array() +// +// Returns the array string for a datatype. +// -------------------------------------------------------------------- + +char *DataType::get_array() { + return arraystr; +} + +// -------------------------------------------------------------------- +// typedef support. This needs to be scoped. +// -------------------------------------------------------------------- + +Hash *DataType::typedef_hash[MAXSCOPE]; +int DataType::scope = 0; // Current scope + +static Hash undefined_types; // Hash table containing undefined datatypes. + +// ----------------------------------------------------------------------------- +// int DataType::check_defined() +// +// Checks to see if a datatype is defined. If not, returns -1 and puts an entry +// into an internal hash table +// ----------------------------------------------------------------------------- + +int DataType::check_defined() { + if (type == T_USER) { + + // Type might be in typedef hash. Check for that + int s = scope; + while (s >= 0) { + if (typedef_hash[s]->lookup(name)) return 0; + s--; + } + + // Nope. Add as an undefined type and continue. + + char *st; + st = copy_string(name); + undefined_types.add(st,st); + return -1; + } + return 0; +} + +// ----------------------------------------------------------------------------- +// void DataType::init_typedef() +// +// Inputs : None +// +// Output : None +// +// Side Effects : Initializes the typedef hash tables +// ----------------------------------------------------------------------------- + +void DataType::init_typedef() { + int i; + for (i = 0; i < MAXSCOPE; i++) + typedef_hash[i] = 0; + scope = 0; + // Create a new hash + typedef_hash[scope] = new Hash; +} + +// -------------------------------------------------------------------- +// void DataType::typedef_add(char *typename, int mode = 0) +// +// Adds this datatype to the typedef hash table. mode is an optional +// flag that can be used to only add the symbol as a typedef, but not +// generate any support code for the SWIG typechecker. This is used +// for some of the more obscure datatypes like function pointers, +// arrays, and enums. +// -------------------------------------------------------------------- + +void DataType::typedef_add(char *tname, int mode) { + String name1,name2; + DataType *nt, t1; + void typeeq_addtypedef(char *name, char *eqname); + + // Check to see if this typedef already defined + // We only check in the local scope. C++ classes may make typedefs + // that shadow global ones. + + if (typedef_hash[scope]->lookup(tname)) { + fprintf(stderr,"%s : Line %d. Warning. Datatype %s already defined (2nd definition ignored).\n", + input_file, line_number, tname); + return; + } + + // Make a new datatype that we will place in our hash table + + nt = new DataType(this); + nt->implicit_ptr = (is_pointer-implicit_ptr); // Record if mapped type is a pointer + nt->is_pointer = (is_pointer-implicit_ptr); // Adjust pointer value to be correct + nt->typedef_resolve(); // Resolve any other mappings of this type + // strcpy(nt->name,tname); // Copy over the new name + + // Add this type to our hash table + typedef_hash[scope]->add(tname,(void *) nt); + + // Now add this type mapping to our type-equivalence table + + if (mode == 0) { + if ((type != T_VOID) && (strcmp(name,tname) != 0)) { + strcpy(t1.name,tname); + name2 << t1.print_mangle(); + name1 << print_mangle(); + typeeq_addtypedef(name1,name2); + typeeq_addtypedef(name2,name1); + } + } + // Call into the target language with this typedef + lang->add_typedef(this,tname); +} + + +// -------------------------------------------------------------------- +// void DataType::typedef_resolve(int level = 0) +// +// Checks to see if this datatype is in the typedef hash and +// resolves it if necessary. This will check all of the typedef +// hash tables we know about. +// +// level is an optional parameter that determines which scope to use. +// Usually this is only used with a bare :: operator in a datatype. +// +// The const headache : +// +// Normally SWIG will fail if a const variable is used in a typedef +// like this : +// +// typedef const char *String; +// +// This is because future occurrences of "String" will be treated like +// a char *, but without regard to the "constness". To work around +// this problem. The resolve() method checks to see if these original +// data type is const. If so, we'll substitute the name of the original +// datatype instead. Got it? Whew. In a nutshell, this means that +// all future occurrences of "String" will really be "const char *". +// -------------------------------------------------------------------- + +void DataType::typedef_resolve(int level) { + + DataType *td; + int s = scope - level; + + while (s >= 0) { + if ((td = (DataType *) typedef_hash[s]->lookup(name))) { + type = td->type; + is_pointer += td->is_pointer; + implicit_ptr += td->implicit_ptr; + status = status | td->status; + + // Check for constness, and replace type name if necessary + + if (td->qualifier) { + if (strcmp(td->qualifier,"const") == 0) { + strcpy(name,td->name); + qualifier = copy_string(td->qualifier); + implicit_ptr -= td->implicit_ptr; + } + } + return; + } + s--; + } + // Not found, do nothing + return; +} + +// -------------------------------------------------------------------- +// void DataType::typedef_replace() +// +// Checks to see if this datatype is in the typedef hash and +// replaces it with the hash entry. Only applies to current scope. +// -------------------------------------------------------------------- + +void DataType::typedef_replace () { + DataType *td; + String temp; + + if ((td = (DataType *) typedef_hash[scope]->lookup(name))) { + type = td->type; + is_pointer = td->is_pointer; + implicit_ptr -= td->implicit_ptr; + strcpy(name, td->name); + if (td->arraystr) { + if (arraystr) { + temp << arraystr; + delete arraystr; + } + temp << td->arraystr; + arraystr = copy_string(temp); + } + } + // Not found, do nothing + return; +} + +// --------------------------------------------------------------- +// int DataType::is_typedef(char *t) +// +// Checks to see whether t is the name of a datatype we know +// about. Returns 1 if there's a match, 0 otherwise +// --------------------------------------------------------------- + +int DataType::is_typedef(char *t) { + int s = scope; + while (s >= 0) { + if (typedef_hash[s]->lookup(t)) return 1; + s--; + } + return 0; +} + +// --------------------------------------------------------------- +// void DataType::typedef_updatestatus(int newstatus) +// +// Checks to see if this datatype is in the hash table. If +// so, we'll update its status. This is sometimes used with +// typemap handling. Only applies to current scope. +// --------------------------------------------------------------- + +void DataType::typedef_updatestatus(int newstatus) { + + DataType *t; + if ((t = (DataType *) typedef_hash[scope]->lookup(name))) { + t->status = newstatus; + } +} + + +// ----------------------------------------------------------------------------- +// void DataType::merge_scope(Hash *h) +// +// Copies all of the entries in scope h into the current scope. This is +// primarily done with C++ inheritance. +// +// Inputs : Hash table h. +// +// Output : None +// +// Side Effects : Copies all of the entries in h to current scope. +// ----------------------------------------------------------------------------- + +void DataType::merge_scope(Hash *h) { + char *key; + DataType *t, *nt; + + if (h) { + // Copy all of the entries in the given hash table to this new one + key = h->firstkey(); + while (key) { + // printf("%s\n", key); + t = (DataType *) h->lookup(key); + nt = new DataType(t); + typedef_hash[scope]->add(key,(void *) nt); + key = h->nextkey(); + } + } +} + +// ----------------------------------------------------------------------------- +// void DataType::new_scope(Hash *h = 0) +// +// Creates a new scope for handling typedefs. This is used in C++ handling +// to create typedef local to a class definition. +// +// Inputs : h = Optional hash table scope (Used for C++ inheritance). +// +// Output : None +// +// Side Effects : Creates a new hash table and increments the scope counter +// ----------------------------------------------------------------------------- + +void DataType::new_scope(Hash *h) { + scope++; + typedef_hash[scope] = new Hash; + + if (h) { + merge_scope(h); + } +} + +// ----------------------------------------------------------------------------- +// Hash *DataType::collapse_scope(char *prefix) +// +// Collapses the current scope into the previous one, but applies a prefix to +// all of the datatypes. This is done in order to properly handle C++ stuff. +// For example : +// +// class Foo { +// ... +// typedef double Real; +// } +// +// will have a type mapping of "double --> Real" within the class itself. +// When we collapse the scope, this mapping will become "double --> Foo::Real" +// +// Inputs : None +// +// Output : None +// +// Side Effects : Returns the hash table corresponding to the current scope +// ----------------------------------------------------------------------------- + +Hash *DataType::collapse_scope(char *prefix) { + DataType *t,*nt; + char *key; + char *temp; + Hash *h; + + if (scope > 0) { + if (prefix) { + key = typedef_hash[scope]->firstkey(); + while (key) { + t = (DataType *) typedef_hash[scope]->lookup(key); + nt = new DataType(t); + temp = new char[strlen(prefix)+strlen(key)+3]; + sprintf(temp,"%s::%s",prefix,key); + // printf("creating %s\n", temp); + typedef_hash[scope-1]->add(temp,(void *) nt); + delete temp; + key = typedef_hash[scope]->nextkey(); + } + } + h = typedef_hash[scope]; + typedef_hash[scope] = 0; + scope--; + return h; + } + return (Hash *) 0; +} + +// ------------------------------------------------------------- +// Class equivalency lists +// +// These are used to keep track of which datatypes are equivalent. +// This information can be dumped in tabular form upon completion +// for use in the pointer type checker. +// +// cast is an extension needed to properly handle multiple inheritance +// -------------------------------------------------------------- + +struct EqEntry { + char *name; + char *cast; + EqEntry *next; + char *sz; +}; + +static Hash typeeq_hash; +static int te_init = 0; + +void typeeq_init() { + void typeeq_standard(); + te_init = 1; + typeeq_standard(); +} + + +// -------------------------------------------------------------- +// typeeq_add(char *name, char *eqname, char *cast) +// +// Adds a new name to the type-equivalence tables. +// Creates a new entry if it doesn't exit. +// +// Cast is an optional name for a pointer casting function. +// -------------------------------------------------------------- + +void typeeq_add(char *name, char *eqname, char *cast = 0) { + EqEntry *e1,*e2; + + if (!te_init) typeeq_init(); + + if (strcmp(name,eqname) == 0) return; // If they're the same, forget it. + + // Search for "name" entry in the hash table + + e1 = (EqEntry *) typeeq_hash.lookup(name); + + if (!e1) { + // Create a new entry + e1 = new EqEntry; + e1->name = copy_string(name); + e1->next = 0; + e1->cast = 0; + // Add it to the hash table + typeeq_hash.add(name,(void *) e1); + } + + + + // Add new type to the list + // We'll first check to see if it's already been added + + e2 = e1->next; + while (e2) { + if (strcmp(e2->name, eqname) == 0) { + if (cast) + e2->cast = copy_string(cast); + return; + } + e2 = e2->next; + } + + e2 = new EqEntry; + e2->name = copy_string(eqname); + e2->cast = copy_string(cast); + e2->next = e1->next; // Add onto the linked list for name + e1->next = e2; + +} + +// -------------------------------------------------------------- +// typeeq_addtypedef(char *name, char *eqname) +// +// Adds a new typedef declaration to the equivelency list. +// -------------------------------------------------------------- + +void typeeq_addtypedef(char *name, char *eqname) { + EqEntry *e1,*e2; + + if (!te_init) typeeq_init(); + + // First we're going to add the equivalence, no matter what + + typeeq_add(name,eqname); + + // Now find the hash entry + + e1 = (EqEntry *) typeeq_hash.lookup(name); + if (!e1) return; + + // Walk down the list and make other equivalences + + e2 = e1->next; + while (e2) { + if (strcmp(e2->name, eqname) != 0) { + typeeq_add(e2->name, eqname,e2->cast); + typeeq_add(eqname, e2->name,e2->cast); + } + e2 = e2->next; + } +} + +// ---------------------------------------------------------------- +// void emit_ptr_equivalence(FILE *f) +// +// Dump out the pointer equivalence table to file. +// +// Changed to register datatypes with the type checker in order +// to support proper type-casting (needed for multiple inheritance) +// ---------------------------------------------------------------- + +void emit_ptr_equivalence(FILE *f) { + + EqEntry *e1,*e2; + void typeeq_standard(); + String ttable; + + if (!te_init) typeeq_init(); + + ttable << "\ +/*\n\ + * This table is used by the pointer type-checker\n\ + */\n\ +static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {\n"; + + e1 = (EqEntry *) typeeq_hash.first(); + while (e1) { + e2 = e1->next; + // Walk through the equivalency list + while (e2) { + if (e2->cast) + ttable << tab4 << "{ \"" << e1->name << "\",\"" << e2->name << "\"," << e2->cast << "},\n"; + else + ttable << tab4 << "{ \"" << e1->name << "\",\"" << e2->name << "\",0},\n"; + e2 = e2->next; + } + e1 = (EqEntry *) typeeq_hash.next(); + } + ttable << "{0,0,0}};\n"; + fprintf(f_wrappers,"%s\n", ttable.get()); + fprintf(f,"{\n"); + fprintf(f," int i;\n"); + fprintf(f," for (i = 0; _swig_mapping[i].n1; i++)\n"); + fprintf(f," SWIG_RegisterMapping(_swig_mapping[i].n1,_swig_mapping[i].n2,_swig_mapping[i].pcnv);\n"); + fprintf(f,"}\n"); +} + +// ------------------------------------------------------------------------------ +// typeeq_derived(char *n1, char *n2, char *cast=) +// +// Adds a one-way mapping between datatypes. +// ------------------------------------------------------------------------------ + +void typeeq_derived(char *n1, char *n2, char *cast=0) { + DataType t,t1; + String name,name2; + EqEntry *e1; + + if (!te_init) typeeq_init(); + + strcpy(t.name,n1); + strcpy(t1.name,n2); + name << t.print_mangle(); + name2 << t1.print_mangle(); + typeeq_add(name,name2,cast); + + // Now find the hash entry + + e1 = (EqEntry *) typeeq_hash.lookup(name); + + // Walk down the list and make other equivalences + + /* I don't think this is necessary, but we'll keep this code in case + + e2 = e1->next; + while (e2) { + if (strcmp(e2->name, name2) != 0) { + typeeq_add(e2->name, name2,e2->cast); + } + e2 = e2->next; + } + */ + +} + +// ------------------------------------------------------------------------------ +// typeeq_mangle(char *n1, char *n2, char *cast=) +// +// Adds a single type equivalence +// ------------------------------------------------------------------------------ + +void typeeq_mangle(char *n1, char *n2, char *cast=0) { + DataType t,t1; + String name,name2; + + if (!te_init) typeeq_init(); + + strcpy(t.name,n1); + strcpy(t1.name,n2); + name << t.print_mangle(); + name2 << t1.print_mangle(); + typeeq_add(name,name2,cast); +} + +// ------------------------------------------------------------------------------ +// typeeq_standard(void) +// +// Generate standard type equivalences (well, pointers that can map into +// other pointers naturally). +// +// ------------------------------------------------------------------------------- + +void typeeq_standard(void) { + + typeeq_mangle("int", "signed int"); + typeeq_mangle("int", "unsigned int"); + typeeq_mangle("signed int", "int"); + typeeq_mangle("unsigned int", "int"); + typeeq_mangle("short","signed short"); + typeeq_mangle("signed short","short"); + typeeq_mangle("short","unsigned short"); + typeeq_mangle("unsigned short","short"); + typeeq_mangle("long","signed long"); + typeeq_mangle("signed long","long"); + typeeq_mangle("long","unsigned long"); + typeeq_mangle("unsigned long","long"); + +} + +// ------------------------------------------------------------------------------ +// type_undefined_check(void) +// +// Checks the hash table for undefined datatypes and prints a warning message. +// ------------------------------------------------------------------------------- + +void type_undefined_check(void) { + char *s; + + s = (char *) undefined_types.first(); + if (s) { + fprintf(stderr,"The following datatypes were used, but undefined.\n"); + while (s) { + fprintf(stderr," %s\n",s); + s = (char *) undefined_types.next(); + } + } +} + diff --git a/wxPython/wxSWIG/SWIG/wrapfunc.cxx b/wxPython/wxSWIG/SWIG/wrapfunc.cxx new file mode 100644 index 0000000000..5abb01e618 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/wrapfunc.cxx @@ -0,0 +1,164 @@ +/******************************************************************************* + * Simplified Wrapper and Interface Generator (SWIG) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + *******************************************************************************/ + +// ------------------------------------------------------------------ +// wrapfunc.cxx +// +// Created : June 22, 1996 +// Dave Beazley +// +// This file defines a class for writing wrappers. Instead of worrying +// about I/O problems, this wrapper class can be used to write functions +// out of order. +// +// Defines 3 string objects. +// def - Wrapper function definition (function name and arguments) +// locals - Local variable definitions +// code - The actual wrapper function code +// +//------------------------------------------------------------------- + +#include "internal.h" +#include + +// ------------------------------------------------------------------- +// Print out a wrapper function. +// +// ------------------------------------------------------------------- + +void WrapperFunction::print(FILE *f) { + fprintf(f,"%s\n",def.get()); + fprintf(f,"%s\n",locals.get()); + fprintf(f,"%s\n",code.get()); +} + +// ------------------------------------------------------------------- +// Print out a wrapper function. +// +// ------------------------------------------------------------------- + +void WrapperFunction::print(String &f) { + f << def << "\n" + << locals << "\n" + << code << "\n"; +} + +// ------------------------------------------------------------------- +// Safely add a local variable. +// +// Maintains a hash table to prevent double adding. +// ------------------------------------------------------------------- + +void WrapperFunction::add_local(char *type, char *name, char *defarg) { + char *stored_type; + char *new_type; + char temp[256],*c,*t; + + new_type = new char[strlen(type)+1]; + strcpy(new_type,type); + + // Figure out what the name of this variable is + + c = name; + t = temp; + while ((isalnum(*c) || (*c == '_') || (*c == '$')) && (*c)) { + *(t++) = *c; + c++; + } + *t = 0; + if (h.add(temp,new_type,WrapperFunction::del_type) == -1) { + // Check to see if a type mismatch has occurred + stored_type = (char *) h.lookup(temp); + if (strcmp(type,stored_type) != 0) + fprintf(stderr,"Error. Type %s conflicts with previously declared type of %s\n", + type, stored_type); + return; + } + + // Successful, write some wrapper code + + if (!defarg) + locals << tab4 << type << " " << name << ";\n"; + else + locals << tab4 << type << " " << name << " = " << defarg << ";\n"; +} + + +// ------------------------------------------------------------------- +// char *WrapperFunction::new_local(char *type, char *name, char *defarg) { +// +// A safe way to add a new local variable. type and name are used as +// a starting point, but a new local variable will be created if these +// are already in use. +// ------------------------------------------------------------------- + +char *WrapperFunction::new_local(char *type, char *name, char *defarg) { + char *new_type; + static String new_name; + char *c; + new_type = new char[strlen(type)+1]; + + strcpy(new_type,type); + new_name = ""; + c = name; + for (c = name; ((isalnum(*c) || (*c == '_') || (*c == '$')) && (*c)); c++) + new_name << *c; + + // Try to add a new local variable + if (h.add(new_name,new_type,WrapperFunction::del_type) == -1) { + // Local variable already exists, try to generate a new name + int i = 0; + new_name = ""; + // This is a little funky. We copy characters until we reach a nonvalid + // identifier symbol, add a number, then append the rest. This is + // needed to properly handle arrays. + c = name; + for (c = name; ((isalnum(*c) || (*c == '_') || (*c == '$')) && (*c)); c++) + new_name << *c; + new_name << i; + while (h.add(new_name,new_type,WrapperFunction::del_type) == -1) { + i++; + c = name; + new_name = ""; + for (c = name; ((isalnum(*c) || (*c == '_') || (*c == '$')) && (*c)); c++) + new_name << *c; + new_name << i; + } + } + new_name << c; + // Successful, write some wrapper code + if (!defarg) + locals << tab4 << type << " " << new_name << ";\n"; + else + locals << tab4 << type << " " << new_name << " = " << defarg << ";\n"; + + // Need to strip off the array symbols now + + c = new_name.get(); + while ((isalnum(*c) || (*c == '_') || (*c == '$')) && (*c)) + c++; + *c = 0; + return new_name; +} + +// ------------------------------------------------------------------ +// static WrapperFunction::del_type(void *obj) +// +// Callback function used when cleaning up the hash table. +// ------------------------------------------------------------------ + +void WrapperFunction::del_type(void *obj) { + delete (char *) obj; +} diff --git a/wxPython/wxSWIG/configure.in b/wxPython/wxSWIG/configure.in new file mode 100644 index 0000000000..1d9315b7e9 --- /dev/null +++ b/wxPython/wxSWIG/configure.in @@ -0,0 +1,445 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(Include/swig.h) +AC_PREREQ(2.0) + +# Set name for machine-dependent library files +AC_SUBST(MACHDEP) +AC_MSG_CHECKING(MACHDEP) +if test -z "$MACHDEP" +then + if test -f /usr/lib/NextStep/software_version; then + set X `hostinfo | grep 'NeXT Mach.*:' | \ + sed -e 's/://' -e 's/\./_/'` && \ + ac_sys_system=next && ac_sys_release=$4 + MACHDEP="$ac_sys_system$ac_sys_release$ac_sys_cpu" + else + ac_sys_system=`uname -s` + if test "$ac_sys_system" = "AIX" ; then + ac_sys_release=`uname -v` + else + ac_sys_release=`uname -r` + fi + ac_md_system=`echo $ac_sys_system | + tr -d '[/ ]' | tr '[[A-Z]]' '[[a-z]]'` + ac_md_release=`echo $ac_sys_release | + tr -d '[/ ]' | sed 's/\..*//'` + MACHDEP="$ac_md_system$ac_md_release" + fi + case MACHDEP in + '') MACHDEP=unknown;; + esac +fi +AC_MSG_RESULT($MACHDEP) + +AC_LANG_CPLUSPLUS + +dnl Checks for programs. +AC_PROG_CXX +AC_PROG_CC +AC_PROG_RANLIB + +AC_SUBST(AR) +AC_CHECK_PROGS(AR, ar aal, ar) + +dnl Checks for header files. +AC_HEADER_STDC +dnl Checks for library functions. + +AC_FUNC_ALLOCA +AC_ARG_WITH(lang,[ --with-lang=LANG Set SWIG target language (TCL,TCL8,PYTHON,PERL5,PERL4,GUILE)],[ + AC_DEFINE_UNQUOTED(SWIG_LANG,$withval)], [AC_DEFINE(SWIG_LANG,TCL)]) + +AC_ARG_WITH(doc,[ --with-doc=DOC Set SWIG target documentation method (ASCII,LATEX,HTML,NODOC)], [ + AC_DEFINE_UNQUOTED(SWIG_DOC,$withval)], [AC_DEFINE(SWIG_DOC,ASCII)]) + +AC_ARG_WITH(yacc,[ --without-yacc Try to compile without yacc/bison], [ + YACC="cp parser.cxx.no y.tab.c; cp parser.h.no y.tab.h" + AC_SUBST(YACC) + YACCFLAGS="" + AC_SUBST(YACCFLAGS) +], [ AC_PROG_YACC + YACCFLAGS="-d parser.y" + AC_SUBST(YACCFLAGS) ]) + +# This borrowed from the Python configuration file +# Set info about shared libraries. + +AC_SUBST(SO) +AC_SUBST(LDSHARED) +AC_SUBST(CCSHARED) +AC_SUBST(LINKFORSHARED) +# SO is the extension of shared libraries `(including the dot!) +# -- usually .so, .sl on HP-UX +AC_MSG_CHECKING(SO) +if test -z "$SO" +then + case $ac_sys_system in + hp*|HP*) SO=.sl;; + NeXT|next) SO=.a;; # no shared libs on NeXT 3.3 and less + *) SO=.so;; + esac +fi +AC_MSG_RESULT($SO) +# LDSHARED is the ld *command* used to create shared library +# -- "ld" on SunOS 4.x.x, "ld -G" on SunOS 5.x, "ld -shared" on IRIX 5 +AC_MSG_CHECKING(LDSHARED) +if test -z "$LDSHARED" +then + case $ac_sys_system/$ac_sys_release in + AIX*) LDSHARED="ld_so_aix";; + IRIX*) LDSHARED="ld -shared";; + SunOS/4*) LDSHARED="ld";; + SunOS/5*) LDSHARED="ld -G";; + hp*|HP*) LDSHARED="ld -b";; + OSF*) LDSHARED="ld -shared -expect_unresolved \"*\"";; + DYNIX/ptx*) LDSHARED="ld -G";; + Linux*) LDSHARED="gcc -shared";; + FreeBSD*) LDSHARED="ld -Bshareable";; + NeXT|next/3*) LDSHARED="ld -u libsys_s";; + *) LDSHARED="ld";; + esac +fi +AC_MSG_RESULT($LDSHARED) +# CCSHARED are the C *flags* used to create objects to go into a shared +# library -- this is only needed for a few systems +AC_MSG_CHECKING(CCSHARED) +if test -z "$CCSHARED" +then + case $ac_sys_system in + hp*|HP*) if test "$GCC" = yes; + then CCSHARED="-fpic"; + else CCSHARED="+z"; + fi;; + Linux*) CCSHARED="-fpic";; + FreeBSD*) CCSHARED="-fpic";; + esac +fi +AC_MSG_RESULT($CCSHARED) + +# LINKFORSHARED are the flags passed to the $(CC) command that links +# the a few executables -- this is only needed for a few systems + +AC_MSG_CHECKING(LINKFORSHARED) +if test -z "$LINKFORSHARED" +then + case $ac_sys_system/$ac_sys_release in + AIX*) LINKFORSHARED='-Wl,-bE:$(srcdir)/python.exp -lld';; + hp*|HP*) + LINKFORSHARED="-Wl,-E -Wl,+s -Wl,+b\$(BINLIBDEST)/lib-dynload";; + Linux*) LINKFORSHARED="-Xlinker -export-dynamic";; + next/*) LINKFORSHARED="-u libsys_s";; + SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";; + IRIX*/6*) LINKFORSHARED="-all";; + esac +fi +AC_MSG_RESULT($LINKFORSHARED) + +echo "" +echo "Checking for installed packages." +echo "Note : None of the following packages are required to compile SWIG" +echo "" + +# Check for specific libraries. Used for SWIG examples +AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV +AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX + +# The following three (nsl,inet,socket) are needed on Sequent; +# the order of checking must be this. Most SVR4 platforms will +# need -lsocket and -lnsl. However on SGI IRIX 5, these exist but +# broken. I see no elegant solution (probably CHECK_LIB should be +# fixed to only add the library if the given entry point is not +# satisfied without it). +if test "`uname -s`" != IRIX +then +AC_CHECK_LIB(nsl, t_open, [LIBS="-lnsl $LIBS"]) # SVR4 +AC_CHECK_LIB(inet, gethostbyname, [LIBS="-linet $LIBS"], [], -lnsl) # Sequent +AC_CHECK_LIB(socket, socket, [LIBS="-lsocket $LIBS"], [], $LIBS) # SVR4 sockets +fi + +# check for --with-libm=... +AC_SUBST(LIBM) +LIBM=-lm +AC_ARG_WITH(libm, [ --with-libm=STRING math library], [ +if test "$withval" != yes +then LIBM=$withval +else AC_ERROR(proper usage is --with-libm=STRING) +fi]) +AC_CHECK_LIB(ieee, main, [LIBM="-lieee $LIBM"]) +AC_CHECK_LIB(crypt,crypt, [LIBCRYPT="-lcrypt"]) +AC_SUBST(LIBCRYPT) + +# check for --with-libc=... +AC_SUBST(LIBC) +AC_ARG_WITH(libc, [ --with-libc=STRING C library], [ +if test "$withval" != yes +then LIBC=$withval +else AC_ERROR(proper usage is --with-libc=STRING) +fi]) + +#-------------------------------------------------------------------- +# Locate the X11 header files and the X11 library archive. Try +# the ac_path_x macro first, but if it doesn't find the X stuff +# (e.g. because there's no xmkmf program) then check through +# a list of possible directories. Under some conditions the +# autoconf macro will return an include directory that contains +# no include files, so double-check its result just to be safe. +#-------------------------------------------------------------------- + +AC_PATH_X +not_really_there="" +if test "$no_x" = ""; then + if test "$x_includes" = ""; then + AC_TRY_CPP([#include ], , not_really_there="yes") + else + if test ! -r $x_includes/X11/Intrinsic.h; then + not_really_there="yes" + fi + fi +fi +if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then + AC_MSG_CHECKING(for X11 header files) + XINCLUDES="# no special path needed" + AC_TRY_CPP([#include ], , XINCLUDES="nope") + if test "$XINCLUDES" = nope; then + dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/include/X11R4 /usr/X11R5/include /usr/include/X11R5 /usr/openwin/include /usr/X11/include /usr/sww/include /usr/X11R6/include /usr/include/X11R6" + for i in $dirs ; do + if test -r $i/X11/Intrinsic.h; then + AC_MSG_RESULT($i) + XINCLUDES=" -I$i" + break + fi + done + fi +else + if test "$x_includes" != ""; then + XINCLUDES=-I$x_includes + else + XINCLUDES="# no special path needed" + fi +fi +if test "$XINCLUDES" = nope; then + AC_MSG_RESULT(couldn't find any!) + XINCLUDES="# no include files found" +fi + +if test "$no_x" = yes; then + AC_MSG_CHECKING(for X11 libraries) + XLIBSW=nope + dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/lib/X11R4 /usr/X11R5/lib /usr/lib/X11R5 /usr/X11R6/lib /usr/lib/X11R6 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" + for i in $dirs ; do + if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then + AC_MSG_RESULT($i) + XLIBSW="-L$i -lX11" + break + fi + done +else + if test "$x_libraries" = ""; then + XLIBSW=-lX11 + else + XLIBSW="-L$x_libraries -lX11" + fi +fi +if test "$XLIBSW" = nope ; then + AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow) +fi +if test "$XLIBSW" = nope ; then + AC_MSG_RESULT(couldn't find any! Using -lX11.) + XLIBSW=-lX11 +fi + +AC_SUBST(XINCLUDES) +AC_SUBST(XLIBSW) + +#-------------------------------------------------------------------- +# Try to locate the Tcl package +#-------------------------------------------------------------------- + +TCLINCLUDE=nope +TCLLIB=nope +TCLPACKAGE=nope + +AC_ARG_WITH(tcl,[ --with-tcl=path Set location of Tcl package],[ + TCLPACKAGE="$withval"], [TCLPACKAGE=nope]) +AC_ARG_WITH(tclincl,[ --with-tclincl=path Set location of Tcl include directory],[ + TCLINCLUDE="-I$withval"], [TCLINCLUDE=nope]) +AC_ARG_WITH(tcllib,[ --with-tcllib=path Set location of Tcl library directory],[ + TCLLIB="-L$withval"], [TCLLIB=nope]) + +if test "$TCLINCLUDE" = nope; then + if test "$TCLPACKAGE" != nope; then + TCLINCLUDE="-I$TCLPACKAGE/include" + fi +fi + +if test "$TCLLIB" = nope; then + if test "$TCLPACKAGE" != nope; then + TCLLIB="-L$TCLPACKAGE/lib" + fi +fi + +AC_MSG_CHECKING(for Tcl header files) +if test "$TCLINCLUDE" = nope; then +AC_TRY_CPP([#include ], , TCLINCLUDE="nope") +if test "$TCLINCLUDE" = nope; then + dirs="$prefix/include /usr/local/include /usr/include /opt/local/include /home/sci/local/include" + for i in $dirs ; do + if test -r $i/tcl.h; then + AC_MSG_RESULT($i) + TCLINCLUDE="-I$i" + break + fi + done +fi +if test "$TCLINCLUDE" = nope; then + TCLINCLUDE="-I/usr/local/include" + AC_MSG_RESULT(not found) +fi +else + AC_MSG_RESULT($TCLINCLUDE) +fi + +AC_MSG_CHECKING(for Tcl library) +if test "$TCLLIB" = nope; then +dirs="$prefix/lib /usr/local/lib /usr/lib /opt/local/lib /home/sci/local/lib" +for i in $dirs ; do + if test -r $i/libtcl.a; then + AC_MSG_RESULT($i) + TCLLIB="-L$i" + break + fi +done +if test "$TCLLIB" = nope; then + AC_MSG_RESULT(not found) + TCLLIB="-L/usr/local/lib" +fi +else +AC_MSG_RESULT($TCLLIB) +fi + +AC_SUBST(TCLINCLUDE) +AC_SUBST(TCLLIB) + +#---------------------------------------------------------------- +# Look for Python +#---------------------------------------------------------------- + +PYINCLUDE=nope +PYLIB=nope +PYPACKAGE=nope +PYLINK="-lModules -lPython -lObjects -lParser" + +AC_ARG_WITH(py,[ --with-py=path Set location of Python],[ + PYPACKAGE="$withval"], [PYPACKAGE=nope]) +AC_ARG_WITH(pyincl,[ --with-pyincl=path Set location of Python include directory],[ + PYINCLUDE="$withval"], [PYINCLUDE=nope]) +AC_ARG_WITH(pylib,[ --with-pylib=path Set location of Python library directory],[ + PYLIB="$withval"], [PYLIB=nope]) + +if test "$PYINCLUDE" = nope; then + if test "$PYPACKAGE" != nope; then + PYINCLUDE="$PYPACKAGE/include" + fi +fi + +if test "$PYLIB" = nope; then + if test "$PYPACKAGE" != nope; then + PYLIB="$PYPACKAGE/lib" + fi +fi + + +AC_MSG_CHECKING(for Python header files) + +dirs="$PYINCLUDE $PYINCLUDE/python1.5 $PYINCLUDE/python1.4 $PYINCLUDE/Py $prefix/include/python1.5 $prefix/include/python1.4 /usr/local/include/python1.5 /usr/include/python1.5 /usr/local/include/python1.4 /usr/include/python1.4 $prefix/include/Py /usr/local/include/Py /usr/include/Py" +for i in $dirs ; do + if test -r $i/Python.h; then + AC_MSG_RESULT($i) + PYINCLUDE="-I$i" + break + fi +done +if test "$PYINCLUDE" = nope; then + PYINCLUDE="-I/usr/local/include/Py" + AC_MSG_RESULT(not found) +fi + +AC_MSG_CHECKING(for Python library) +dirs="$PYLIB $PYLIB/config $PYLIB/lib $PYLIB/python1.5/config $PYLIB/python1.4/config $PYLIB/python/lib $prefix/lib/python1.5/config $prefix/lib/python1.4/config /usr/local/lib/python1.5/config /usr/lib/python1.5 /usr/local/lib/python1.4/config /usr/lib/python1.4 $prefix/lib/python/lib /usr/local/lib/python/lib /usr/lib/python/lib /home/sci/local/lib/python" + +for i in $dirs ; do + if test -r $i/libpython1.5.a; then + AC_MSG_RESULT($i) + PYLIB="$i" + PYINCLUDE="$PYINCLUDE -I$i" + PYLINK="-lpython1.5" + break + fi + if test -r $i/libPython.a; then + AC_MSG_RESULT($i) + PYLIB="$i" + PYINCLUDE="$PYINCLUDE -I$i" + break + fi +done +if test "$PYLIB" = nope; then + AC_MSG_RESULT(not found) + PYLIB="/usr/local/lib/python/lib" + PYINCLUDE="$PYINCLUDE -I$PYLIB" +fi + +AC_SUBST(PYINCLUDE) +AC_SUBST(PYLIB) +AC_SUBST(PYLINK) + +#---------------------------------------------------------------- +# Look for Perl5 +#---------------------------------------------------------------- + +PERLBIN=nope + +AC_ARG_WITH(perl5,[ --with-perl5=path Set location of Perl5 executable],[ + PERLBIN="$withval"], [PERLBIN=nope]) + +# First figure out what the name of Perl5 is + +if test "$PERLBIN" = nope; then +AC_CHECK_PROGS(PERL, perl5.004 perl5.003 perl5.002 perl5.001 perl5 perl,nope) +else +PERL="$PERLBIN" +fi +AC_MSG_CHECKING(for Perl5 header files) +if test "$PERL" != nope; then + PERL5DIR=`($PERL -e 'use Config; print $Config{archlib};') 2>/dev/null` + if test "$PERL5DIR" != ""; then + dirs="$PERL5DIR $PERL5DIR/CORE" + PERL5EXT=none + for i in $dirs; do + if test -r $i/perl.h; then + AC_MSG_RESULT($i) + PERL5EXT="$i" + break; + fi + done + if test "$PERL5EXT" = none; then + PERL5EXT="$PERL5DIR/CORE" + AC_MSG_RESULT(could not locate perl.h...using $PERL5EXT) + fi + else + AC_MSG_RESULT(unable to determine perl5 configuration) + PERL5EXT=$PERL5DIR + fi + else + AC_MSG_RESULT(could not figure out how to run perl5) + PERL5EXT="/usr/local/lib/perl/archname/5.003/CORE" + fi + +AC_SUBST(PERL5EXT) + +AC_OUTPUT(Makefile SWIG/Makefile Modules/Makefile Runtime/Makefile swig_lib/tcl/Makefile swig_lib/python/Makefile swig_lib/perl5/Makefile Makefile.template) + + + + + + diff --git a/wxPython/wxSWIG/make_win.in b/wxPython/wxSWIG/make_win.in new file mode 100644 index 0000000000..195cfc8f2d --- /dev/null +++ b/wxPython/wxSWIG/make_win.in @@ -0,0 +1,70 @@ +####################################################################### +# $Header$ +# Simplified Wrapper and Interface Generator (SWIG) +# +# Windows NT/95 Makefile for version 1.1 +# Kevin Butler & Dave Beazley +# March 12, 1997 +# +# This file contains default values and various parameters for +# building SWIG with MS Visual C++. +# +####################################################################### + + +# --------------------------------------------------------------------- +# Set your compiler location here +# MS Visual C++ defaults to the listed locations +# (Set compiler, linker/lib manager, and location of standard includes +# --------------------------------------------------------------------- + +CC = cl.exe +LD = lib.exe +##CCHOME = c:\Tools\VisStudio\vc98 +##STD_INC = "$(CCHOME)/include" + + +# +# Set the prefix below to indicate where you want SWIG to install its +# files. Normally this is c:\swig +# +# 'prefix' is used as a symbol for SWIG itself. +# 'dprefix' is the DOS prefix with the backwards slash. + +##prefix = c:/tools/swig1.1-883 +##dprefix = c:\tools\swig1.1-883 + +# Location and filename of the SWIG executable. Feel free to put this +# wherever you'd like in your PATH, or leave it in c:\swig\swig.exe + +##dSWIG_EXE = $(dprefix)\swig.exe + + +# Location of the SWIG library. Is normally placed in c:\swig\swig_lib +# on NT/Win95. The SWIG library contains configuration files and library modules +# so you should install it someplace where it can be easily accessed. + +##SWIG_LIB = $(prefix)/swig_lib +##dSWIG_LIB = $(dprefix)\swig_lib + +# +# SWIG_OPTS controls swig defaults. +# You may want to change SWIG_LANG or SWIG_DOC. +# +# SWIG_LANG may be one of : TCL,TCL8,PERL5,PERL4,PYTHON, or GUILE +# SWIG_DOC may be one of : ASCII, LATEX, HTML, NONE +# + +SWIG_OPTS = -DSWIG_LANG=PYTHON -DSWIG_DOC=ASCII + +MAKE = nmake /f makefile.vc + + +## -DSWIG_LIB="\"$(SWIG_LIB)\"" + +DEBUG = -Zi +CFLAGS = $(DEBUG) -nologo -DSWIG_CC="\"$(CC)\"" -DMSDOS -DSTDC_HEADERS=1 -DHAVE_LIBDL=1 $(SWIG_OPTS) +INCFLAGS= -I$(rootdir)/Include -I$(rootdir)/SWIG -I$(rootdir)/Modules +LD_FLAGS= -VERBOSE + + diff --git a/wxPython/wxSWIG/makefile.vc b/wxPython/wxSWIG/makefile.vc new file mode 100644 index 0000000000..1dfcb9fd26 --- /dev/null +++ b/wxPython/wxSWIG/makefile.vc @@ -0,0 +1,155 @@ +####################################################################### +# $Header$ +# Simplified Wrapper and Interface Generator (SWIG) +# +# Makefile for version 1.1 +# Dave Beazley +# March 12, 1997 +# +# Modified for Visual C++ +# Kevin Butler +# 1/10/97 +# +# $Log$ +# Revision 1.1 2002/04/29 19:56:47 RD +# Since I have made several changes to SWIG over the years to accomodate +# special cases and other things in wxPython, and since I plan on making +# several more, I've decided to put the SWIG sources in wxPython's CVS +# instead of relying on maintaining patches. This effectivly becomes a +# fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still +# doesn't have some things I rely on in 1.1, not to mention that my +# custom patches would all have to be redone, I felt that this is the +# easier road to take. +# +# Revision 1.3 1999/11/01 15:24:53 beazley +# Removed perl4 +# +# Revision 1.2 1999/08/10 16:50:30 beazley +# Windows Runtime +# +# Revision 1.1.1.1 1999/02/28 02:00:53 beazley +# Swig1.1 +# +# Revision 1.1 1996/08/12 01:55:02 dmb +# Initial revision +# +####################################################################### + + +!include + +srcdir = . + +all: wxswig + +wxswig: wxswig.exe + +wxswig.exe: + @echo "Making the SWIG Parser..." + cd SWIG + $(MAKE) + @echo "Make Modules..." + cd ..\Modules + $(MAKE) + cd .. + +clean: + del *.lib + del *.obj + del swig.exe + @cd SWIG + @$(MAKE) clean + @cd ..\Modules + @$(MAKE) clean + @cd .. + +doc: swig + @echo "Building Documentation for SWIG library..." + .\swig -Iswig_lib -d Doc/swiglib -I./swig_lib ./swig_lib/autodoc.i + +runtime: swig + @cd Runtime + $(MAKE) + +## # Install the SWIG program +## +## INSTALL = copy +## +## install: install-main install-lib install-runtime +## @echo "Installation complete" +## +## install-runtime: +## @cd ..\..\Runtime +## $(MAKE) install +## +## install95: install-main95 install-lib95 install-runtime95 +## @echo "Installation complete" +## +## install-runtime95: +## @ ..\..\Runtime +## $(MAKE) install95 +## +## smallinstall: install-main +## +## install-main: swig +## @if not exist $(dprefix) mkdir $(dprefix) +## @echo "Installing $(dSWIG_EXE)" +## @copy ..\swig.exe $(dSWIG_EXE) +## install-lib: +## @if not exist $(dSWIG_LIB) mkdir $(dSWIG_LIB) +## @echo "$(dSWIG_LIB)" +## @echo "Installing the SWIG library" +## @cd ..\swig_lib +## @xcopy *.i $(dSWIG_LIB) +## @xcopy *.swg $(dSWIG_LIB) +## @if not exist $(dSWIG_LIB)\tcl mkdir $(dSWIG_LIB)\tcl +## @cd tcl +## @xcopy *.i $(dSWIG_LIB)\tcl +## @xcopy *.swg $(dSWIG_LIB)\tcl +## @if not exist $(dSWIG_LIB)\perl5 mkdir $(dSWIG_LIB)\perl5 +## @cd ..\perl5 +## @xcopy *.i $(dSWIG_LIB)\perl5 +## @xcopy *.swg $(dSWIG_LIB)\perl5 +## @if not exist $(dSWIG_LIB)\python mkdir $(dSWIG_LIB)\python +## @cd ..\python +## @xcopy *.i $(dSWIG_LIB)\python +## @xcopy *.swg $(dSWIG_LIB)\python +## @if not exist $(dSWIG_LIB)\guile mkdir $(dSWIG_LIB)\guile +## @cd ..\guile +## @xcopy *.i $(dSWIG_LIB)\guile +## @xcopy *.swg $(dSWIG_LIB)\guile +## +## install-main95: swig +## @if not exist $(dprefix) mkdir $(dprefix) +## @echo "Installing $(dSWIG_EXE)" +## @copy ..\swig.exe $(dSWIG_EXE) /Y +## install-lib95: +## @if not exist $(dSWIG_LIB) mkdir $(dSWIG_LIB) +## @echo "$(dSWIG_LIB)" +## @echo "Installing the SWIG library" +## @cd ..\swig_lib +## @xcopy *.i $(dSWIG_LIB) /Y +## @xcopy *.swg $(dSWIG_LIB) /Y +## @mkdir $(dSWIG_LIB)\tcl +## @cd tcl +## @xcopy *.i $(dSWIG_LIB)\tcl /Y +## @xcopy *.swg $(dSWIG_LIB)\tcl /Y +## @mkdir $(dSWIG_LIB)\perl5 +## @cd ..\perl5 +## @xcopy *.i $(dSWIG_LIB)\perl5 /Y +## @xcopy *.swg $(dSWIG_LIB)\perl5 /Y +## @mkdir $(dSWIG_LIB)\python +## @cd ..\python +## @xcopy *.i $(dSWIG_LIB)\python /Y +## @xcopy *.swg $(dSWIG_LIB)\python /Y +## @mkdir $(dSWIG_LIB)\guile +## @cd ..\guile +## @xcopy *.i $(dSWIG_LIB)\guile /Y +## @xcopy *.swg $(dSWIG_LIB)\guile /Y + +#Makefile.template has not been ported to NT +# @echo "Installing Makefile" +# $(INSTALL_DATA) Makefile.template $(dSWIG_LIB)/Makefile + + + diff --git a/wxPython/wxSWIG/swig_lib/array.i b/wxPython/wxSWIG/swig_lib/array.i new file mode 100644 index 0000000000..3ae8a8c4d8 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/array.i @@ -0,0 +1,401 @@ +// +// array.i +// Dave Beazley +// November 30, 1996 +// +// This SWIG library file provides access to C arrays. + +%module carray + +%section "SWIG C Array Module",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 + +%text %{ +%include array.i + +This module provides scripting language access to various kinds of C/C++ +arrays. For each datatype, a collection of four functions are created : + + _array(size) : Create a new array of given size + _get(array, index) : Get an element from the array + _set(array, index, value) : Set an element in the array + _destroy(array) : Destroy an array + +The functions in this library are only low-level accessor functions +designed to directly access C arrays. Like C, no bounds checking is +performed so use at your own peril. +%} + +// Grab the SWIG exception library + +#ifndef AUTODOC +%include exception.i +#endif + +// A Typemap used to check input arguments. + +%typemap(check) int *, double *, float *, char **, short *, long * { + if (!$target) { + SWIG_exception(SWIG_ValueError,"Received a NULL Pointer"); + } +} + +%typemap(ret) int *, double *, float *, char **, short *, long * { + if (!$source) { + SWIG_exception(SWIG_MemoryError,"Out of memory."); + } +} + +// ----------------------------------------------------------------------- +// Integer array support +// ----------------------------------------------------------------------- + +%subsection "Integer Arrays" +%text %{ +The following functions provide access to integer arrays (mapped +onto the C 'int' datatype. +%} + +%{ +#include + +/* Create a new integer array */ + + static int *int_array(int size) { +#ifdef __cplusplus + return new int[size]; +#else + return (int *) malloc(size*sizeof(int)); +#endif + } + + /* Destroy an integer array */ + + static void int_destroy(int *array) { + if (array) { +#ifdef __cplusplus + delete array; +#else + free(array); +#endif + } + } + + /* Return an element */ + + static int int_get(int *array, int index) { + if (array) { + return array[index]; + } else { + return INT_MIN; + } + } + + /* Set an element */ + + static int int_set(int *array, int index, int value) { + if (array) { + return (array[index] = value); + } else { + return INT_MIN; + } + } + +%} + +int *int_array(int nitems); +/* Creates a new array of integers. nitems specifies the number of elements. + The array is created using malloc() in C and new() in C++. */ + +void int_destroy(int *array); +/* Destroys the given array. */ + +int int_get(int *array, int index); +/* Returns the value of array[index]. */ + +int int_set(int *array, int index, int value); +/* Sets array[index] = value. Returns value. */ + + +// ----------------------------------------------------------------------- +// Floating point +// ----------------------------------------------------------------------- + +%subsection "Floating Point Arrays" +/* The following functions provide access to arrays of floats and doubles. */ + + +%{ + #include + + /* Create a new float array */ + + static float *float_array(int size) { +#ifdef __cplusplus + return new float[size]; +#else + return (float *) malloc(size*sizeof(float)); +#endif + } + + /* Destroy an array */ + + static void float_destroy(float *array) { + if (array) { +#ifdef __cplusplus + delete array; +#else + free(array); +#endif + } + } + + /* Return an element */ + + static float float_get(float *array, int index) { + if (array) { + return array[index]; + } else { + return FLT_MIN; + } + } + + /* Set an element */ + + static float float_set(float *array, int index, float value) { + if (array) { + return (array[index] = value); + } else { + return FLT_MIN; + } + } + + /* Create a new double array */ + + static double *double_array(int size) { +#ifdef __cplusplus + return new double[size]; +#else + return (double *) malloc(size*sizeof(double)); +#endif + } + + /* Destroy an array */ + + static void double_destroy(double *array) { + if (array) { +#ifdef __cplusplus + delete array; +#else + free(array); +#endif + } + } + + /* Return an element */ + + static double double_get(double *array, int index) { + if (array) { + return array[index]; + } else { + return FLT_MIN; + } + } + + /* Set an element */ + + static double double_set(double *array, int index, double value) { + if (array) { + return (array[index] = value); + } else { + return FLT_MIN; + } + } + +%} + +double *double_array(int nitems); +/* Creates a new array of doubles. nitems specifies the number of elements. + The array is created using malloc() in C and new() in C++. */ + +void double_destroy(double *array); +/* Destroys the given array. */ + +double double_get(double *array, int index); +/* Returns the value of array[index]. */ + +double double_set(double *array, int index, double value); +/* Sets array[index] = value. Returns value. */ + +float *float_array(int nitems); +/* Creates a new array of floats. nitems specifies the number of elements. + The array is created using malloc() in C and new() in C++. */ + +void float_destroy(float *array); +/* Destroys the given array. */ + +float float_get(float *array, int index); +/* Returns the value of array[index]. */ + +float float_set(float *array, int index, float value); +/* Sets array[index] = value. Returns value. */ + +// ----------------------------------------------------------------------- +// Character strings +// ----------------------------------------------------------------------- + +%subsection "String Arrays" + +%text %{ +The following functions provide support for the 'char **' datatype. This +is primarily used to handle argument lists and other similar structures that +need to be passed to a C/C++ function. +%} + +#if defined(SWIGTCL) +%text %{ +To convert from a Tcl list into a 'char **', the following code can be used : + + # $list is a list + set args [string_array expr {[llength $list] + 1}] + set i 0 + foreach a $list { + string_set $args $i $a + incr i 1 + } + string_set $i "" + # $args is now a char ** type +%} +#elif defined(SWIGPERL) + +%text %{ +To convert from a Perl list into a 'char **', code similar to the following +can be used : + + # @list is a list + my $l = scalar(@list); + my $args = string_array($l+1); + my $i = 0; + foreach $arg (@list) { + string_set($args,$i,$arg); + $i++; + } + string_set($args,$i,""); + +(of course, there is always more than one way to do it) +%} +#elif defined(SWIGPYTHON) + +%text %{ +To convert from a Python list to a 'char **', code similar to the following +can be used : + + # 'list' is a list + args = string_array(len(list)+1) + for i in range(0,len(list)): + string_set(args,i,list[i]) + string_set(args,len(list),"") +%} + +#endif + +%{ +/* Create character string arrays */ + +static char **string_array(int size) { + char **a; + int i; +#ifdef __cplusplus + a = new char *[size]; +#else + a = (char **) malloc(size*sizeof(char *)); +#endif + for (i = 0; i < size; i++) + a[i] = 0; + return a; +} + +/* Destroy a string array */ + +static void string_destroy(char **array) { + int i = 0; + if (array) { + while (array[i]) { +#ifdef __cplusplus + delete array[i]; +#else + free(array[i]); +#endif + i++; + } +#ifdef __cplusplus + delete array; +#else + free(array); +#endif + } +} + +/* Get an element */ + +static char *string_get(char **array_string, int index) { + if (array_string) + if (array_string[index]) return (array_string[index]); + else return ""; + else + return ""; +} + +/* Set an element */ + +static char *string_set(char **array_string, int index, char * val) { + if (array_string) { + if (array_string[index]) { +#ifdef __cplusplus + delete array_string[index]; +#else + free(array_string[index]); +#endif + } + if (strlen(val) > 0) { +#ifdef __cplusplus + array_string[index] = new char[strlen(val)+1]; +#else + array_string[index] = (char *) malloc(strlen(val)+1); +#endif + strcpy(array_string[index],val); + return array_string[index]; + } else { + array_string[index] = 0; + return val; + } + } else return val; +} + +%} + +char **string_array(int nitems); +/* Creates a new array of strings. nitems specifies the number of elements. + The array is created using malloc() in C and new() in C++. Each element + of the array is set to NULL upon initialization. */ + +void string_destroy(char **array); +/* Destroys the given array. Each element of the array is assumed to be + a NULL-terminated string allocated with malloc() or new(). All of + these strings will be destroyed as well. (It is probably only safe to + use this function on an array created by string_array) */ + +char *string_get(char **array, int index); +/* Returns the value of array[index]. Returns a string of zero length + if the corresponding element is NULL. */ + +char *string_set(char **array, int index, char *value); +/* Sets array[index] = value. value is assumed to be a NULL-terminated + string. A string of zero length is mapped into a NULL value. When + setting the value, the value will be copied into a new string allocated + with malloc() or new(). Any previous value in the array will be + destroyed. */ + + +%typemap(check) int *, double *, float *, char **, short *, long * = PREVIOUS; +%typemap(out) int *, double *, float *, char **, short *, long * = PREVIOUS; + diff --git a/wxPython/wxSWIG/swig_lib/autodoc.i b/wxPython/wxSWIG/swig_lib/autodoc.i new file mode 100644 index 0000000000..4f99c55c1a --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/autodoc.i @@ -0,0 +1,109 @@ +// This file automatically generates the SWIG library documentation +%doconly +%style latex_section="\\newpage \\section{:}" +%title "SWIG Library Reference",pre,sort,chop_left = 0,noinfo +/* +Version 1.1p4 +January, 1998 + +Copyright (C) 1996-1998 +Dave Beazley + +(This file was automatically generated by SWIG) +*/ +%style html_contents="


    :

    " +%module swig_lib + +%section " Introduction" +%text %{ +This file describes all of the functions in the generic SWIG library. +The SWIG library is a collection of generally useful functions that +can be used to supplement an interface file. These include functions +to manipulate arrays, functions from the C library, and interesting +modules. + +This document is automatically generated by SWIG from the file +"swig_lib/autodoc.i". Some modules may supply additional documentation +for a particular target language. To recreate the documentation for +a particular target language, simply run SWIG on the file 'autodoc.i' +with the appropriate target language option. +%} + +#if defined(SWIGTCL) +%text %{ +This document has been generated for Tcl. +%} +#elif defined(SWIGPERL) +%text %{ +This document has been generated for Perl. +%} +#elif defined(SWIGPYTHON) +%text %{ +This document has been generated for Python. +%} +#endif + +%subsection "Call for contributions" +%text %{ +My long-term goal is for the SWIG library to be a collection of useful +modules that can be used to quickly put together interesting programs. +To contribute new modules send e-mail to beazley@cs.utah.edu and I +will include them here. +%} + +#define AUTODOC + +%include array.i +%include math.i +%include timers.i +%include malloc.i +%include memory.i +%include exception.i +%include pointer.i +%include constraints.i +%include typemaps.i + +#ifdef SWIGTCL +%section "Tcl Library Files",nosort +%text %{ +The following library modules are available when using the Tcl +language module. +%} +%include "tcl/consthash.i" +%include "tcl/constarray.i" +%include "tcl/tclsh.i" +%include "tcl/wish.i" +%include "tcl/expect.i" +%include "tcl/expectk.i" +%include "tcl/blt.i" +%include "tcl/tix.i" +%include "tcl/ish.i" +%include "tcl/itclsh.i" +%include "tcl/iwish.i" +%include "tcl/itkwish.i" +#endif + +#ifdef SWIGPYTHON +%section "Python Library Files",nosort +%text %{ +The following modules are available when using the Python language +module. +%} +%include "python/embed.i" +%include "python/embed14.i" +%include "python/embed13.i" + +#endif + +#ifdef SWIGPERL +%section "Perl Library Files",nosort + +%text %{ +The following modules are available when using the Perl5 language +module. +%} + +%include "perl5/perlmain.i" +#endif + + diff --git a/wxPython/wxSWIG/swig_lib/carray.i b/wxPython/wxSWIG/swig_lib/carray.i new file mode 100644 index 0000000000..29e51d2a80 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/carray.i @@ -0,0 +1,182 @@ +// +// $Header$ +// carray.i +// Dave Beazley +// March 24, 1996 +// +// This SWIG library file supports C arrays of various datatypes. +// These arrays are probably *not* compatible with scripting languages +// but they are compatible with C functions. +// +/* Revision History + * -- $Log$ + * -- Revision 1.1 2002/04/29 19:56:49 RD + * -- Since I have made several changes to SWIG over the years to accomodate + * -- special cases and other things in wxPython, and since I plan on making + * -- several more, I've decided to put the SWIG sources in wxPython's CVS + * -- instead of relying on maintaining patches. This effectivly becomes a + * -- fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * -- doesn't have some things I rely on in 1.1, not to mention that my + * -- custom patches would all have to be redone, I felt that this is the + * -- easier road to take. + * -- + * -- Revision 1.1.1.1 1999/02/28 02:00:53 beazley + * -- Swig1.1 + * -- + * -- Revision 1.1 1996/05/22 17:23:48 beazley + * -- Initial revision + * -- + */ + +%module carray +%{ + +#include + +/* Create an integer array of given size */ + +static int *array_int(int size) { + return (int *) malloc(size*sizeof(int)); +} + +static int get_int(int *array_int, int index) { + if (array_int) + return (array_int[index]); + else + return 0; +} + +static int set_int(int *array_int, int index, int val) { + if (array_int) + return (array_int[index] = val); + else + return 0; +} + +/* Create double precision arrays */ + +static double *array_double(int size) { + return (double *) malloc(size*sizeof(double)); +} + +static double get_double(double *array_double, int index) { + if (array_double) + return (array_double[index]); + else + return 0; +} + +static double set_double(double *array_double, int index, double val) { + if (array_double) + return (array_double[index] = val); + else + return 0; +} + +/* Create byte arrays */ + +typedef unsigned char byte; + +static byte *array_byte(int size) { + return (byte *) malloc(size*sizeof(byte)); +} + +static byte get_byte(byte *array_byte, int index) { + if (array_byte) + return (array_byte[index]); + else + return 0; +} + +static byte set_byte(byte *array_byte, int index, byte val) { + if (array_byte) + return (array_byte[index] = val); + else + return 0; +} + +/* Create character string arrays */ + +static char **array_string(int size) { + char **a; + int i; + + a = (char **) malloc(size*sizeof(char *)); + for (i = 0; i < size; i++) + a[i] = 0; + return a; +} + +static char *get_string(char **array_string, int index) { + if (array_string) + return (array_string[index]); + else + return ""; +} + +static char *set_string(char **array_string, int index, char * val) { + if (array_string) { + if (array_string[index]) free(array_string[index]); + if (strlen(val) > 0) { + array_string[index] = (char *) malloc(strlen(val)+1); + strcpy(array_string[index],val); + return array_string[index]; + } else { + array_string[index] = 0; + return val; + } + } + else + return val; + } + +%} + +%section "Array Operations" + +int *array_int(int size); +/* Creates an integer array of size elements. Integers are the same +size as the C int type. */ + +int get_int(int *array_int, int index) ; +/* Return the integer in array_int[index] */ + +int set_int(int *array_int, int index, int ival); +/* Sets array_int[index] = ival. Returns it's value so you +can use this function in an expression. */ + +/* Create double precision arrays */ + +double *array_double(int size); +/* Creates an array of double precision floats. */ + +double get_double(double *array_double, int index); +/* Return the double in array_double[index] */ + +double set_double(double *array_double, int index, double dval); +/* Sets array_double[index] = dval. Returns it's value */ + +typedef unsigned char byte; + +byte *array_byte(int nbytes); +/* Creates a byte array. A byte is defined as an unsigned char. */ + +byte get_byte(byte *array_byte, int index); +/* Returns array_byte[index] */ + +byte set_byte(byte *array_byte, int index, byte val); +/* Sets array_byte[index] = val. Returns it's new value */ + +char **array_string(int size); +/* Creates a string array. A string is array is the same as char ** in C */ + +char *get_string(char **array_string, int index); +/* Returns character string in array_string[index]. If that entry is +NULL, returns an empty string */ + +char *set_string(char **array_string, int index, char * string); +/* Sets array_string[index] = string. string must be a 0-terminated +ASCII string. If string is "" then this will create a NULL pointer. */ + + + diff --git a/wxPython/wxSWIG/swig_lib/config/swigptr.swg b/wxPython/wxSWIG/swig_lib/config/swigptr.swg new file mode 100644 index 0000000000..80b002e372 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/config/swigptr.swg @@ -0,0 +1,172 @@ +/* swigptr.cfg + * $Header$ + * + * This file contains two functions : + * + * void _swig_make_hex(char *_c, void *_ptr, char *type) + * char *_swig_get_hex(char *_c, void **ptr, char *type) + * + * These are used to convert pointers to and from pointer strings + * and to perform type checking. + * + * You can remap these functions by making a file called "swigptr.cfg" in + * your the same directory as the interface file you are wrapping. + * + * IMPORTANT !!! the function _swig_get_hex returns a non-null char pointer + * in the event of a type error (this is used to generate an error message). + * If a type is successfully parsed, a NULL pointer is returned. + * + * $Log$ + * Revision 1.1 2002/04/29 19:56:50 RD + * Since I have made several changes to SWIG over the years to accomodate + * special cases and other things in wxPython, and since I plan on making + * several more, I've decided to put the SWIG sources in wxPython's CVS + * instead of relying on maintaining patches. This effectivly becomes a + * fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * doesn't have some things I rely on in 1.1, not to mention that my + * custom patches would all have to be redone, I felt that this is the + * easier road to take. + * + * Revision 1.1.1.1 1999/02/28 02:00:53 beazley + * Swig1.1 + * + * Revision 1.5 1996/08/01 16:28:56 dmb + * Took out unused "dt" variable. + * + * Revision 1.4 1996/07/23 14:38:42 dmb + * Minor change to handling of NULL pointers. + * + * Revision 1.3 1996/07/17 15:26:08 dmb + * Made a minor bug fix so pointers of form _0_Type could be used + * (as described in the manual). Disable by compiling with -DNO_ZERO. + * + * Revision 1.2 1996/06/10 23:42:10 beazley + * Added const qualifier. + * +# Revision 1.1 1996/05/22 17:17:47 beazley +# Initial revision +# + */ + +static void +_swig_make_hex (char *_c, const void *_ptr, char *type) +{ + static char _hex[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + unsigned long _p, _s; + char _result[128], *_r; + _r = _result; + _p = (unsigned long) _ptr; + if (_p > 0) + { + while (_p > 0) + { + _s = _p & 0xf; + *(_r++) = _hex[_s]; + _p = _p >> 4; + } + *_r = '_'; + while (_r >= _result) + *(_c++) = *(_r--); + } + else + { + strcpy (_c, "NULL"); + } + if (_ptr) + strcpy (_c, type); +} + +/* A forward reference; */ + +static char ***swig_ptr_derived = 0; + +static char * +_swig_get_hex (char *_c, void **ptr, char *_t) +{ + unsigned long _p; + char temp_type[256]; + char *_tt; + char **eq; + int i, j, n; + _p = 0; + if (*_c == '_') + { + _c++; + while (*_c) + { + if ((*_c >= '0') && (*_c <= '9')) + _p = (_p << 4) + (*_c - '0'); + else if ((*_c >= 'a') && (*_c <= 'f')) + _p = (_p << 4) + ((*_c - 'a') + 10); + else + break; + _c++; + } +#ifdef NO_ZERO + if (_p == 0) + { + return (char *) _c; + } +#endif + _tt = _c; + if (_t) + { + if (strcmp (_c, _t)) + { + /* Have a type mismatch, we're going to have to do some + searching here */ + i = 0; + if (swig_ptr_derived) + { + while (swig_ptr_derived[i]) + { + eq = swig_ptr_derived[i]; + /* Check type */ + if (strncmp (_t, eq[0], strlen (eq[0])) == 0) + { + /* Found derived type list for this. */ + n = strlen (eq[0]); + j = 1; + while (eq[j]) + { + sprintf (temp_type, "%s%s", eq[j], _t + n); + if (strcmp (_c, temp_type) == 0) + { + *ptr = (void *) _p; + return (char *) 0; + } + j++; + } + } + i++; + } + } + *ptr = (void *) _p; + return _tt; + } + else + { + *ptr = (void *) _p; + return (char *) 0; + } + } + else + { + *ptr = (void *) _p; + return (char *) 0; + } + } + else { +#ifdef ALLOW_NULL + if (strcmp (_c, "NULL") == 0) + { + *ptr = (void *) 0; + return (char *) 0; + } +#endif + *ptr = (void *) 0; + return _c; + } +} diff --git a/wxPython/wxSWIG/swig_lib/constraints.i b/wxPython/wxSWIG/swig_lib/constraints.i new file mode 100644 index 0000000000..07ce322080 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/constraints.i @@ -0,0 +1,208 @@ +// +// SWIG constraint library +// Dave Beazley +// May 4, 1997 +// +// This library file contains typemaps for implementing various kinds of +// constraints. Depends upon the SWIG exception library for generating +// errors in a language-independent manner. + +#ifdef AUTODOC +%section "Constraint Library",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 + +%text %{ +%include constraints.i + +This library provides support for applying constraints to function +arguments. Using a constraint, you can restrict arguments to be +positive numbers, non-NULL pointers, and so on. The following +constraints are available : + + Number POSITIVE - Positive number (not zero) + Number NEGATIVE - Negative number (not zero) + Number NONZERO - Nonzero number + Number NONNEGATIVE - Positive number (including zero) + Number NONPOSITIVE - Negative number (including zero) + Pointer NONNULL - Non-NULL pointer + Pointer ALIGN8 - 8-byte aligned pointer + Pointer ALIGN4 - 4-byte aligned pointer + Pointer ALIGN2 - 2-byte aligned pointer + +To use the constraints, you need to "apply" them to specific +function arguments in your code. This is done using the %apply +directive. For example : + + %apply Number NONNEGATIVE { double nonneg }; + double sqrt(double nonneg); // Name of argument must match + + %apply Pointer NONNULL { void *ptr }; + void *malloc(int POSITIVE); // May return a NULL pointer + void free(void *ptr); // May not accept a NULL pointer + +Any function argument of the type you specify with the %apply directive +will be checked with the appropriate constraint. Multiple types may +be specified as follows : + + %apply Pointer NONNULL { void *, Vector *, List *, double *}; + +In this case, all of the types listed would be checked for non-NULL +pointers. + +The common datatypes of int, short, long, unsigned int, unsigned long, +unsigned short, unsigned char, signed char, float, and double can be +checked without using the %apply directive by simply using the +constraint name as the parameter name. For example : + + double sqrt(double NONNEGATIVE); + double log(double POSITIVE); + +If you have used typedef to change type-names, you can also do this : + + %apply double { Real }; // Make everything defined for doubles + // work for Reals. + Real sqrt(Real NONNEGATIVE); + Real log(Real POSITIVE); + +%} +#endif + +%include exception.i + +// Positive numbers + +%typemap(check) int POSITIVE, + short POSITIVE, + long POSITIVE, + unsigned int POSITIVE, + unsigned short POSITIVE, + unsigned long POSITIVE, + signed char POSITIVE, + unsigned char POSITIVE, + float POSITIVE, + double POSITIVE, + Number POSITIVE +{ + if ($target <= 0) { + SWIG_exception(SWIG_ValueError,"Expected a positive value."); + } +} + +// Negative numbers + +%typemap(check) int NEGATIVE, + short NEGATIVE, + long NEGATIVE, + unsigned int NEGATIVE, + unsigned short NEGATIVE, + unsigned long NEGATIVE, + signed char NEGATIVE, + unsigned char NEGATIVE, + float NEGATIVE, + double NEGATIVE, + Number NEGATIVE +{ + if ($target >= 0) { + SWIG_exception(SWIG_ValueError,"Expected a negative value."); + } +} + +// Nonzero numbers + +%typemap(check) int NONZERO, + short NONZERO, + long NONZERO, + unsigned int NONZERO, + unsigned short NONZERO, + unsigned long NONZERO, + signed char NONZERO, + unsigned char NONZERO, + float NONZERO, + double NONZERO, + Number NONZERO +{ + if ($target == 0) { + SWIG_exception(SWIG_ValueError,"Expected a nonzero value."); + } +} + +// Nonnegative numbers + +%typemap(check) int NONNEGATIVE, + short NONNEGATIVE, + long NONNEGATIVE, + unsigned int NONNEGATIVE, + unsigned short NONNEGATIVE, + unsigned long NONNEGATIVE, + signed char NONNEGATIVE, + unsigned char NONNEGATIVE, + float NONNEGATIVE, + double NONNEGATIVE, + Number NONNEGATIVE +{ + if ($target < 0) { + SWIG_exception(SWIG_ValueError,"Expected a non-negative value."); + } +} + +// Nonpositive numbers + +%typemap(check) int NONPOSITIVE, + short NONPOSITIVE, + long NONPOSITIVE, + unsigned int NONPOSITIVE, + unsigned short NONPOSITIVE, + unsigned long NONPOSITIVE, + signed char NONPOSITIVE, + unsigned char NONPOSITIVE, + float NONPOSITIVE, + double NONPOSITIVE, + Number NONPOSITIVE +{ + if ($target < 0) { + SWIG_exception(SWIG_ValueError,"Expected a non-positive value."); + } +} + +// Non-NULL pointer + +%typemap(check) void * NONNULL, + Pointer NONNULL +{ + if (!$target) { + SWIG_exception(SWIG_ValueError,"Received a NULL pointer."); + } +} + +// Aligned pointers + +%typemap(check) void * ALIGN8, + Pointer ALIGN8 +{ + long tmp; + tmp = (long) $target; + if (tmp & 7) { + SWIG_exception(SWIG_ValueError,"Pointer must be 8-byte aligned."); + } +} + +%typemap(check) void * ALIGN4, + Pointer ALIGN4 +{ + long tmp; + tmp = (long) $target; + if (tmp & 3) { + SWIG_exception(SWIG_ValueError,"Pointer must be 4-byte aligned."); + } +} + +%typemap(check) void * ALIGN2, + Pointer ALIGN2 +{ + long tmp; + tmp = (long) $target; + if (tmp & 1) { + SWIG_exception(SWIG_ValueError,"Pointer must be 2-byte aligned."); + } +} + + diff --git a/wxPython/wxSWIG/swig_lib/ctype.i b/wxPython/wxSWIG/swig_lib/ctype.i new file mode 100644 index 0000000000..5b4ac54e87 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/ctype.i @@ -0,0 +1,64 @@ +// +// ctype.i +// Dave Beazley +// November 30, 1996 +// SWIG file for character tests +// + +%module ctype +%{ +#include +%} + +%section "Character Class Testing Module",after,info,nosort,pre,chop_left=3,chop_bottom=0,chop_top=0,chop_right=0,skip=1 + +%text %{ +%include ctype.i + +This module provides access to a number of functions for testing +characters. These functions are in the C library. +Most scripting languages already provide much of this functionality, +but just in case you want to use one of the built-in C functions, +you can use this module. +%} + +int isalnum(char c); +/* Returns 1 if isalpha(c) or isdigit(c) is true. */ + +int isalpha(char c); +/* Returns 1 if isupper(c) or islower(c) is true. */ + +int iscntrl(char c); +/* Returns 1 if c is a control character. */ + +int isdigit(char c); +/* Returns 1 if c is a decimal digit. */ + +int isgraph(char c); +/* Returns 1 if c is a printing character except space. */ + +int islower(char c); +/* Returns 1 if c is a lower-case letter. */ + +int isprint(char c); +/* Returns 1 if c is a printing character including space. */ + +int ispunct(char c); +/* Returns 1 if c is a printing character except space or letter + or digit. */ + +int isspace(char c); +/* Returns 1 if c is a space, formfeed, newline, carriage return, + tab, or vertical tab. */ + +int isupper(char c); +/* Returns 1 if c is an upper case letter. */ + +int isxdigit(char c); +/* Returns 1 if c is a hexadecimal digit. */ + +char tolower(char c); +/* Converts c to lower case */ + +char toupper(char c); +/* Converts c to upper case */ diff --git a/wxPython/wxSWIG/swig_lib/exception.i b/wxPython/wxSWIG/swig_lib/exception.i new file mode 100644 index 0000000000..007d3aa824 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/exception.i @@ -0,0 +1,146 @@ +// +// except.i +// Dave Beazley +// April 14, 1997 +// +// This SWIG library file provides language independent exception handling + +#ifdef AUTODOC +%section "Exception Handling Library",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 + +%text %{ +%include exception.i + +This library provides language independent support for raising scripting +language exceptions in SWIG generated wrapper code. Normally, this is +used in conjunction with the %except directive. + +To raise an exception, use the following function call : + + SWIG_exception(int exctype, char *msg); + +'exctype' is an exception type code and may be one of the following : + + SWIG_MemoryError + SWIG_IOError + SWIG_RuntimeError + SWIG_IndexError + SWIG_TypeError + SWIG_DivisionByZero + SWIG_OverflowError + SWIG_SyntaxError + SWIG_ValueError + SWIG_SystemError + SWIG_UnknownError + +'msg' is an error string that should be reported to the user. + +The library is normally used in conjunction with the %except directive +as follows : + +%except { + try { + $function + } catch RangeError { + SWIG_exception(SWIG_IndexError,"Array index out of bounds"); + } catch(...) { + SWIG_exception(SWIG_UnknownError,"Uncaught exception"); + } +} + +It is important to note that the SWIG_exception() function is only available +to the C code generated by SWIG. It is not available in the scripting language +interface itself. +%} + +#endif + +%{ +#define SWIG_MemoryError 1 +#define SWIG_IOError 2 +#define SWIG_RuntimeError 3 +#define SWIG_IndexError 4 +#define SWIG_TypeError 5 +#define SWIG_DivisionByZero 6 +#define SWIG_OverflowError 7 +#define SWIG_SyntaxError 8 +#define SWIG_ValueError 9 +#define SWIG_SystemError 10 +#define SWIG_UnknownError 99 +%} + +#ifdef SWIGTCL8 +%{ +#define SWIG_exception(a,b) Tcl_SetStringObj(tcl_result,b,-1); return TCL_ERROR +%} +#else +#ifdef SWIGTCL +%{ +#define SWIG_exception(a,b) Tcl_SetResult(interp,b,TCL_VOLATILE); return TCL_ERROR +%} +#endif +#endif + +#ifdef SWIGPERL5 +%{ +#define SWIG_exception(a,b) croak(b) +%} +#endif + +#ifdef SWIGPERL4 +%{ +#define SWIG_exception(a,b) fatal(b) +%} +#endif + +#ifdef SWIGPYTHON +%{ +static void _SWIG_exception(int code, char *msg) { + switch(code) { + case SWIG_MemoryError: + PyErr_SetString(PyExc_MemoryError,msg); + break; + case SWIG_IOError: + PyErr_SetString(PyExc_IOError,msg); + break; + case SWIG_RuntimeError: + PyErr_SetString(PyExc_RuntimeError,msg); + break; + case SWIG_IndexError: + PyErr_SetString(PyExc_IndexError,msg); + break; + case SWIG_TypeError: + PyErr_SetString(PyExc_TypeError,msg); + break; + case SWIG_DivisionByZero: + PyErr_SetString(PyExc_ZeroDivisionError,msg); + break; + case SWIG_OverflowError: + PyErr_SetString(PyExc_OverflowError,msg); + break; + case SWIG_SyntaxError: + PyErr_SetString(PyExc_SyntaxError,msg); + break; + case SWIG_ValueError: + PyErr_SetString(PyExc_ValueError,msg); + break; + case SWIG_SystemError: + PyErr_SetString(PyExc_SystemError,msg); + break; + default: + PyErr_SetString(PyExc_RuntimeError,msg); + break; + } +} + +#define SWIG_exception(a,b) _SWIG_exception(a,b); return NULL +%} +#endif + +#ifdef SWIGGUILE +%echo %{ +exception.i : Guile not currently supported. +%} +#endif + + diff --git a/wxPython/wxSWIG/swig_lib/guile/Makefile b/wxPython/wxSWIG/swig_lib/guile/Makefile new file mode 100644 index 0000000000..ff66f9efad --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/guile/Makefile @@ -0,0 +1,4 @@ + +co:: + co RCS/*.i* RCS/*.swg* + diff --git a/wxPython/wxSWIG/swig_lib/guile/guile.swg b/wxPython/wxSWIG/swig_lib/guile/guile.swg new file mode 100644 index 0000000000..35649e441e --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/guile/guile.swg @@ -0,0 +1,15 @@ +/* ----------------------------------------------------------------------- + * swig_lib/guile/guile.swg + * + * Guile configuration file. This file assumes FSF Guile 1.0. It may not + * work with other versions + * ----------------------------------------------------------------------- */ + +#include "guile/gh.h" + +/* Since GUILE seems to be somewhat incomplete, these bindings + are used in the SWIG generated code. To change the Guile + interface, simply change this file */ + +#define GH_NOT_PASSED SCM_UNDEFINED + diff --git a/wxPython/wxSWIG/swig_lib/guile/guilemain.i b/wxPython/wxSWIG/swig_lib/guile/guilemain.i new file mode 100644 index 0000000000..88988e9bbb --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/guile/guilemain.i @@ -0,0 +1,21 @@ +%{ +void guile_main(void *closure, int argc, char **argv) { + char buffer[1024]; + void SWIG_init(); + SWIG_init(); + printf("starting Guile...\n"); + printf("guile >"); + while (fgets(buffer,1024,stdin)) { + gh_eval_str(buffer); + printf("guile >"); + } +} + +void main(int argc, char **argv) { + gh_enter(argc,argv, guile_main); +} +%} + + + + diff --git a/wxPython/wxSWIG/swig_lib/guile/interpreter.i b/wxPython/wxSWIG/swig_lib/guile/interpreter.i new file mode 100644 index 0000000000..488d4a833f --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/guile/interpreter.i @@ -0,0 +1,78 @@ +// +// $Header$ +// +// SWIG file for a simple Guile interpreter +// +/* Revision History + * $Log$ + * Revision 1.1 2002/04/29 19:56:52 RD + * Since I have made several changes to SWIG over the years to accomodate + * special cases and other things in wxPython, and since I plan on making + * several more, I've decided to put the SWIG sources in wxPython's CVS + * instead of relying on maintaining patches. This effectivly becomes a + * fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * doesn't have some things I rely on in 1.1, not to mention that my + * custom patches would all have to be redone, I felt that this is the + * easier road to take. + * + * Revision 1.1.1.1 1999/02/28 02:00:54 beazley + * Swig1.1 + * + * Revision 1.1 1996/05/22 20:02:10 beazley + * Initial revision + * + */ + +%{ + +#include +GSCM_status guile_init(); + +int main(int argc, char **argv) { + GSCM_status status; + GSCM_top_level toplev; + char *eval_answer; + char input_str[16384]; + int done; + + /* start a scheme interpreter */ + status = gscm_run_scm(argc, argv, 0, stdout, stderr, guile_init, 0, "#t"); + if (status != GSCM_OK) { + fputs(gscm_error_msg(status), stderr); + fputc('\n', stderr); + printf("Error in startup.\n"); + exit(1); + } + + /* create the top level environment */ + status = gscm_create_top_level(&toplev); + if (status != GSCM_OK) { + fputs(gscm_error_msg(status), stderr); + fputc('\n', stderr); + exit(1); + } + + /* now sit in a scheme eval loop: I input the expressions, have guile + * evaluate them, and then get another expression. + */ + done = 0; + fprintf(stdout,"Guile > "); + while (!done) { + if (fgets(input_str,16384,stdin) == NULL) { + exit(1); + } else { + if (strncmp(input_str,"quit",4) == 0) exit(1); + status = gscm_eval_str(&eval_answer, toplev, input_str); + fprintf(stdout,"%s\n", eval_answer); + fprintf(stdout,"Guile > "); + } + } + + /* now clean up and quit */ + gscm_destroy_top_level(toplev); +} + +%} + + + diff --git a/wxPython/wxSWIG/swig_lib/malloc.i b/wxPython/wxSWIG/swig_lib/malloc.i new file mode 100644 index 0000000000..8398aaa962 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/malloc.i @@ -0,0 +1,64 @@ +// +// $Header$ +// +// malloc.i +// Dave Beazley +// March 24, 1996 +// SWIG file for memory management functions +// (also contained in stdlib.i) +// +/* Revision History + * $Log$ + * Revision 1.1 2002/04/29 19:56:49 RD + * Since I have made several changes to SWIG over the years to accomodate + * special cases and other things in wxPython, and since I plan on making + * several more, I've decided to put the SWIG sources in wxPython's CVS + * instead of relying on maintaining patches. This effectivly becomes a + * fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * doesn't have some things I rely on in 1.1, not to mention that my + * custom patches would all have to be redone, I felt that this is the + * easier road to take. + * + * Revision 1.1.1.1 1999/02/28 02:00:53 beazley + * Swig1.1 + * + * Revision 1.1 1996/05/22 17:27:01 beazley + * Initial revision + * + */ + +%module malloc +%{ +#include +%} + +%section "Memory Allocation Module", + pre,info,after,nosort,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0,skip=1 + +%text %{ +%include malloc.i + +This module provides access to a few basic C memory management functions. +All functions return void pointers, but realloc() and free() will operate +on any sort of pointer. Sizes should be specified in bytes. +%} + +void *calloc(unsigned nobj, unsigned size); +/* Returns a pointer to a space for an array of nobj objects, each with + size bytes. Returns NULL if the request can't be satisfied. + Initializes the space to zero bytes. */ + +void *malloc(unsigned size); +/* Returns a pointer to space for an object of size bytes. Returns NULL + upon failure. */ + +void *realloc(void *ptr, unsigned size); +/* Changes the size of the object pointed to by ptr to size bytes. + The contents will be unchanged up the minimum of the old and new + sizes. Returns a pointer to the new space of NULL upon failure, + in which case *ptr is unchanged. */ + +void free(void *ptr); +/* Deallocates the space pointed to by ptr. Does nothing if ptr is NULL. + ptr must be a space previously allocated by calloc, malloc, or realloc. */ + diff --git a/wxPython/wxSWIG/swig_lib/math.i b/wxPython/wxSWIG/swig_lib/math.i new file mode 100644 index 0000000000..1d064c1507 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/math.i @@ -0,0 +1,120 @@ +// +// $Header$ +// +// math.i +// Dave Beazley +// March 24, 1996 +// SWIG file for floating point operations +// +/* Revision history + * $Log$ + * Revision 1.1 2002/04/29 19:56:49 RD + * Since I have made several changes to SWIG over the years to accomodate + * special cases and other things in wxPython, and since I plan on making + * several more, I've decided to put the SWIG sources in wxPython's CVS + * instead of relying on maintaining patches. This effectivly becomes a + * fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * doesn't have some things I rely on in 1.1, not to mention that my + * custom patches would all have to be redone, I felt that this is the + * easier road to take. + * + * Revision 1.1.1.1 1999/02/28 02:00:53 beazley + * Swig1.1 + * + * Revision 1.1 1996/05/22 17:27:01 beazley + * Initial revision + * + */ + +%module math +%{ +#include +%} + +%section "SWIG Math Module",after,info,nosort,pre,chop_left=3,chop_bottom=0,chop_top=0,chop_right=0,skip=1 + +%text %{ +%include math.i + +This module provides access to the C math library and contains most +of the functions in . Most scripting languages already provide +math support, but in certain cases, this module can provide more +direct access. +%} + +%subsection "Functions" + + +extern double cos(double x); +/* Cosine of x */ + +extern double sin(double x); +/* Sine of x */ + +extern double tan(double x); +/* Tangent of x */ + +extern double acos(double x); +/* Inverse cosine in range [-PI/2,PI/2], x in [-1,1]. */ + +extern double asin(double x); +/* Inverse sine in range [0,PI], x in [-1,1]. */ + +extern double atan(double x); +/* Inverse tangent in range [-PI/2,PI/2]. */ + +extern double atan2(double y, double x); +/* Inverse tangent of y/x in range [-PI,PI]. */ + +extern double cosh(double x); +/* Hyperbolic cosine of x */ + +extern double sinh(double x); +/* Hyperbolic sine of x */ + +extern double tanh(double x); +/* Hyperbolic tangent of x */ + +extern double exp(double x); +/* Natural exponential function e^x */ + +extern double log(double x); +/* Natural logarithm ln(x), x > 0 */ + +extern double log10(double x); +/* Base 10 logarithm, x > 0 */ + +extern double pow(double x, double y); +/* Power function x^y. */ + +extern double sqrt(double x); +/* Square root. x >= 0 */ + +extern double fabs(double x); +/* Absolute value of x */ + +extern double ceil(double x); +/* Smallest integer not less than x, as a double */ + +extern double floor(double x); +/* Largest integer not greater than x, as a double */ + +extern double fmod(double x, double y); +/* Floating-point remainder of x/y, with the same sign as x. */ + +%subsection "Mathematical constants",noinfo + +#define M_E 2.7182818284590452354 +#define M_LOG2E 1.4426950408889634074 +#define M_LOG10E 0.43429448190325182765 +#define M_LN2 0.69314718055994530942 +#define M_LN10 2.30258509299404568402 +#define M_PI 3.14159265358979323846 +#define M_PI_2 1.57079632679489661923 +#define M_PI_4 0.78539816339744830962 +#define M_1_PI 0.31830988618379067154 +#define M_2_PI 0.63661977236758134308 +#define M_2_SQRTPI 1.12837916709551257390 +#define M_SQRT2 1.41421356237309504880 +#define M_SQRT1_2 0.70710678118654752440 + diff --git a/wxPython/wxSWIG/swig_lib/memory.i b/wxPython/wxSWIG/swig_lib/memory.i new file mode 100644 index 0000000000..e656325a0e --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/memory.i @@ -0,0 +1,39 @@ +// +// memory.i +// Dave Beazley +// November 30, 1996 +// SWIG file for memory operations +// + +%module memory +%{ +#include +%} + +%section "Memory Manipulation Module",after,info,nosort,pre,chop_left=3,chop_bottom=0,chop_top=0,chop_right=0,skip=1 + +%text %{ +%include memory.i + +This module provides support for a few memory operations from the C + library. These functions can be used to manipulate binary +data. s and t are of type void *, cs and ct are both of type const void *. +%} + +void *memcpy(void *s, const void *ct, int n); +/* Copy n characters from ct to s, and return s */ + +void *memmove(void *s, const void *ct, int n); +/* Same as memcpy except that it works even if the objects overlap. */ + +int memcmp(const void *cs, const void *ct, int n); +/* Compare the first n characters of cs with ct. Returns 0 if + they are equal, <0 if cs < ct, and >0 if cs > ct. */ + +void *memchr(const void *cs, char c, int n); +/* Returns pointer to the first occurrence of character c in cs. */ + +void *memset(void *s, char c, int n); +/* Place character c into first n characters of s, return s */ + + diff --git a/wxPython/wxSWIG/swig_lib/objc.i b/wxPython/wxSWIG/swig_lib/objc.i new file mode 100644 index 0000000000..2655fb8966 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/objc.i @@ -0,0 +1,56 @@ +// SWIG Objective-C configuration file +// Dave Beazley +// Copyright (C) 1997 + +// This file provides support to Objective-C parsing and +// should be included with just about any Objective-C module + +// Base Object class + +@interface Object { } + +-(char *) name; // Get object name + +@end + +typedef Object *id; // Make 'id' behave like any other "Object" + +// Typemaps to make *id work like kind of like a void pointer + +%typemap(python,in) id { + char *temp; + if (!PyString_Check($source)) { + PyErr_SetString(PyExc_TypeError,"Expecting an 'id' in argument $argnum of $name"); + return NULL; + } + temp = PyString_AsString($source); + if (SWIG_GetPtr(temp, (void **) &$target, 0)) { + PyErr_SetString(PyExc_TypeError,"Expecting an 'id' in argument $argnum of $name"); + return NULL; + } +} + +%typemap(tcl,in) id { + if (SWIG_GetPtr($source,(void **) &$target, 0)) { + Tcl_SetResult(interp,"Expecting an 'id' in argument $argnum of $name",TCL_STATIC); + return TCL_ERROR; + } +} + +%typemap(tcl8,in) id { + if (SWIG_GetPointerObj(interp, $source, (void **) &$target, 0)) { + Tcl_SetStringObj(result_obj, "Expecting an 'id' in argument $argnum of $name"); + } +} + +%typemap(perl5,in) id { + if (SWIG_GetPtr($source, (void **) &$target, 0)) { + croak("Expecting an 'id' in argument $argnum of $name"); + } +} + + + + + + diff --git a/wxPython/wxSWIG/swig_lib/perl5/Makefile b/wxPython/wxSWIG/swig_lib/perl5/Makefile new file mode 100644 index 0000000000..abadc851cd --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/perl5/Makefile @@ -0,0 +1,140 @@ +# Generated automatically from Makefile.in by configure. +# --------------------------------------------------------------- +# $Header$ +# SWIG Perl5 Makefile +# +# This file can be used to build various Perl5 extensions with SWIG. +# By default this file is set up for dynamic loading, but it can +# be easily customized for static extensions by modifying various +# portions of the file. +# +# SRCS = C source files +# CXXSRCS = C++ source files +# OBJCSRCS = Objective-C source files +# OBJS = Additional .o files (compiled previously) +# INTERFACE = SWIG interface file +# TARGET = Name of target module or executable +# +# Many portions of this file were created by the SWIG configure +# script and should already reflect your machine. +#---------------------------------------------------------------- + +SRCS = +CXXSRCS = +OBJCSRCS = +OBJS = +INTERFACE = +WRAPFILE = $(INTERFACE:.i=_wrap.c) +WRAPOBJ = $(INTERFACE:.i=_wrap.o) +TARGET = module.so # Use this kind of target for dynamic loading +#TARGET = myperl # Use this target for static linking + +prefix = /usr/local +exec_prefix = ${prefix} + +CC = cc +CXX = CC +OBJC = cc -Wno-import # -Wno-import needed for gcc +CFLAGS = +INCLUDE = +LIBS = + +# SWIG Options +# SWIG = location of the SWIG executable +# SWIGOPT = SWIG compiler options +# SWIGCC = Compiler used to compile the wrapper file + +SWIG = $(exec_prefix)/bin/swig +SWIGOPT = -perl5 +SWIGCC = $(CC) + +# SWIG Library files. Uncomment this to staticly rebuild Perl +#SWIGLIB = -static -lperlmain.i + +# Rules for creating .o files from source. + +COBJS = $(SRCS:.c=.o) +CXXOBJS = $(CXXSRCS:.cxx=.o) +OBJCOBJS = $(OBJCSRCS:.m=.o) +ALLOBJS = $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(OBJS) + +# Command that will be used to build the final extension. +BUILD = $(SWIGCC) + +# Uncomment the following if you are using dynamic loading +CCSHARED = +BUILD = ld -G + +# Uncomment the following if you are using dynamic loading with C++ and +# need to provide additional link libraries (this is not always required). + +#DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ + -L/usr/local/lib -lg++ -lstdc++ -lgcc + +# X11 installation (possibly needed if using Perl-Tk) + +XLIB = -L/usr/openwin/lib -lX11 +XINCLUDE = -I/usr/openwin/include + +# Perl installation + +PERL_INCLUDE = -I/usr/local/lib/perl5/5.00503/sun4-solaris/CORE +PERL_LIB = -L/usr/local/lib/perl5/5.00503/sun4-solaris/CORE -lperl +PERL_FLAGS = -Dbool=char -Dexplicit= + +# Tcl installation. If using Tk you might need this + +TCL_INCLUDE = -I/usr/local/include +TCL_LIB = -L/usr/local/lib + +# Build libraries (needed for static builds) + +LIBM = -lm +LIBC = +SYSLIBS = $(LIBM) $(LIBC) -lsocket -lnsl -ldl + +# Build options (uncomment only one these) + +#TK_LIB = $(TCL_LIB) -ltcl -ltk $(XLIB) +BUILD_LIBS = $(LIBS) # Dynamic loading +#BUILD_LIBS = $(PERL_LIB) $(TK_LIB) $(LIBS) $(SYSLIBS) # Static linking + +# Compilation rules for non-SWIG components + +.SUFFIXES: .c .cxx .m + +.c.o: + $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + +.cxx.o: + $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDE) -c $< + +.m.o: + $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + + +# ---------------------------------------------------------------------- +# Rules for building the extension +# ---------------------------------------------------------------------- + +all: $(TARGET) + +# Convert the wrapper file into an object file + +$(WRAPOBJ) : $(WRAPFILE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(INCLUDE) $(PERL_INCLUDE) $(PERL_FLAGS) $(WRAPFILE) + +$(WRAPFILE) : $(INTERFACE) + $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) + +$(TARGET): $(WRAPOBJ) $(ALLOBJS) + $(BUILD) $(WRAPOBJ) $(ALLOBJS) $(BUILD_LIBS) -o $(TARGET) + +clean: + rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) + + + + + + diff --git a/wxPython/wxSWIG/swig_lib/perl5/Makefile.in b/wxPython/wxSWIG/swig_lib/perl5/Makefile.in new file mode 100644 index 0000000000..7501aeca31 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/perl5/Makefile.in @@ -0,0 +1,139 @@ +# --------------------------------------------------------------- +# $Header$ +# SWIG Perl5 Makefile +# +# This file can be used to build various Perl5 extensions with SWIG. +# By default this file is set up for dynamic loading, but it can +# be easily customized for static extensions by modifying various +# portions of the file. +# +# SRCS = C source files +# CXXSRCS = C++ source files +# OBJCSRCS = Objective-C source files +# OBJS = Additional .o files (compiled previously) +# INTERFACE = SWIG interface file +# TARGET = Name of target module or executable +# +# Many portions of this file were created by the SWIG configure +# script and should already reflect your machine. +#---------------------------------------------------------------- + +SRCS = +CXXSRCS = +OBJCSRCS = +OBJS = +INTERFACE = +WRAPFILE = $(INTERFACE:.i=_wrap.c) +WRAPOBJ = $(INTERFACE:.i=_wrap.o) +TARGET = module@SO@ # Use this kind of target for dynamic loading +#TARGET = myperl # Use this target for static linking + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +CC = @CC@ +CXX = @CXX@ +OBJC = @CC@ -Wno-import # -Wno-import needed for gcc +CFLAGS = +INCLUDE = +LIBS = + +# SWIG Options +# SWIG = location of the SWIG executable +# SWIGOPT = SWIG compiler options +# SWIGCC = Compiler used to compile the wrapper file + +SWIG = $(exec_prefix)/bin/swig +SWIGOPT = -perl5 +SWIGCC = $(CC) + +# SWIG Library files. Uncomment this to staticly rebuild Perl +#SWIGLIB = -static -lperlmain.i + +# Rules for creating .o files from source. + +COBJS = $(SRCS:.c=.o) +CXXOBJS = $(CXXSRCS:.cxx=.o) +OBJCOBJS = $(OBJCSRCS:.m=.o) +ALLOBJS = $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(OBJS) + +# Command that will be used to build the final extension. +BUILD = $(SWIGCC) + +# Uncomment the following if you are using dynamic loading +CCSHARED = @CCSHARED@ +BUILD = @LDSHARED@ + +# Uncomment the following if you are using dynamic loading with C++ and +# need to provide additional link libraries (this is not always required). + +#DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ + -L/usr/local/lib -lg++ -lstdc++ -lgcc + +# X11 installation (possibly needed if using Perl-Tk) + +XLIB = @XLIBSW@ +XINCLUDE = @XINCLUDES@ + +# Perl installation + +PERL_INCLUDE = -I@PERL5EXT@ +PERL_LIB = -L@PERL5EXT@ -lperl +PERL_FLAGS = -Dbool=char -Dexplicit= + +# Tcl installation. If using Tk you might need this + +TCL_INCLUDE = @TCLINCLUDE@ +TCL_LIB = @TCLLIB@ + +# Build libraries (needed for static builds) + +LIBM = @LIBM@ +LIBC = @LIBC@ +SYSLIBS = $(LIBM) $(LIBC) @LIBS@ + +# Build options (uncomment only one these) + +#TK_LIB = $(TCL_LIB) -ltcl -ltk $(XLIB) +BUILD_LIBS = $(LIBS) # Dynamic loading +#BUILD_LIBS = $(PERL_LIB) $(TK_LIB) $(LIBS) $(SYSLIBS) # Static linking + +# Compilation rules for non-SWIG components + +.SUFFIXES: .c .cxx .m + +.c.o: + $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + +.cxx.o: + $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDE) -c $< + +.m.o: + $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + + +# ---------------------------------------------------------------------- +# Rules for building the extension +# ---------------------------------------------------------------------- + +all: $(TARGET) + +# Convert the wrapper file into an object file + +$(WRAPOBJ) : $(WRAPFILE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(INCLUDE) $(PERL_INCLUDE) $(PERL_FLAGS) $(WRAPFILE) + +$(WRAPFILE) : $(INTERFACE) + $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) + +$(TARGET): $(WRAPOBJ) $(ALLOBJS) + $(BUILD) $(WRAPOBJ) $(ALLOBJS) $(BUILD_LIBS) -o $(TARGET) + +clean: + rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) + + + + + + diff --git a/wxPython/wxSWIG/swig_lib/perl5/Makefile.pl b/wxPython/wxSWIG/swig_lib/perl5/Makefile.pl new file mode 100644 index 0000000000..05240f1e93 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/perl5/Makefile.pl @@ -0,0 +1,21 @@ +# File : Makefile.pl +# MakeMaker file for a SWIG module. Use this file if you are +# producing a module for general use or distribution. +# +# 1. Modify the file as appropriate. Replace $module with the +# real name of your module and wrapper file. +# 2. Run perl as 'perl Makefile.pl' +# 3. Type 'make' to build your module +# 4. Type 'make install' to install your module. +# +# See "Programming Perl", 2nd. Ed, for more gory details than +# you ever wanted to know. + +use ExtUtils::MakeMaker; +WriteMakefile( + 'NAME' => '$module', # Name of your module + 'LIBS' => [''], # Custom libraries (if any) + 'OBJECT' => '$module_wrap.o' # Object files +); + + diff --git a/wxPython/wxSWIG/swig_lib/perl5/headers.swg b/wxPython/wxSWIG/swig_lib/perl5/headers.swg new file mode 100644 index 0000000000..3ae8f6a9ec --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/perl5/headers.swg @@ -0,0 +1,24 @@ +/* $Header$ */ +/* Implementation : PERL 5 */ + +#define SWIGPERL +#define SWIGPERL5 +#ifdef __cplusplus +/* Needed on some windows machines---since MS plays funny + games with the header files under C++ */ +#include +#include +extern "C" { +#endif +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +/* Get rid of free and malloc defined by perl */ +#undef free +#undef malloc + +#include +#ifdef __cplusplus +} +#endif diff --git a/wxPython/wxSWIG/swig_lib/perl5/perl5.swg b/wxPython/wxSWIG/swig_lib/perl5/perl5.swg new file mode 100644 index 0000000000..0eecbd28dc --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/perl5/perl5.swg @@ -0,0 +1,361 @@ +/* Definitions for compiling Perl extensions on a variety of machines */ + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# if defined(_MSC_VER) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# if defined(__BORLANDC__) +# define SWIGEXPORT(a) a _export +# else +# define SWIGEXPORT(a) a +# endif +# endif +#else +# define SWIGEXPORT(a) a +#endif + +#ifdef PERL_OBJECT +#define MAGIC_PPERL CPerlObj *pPerl = (CPerlObj *) this; +#define MAGIC_CAST (int (CPerlObj::*)(SV *, MAGIC *)) +#define SWIGCLASS_STATIC +#else +#define MAGIC_PPERL +#define MAGIC_CAST +#define SWIGCLASS_STATIC static +#endif + +#if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE) +#define PerlIO_exportFILE(fh,fl) (FILE*)(fh) +#endif + +/* Modifications for newer Perl 5.005 releases */ + +#if !defined(PERL_REVISION) || ((PERL_REVISION >= 5) && ((PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION < 50)))) +#ifndef PL_sv_yes +#define PL_sv_yes sv_yes +#endif +#ifndef PL_sv_undef +#define PL_sv_undef sv_undef +#endif +#ifndef PL_na +#define PL_na na +#endif +#endif + +/****************************************************************************** + * Pointer type-checking code + *****************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SWIG_NOINCLUDE +extern void SWIG_MakePtr(char *, void *, char *); +#ifndef PERL_OBJECT +extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); +#else +#define SWIG_RegisterMapping(a,b,c) _SWIG_RegisterMapping(pPerl,a,b,c); +extern void _SWIG_RegisterMapping(CPerlObj *,char *, char *, void *(*)(void *),int); +#endif +#ifndef PERL_OBJECT +extern char *SWIG_GetPtr(SV *, void **, char *); +#else +extern char *_SWIG_GetPtr(CPerlObj *, SV *, void **, char *); +#define SWIG_GetPtr(a,b,c) _SWIG_GetPtr(pPerl,a,b,c) +#endif + +#else + +#ifdef SWIG_GLOBAL +#define SWIGSTATICRUNTIME(a) SWIGEXPORT(a) +#else +#define SWIGSTATICRUNTIME(a) static a +#endif + +/* These are internal variables. Should be static */ + +typedef struct SwigPtrType { + char *name; + int len; + void *(*cast)(void *); + struct SwigPtrType *next; +} SwigPtrType; + +/* Pointer cache structure */ + +typedef struct { + int stat; /* Status (valid) bit */ + SwigPtrType *tp; /* Pointer to type structure */ + char name[256]; /* Given datatype name */ + char mapped[256]; /* Equivalent name */ +} SwigCacheType; + +static int SwigPtrMax = 64; /* Max entries that can be currently held */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ +static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ +static int SwigStart[256]; /* Table containing starting positions */ + +/* Cached values */ + +#define SWIG_CACHESIZE 8 +#define SWIG_CACHEMASK 0x7 +static SwigCacheType SwigCache[SWIG_CACHESIZE]; +static int SwigCacheIndex = 0; +static int SwigLastCache = 0; + +/* Sort comparison function */ +static int swigsort(const void *data1, const void *data2) { + SwigPtrType *d1 = (SwigPtrType *) data1; + SwigPtrType *d2 = (SwigPtrType *) data2; + return strcmp(d1->name,d2->name); +} + +/* Binary Search function */ +static int swigcmp(const void *key, const void *data) { + char *k = (char *) key; + SwigPtrType *d = (SwigPtrType *) data; + return strncmp(k,d->name,d->len); +} + +/* Register a new datatype with the type-checker */ + +#ifndef PERL_OBJECT +SWIGSTATICRUNTIME(void) +SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { +#else +#define SWIG_RegisterMapping(a,b,c) _SWIG_RegisterMapping(pPerl, a,b,c) +SWIGSTATICRUNTIME(void) +_SWIG_RegisterMapping(CPerlObj *pPerl, char *origtype, char *newtype, void *(*cast)(void *)) { +#endif + + int i; + SwigPtrType *t = 0, *t1; + + if (!SwigPtrTable) { + SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); + SwigPtrN = 0; + } + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTable = (SwigPtrType *) realloc(SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); + } + for (i = 0; i < SwigPtrN; i++) + if (strcmp(SwigPtrTable[i].name,origtype) == 0) { + t = &SwigPtrTable[i]; + break; + } + if (!t) { + t = &SwigPtrTable[SwigPtrN]; + t->name = origtype; + t->len = strlen(t->name); + t->cast = 0; + t->next = 0; + SwigPtrN++; + } + while (t->next) { + if (strcmp(t->name,newtype) == 0) { + if (cast) t->cast = cast; + return; + } + t = t->next; + } + t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + t1->name = newtype; + t1->len = strlen(t1->name); + t1->cast = cast; + t1->next = 0; + t->next = t1; + SwigPtrSort = 0; +} + +/* Make a pointer value string */ + +SWIGSTATICRUNTIME(void) +SWIG_MakePtr(char *_c, const void *_ptr, char *type) { + static char _hex[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + unsigned long _p, _s; + char _result[20], *_r; /* Note : a 64-bit hex number = 16 digits */ + _r = _result; + _p = (unsigned long) _ptr; + if (_p > 0) { + while (_p > 0) { + _s = _p & 0xf; + *(_r++) = _hex[_s]; + _p = _p >> 4; + } + *_r = '_'; + while (_r >= _result) + *(_c++) = *(_r--); + } else { + strcpy (_c, "NULL"); + } + if (_ptr) + strcpy (_c, type); +} + +/* Function for getting a pointer value */ + +#ifndef PERL_OBJECT +SWIGSTATICRUNTIME(char *) +SWIG_GetPtr(SV *sv, void **ptr, char *_t) +#else +#define SWIG_GetPtr(a,b,c) _SWIG_GetPtr(pPerl,a,b,c) +SWIGSTATICRUNTIME(char *) +_SWIG_GetPtr(CPerlObj *pPerl, SV *sv, void **ptr, char *_t) +#endif +{ + char temp_type[256]; + char *name,*_c; + int len,i,start,end; + IV tmp; + SwigPtrType *sp,*tp; + SwigCacheType *cache; + + /* If magical, apply more magic */ + + if (SvGMAGICAL(sv)) + mg_get(sv); + + /* Check to see if this is an object */ + if (sv_isobject(sv)) { + SV *tsv = (SV*) SvRV(sv); + if ((SvTYPE(tsv) == SVt_PVHV)) { + MAGIC *mg; + if (SvMAGICAL(tsv)) { + mg = mg_find(tsv,'P'); + if (mg) { + SV *rsv = mg->mg_obj; + if (sv_isobject(rsv)) { + tmp = SvIV((SV*)SvRV(rsv)); + } + } + } else { + return "Not a valid pointer value"; + } + } else { + tmp = SvIV((SV*)SvRV(sv)); + } + if (!_t) { + *(ptr) = (void *) tmp; + return (char *) 0; + } + } else if (! SvOK(sv)) { /* Check for undef */ + *(ptr) = (void *) 0; + return (char *) 0; + } else if (SvTYPE(sv) == SVt_RV) { /* Check for NULL pointer */ + *(ptr) = (void *) 0; + if (!SvROK(sv)) + return (char *) 0; + else + return "Not a valid pointer value"; + } else { /* Don't know what it is */ + *(ptr) = (void *) 0; + return "Not a valid pointer value"; + } + if (_t) { + /* Now see if the types match */ + + if (!sv_isa(sv,_t)) { + _c = HvNAME(SvSTASH(SvRV(sv))); + if (!SwigPtrSort) { + qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); + for (i = 0; i < 256; i++) { + SwigStart[i] = SwigPtrN; + } + for (i = SwigPtrN-1; i >= 0; i--) { + SwigStart[SwigPtrTable[i].name[0]] = i; + } + for (i = 255; i >= 1; i--) { + if (SwigStart[i-1] > SwigStart[i]) + SwigStart[i-1] = SwigStart[i]; + } + SwigPtrSort = 1; + for (i = 0; i < SWIG_CACHESIZE; i++) + SwigCache[i].stat = 0; + } + /* First check cache for matches. Uses last cache value as starting point */ + cache = &SwigCache[SwigLastCache]; + for (i = 0; i < SWIG_CACHESIZE; i++) { + if (cache->stat) { + if (strcmp(_t,cache->name) == 0) { + if (strcmp(_c,cache->mapped) == 0) { + cache->stat++; + *ptr = (void *) tmp; + if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); + return (char *) 0; + } + } + } + SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; + if (!SwigLastCache) cache = SwigCache; + else cache++; + } + + start = SwigStart[_t[0]]; + end = SwigStart[_t[0]+1]; + sp = &SwigPtrTable[start]; + while (start < end) { + if (swigcmp(_t,sp) == 0) break; + sp++; + start++; + } + if (start > end) sp = 0; + while (start <= end) { + if (swigcmp(_t,sp) == 0) { + name = sp->name; + len = sp->len; + tp = sp->next; + while(tp) { + if (tp->len >= 255) { + return _c; + } + strcpy(temp_type,tp->name); + strncat(temp_type,_t+len,255-tp->len); + if (sv_isa(sv,temp_type)) { + /* Get pointer value */ + *ptr = (void *) tmp; + if (tp->cast) *ptr = (*(tp->cast))(*ptr); + + strcpy(SwigCache[SwigCacheIndex].mapped,_c); + strcpy(SwigCache[SwigCacheIndex].name,_t); + SwigCache[SwigCacheIndex].stat = 1; + SwigCache[SwigCacheIndex].tp = tp; + SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; + return (char *) 0; + } + tp = tp->next; + } + } + sp++; + start++; + } + /* Didn't find any sort of match for this data. + Get the pointer value and return the received type */ + *ptr = (void *) tmp; + return _c; + } else { + /* Found a match on the first try. Return pointer value */ + *ptr = (void *) tmp; + return (char *) 0; + } + } + *ptr = (void *) tmp; + return (char *) 0; +} + +#endif +#ifdef __cplusplus +} +#endif + + + + + + diff --git a/wxPython/wxSWIG/swig_lib/perl5/perl5mg.swg b/wxPython/wxSWIG/swig_lib/perl5/perl5mg.swg new file mode 100644 index 0000000000..d5a0cfbc11 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/perl5/perl5mg.swg @@ -0,0 +1,19 @@ +/* Magic variable code */ +#ifndef PERL_OBJECT +#define swig_create_magic(s,a,b,c) _swig_create_magic(s,a,b,c) +static void _swig_create_magic(SV *sv, char *name, int (*set)(SV *, MAGIC *), int (*get)(SV *,MAGIC *)) { +#else +#define swig_create_magic(s,a,b,c) _swig_create_magic(pPerl,s,a,b,c) +static void _swig_create_magic(CPerlObj *pPerl, SV *sv, char *name, int (CPerlObj::*set)(SV *, MAGIC *), int (CPerlObj::*get)(SV *, MAGIC *)) { +#endif + MAGIC *mg; + sv_magic(sv,sv,'U',name,strlen(name)); + mg = mg_find(sv,'U'); + mg->mg_virtual = (MGVTBL *) malloc(sizeof(MGVTBL)); + mg->mg_virtual->svt_get = get; + mg->mg_virtual->svt_set = set; + mg->mg_virtual->svt_len = 0; + mg->mg_virtual->svt_clear = 0; + mg->mg_virtual->svt_free = 0; +} + diff --git a/wxPython/wxSWIG/swig_lib/perl5/perlmain.i b/wxPython/wxSWIG/swig_lib/perl5/perlmain.i new file mode 100644 index 0000000000..b6f88b926d --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/perl5/perlmain.i @@ -0,0 +1,80 @@ +// $Header$ +// Code to statically rebuild perl5. +// + +#ifdef AUTODOC +%subsection "perlmain.i" +%text %{ +This module provides support for building a new version of the +Perl executable. This will be necessary on systems that do +not support shared libraries and may be necessary with C++ +extensions. + +This module may only build a stripped down version of the +Perl executable. Thus, it may be necessary (or desirable) +to hand-edit this file for your particular application. To +do this, simply copy this file from swig_lib/perl5/perlmain.i +to your working directory and make the appropriate modifications. + +This library file works with Perl 5.003. It may work with earlier +versions, but it hasn't been tested. As far as I know, this +library is C++ safe. +%} +#endif + +%{ + +static void xs_init _((void)); +static PerlInterpreter *my_perl; + +int perl_eval(char *string) { + char *argv[2]; + argv[0] = string; + argv[1] = (char *) 0; + return perl_call_argv("eval",0,argv); +} + +int +main(int argc, char **argv, char **env) +{ + int exitstatus; + + my_perl = perl_alloc(); + if (!my_perl) + exit(1); + perl_construct( my_perl ); + + exitstatus = perl_parse( my_perl, xs_init, argc, argv, (char **) NULL ); + if (exitstatus) + exit( exitstatus ); + + /* Initialize all of the module variables */ + + exitstatus = perl_run( my_perl ); + + perl_destruct( my_perl ); + perl_free( my_perl ); + + exit( exitstatus ); +} + +/* Register any extra external extensions */ + +/* Do not delete this line--writemain depends on it */ +/* EXTERN_C void boot_DynaLoader _((CV* cv)); */ + +static void +xs_init() +{ +/* dXSUB_SYS; */ + char *file = __FILE__; + { + /* newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); */ + newXS(SWIG_name, SWIG_init, file); +#ifdef SWIGMODINIT + SWIGMODINIT +#endif + } +} + +%} diff --git a/wxPython/wxSWIG/swig_lib/perl5/ptrlang.i b/wxPython/wxSWIG/swig_lib/perl5/ptrlang.i new file mode 100644 index 0000000000..a1bc88e8db --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/perl5/ptrlang.i @@ -0,0 +1,650 @@ +// +// SWIG pointer conversion and utility library +// +// Dave Beazley +// April 19, 1997 +// +// Perl5 specific implementation. This file is included +// by the file ../pointer.i + +%{ + +#ifdef WIN32 +#undef isspace +#define isspace(c) (c == ' ') +#endif + +/*------------------------------------------------------------------ + ptrcast(value,type) + + Constructs a new pointer value. Value may either be a string + or an integer. Type is a string corresponding to either the + C datatype or mangled datatype. + + ptrcast(0,"Vector *") + or + ptrcast(0,"Vector_p") + ------------------------------------------------------------------ */ +#ifdef PERL_OBJECT +static SV *_ptrcast(CPerlObj *pPerl, SV *_PTRVALUE, char *type) { +#define ptrcast(a,b) _ptrcast(pPerl,a,b) +#else +static SV *_ptrcast(SV *_PTRVALUE, char *type) { +#define ptrcast(a,b) _ptrcast(a,b) +#endif + char *r,*s; + void *ptr; + SV *obj; + char *typestr,*c; + + /* Produce a "mangled" version of the type string. */ + + typestr = (char *) malloc(strlen(type)+20); + + /* Go through and munge the typestring */ + + r = typestr; + c = type; + while (*c) { + if (!isspace(*c)) { + if ((*c == '*') || (*c == '&')) { + strcpy(r,"Ptr"); + r+=3; + } else *(r++) = *c; + } + c++; + } + *(r++) = 0; + + /* Check to see if the input value is an integer */ + if (SvIOK(_PTRVALUE)) { + ptr = (void *) SvIV(_PTRVALUE); + /* Received a numerical value. Make a pointer out of it */ + obj = sv_newmortal(); + sv_setref_pv(obj,typestr,ptr); + } else if (sv_isobject(_PTRVALUE)) { + /* Have a real pointer value now. Try to strip out the pointer value */ + /* Now extract the pointer value */ + if (!SWIG_GetPtr(_PTRVALUE,&ptr,0)) { + obj = sv_newmortal(); + sv_setref_pv(obj,typestr,ptr); + } + } else { + croak("ptrcast(). Not a reference."); + } + free(typestr); + return obj; +} + + + +/*------------------------------------------------------------------ + ptrvalue(ptr,type = 0) + + Attempts to dereference a pointer value. If type is given, it + will try to use that type. Otherwise, this function will attempt + to "guess" the proper datatype by checking against all of the + builtin C datatypes. + ------------------------------------------------------------------ */ + +#ifdef PERL_OBJECT +static SV *_ptrvalue(CPerlObj *pPerl,SV *_PTRVALUE, int index, char *type) { +#define ptrvalue(a,b,c) _ptrvalue(pPerl,a,b,c) +#else +static SV *_ptrvalue(SV *_PTRVALUE, int index, char *type) { +#define ptrvalue(a,b,c) _ptrvalue(a,b,c) +#endif + + void *ptr; + SV *obj = 0; + + + if (SWIG_GetPtr(_PTRVALUE,&ptr,0)) { + croak("Type error it ptrvalue. Argument is not a valid pointer value."); + } else { + /* If no datatype was passed, try a few common datatypes first */ + if (!type) { + + /* No datatype was passed. Type to figure out if it's a common one */ + + if (!SWIG_GetPtr(_PTRVALUE,&ptr,"intPtr")) { + type = "int"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"doublePtr")) { + type = "double"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"shortPtr")) { + type = "short"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"longPtr")) { + type = "long"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"floatPtr")) { + type = "float"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"charPtr")) { + type = "char"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"charPtrPtr")) { + type = "char *"; + } else { + type = "unknown"; + } + } + + if (!ptr) { + croak("Unable to dereference NULL pointer."); + return 0; + } + + /* Now we have a datatype. Try to figure out what to do about it */ + if (strcmp(type,"int") == 0) { + obj = sv_newmortal(); + sv_setiv(obj,(IV) *(((int *) ptr) + index)); + } else if (strcmp(type,"double") == 0) { + obj = sv_newmortal(); + sv_setnv(obj,(double) *(((double *) ptr)+index)); + } else if (strcmp(type,"short") == 0) { + obj = sv_newmortal(); + sv_setiv(obj,(IV) *(((short *) ptr) + index)); + } else if (strcmp(type,"long") == 0) { + obj = sv_newmortal(); + sv_setiv(obj,(IV) *(((long *) ptr) + index)); + } else if (strcmp(type,"float") == 0) { + obj = sv_newmortal(); + sv_setnv(obj,(double) *(((float *) ptr)+index)); + } else if (strcmp(type,"char") == 0) { + obj = sv_newmortal(); + sv_setpv(obj,((char *) ptr)+index); + } else if (strcmp(type,"char *") == 0) { + char *c = *(((char **) ptr)+index); + obj = sv_newmortal(); + if (c) + sv_setpv(obj,c); + else + sv_setpv(obj,"NULL"); + } else { + croak("Unable to dereference unsupported datatype."); + obj = 0; + } + } + return obj; +} + +/*------------------------------------------------------------------ + ptrcreate(type,value = 0,numelements = 1) + + Attempts to create a new object of given type. Type must be + a basic C datatype. Will not create complex objects. + ------------------------------------------------------------------ */ +#ifdef PERL_OBJECT +static SV *_ptrcreate(CPerlObj *pPerl, char *type, SV *value, int numelements) { +#define ptrcreate(a,b,c) _ptrcreate(pPerl,a,b,c) +#else +static SV *_ptrcreate(char *type, SV *value, int numelements) { +#define ptrcreate(a,b,c) _ptrcreate(a,b,c) +#endif + + void *ptr; + SV *obj; + int sz; + char *cast; + char temp[40]; + + /* Check the type string against a variety of possibilities */ + + if (strcmp(type,"int") == 0) { + sz = sizeof(int)*numelements; + cast = "intPtr"; + } else if (strcmp(type,"short") == 0) { + sz = sizeof(short)*numelements; + cast = "shortPtr"; + } else if (strcmp(type,"long") == 0) { + sz = sizeof(long)*numelements; + cast = "longPtr"; + } else if (strcmp(type,"double") == 0) { + sz = sizeof(double)*numelements; + cast = "doublePtr"; + } else if (strcmp(type,"float") == 0) { + sz = sizeof(float)*numelements; + cast = "floatPtr"; + } else if (strcmp(type,"char") == 0) { + sz = sizeof(char)*numelements; + cast = "charPtr"; + } else if (strcmp(type,"char *") == 0) { + sz = sizeof(char *)*(numelements+1); + cast = "charPtrPtr"; + } else if (strcmp(type,"void") == 0) { + sz = numelements; + cast = "voidPtr"; + } else { + croak("Unable to create unknown datatype."); + return 0; + } + + /* Create the new object */ + + ptr = (void *) malloc(sz); + if (!ptr) { + croak("Out of memory in ptrcreate."); + return 0; + } + + /* Now try to set its default value */ + + if (value) { + if (strcmp(type,"int") == 0) { + int *ip,i,ivalue; + ivalue = (int) SvIV(value); + ip = (int *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"short") == 0) { + short *ip,ivalue; + int i; + ivalue = (short) SvIV(value); + ip = (short *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"long") == 0) { + long *ip,ivalue; + int i; + ivalue = (long) SvIV(value); + ip = (long *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"double") == 0) { + double *ip,ivalue; + int i; + ivalue = (double) SvNV(value); + ip = (double *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"float") == 0) { + float *ip,ivalue; + int i; + ivalue = (float) SvNV(value); + ip = (float *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"char") == 0) { + char *ip,*ivalue; + ivalue = (char *) SvPV(value,PL_na); + ip = (char *) ptr; + strncpy(ip,ivalue,numelements-1); + } else if (strcmp(type,"char *") == 0) { + char **ip, *ivalue; + int i; + ivalue = (char *) SvPV(value,PL_na); + ip = (char **) ptr; + for (i = 0; i < numelements; i++) { + if (ivalue) { + ip[i] = (char *) malloc(strlen(ivalue)+1); + strcpy(ip[i],ivalue); + } else { + ip[i] = 0; + } + } + ip[numelements] = 0; + } + } + /* Create the pointer value */ + + SWIG_MakePtr(temp,ptr,cast); + obj = sv_newmortal(); + sv_setref_pv(obj,cast,ptr); + return obj; +} + +/*------------------------------------------------------------------ + ptrset(ptr,value,index = 0,type = 0) + + Attempts to set the value of a pointer variable. If type is + given, we will use that type. Otherwise, we'll guess the datatype. + ------------------------------------------------------------------ */ + +#ifdef PERL_OBJECT +static void _ptrset(CPerlObj *pPerl,SV *_PTRVALUE, SV *value, int index, char *type) { +#define ptrset(a,b,c,d) _ptrset(pPerl,a,b,c,d) +#else +static void _ptrset(SV *_PTRVALUE, SV *value, int index, char *type) { +#define ptrset(a,b,c,d) _ptrset(a,b,c,d) +#endif + void *ptr; + SV *obj; + + if (SWIG_GetPtr(_PTRVALUE,&ptr,0)) { + croak("Type error in ptrset. Argument is not a valid pointer value."); + return; + } + + /* If no datatype was passed, try a few common datatypes first */ + + if (!type) { + + /* No datatype was passed. Type to figure out if it's a common one */ + + if (!SWIG_GetPtr(_PTRVALUE,&ptr,"intPtr")) { + type = "int"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"doublePtr")) { + type = "double"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"shortPtr")) { + type = "short"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"longPtr")) { + type = "long"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"floatPtr")) { + type = "float"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"charPtr")) { + type = "char"; + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"charPtrPtr")) { + type = "char *"; + } else { + type = "unknown"; + } + } + + if (!ptr) { + croak("Unable to set NULL pointer."); + return; + } + + /* Now we have a datatype. Try to figure out what to do about it */ + if (strcmp(type,"int") == 0) { + *(((int *) ptr)+index) = (int) SvIV(value); + } else if (strcmp(type,"double") == 0) { + *(((double *) ptr)+index) = (double) SvNV(value); + } else if (strcmp(type,"short") == 0) { + *(((short *) ptr)+index) = (short) SvIV(value); + } else if (strcmp(type,"long") == 0) { + *(((long *) ptr)+index) = (long) SvIV(value); + } else if (strcmp(type,"float") == 0) { + *(((float *) ptr)+index) = (float) SvNV(value); + } else if (strcmp(type,"char") == 0) { + char *c = SvPV(value,PL_na); + strcpy(((char *) ptr)+index, c); + } else if (strcmp(type,"char *") == 0) { + char *c = SvPV(value,PL_na); + char **ca = (char **) ptr; + if (ca[index]) free(ca[index]); + if (strcmp(c,"NULL") == 0) { + ca[index] = 0; + } else { + ca[index] = (char *) malloc(strlen(c)+1); + strcpy(ca[index],c); + } + } else { + croak("Unable to set unsupported datatype."); + return; + } +} + +/*------------------------------------------------------------------ + ptradd(ptr,offset) + + Adds a value to an existing pointer value. Will do a type-dependent + add for basic datatypes. For other datatypes, will do a byte-add. + ------------------------------------------------------------------ */ + +#ifdef PERL_OBJECT +static SV *_ptradd(CPerlObj *pPerl, SV *_PTRVALUE, int offset) { +#define ptradd(a,b) _ptradd(pPerl,a,b) +#else +static SV *_ptradd(SV *_PTRVALUE, int offset) { +#define ptradd(a,b) _ptradd(a,b) +#endif + + void *ptr,*junk; + SV *obj; + char *type; + + /* Try to handle a few common datatypes first */ + + if (!SWIG_GetPtr(_PTRVALUE,&ptr,"intPtr")) { + ptr = (void *) (((int *) ptr) + offset); + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"doublePtr")) { + ptr = (void *) (((double *) ptr) + offset); + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"shortPtr")) { + ptr = (void *) (((short *) ptr) + offset); + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"longPtr")) { + ptr = (void *) (((long *) ptr) + offset); + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"floatPtr")) { + ptr = (void *) (((float *) ptr) + offset); + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,"charPtr")) { + ptr = (void *) (((char *) ptr) + offset); + } else if (!SWIG_GetPtr(_PTRVALUE,&ptr,0)) { + ptr = (void *) (((char *) ptr) + offset); + } else { + croak("Type error in ptradd. Argument is not a valid pointer value."); + return 0; + } + type = SWIG_GetPtr(_PTRVALUE,&junk,"INVALID POINTER"); + obj = sv_newmortal(); + sv_setref_pv(obj,type,ptr); + return obj; +} + +/*------------------------------------------------------------------ + ptrmap(type1,type2) + + Allows a mapping between type1 and type2. (Like a typedef) + ------------------------------------------------------------------ */ + +#ifdef PERL_OBJECT +static void _ptrmap(CPerlObj *pPerl,char *type1, char *type2) { +#define ptrmap(a,b) _ptrmap(pPerl,a,b) +#else +static void _ptrmap(char *type1, char *type2) { +#define ptrmap(a,b) _ptrmap(a,b) +#endif + char *typestr1,*typestr2,*c,*r; + /* Produce a "mangled" version of the type string. */ + + typestr1 = (char *) malloc(strlen(type1)+20); + + + /* Go through and munge the typestring */ + + r = typestr1; + *(r++) = '_'; + c = type1; + + while (*c) { + if (!isspace(*c)) { + if ((*c == '*') || (*c == '&')) { + strcpy(r,"Ptr"); + r+=3; + } + else *(r++) = *c; + } + c++; + } + *(r++) = 0; + + typestr2 = (char *) malloc(strlen(type2)+20); + + /* Go through and munge the typestring */ + + r = typestr2; + *(r++) = '_'; + c = type2; + while (*c) { + if (!isspace(*c)) { + if ((*c == '*') || (*c == '&')) { + strcpy(r,"Ptr"); + r+=3; + } + else *(r++) = *c; + } + c++; + } + *(r++) = 0; + SWIG_RegisterMapping(typestr1,typestr2,0); + SWIG_RegisterMapping(typestr2,typestr1,0); +} + +/*------------------------------------------------------------------ + ptrfree(ptr) + + Destroys a pointer value + ------------------------------------------------------------------ */ +#ifdef PERL_OBJECT +void _ptrfree(CPerlObj *pPerl, SV *_PTRVALUE) { +#define ptrfree(a) _ptrfree(pPerl, a) +#else +void _ptrfree(SV *_PTRVALUE) { +#define ptrfree(a) _ptrfree(a) +#endif + + void *ptr, *junk; + + if (SWIG_GetPtr(_PTRVALUE,&ptr,0)) { + croak("Type error in ptrfree. Argument is not a valid pointer value."); + return; + } + + /* Check to see if this pointer is a char ** */ + if (!SWIG_GetPtr(_PTRVALUE,&junk,"charPtrPtr")) { + char **c = (char **) ptr; + if (c) { + int i = 0; + while (c[i]) { + free(c[i]); + i++; + } + } + } + if (ptr) + free((char *) ptr); +} + +%} + +%typemap(perl5,in) SV *ptr, SV *value { + $target = $source; +} + + +%typemap(perl5,out) SV *ptrcast, + SV *ptrvalue, + SV *ptrcreate, + SV *ptradd +{ + $target = $source; + argvi++; +} + +%typemap(perl5,ret) int ptrset { + if ($source == -1) return NULL; +} + +SV *ptrcast(SV *ptr, char *type); +// Casts a pointer ptr to a new datatype given by the string type. +// type may be either the SWIG generated representation of a datatype +// or the C representation. For example : +// +// ptrcast($ptr,"doublePtr"); # Perl5 representation +// ptrcast($ptr,"double *"); # C representation +// +// A new pointer value is returned. ptr may also be an integer +// value in which case the value will be used to set the pointer +// value. For example : +// +// $a = ptrcast(0,"VectorPtr"); +// +// Will create a NULL pointer of type "VectorPtr" +// +// The casting operation is sensitive to formatting. As a result, +// "double *" is different than "double*". As a result of thumb, +// there should always be exactly one space between the C datatype +// and any pointer specifiers (*). + +SV *ptrvalue(SV *ptr, int index = 0, char *type = 0); +// Returns the value that a pointer is pointing to (ie. dereferencing). +// The type is automatically inferred by the pointer type--thus, an +// integer pointer will return an integer, a double will return a double, +// and so on. The index and type fields are optional parameters. When +// an index is specified, this function returns the value of ptr[index]. +// This allows array access. When a type is specified, it overrides +// the given pointer type. Examples : +// +// ptrvalue($a) # Returns the value *a +// ptrvalue($a,10) # Returns the value a[10] +// ptrvalue($a,10,"double") # Returns a[10] assuming a is a double * + + +void ptrset(SV *ptr, SV *value, int index = 0, char *type = 0); +// Sets the value pointed to by a pointer. The type is automatically +// inferred from the pointer type so this function will work for +// integers, floats, doubles, etc... The index and type fields are +// optional. When an index is given, it provides array access. When +// type is specified, it overrides the given pointer type. Examples : +// +// ptrset($a,3) # Sets the value *a = 3 +// ptrset($a,3,10) # Sets a[10] = 3 +// ptrset($a,3,10,"int") # Sets a[10] = 3 assuming a is a int * + + +SV *ptrcreate(char *type, SV *value = 0, int nitems = 1); +// Creates a new object and returns a pointer to it. This function +// can be used to create various kinds of objects for use in C functions. +// type specifies the basic C datatype to create and value is an +// optional parameter that can be used to set the initial value of the +// object. nitems is an optional parameter that can be used to create +// an array. This function results in a memory allocation using +// malloc(). Examples : +// +// $a = ptrcreate("double") # Create a new double, return pointer +// $a = ptrcreate("int",7) # Create an integer, set value to 7 +// $a = ptrcreate("int",0,1000) # Create an integer array with initial +// # values all set to zero +// +// This function only recognizes a few common C datatypes as listed below : +// +// int, short, long, float, double, char, char *, void +// +// All other datatypes will result in an error. However, other +// datatypes can be created by using the ptrcast function. For +// example: +// +// $a = ptrcast(ptrcreate("int",0,100),"unsigned int *") + + +void ptrfree(SV *ptr); +// Destroys the memory pointed to by ptr. This function calls free() +// and should only be used with objects created by ptrcreate(). Since +// this function calls free, it may work with other objects, but this +// is generally discouraged unless you absolutely know what you're +// doing. + +SV *ptradd(SV *ptr, int offset); +// Adds a value to the current pointer value. For the C datatypes of +// int, short, long, float, double, and char, the offset value is the +// number of objects and works in exactly the same manner as in C. For +// example, the following code steps through the elements of an array +// +// $a = ptrcreate("double",0,100); # Create an array double a[100] +// $b = $a; +// for ($i = 0; $i < 100; $i++) { +// ptrset($b,0.0025*$i); # set *b = 0.0025*i +// $b = ptradd($b,1); # b++ (go to next double) +// } +// +// In this case, adding one to b goes to the next double. +// +// For all other datatypes (including all complex datatypes), the +// offset corresponds to bytes. This function does not perform any +// bounds checking and negative offsets are perfectly legal. + +void ptrmap(char *type1, char *type2); +// This is a rarely used function that performs essentially the same +// operation as a C typedef. To manage datatypes at run-time, SWIG +// modules manage an internal symbol table of type mappings. This +// table keeps track of which types are equivalent to each other. The +// ptrmap() function provides a mechanism for scripts to add symbols +// to this table. For example : +// +// ptrmap("doublePtr","RealPtr"); +// +// would make the types "doublePtr" and "RealPtr" equivalent to each +// other. Pointers of either type could now be used interchangably. +// +// Normally this function is not needed, but it can be used to +// circumvent SWIG's normal type-checking behavior or to work around +// weird type-handling problems. + + + diff --git a/wxPython/wxSWIG/swig_lib/perl5/typemaps.i b/wxPython/wxSWIG/swig_lib/perl5/typemaps.i new file mode 100644 index 0000000000..ff0b5ae39a --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/perl5/typemaps.i @@ -0,0 +1,475 @@ +// +// SWIG Typemap library +// Dave Beazley +// May 5, 1997 +// +// Perl5 implementation +// +// This library provides standard typemaps for modifying SWIG's behavior. +// With enough entries in this file, I hope that very few people actually +// ever need to write a typemap. +// + +#ifdef AUTODOC +%section "Typemap Library (Perl 5)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 +%text %{ +%include typemaps.i + +The SWIG typemap library provides a language independent mechanism for +supporting output arguments, input values, and other C function +calling mechanisms. The primary use of the library is to provide a +better interface to certain C function--especially those involving +pointers. +%} + +#endif + +// ------------------------------------------------------------------------ +// Pointer handling +// +// These mappings provide support for input/output arguments and common +// uses for C/C++ pointers. +// ------------------------------------------------------------------------ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + + +#ifdef AUTODOC +%subsection "Input Methods" + +%text %{ +The following methods can be applied to turn a pointer into a simple +"input" value. That is, instead of passing a pointer to an object, +you would use a real value instead. + + int *INPUT + short *INPUT + long *INPUT + unsigned int *INPUT + unsigned short *INPUT + unsigned long *INPUT + unsigned char *INPUT + float *INPUT + double *INPUT + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + %include typemaps.i + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +%} +#endif + +%typemap(perl5,in) double *INPUT(double temp) +{ + temp = (double) SvNV($source); + $target = &temp; +} + +%typemap(perl5,in) float *INPUT(float temp) +{ + temp = (float) SvNV($source); + $target = &temp; +} + +%typemap(perl5,in) int *INPUT(int temp) +{ + temp = (int) SvIV($source); + $target = &temp; +} + +%typemap(perl5,in) short *INPUT(short temp) +{ + temp = (short) SvIV($source); + $target = &temp; +} + +%typemap(perl5,in) long *INPUT(long temp) +{ + temp = (long) SvIV($source); + $target = &temp; +} +%typemap(perl5,in) unsigned int *INPUT(unsigned int temp) +{ + temp = (unsigned int) SvIV($source); + $target = &temp; +} +%typemap(perl5,in) unsigned short *INPUT(unsigned short temp) +{ + temp = (unsigned short) SvIV($source); + $target = &temp; +} +%typemap(perl5,in) unsigned long *INPUT(unsigned long temp) +{ + temp = (unsigned long) SvIV($source); + $target = &temp; +} +%typemap(perl5,in) unsigned char *INPUT(unsigned char temp) +{ + temp = (unsigned char) SvIV($source); + $target = &temp; +} + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + + +#ifdef AUTODOC +%subsection "Output Methods" + +%text %{ +The following methods can be applied to turn a pointer into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. In the case of +multiple output values, functions will return a Perl array. + + int *OUTPUT + short *OUTPUT + long *OUTPUT + unsigned int *OUTPUT + unsigned short *OUTPUT + unsigned long *OUTPUT + unsigned char *OUTPUT + float *OUTPUT + double *OUTPUT + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters).K: + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include typemaps.i + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Perl output of the function would be an array containing both +output values. + +%} + +#endif + +// Force the argument to be ignored. + +%typemap(perl5,ignore) int *OUTPUT(int temp), + short *OUTPUT(short temp), + long *OUTPUT(long temp), + unsigned int *OUTPUT(unsigned int temp), + unsigned short *OUTPUT(unsigned short temp), + unsigned long *OUTPUT(unsigned long temp), + unsigned char *OUTPUT(unsigned char temp), + float *OUTPUT(float temp), + double *OUTPUT(double temp) +{ + $target = &temp; +} + +%typemap(perl5,argout) int *OUTPUT, + short *OUTPUT, + long *OUTPUT, + unsigned int *OUTPUT, + unsigned short *OUTPUT, + unsigned long *OUTPUT, + unsigned char *OUTPUT +{ + if (argvi >= items) { + EXTEND(sp,1); + } + $target = sv_newmortal(); + sv_setiv($target,(IV) *($source)); + argvi++; +} + +%typemap(perl5,argout) float *OUTPUT, + double *OUTPUT +{ + if (argvi >= items) { + EXTEND(sp,1); + } + $target = sv_newmortal(); + sv_setnv($target,(double) *($source)); + argvi++; +} + +// BOTH +// Mappings for an argument that is both an input and output +// parameter + + +#ifdef AUTODOC +%subsection "Input/Output Methods" + +%text %{ +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned in the form of a Tcl list. + + int *BOTH + short *BOTH + long *BOTH + unsigned int *BOTH + unsigned short *BOTH + unsigned long *BOTH + unsigned char *BOTH + float *BOTH + double *BOTH + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include typemaps.i + void neg(double *BOTH); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *BOTH { double *x }; + void neg(double *x); + +Unlike C, this mapping does not directly modify the input value. +Rather, the modified input value shows up as the return value of the +function. Thus, to apply this function to a Perl variable you might +do this : + + $x = neg($x); + +%} + +#endif + +%typemap(perl5,in) int *BOTH = int *INPUT; +%typemap(perl5,in) short *BOTH = short *INPUT; +%typemap(perl5,in) long *BOTH = long *INPUT; +%typemap(perl5,in) unsigned *BOTH = unsigned *INPUT; +%typemap(perl5,in) unsigned short *BOTH = unsigned short *INPUT; +%typemap(perl5,in) unsigned long *BOTH = unsigned long *INPUT; +%typemap(perl5,in) unsigned char *BOTH = unsigned char *INPUT; +%typemap(perl5,in) float *BOTH = float *INPUT; +%typemap(perl5,in) double *BOTH = double *INPUT; + +%typemap(perl5,argout) int *BOTH = int *OUTPUT; +%typemap(perl5,argout) short *BOTH = short *OUTPUT; +%typemap(perl5,argout) long *BOTH = long *OUTPUT; +%typemap(perl5,argout) unsigned *BOTH = unsigned *OUTPUT; +%typemap(perl5,argout) unsigned short *BOTH = unsigned short *OUTPUT; +%typemap(perl5,argout) unsigned long *BOTH = unsigned long *OUTPUT; +%typemap(perl5,argout) unsigned char *BOTH = unsigned char *OUTPUT; +%typemap(perl5,argout) float *BOTH = float *OUTPUT; +%typemap(perl5,argout) double *BOTH = double *OUTPUT; + +// REFERENCE +// Accept Perl references as pointers + + +#ifdef AUTODOC +%subsection "Reference Methods" + +%text %{ +The following methods make Perl references work like simple C +pointers. References can only be used for simple input/output +values, not C arrays however. It should also be noted that +REFERENCES are specific to Perl and not supported in other +scripting languages at this time. + + int *REFERENCE + short *REFERENCE + long *REFERENCE + unsigned int *REFERENCE + unsigned short *REFERENCE + unsigned long *REFERENCE + unsigned char *REFERENCE + float *REFERENCE + double *REFERENCE + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include typemaps.i + void neg(double *REFERENCE); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *REFERENCE { double *x }; + void neg(double *x); + +Unlike the BOTH mapping described previous, this approach directly +modifies the value of a Perl reference. Thus, you could use it +as follows : + + $x = 3; + neg(\$x); + print "$x\n"; # Should print out -3. +%} + +#endif + +%typemap(perl5,in) double *REFERENCE (double dvalue) +{ + SV *tempsv; + if (!SvROK($source)) { + croak("expected a reference"); + } + tempsv = SvRV($source); + if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { + printf("Received %d\n", SvTYPE(tempsv)); + croak("Expected a double reference."); + } + dvalue = SvNV(tempsv); + $target = &dvalue; +} + +%typemap(perl5,in) float *REFERENCE (float dvalue) +{ + SV *tempsv; + if (!SvROK($source)) { + croak("expected a reference"); + } + tempsv = SvRV($source); + if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { + croak("expected a double reference"); + } + dvalue = (float) SvNV(tempsv); + $target = &dvalue; +} + +%typemap(perl5,in) int *REFERENCE (int dvalue) +{ + SV *tempsv; + if (!SvROK($source)) { + croak("expected a reference"); + } + tempsv = SvRV($source); + if (!SvIOK(tempsv)) { + croak("expected a integer reference"); + } + dvalue = SvIV(tempsv); + $target = &dvalue; +} + +%typemap(perl5,in) short *REFERENCE (short dvalue) +{ + SV *tempsv; + if (!SvROK($source)) { + croak("expected a reference"); + } + tempsv = SvRV($source); + if (!SvIOK(tempsv)) { + croak("expected a integer reference"); + } + dvalue = (short) SvIV(tempsv); + $target = &dvalue; +} +%typemap(perl5,in) long *REFERENCE (long dvalue) +{ + SV *tempsv; + if (!SvROK($source)) { + croak("expected a reference"); + } + tempsv = SvRV($source); + if (!SvIOK(tempsv)) { + croak("expected a integer reference"); + } + dvalue = (long) SvIV(tempsv); + $target = &dvalue; +} +%typemap(perl5,in) unsigned int *REFERENCE (unsigned int dvalue) +{ + SV *tempsv; + if (!SvROK($source)) { + croak("expected a reference"); + } + tempsv = SvRV($source); + if (!SvIOK(tempsv)) { + croak("expected a integer reference"); + } + dvalue = (unsigned int) SvIV(tempsv); + $target = &dvalue; +} +%typemap(perl5,in) unsigned short *REFERENCE (unsigned short dvalue) +{ + SV *tempsv; + if (!SvROK($source)) { + croak("expected a reference"); + } + tempsv = SvRV($source); + if (!SvIOK(tempsv)) { + croak("expected a integer reference"); + } + dvalue = (unsigned short) SvIV(tempsv); + $target = &dvalue; +} +%typemap(perl5,in) unsigned long *REFERENCE (unsigned long dvalue) +{ + SV *tempsv; + if (!SvROK($source)) { + croak("expected a reference"); + } + tempsv = SvRV($source); + if (!SvIOK(tempsv)) { + croak("expected a integer reference"); + } + dvalue = (unsigned long) SvIV(tempsv); + $target = &dvalue; +} + +%typemap(perl5,argout) double *REFERENCE, + float *REFERENCE +{ + SV *tempsv; + tempsv = SvRV($arg); + sv_setnv(tempsv, (double) *$source); +} + +%typemap(perl5,argout) int *REFERENCE, + short *REFERENCE, + long *REFERENCE, + unsigned int *REFERENCE, + unsigned short *REFERENCE, + unsigned long *REFERENCE +{ + SV *tempsv; + tempsv = SvRV($arg); + sv_setiv(tempsv, (int) *$source); +} + +// -------------------------------------------------------------------- +// Special types +// +// -------------------------------------------------------------------- + + diff --git a/wxPython/wxSWIG/swig_lib/pointer.i b/wxPython/wxSWIG/swig_lib/pointer.i new file mode 100644 index 0000000000..04ad288445 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/pointer.i @@ -0,0 +1,58 @@ +// +// SWIG Pointer manipulation library +// +// This library can be used to manipulate C pointers. +%title "SWIG Pointer Library" + +%module pointer + + +%section "Pointer Handling Library",noinfo,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 + +%text %{ +%include pointer.i + +The pointer.i library provides run-time support for managing and +manipulating a variety of C/C++ pointer values. In particular, +you can create various kinds of objects and dereference common +pointer types. This is done through a common set of functions: + + ptrcast - Casts a pointer to a new type + ptrvalue - Dereferences a pointer + ptrset - Set the value of an object referenced by + a pointer. + ptrcreate - Create a new object and return a pointer. + ptrfree - Free the memory allocated by ptrcreate. + ptradd - Increment/decrement a pointer value. + ptrmap - Make two datatypes equivalent to each other. + (Is a runtime equivalent of typedef). + +When creating, dereferencing, or setting the value of pointer +variable, only the common C datatypes of int, short, long, float, +double, char, and char * are currently supported. Other +datatypes may generate an error. + +One of the more interesting aspects of this library is that +it operates with a wide range of datatypes. For example, +the "ptrvalue" function can dereference "double *", "int *", +"long *", "char *", and other datatypes. Since SWIG encodes +pointers with type information, this can be done transparently +and in most cases, you can dereference a pointer without +ever knowing what type it actually is. + +This library is primarily designed for utility, not high +performance (the dynamic determination of pointer types takes +more work than most normal wrapper functions). As a result, +you may achieve better performance by writing customized +"helper" functions if you're making lots of calls to these +functions in inner loops or other intensive operations. +%} + +// This library is a pretty hideous mess of language dependent code. +// Grab the implementation from the appropriate libray + +%include ptrlang.i + + + + diff --git a/wxPython/wxSWIG/swig_lib/python/Makefile b/wxPython/wxSWIG/swig_lib/python/Makefile new file mode 100644 index 0000000000..e8c546178d --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/Makefile @@ -0,0 +1,137 @@ +# Generated automatically from Makefile.in by configure. +# --------------------------------------------------------------- +# $Header$ +# SWIG Python Makefile +# +# This file can be used to build various Python extensions with SWIG. +# By default this file is set up for dynamic loading, but it can +# be easily customized for static extensions by modifying various +# portions of the file. +# +# SRCS = C source files +# CXXSRCS = C++ source files +# OBJCSRCS = Objective-C source files +# OBJS = Additional .o files (compiled previously) +# INTERFACE = SWIG interface file +# TARGET = Name of target module or executable +# +# Many portions of this file were created by the SWIG configure +# script and should already reflect your machine. +#---------------------------------------------------------------- + +SRCS = +CXXSRCS = +OBJCSRCS = +OBJS = +INTERFACE = +WRAPFILE = $(INTERFACE:.i=_wrap.c) +WRAPOBJ = $(INTERFACE:.i=_wrap.o) +TARGET = module.so # Use this kind of target for dynamic loading +#TARGET = mypython # Use this target for static linking + +prefix = /usr/local +exec_prefix = ${prefix} + +CC = cc +CXX = CC +OBJC = cc -Wno-import # -Wno-import needed for gcc +CFLAGS = +INCLUDE = +LIBS = + +# SWIG Options +# SWIG = location of the SWIG executable +# SWIGOPT = SWIG compiler options +# SWIGCC = Compiler used to compile the wrapper file + +SWIG = $(exec_prefix)/bin/swig +SWIGOPT = -python +SWIGCC = $(CC) + +# SWIG Library files. Uncomment if rebuilding the Python interpreter +#SWIGLIB = -lembed.i + +# Rules for creating .o files from source. + +COBJS = $(SRCS:.c=.o) +CXXOBJS = $(CXXSRCS:.cxx=.o) +OBJCOBJS = $(OBJCSRCS:.m=.o) +ALLOBJS = $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(OBJS) + +# Command that will be used to build the final extension. +BUILD = $(SWIGCC) + +# Uncomment the following if you are using dynamic loading +CCSHARED = +BUILD = ld -G + +# Uncomment the following if you are using dynamic loading with C++ and +# need to provide additional link libraries (this is not always required). + +#DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ + -L/usr/local/lib -lg++ -lstdc++ -lgcc + +# X11 installation (needed if rebuilding Python + tkinter) + +XLIB = -L/usr/openwin/lib -lX11 +XINCLUDE = -I/usr/openwin/include + +# Python installation + +PY_INCLUDE = -DHAVE_CONFIG_H -I/usr/local/include/python1.5 -I/usr/local/lib/python1.5/config +PY_LIB = /usr/local/lib/python1.5/config + +# Tcl installation. Needed if rebuilding Python with tkinter. + +TCL_INCLUDE = -I/usr/local/include +TCL_LIB = -L/usr/local/lib + +# Build libraries (needed for static builds) + +LIBM = -lm +LIBC = +SYSLIBS = $(LIBM) $(LIBC) -lsocket -lnsl -ldl + +# Build options (uncomment only one these) + +#TKINTER = $(TCL_LIB) -ltk -ltcl $(XLIB) +BUILD_LIBS = $(LIBS) # Dynamic loading +#BUILD_LIBS = $(PY_LIB) -lpython1.5 $(TKINTER) $(LIBS) $(SYSLIBS) + +# Compilation rules for non-SWIG components + +.SUFFIXES: .c .cxx .m + +.c.o: + $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + +.cxx.o: + $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDE) -c $< + +.m.o: + $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + + +# ---------------------------------------------------------------------- +# Rules for building the extension +# ---------------------------------------------------------------------- + +all: $(TARGET) + +# Convert the wrapper file into an object file + +$(WRAPOBJ) : $(WRAPFILE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDE) $(PY_INCLUDE) + +$(WRAPFILE) : $(INTERFACE) + $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) + +$(TARGET): $(WRAPOBJ) $(ALLOBJS) + $(BUILD) $(WRAPOBJ) $(ALLOBJS) $(BUILD_LIBS) -o $(TARGET) + +clean: + rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) + + + + diff --git a/wxPython/wxSWIG/swig_lib/python/Makefile.in b/wxPython/wxSWIG/swig_lib/python/Makefile.in new file mode 100644 index 0000000000..e9f553078a --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/Makefile.in @@ -0,0 +1,136 @@ +# --------------------------------------------------------------- +# $Header$ +# SWIG Python Makefile +# +# This file can be used to build various Python extensions with SWIG. +# By default this file is set up for dynamic loading, but it can +# be easily customized for static extensions by modifying various +# portions of the file. +# +# SRCS = C source files +# CXXSRCS = C++ source files +# OBJCSRCS = Objective-C source files +# OBJS = Additional .o files (compiled previously) +# INTERFACE = SWIG interface file +# TARGET = Name of target module or executable +# +# Many portions of this file were created by the SWIG configure +# script and should already reflect your machine. +#---------------------------------------------------------------- + +SRCS = +CXXSRCS = +OBJCSRCS = +OBJS = +INTERFACE = +WRAPFILE = $(INTERFACE:.i=_wrap.c) +WRAPOBJ = $(INTERFACE:.i=_wrap.o) +TARGET = module@SO@ # Use this kind of target for dynamic loading +#TARGET = mypython # Use this target for static linking + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +CC = @CC@ +CXX = @CXX@ +OBJC = @CC@ -Wno-import # -Wno-import needed for gcc +CFLAGS = +INCLUDE = +LIBS = + +# SWIG Options +# SWIG = location of the SWIG executable +# SWIGOPT = SWIG compiler options +# SWIGCC = Compiler used to compile the wrapper file + +SWIG = $(exec_prefix)/bin/swig +SWIGOPT = -python +SWIGCC = $(CC) + +# SWIG Library files. Uncomment if rebuilding the Python interpreter +#SWIGLIB = -lembed.i + +# Rules for creating .o files from source. + +COBJS = $(SRCS:.c=.o) +CXXOBJS = $(CXXSRCS:.cxx=.o) +OBJCOBJS = $(OBJCSRCS:.m=.o) +ALLOBJS = $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(OBJS) + +# Command that will be used to build the final extension. +BUILD = $(SWIGCC) + +# Uncomment the following if you are using dynamic loading +CCSHARED = @CCSHARED@ +BUILD = @LDSHARED@ + +# Uncomment the following if you are using dynamic loading with C++ and +# need to provide additional link libraries (this is not always required). + +#DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ + -L/usr/local/lib -lg++ -lstdc++ -lgcc + +# X11 installation (needed if rebuilding Python + tkinter) + +XLIB = @XLIBSW@ +XINCLUDE = @XINCLUDES@ + +# Python installation + +PY_INCLUDE = -DHAVE_CONFIG_H @PYINCLUDE@ +PY_LIB = @PYLIB@ + +# Tcl installation. Needed if rebuilding Python with tkinter. + +TCL_INCLUDE = @TCLINCLUDE@ +TCL_LIB = @TCLLIB@ + +# Build libraries (needed for static builds) + +LIBM = @LIBM@ +LIBC = @LIBC@ +SYSLIBS = $(LIBM) $(LIBC) @LIBS@ + +# Build options (uncomment only one these) + +#TKINTER = $(TCL_LIB) -ltk -ltcl $(XLIB) +BUILD_LIBS = $(LIBS) # Dynamic loading +#BUILD_LIBS = $(PY_LIB) @PYLINK@ $(TKINTER) $(LIBS) $(SYSLIBS) + +# Compilation rules for non-SWIG components + +.SUFFIXES: .c .cxx .m + +.c.o: + $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + +.cxx.o: + $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDE) -c $< + +.m.o: + $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + + +# ---------------------------------------------------------------------- +# Rules for building the extension +# ---------------------------------------------------------------------- + +all: $(TARGET) + +# Convert the wrapper file into an object file + +$(WRAPOBJ) : $(WRAPFILE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDE) $(PY_INCLUDE) + +$(WRAPFILE) : $(INTERFACE) + $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) + +$(TARGET): $(WRAPOBJ) $(ALLOBJS) + $(BUILD) $(WRAPOBJ) $(ALLOBJS) $(BUILD_LIBS) -o $(TARGET) + +clean: + rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) + + + + diff --git a/wxPython/wxSWIG/swig_lib/python/defarg.swg b/wxPython/wxSWIG/swig_lib/python/defarg.swg new file mode 100644 index 0000000000..83f6d5516f --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/defarg.swg @@ -0,0 +1,36 @@ +/* This file defines an internal function for processing default arguments + with shadow classes. + + There seems to be no straightforward way to write a shadow functions + involving default arguments. For example : + + def foo(arg1,arg2,*args): + shadowc.foo(arg1,arg2,args) + + This fails because args is now a tuple and SWIG doesn't know what to + do with it. + + This file allows a different approach : + + def foo(arg1,arg2,*args): + shadowc.__call_defarg(shadowc.foo,(arg1,arg2,)+args) + + Basically, we form a new tuple from the object, call this special + __call_defarg method and it passes control to the real wrapper function. + An ugly hack, but it works. +*/ + +static PyObject *swig_call_defargs(PyObject *self, PyObject *args) { + PyObject *func; + PyObject *parms; + + if (!PyArg_ParseTuple(args,"OO",&func,&parms)) + return NULL; + + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, "__call_defarg : Need a callable object!"); + return NULL; + } + return PyEval_CallObject(func,parms); + +} diff --git a/wxPython/wxSWIG/swig_lib/python/embed.i b/wxPython/wxSWIG/swig_lib/python/embed.i new file mode 100644 index 0000000000..654e241880 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/embed.i @@ -0,0 +1,115 @@ +// +// embed15.i +// SWIG file embedding the Python interpreter in something else. +// This file is based on Python-1.5. It will not work with +// earlier versions. +// +// This file makes it possible to extend Python and all of its +// built-in functions without having to hack it's setup script. +// + + +#ifdef AUTODOC +%subsection "embed.i" +%text %{ +This module provides support for building a new version of the +Python executable. This will be necessary on systems that do +not support shared libraries and may be necessary with C++ +extensions. This file contains everything you need to build +a new version of Python from include files and libraries normally +installed with the Python language. + +This module will automatically grab all of the Python modules +present in your current Python executable (including any special +purpose modules you have enabled such as Tkinter). Thus, you +may need to provide additional link libraries when compiling. + +This library file only works with Python 1.5. A version +compatible with Python 1.4 is available as embed14.i and +a Python1.3 version is available as embed13.i. As far as +I know, this module is C++ safe. +%} +#else +%echo "embed.i : Using Python 1.5" +#endif + +%wrapper %{ + +#include + +#ifdef __cplusplus +extern "C" +#endif +void SWIG_init(); /* Forward reference */ + +#define _PyImport_Inittab swig_inittab + +/* Grab Python's inittab[] structure */ + +#ifdef __cplusplus +extern "C" { +#endif +#include + +#undef _PyImport_Inittab + +/* Now define our own version of it. + Hopefully someone does not have more than 1000 built-in modules */ + +struct _inittab _SwigImport_Inittab[1000]; + +static int swig_num_modules = 0; + +/* Function for adding modules to Python */ + +static void swig_add_module(char *name, void (*initfunc)()) { + _SwigImport_Inittab[swig_num_modules].name = name; + _SwigImport_Inittab[swig_num_modules].initfunc = initfunc; + swig_num_modules++; + _SwigImport_Inittab[swig_num_modules].name = (char *) 0; + _SwigImport_Inittab[swig_num_modules].initfunc = 0; +} + +/* Function to add all of Python's build in modules to our interpreter */ + +static void swig_add_builtin() { + int i = 0; + while (swig_inittab[i].name) { + swig_add_module(swig_inittab[i].name, swig_inittab[i].initfunc); + i++; + } +#ifdef SWIGMODINIT + SWIGMODINIT +#endif + /* Add SWIG builtin function */ + swig_add_module(SWIG_name, SWIG_init); +} + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern int Py_Main(int, char **); + +#ifdef __cplusplus +} +#endif + +extern struct _inittab *PyImport_Inittab; + +int +main(int argc, char **argv) { + swig_add_builtin(); + PyImport_Inittab = _SwigImport_Inittab; + return Py_Main(argc,argv); +} + +%} + + + + diff --git a/wxPython/wxSWIG/swig_lib/python/embed13.i b/wxPython/wxSWIG/swig_lib/python/embed13.i new file mode 100644 index 0000000000..0b952638e9 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/embed13.i @@ -0,0 +1,342 @@ +// +// embed.i +// SWIG file embedding the Python interpreter in something else. +// This file is based on Python-1.3, but it might work with +// later versions. +// +// This file makes it possible to extend Python and all of its +// built-in functions without having to hack it's setup script. +// + +#ifdef AUTODOC +%subsection "embed13.i" +%text %{ +This module provides support for building a new version of the +Python 1.3 executable. This will be necessary on systems that do +not support shared libraries and may be necessary with C++ +extensions. This file contains everything you need to build +a new version of Python from include files and libraries normally +installed with the Python language. + +This module is functionally equivalent to the embed.i library, +but has a number of changes needed to work with older versions +of Python. +%} +#else +%echo "embed.i : Using Python 1.3" +#endif + + + + +%wrapper %{ + +#ifndef NEED_GETOPT +#include +#endif + +#include +typedef struct SWIGPyTab { + char *name; + void (*initfunc)(); +} SWIGPyTab; + +#ifdef __cplusplus +extern "C" +#endif +void SWIG_init(void); /* Forward reference */ + +#define inittab python_inittab + +/* Grab Python's inittab[] structure */ + +#ifdef __cplusplus +extern "C" { +#endif +#include + +#undef inittab + + +/* Now define our own version of it. + God forbid someone have more than 1000 built-in modules! */ + +SWIGPyTab inittab[1000]; + +static int swig_num_modules = 0; + +/* Function for adding modules to Python */ + +static void swig_add_module(char *name, void (*initfunc)()) { + inittab[swig_num_modules].name = name; + inittab[swig_num_modules].initfunc = initfunc; + swig_num_modules++; + inittab[swig_num_modules].name = (char *) 0; + inittab[swig_num_modules].initfunc = (void (*)()) 0; +} + +/* Function to add all of Python's build in modules to our interpreter */ + +static void swig_add_builtin() { + int i = 0; + while (python_inittab[i].name) { + swig_add_module(python_inittab[i].name, python_inittab[i].initfunc); + i++; + } + + /* Add SWIG builtin function */ + swig_add_module(SWIG_name, SWIG_init); +#ifdef SWIGMODINIT + SWIGMODINIT +#endif +} +#ifdef __cplusplus +} +#endif + +/* Interface to getopt(): */ +extern int optind; +extern char *optarg; + +#ifdef NEED_GETOPT +#ifdef __cplusplus +extern "C" int getopt(int, char **, char *); +#else +extern int getopt(); /* PROTO((int, char **, char *)); -- not standardized */ +#endif +#endif + +extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */ +extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */ +extern int Py_SuppressPrintingFlag; /* For ceval.c, declared in pythonrun.c */ + +/* Subroutines that live in their own file */ +#ifdef __cplusplus +extern "C" { +extern int isatty(int fd); +extern int PySys_SetArgv(int, char **); +#endif +extern char *getversion(); +extern char *getcopyright(); +#ifdef __cplusplus +} +#endif + +/* For getprogramname(); set by main() */ +static char *argv0; + +/* For getargcargv(); set by main() */ +static char **orig_argv; +static int orig_argc; + +/* Short usage message (with %s for argv0) */ +static char *usage_line = +"usage: %s [-d] [-i] [-s] [-u ] [-v] [-c cmd | file | -] [arg] ...\n"; + +/* Long usage message, split into parts < 512 bytes */ +static char *usage_top = "\n\ +Options and arguments (and corresponding environment variables):\n\ +-d : debug output from parser (also PYTHONDEBUG=x)\n\ +-i : inspect interactively after running script (also PYTHONINSPECT=x)\n\ +-s : suppress printing of top level expressions (also PYTHONSUPPRESS=x)\n\ +-u : unbuffered stdout and stderr (also PYTHONUNBUFFERED=x)\n\ +-v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ +-c cmd : program passed in as string (terminates option list)\n\ +"; +static char *usage_bot = "\ +file : program read from script file\n\ +- : program read from stdin (default; interactive mode if a tty)\n\ +arg ...: arguments passed to program in sys.argv[1:]\n\ +\n\ +Other environment variables:\n\ +PYTHONSTARTUP: file executed on interactive startup (no default)\n\ +PYTHONPATH : colon-separated list of directories prefixed to the\n\ + default module search path. The result is sys.path.\n\ +"; + +/* Main program */ + +int +main(int argc, char **argv) { + int c; + int sts; + char *command = NULL; + char *filename = NULL; + FILE *fp = stdin; + char *p; + int inspect = 0; + int unbuffered = 0; + + swig_add_builtin(); /* Add SWIG built-in modules */ + orig_argc = argc; /* For getargcargv() */ + orig_argv = argv; + argv0 = argv[0]; /* For getprogramname() */ + + if ((p = getenv("PYTHONDEBUG")) && *p != '\0') + Py_DebugFlag = 1; + if ((p = getenv("PYTHONSUPPRESS")) && *p != '\0') + Py_SuppressPrintingFlag = 1; + if ((p = getenv("PYTHONVERBOSE")) && *p != '\0') + Py_VerboseFlag = 1; + if ((p = getenv("PYTHONINSPECT")) && *p != '\0') + inspect = 1; + if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0') + unbuffered = 1; + + while ((c = getopt(argc, argv, "c:disuv")) != EOF) { + if (c == 'c') { + /* -c is the last option; following arguments + that look like options are left for the + the command to interpret. */ + command = (char *) malloc(strlen(optarg) + 2); + if (command == NULL) + Py_FatalError( + "not enough memory to copy -c argument"); + strcpy(command, optarg); + strcat(command, "\n"); + break; + } + + switch (c) { + + case 'd': + Py_DebugFlag++; + break; + + case 'i': + inspect++; + break; + + case 's': + Py_SuppressPrintingFlag++; + break; + + case 'u': + unbuffered++; + break; + + case 'v': + Py_VerboseFlag++; + break; + + /* This space reserved for other options */ + + default: + fprintf(stderr, usage_line, argv[0]); + fprintf(stderr, usage_top); + fprintf(stderr, usage_bot); + exit(2); + /*NOTREACHED*/ + + } + } + + if (unbuffered) { +#ifndef MPW + setbuf(stdout, (char *)NULL); + setbuf(stderr, (char *)NULL); +#else + /* On MPW (3.2) unbuffered seems to hang */ + setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); + setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ); +#endif + } + + if (command == NULL && optind < argc && + strcmp(argv[optind], "-") != 0) + filename = argv[optind]; + + if (Py_VerboseFlag || + command == NULL && filename == NULL && isatty((int)fileno(fp))) + fprintf(stderr, "Python %s\n%s\n", + getversion(), getcopyright()); + + if (filename != NULL) { + if ((fp = fopen(filename, "r")) == NULL) { + fprintf(stderr, "%s: can't open file '%s'\n", + argv[0], filename); + exit(2); + } + } + + Py_Initialize(); + if (command != NULL) { + /* Backup optind and force sys.argv[0] = '-c' */ + optind--; + argv[optind] = "-c"; + } + + PySys_SetArgv(argc-optind, argv+optind); + + if (command) { + sts = PyRun_SimpleString(command) != 0; + } + else { + if (filename == NULL && isatty((int)fileno(fp))) { + char *startup = getenv("PYTHONSTARTUP"); + if (startup != NULL && startup[0] != '\0') { + FILE *fp = fopen(startup, "r"); + if (fp != NULL) { + (void) PyRun_SimpleFile(fp, startup); + PyErr_Clear(); + fclose(fp); + } + } + } + sts = PyRun_AnyFile( + fp, filename == NULL ? "" : filename) != 0; + if (filename != NULL) + fclose(fp); + } + + if (inspect && isatty((int)fileno(stdin)) && + (filename != NULL || command != NULL)) + sts = PyRun_AnyFile(stdin, "") != 0; + + Py_Exit(sts); + /*NOTREACHED*/ +} + + +/* Return the program name -- some code out there needs this. */ + +#ifdef __cplusplus +extern "C" +#endif + +char * +getprogramname() +{ + return argv0; +} + + +/* Make the *original* argc/argv available to other modules. + This is rare, but it is needed by the secureware extension. */ + +#ifdef __cplusplus +extern "C" +#endif +void +getargcargv(int *argc,char ***argv) +{ + *argc = orig_argc; + *argv = orig_argv; +} + +/* Total Hack to get getpath.c to compile under C++ */ + +#ifdef __cplusplus +#define malloc (char *) malloc +extern "C" { +#endif +#include +#ifdef __cplusplus +} +#undef malloc +#endif + +%} + + + diff --git a/wxPython/wxSWIG/swig_lib/python/embed14.i b/wxPython/wxSWIG/swig_lib/python/embed14.i new file mode 100644 index 0000000000..2558c39758 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/embed14.i @@ -0,0 +1,340 @@ +// +// embed.i +// SWIG file embedding the Python interpreter in something else. +// This file is based on Python-1.4. +// +// This file makes it possible to extend Python and all of its +// built-in functions without having to hack it's setup script. +// + + +#ifdef AUTODOC +%subsection "embed.i" +%text %{ +This module provides support for building a new version of the +Python executable. This will be necessary on systems that do +not support shared libraries and may be necessary with C++ +extensions. This file contains everything you need to build +a new version of Python from include files and libraries normally +installed with the Python language. + +This module will automatically grab all of the Python modules +present in your current Python executable (including any special +purpose modules you have enabled such as tkinter). Thus, you +may need to provide additional link libraries when compiling. + +This library file only works with Python 1.4. A version compatible +with Python 1.3 is available as embed13.i. A Python 1.5 version is +available as embed15.i As far as I know, this module is C++ safe +(well, it works for me). +%} +#else +%echo "embed.i : Using Python 1.4" +#endif + +%wrapper %{ +#ifndef NEED_GETOPT +#include +#endif + +#include + +#ifdef __cplusplus +extern "C" +#endif +void SWIG_init(); /* Forward reference */ + +#define inittab python_inittab + +/* Grab Python's inittab[] structure */ + +#ifdef __cplusplus +extern "C" { +#endif +#include + +#undef inittab + +/* Now define our own version of it. + Hopefully someone does not have more than 1000 built-in modules */ + +struct _inittab inittab[1000]; + +static int swig_num_modules = 0; + +/* Function for adding modules to Python */ + + +static void swig_add_module(char *name, void (*initfunc)()) { + inittab[swig_num_modules].name = name; + inittab[swig_num_modules].initfunc = initfunc; + swig_num_modules++; + inittab[swig_num_modules].name = (char *) 0; + inittab[swig_num_modules].initfunc = 0; +} + +/* Function to add all of Python's build in modules to our interpreter */ + +static void swig_add_builtin() { + int i = 0; + while (python_inittab[i].name) { + swig_add_module(python_inittab[i].name, python_inittab[i].initfunc); + i++; + } +#ifdef SWIGMODINIT + SWIGMODINIT +#endif + /* Add SWIG builtin function */ + swig_add_module(SWIG_name, SWIG_init); +} + +#ifdef __cplusplus +} +#endif + +/* Interface to getopt(): */ +extern int optind; +extern char *optarg; +#ifdef NEED_GETOPT +#ifdef __cplusplus +extern "C" int getopt(int, char **, char *); +#else +extern int getopt(); /* PROTO((int, char **, char *)); -- not standardized */ +#endif +#endif + +extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */ +extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */ +extern int Py_SuppressPrintingFlag; /* For ceval.c, declared in pythonrun.c */ + +/* Subroutines that live in their own file */ +#ifdef __cplusplus +extern "C" { +extern int isatty(int fd); +extern void PySys_SetArgv(int, char **); +#endif +extern char *Py_GetVersion(); +extern char *Py_GetCopyright(); +#ifdef __cplusplus +} +#endif + +/* For getprogramname(); set by main() */ +static char *argv0; + +/* For getargcargv(); set by main() */ +static char **orig_argv; +static int orig_argc; + +/* Short usage message (with %s for argv0) */ +static char *usage_line = +"usage: %s [-d] [-i] [-s] [-u ] [-v] [-c cmd | file | -] [arg] ...\n"; + +/* Long usage message, split into parts < 512 bytes */ +static char *usage_top = "\n\ +Options and arguments (and corresponding environment variables):\n\ +-d : debug output from parser (also PYTHONDEBUG=x)\n\ +-i : inspect interactively after running script (also PYTHONINSPECT=x)\n\ +-s : suppress printing of top level expressions (also PYTHONSUPPRESS=x)\n\ +-u : unbuffered stdout and stderr (also PYTHONUNBUFFERED=x)\n\ +-v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ +-c cmd : program passed in as string (terminates option list)\n\ +"; +static char *usage_bot = "\ +file : program read from script file\n\ +- : program read from stdin (default; interactive mode if a tty)\n\ +arg ...: arguments passed to program in sys.argv[1:]\n\ +\n\ +Other environment variables:\n\ +PYTHONSTARTUP: file executed on interactive startup (no default)\n\ +PYTHONPATH : colon-separated list of directories prefixed to the\n\ + default module search path. The result is sys.path.\n\ +"; + +/* Main program */ + +int +main(int argc, char **argv) { + int c; + int sts; + char *command = NULL; + char *filename = NULL; + FILE *fp = stdin; + char *p; + int inspect = 0; + int unbuffered = 0; + + swig_add_builtin(); /* Add SWIG built-in modules */ + orig_argc = argc; /* For getargcargv() */ + orig_argv = argv; + argv0 = argv[0]; /* For getprogramname() */ + + if ((p = getenv("PYTHONDEBUG")) && *p != '\0') + Py_DebugFlag = 1; + if ((p = getenv("PYTHONSUPPRESS")) && *p != '\0') + Py_SuppressPrintingFlag = 1; + if ((p = getenv("PYTHONVERBOSE")) && *p != '\0') + Py_VerboseFlag = 1; + if ((p = getenv("PYTHONINSPECT")) && *p != '\0') + inspect = 1; + if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0') + unbuffered = 1; + + while ((c = getopt(argc, argv, "c:disuv")) != EOF) { + if (c == 'c') { + /* -c is the last option; following arguments + that look like options are left for the + the command to interpret. */ + command = (char *) malloc(strlen(optarg) + 2); + if (command == NULL) + Py_FatalError( + "not enough memory to copy -c argument"); + strcpy(command, optarg); + strcat(command, "\n"); + break; + } + + switch (c) { + + case 'd': + Py_DebugFlag++; + break; + + case 'i': + inspect++; + break; + + case 's': + Py_SuppressPrintingFlag++; + break; + + case 'u': + unbuffered++; + break; + + case 'v': + Py_VerboseFlag++; + break; + + /* This space reserved for other options */ + + default: + fprintf(stderr, usage_line, argv[0]); + fprintf(stderr, usage_top); + fprintf(stderr, usage_bot); + exit(2); + /*NOTREACHED*/ + + } + } + + if (unbuffered) { +#ifndef MPW + setbuf(stdout, (char *)NULL); + setbuf(stderr, (char *)NULL); +#else + /* On MPW (3.2) unbuffered seems to hang */ + setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); + setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ); +#endif + } + + if (command == NULL && optind < argc && + strcmp(argv[optind], "-") != 0) + filename = argv[optind]; + + if (Py_VerboseFlag || + command == NULL && filename == NULL && isatty((int)fileno(fp))) + fprintf(stderr, "Python %s\n%s\n", + Py_GetVersion(), Py_GetCopyright()); + + if (filename != NULL) { + if ((fp = fopen(filename, "r")) == NULL) { + fprintf(stderr, "%s: can't open file '%s'\n", + argv[0], filename); + exit(2); + } + } + + Py_Initialize(); + if (command != NULL) { + /* Backup optind and force sys.argv[0] = '-c' */ + optind--; + argv[optind] = "-c"; + } + + PySys_SetArgv(argc-optind, argv+optind); + + if (command) { + sts = PyRun_SimpleString(command) != 0; + } + else { + if (filename == NULL && isatty((int)fileno(fp))) { + char *startup = getenv("PYTHONSTARTUP"); + if (startup != NULL && startup[0] != '\0') { + FILE *fp = fopen(startup, "r"); + if (fp != NULL) { + (void) PyRun_SimpleFile(fp, startup); + PyErr_Clear(); + fclose(fp); + } + } + } + sts = PyRun_AnyFile( + fp, filename == NULL ? "" : filename) != 0; + if (filename != NULL) + fclose(fp); + } + + if (inspect && isatty((int)fileno(stdin)) && + (filename != NULL || command != NULL)) + sts = PyRun_AnyFile(stdin, "") != 0; + + Py_Exit(sts); + /*NOTREACHED*/ +} + + +/* Return the program name -- some code out there needs this. */ + +#ifdef __cplusplus +extern "C" +#endif + +char * +Py_GetProgramName() +{ + return argv0; +} + + +/* Make the *original* argc/argv available to other modules. + This is rare, but it is needed by the secureware extension. */ + +#ifdef __cplusplus +extern "C" +#endif +void +getargcargv(int *argc,char ***argv) +{ + *argc = orig_argc; + *argv = orig_argv; +} + +/* Total Hack to get getpath.c to compile under C++ */ + +#ifdef __cplusplus +#define malloc (char *) malloc +extern "C" { +#endif +#include +#ifdef __cplusplus +} +#undef malloc +#endif + +%} + + + + diff --git a/wxPython/wxSWIG/swig_lib/python/embed15.i b/wxPython/wxSWIG/swig_lib/python/embed15.i new file mode 100644 index 0000000000..654e241880 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/embed15.i @@ -0,0 +1,115 @@ +// +// embed15.i +// SWIG file embedding the Python interpreter in something else. +// This file is based on Python-1.5. It will not work with +// earlier versions. +// +// This file makes it possible to extend Python and all of its +// built-in functions without having to hack it's setup script. +// + + +#ifdef AUTODOC +%subsection "embed.i" +%text %{ +This module provides support for building a new version of the +Python executable. This will be necessary on systems that do +not support shared libraries and may be necessary with C++ +extensions. This file contains everything you need to build +a new version of Python from include files and libraries normally +installed with the Python language. + +This module will automatically grab all of the Python modules +present in your current Python executable (including any special +purpose modules you have enabled such as Tkinter). Thus, you +may need to provide additional link libraries when compiling. + +This library file only works with Python 1.5. A version +compatible with Python 1.4 is available as embed14.i and +a Python1.3 version is available as embed13.i. As far as +I know, this module is C++ safe. +%} +#else +%echo "embed.i : Using Python 1.5" +#endif + +%wrapper %{ + +#include + +#ifdef __cplusplus +extern "C" +#endif +void SWIG_init(); /* Forward reference */ + +#define _PyImport_Inittab swig_inittab + +/* Grab Python's inittab[] structure */ + +#ifdef __cplusplus +extern "C" { +#endif +#include + +#undef _PyImport_Inittab + +/* Now define our own version of it. + Hopefully someone does not have more than 1000 built-in modules */ + +struct _inittab _SwigImport_Inittab[1000]; + +static int swig_num_modules = 0; + +/* Function for adding modules to Python */ + +static void swig_add_module(char *name, void (*initfunc)()) { + _SwigImport_Inittab[swig_num_modules].name = name; + _SwigImport_Inittab[swig_num_modules].initfunc = initfunc; + swig_num_modules++; + _SwigImport_Inittab[swig_num_modules].name = (char *) 0; + _SwigImport_Inittab[swig_num_modules].initfunc = 0; +} + +/* Function to add all of Python's build in modules to our interpreter */ + +static void swig_add_builtin() { + int i = 0; + while (swig_inittab[i].name) { + swig_add_module(swig_inittab[i].name, swig_inittab[i].initfunc); + i++; + } +#ifdef SWIGMODINIT + SWIGMODINIT +#endif + /* Add SWIG builtin function */ + swig_add_module(SWIG_name, SWIG_init); +} + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern int Py_Main(int, char **); + +#ifdef __cplusplus +} +#endif + +extern struct _inittab *PyImport_Inittab; + +int +main(int argc, char **argv) { + swig_add_builtin(); + PyImport_Inittab = _SwigImport_Inittab; + return Py_Main(argc,argv); +} + +%} + + + + diff --git a/wxPython/wxSWIG/swig_lib/python/ptrlang.i b/wxPython/wxSWIG/swig_lib/python/ptrlang.i new file mode 100644 index 0000000000..3db7a52fee --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/ptrlang.i @@ -0,0 +1,652 @@ +// +// SWIG pointer conversion and utility library +// +// Dave Beazley +// April 19, 1997 +// +// Python specific implementation. This file is included +// by the file ../pointer.i + +%{ + +#include + +/*------------------------------------------------------------------ + ptrcast(value,type) + + Constructs a new pointer value. Value may either be a string + or an integer. Type is a string corresponding to either the + C datatype or mangled datatype. + + ptrcast(0,"Vector *") + or + ptrcast(0,"Vector_p") + ------------------------------------------------------------------ */ + +static PyObject *ptrcast(PyObject *_PTRVALUE, char *type) { + + char *r,*s; + void *ptr; + PyObject *obj; + char *typestr,*c; + + /* Produce a "mangled" version of the type string. */ + + typestr = (char *) malloc(strlen(type)+2); + + /* Go through and munge the typestring */ + + r = typestr; + *(r++) = '_'; + c = type; + while (*c) { + if (!isspace(*c)) { + if ((*c == '*') || (*c == '&')) { + *(r++) = 'p'; + } + else *(r++) = *c; + } else { + *(r++) = '_'; + } + c++; + } + *(r++) = 0; + + /* Check to see what kind of object _PTRVALUE is */ + + if (PyInt_Check(_PTRVALUE)) { + ptr = (void *) PyInt_AsLong(_PTRVALUE); + /* Received a numerical value. Make a pointer out of it */ + r = (char *) malloc(strlen(typestr)+22); + if (ptr) { + SWIG_MakePtr(r, ptr, typestr); + } else { + sprintf(r,"_0%s",typestr); + } + obj = PyString_FromString(r); + free(r); + } else if (PyString_Check(_PTRVALUE)) { + /* Have a real pointer value now. Try to strip out the pointer + value */ + s = PyString_AsString(_PTRVALUE); + r = (char *) malloc(strlen(type)+22); + + /* Now extract the pointer value */ + if (!SWIG_GetPtr(s,&ptr,0)) { + if (ptr) { + SWIG_MakePtr(r,ptr,typestr); + } else { + sprintf(r,"_0%s",typestr); + } + obj = PyString_FromString(r); + } else { + obj = NULL; + } + free(r); + } else { + obj = NULL; + } + free(typestr); + if (!obj) + PyErr_SetString(PyExc_TypeError,"Type error in ptrcast. Argument is not a valid pointer value."); + return obj; +} + +/*------------------------------------------------------------------ + ptrvalue(ptr,type = 0) + + Attempts to dereference a pointer value. If type is given, it + will try to use that type. Otherwise, this function will attempt + to "guess" the proper datatype by checking against all of the + builtin C datatypes. + ------------------------------------------------------------------ */ + +static PyObject *ptrvalue(PyObject *_PTRVALUE, int index, char *type) { + void *ptr; + char *s; + PyObject *obj; + + if (!PyString_Check(_PTRVALUE)) { + PyErr_SetString(PyExc_TypeError,"Type error in ptrvalue. Argument is not a valid pointer value."); + return NULL; + } + s = PyString_AsString(_PTRVALUE); + if (SWIG_GetPtr(s,&ptr,0)) { + PyErr_SetString(PyExc_TypeError,"Type error in ptrvalue. Argument is not a valid pointer value."); + return NULL; + } + + /* If no datatype was passed, try a few common datatypes first */ + + if (!type) { + + /* No datatype was passed. Type to figure out if it's a common one */ + + if (!SWIG_GetPtr(s,&ptr,"_int_p")) { + type = "int"; + } else if (!SWIG_GetPtr(s,&ptr,"_double_p")) { + type = "double"; + } else if (!SWIG_GetPtr(s,&ptr,"_short_p")) { + type = "short"; + } else if (!SWIG_GetPtr(s,&ptr,"_long_p")) { + type = "long"; + } else if (!SWIG_GetPtr(s,&ptr,"_float_p")) { + type = "float"; + } else if (!SWIG_GetPtr(s,&ptr,"_char_p")) { + type = "char"; + } else if (!SWIG_GetPtr(s,&ptr,"_char_pp")) { + type = "char *"; + } else { + type = "unknown"; + } + } + + if (!ptr) { + PyErr_SetString(PyExc_TypeError,"Unable to dereference NULL pointer."); + return NULL; + } + + /* Now we have a datatype. Try to figure out what to do about it */ + if (strcmp(type,"int") == 0) { + obj = PyInt_FromLong((long) *(((int *) ptr) + index)); + } else if (strcmp(type,"double") == 0) { + obj = PyFloat_FromDouble((double) *(((double *) ptr)+index)); + } else if (strcmp(type,"short") == 0) { + obj = PyInt_FromLong((long) *(((short *) ptr)+index)); + } else if (strcmp(type,"long") == 0) { + obj = PyInt_FromLong((long) *(((long *) ptr)+index)); + } else if (strcmp(type,"float") == 0) { + obj = PyFloat_FromDouble((double) *(((float *) ptr)+index)); + } else if (strcmp(type,"char") == 0) { + obj = PyString_FromString(((char *) ptr)+index); + } else if (strcmp(type,"char *") == 0) { + char *c = *(((char **) ptr)+index); + if (c) obj = PyString_FromString(c); + else obj = PyString_FromString("NULL"); + } else { + PyErr_SetString(PyExc_TypeError,"Unable to dereference unsupported datatype."); + return NULL; + } + return obj; +} + +/*------------------------------------------------------------------ + ptrcreate(type,value = 0,numelements = 1) + + Attempts to create a new object of given type. Type must be + a basic C datatype. Will not create complex objects. + ------------------------------------------------------------------ */ + +static PyObject *ptrcreate(char *type, PyObject *_PYVALUE, int numelements) { + void *ptr; + PyObject *obj; + int sz; + char *cast; + char temp[40]; + + /* Check the type string against a variety of possibilities */ + + if (strcmp(type,"int") == 0) { + sz = sizeof(int)*numelements; + cast = "_int_p"; + } else if (strcmp(type,"short") == 0) { + sz = sizeof(short)*numelements; + cast = "_short_p"; + } else if (strcmp(type,"long") == 0) { + sz = sizeof(long)*numelements; + cast = "_long_p"; + } else if (strcmp(type,"double") == 0) { + sz = sizeof(double)*numelements; + cast = "_double_p"; + } else if (strcmp(type,"float") == 0) { + sz = sizeof(float)*numelements; + cast = "_float_p"; + } else if (strcmp(type,"char") == 0) { + sz = sizeof(char)*numelements; + cast = "_char_p"; + } else if (strcmp(type,"char *") == 0) { + sz = sizeof(char *)*(numelements+1); + cast = "_char_pp"; + } else { + PyErr_SetString(PyExc_TypeError,"Unable to create unknown datatype."); + return NULL; + } + + /* Create the new object */ + + ptr = (void *) malloc(sz); + if (!ptr) { + PyErr_SetString(PyExc_MemoryError,"Out of memory in swig_create."); + return NULL; + } + + /* Now try to set its default value */ + + if (_PYVALUE) { + if (strcmp(type,"int") == 0) { + int *ip,i,ivalue; + ivalue = (int) PyInt_AsLong(_PYVALUE); + ip = (int *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"short") == 0) { + short *ip,ivalue; + int i; + ivalue = (short) PyInt_AsLong(_PYVALUE); + ip = (short *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"long") == 0) { + long *ip,ivalue; + int i; + ivalue = (long) PyInt_AsLong(_PYVALUE); + ip = (long *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"double") == 0) { + double *ip,ivalue; + int i; + ivalue = (double) PyFloat_AsDouble(_PYVALUE); + ip = (double *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"float") == 0) { + float *ip,ivalue; + int i; + ivalue = (float) PyFloat_AsDouble(_PYVALUE); + ip = (float *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"char") == 0) { + char *ip,*ivalue; + ivalue = (char *) PyString_AsString(_PYVALUE); + ip = (char *) ptr; + strncpy(ip,ivalue,numelements-1); + } else if (strcmp(type,"char *") == 0) { + char **ip, *ivalue; + int i; + ivalue = (char *) PyString_AsString(_PYVALUE); + ip = (char **) ptr; + for (i = 0; i < numelements; i++) { + if (ivalue) { + ip[i] = (char *) malloc(strlen(ivalue)+1); + strcpy(ip[i],ivalue); + } else { + ip[i] = 0; + } + } + ip[numelements] = 0; + } + } + /* Create the pointer value */ + + SWIG_MakePtr(temp,ptr,cast); + obj = PyString_FromString(temp); + return obj; +} + + +/*------------------------------------------------------------------ + ptrset(ptr,value,index = 0,type = 0) + + Attempts to set the value of a pointer variable. If type is + given, we will use that type. Otherwise, we'll guess the datatype. + ------------------------------------------------------------------ */ + +static PyObject *ptrset(PyObject *_PTRVALUE, PyObject *_PYVALUE, int index, char *type) { + void *ptr; + char *s; + PyObject *obj; + + if (!PyString_Check(_PTRVALUE)) { + PyErr_SetString(PyExc_TypeError,"Type error in ptrset. Argument is not a valid pointer value."); + return NULL; + } + s = PyString_AsString(_PTRVALUE); + if (SWIG_GetPtr(s,&ptr,0)) { + PyErr_SetString(PyExc_TypeError,"Type error in ptrset. Argument is not a valid pointer value."); + return NULL; + } + + /* If no datatype was passed, try a few common datatypes first */ + + if (!type) { + + /* No datatype was passed. Type to figure out if it's a common one */ + + if (!SWIG_GetPtr(s,&ptr,"_int_p")) { + type = "int"; + } else if (!SWIG_GetPtr(s,&ptr,"_double_p")) { + type = "double"; + } else if (!SWIG_GetPtr(s,&ptr,"_short_p")) { + type = "short"; + } else if (!SWIG_GetPtr(s,&ptr,"_long_p")) { + type = "long"; + } else if (!SWIG_GetPtr(s,&ptr,"_float_p")) { + type = "float"; + } else if (!SWIG_GetPtr(s,&ptr,"_char_p")) { + type = "char"; + } else if (!SWIG_GetPtr(s,&ptr,"_char_pp")) { + type = "char *"; + } else { + type = "unknown"; + } + } + + if (!ptr) { + PyErr_SetString(PyExc_TypeError,"Unable to set NULL pointer."); + return NULL; + } + + /* Now we have a datatype. Try to figure out what to do about it */ + if (strcmp(type,"int") == 0) { + *(((int *) ptr)+index) = (int) PyInt_AsLong(_PYVALUE); + } else if (strcmp(type,"double") == 0) { + *(((double *) ptr)+index) = (double) PyFloat_AsDouble(_PYVALUE); + } else if (strcmp(type,"short") == 0) { + *(((short *) ptr)+index) = (short) PyInt_AsLong(_PYVALUE); + } else if (strcmp(type,"long") == 0) { + *(((long *) ptr)+index) = (long) PyInt_AsLong(_PYVALUE); + } else if (strcmp(type,"float") == 0) { + *(((float *) ptr)+index) = (float) PyFloat_AsDouble(_PYVALUE); + } else if (strcmp(type,"char") == 0) { + char *c = PyString_AsString(_PYVALUE); + strcpy(((char *) ptr)+index, c); + } else if (strcmp(type,"char *") == 0) { + char *c = PyString_AsString(_PYVALUE); + char **ca = (char **) ptr; + if (ca[index]) free(ca[index]); + if (strcmp(c,"NULL") == 0) { + ca[index] = 0; + } else { + ca[index] = (char *) malloc(strlen(c)+1); + strcpy(ca[index],c); + } + } else { + PyErr_SetString(PyExc_TypeError,"Unable to set unsupported datatype."); + return NULL; + } + Py_INCREF(Py_None); + return Py_None; +} + + +/*------------------------------------------------------------------ + ptradd(ptr,offset) + + Adds a value to an existing pointer value. Will do a type-dependent + add for basic datatypes. For other datatypes, will do a byte-add. + ------------------------------------------------------------------ */ + +static PyObject *ptradd(PyObject *_PTRVALUE, int offset) { + + char *r,*s; + void *ptr,*junk; + PyObject *obj; + char *type; + + /* Check to see what kind of object _PTRVALUE is */ + + if (PyString_Check(_PTRVALUE)) { + /* Have a potential pointer value now. Try to strip out the value */ + s = PyString_AsString(_PTRVALUE); + + /* Try to handle a few common datatypes first */ + + if (!SWIG_GetPtr(s,&ptr,"_int_p")) { + ptr = (void *) (((int *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,"_double_p")) { + ptr = (void *) (((double *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,"_short_p")) { + ptr = (void *) (((short *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,"_long_p")) { + ptr = (void *) (((long *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,"_float_p")) { + ptr = (void *) (((float *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,"_char_p")) { + ptr = (void *) (((char *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,0)) { + ptr = (void *) (((char *) ptr) + offset); + } else { + PyErr_SetString(PyExc_TypeError,"Type error in ptradd. Argument is not a valid pointer value."); + return NULL; + } + type = SWIG_GetPtr(s,&junk,"INVALID POINTER"); + r = (char *) malloc(strlen(type)+20); + if (ptr) { + SWIG_MakePtr(r,ptr,type); + } else { + sprintf(r,"_0%s",type); + } + obj = PyString_FromString(r); + free(r); + } + return obj; +} + +/*------------------------------------------------------------------ + ptrmap(type1,type2) + + Allows a mapping between type1 and type2. (Like a typedef) + ------------------------------------------------------------------ */ + +static void ptrmap(char *type1, char *type2) { + + char *typestr1,*typestr2,*c,*r; + + /* Produce a "mangled" version of the type string. */ + + typestr1 = (char *) malloc(strlen(type1)+2); + + /* Go through and munge the typestring */ + + r = typestr1; + *(r++) = '_'; + c = type1; + while (*c) { + if (!isspace(*c)) { + if ((*c == '*') || (*c == '&')) { + *(r++) = 'p'; + } + else *(r++) = *c; + } else { + *(r++) = '_'; + } + c++; + } + *(r++) = 0; + + typestr2 = (char *) malloc(strlen(type2)+2); + + /* Go through and munge the typestring */ + + r = typestr2; + *(r++) = '_'; + c = type2; + while (*c) { + if (!isspace(*c)) { + if ((*c == '*') || (*c == '&')) { + *(r++) = 'p'; + } + else *(r++) = *c; + } else { + *(r++) = '_'; + } + c++; + } + *(r++) = 0; + SWIG_RegisterMapping(typestr1,typestr2,0); + SWIG_RegisterMapping(typestr2,typestr1,0); +} + +/*------------------------------------------------------------------ + ptrfree(ptr) + + Destroys a pointer value + ------------------------------------------------------------------ */ + +PyObject *ptrfree(PyObject *_PTRVALUE) { + void *ptr, *junk; + char *s; + + if (!PyString_Check(_PTRVALUE)) { + PyErr_SetString(PyExc_TypeError,"Type error in ptrfree. Argument is not a valid pointer value."); + return NULL; + } + s = PyString_AsString(_PTRVALUE); + if (SWIG_GetPtr(s,&ptr,0)) { + PyErr_SetString(PyExc_TypeError,"Type error in ptrfree. Argument is not a valid pointer value."); + return NULL; + } + + /* Check to see if this pointer is a char ** */ + if (!SWIG_GetPtr(s,&junk,"_char_pp")) { + char **c = (char **) ptr; + if (c) { + int i = 0; + while (c[i]) { + free(c[i]); + i++; + } + } + } + if (ptr) + free((char *) ptr); + + Py_INCREF(Py_None); + return Py_None; +} + +%} +%typemap(python,in) PyObject *ptr, PyObject *value { + $target = $source; +} + +%typemap(python,out) PyObject *ptrcast, + PyObject *ptrvalue, + PyObject *ptrcreate, + PyObject *ptrset, + PyObject *ptradd, + PyObject *ptrfree +{ + $target = $source; +} + +%typemap(python,ret) int ptrset { + if ($source == -1) return NULL; +} + +PyObject *ptrcast(PyObject *ptr, char *type); +// Casts a pointer ptr to a new datatype given by the string type. +// type may be either the SWIG generated representation of a datatype +// or the C representation. For example : +// +// ptrcast(ptr,"double_p"); # Python representation +// ptrcast(ptr,"double *"); # C representation +// +// A new pointer value is returned. ptr may also be an integer +// value in which case the value will be used to set the pointer +// value. For example : +// +// a = ptrcast(0,"Vector_p"); +// +// Will create a NULL pointer of type "Vector_p" +// +// The casting operation is sensitive to formatting. As a result, +// "double *" is different than "double*". As a result of thumb, +// there should always be exactly one space between the C datatype +// and any pointer specifiers (*). + +PyObject *ptrvalue(PyObject *ptr, int index = 0, char *type = 0); +// Returns the value that a pointer is pointing to (ie. dereferencing). +// The type is automatically inferred by the pointer type--thus, an +// integer pointer will return an integer, a double will return a double, +// and so on. The index and type fields are optional parameters. When +// an index is specified, this function returns the value of ptr[index]. +// This allows array access. When a type is specified, it overrides +// the given pointer type. Examples : +// +// ptrvalue(a) # Returns the value *a +// ptrvalue(a,10) # Returns the value a[10] +// ptrvalue(a,10,"double") # Returns a[10] assuming a is a double * + +PyObject *ptrset(PyObject *ptr, PyObject *value, int index = 0, char *type = 0); +// Sets the value pointed to by a pointer. The type is automatically +// inferred from the pointer type so this function will work for +// integers, floats, doubles, etc... The index and type fields are +// optional. When an index is given, it provides array access. When +// type is specified, it overrides the given pointer type. Examples : +// +// ptrset(a,3) # Sets the value *a = 3 +// ptrset(a,3,10) # Sets a[10] = 3 +// ptrset(a,3,10,"int") # Sets a[10] = 3 assuming a is a int * + +PyObject *ptrcreate(char *type, PyObject *value = 0, int nitems = 1); +// Creates a new object and returns a pointer to it. This function +// can be used to create various kinds of objects for use in C functions. +// type specifies the basic C datatype to create and value is an +// optional parameter that can be used to set the initial value of the +// object. nitems is an optional parameter that can be used to create +// an array. This function results in a memory allocation using +// malloc(). Examples : +// +// a = ptrcreate("double") # Create a new double, return pointer +// a = ptrcreate("int",7) # Create an integer, set value to 7 +// a = ptrcreate("int",0,1000) # Create an integer array with initial +// # values all set to zero +// +// This function only recognizes a few common C datatypes as listed below : +// +// int, short, long, float, double, char, char *, void +// +// All other datatypes will result in an error. However, other +// datatypes can be created by using the ptrcast function. For +// example: +// +// a = ptrcast(ptrcreate("int",0,100),"unsigned int *") + +PyObject *ptrfree(PyObject *ptr); +// Destroys the memory pointed to by ptr. This function calls free() +// and should only be used with objects created by ptrcreate(). Since +// this function calls free, it may work with other objects, but this +// is generally discouraged unless you absolutely know what you're +// doing. + +PyObject *ptradd(PyObject *ptr, int offset); +// Adds a value to the current pointer value. For the C datatypes of +// int, short, long, float, double, and char, the offset value is the +// number of objects and works in exactly the same manner as in C. For +// example, the following code steps through the elements of an array +// +// a = ptrcreate("double",0,100); # Create an array double a[100] +// b = a; +// for i in range(0,100): +// ptrset(b,0.0025*i); # set *b = 0.0025*i +// b = ptradd(b,1); # b++ (go to next double) +// +// In this case, adding one to b goes to the next double. +// +// For all other datatypes (including all complex datatypes), the +// offset corresponds to bytes. This function does not perform any +// bounds checking and negative offsets are perfectly legal. + +void ptrmap(char *type1, char *type2); +// This is a rarely used function that performs essentially the same +// operation as a C typedef. To manage datatypes at run-time, SWIG +// modules manage an internal symbol table of type mappings. This +// table keeps track of which types are equivalent to each other. The +// ptrmap() function provides a mechanism for scripts to add symbols +// to this table. For example : +// +// ptrmap("double_p","Real_p"); +// +// would make the types "doublePtr" and "RealPtr" equivalent to each +// other. Pointers of either type could now be used interchangably. +// +// Normally this function is not needed, but it can be used to +// circumvent SWIG's normal type-checking behavior or to work around +// weird type-handling problems. + + + + diff --git a/wxPython/wxSWIG/swig_lib/python/pyexp.swg b/wxPython/wxSWIG/swig_lib/python/pyexp.swg new file mode 100644 index 0000000000..a7305579be --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/pyexp.swg @@ -0,0 +1,32 @@ +#include +#include +/* Definitions for Windows/Unix exporting */ +#if defined(__WIN32__) +# if defined(_MSC_VER) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# if defined(__BORLANDC__) +# define SWIGEXPORT(a) a _export +# else +# define SWIGEXPORT(a) a +# endif +# endif +#else +# define SWIGEXPORT(a) a +#endif + +#include "Python.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void SWIG_MakePtr(char *, void *, char *); +extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); +extern char *SWIG_GetPtr(char *, void **, char *); +extern char *SWIG_GetPtrObj(PyObject *, void **, char *); +extern void SWIG_addvarlink(PyObject *, char *, PyObject *(*)(void), int (*)(PyObject *)); +extern PyObject *SWIG_newvarlink(void); +#ifdef __cplusplus +} +#endif diff --git a/wxPython/wxSWIG/swig_lib/python/python.swg b/wxPython/wxSWIG/swig_lib/python/python.swg new file mode 100644 index 0000000000..9fca855598 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/python.swg @@ -0,0 +1,417 @@ +/*********************************************************************** + * $Header$ + * swig_lib/python/python.cfg + * + * Contains variable linking and pointer type-checking code. + ************************************************************************/ + +#include +#include + +#include "Python.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Definitions for Windows/Unix exporting */ +#if defined(_WIN32) || defined(__WIN32__) +# if defined(_MSC_VER) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# if defined(__BORLANDC__) +# define SWIGEXPORT(a) a _export +# else +# define SWIGEXPORT(a) a +# endif +# endif +#else +# define SWIGEXPORT(a) a +#endif + +#ifdef SWIG_GLOBAL +#define SWIGSTATICRUNTIME(a) SWIGEXPORT(a) +#else +#define SWIGSTATICRUNTIME(a) static a +#endif + +typedef struct { + char *name; + PyObject *(*get_attr)(void); + int (*set_attr)(PyObject *); +} swig_globalvar; + +typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar **vars; + int nvars; + int maxvars; +} swig_varlinkobject; + +/* ---------------------------------------------------------------------- + swig_varlink_repr() + + Function for python repr method + ---------------------------------------------------------------------- */ + +static PyObject * +swig_varlink_repr(swig_varlinkobject *v) +{ + v = v; + return PyString_FromString(""); +} + +/* --------------------------------------------------------------------- + swig_varlink_print() + + Print out all of the global variable names + --------------------------------------------------------------------- */ + +static int +swig_varlink_print(swig_varlinkobject *v, FILE *fp, int flags) +{ + + int i = 0; + flags = flags; + fprintf(fp,"Global variables { "); + while (v->vars[i]) { + fprintf(fp,"%s", v->vars[i]->name); + i++; + if (v->vars[i]) fprintf(fp,", "); + } + fprintf(fp," }\n"); + return 0; +} + +/* -------------------------------------------------------------------- + swig_varlink_getattr + + This function gets the value of a variable and returns it as a + PyObject. In our case, we'll be looking at the datatype and + converting into a number or string + -------------------------------------------------------------------- */ + +static PyObject * +swig_varlink_getattr(swig_varlinkobject *v, char *n) +{ + int i = 0; + char temp[128]; + + while (v->vars[i]) { + if (strcmp(v->vars[i]->name,n) == 0) { + return (*v->vars[i]->get_attr)(); + } + i++; + } + sprintf(temp,"C global variable %s not found.", n); + PyErr_SetString(PyExc_NameError,temp); + return NULL; +} + +/* ------------------------------------------------------------------- + swig_varlink_setattr() + + This function sets the value of a variable. + ------------------------------------------------------------------- */ + +static int +swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) +{ + char temp[128]; + int i = 0; + while (v->vars[i]) { + if (strcmp(v->vars[i]->name,n) == 0) { + return (*v->vars[i]->set_attr)(p); + } + i++; + } + sprintf(temp,"C global variable %s not found.", n); + PyErr_SetString(PyExc_NameError,temp); + return 1; +} + +statichere PyTypeObject varlinktype = { +/* PyObject_HEAD_INIT(&PyType_Type) Note : This doesn't work on some machines */ + PyObject_HEAD_INIT(0) + 0, + "varlink", /* Type name */ + sizeof(swig_varlinkobject), /* Basic size */ + 0, /* Itemsize */ + 0, /* Deallocator */ + (printfunc) swig_varlink_print, /* Print */ + (getattrfunc) swig_varlink_getattr, /* get attr */ + (setattrfunc) swig_varlink_setattr, /* Set attr */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_mapping*/ + 0, /* tp_hash */ +}; + +/* Create a variable linking object for use later */ + +SWIGSTATICRUNTIME(PyObject *) +SWIG_newvarlink(void) +{ + swig_varlinkobject *result = 0; + result = PyMem_NEW(swig_varlinkobject,1); + varlinktype.ob_type = &PyType_Type; /* Patch varlinktype into a PyType */ + result->ob_type = &varlinktype; + /* _Py_NewReference(result); Does not seem to be necessary */ + result->nvars = 0; + result->maxvars = 64; + result->vars = (swig_globalvar **) malloc(64*sizeof(swig_globalvar *)); + result->vars[0] = 0; + result->ob_refcnt = 0; + Py_XINCREF((PyObject *) result); + return ((PyObject*) result); +} + +SWIGSTATICRUNTIME(void) +SWIG_addvarlink(PyObject *p, char *name, + PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) +{ + swig_varlinkobject *v; + v= (swig_varlinkobject *) p; + + if (v->nvars >= v->maxvars -1) { + v->maxvars = 2*v->maxvars; + v->vars = (swig_globalvar **) realloc(v->vars,v->maxvars*sizeof(swig_globalvar *)); + if (v->vars == NULL) { + fprintf(stderr,"SWIG : Fatal error in initializing Python module.\n"); + exit(1); + } + } + v->vars[v->nvars] = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + v->vars[v->nvars]->name = (char *) malloc(strlen(name)+1); + strcpy(v->vars[v->nvars]->name,name); + v->vars[v->nvars]->get_attr = get_attr; + v->vars[v->nvars]->set_attr = set_attr; + v->nvars++; + v->vars[v->nvars] = 0; +} + +/* ----------------------------------------------------------------------------- + * Pointer type-checking + * ----------------------------------------------------------------------------- */ + +/* SWIG pointer structure */ +typedef struct SwigPtrType { + char *name; /* Datatype name */ + int len; /* Length (used for optimization) */ + void *(*cast)(void *); /* Pointer casting function */ + struct SwigPtrType *next; /* Linked list pointer */ +} SwigPtrType; + +/* Pointer cache structure */ +typedef struct { + int stat; /* Status (valid) bit */ + SwigPtrType *tp; /* Pointer to type structure */ + char name[256]; /* Given datatype name */ + char mapped[256]; /* Equivalent name */ +} SwigCacheType; + +static int SwigPtrMax = 64; /* Max entries that can be currently held */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ +static int SwigStart[256]; /* Starting positions of types */ +static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ + +/* Cached values */ +#define SWIG_CACHESIZE 8 +#define SWIG_CACHEMASK 0x7 +static SwigCacheType SwigCache[SWIG_CACHESIZE]; +static int SwigCacheIndex = 0; +static int SwigLastCache = 0; + +/* Sort comparison function */ +static int swigsort(const void *data1, const void *data2) { + SwigPtrType *d1 = (SwigPtrType *) data1; + SwigPtrType *d2 = (SwigPtrType *) data2; + return strcmp(d1->name,d2->name); +} + +/* Register a new datatype with the type-checker */ +SWIGSTATICRUNTIME(void) +SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { + int i; + SwigPtrType *t = 0,*t1; + + /* Allocate the pointer table if necessary */ + if (!SwigPtrTable) { + SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); + } + + /* Grow the table */ + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTable = (SwigPtrType *) realloc((char *) SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); + } + for (i = 0; i < SwigPtrN; i++) { + if (strcmp(SwigPtrTable[i].name,origtype) == 0) { + t = &SwigPtrTable[i]; + break; + } + } + if (!t) { + t = &SwigPtrTable[SwigPtrN++]; + t->name = origtype; + t->len = strlen(t->name); + t->cast = 0; + t->next = 0; + } + + /* Check for existing entries */ + while (t->next) { + if ((strcmp(t->name,newtype) == 0)) { + if (cast) t->cast = cast; + return; + } + t = t->next; + } + t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + t1->name = newtype; + t1->len = strlen(t1->name); + t1->cast = cast; + t1->next = 0; + t->next = t1; + SwigPtrSort = 0; +} + +/* Make a pointer value string */ +SWIGSTATICRUNTIME(void) +SWIG_MakePtr(char *c, const void *ptr, char *type) { + static char hex[17] = "0123456789abcdef"; + unsigned long p, s; + char result[24], *r; + r = result; + p = (unsigned long) ptr; + if (p > 0) { + while (p > 0) { + s = p & 0xf; + *(r++) = hex[s]; + p = p >> 4; + } + *r = '_'; + while (r >= result) + *(c++) = *(r--); + strcpy (c, type); + } else { + strcpy (c, "NULL"); + } +} + +/* Function for getting a pointer value */ +SWIGSTATICRUNTIME(char *) +SWIG_GetPtr(char *c, void **ptr, char *t) +{ + unsigned long p; + char temp_type[256], *name; + int i, len, start, end; + SwigPtrType *sp,*tp; + SwigCacheType *cache; + register int d; + + p = 0; + /* Pointer values must start with leading underscore */ + if (*c != '_') { + *ptr = (void *) 0; + if (strcmp(c,"NULL") == 0) return (char *) 0; + else c; + } + c++; + /* Extract hex value from pointer */ + while (d = *c) { + if ((d >= '0') && (d <= '9')) + p = (p << 4) + (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + p = (p << 4) + (d - ('a'-10)); + else + break; + c++; + } + *ptr = (void *) p; + if ((!t) || (strcmp(t,c)==0)) return (char *) 0; + + if (!SwigPtrSort) { + qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); + for (i = 0; i < 256; i++) SwigStart[i] = SwigPtrN; + for (i = SwigPtrN-1; i >= 0; i--) SwigStart[(int) (SwigPtrTable[i].name[1])] = i; + for (i = 255; i >= 1; i--) { + if (SwigStart[i-1] > SwigStart[i]) + SwigStart[i-1] = SwigStart[i]; + } + SwigPtrSort = 1; + for (i = 0; i < SWIG_CACHESIZE; i++) SwigCache[i].stat = 0; + } + /* First check cache for matches. Uses last cache value as starting point */ + cache = &SwigCache[SwigLastCache]; + for (i = 0; i < SWIG_CACHESIZE; i++) { + if (cache->stat && (strcmp(t,cache->name) == 0) && (strcmp(c,cache->mapped) == 0)) { + cache->stat++; + if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); + return (char *) 0; + } + SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; + if (!SwigLastCache) cache = SwigCache; + else cache++; + } + /* Type mismatch. Look through type-mapping table */ + start = SwigStart[(int) t[1]]; + end = SwigStart[(int) t[1]+1]; + sp = &SwigPtrTable[start]; + + /* Try to find a match */ + while (start <= end) { + if (strncmp(t,sp->name,sp->len) == 0) { + name = sp->name; + len = sp->len; + tp = sp->next; + /* Try to find entry for our given datatype */ + while(tp) { + if (tp->len >= 255) { + return c; + } + strcpy(temp_type,tp->name); + strncat(temp_type,t+len,255-tp->len); + if (strcmp(c,temp_type) == 0) { + strcpy(SwigCache[SwigCacheIndex].mapped,c); + strcpy(SwigCache[SwigCacheIndex].name,t); + SwigCache[SwigCacheIndex].stat = 1; + SwigCache[SwigCacheIndex].tp = tp; + SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; + /* Get pointer value */ + *ptr = (void *) p; + if (tp->cast) *ptr = (*(tp->cast))(*ptr); + return (char *) 0; + } + tp = tp->next; + } + } + sp++; + start++; + } + return c; +} + +/* New object-based GetPointer function. This uses the Python abstract + * object interface to automatically dereference the 'this' attribute + * of shadow objects. */ + +SWIGSTATICRUNTIME(char *) +SWIG_GetPtrObj(PyObject *obj, void **ptr, char *type) { + PyObject *sobj = obj; + char *str; + if (!PyString_Check(obj)) { + sobj = PyObject_GetAttrString(obj,"this"); + if (!sobj) return ""; + } + str = PyString_AsString(sobj); + return SWIG_GetPtr(str,ptr,type); +} + +#ifdef __cplusplus +} +#endif + + diff --git a/wxPython/wxSWIG/swig_lib/python/typemaps.i b/wxPython/wxSWIG/swig_lib/python/typemaps.i new file mode 100644 index 0000000000..537511123c --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/typemaps.i @@ -0,0 +1,564 @@ +// +// SWIG Typemap library +// Dave Beazley +// May 5, 1997 +// +// Python implementation +// +// This library provides standard typemaps for modifying SWIG's behavior. +// With enough entries in this file, I hope that very few people actually +// ever need to write a typemap. +// +// Disclaimer : Unless you really understand how typemaps work, this file +// probably isn't going to make much sense. +// +#ifdef AUTODOC +%section "Typemap Library (Python)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 +%text %{ +%include typemaps.i + +The SWIG typemap library provides a language independent mechanism for +supporting output arguments, input values, and other C function +calling mechanisms. The primary use of the library is to provide a +better interface to certain C function--especially those involving +pointers. +%} + +#endif + +// ------------------------------------------------------------------------ +// Pointer handling +// +// These mappings provide support for input/output arguments and common +// uses for C/C++ pointers. +// ------------------------------------------------------------------------ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + + +#ifdef AUTODOC +%subsection "Input Methods" + +%text %{ +The following methods can be applied to turn a pointer into a simple +"input" value. That is, instead of passing a pointer to an object, +you would use a real value instead. + + int *INPUT + short *INPUT + long *INPUT + unsigned int *INPUT + unsigned short *INPUT + unsigned long *INPUT + unsigned char *INPUT + float *INPUT + double *INPUT + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + %include typemaps.i + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +%} +#endif + +%typemap(python,in) double *INPUT(double temp) +{ + temp = PyFloat_AsDouble($source); + $target = &temp; +} + +%typemap(python,in) float *INPUT(float temp) +{ + temp = (float) PyFloat_AsDouble($source); + $target = &temp; +} + +%typemap(python,in) int *INPUT(int temp) +{ + temp = (int) PyInt_AsLong($source); + $target = &temp; +} + +%typemap(python,in) short *INPUT(short temp) +{ + temp = (short) PyInt_AsLong($source); + $target = &temp; +} + +%typemap(python,in) long *INPUT(long temp) +{ + temp = (long) PyInt_AsLong($source); + $target = &temp; +} +%typemap(python,in) unsigned int *INPUT(unsigned int temp) +{ + temp = (unsigned int) PyInt_AsLong($source); + $target = &temp; +} +%typemap(python,in) unsigned short *INPUT(unsigned short temp) +{ + temp = (unsigned short) PyInt_AsLong($source); + $target = &temp; +} +%typemap(python,in) unsigned long *INPUT(unsigned long temp) +{ + temp = (unsigned long) PyInt_AsLong($source); + $target = &temp; +} +%typemap(python,in) unsigned char *INPUT(unsigned char temp) +{ + temp = (unsigned char) PyInt_AsLong($source); + $target = &temp; +} + +%typemap(python,in) signed char *INPUT(signed char temp) +{ + temp = (unsigned char) PyInt_AsLong($source); + $target = &temp; +} + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + +#ifdef AUTODOC +%subsection "Output Methods" + +%text %{ +The following methods can be applied to turn a pointer into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. In the case of +multiple output values, they are returned in the form of a Python tuple. + + int *OUTPUT + short *OUTPUT + long *OUTPUT + unsigned int *OUTPUT + unsigned short *OUTPUT + unsigned long *OUTPUT + unsigned char *OUTPUT + float *OUTPUT + double *OUTPUT + +A Python List can also be returned by using L_OUTPUT instead of OUTPUT. + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters).K: + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include typemaps.i + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Python output of the function would be a tuple containing both +output values. +%} +#endif + + +// I don't use this anywhere, get rid of it... + +// Helper function for List output +// static PyObject* l_output_helper(PyObject* target, PyObject* o) { +// PyObject* o2; +// if (!target) { +// target = o; +// } else if (target == Py_None) { +// Py_DECREF(Py_None); +// target = o; +// } else { +// if (!PyList_Check(target)) { +// o2 = target; +// target = PyList_New(0); +// PyList_Append(target, o2); +// Py_XDECREF(o2); +// } +// PyList_Append(target,o); +// Py_XDECREF(o); +// } +// return target; +// } + +%{ +%} + +// Force the argument to be ignored. + +%typemap(python,ignore) int *L_OUTPUT(int temp), + short *L_OUTPUT(short temp), + long *L_OUTPUT(long temp), + unsigned int *L_OUTPUT(unsigned int temp), + unsigned short *L_OUTPUT(unsigned short temp), + unsigned long *L_OUTPUT(unsigned long temp), + unsigned char *L_OUTPUT(unsigned char temp), + signed char *L_OUTPUT(signed char temp), + float *L_OUTPUT(float temp), + double *L_OUTPUT(double temp) +{ + $target = &temp; +} + +%typemap(python,argout) int *L_OUTPUT, + short *L_OUTPUT, + long *L_OUTPUT, + unsigned int *L_OUTPUT, + unsigned short *L_OUTPUT, + unsigned long *L_OUTPUT, + unsigned char *L_OUTPUT, + signed char *L_OUTPUT +{ + PyObject *o; + o = PyInt_FromLong((long) (*$source)); + l_output_helper($target,o); +} + +%typemap(python,argout) float *L_OUTPUT, + double *L_OUTPUT +{ + PyObject *o; + o = PyFloat_FromDouble((double) (*$source)); + $target = l_output_helper($target,o); +} + +// These typemaps contributed by Robin Dunn +//---------------------------------------------------------------------- +// +// T_OUTPUT typemap (and helper function) to return multiple argouts as +// a tuple instead of a list. +// +// Author: Robin Dunn +//---------------------------------------------------------------------- + +%{ +static PyObject* t_output_helper(PyObject* target, PyObject* o) { + PyObject* o2; + PyObject* o3; + + if (!target) { + target = o; + } else if (target == Py_None) { + Py_DECREF(Py_None); + target = o; + } else { + if (!PyTuple_Check(target)) { + o2 = target; + target = PyTuple_New(1); + PyTuple_SetItem(target, 0, o2); + } + o3 = PyTuple_New(1); + PyTuple_SetItem(o3, 0, o); + + o2 = target; + target = PySequence_Concat(o2, o3); + Py_DECREF(o2); + Py_DECREF(o3); + } + return target; +} +%} + +// Force the argument to be ignored. +%typemap(python,ignore) int *T_OUTPUT(int temp), + short *T_OUTPUT(short temp), + long *T_OUTPUT(long temp), + unsigned int *T_OUTPUT(unsigned int temp), + unsigned short *T_OUTPUT(unsigned short temp), + unsigned long *T_OUTPUT(unsigned long temp), + unsigned char *T_OUTPUT(unsigned char temp), + float *T_OUTPUT(float temp), + double *T_OUTPUT(double temp) +{ + $target = &temp; +} + +%typemap(python,argout) int *T_OUTPUT, + short *T_OUTPUT, + long *T_OUTPUT, + unsigned int *T_OUTPUT, + unsigned short *T_OUTPUT, + unsigned long *T_OUTPUT, + unsigned char *T_OUTPUT +{ + PyObject *o; + o = PyInt_FromLong((long) (*$source)); + $target = t_output_helper($target, o); +} + +%typemap(python,argout) float *T_OUTPUT, + double *T_OUTPUT +{ + PyObject *o; + o = PyFloat_FromDouble((double) (*$source)); + $target = t_output_helper($target, o); +} + +// Set the default output typemap + +#ifdef OUTPUT_LIST +%typemap(python,ignore) int *OUTPUT = int *L_OUTPUT; +%typemap(python,ignore) short *OUTPUT = short *L_OUTPUT; +%typemap(python,ignore) long *OUTPUT = long *L_OUTPUT; +%typemap(python,ignore) unsigned *OUTPUT = unsigned *L_OUTPUT; +%typemap(python,ignore) unsigned short *OUTPUT = unsigned short *L_OUTPUT; +%typemap(python,ignore) unsigned long *OUTPUT = unsigned long *L_OUTPUT; +%typemap(python,ignore) unsigned char *OUTPUT = unsigned char *L_OUTPUT; +%typemap(python,ignore) signed char *OUTPUT = signed char *L_OUTPUT; +%typemap(python,ignore) double *OUTPUT = double *L_OUTPUT; +%typemap(python,ignore) float *OUTPUT = float *L_OUTPUT; + +%typemap(python,argout) int *OUTPUT = int *L_OUTPUT; +%typemap(python,argout) short *OUTPUT = short *L_OUTPUT; +%typemap(python,argout) long *OUTPUT = long *L_OUTPUT; +%typemap(python,argout) unsigned *OUTPUT = unsigned *L_OUTPUT; +%typemap(python,argout) unsigned short *OUTPUT = unsigned short *L_OUTPUT; +%typemap(python,argout) unsigned long *OUTPUT = unsigned long *L_OUTPUT; +%typemap(python,argout) unsigned char *OUTPUT = unsigned char *L_OUTPUT; +%typemap(python,argout) signed char *OUTPUT = signed char *L_OUTPUT; +%typemap(python,argout) double *OUTPUT = double *L_OUTPUT; +%typemap(python,argout) float *OUTPUT = float *L_OUTPUT; +#else +%typemap(python,ignore) int *OUTPUT = int *T_OUTPUT; +%typemap(python,ignore) short *OUTPUT = short *T_OUTPUT; +%typemap(python,ignore) long *OUTPUT = long *T_OUTPUT; +%typemap(python,ignore) unsigned *OUTPUT = unsigned *T_OUTPUT; +%typemap(python,ignore) unsigned short *OUTPUT = unsigned short *T_OUTPUT; +%typemap(python,ignore) unsigned long *OUTPUT = unsigned long *T_OUTPUT; +%typemap(python,ignore) unsigned char *OUTPUT = unsigned char *T_OUTPUT; +%typemap(python,ignore) signed char *OUTPUT = signed char *T_OUTPUT; +%typemap(python,ignore) double *OUTPUT = double *T_OUTPUT; +%typemap(python,ignore) float *OUTPUT = float *T_OUTPUT; + +%typemap(python,argout) int *OUTPUT = int *T_OUTPUT; +%typemap(python,argout) short *OUTPUT = short *T_OUTPUT; +%typemap(python,argout) long *OUTPUT = long *T_OUTPUT; +%typemap(python,argout) unsigned *OUTPUT = unsigned *T_OUTPUT; +%typemap(python,argout) unsigned short *OUTPUT = unsigned short *T_OUTPUT; +%typemap(python,argout) unsigned long *OUTPUT = unsigned long *T_OUTPUT; +%typemap(python,argout) unsigned char *OUTPUT = unsigned char *T_OUTPUT; +%typemap(python,argout) signed char *OUTPUT = signed char *T_OUTPUT; +%typemap(python,argout) double *OUTPUT = double *T_OUTPUT; +%typemap(python,argout) float *OUTPUT = float *T_OUTPUT; +#endif + +// INOUT +// Mappings for an argument that is both an input and output +// parameter + + +#ifdef AUTODOC +%subsection "Input/Output Methods" + +%text %{ +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned in the form of a Python tuple. To return a Python list, +using L_INOUT instead. + + int *INOUT + short *INOUT + long *INOUT + unsigned int *INOUT + unsigned short *INOUT + unsigned long *INOUT + unsigned char *INOUT + float *INOUT + double *INOUT + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include typemaps.i + void neg(double *INOUT); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *INOUT { double *x }; + void neg(double *x); + +Unlike C, this mapping does not directly modify the input value (since +this makes no sense in Python). Rather, the modified input value shows +up as the return value of the function. Thus, to apply this function +to a Python variable you might do this : + + x = neg(x) + +Note : previous versions of SWIG used the symbol 'BOTH' to mark +input/output arguments. This is still supported, but will be slowly +phased out in future releases. +%} + +#endif + +%typemap(python,in) int *INOUT = int *INPUT; +%typemap(python,in) short *INOUT = short *INPUT; +%typemap(python,in) long *INOUT = long *INPUT; +%typemap(python,in) unsigned *INOUT = unsigned *INPUT; +%typemap(python,in) unsigned short *INOUT = unsigned short *INPUT; +%typemap(python,in) unsigned long *INOUT = unsigned long *INPUT; +%typemap(python,in) unsigned char *INOUT = unsigned char *INPUT; +%typemap(python,in) float *INOUT = float *INPUT; +%typemap(python,in) double *INOUT = double *INPUT; + +%typemap(python,argout) int *INOUT = int *OUTPUT; +%typemap(python,argout) short *INOUT = short *OUTPUT; +%typemap(python,argout) long *INOUT = long *OUTPUT; +%typemap(python,argout) unsigned *INOUT = unsigned *OUTPUT; +%typemap(python,argout) unsigned short *INOUT = unsigned short *OUTPUT; +%typemap(python,argout) unsigned long *INOUT = unsigned long *OUTPUT; +%typemap(python,argout) unsigned char *INOUT = unsigned char *OUTPUT; +%typemap(python,argout) float *INOUT = float *OUTPUT; +%typemap(python,argout) double *INOUT = double *OUTPUT; + +%typemap(python,in) int *T_INOUT = int *INPUT; +%typemap(python,in) short *T_INOUT = short *INPUT; +%typemap(python,in) long *T_INOUT = long *INPUT; +%typemap(python,in) unsigned *T_INOUT = unsigned *INPUT; +%typemap(python,in) unsigned short *T_INOUT = unsigned short *INPUT; +%typemap(python,in) unsigned long *T_INOUT = unsigned long *INPUT; +%typemap(python,in) unsigned char *T_INOUT = unsigned char *INPUT; +%typemap(python,in) float *T_INOUT = float *INPUT; +%typemap(python,in) double *T_INOUT = double *INPUT; + +%typemap(python,argout) int *T_INOUT = int *T_OUTPUT; +%typemap(python,argout) short *T_INOUT = short *T_OUTPUT; +%typemap(python,argout) long *T_INOUT = long *T_OUTPUT; +%typemap(python,argout) unsigned *T_INOUT = unsigned *T_OUTPUT; +%typemap(python,argout) unsigned short *T_INOUT = unsigned short *T_OUTPUT; +%typemap(python,argout) unsigned long *T_INOUT = unsigned long *T_OUTPUT; +%typemap(python,argout) unsigned char *T_INOUT = unsigned char *T_OUTPUT; +%typemap(python,argout) float *T_INOUT = float *T_OUTPUT; +%typemap(python,argout) double *T_INOUT = double *T_OUTPUT; + +%typemap(python,in) int *L_INOUT = int *INPUT; +%typemap(python,in) short *L_INOUT = short *INPUT; +%typemap(python,in) long *L_INOUT = long *INPUT; +%typemap(python,in) unsigned *L_INOUT = unsigned *INPUT; +%typemap(python,in) unsigned short *L_INOUT = unsigned short *INPUT; +%typemap(python,in) unsigned long *L_INOUT = unsigned long *INPUT; +%typemap(python,in) unsigned char *L_INOUT = unsigned char *INPUT; +%typemap(python,in) float *L_INOUT = float *INPUT; +%typemap(python,in) double *L_INOUT = double *INPUT; + +%typemap(python,argout) int *L_INOUT = int *L_OUTPUT; +%typemap(python,argout) short *L_INOUT = short *L_OUTPUT; +%typemap(python,argout) long *L_INOUT = long *L_OUTPUT; +%typemap(python,argout) unsigned *L_INOUT = unsigned *L_OUTPUT; +%typemap(python,argout) unsigned short *L_INOUT = unsigned short *L_OUTPUT; +%typemap(python,argout) unsigned long *L_INOUT = unsigned long *L_OUTPUT; +%typemap(python,argout) unsigned char *L_INOUT = unsigned char *L_OUTPUT; +%typemap(python,argout) float *L_INOUT = float *L_OUTPUT; +%typemap(python,argout) double *L_INOUT = double *L_OUTPUT; + +// Backwards compatibility + +%typemap(python,in) int *BOTH = int *INOUT; +%typemap(python,in) short *BOTH = short *INOUT; +%typemap(python,in) long *BOTH = long *INOUT; +%typemap(python,in) unsigned *BOTH = unsigned *INOUT; +%typemap(python,in) unsigned short *BOTH = unsigned short *INOUT; +%typemap(python,in) unsigned long *BOTH = unsigned long *INOUT; +%typemap(python,in) unsigned char *BOTH = unsigned char *INOUT; +%typemap(python,in) float *BOTH = float *INOUT; +%typemap(python,in) double *BOTH = double *INOUT; + +%typemap(python,argout) int *BOTH = int *INOUT; +%typemap(python,argout) short *BOTH = short *INOUT; +%typemap(python,argout) long *BOTH = long *INOUT; +%typemap(python,argout) unsigned *BOTH = unsigned *INOUT; +%typemap(python,argout) unsigned short *BOTH = unsigned short *INOUT; +%typemap(python,argout) unsigned long *BOTH = unsigned long *INOUT; +%typemap(python,argout) unsigned char *BOTH = unsigned char *INOUT; +%typemap(python,argout) float *BOTH = float *INOUT; +%typemap(python,argout) double *BOTH = double *INOUT; + +%typemap(python,in) int *T_BOTH = int *T_INOUT; +%typemap(python,in) short *T_BOTH = short *T_INOUT; +%typemap(python,in) long *T_BOTH = long *T_INOUT; +%typemap(python,in) unsigned *T_BOTH = unsigned *T_INOUT; +%typemap(python,in) unsigned short *T_BOTH = unsigned short *T_INOUT; +%typemap(python,in) unsigned long *T_BOTH = unsigned long *T_INOUT; +%typemap(python,in) unsigned char *T_BOTH = unsigned char *T_INOUT; +%typemap(python,in) float *T_BOTH = float *T_INOUT; +%typemap(python,in) double *T_BOTH = double *T_INOUT; + +%typemap(python,argout) int *T_BOTH = int *T_INOUT; +%typemap(python,argout) short *T_BOTH = short *T_INOUT; +%typemap(python,argout) long *T_BOTH = long *T_INOUT; +%typemap(python,argout) unsigned *T_BOTH = unsigned *T_INOUT; +%typemap(python,argout) unsigned short *T_BOTH = unsigned short *T_INOUT; +%typemap(python,argout) unsigned long *T_BOTH = unsigned long *T_INOUT; +%typemap(python,argout) unsigned char *T_BOTH = unsigned char *T_INOUT; +%typemap(python,argout) float *T_BOTH = float *T_INOUT; +%typemap(python,argout) double *T_BOTH = double *T_INOUT; + +// -------------------------------------------------------------------- +// Special types +// +// -------------------------------------------------------------------- + +#ifdef AUTODOC +%subsection "Special Methods" + +%text %{ +The typemaps.i library also provides the following mappings : + +PyObject * + + When a PyObject * appears as either an input value or return + value of a function, SWIG passes it through unmodified. Thus, + if you want to write a C function that operates on PyObjects, + it is easy to write. For example : + + %include typemaps.i + PyObject *spam(PyObject *obj1, int n); + + Unlike normal Python wrapper functions, These functions can + use any combination of parameters that you wish. + +%} + +#endif + + +// If a PyObject * appears as either an argument or a function return +// value, simply pass it straight through. + +%typemap(python,in) PyObject * { + $target = $source; +} + +%typemap(python,out) PyObject * { + $target = $source; +} + diff --git a/wxPython/wxSWIG/swig_lib/stdlib.i b/wxPython/wxSWIG/swig_lib/stdlib.i new file mode 100644 index 0000000000..e48616b900 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/stdlib.i @@ -0,0 +1,50 @@ +// +// $Header$ +// +// stdlib.i +// Dave Beazley +// March 24, 1996 +// SWIG file for some C stdlib functions +// +/* Revision history + * $Log$ + * Revision 1.1 2002/04/29 19:56:49 RD + * Since I have made several changes to SWIG over the years to accomodate + * special cases and other things in wxPython, and since I plan on making + * several more, I've decided to put the SWIG sources in wxPython's CVS + * instead of relying on maintaining patches. This effectivly becomes a + * fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * doesn't have some things I rely on in 1.1, not to mention that my + * custom patches would all have to be redone, I felt that this is the + * easier road to take. + * + * Revision 1.1.1.1 1999/02/28 02:00:53 beazley + * Swig1.1 + * + * Revision 1.1 1996/05/22 17:27:01 beazley + * Initial revision + * + */ + +%module stdlib +%{ +#include +%} + +typedef unsigned int size_t; + +double atof(const char *s); +int atoi(const char *s); +long atol(const char *s); +int rand(); +void srand(unsigned int seed); +void *calloc(size_t nobj, size_t size); +void *malloc(size_t size); +void *realloc(void *ptr, size_t size); +void free(void *ptr); +void abort(void); +int system(const char *s); +char *getenv(const char *name); +int abs(int n); +long labs(long n); + diff --git a/wxPython/wxSWIG/swig_lib/swigptr.swg b/wxPython/wxSWIG/swig_lib/swigptr.swg new file mode 100644 index 0000000000..ed8de62d75 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/swigptr.swg @@ -0,0 +1,326 @@ +/***************************************************************************** + * $Header$ + * + * swigptr.swg + * + * This file contains supporting code for the SWIG run-time type checking + * mechanism. The following functions are available : + * + * SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)); + * + * Registers a new type-mapping with the type-checker. origtype is the + * original datatype and newtype is an equivalent type. cast is optional + * pointer to a function to cast pointer values between types (this + * is typically used to cast pointers from derived classes to base classes in C++) + * + * SWIG_MakePtr(char *buffer, void *ptr, char *typestring); + * + * Makes a pointer string from a pointer and typestring. The result is returned + * in buffer which is assumed to hold enough space for the result. + * + * char * SWIG_GetPtr(char *buffer, void **ptr, char *type) + * + * Gets a pointer value from a string. If there is a type-mismatch, returns + * a character string to the received type. On success, returns NULL. + * + * + * You can remap these functions by making a file called "swigptr.swg" in + * your the same directory as the interface file you are wrapping. + * + * These functions are normally declared static, but this file can be + * can be used in a multi-module environment by redefining the symbol + * SWIGSTATIC. + *****************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SWIG_GLOBAL +#define SWIGSTATIC +#endif + +#ifndef SWIGSTATIC +#define SWIGSTATIC static +#endif + + + +/* SWIG pointer structure */ + +typedef struct SwigPtrType { + char *name; /* Datatype name */ + int len; /* Length (used for optimization) */ + void *(*cast)(void *); /* Pointer casting function */ + struct SwigPtrType *next; /* Linked list pointer */ +} SwigPtrType; + +/* Pointer cache structure */ + +typedef struct { + int stat; /* Status (valid) bit */ + SwigPtrType *tp; /* Pointer to type structure */ + char name[256]; /* Given datatype name */ + char mapped[256]; /* Equivalent name */ +} SwigCacheType; + +/* Some variables */ + +static int SwigPtrMax = 64; /* Max entries that can be currently held */ + /* This value may be adjusted dynamically */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ +static int SwigStart[256]; /* Starting positions of types */ + +/* Pointer table */ +static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ + +/* Cached values */ + +#define SWIG_CACHESIZE 8 +#define SWIG_CACHEMASK 0x7 +static SwigCacheType SwigCache[SWIG_CACHESIZE]; +static int SwigCacheIndex = 0; +static int SwigLastCache = 0; + +/* Sort comparison function */ +static int swigsort(const void *data1, const void *data2) { + SwigPtrType *d1 = (SwigPtrType *) data1; + SwigPtrType *d2 = (SwigPtrType *) data2; + return strcmp(d1->name,d2->name); +} + +/* Binary Search function */ +static int swigcmp(const void *key, const void *data) { + char *k = (char *) key; + SwigPtrType *d = (SwigPtrType *) data; + return strncmp(k,d->name,d->len); +} + +/* Register a new datatype with the type-checker */ + +SWIGSTATIC +void SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { + + int i; + SwigPtrType *t = 0,*t1; + + /* Allocate the pointer table if necessary */ + + if (!SwigPtrTable) { + SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); + SwigPtrN = 0; + } + /* Grow the table */ + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTable = (SwigPtrType *) realloc((char *) SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); + } + for (i = 0; i < SwigPtrN; i++) + if (strcmp(SwigPtrTable[i].name,origtype) == 0) { + t = &SwigPtrTable[i]; + break; + } + if (!t) { + t = &SwigPtrTable[SwigPtrN]; + t->name = origtype; + t->len = strlen(t->name); + t->cast = 0; + t->next = 0; + SwigPtrN++; + } + + /* Check for existing entry */ + + while (t->next) { + if ((strcmp(t->name,newtype) == 0)) { + if (cast) t->cast = cast; + return; + } + t = t->next; + } + + /* Now place entry (in sorted order) */ + + t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + t1->name = newtype; + t1->len = strlen(t1->name); + t1->cast = cast; + t1->next = 0; + t->next = t1; + SwigPtrSort = 0; +} + +/* Make a pointer value string */ + +SWIGSTATIC +void SWIG_MakePtr(char *_c, const void *_ptr, char *type) { + static char _hex[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + unsigned long _p, _s; + char _result[20], *_r; /* Note : a 64-bit hex number = 16 digits */ + _r = _result; + _p = (unsigned long) _ptr; + if (_p > 0) { + while (_p > 0) { + _s = _p & 0xf; + *(_r++) = _hex[_s]; + _p = _p >> 4; + } + *_r = '_'; + while (_r >= _result) + *(_c++) = *(_r--); + } else { + strcpy (_c, "NULL"); + } + if (_ptr) + strcpy (_c, type); +} + +/* Define for backwards compatibility */ + +#define _swig_make_hex SWIG_MakePtr + +/* Function for getting a pointer value */ + +SWIGSTATIC +char *SWIG_GetPtr(char *_c, void **ptr, char *_t) +{ + unsigned long _p; + char temp_type[256]; + char *name; + int i, len; + SwigPtrType *sp,*tp; + SwigCacheType *cache; + int start, end; + _p = 0; + + /* Pointer values must start with leading underscore */ + if (*_c == '_') { + _c++; + /* Extract hex value from pointer */ + while (*_c) { + if ((*_c >= '0') && (*_c <= '9')) + _p = (_p << 4) + (*_c - '0'); + else if ((*_c >= 'a') && (*_c <= 'f')) + _p = (_p << 4) + ((*_c - 'a') + 10); + else + break; + _c++; + } + + if (_t) { + if (strcmp(_t,_c)) { + if (!SwigPtrSort) { + qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); + for (i = 0; i < 256; i++) { + SwigStart[i] = SwigPtrN; + } + for (i = SwigPtrN-1; i >= 0; i--) { + SwigStart[(int) (SwigPtrTable[i].name[1])] = i; + } + for (i = 255; i >= 1; i--) { + if (SwigStart[i-1] > SwigStart[i]) + SwigStart[i-1] = SwigStart[i]; + } + SwigPtrSort = 1; + for (i = 0; i < SWIG_CACHESIZE; i++) + SwigCache[i].stat = 0; + } + + /* First check cache for matches. Uses last cache value as starting point */ + cache = &SwigCache[SwigLastCache]; + for (i = 0; i < SWIG_CACHESIZE; i++) { + if (cache->stat) { + if (strcmp(_t,cache->name) == 0) { + if (strcmp(_c,cache->mapped) == 0) { + cache->stat++; + *ptr = (void *) _p; + if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); + return (char *) 0; + } + } + } + SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; + if (!SwigLastCache) cache = SwigCache; + else cache++; + } + /* We have a type mismatch. Will have to look through our type + mapping table to figure out whether or not we can accept this datatype */ + + start = SwigStart[(int) _t[1]]; + end = SwigStart[(int) _t[1]+1]; + sp = &SwigPtrTable[start]; + while (start < end) { + if (swigcmp(_t,sp) == 0) break; + sp++; + start++; + } + if (start > end) sp = 0; + /* Try to find a match for this */ + while (start <= end) { + if (swigcmp(_t,sp) == 0) { + name = sp->name; + len = sp->len; + tp = sp->next; + /* Try to find entry for our given datatype */ + while(tp) { + if (tp->len >= 255) { + return _c; + } + strcpy(temp_type,tp->name); + strncat(temp_type,_t+len,255-tp->len); + if (strcmp(_c,temp_type) == 0) { + + strcpy(SwigCache[SwigCacheIndex].mapped,_c); + strcpy(SwigCache[SwigCacheIndex].name,_t); + SwigCache[SwigCacheIndex].stat = 1; + SwigCache[SwigCacheIndex].tp = tp; + SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; + + /* Get pointer value */ + *ptr = (void *) _p; + if (tp->cast) *ptr = (*(tp->cast))(*ptr); + return (char *) 0; + } + tp = tp->next; + } + } + sp++; + start++; + } + /* Didn't find any sort of match for this data. + Get the pointer value and return the received type */ + *ptr = (void *) _p; + return _c; + } else { + /* Found a match on the first try. Return pointer value */ + *ptr = (void *) _p; + return (char *) 0; + } + } else { + /* No type specified. Good luck */ + *ptr = (void *) _p; + return (char *) 0; + } + } else { + if (strcmp (_c, "NULL") == 0) { + *ptr = (void *) 0; + return (char *) 0; + } + *ptr = (void *) 0; + return _c; + } +} + +/* Compatibility mode */ + +#define _swig_get_hex SWIG_GetPtr + +#ifdef __cplusplus +} +#endif + diff --git a/wxPython/wxSWIG/swig_lib/tcl/Makefile b/wxPython/wxSWIG/swig_lib/tcl/Makefile new file mode 100644 index 0000000000..f24b05ccdc --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/Makefile @@ -0,0 +1,135 @@ +# Generated automatically from Makefile.in by configure. +# --------------------------------------------------------------- +# $Header$ +# SWIG Tcl/Tk Makefile +# +# This file can be used to build various Tcl extensions with SWIG. +# By default this file is set up for dynamic loading, but it can +# be easily customized for static extensions by modifying various +# portions of the file. +# +# SRCS = C source files +# CXXSRCS = C++ source files +# OBJCSRCS = Objective-C source files +# OBJS = Additional .o files (compiled previously) +# INTERFACE = SWIG interface file +# TARGET = Name of target module or executable +# +# Many portions of this file were created by the SWIG configure +# script and should already reflect your machine. However, you +# may need to modify the Makefile to reflect your specific +# application. +#---------------------------------------------------------------- + +SRCS = +CXXSRCS = +OBJCSRCS = +OBJS = +INTERFACE = +WRAPFILE = $(INTERFACE:.i=_wrap.c) +WRAPOBJ = $(INTERFACE:.i=_wrap.o) +TARGET = module.so # Use this kind of target for dynamic loading +#TARGET = my_tclsh # Use this target for static linking + +prefix = /usr/local +exec_prefix = ${prefix} + +CC = cc +CXX = CC +OBJC = cc -Wno-import # -Wno-import needed for gcc +CFLAGS = +INCLUDE = +LIBS = + +# SWIG Options +# SWIG = location of the SWIG executable +# SWIGOPT = SWIG compiler options +# SWIGCC = Compiler used to compile the wrapper file + +SWIG = $(exec_prefix)/bin/swig +SWIGOPT = -tcl # use -tcl8 for Tcl 8.0 +SWIGCC = $(CC) + +# SWIG Library files. Uncomment one of these for rebuilding tclsh or wish +#SWIGLIB = -ltclsh.i +#SWIGLIB = -lwish.i + +# Rules for creating .o files from source. + +COBJS = $(SRCS:.c=.o) +CXXOBJS = $(CXXSRCS:.cxx=.o) +OBJCOBJS = $(OBJCSRCS:.m=.o) +ALLOBJS = $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(OBJS) + +# Command that will be used to build the final extension. +BUILD = $(SWIGCC) + +# Uncomment the following if you are using dynamic loading +CCSHARED = +BUILD = ld -G + +# Uncomment the following if you are using dynamic loading with C++ and +# need to provide additional link libraries (this is not always required). + +#DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ + -L/usr/local/lib -lg++ -lstdc++ -lgcc + +# X11 installation (needed to rebuild Tk extensions) + +XLIB = -L/usr/openwin/lib -lX11 +XINCLUDE = -I/usr/openwin/include + +# Tcl installation (where is Tcl/Tk located) + +TCL_INCLUDE = -I/usr/local/include +TCL_LIB = -L/usr/local/lib + +# Build libraries (needed for static builds) + +LIBM = -lm +LIBC = +SYSLIBS = $(LIBM) $(LIBC) -lsocket -lnsl -ldl + +# Build options (uncomment only one these) + +BUILD_LIBS = $(LIBS) # Dynamic loading +#BUILD_LIBS = $(TCL_LIB) -ltcl $(LIBS) $(SYSLIBS) # tclsh +#BUILD_LIBS = $(TCL_LIB) -ltk -ltcl $(XLIB) $(LIBS) $(SYSLIBS) # wish + +# Compilation rules for non-SWIG components + +.SUFFIXES: .c .cxx .m + +.c.o: + $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + +.cxx.o: + $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDE) -c $< + +.m.o: + $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + + +# ---------------------------------------------------------------------- +# Rules for building the extension +# ---------------------------------------------------------------------- + +all: $(TARGET) + +# Convert the wrapper file into an object file + +$(WRAPOBJ) : $(WRAPFILE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDE) $(TCL_INCLUDE) + +$(WRAPFILE) : $(INTERFACE) + $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) + +$(TARGET): $(WRAPOBJ) $(ALLOBJS) + $(BUILD) $(WRAPOBJ) $(ALLOBJS) $(BUILD_LIBS) -o $(TARGET) + +clean: + rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) + + + + diff --git a/wxPython/wxSWIG/swig_lib/tcl/Makefile.in b/wxPython/wxSWIG/swig_lib/tcl/Makefile.in new file mode 100644 index 0000000000..3ba07d4a3e --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/Makefile.in @@ -0,0 +1,134 @@ +# --------------------------------------------------------------- +# $Header$ +# SWIG Tcl/Tk Makefile +# +# This file can be used to build various Tcl extensions with SWIG. +# By default this file is set up for dynamic loading, but it can +# be easily customized for static extensions by modifying various +# portions of the file. +# +# SRCS = C source files +# CXXSRCS = C++ source files +# OBJCSRCS = Objective-C source files +# OBJS = Additional .o files (compiled previously) +# INTERFACE = SWIG interface file +# TARGET = Name of target module or executable +# +# Many portions of this file were created by the SWIG configure +# script and should already reflect your machine. However, you +# may need to modify the Makefile to reflect your specific +# application. +#---------------------------------------------------------------- + +SRCS = +CXXSRCS = +OBJCSRCS = +OBJS = +INTERFACE = +WRAPFILE = $(INTERFACE:.i=_wrap.c) +WRAPOBJ = $(INTERFACE:.i=_wrap.o) +TARGET = module@SO@ # Use this kind of target for dynamic loading +#TARGET = my_tclsh # Use this target for static linking + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +CC = @CC@ +CXX = @CXX@ +OBJC = @CC@ -Wno-import # -Wno-import needed for gcc +CFLAGS = +INCLUDE = +LIBS = + +# SWIG Options +# SWIG = location of the SWIG executable +# SWIGOPT = SWIG compiler options +# SWIGCC = Compiler used to compile the wrapper file + +SWIG = $(exec_prefix)/bin/swig +SWIGOPT = -tcl # use -tcl8 for Tcl 8.0 +SWIGCC = $(CC) + +# SWIG Library files. Uncomment one of these for rebuilding tclsh or wish +#SWIGLIB = -ltclsh.i +#SWIGLIB = -lwish.i + +# Rules for creating .o files from source. + +COBJS = $(SRCS:.c=.o) +CXXOBJS = $(CXXSRCS:.cxx=.o) +OBJCOBJS = $(OBJCSRCS:.m=.o) +ALLOBJS = $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(OBJS) + +# Command that will be used to build the final extension. +BUILD = $(SWIGCC) + +# Uncomment the following if you are using dynamic loading +CCSHARED = @CCSHARED@ +BUILD = @LDSHARED@ + +# Uncomment the following if you are using dynamic loading with C++ and +# need to provide additional link libraries (this is not always required). + +#DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ + -L/usr/local/lib -lg++ -lstdc++ -lgcc + +# X11 installation (needed to rebuild Tk extensions) + +XLIB = @XLIBSW@ +XINCLUDE = @XINCLUDES@ + +# Tcl installation (where is Tcl/Tk located) + +TCL_INCLUDE = @TCLINCLUDE@ +TCL_LIB = @TCLLIB@ + +# Build libraries (needed for static builds) + +LIBM = @LIBM@ +LIBC = @LIBC@ +SYSLIBS = $(LIBM) $(LIBC) @LIBS@ + +# Build options (uncomment only one these) + +BUILD_LIBS = $(LIBS) # Dynamic loading +#BUILD_LIBS = $(TCL_LIB) -ltcl $(LIBS) $(SYSLIBS) # tclsh +#BUILD_LIBS = $(TCL_LIB) -ltk -ltcl $(XLIB) $(LIBS) $(SYSLIBS) # wish + +# Compilation rules for non-SWIG components + +.SUFFIXES: .c .cxx .m + +.c.o: + $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + +.cxx.o: + $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDE) -c $< + +.m.o: + $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDE) -c $< + + +# ---------------------------------------------------------------------- +# Rules for building the extension +# ---------------------------------------------------------------------- + +all: $(TARGET) + +# Convert the wrapper file into an object file + +$(WRAPOBJ) : $(WRAPFILE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDE) $(TCL_INCLUDE) + +$(WRAPFILE) : $(INTERFACE) + $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) + +$(TARGET): $(WRAPOBJ) $(ALLOBJS) + $(BUILD) $(WRAPOBJ) $(ALLOBJS) $(BUILD_LIBS) -o $(TARGET) + +clean: + rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) + + + + diff --git a/wxPython/wxSWIG/swig_lib/tcl/blt.i b/wxPython/wxSWIG/swig_lib/tcl/blt.i new file mode 100644 index 0000000000..efe1871537 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/blt.i @@ -0,0 +1,28 @@ +// Initialization code for BLT +%{ +#ifdef __cplusplus +extern "C" { +#endif +extern int Blt_Init(Tcl_Interp *); +#ifdef __cplusplus +} +#endif +%} + +#ifdef AUTODOC +%subsection "blt.i" +%text %{ +This module initializes the BLT package. This is usually done in +combination with the wish.i or similar module. For example : + + %include wish.i // Build a new wish executable + %include blt.i // Initialize BLT +%} +#endif + +%init %{ + if (Blt_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +%} + diff --git a/wxPython/wxSWIG/swig_lib/tcl/configcode.swg b/wxPython/wxSWIG/swig_lib/tcl/configcode.swg new file mode 100644 index 0000000000..46c370c426 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/configcode.swg @@ -0,0 +1,27 @@ +/* configcode.swg */ + + else if ((*(argv[1]) == 'c') && (strncmp(argv[1],"configure") == 0) && (argv[1][1])) { + int i = 2; + cmd = 0; + while (i+1 < argc) { + @CONFIGMETHODS@ + if (cmd) { + oldarg = argv[i]; + argv[i] = &temp[0]; + rcode = (*cmd)(clientData,interp,3,&argv[i-1]); + argv[i] = oldarg; + if (rcode == TCL_ERROR) return rcode; + cmd = 0; + } else { + Tcl_SetResult(interp,"Invalid configure option. Must be { @CONFIGLIST@ }",TCL_STATIC); + return TCL_ERROR; + } + i+=2; + } + if ((i < argc) || (i == 2)) { + Tcl_SetResult(interp,"{ @CONFIGLIST@ }",TCL_STATIC); + return TCL_ERROR; + } + return TCL_OK; + } + diff --git a/wxPython/wxSWIG/swig_lib/tcl/constarray.i b/wxPython/wxSWIG/swig_lib/tcl/constarray.i new file mode 100644 index 0000000000..d9a4dc290b --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/constarray.i @@ -0,0 +1,108 @@ +// constarray.i +// +// This module changes SWIG to place constant values into a Tcl array + + +#ifdef AUTODOC +%subsection "Array Constants",pre +%text %{ +%include constarray.i + +This module changes SWIG so that constant values are placed into a Tcl +array instead of global variables. The array is given the same name as +the SWIG module (specified with the %module directive). + +This module should generally be included at the top of an interface +file before any declarations appear. Furthermore, this module changes +the default handling of basic datatypes including integers, floats, +and character strings. + +When this module is used, constants are simply accessed through the +module name. For example : + + %module example + ... + #define FOO 42 + +would be accessed as '$example(FOO)' + +Note : This module replaces the existing mechanism for creating constants. +The method used by this module is based on a set of typemaps supplied +by Tim Medley. +%} +#endif + +%typemap(tcl,const) int SWIG_DEFAULT_TYPE, + unsigned int SWIG_DEFAULT_TYPE, + long SWIG_DEFAULT_TYPE, + unsigned long SWIG_DEFAULT_TYPE, + short SWIG_DEFAULT_TYPE, + unsigned short SWIG_DEFAULT_TYPE, + unsigned char SWIG_DEFAULT_TYPE, + signed char SWIG_DEFAULT_TYPE +{ + static int ivalue = (int) $source; + Tcl_LinkVar(interp,SWIG_name "($target)",(char *) &ivalue, TCL_LINK_INT | TCL_LINK_READ_ONLY); +} + +%typemap(tcl,const) float SWIG_DEFAULT_TYPE, + double SWIG_DEFAULT_TYPE +{ + static double dvalue = (double) $source; + Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &dvalue, TCL_LINK_DOUBLE | TCL_LINK_READ_ONLY); +} + +%typemap(tcl,const) char *SWIG_DEFAULT_TYPE +{ + static char *cvalue = $source; + Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &cvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); +} + +%typemap(tcl,const) Pointer *SWIG_DEFAULT_TYPE +{ + static char *pvalue; + pvalue = (char *) malloc(20+strlen("$mangle")); + SWIG_MakePtr(pvalue, (void *) ($source), "$mangle"); + Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &pvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); +} + +// ---------------------------------------------------------------------------------- +// Tcl 8 Object versions +// ---------------------------------------------------------------------------------- + +%typemap(tcl8,const) int SWIG_DEFAULT_TYPE, + unsigned int SWIG_DEFAULT_TYPE, + long SWIG_DEFAULT_TYPE, + unsigned long SWIG_DEFAULT_TYPE, + short SWIG_DEFAULT_TYPE, + unsigned short SWIG_DEFAULT_TYPE, + unsigned char SWIG_DEFAULT_TYPE, + signed char SWIG_DEFAULT_TYPE +{ + static int ivalue = (int) $source; + Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &ivalue, TCL_LINK_INT | TCL_LINK_READ_ONLY); +} + +%typemap(tcl8,const) float SWIG_DEFAULT_TYPE, + double SWIG_DEFAULT_TYPE +{ + static double dvalue = (double) $source; + Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &dvalue, TCL_LINK_DOUBLE | TCL_LINK_READ_ONLY); +} + +%typemap(tcl8,const) char *SWIG_DEFAULT_TYPE +{ + static char *cvalue = $source; + Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &cvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); +} + +%typemap(tcl8,const) Pointer *SWIG_DEFAULT_TYPE +{ + static char *pvalue; + pvalue = (char *) malloc(20+strlen("$mangle")); + SWIG_MakePtr(pvalue, (void *) ($source), "$mangle"); + Tcl_LinkVar(interp, SWIG_prefix SWIG_name "($target)",(char *) &pvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); +} + + + diff --git a/wxPython/wxSWIG/swig_lib/tcl/consthash.i b/wxPython/wxSWIG/swig_lib/tcl/consthash.i new file mode 100644 index 0000000000..e90f96564e --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/consthash.i @@ -0,0 +1,223 @@ +// consthash.i +// +// This module changes SWIG to place constant values into a Tcl +// hash table. + + +#ifdef AUTODOC +%subsection "Hash Constants",pre +%text %{ +%include consthash.i + +This module changes SWIG so that constant values are placed into a Tcl +hash table in addition to normal Tcl variables. When working with systems +involving large numbers of constants, the use of a hash table +simplifies use because it is no longer necessary to declare constants +using the 'global' statement. + +This module should generally be included at the top of an interface +file before any declarations appear. Furthermore, this module changes +the default handling of basic datatypes including integers, floats, +and character strings. + +When this module is used, constants are simply accessed by name +without the associated dollar sign. For example : + + #define FOO 42 + +would be accessed as 'FOO' in Tcl, not '$FOO'. + +Note : This module only affects integer, float, and character +constants. Pointer constants are not currently affected. This module +should not break existing Tcl scripts that rely on the normal SWIG +constant mechanism. +%} +#endif + +%{ +static Tcl_HashTable intHash, doubleHash, charHash; +static Tcl_HashEntry *entryPtr; +static int init_dummy; +%} + +%init %{ + Tcl_InitHashTable(&intHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&doubleHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&charHash, TCL_STRING_KEYS); +%} + +%typemap(tcl,const) int SWIG_DEFAULT_TYPE, + unsigned int SWIG_DEFAULT_TYPE, + long SWIG_DEFAULT_TYPE, + unsigned long SWIG_DEFAULT_TYPE, + short SWIG_DEFAULT_TYPE, + unsigned short SWIG_DEFAULT_TYPE, + unsigned char SWIG_DEFAULT_TYPE, + signed char SWIG_DEFAULT_TYPE +{ + static int ivalue = (int) $source; + entryPtr = Tcl_CreateHashEntry(&intHash, "$target", &init_dummy); + Tcl_SetHashValue(entryPtr, &ivalue); + Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &ivalue, TCL_LINK_INT | TCL_LINK_READ_ONLY); +} + +%typemap(tcl,const) float SWIG_DEFAULT_TYPE, + double SWIG_DEFAULT_TYPE +{ + static double dvalue = (double) $source; + entryPtr = Tcl_CreateHashEntry(&doubleHash, "$target", &init_dummy); + Tcl_SetHashValue(entryPtr, &dvalue); + Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &dvalue, TCL_LINK_DOUBLE | TCL_LINK_READ_ONLY); +} + +%typemap(tcl,const) char *SWIG_DEFAULT_TYPE +{ + static char *cvalue = $source; + entryPtr = Tcl_CreateHashEntry(&charHash, "$target", &init_dummy); + Tcl_SetHashValue(entryPtr, &cvalue); + Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &cvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); +} + +// Change input handling to look for names + +%typemap(tcl,in) int SWIG_DEFAULT_TYPE, + unsigned int SWIG_DEFAULT_TYPE, + long SWIG_DEFAULT_TYPE, + unsigned long SWIG_DEFAULT_TYPE, + short SWIG_DEFAULT_TYPE, + unsigned short SWIG_DEFAULT_TYPE, + unsigned char SWIG_DEFAULT_TYPE, + signed char SWIG_DEFAULT_TYPE +{ + Tcl_HashEntry *entry; + entry = Tcl_FindHashEntry(&intHash,$source); + if (entry) { + $target = ($type) (*((int *) Tcl_GetHashValue(entry))); + } else { + int temp; + if (Tcl_GetInt(interp, $source, &temp) == TCL_ERROR) return TCL_ERROR; + $target = ($type) temp; + } +} + +%typemap(tcl,in) float SWIG_DEFAULT_TYPE, + double SWIG_DEFAULT_TYPE +{ + Tcl_HashEntry *entry; + entry = Tcl_FindHashEntry(&doubleHash,$source); + if (entry) { + $target = ($type) (*((double *) Tcl_GetHashValue(entry))); + } else if (entry = Tcl_FindHashEntry(&intHash,$source)) { + $target = ($type) (*((int *) Tcl_GetHashValue(entry))); + } else { + double temp; + if (Tcl_GetDouble(interp,$source,&temp) == TCL_ERROR) return TCL_ERROR; + $target = ($type) temp; + } +} + +%typemap(tcl,in) char *SWIG_DEFAULT_TYPE +{ + Tcl_HashEntry *entry; + entry = Tcl_FindHashEntry(&charHash,$source); + if (entry) { + $target = ($type) (*((char **) Tcl_GetHashValue(entry))); + } else { + $target = $source; + } +} + +// ---------------------------------------------------------------------------------- +// Tcl 8 Object versions +// ---------------------------------------------------------------------------------- + +%typemap(tcl8,const) int SWIG_DEFAULT_TYPE, + unsigned int SWIG_DEFAULT_TYPE, + long SWIG_DEFAULT_TYPE, + unsigned long SWIG_DEFAULT_TYPE, + short SWIG_DEFAULT_TYPE, + unsigned short SWIG_DEFAULT_TYPE, + unsigned char SWIG_DEFAULT_TYPE, + signed char SWIG_DEFAULT_TYPE +{ + static int ivalue = (int) $source; + entryPtr = Tcl_CreateHashEntry(&intHash, "$target", &init_dummy); + Tcl_SetHashValue(entryPtr, &ivalue); + Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &ivalue, TCL_LINK_INT | TCL_LINK_READ_ONLY); +} + +%typemap(tcl8,const) float SWIG_DEFAULT_TYPE, + double SWIG_DEFAULT_TYPE +{ + static double dvalue = (double) $source; + entryPtr = Tcl_CreateHashEntry(&doubleHash, "$target", &init_dummy); + Tcl_SetHashValue(entryPtr, &dvalue); + Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &dvalue, TCL_LINK_DOUBLE | TCL_LINK_READ_ONLY); +} + +%typemap(tcl8,const) char *SWIG_DEFAULT_TYPE +{ + static char *cvalue = $source; + entryPtr = Tcl_CreateHashEntry(&charHash, "$target", &init_dummy); + Tcl_SetHashValue(entryPtr, &cvalue); + Tcl_LinkVar(interp, SWIG_prefix "$target",(char *) &cvalue, TCL_LINK_STRING | TCL_LINK_READ_ONLY); +} + +// Change input handling to look for names + +%typemap(tcl8,in) int SWIG_DEFAULT_TYPE, + unsigned int SWIG_DEFAULT_TYPE, + long SWIG_DEFAULT_TYPE, + unsigned long SWIG_DEFAULT_TYPE, + short SWIG_DEFAULT_TYPE, + unsigned short SWIG_DEFAULT_TYPE, + unsigned char SWIG_DEFAULT_TYPE, + signed char SWIG_DEFAULT_TYPE +{ + Tcl_HashEntry *entry; + int _len; + char *_str = Tcl_GetStringFromObj($source,&_len); + entry = Tcl_FindHashEntry(&intHash,_str); + if (entry) { + $target = ($type) (*((int *) Tcl_GetHashValue(entry))); + } else { + int temp; + if (Tcl_GetIntFromObj(interp, $source, &temp) == TCL_ERROR) return TCL_ERROR; + $target = ($type) temp; + } +} + +%typemap(tcl8,in) float SWIG_DEFAULT_TYPE, + double SWIG_DEFAULT_TYPE +{ + Tcl_HashEntry *entry; + int _len; + char *_str = Tcl_GetStringFromObj($source,&_len); + entry = Tcl_FindHashEntry(&doubleHash,_str); + if (entry) { + $target = ($type) (*((double *) Tcl_GetHashValue(entry))); + } else if (entry = Tcl_FindHashEntry(&intHash,_str)) { + $target = ($type) (*((int *) Tcl_GetHashValue(entry))); + } else { + double temp; + if (Tcl_GetDoubleFromObj(interp,$source,&temp) == TCL_ERROR) return TCL_ERROR; + $target = ($type) temp; + } +} + +%typemap(tcl8,in) char *SWIG_DEFAULT_TYPE +{ + Tcl_HashEntry *entry; + int _len; + char *_str = Tcl_GetStringFromObj($source,&_len); + entry = Tcl_FindHashEntry(&charHash,_str); + if (entry) { + $target = ($type) (*((char **) Tcl_GetHashValue(entry))); + } else { + $target = _str; + } +} + + + + diff --git a/wxPython/wxSWIG/swig_lib/tcl/delcmd.swg b/wxPython/wxSWIG/swig_lib/tcl/delcmd.swg new file mode 100644 index 0000000000..e594ab4fd3 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/delcmd.swg @@ -0,0 +1,6 @@ +/* delcmd.swg : Tcl object deletion method */ + +static void TclDelete@CLASS@(ClientData clientData) { + @DESTRUCTOR@((@CLASSTYPE@) clientData); +} + diff --git a/wxPython/wxSWIG/swig_lib/tcl/delcmd8.swg b/wxPython/wxSWIG/swig_lib/tcl/delcmd8.swg new file mode 100644 index 0000000000..e594ab4fd3 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/delcmd8.swg @@ -0,0 +1,6 @@ +/* delcmd.swg : Tcl object deletion method */ + +static void TclDelete@CLASS@(ClientData clientData) { + @DESTRUCTOR@((@CLASSTYPE@) clientData); +} + diff --git a/wxPython/wxSWIG/swig_lib/tcl/expect.i b/wxPython/wxSWIG/swig_lib/tcl/expect.i new file mode 100644 index 0000000000..a4d4187a80 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/expect.i @@ -0,0 +1,97 @@ +// +// $Header$ +// SWIG File for building expect +// Dave Beazley +// March 18, 1996 +// +/* Revision History + * $Log$ + * Revision 1.1 2002/04/29 19:56:56 RD + * Since I have made several changes to SWIG over the years to accomodate + * special cases and other things in wxPython, and since I plan on making + * several more, I've decided to put the SWIG sources in wxPython's CVS + * instead of relying on maintaining patches. This effectivly becomes a + * fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * doesn't have some things I rely on in 1.1, not to mention that my + * custom patches would all have to be redone, I felt that this is the + * easier road to take. + * + * Revision 1.2 1999/11/05 21:45:14 beazley + * Minor Changes + * + * Revision 1.1.1.1 1999/02/28 02:00:55 beazley + * Swig1.1 + * + * Revision 1.1 1996/05/22 19:47:45 beazley + * Initial revision + * + */ + +#ifdef AUTODOC +%subsection "expect.i" +%text %{ +This module provides a main() function for building an extended version of +Expect. It has been tested with Expect 5.19, but may need modification +for newer versions. +%} +#endif + + +%{ + +/* main.c - main() and some logging routines for expect + +Written by: Don Libes, NIST, 2/6/90 + +Design and implementation of this program was paid for by U.S. tax +dollars. Therefore it is public domain. However, the author and NIST +would appreciate credit if this program or parts of it are used. +*/ + +#include "expect_cf.h" +#include +#include "expect_tcl.h" + +void +main(argc, argv) +int argc; +char *argv[]; +{ + int rc = 0; + Tcl_Interp *interp = Tcl_CreateInterp(); + int SWIG_init(Tcl_Interp *); + + if (Tcl_Init(interp) == TCL_ERROR) { + fprintf(stderr,"Tcl_Init failed: %s\n",interp->result); + exit(1); + } + + if (Exp_Init(interp) == TCL_ERROR) { + fprintf(stderr,"Exp_Init failed: %s\n",interp->result); + exit(1); + } + + /* SWIG initialization. --- 2/11/96 */ + + if (SWIG_init(interp) == TCL_ERROR) { + fprintf(stderr,"SWIG initialization failed: %s\n", interp->result); + exit(1); + } + + exp_parse_argv(interp,argc,argv); + + /* become interactive if requested or "nothing to do" */ + if (exp_interactive) + (void) exp_interpreter(interp); + else if (exp_cmdfile) + rc = exp_interpret_cmdfile(interp,exp_cmdfile); + else if (exp_cmdfilename) + rc = exp_interpret_cmdfilename(interp,exp_cmdfilename); + + /* assert(exp_cmdlinecmds != 0) */ + + exp_exit(interp,rc); + /*NOTREACHED*/ +} + +%} diff --git a/wxPython/wxSWIG/swig_lib/tcl/expectk.i b/wxPython/wxSWIG/swig_lib/tcl/expectk.i new file mode 100644 index 0000000000..10a0958256 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/expectk.i @@ -0,0 +1,733 @@ +// +// $Header$ +// +// SWIG file for building expectk +// Dave Beazley +// March 18, 1996 +// +/* Revision History + * $Log$ + * Revision 1.1 2002/04/29 19:56:56 RD + * Since I have made several changes to SWIG over the years to accomodate + * special cases and other things in wxPython, and since I plan on making + * several more, I've decided to put the SWIG sources in wxPython's CVS + * instead of relying on maintaining patches. This effectivly becomes a + * fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * doesn't have some things I rely on in 1.1, not to mention that my + * custom patches would all have to be redone, I felt that this is the + * easier road to take. + * + * Revision 1.2 1999/11/05 21:45:14 beazley + * Minor Changes + * + * Revision 1.1.1.1 1999/02/28 02:00:55 beazley + * Swig1.1 + * + * Revision 1.1 1996/05/22 19:47:45 beazley + * Initial revision + * + */ + + +#ifdef AUTODOC +%subsection "expectk.i" +%text %{ +This module provides a main() function for building an extended version of +expectk. It has been tested with Expect 5.19, but may need modification +for newer versions. +%} +#endif + +%{ + +/* exp_main_tk.c - main for expectk + +This is "main.c" from the Tk distribution with some minor modifications to +support Expect. + +Don Libes, NIST, 12/19/92 + +*/ + + +/* + * main.c -- + * + * This file contains the main program for "wish", a windowing + * shell based on Tk and Tcl. It also provides a template that + * can be used as the basis for main programs for other Tk + * applications. + * + * Copyright (c) 1990-1993 The Regents of the University of California. + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +/*#include "tkConfig.h"*/ +/*#include "tkInt.h"*/ +#include +#include "expect_tcl.h" +#include "Dbg.h" +#include "string.h" + +#ifdef TK_EXTENDED +# include "tclExtend.h" +#endif + +/* + * Global variables used by the main program: + */ + +static Tk_Window mainWindow; /* The main window for the application. If + * NULL then the application no longer + * exists. */ +static Tcl_Interp *interp; /* Interpreter for this application. */ +#if 0 +char *tcl_RcFileName = NULL; /* Name of a user-specific startup script + * to source if the application is being run + * interactively (e.g. "~/.wishrc"). Set + * by Tcl_AppInit. NULL means don't source + * anything ever. */ +#endif +static Tcl_DString command; /* Used to assemble lines of terminal input + * into Tcl commands. */ +static int tty; /* Non-zero means standard input is a + * terminal-like device. Zero means it's + * a file. */ +static char normalExitCmd[] = "exit"; +static char errorExitCmd[] = "exit 1"; + +/* + * Command-line options: + */ + +int synchronize = 0; +char *fileName = NULL; +char *name = NULL; +char *display = NULL; +char *geometry = NULL; + +/* for Expect */ +int my_rc = 1; +int sys_rc = 1; +int optcmd_eval(); +int dashdash; /* not used, but Tk's arg parser requires a placeholder */ +#ifdef TCL_DEBUGGER +int optcmd_debug(); +#endif + +Tk_ArgvInfo argTable[] = { + {"-file", TK_ARGV_STRING, (char *) NULL, (char *) &fileName, + "File from which to read commands"}, + {"-geometry", TK_ARGV_STRING, (char *) NULL, (char *) &geometry, + "Initial geometry for window"}, + {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display, + "Display to use"}, + {"-name", TK_ARGV_STRING, (char *) NULL, (char *) &name, + "Name to use for application"}, + {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize, + "Use synchronous mode for display server"}, + +/* for Expect */ + {"-buffer", TK_ARGV_STRING, (char *) 1, (char *) &exp_buffer_command_input, + "Buffer command input"}, + {"-command", TK_ARGV_GENFUNC, (char *) optcmd_eval, (char *)0, + "Command(s) to execute immediately"}, + {"-diag", TK_ARGV_CONSTANT, (char *) 1, (char *) &exp_is_debugging, + "Enable diagnostics"}, + {"--", TK_ARGV_REST, (char *)NULL, (char *)&dashdash, + "End of options"}, +#if TCL_DEBUGGER + {"-Debug", TK_ARGV_GENFUNC, (char *) optcmd_debug, (char *)0, + "Enable debugger"}, +#endif + {"-interactive", TK_ARGV_CONSTANT, (char *) 1, (char *) &exp_interactive, + "Interactive mode"}, + {"-norc", TK_ARGV_CONSTANT, (char *) 0, (char *) &my_rc, + "Don't read ~/.expect.rc"}, + {"-NORC", TK_ARGV_CONSTANT, (char *) 0, (char *) &sys_rc, + "Don't read system-wide expect.rc"}, + {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL, + (char *) NULL} +}; + +#ifdef TCL_DEBUGGER +/*ARGSUSED*/ +int +optcmd_debug(dst,interp,key,argc,argv) +char *dst; +Tcl_Interp *interp; +char *key; +int argc; +char **argv; +{ + int i; + + if (argc == 0) { + strcpy(interp->result,"-Debug flag needs 1 or 0 argument"); + return -1; + } + + if (Tcl_GetInt(interp,argv[0],&i) != TCL_OK) { + return -1; + } + + if (i) { + Dbg_On(interp,0); + } + + argc--; + for (i=0;iresult); + return 1; + } + + /* Add SWIG Extension */ + + if (SWIG_init(interp) == TCL_ERROR) { + fprintf(stderr,"Unable to initialize user-extensions : %s\n", interp->result); + return 1; + } + exp_argv0 = argv[0]; + +#ifdef TCL_DEBUGGER + Dbg_ArgcArgv(argc,argv,1); +#endif + + /* + * Parse command-line arguments. + */ + + if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv, argTable, 0) + != TCL_OK) { + fprintf(stderr, "%s\n", interp->result); + exit(1); + } + + if (!fileName) { /* added for Expect - DEL */ + fileName = argv[1]; + used_argv1_for_filename = 1; + } + + if (name == NULL) { + if (fileName != NULL) { + p = fileName; + } else { + p = argv[0]; + } + name = strrchr(p, '/'); + if (name != NULL) { + name++; + } else { + name = p; + } + } + + /* if user hasn't explicitly requested we be interactive */ + /* look for a file or some other source of commands */ + if (fileName && !exp_interactive) { + if (0 == strcmp(fileName,"-")) { + exp_cmdfile = stdin; + } else if (exp_buffer_command_input) { + if (NULL == (exp_cmdfile = fopen(fileName,"r"))) { + perror(fileName); + exp_exit(interp,1); + } else { + exp_close_on_exec(fileno(exp_cmdfile)); + } + } else { + exp_cmdfilename = fileName; + } + } else if (!exp_cmdlinecmds) { + /* no other source of commands, force interactive */ + exp_interactive = 1; + } + + /* + * If a display was specified, put it into the DISPLAY + * environment variable so that it will be available for + * any sub-processes created by us. + */ + + if (display != NULL) { + Tcl_SetVar2(interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY); + } + + /* + * Initialize the Tk application. If a -name option was provided, + * use it; otherwise, if a file name was provided, use the last + * element of its path as the name of the application; otherwise + * use the last element of the program name. For the application's + * class, capitalize the first letter of the name. + */ + +#if TK_MAJOR_VERSION >= 4 + class = (char *) ckalloc((unsigned) (strlen(name) + 1)); + strcpy(class, name); + class[0] = toupper((unsigned char) class[0]); + mainWindow = Tk_CreateMainWindow(interp, display, name, class); +#else +# if TK_MAJOR_VERSION == 3 && TK_MINOR_VERSION < 4 + mainWindow = Tk_CreateMainWindow(interp, display, name); +# else + mainWindow = Tk_CreateMainWindow(interp, display, name, "Tk"); +# endif +#endif + + if (mainWindow == NULL) { + fprintf(stderr, "%s\n", interp->result); + exit(1); + } +#if TK_MAJOR_VERSION == 3 && TK_MINOR_VERSION < 4 + Tk_SetClass(mainWindow, "Tk"); +#endif + if (synchronize) { + XSynchronize(Tk_Display(mainWindow), True); + } + +#if TK_MAJOR_VERSION < 4 + Tk_GeometryRequest(mainWindow, 200, 200); +#endif + + /* + * Make command-line arguments available in the Tcl variables "argc" + * and "argv". Also set the "geometry" variable from the geometry + * specified on the command line. + */ + + if (used_argv1_for_filename) { /* added for Expect - DEL */ + argv++; + argc--; + /* if no script name, use interpreter name */ + if (!argv[0] && !fileName) argv[0] = name; + } + + args = Tcl_Merge(argc-1, argv+1); + Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY); + ckfree(args); + sprintf(buf, "%d", argc-1); + Tcl_SetVar(interp, "argc", buf, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "argv0", (fileName != NULL) ? fileName : argv[0], + TCL_GLOBAL_ONLY); + if (geometry != NULL) { +#if TK_MAJOR_VERSION < 4 + Tcl_SetVar(interp, "geometry", geometry, TCL_GLOBAL_ONLY); +#else + Tcl_SetVar(interp, "geometry", geometry, TCL_GLOBAL_ONLY); + code = Tcl_VarEval(interp, "wm geometry . ", geometry, (char *) NULL); + if (code != TCL_OK) { + fprintf(stderr, "%s\n", interp->result); + } +#endif + } + + /* + * Set the "tcl_interactive" variable. + */ + + tty = isatty(0); + Tcl_SetVar(interp, "tcl_interactive", + ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY); + + /* + * Add a few application-specific commands to the application's + * interpreter. + */ + +#ifdef SQUARE_DEMO + Tcl_CreateCommand(interp, "square", SquareCmd, (ClientData) mainWindow, + (void (*)()) NULL); +#endif + + if (Tcl_Init(interp) == TCL_ERROR) { + fprintf(stderr,"Tcl_Init failed: %s\n",interp->result); + return 1; + } + if (Tk_Init(interp) == TCL_ERROR) { + fprintf(stderr,"Tk_Init failed: %s\n",interp->result); + return 1; + } + + /* Call Exp_Init again because Tcl_Init resets auto_path, sigh. */ + /* A better solution would be to execute Tcl/Tk_Init much earlier */ + /* (before argc/argv is processed). */ + + if (Exp_Init(interp) == TCL_ERROR) { + fprintf(stderr,"Exp_Init failed: %s\n",interp->result); + return 1; + } + +#if 0 + tcl_RcFileName = "~/.wishrc"; + + /* + * Invoke application-specific initialization. + */ + + if (Tcl_AppInit(interp) != TCL_OK) { + fprintf(stderr, "Tcl_AppInit failed: %s\n", interp->result); + } +#endif + + exp_interpret_rcfiles(interp,my_rc,sys_rc); + +#ifdef TK_EXTENDED + tclAppName = "Wish"; + tclAppLongname = "Wish - Tk Shell"; + tclAppVersion = TK_VERSION; + Tcl_ShellEnvInit (interp, TCLSH_ABORT_STARTUP_ERR, + name, + 0, NULL, /* argv var already set */ + fileName == NULL, /* interactive? */ + NULL); /* Standard default file */ +#endif + + /* + * Set the geometry of the main window, if requested. + */ + + if (geometry != NULL) { + code = Tcl_VarEval(interp, "wm geometry . ", geometry, (char *) NULL); + if (code != TCL_OK) { + fprintf(stderr, "%s\n", interp->result); + } + } + + /* + * Invoke the script specified on the command line, if any. + */ + + /* become interactive if requested or "nothing to do" */ + if (exp_interactive) { + (void) exp_interpreter(interp); + } else if (exp_cmdfile) { + int rc = exp_interpret_cmdfile(interp,exp_cmdfile); + if (rc != TCL_OK) exp_exit(interp,rc); + Tk_MainLoop(); + } else if (exp_cmdfilename) { + int rc = exp_interpret_cmdfilename(interp,exp_cmdfilename); + if (rc != TCL_OK) exp_exit(interp,rc); + Tk_MainLoop(); + } + + /* + * Don't exit directly, but rather invoke the Tcl "exit" command. + * This gives the application the opportunity to redefine "exit" + * to do additional cleanup. + */ + + Tcl_Eval(interp,normalExitCmd); + exit(1); + +#if 0 + if (fileName != NULL) { + Dbg_On(interp,0); + code = Tcl_VarEval(interp, "source ", fileName, (char *) NULL); + if (code != TCL_OK) { + goto error; + } + tty = 0; + } else { + /* + * Commands will come from standard input, so set up an event + * handler for standard input. If the input device is aEvaluate the + * .rc file, if one has been specified, set up an event handler + * for standard input, and print a prompt if the input + * device is a terminal. + */ + + if (tcl_RcFileName != NULL) { + Tcl_DString buffer; + char *fullName; + + fullName = Tcl_TildeSubst(interp, tcl_RcFileName, &buffer); + if (fullName == NULL) { + fprintf(stderr, "%s\n", interp->result); + } else { + if (access(fullName, R_OK) == 0) { + code = Tcl_EvalFile(interp, fullName); + if (code != TCL_OK) { + fprintf(stderr, "%s\n", interp->result); + } + } + } + Tcl_DStringFree(&buffer); + } + Tk_CreateFileHandler(0, TK_READABLE, StdinProc, (ClientData) 0); + if (tty) { + Prompt(interp, 0); + } + } + fflush(stdout); + Tcl_DStringInit(&command); + + /* + * Loop infinitely, waiting for commands to execute. When there + * are no windows left, Tk_MainLoop returns and we exit. + */ + + Tk_MainLoop(); + + /* + * Don't exit directly, but rather invoke the Tcl "exit" command. + * This gives the application the opportunity to redefine "exit" + * to do additional cleanup. + */ + + Tcl_Eval(interp, "exit"); + exit(1); + +error: + msg = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); + if (msg == NULL) { + msg = interp->result; + } + fprintf(stderr, "%s\n", msg); + Tcl_Eval(interp, errorExitCmd); + return 1; /* Needed only to prevent compiler warnings. */ + +#endif /*0*/ +} + +#if 0 +/* + *---------------------------------------------------------------------- + * + * StdinProc -- + * + * This procedure is invoked by the event dispatcher whenever + * standard input becomes readable. It grabs the next line of + * input characters, adds them to a command being assembled, and + * executes the command if it's complete. + * + * Results: + * None. + * + * Side effects: + * Could be almost arbitrary, depending on the command that's + * typed. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static void +StdinProc(clientData, mask) + ClientData clientData; /* Not used. */ + int mask; /* Not used. */ +{ +#define BUFFER_SIZE 4000 + char input[BUFFER_SIZE+1]; + static int gotPartial = 0; + char *cmd; + int code, count; + + count = read(fileno(stdin), input, BUFFER_SIZE); + if (count <= 0) { + if (!gotPartial) { + if (tty) { + Tcl_Eval(interp, "exit"); + exit(1); + } else { + Tk_DeleteFileHandler(0); + } + return; + } else { + count = 0; + } + } + cmd = Tcl_DStringAppend(&command, input, count); + if (count != 0) { + if ((input[count-1] != '\n') && (input[count-1] != ';')) { + gotPartial = 1; + goto prompt; + } + if (!Tcl_CommandComplete(cmd)) { + gotPartial = 1; + goto prompt; + } + } + gotPartial = 0; + + /* + * Disable the stdin file handler while evaluating the command; + * otherwise if the command re-enters the event loop we might + * process commands from stdin before the current command is + * finished. Among other things, this will trash the text of the + * command being evaluated. + */ + + Tk_CreateFileHandler(0, 0, StdinProc, (ClientData) 0); + code = Tcl_RecordAndEval(interp, cmd, 0); + Tk_CreateFileHandler(0, TK_READABLE, StdinProc, (ClientData) 0); + Tcl_DStringFree(&command); + if (*interp->result != 0) { + if ((code != TCL_OK) || (tty)) { + printf("%s\n", interp->result); + } + } + + /* + * Output a prompt. + */ + + prompt: + if (tty) { + Prompt(interp, gotPartial); + } +} + +/* + *---------------------------------------------------------------------- + * + * Prompt -- + * + * Issue a prompt on standard output, or invoke a script + * to issue the prompt. + * + * Results: + * None. + * + * Side effects: + * A prompt gets output, and a Tcl script may be evaluated + * in interp. + * + *---------------------------------------------------------------------- + */ + +static void +Prompt(interp, partial) + Tcl_Interp *interp; /* Interpreter to use for prompting. */ + int partial; /* Non-zero means there already + * exists a partial command, so use + * the secondary prompt. */ +{ + char *promptCmd; + int code; + + promptCmd = Tcl_GetVar(interp, + partial ? "tcl_prompt2" : "tcl_prompt1", TCL_GLOBAL_ONLY); + if (promptCmd == NULL) { + defaultPrompt: + if (!partial) { + fputs("% ", stdout); + } + } else { + code = Tcl_Eval(interp, promptCmd); + if (code != TCL_OK) { + Tcl_AddErrorInfo(interp, + "\n (script that generates prompt)"); + fprintf(stderr, "%s\n", interp->result); + goto defaultPrompt; + } + } + fflush(stdout); +} +#endif /*0*/ + +%} diff --git a/wxPython/wxSWIG/swig_lib/tcl/ish.i b/wxPython/wxSWIG/swig_lib/tcl/ish.i new file mode 100644 index 0000000000..a4c640a258 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/ish.i @@ -0,0 +1,170 @@ +// +// SWIG Interface file for building a new version of ish +// Dave Beazley +// August 14, 1996 +// + + +#ifdef AUTODOC +%subsection "ish.i" +%text %{ +This module provides a main() program needed to build a new version +of the [incr Tcl] 'ish' executable. It has been tested with itcl 2.1, +but may need tweaking for later versions and for use with C++. +%} +#endif + +%{ + +/* + * tclAppInit.c -- + * + * Provides a default version of the main program and Tcl_AppInit + * procedure for Tcl applications (without Tk). + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tclAppInit.c 1.17 96/03/26 12:45:29 + */ + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SWIG_RcFileName +char *SWIG_RcFileName = "~/.tclshrc"; +#endif + +extern int matherr _ANSI_ARGS_((void)); +static int (*dummyMathPtr) _ANSI_ARGS_((void)) = matherr; + +#ifdef __cplusplus +} +#endif + +#ifdef TCL_TEST +extern int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +extern int Tclptest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +#endif /* TCL_TEST */ + + +#if (TCL_MAJOR_VERSION == 7) && (TCL_MINOR_VERSION < 4) +/* + * The following variable is a special hack that allows applications + * to be linked using the procedure "main" from the Tcl7.3 library. The + * variable generates a reference to "main", which causes main to + * be brought in from the library (and all of Tcl with it). + */ + +extern int main _ANSI_ARGS_((int argc, char **argv)); +static int (*dummyMainPtr) _ANSI_ARGS_((int argc, char **argv)) = main; + +#else + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tcl_Main never returns here, so this procedure never + * returns either. + * + * Side effects: + * Whatever the application does. + * + *---------------------------------------------------------------------- + */ + +int +#ifdef _USING_PROTOTYPES_ +main (int argc, /* Number of command-line arguments. */ + char **argv) /* Values of command-line arguments. */ +#else +main(argc, argv) + int argc; /* Number of command-line arguments. */ + char **argv; /* Values of command-line arguments. */ +#endif +{ + Tcl_Main(argc, argv, Tcl_AppInit); + return 0; /* Needed only to prevent compiler warning. */ +} +#endif + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int +#ifdef _USING_PROTOTYPES_ +Tcl_AppInit (Tcl_Interp *interp) /* Interpreter for application. */ +#else +Tcl_AppInit(interp) + Tcl_Interp *interp; /* Interpreter for application. */ +#endif +{ + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (SWIG_init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + +#if (TCL_MAJOR_VERSION > 7) || (TCL_MINOR_VERSION > 4) + Tcl_SetVar(interp, "tcl_rcFileName", SWIG_RcFileName, TCL_GLOBAL_ONLY); +#else + tcl_RcFileName = SWIG_RcFileName; +#endif + return TCL_OK; +} + +%} diff --git a/wxPython/wxSWIG/swig_lib/tcl/itclsh.i b/wxPython/wxSWIG/swig_lib/tcl/itclsh.i new file mode 100644 index 0000000000..29b2349cee --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/itclsh.i @@ -0,0 +1,152 @@ +// +// SWIG Interface file for building a new version of itclsh +// Dave Beazley +// August 14, 1996 +// + + +#ifdef AUTODOC +%subsection "itclsh.i" +%text %{ +This module provides a main() program needed to build a new version +of the [incr Tcl] 'itclsh' executable. It has been tested with itcl 2.1, +but may need tweaking for later versions and for use with C++. +%} +#endif + +%{ + +/* + * tclAppInit.c -- + * + * Provides a default version of the main program and Tcl_AppInit + * procedure for Tcl applications (without Tk). + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +static char sccsid[] = "@(#) tclAppInit.c 1.13 95/06/08 10:55:54"; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SWIG_RcFileName +char *SWIG_RcFileName = "~/.tclshrc"; +#endif + +extern int Itcl_Init _ANSI_ARGS_((Tcl_Interp *interp)); + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ + +extern int matherr _ANSI_ARGS_((void)); +static int (*dummyMathPtr) _ANSI_ARGS_((void)) = matherr; + +#ifdef __cplusplus +} +#endif + + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tcl_Main never returns here, so this procedure never + * returns either. + * + * Side effects: + * Whatever the application does. + * + *---------------------------------------------------------------------- + */ + +int +main(argc, argv) + int argc; /* Number of command-line arguments. */ + char **argv; /* Values of command-line arguments. */ +{ + Tcl_Main(argc, argv, Tcl_AppInit); + return 0; /* Needed only to prevent compiler warning. */ +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_AppInit(interp) + Tcl_Interp *interp; /* Interpreter for application. */ +{ + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + + if (Itcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (SWIG_init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + +#if (TCL_MAJOR_VERSION > 7) || (TCL_MINOR_VERSION > 4) + Tcl_StaticPackage(interp, "Itcl", Itcl_Init, (Tcl_PackageInitProc *) NULL); +#endif + + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + +#if (TCL_MAJOR_VERSION > 7) || (TCL_MINOR_VERSION > 4) + Tcl_SetVar(interp, "tcl_rcFileName", SWIG_RcFileName, TCL_GLOBAL_ONLY); +#else + tcl_RcFileName = SWIG_RcFileName; +#endif + return TCL_OK; +} + +%} diff --git a/wxPython/wxSWIG/swig_lib/tcl/itkwish.i b/wxPython/wxSWIG/swig_lib/tcl/itkwish.i new file mode 100644 index 0000000000..080ceae7c5 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/itkwish.i @@ -0,0 +1,150 @@ +// +// SWIG Interface file for building a new version of itkwish +// Dave Beazley +// August 14, 1996 +// + + +#ifdef AUTODOC +%subsection "itkwish.i" +%text %{ +This module provides a main() program needed to build a new version +of the [incr Tcl] 'itkwish' executable. It has been tested with itcl 2.1, +but may need tweaking for later versions and for use with C++. +%} +#endif + +%{ + +/* + * tkAppInit.c -- + * + * Provides a default version of the Tcl_AppInit procedure for + * use in wish and similar Tk-based applications. + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef lint +static char sccsid[] = "@(#) tkAppInit.c 1.15 95/06/28 13:14:28"; +#endif /* not lint */ + +#include + +EXTERN int Itcl_Init _ANSI_ARGS_((Tcl_Interp *interp)); +EXTERN int Itk_Init _ANSI_ARGS_((Tcl_Interp *interp)); + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ + +#ifndef SWIG_RcFileName +char *SWIG_RcFileName = "~/.itkwishrc"; +#endif + +extern int matherr(); +static int (*dummyMathPtr)() = matherr; + + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tk_Main never returns here, so this procedure never + * returns either. + * + * Side effects: + * Whatever the application does. + * + *---------------------------------------------------------------------- + */ + +int +main(argc, argv) + int argc; /* Number of command-line arguments. */ + char **argv; /* Values of command-line arguments. */ +{ + Tk_Main(argc, argv, Tcl_AppInit); + return 0; /* Needed only to prevent compiler warning. */ +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_AppInit(interp) + Tcl_Interp *interp; /* Interpreter for application. */ +{ + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (Tk_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + if (Itcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (Itk_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (SWIG_init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + + if (Tcl_PkgRequire(interp, "Iwidgets", (char*)NULL, 0) == NULL) { + return TCL_ERROR; + } + + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + + Tcl_SetVar(interp, "tcl_rcFileName", SWIG_RcFileName, TCL_GLOBAL_ONLY); + return TCL_OK; +} + +%} diff --git a/wxPython/wxSWIG/swig_lib/tcl/iwish.i b/wxPython/wxSWIG/swig_lib/tcl/iwish.i new file mode 100644 index 0000000000..57fec5991c --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/iwish.i @@ -0,0 +1,180 @@ +// +// SWIG Interface file for building a new version of iwish +// Dave Beazley +// August 14, 1996 +// + + +#ifdef AUTODOC +%subsection "iwish.i" +%text %{ +This module provides a main() program needed to build a new version +of the [incr Tcl] 'iwish' executable. It has been tested with itcl 2.1, +but may need tweaking for later versions and for use with C++. +%} +#endif + +%{ +/* + * tkAppInit.c -- + * + * Provides a default version of the Tcl_AppInit procedure for + * use in wish and similar Tk-based applications. + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tkAppInit.c 1.21 96/03/26 16:47:07 + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SWIG_RcFileName +char *SWIG_RcFileName = "~/.wishrc"; +#endif + +extern int Tk_Init _ANSI_ARGS_((Tcl_Interp *interp)); +extern void Tk_Main _ANSI_ARGS_((int argc, char **argv, + Tcl_AppInitProc *appInitProc)); + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ + +extern int matherr _ANSI_ARGS_((void)); +static int (*tclDummyMathPtr) _ANSI_ARGS_((void)) = matherr; + +#ifdef __cplusplus +} +#endif + +#ifdef TK_TEST +extern int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +#endif /* TK_TEST */ + + +#if (TCL_MAJOR_VERSION == 7) && (TCL_MINOR_VERSION < 4) +/* + * The following variable is a special hack that allows applications + * to be linked using the procedure "main" from the Tcl7.3 library. The + * variable generates a reference to "main", which causes main to + * be brought in from the library (and all of Tcl with it). + */ + +extern int main _ANSI_ARGS_((int argc, char **argv)); +static int (*dummyMainPtr) _ANSI_ARGS_((int argc, char **argv)) = main; + +#else + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tk_Main never returns here, so this procedure never + * returns either. + * + * Side effects: + * Whatever the application does. + * + *---------------------------------------------------------------------- + */ + +int +#ifdef _USING_PROTOTYPES_ +main (int argc, /* Number of command-line arguments. */ + char **argv) /* Values of command-line arguments. */ +#else +main(argc, argv) + int argc; /* Number of command-line arguments. */ + char **argv; /* Values of command-line arguments. */ +#endif +{ + Tk_Main(argc, argv, Tcl_AppInit); + return 0; /* Needed only to prevent compiler warning. */ +} +#endif + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int +#ifdef _USING_PROTOTYPES_ +Tcl_AppInit (Tcl_Interp *interp) /* Interpreter for application. */ +#else +Tcl_AppInit(interp) + Tcl_Interp *interp; /* Interpreter for application. */ +#endif +{ + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (Tk_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (SWIG_init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + +#if (TCL_MAJOR_VERSION > 7) || (TCL_MINOR_VERSION > 4) + Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL); +#endif + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + +#if (TCL_MAJOR_VERSION > 7) || (TCL_MINOR_VERSION > 4) + Tcl_SetVar(interp, "tcl_rcFileName", SWIG_RcFileName, TCL_GLOBAL_ONLY); +#else + tcl_RcFileName = SWIG_RcFileName; +#endif + return TCL_OK; +} + +%} diff --git a/wxPython/wxSWIG/swig_lib/tcl/mactclinit.c b/wxPython/wxSWIG/swig_lib/tcl/mactclinit.c new file mode 100644 index 0000000000..de30bdaf55 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/mactclinit.c @@ -0,0 +1,86 @@ +/* + * tclMacAppInit.c -- + * + * Provides a version of the Tcl_AppInit procedure for the example shell. + * + * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tclMacAppInit.c 1.17 97/01/21 18:13:34 + */ + +#include "tcl.h" +#include "tclInt.h" +#include "tclMacInt.h" + +#if defined(THINK_C) +# include +#elif defined(__MWERKS__) +# include +short InstallConsole _ANSI_ARGS_((short fd)); +#endif + + + +/* + *---------------------------------------------------------------------- + * + * MacintoshInit -- + * + * This procedure calls initalization routines to set up a simple + * console on a Macintosh. This is necessary as the Mac doesn't + * have a stdout & stderr by default. + * + * Results: + * Returns TCL_OK if everything went fine. If it didn't the + * application should probably fail. + * + * Side effects: + * Inits the appropiate console package. + * + *---------------------------------------------------------------------- + */ + +#ifdef __cpluscplus +extern "C" +#endif +extern int +MacintoshInit() +{ +#if defined(THINK_C) + + /* Set options for Think C console package */ + /* The console package calls the Mac init calls */ + console_options.pause_atexit = 0; + console_options.title = "\pTcl Interpreter"; + +#elif defined(__MWERKS__) + + /* Set options for CodeWarrior SIOUX package */ + SIOUXSettings.autocloseonquit = true; + SIOUXSettings.showstatusline = true; + SIOUXSettings.asktosaveonclose = false; + InstallConsole(0); + SIOUXSetTitle("\pTcl Interpreter"); + +#elif defined(applec) + + /* Init packages used by MPW SIOW package */ + InitGraf((Ptr)&qd.thePort); + InitFonts(); + InitWindows(); + InitMenus(); + TEInit(); + InitDialogs(nil); + InitCursor(); + +#endif + + TclMacSetEventProc((TclMacConvertEventPtr) SIOUXHandleOneEvent); + + /* No problems with initialization */ + return TCL_OK; +} diff --git a/wxPython/wxSWIG/swig_lib/tcl/mactkinit.c b/wxPython/wxSWIG/swig_lib/tcl/mactkinit.c new file mode 100644 index 0000000000..e728418f4e --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/mactkinit.c @@ -0,0 +1,229 @@ +/* This is a support file needed to build a new version of Wish + Normally, this capability is found in TkAppInit.c, but this creates + tons of namespace problems for many applications. */ + +#include +#include +#include +#include +#include +#include + +#include "tk.h" +#include "tkInt.h" +#include "tkMacInt.h" + +typedef int (*TclMacConvertEventPtr) _ANSI_ARGS_((EventRecord *eventPtr)); +Tcl_Interp *gStdoutInterp = NULL; + +void TclMacSetEventProc _ANSI_ARGS_((TclMacConvertEventPtr procPtr)); +int TkMacConvertEvent _ANSI_ARGS_((EventRecord *eventPtr)); + +/* + * Prototypes for functions the ANSI library needs to link against. + */ +short InstallConsole _ANSI_ARGS_((short fd)); +void RemoveConsole _ANSI_ARGS_((void)); +long WriteCharsToConsole _ANSI_ARGS_((char *buff, long n)); +long ReadCharsFromConsole _ANSI_ARGS_((char *buff, long n)); +extern char * __ttyname _ANSI_ARGS_((long fildes)); +short SIOUXHandleOneEvent _ANSI_ARGS_((EventRecord *event)); + +/* + * Forward declarations for procedures defined later in this file: + */ + +/* + *---------------------------------------------------------------------- + * + * MacintoshInit -- + * + * This procedure calls Mac specific initilization calls. Most of + * these calls must be made as soon as possible in the startup + * process. + * + * Results: + * Returns TCL_OK if everything went fine. If it didn't the + * application should probably fail. + * + * Side effects: + * Inits the application. + * + *---------------------------------------------------------------------- + */ + +int +MacintoshInit() +{ + int i; + long result, mask = 0x0700; /* mask = system 7.x */ + + /* + * Tk needs us to set the qd pointer it uses. This is needed + * so Tk doesn't have to assume the availablity of the qd global + * variable. Which in turn allows Tk to be used in code resources. + */ + tcl_macQdPtr = &qd; + + InitGraf(&tcl_macQdPtr->thePort); + InitFonts(); + InitWindows(); + InitMenus(); + InitDialogs((long) NULL); + InitCursor(); + + /* + * Make sure we are running on system 7 or higher + */ + + if ((NGetTrapAddress(_Gestalt, ToolTrap) == + NGetTrapAddress(_Unimplemented, ToolTrap)) + || (((Gestalt(gestaltSystemVersion, &result) != noErr) + || (mask != (result & mask))))) { + panic("Tcl/Tk requires System 7 or higher."); + } + + /* + * Make sure we have color quick draw + * (this means we can't run on 68000 macs) + */ + + if (((Gestalt(gestaltQuickdrawVersion, &result) != noErr) + || (result < gestalt32BitQD13))) { + panic("Tk requires Color QuickDraw."); + } + + + FlushEvents(everyEvent, 0); + SetEventMask(everyEvent); + + /* + * Set up stack & heap sizes + */ + /* TODO: stack size + size = StackSpace(); + SetAppLimit(GetAppLimit() - 8192); + */ + MaxApplZone(); + for (i = 0; i < 4; i++) { + (void) MoreMasters(); + } + + TclMacSetEventProc(TkMacConvertEvent); + TkConsoleCreate(); + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * SetupMainInterp -- + * + * This procedure calls initalization routines require a Tcl + * interp as an argument. This call effectively makes the passed + * iterpreter the "main" interpreter for the application. + * + * Results: + * Returns TCL_OK if everything went fine. If it didn't the + * application should probably fail. + * + * Side effects: + * More initilization. + * + *---------------------------------------------------------------------- + */ + +int +SetupMainInterp( + Tcl_Interp *interp) +{ + /* + * Initialize the console only if we are running as an interactive + * application. + */ + + TkMacInitAppleEvents(interp); + TkMacInitMenus(interp); + + if (strcmp(Tcl_GetVar(interp, "tcl_interactive", TCL_GLOBAL_ONLY), "1") + == 0) { + if (TkConsoleInit(interp) == TCL_ERROR) { + goto error; + } + } + + /* + * Attach the global interpreter to tk's expected global console + */ + + gStdoutInterp = interp; + + return TCL_OK; + +error: + panic(interp->result); + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * InstallConsole, RemoveConsole, etc. -- + * + * The following functions provide the UI for the console package. + * Users wishing to replace SIOUX with their own console package + * need only provide the four functions below in a library. + * + * Results: + * See SIOUX documentation for details. + * + * Side effects: + * See SIOUX documentation for details. + * + *---------------------------------------------------------------------- + */ + +short +InstallConsole(short fd) +{ +#pragma unused (fd) + + return 0; +} + +void +RemoveConsole(void) +{ +} + +long +WriteCharsToConsole(char *buffer, long n) +{ + TkConsolePrint(gStdoutInterp, TCL_STDOUT, buffer, n); + return n; +} + +long +ReadCharsFromConsole(char *buffer, long n) +{ + return 0; +} + +extern char * +__ttyname(long fildes) +{ + static char *__devicename = "null device"; + + if (fildes >= 0 && fildes <= 2) { + return (__devicename); + } + + return (0L); +} + +short +SIOUXHandleOneEvent(EventRecord *event) +{ + return 0; +} diff --git a/wxPython/wxSWIG/swig_lib/tcl/methodcmd.swg b/wxPython/wxSWIG/swig_lib/tcl/methodcmd.swg new file mode 100644 index 0000000000..821cb595fe --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/methodcmd.swg @@ -0,0 +1,74 @@ +/* methodcmd.swg : Tcl method invocation */ + +static int Tcl@CLASS@MethodCmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { + int (*cmd)(ClientData, Tcl_Interp *, int, char **) = 0; + char temp[256], *oldarg; + int rcode; + int length; + char c; + + if (argc < 2) { + Tcl_SetResult(interp,"@CLASS@ methods : { @METHODLIST@ }",TCL_STATIC); + return TCL_ERROR; + } + c = argv[1][0]; + length = strlen(argv[1]); + SWIG_MakePtr(temp,(void *) clientData, "@CLASSMANGLE@"); + if (0); + @METHODS@ + else if ((c == 'c') && (strncmp(argv[1],"configure",length) == 0) && (length >= 2)) { + int i = 2; + cmd = 0; + while (i+1 < argc) { + @CONFIGMETHODS@ + if (cmd) { + oldarg = argv[i]; + argv[i] = &temp[0]; + rcode = (*cmd)(clientData,interp,3,&argv[i-1]); + argv[i] = oldarg; + if (rcode == TCL_ERROR) return rcode; + cmd = 0; + } else { + Tcl_SetResult(interp,"Invalid configure option. Must be { @CONFIGLIST@ }",TCL_STATIC); + return TCL_ERROR; + } + i+=2; + } + if ((i < argc) || (i == 2)) { + Tcl_SetResult(interp,"{ @CONFIGLIST@ }",TCL_STATIC); + return TCL_ERROR; + } + return TCL_OK; + } else if ((c == 'c') && (strncmp(argv[1],"cget",length) == 0) && (length >= 2)) { + if (argc == 3) { + if (0) {} + @CGETMETHODS@ + else if (strcmp(argv[2],"-this") == 0) { + SWIG_MakePtr(interp->result,(void *) clientData, "@CLASSMANGLE@"); + return TCL_OK; + } + if (cmd) { + oldarg = argv[2]; + argv[2] = &temp[0]; + rcode = (*cmd)(clientData,interp,argc-1,&argv[1]); + argv[2] = oldarg; + return rcode; + } else { + Tcl_SetResult(interp,"Invalid cget option. Must be { -this @CGETLIST@ }",TCL_STATIC); + return TCL_ERROR; + } + } else { + Tcl_SetResult(interp,"{ -this @CGETLIST@ }", TCL_STATIC); + return TCL_ERROR; + } + } + if (!cmd) { + Tcl_SetResult(interp,"Invalid Method. Must be { @METHODLIST@}",TCL_STATIC); + return TCL_ERROR; + } + oldarg = argv[1]; + argv[1] = &temp[0]; + rcode = (*cmd)(clientData,interp,argc,argv); + argv[1] = oldarg; + return rcode; +} diff --git a/wxPython/wxSWIG/swig_lib/tcl/methodcmd8.swg b/wxPython/wxSWIG/swig_lib/tcl/methodcmd8.swg new file mode 100644 index 0000000000..73f9bf6e31 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/methodcmd8.swg @@ -0,0 +1,96 @@ +/* methodcmd8.swg : Tcl8.x method invocation */ + +static int Tcl@CLASS@MethodCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST _objv[]) { + int (*cmd)(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*) = 0; + char *_str; + int rcode; + Tcl_Obj **objv; + Tcl_Obj *oldarg,*tcl_result,*obj; + int length; + char c; + + tcl_result = Tcl_GetObjResult(interp); + objv = (Tcl_Obj **) _objv; + if (objc < 2) { + Tcl_SetStringObj(tcl_result,"@CLASS@ methods : { @METHODLIST@ }",-1); + return TCL_ERROR; + } + obj = Tcl_NewObj(); + SWIG_SetPointerObj(obj,(void *) clientData,"@CLASSMANGLE@"); + _str = Tcl_GetStringFromObj(objv[1],&length); + c = *_str; + if (0); +@METHODS@ + else if ((c == 'c') && (strncmp(_str,"configure",length) == 0) && (length >= 2)) { + int i = 2; + cmd = 0; + while (i+1 < objc) { + _str = Tcl_GetStringFromObj(objv[i],&length); +@CONFIGMETHODS@ + if (cmd) { + oldarg = objv[i]; + objv[i] = obj; + rcode = (*cmd)(clientData,interp,3,&objv[i-1]); + objv[i] = oldarg; + if (rcode == TCL_ERROR) { + Tcl_DecrRefCount(obj); + return rcode; + } + cmd = 0; + } else { + Tcl_SetStringObj(tcl_result,"Invalid configure option. Must be { @CONFIGLIST@ }",-1); + Tcl_DecrRefCount(obj); + return TCL_ERROR; + } + i+=2; + } + if ((i < objc) || (i == 2)) { + Tcl_SetStringObj(tcl_result,"{ @CONFIGLIST@ }",-1); + Tcl_DecrRefCount(obj); + return TCL_ERROR; + } + Tcl_DecrRefCount(obj); + return TCL_OK; + } else if ((c == 'c') && (strncmp(_str,"cget",length) == 0) && (length >= 2)) { + if (objc == 3) { + _str = Tcl_GetStringFromObj(objv[2],&length); + if (0) {} +@CGETMETHODS@ + else if (strcmp(_str,"-this") == 0) { + SWIG_SetPointerObj(tcl_result,(void *) clientData, "@CLASSMANGLE@"); + Tcl_DecrRefCount(obj); + return TCL_OK; + } + if (cmd) { + oldarg = objv[2]; + objv[2] = obj; + rcode = (*cmd)(clientData,interp,objc-1,&objv[1]); + objv[2] = oldarg; + Tcl_DecrRefCount(obj); + return rcode; + } else { + Tcl_SetStringObj(tcl_result,"Invalid cget option. Must be { -this @CGETLIST@ }",-1); + Tcl_DecrRefCount(obj); + return TCL_ERROR; + } + } else { + Tcl_SetStringObj(tcl_result,"{ -this @CGETLIST@ }", -1); + Tcl_DecrRefCount(obj); + return TCL_ERROR; + } + } + if (!cmd) { + Tcl_SetStringObj(tcl_result,"Invalid Method. Must be { @METHODLIST@}",-1); + Tcl_DecrRefCount(obj); + return TCL_ERROR; + } + oldarg = objv[1]; + objv[1] = obj; + rcode = (*cmd)(clientData,interp,objc,objv); + objv[1] = oldarg; + Tcl_DecrRefCount(obj); + return rcode; +} + + + diff --git a/wxPython/wxSWIG/swig_lib/tcl/objcmd.swg b/wxPython/wxSWIG/swig_lib/tcl/objcmd.swg new file mode 100644 index 0000000000..119b77ab33 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/objcmd.swg @@ -0,0 +1,69 @@ +/* objcmd.swg : Tcl object creation */ + +static int Tcl@CLASS@Cmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { + void (*del)(ClientData) = 0; + char *name = 0; + int (*cmd)(ClientData, Tcl_Interp *, int, char **) = 0; + @CLASSTYPE@ newObj = 0; + int firstarg = 0; + int thisarg = 0; + if (argc == 1) { + cmd = @TCLCONSTRUCTOR@; + } else { + if (strcmp(argv[1],"-this") == 0) thisarg = 2; + else if (strcmp(argv[1],"-args") == 0) { + firstarg = 1; + cmd = @TCLCONSTRUCTOR@; + } else if (argc == 2) { + firstarg = 1; + name = argv[1]; + cmd = @TCLCONSTRUCTOR@; + } else if (argc >= 3) { + name = argv[1]; + if (strcmp(argv[2],"-this") == 0) thisarg = 3; + else { + firstarg = 1; + cmd = @TCLCONSTRUCTOR@; + } + } + } + if (cmd) { + int result; + result = (*cmd)(clientData,interp,argc-firstarg,&argv[firstarg]); + if (result == TCL_OK) { + SWIG_GetPtr(interp->result,(void **) &newObj,"@CLASSMANGLE@"); + } else { return result; } + if (!name) name = interp->result; + del = @TCLDESTRUCTOR@; + } else if (thisarg > 0) { + if (thisarg < argc) { + char *r; + r = SWIG_GetPtr(argv[thisarg],(void **) &newObj,"@CLASSMANGLE@"); + if (r) { + interp->result = "Type error. not a @CLASS@ object."; + return TCL_ERROR; + } + if (!name) name = argv[thisarg]; + /* Return value is same as pointer value */ + Tcl_SetResult(interp,argv[thisarg],TCL_VOLATILE); + } else { + interp->result = "wrong # args."; + return TCL_ERROR; + } + } else { + interp->result = "No constructor available."; + return TCL_ERROR; + } + { + Tcl_CmdInfo dummy; + if (!Tcl_GetCommandInfo(interp,name,&dummy)) { + Tcl_CreateCommand(interp,name, Tcl@CLASS@MethodCmd, (ClientData) newObj, del); + return TCL_OK; + } else { + Tcl_SetResult(interp,"",TCL_VOLATILE); + Tcl_AppendResult(interp,"Object ", name, " already exists!", (char *) NULL); + return TCL_ERROR; + } + } +} + diff --git a/wxPython/wxSWIG/swig_lib/tcl/objcmd8.swg b/wxPython/wxSWIG/swig_lib/tcl/objcmd8.swg new file mode 100644 index 0000000000..b67dd77131 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/objcmd8.swg @@ -0,0 +1,74 @@ +/* objcmd8.swg : Tcl 8.x object creation */ + +static int Tcl@CLASS@Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + void (*del)(ClientData) = 0; + char *name = 0; + int (*cmd)(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*) = 0; + @CLASSTYPE@ newObj = 0; + int firstarg = 0; + int thisarg = 0; + int length; + char *_str; + Tcl_Obj *tcl_result; + + tcl_result = Tcl_GetObjResult(interp); + if (objc == 1) { + cmd = @TCLCONSTRUCTOR@; + } else { + _str = Tcl_GetStringFromObj(objv[1],&length); + if (strcmp(_str,"-this") == 0) thisarg = 2; + else if (strcmp(_str,"-args") == 0) { + firstarg = 1; + cmd = @TCLCONSTRUCTOR@; + } else if (objc == 2) { + firstarg = 1; + name = _str; + cmd = @TCLCONSTRUCTOR@; + } else if (objc >= 3) { + name = _str; + _str = Tcl_GetStringFromObj(objv[2],&length); + if (strcmp(_str,"-this") == 0) thisarg = 3; + else { + firstarg = 1; + cmd = @TCLCONSTRUCTOR@; + } + } + } + if (cmd) { + int result; + result = (*cmd)(clientData,interp,objc-firstarg,&objv[firstarg]); + if (result == TCL_OK) { + SWIG_GetPointerObj(interp,tcl_result,(void **) &newObj,"@CLASSMANGLE@"); + } else { return result; } + if (!name) name = Tcl_GetStringFromObj(tcl_result,&length); + del = @TCLDESTRUCTOR@; + } else if (thisarg > 0) { + if (thisarg < objc) { + char *r; + r = SWIG_GetPointerObj(interp,objv[thisarg],(void **) &newObj,"@CLASSMANGLE@"); + if (r) { + Tcl_SetStringObj(tcl_result,"Type error. not a @CLASS@ object.",-1); + return TCL_ERROR; + } + if (!name) name = Tcl_GetStringFromObj(objv[thisarg],&length); + Tcl_SetStringObj(tcl_result,name,-1); + } else { + Tcl_SetStringObj(tcl_result,"wrong # args.",-1); + return TCL_ERROR; + } + } else { + Tcl_SetStringObj(tcl_result,"No constructor available.",-1); + return TCL_ERROR; + } + { + Tcl_CmdInfo dummy; + if (!Tcl_GetCommandInfo(interp,name,&dummy)) { + Tcl_CreateObjCommand(interp,name, Tcl@CLASS@MethodCmd, (ClientData) newObj, del); + return TCL_OK; + } else { + Tcl_SetStringObj(tcl_result,"Object name already exists!",-1); + return TCL_ERROR; + } + } +} + diff --git a/wxPython/wxSWIG/swig_lib/tcl/ptrlang.i b/wxPython/wxSWIG/swig_lib/tcl/ptrlang.i new file mode 100644 index 0000000000..977cd6d78e --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/ptrlang.i @@ -0,0 +1,695 @@ +// +// SWIG pointer conversion and utility library +// +// Dave Beazley +// April 19, 1997 +// +// Tcl specific implementation. This file is included +// by the file ../pointer.i + + +#if defined(SWIGTCL8) + +// ----------------------------------------------------------------- +// Define a hack for GetPtr on Tcl 8 +// +// ----------------------------------------------------------------- + +%{ + +static char *_SWIG_GetPtr(Tcl_Interp *interp, char *s, void **ptr, char *type) { + Tcl_Obj *obj; + char *c; + obj = Tcl_NewStringObj(s, strlen(s)); + c = SWIG_GetPointerObj(interp, obj, ptr, type); + if (c) { + c = strstr(s,c); + } + Tcl_DecrRefCount(obj); + return c; +} + +#define SWIG_GetPtr(a,b,c) _SWIG_GetPtr(interp, a,b,c) + +%} +#endif + +%{ + +#include + +/*------------------------------------------------------------------ + ptrcast(value,type) + + Constructs a new pointer value. Value may either be a string + or an integer. Type is a string corresponding to either the + C datatype or mangled datatype. + + ptrcast(0,"Vector *") + or + ptrcast(0,"Vector_p") + ------------------------------------------------------------------ */ + +static int ptrcast(Tcl_Interp *interp, char *_ptrvalue, char *type) { + + char *r,*s; + void *ptr; + char *typestr,*c; + int pv; + int error = 0; + + /* Produce a "mangled" version of the type string. */ + + typestr = (char *) malloc(strlen(type)+2); + + /* Go through and munge the typestring */ + + r = typestr; + *(r++) = '_'; + c = type; + while (*c) { + if (!isspace(*c)) { + if ((*c == '*') || (*c == '&')) { + *(r++) = 'p'; + } + else *(r++) = *c; + } else { + *(r++) = '_'; + } + c++; + } + *(r++) = 0; + + /* Check to see what kind of object _PTRVALUE is */ + if (Tcl_GetInt(interp,_ptrvalue,&pv) == TCL_OK) { + ptr = (void *) pv; + /* Received a numerical value. Make a pointer out of it */ + r = (char *) malloc(strlen(typestr)+22); + if (ptr) { + SWIG_MakePtr(r, ptr, typestr); + } else { + sprintf(r,"_0%s",typestr); + } + Tcl_SetResult(interp,r,TCL_VOLATILE); + free(r); + } else { + /* Have a string. Try to get the real pointer value */ + s = _ptrvalue; + r = (char *) malloc(strlen(type)+22); + + /* Now extract the pointer value */ + if (!SWIG_GetPtr(s,&ptr,0)) { + if (ptr) { + SWIG_MakePtr(r,ptr,typestr); + } else { + sprintf(r,"_0%s",typestr); + } + Tcl_SetResult(interp,r,TCL_VOLATILE); + } else { + error = 1; + } + free(r); + } + free(typestr); + if (error) { + Tcl_SetResult(interp,"Type error in ptrcast. Argument is not a valid pointer value.",TCL_VOLATILE); + return TCL_ERROR; + } + return TCL_OK; +} + +/*------------------------------------------------------------------ + ptrvalue(ptr,type = 0) + + Attempts to dereference a pointer value. If type is given, it + will try to use that type. Otherwise, this function will attempt + to "guess" the proper datatype by checking against all of the + builtin C datatypes. + ------------------------------------------------------------------ */ + +static int ptrvalue(Tcl_Interp *interp, char *_ptrvalue, int index, char *type) { + void *ptr; + char *s; + int error = 0; + + if (type) { + if (strlen(type) == 0) type = 0; + } + s = _ptrvalue; + if (SWIG_GetPtr(s,&ptr,0)) { + Tcl_SetResult(interp,"Type error in ptrvalue. Argument is not a valid pointer value.", + TCL_STATIC); + return TCL_ERROR; + } + + /* If no datatype was passed, try a few common datatypes first */ + + if (!type) { + + /* No datatype was passed. Type to figure out if it's a common one */ + + if (!SWIG_GetPtr(s,&ptr,"_int_p")) { + type = "int"; + } else if (!SWIG_GetPtr(s,&ptr,"_double_p")) { + type = "double"; + } else if (!SWIG_GetPtr(s,&ptr,"_short_p")) { + type = "short"; + } else if (!SWIG_GetPtr(s,&ptr,"_long_p")) { + type = "long"; + } else if (!SWIG_GetPtr(s,&ptr,"_float_p")) { + type = "float"; + } else if (!SWIG_GetPtr(s,&ptr,"_char_p")) { + type = "char"; + } else if (!SWIG_GetPtr(s,&ptr,"_char_pp")) { + type = "char *"; + } else { + type = "unknown"; + } + } + + if (!ptr) { + Tcl_SetResult(interp,"Unable to dereference NULL pointer.",TCL_STATIC); + return TCL_ERROR; + } + + /* Now we have a datatype. Try to figure out what to do about it */ + if (strcmp(type,"int") == 0) { + sprintf(interp->result,"%ld",(long) *(((int *) ptr) + index)); + } else if (strcmp(type,"double") == 0) { + Tcl_PrintDouble(interp,(double) *(((double *) ptr)+index), interp->result); + } else if (strcmp(type,"short") == 0) { + sprintf(interp->result,"%ld",(long) *(((short *) ptr) + index)); + } else if (strcmp(type,"long") == 0) { + sprintf(interp->result,"%ld",(long) *(((long *) ptr) + index)); + } else if (strcmp(type,"float") == 0) { + Tcl_PrintDouble(interp,(double) *(((float *) ptr)+index), interp->result); + } else if (strcmp(type,"char") == 0) { + Tcl_SetResult(interp,((char *) ptr) + index, TCL_VOLATILE); + } else if (strcmp(type,"char *") == 0) { + char *c = *(((char **) ptr)+index); + if (c) Tcl_SetResult(interp,(char *) c, TCL_VOLATILE); + else Tcl_SetResult(interp,"NULL", TCL_VOLATILE); + } else { + Tcl_SetResult(interp,"Unable to dereference unsupported datatype.",TCL_STATIC); + return TCL_ERROR; + } + return TCL_OK; +} + +/*------------------------------------------------------------------ + ptrcreate(type,value = 0,numelements = 1) + + Attempts to create a new object of given type. Type must be + a basic C datatype. Will not create complex objects. + ------------------------------------------------------------------ */ + +static int ptrcreate(Tcl_Interp *interp, char *type, char *_ptrvalue, int numelements) { + void *ptr; + int sz; + char *cast; + char temp[40]; + + /* Check the type string against a variety of possibilities */ + + if (strcmp(type,"int") == 0) { + sz = sizeof(int)*numelements; + cast = "_int_p"; + } else if (strcmp(type,"short") == 0) { + sz = sizeof(short)*numelements; + cast = "_short_p"; + } else if (strcmp(type,"long") == 0) { + sz = sizeof(long)*numelements; + cast = "_long_p"; + } else if (strcmp(type,"double") == 0) { + sz = sizeof(double)*numelements; + cast = "_double_p"; + } else if (strcmp(type,"float") == 0) { + sz = sizeof(float)*numelements; + cast = "_float_p"; + } else if (strcmp(type,"char") == 0) { + sz = sizeof(char)*numelements; + cast = "_char_p"; + } else if (strcmp(type,"char *") == 0) { + sz = sizeof(char *)*(numelements+1); + cast = "_char_pp"; + } else if (strcmp(type,"void") == 0) { + sz = numelements; + } else { + Tcl_SetResult(interp,"Unable to create unknown datatype.",TCL_STATIC); + return TCL_ERROR; + } + + /* Create the new object */ + + ptr = (void *) malloc(sz); + if (!ptr) { + Tcl_SetResult(interp,"Out of memory in ptrcreate.",TCL_STATIC); + return TCL_ERROR; + } + + /* Now try to set its default value */ + + if (_ptrvalue) { + if (strcmp(type,"int") == 0) { + int *ip,i,ivalue; + Tcl_GetInt(interp,_ptrvalue,&ivalue); + ip = (int *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"short") == 0) { + short *ip; + int i, ivalue; + Tcl_GetInt(interp,_ptrvalue,&ivalue); + ip = (short *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = (short) ivalue; + } else if (strcmp(type,"long") == 0) { + long *ip; + int i, ivalue; + Tcl_GetInt(interp,_ptrvalue,&ivalue); + ip = (long *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = (long) ivalue; + } else if (strcmp(type,"double") == 0) { + double *ip,ivalue; + int i; + Tcl_GetDouble(interp,_ptrvalue,&ivalue); + ip = (double *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = ivalue; + } else if (strcmp(type,"float") == 0) { + float *ip; + double ivalue; + int i; + Tcl_GetDouble(interp,_ptrvalue,&ivalue); + ip = (float *) ptr; + for (i = 0; i < numelements; i++) + ip[i] = (double) ivalue; + } else if (strcmp(type,"char") == 0) { + char *ip,*ivalue; + ivalue = (char *) _ptrvalue; + ip = (char *) ptr; + strncpy(ip,ivalue,numelements-1); + } else if (strcmp(type,"char *") == 0) { + char **ip, *ivalue; + int i; + ivalue = (char *) _ptrvalue; + ip = (char **) ptr; + for (i = 0; i < numelements; i++) { + if (ivalue) { + ip[i] = (char *) malloc(strlen(ivalue)+1); + strcpy(ip[i],ivalue); + } else { + ip[i] = 0; + } + } + ip[numelements] = 0; + } + } + /* Create the pointer value */ + + SWIG_MakePtr(temp,ptr,cast); + Tcl_SetResult(interp,temp,TCL_VOLATILE); + return TCL_OK; +} + +/*------------------------------------------------------------------ + ptrset(ptr,value,index = 0,type = 0) + + Attempts to set the value of a pointer variable. If type is + given, we will use that type. Otherwise, we'll guess the datatype. + ------------------------------------------------------------------ */ + +static int ptrset(Tcl_Interp *interp, char *_PTRVALUE, char *_VALUE, int index, char *type) { + void *ptr; + char *s; + + s = _PTRVALUE; + if (SWIG_GetPtr(s,&ptr,0)) { + Tcl_SetResult(interp,"Type error in ptrset. Argument is not a valid pointer value.", + TCL_STATIC); + return TCL_ERROR; + } + + /* If no datatype was passed, try a few common datatypes first */ + + if (!type) { + + /* No datatype was passed. Type to figure out if it's a common one */ + + if (!SWIG_GetPtr(s,&ptr,"_int_p")) { + type = "int"; + } else if (!SWIG_GetPtr(s,&ptr,"_double_p")) { + type = "double"; + } else if (!SWIG_GetPtr(s,&ptr,"_short_p")) { + type = "short"; + } else if (!SWIG_GetPtr(s,&ptr,"_long_p")) { + type = "long"; + } else if (!SWIG_GetPtr(s,&ptr,"_float_p")) { + type = "float"; + } else if (!SWIG_GetPtr(s,&ptr,"_char_p")) { + type = "char"; + } else if (!SWIG_GetPtr(s,&ptr,"_char_pp")) { + type = "char *"; + } else { + type = "unknown"; + } + } + + if (!ptr) { + Tcl_SetResult(interp,"Unable to set NULL pointer.",TCL_STATIC); + return TCL_ERROR; + } + + /* Now we have a datatype. Try to figure out what to do about it */ + if (strcmp(type,"int") == 0) { + int ivalue; + Tcl_GetInt(interp,_VALUE, &ivalue); + *(((int *) ptr)+index) = ivalue; + } else if (strcmp(type,"double") == 0) { + double ivalue; + Tcl_GetDouble(interp,_VALUE, &ivalue); + *(((double *) ptr)+index) = (double) ivalue; + } else if (strcmp(type,"short") == 0) { + int ivalue; + Tcl_GetInt(interp,_VALUE, &ivalue); + *(((short *) ptr)+index) = (short) ivalue; + } else if (strcmp(type,"long") == 0) { + int ivalue; + Tcl_GetInt(interp,_VALUE, &ivalue); + *(((long *) ptr)+index) = (long) ivalue; + } else if (strcmp(type,"float") == 0) { + double ivalue; + Tcl_GetDouble(interp,_VALUE, &ivalue); + *(((float *) ptr)+index) = (float) ivalue; + } else if (strcmp(type,"char") == 0) { + char *c = _VALUE; + strcpy(((char *) ptr)+index, c); + } else if (strcmp(type,"char *") == 0) { + char *c = _VALUE; + char **ca = (char **) ptr; + if (ca[index]) free(ca[index]); + if (strcmp(c,"NULL") == 0) { + ca[index] = 0; + } else { + ca[index] = (char *) malloc(strlen(c)+1); + strcpy(ca[index],c); + } + } else { + Tcl_SetResult(interp,"Unable to set unsupported datatype.",TCL_STATIC); + return TCL_ERROR; + } + return TCL_OK; +} + +/*------------------------------------------------------------------ + ptradd(ptr,offset) + + Adds a value to an existing pointer value. Will do a type-dependent + add for basic datatypes. For other datatypes, will do a byte-add. + ------------------------------------------------------------------ */ + +static int ptradd(Tcl_Interp *interp, char *_PTRVALUE, int offset) { + + char *r,*s; + void *ptr,*junk; + char *type; + + /* Check to see what kind of object _PTRVALUE is */ + + s = _PTRVALUE; + + /* Try to handle a few common datatypes first */ + + if (!SWIG_GetPtr(s,&ptr,"_int_p")) { + ptr = (void *) (((int *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,"_double_p")) { + ptr = (void *) (((double *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,"_short_p")) { + ptr = (void *) (((short *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,"_long_p")) { + ptr = (void *) (((long *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,"_float_p")) { + ptr = (void *) (((float *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,"_char_p")) { + ptr = (void *) (((char *) ptr) + offset); + } else if (!SWIG_GetPtr(s,&ptr,0)) { + ptr = (void *) (((char *) ptr) + offset); + } else { + Tcl_SetResult(interp,"Type error in ptradd. Argument is not a valid pointer value.",TCL_STATIC); + return TCL_ERROR; + } + type = SWIG_GetPtr(s,&junk,"INVALID POINTER"); + r = (char *) malloc(strlen(type)+20); + if (ptr) { + SWIG_MakePtr(r,ptr,type); + } else { + sprintf(r,"_0%s",type); + } + Tcl_SetResult(interp,r,TCL_VOLATILE); + free(r); + return TCL_OK; +} + + +/*------------------------------------------------------------------ + ptrmap(type1,type2) + + Allows a mapping between type1 and type2. (Like a typedef) + ------------------------------------------------------------------ */ + +static void ptrmap(char *type1, char *type2) { + + char *typestr1,*typestr2,*c,*r; + + /* Produce a "mangled" version of the type string. */ + + typestr1 = (char *) malloc(strlen(type1)+2); + + /* Go through and munge the typestring */ + + r = typestr1; + *(r++) = '_'; + c = type1; + while (*c) { + if (!isspace(*c)) { + if ((*c == '*') || (*c == '&')) { + *(r++) = 'p'; + } + else *(r++) = *c; + } else { + *(r++) = '_'; + } + c++; + } + *(r++) = 0; + + typestr2 = (char *) malloc(strlen(type2)+2); + + /* Go through and munge the typestring */ + + r = typestr2; + *(r++) = '_'; + c = type2; + while (*c) { + if (!isspace(*c)) { + if ((*c == '*') || (*c == '&')) { + *(r++) = 'p'; + } + else *(r++) = *c; + } else { + *(r++) = '_'; + } + c++; + } + *(r++) = 0; + SWIG_RegisterMapping(typestr1,typestr2,0); + SWIG_RegisterMapping(typestr2,typestr1,0); +} + +/*------------------------------------------------------------------ + ptrfree(ptr) + + Destroys a pointer value + ------------------------------------------------------------------ */ + +int ptrfree(Tcl_Interp *interp, char *_PTRVALUE) { + void *ptr, *junk; + char *s; + + s = _PTRVALUE; + if (SWIG_GetPtr(s,&ptr,0)) { + Tcl_SetResult(interp,"Type error in ptrfree. Argument is not a valid pointer value.",TCL_STATIC); + return TCL_ERROR; + } + + /* Check to see if this pointer is a char ** */ + if (!SWIG_GetPtr(s,&junk,"_char_pp")) { + char **c = (char **) ptr; + if (c) { + int i = 0; + while (c[i]) { + free(c[i]); + i++; + } + } + } + if (ptr) + free((char *) ptr); + + return TCL_OK; +} +%} + +%typemap(tcl,out) int ptrcast, + int ptrvalue, + int ptrcreate, + int ptrset, + int ptradd, + int ptrfree +{ + return $source; +} +%typemap(tcl8,out) int ptrcast, + int ptrvalue, + int ptrcreate, + int ptrset, + int ptradd, + int ptrfree +{ + return $source; +} + +// Ignore the Tcl_Interp * value, but set it to a value + +%typemap(tcl,ignore) Tcl_Interp * { + $target = interp; +} +%typemap(tcl8,ignore) Tcl_Interp * { + $target = interp; +} + +int ptrcast(Tcl_Interp *interp, char *ptr, char *type); +// Casts a pointer ptr to a new datatype given by the string type. +// type may be either the SWIG generated representation of a datatype +// or the C representation. For example : +// +// ptrcast $ptr double_p # Tcl representation +// ptrcast $ptr "double *" # C representation +// +// A new pointer value is returned. ptr may also be an integer +// value in which case the value will be used to set the pointer +// value. For example : +// +// set a [ptrcast 0 Vector_p] +// +// Will create a NULL pointer of type "Vector_p" +// +// The casting operation is sensitive to formatting. As a result, +// "double *" is different than "double*". As a result of thumb, +// there should always be exactly one space between the C datatype +// and any pointer specifiers (*). + + +int ptrvalue(Tcl_Interp *interp, char *ptr, int index = 0, char *type = 0); +// Returns the value that a pointer is pointing to (ie. dereferencing). +// The type is automatically inferred by the pointer type--thus, an +// integer pointer will return an integer, a double will return a double, +// and so on. The index and type fields are optional parameters. When +// an index is specified, this function returns the value of ptr[index]. +// This allows array access. When a type is specified, it overrides +// the given pointer type. Examples : +// +// ptrvalue $a # Returns the value *a +// ptrvalue $a 10 # Returns the value a[10] +// ptrvalue $a 10 double # Returns a[10] assuming a is a double * + +int ptrset(Tcl_Interp *interp, char *ptr, char *value, int index = 0, char *type = 0); +// Sets the value pointed to by a pointer. The type is automatically +// inferred from the pointer type so this function will work for +// integers, floats, doubles, etc... The index and type fields are +// optional. When an index is given, it provides array access. When +// type is specified, it overrides the given pointer type. Examples : +// +// ptrset $a 3 # Sets the value *a = 3 +// ptrset $a 3 10 # Sets a[10] = 3 +// ptrset $a 3 10 int # Sets a[10] = 3 assuming a is a int * + +int ptrcreate(Tcl_Interp *interp, char *type, char *value = 0, int nitems = 1); +// Creates a new object and returns a pointer to it. This function +// can be used to create various kinds of objects for use in C functions. +// type specifies the basic C datatype to create and value is an +// optional parameter that can be used to set the initial value of the +// object. nitems is an optional parameter that can be used to create +// an array. This function results in a memory allocation using +// malloc(). Examples : +// +// set a [ptrcreate "double"] # Create a new double, return pointer +// set a [ptrcreate int 7] # Create an integer, set value to 7 +// set a [ptrcreate int 0 1000] # Create an integer array with initial +// # values all set to zero +// +// This function only recognizes a few common C datatypes as listed below : +// +// int, short, long, float, double, char, char *, void +// +// All other datatypes will result in an error. However, other +// datatypes can be created by using the ptrcast function. For +// example: +// +// set a [ptrcast [ptrcreate int 0 100],"unsigned int *"] + +int ptrfree(Tcl_Interp *interp, char *ptr); +// Destroys the memory pointed to by ptr. This function calls free() +// and should only be used with objects created by ptrcreate(). Since +// this function calls free, it may work with other objects, but this +// is generally discouraged unless you absolutely know what you're +// doing. + +int ptradd(Tcl_Interp *interp, char *ptr, int offset); +// Adds a value to the current pointer value. For the C datatypes of +// int, short, long, float, double, and char, the offset value is the +// number of objects and works in exactly the same manner as in C. For +// example, the following code steps through the elements of an array +// +// set a [ptrcreate double 0 100] # Create an array double a[100] +// set b $a +// for {set i 0} {$i < 100} {incr i 1} { +// ptrset $b [expr{0.0025*$i}] # set *b = 0.0025*i +// set b [ptradd $b 1] # b++ (go to next double) +// } +// +// In this case, adding one to b goes to the next double. +// +// For all other datatypes (including all complex datatypes), the +// offset corresponds to bytes. This function does not perform any +// bounds checking and negative offsets are perfectly legal. + +void ptrmap(char *type1, char *type2); +// This is a rarely used function that performs essentially the same +// operation as a C typedef. To manage datatypes at run-time, SWIG +// modules manage an internal symbol table of type mappings. This +// table keeps track of which types are equivalent to each other. The +// ptrmap() function provides a mechanism for scripts to add symbols +// to this table. For example : +// +// ptrmap double_p Real_p +// +// would make the types "double_p" and "Real_p" equivalent to each +// other. Pointers of either type could now be used interchangably. +// +// Normally this function is not needed, but it can be used to +// circumvent SWIG's normal type-checking behavior or to work around +// weird type-handling bugs. + +// Clear the ignore typemap + +%typemap(tcl,ignore) Tcl_Interp *; +%typemap(tcl8,ignore) Tcl_Interp *; + + + + + + + diff --git a/wxPython/wxSWIG/swig_lib/tcl/swigtcl.swg b/wxPython/wxSWIG/swig_lib/tcl/swigtcl.swg new file mode 100644 index 0000000000..9aedd4ad32 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/swigtcl.swg @@ -0,0 +1,249 @@ +/* + * $Header$ + * + * swigtcl.swg + */ + +#if defined(_WIN32) || defined(__WIN32__) +# if defined(_MSC_VER) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# if defined(__BORLANDC__) +# define SWIGEXPORT(a) a _export +# else +# define SWIGEXPORT(a) a +# endif +# endif +#else +# define SWIGEXPORT(a) a +#endif + +/***************************************************************************** + * $Header$ + * + * swigptr.swg + *****************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SWIG_NOINCLUDE +extern void SWIG_MakePtr(char *, void *, char *); +extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); +extern char *SWIG_GetPtr(char *, void **, char *); +#else + +#ifdef SWIG_GLOBAL +#define SWIGSTATICRUNTIME(a) SWIGEXPORT(a) +#else +#define SWIGSTATICRUNTIME(a) static a +#endif + +/* SWIG pointer structure */ +typedef struct SwigPtrType { + char *name; /* Datatype name */ + int len; /* Length (used for optimization) */ + void *(*cast)(void *); /* Pointer casting function */ + struct SwigPtrType *next; /* Linked list pointer */ +} SwigPtrType; + +/* Pointer cache structure */ +typedef struct { + int stat; /* Status (valid) bit */ + SwigPtrType *tp; /* Pointer to type structure */ + char name[256]; /* Given datatype name */ + char mapped[256]; /* Equivalent name */ +} SwigCacheType; + +static int SwigPtrMax = 64; /* Max entries that can be currently held */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ +static int SwigStart[256]; /* Starting positions of types */ +static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ + +/* Cached values */ +#define SWIG_CACHESIZE 8 +#define SWIG_CACHEMASK 0x7 +static SwigCacheType SwigCache[SWIG_CACHESIZE]; +static int SwigCacheIndex = 0; +static int SwigLastCache = 0; + +/* Sort comparison function */ +static int swigsort(const void *data1, const void *data2) { + SwigPtrType *d1 = (SwigPtrType *) data1; + SwigPtrType *d2 = (SwigPtrType *) data2; + return strcmp(d1->name,d2->name); +} + +/* Register a new datatype with the type-checker */ +SWIGSTATICRUNTIME(void) +SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { + int i; + SwigPtrType *t = 0,*t1; + + /* Allocate the pointer table if necessary */ + if (!SwigPtrTable) { + SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); + } + + /* Grow the table */ + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTable = (SwigPtrType *) realloc((char *) SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); + } + for (i = 0; i < SwigPtrN; i++) { + if (strcmp(SwigPtrTable[i].name,origtype) == 0) { + t = &SwigPtrTable[i]; + break; + } + } + if (!t) { + t = &SwigPtrTable[SwigPtrN++]; + t->name = origtype; + t->len = strlen(t->name); + t->cast = 0; + t->next = 0; + } + + /* Check for existing entries */ + while (t->next) { + if ((strcmp(t->name,newtype) == 0)) { + if (cast) t->cast = cast; + return; + } + t = t->next; + } + t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + t1->name = newtype; + t1->len = strlen(t1->name); + t1->cast = cast; + t1->next = 0; + t->next = t1; + SwigPtrSort = 0; +} + +/* Make a pointer value string */ +SWIGSTATICRUNTIME(void) +SWIG_MakePtr(char *c, const void *ptr, char *type) { + static char hex[17] = "0123456789abcdef"; + unsigned long p, s; + char result[24], *r; + r = result; + p = (unsigned long) ptr; + if (p > 0) { + while (p > 0) { + s = p & 0xf; + *(r++) = hex[s]; + p = p >> 4; + } + *r = '_'; + while (r >= result) + *(c++) = *(r--); + strcpy (c, type); + } else { + strcpy (c, "NULL"); + } +} + +/* Function for getting a pointer value */ +SWIGSTATICRUNTIME(char *) +SWIG_GetPtr(char *c, void **ptr, char *t) +{ + unsigned long p; + char temp_type[256], *name; + int i, len, start, end; + SwigPtrType *sp,*tp; + SwigCacheType *cache; + register int d; + + p = 0; + /* Pointer values must start with leading underscore */ + if (*c != '_') { + *ptr = (void *) 0; + if (strcmp(c,"NULL") == 0) return (char *) 0; + else c; + } + c++; + /* Extract hex value from pointer */ + while (d = *c) { + if ((d >= '0') && (d <= '9')) + p = (p << 4) + (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + p = (p << 4) + (d - ('a'-10)); + else + break; + c++; + } + *ptr = (void *) p; + if ((!t) || (strcmp(t,c)==0)) return (char *) 0; + + if (!SwigPtrSort) { + qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); + for (i = 0; i < 256; i++) SwigStart[i] = SwigPtrN; + for (i = SwigPtrN-1; i >= 0; i--) SwigStart[(int) (SwigPtrTable[i].name[1])] = i; + for (i = 255; i >= 1; i--) { + if (SwigStart[i-1] > SwigStart[i]) + SwigStart[i-1] = SwigStart[i]; + } + SwigPtrSort = 1; + for (i = 0; i < SWIG_CACHESIZE; i++) SwigCache[i].stat = 0; + } + /* First check cache for matches. Uses last cache value as starting point */ + cache = &SwigCache[SwigLastCache]; + for (i = 0; i < SWIG_CACHESIZE; i++) { + if (cache->stat && (strcmp(t,cache->name) == 0) && (strcmp(c,cache->mapped) == 0)) { + cache->stat++; + if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); + return (char *) 0; + } + SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; + if (!SwigLastCache) cache = SwigCache; + else cache++; + } + /* Type mismatch. Look through type-mapping table */ + start = SwigStart[(int) t[1]]; + end = SwigStart[(int) t[1]+1]; + sp = &SwigPtrTable[start]; + + /* Try to find a match */ + while (start <= end) { + if (strncmp(t,sp->name,sp->len) == 0) { + name = sp->name; + len = sp->len; + tp = sp->next; + /* Try to find entry for our given datatype */ + while(tp) { + if (tp->len >= 255) { + return c; + } + strcpy(temp_type,tp->name); + strncat(temp_type,t+len,255-tp->len); + if (strcmp(c,temp_type) == 0) { + strcpy(SwigCache[SwigCacheIndex].mapped,c); + strcpy(SwigCache[SwigCacheIndex].name,t); + SwigCache[SwigCacheIndex].stat = 1; + SwigCache[SwigCacheIndex].tp = tp; + SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; + /* Get pointer value */ + *ptr = (void *) p; + if (tp->cast) *ptr = (*(tp->cast))(*ptr); + return (char *) 0; + } + tp = tp->next; + } + } + sp++; + start++; + } + return c; +} + +#endif + +#ifdef __cplusplus +} +#endif + diff --git a/wxPython/wxSWIG/swig_lib/tcl/swigtcl8.swg b/wxPython/wxSWIG/swig_lib/tcl/swigtcl8.swg new file mode 100644 index 0000000000..96f1d1af7a --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/swigtcl8.swg @@ -0,0 +1,367 @@ +/************************************************************************** + * $Header$ + * + * swigtcl8.swg + * + * This file provides type-checked pointer support to Tcl 8.0. + **********************************************************************/ + +#if defined(_WIN32) || defined(__WIN32__) +# if defined(_MSC_VER) +# define SWIGEXPORT(a) __declspec(dllexport) a +# else +# if defined(__BORLANDC__) +# define SWIGEXPORT(a) a _export +# else +# define SWIGEXPORT(a) a +# endif +# endif +#else +# define SWIGEXPORT(a) a +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SWIG_GLOBAL +#include +#define SWIGSTATICRUNTIME(a) SWIGEXPORT(a) +#else +#define SWIGSTATICRUNTIME(a) static a +#endif + +#ifdef SWIG_NOINCLUDE +extern void SWIG_SetPointerObj(Tcl_Obj *, void *, char *); +extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); +extern char *SWIG_GetPointerObj(Tcl_Interp *, Tcl_Obj *, void **, char *); +extern int SWIG_MakePtr(char *, const void *, char *); +extern void SWIG_RegisterType(); +#else + +/* These are internal variables. Should be static */ + +typedef struct SwigPtrType { + char *name; + int len; + void *(*cast)(void *); + struct SwigPtrType *next; +} SwigPtrType; + +/* Pointer cache structure */ + +typedef struct { + int stat; /* Status (valid) bit */ + SwigPtrType *tp; /* Pointer to type structure */ + char name[256]; /* Given datatype name */ + char mapped[256]; /* Equivalent name */ +} SwigCacheType; + +static int SwigPtrMax = 64; /* Max entries that can be currently held */ +static int SwigPtrN = 0; /* Current number of entries */ +static int SwigPtrSort = 0; /* Status flag indicating sort */ +static int SwigStart[256]; /* Array containing start locations (for searching) */ +static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */ + +/* Cached values */ + +#define SWIG_CACHESIZE 8 +#define SWIG_CACHEMASK 0x7 +static SwigCacheType SwigCache[SWIG_CACHESIZE]; +static int SwigCacheIndex = 0; +static int SwigLastCache = 0; + +/* Sort comparison function */ +static int swigsort(const void *data1, const void *data2) { + SwigPtrType *d1 = (SwigPtrType *) data1; + SwigPtrType *d2 = (SwigPtrType *) data2; + return strcmp(d1->name,d2->name); +} + +/* Binary Search function */ +static int swigcmp(const void *key, const void *data) { + char *k = (char *) key; + SwigPtrType *d = (SwigPtrType *) data; + return strncmp(k,d->name,d->len); +} + + +/*--------------------------------------------------------------------- + * SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) + * + * Register a new type-mapping with the type-checking system. + *---------------------------------------------------------------------*/ + +SWIGSTATICRUNTIME(void) +SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { + + int i; + SwigPtrType *t = 0, *t1; + + if (!SwigPtrTable) { + SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); + SwigPtrN = 0; + } + if (SwigPtrN >= SwigPtrMax) { + SwigPtrMax = 2*SwigPtrMax; + SwigPtrTable = (SwigPtrType *) realloc(SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType)); + } + for (i = 0; i < SwigPtrN; i++) + if (strcmp(SwigPtrTable[i].name,origtype) == 0) { + t = &SwigPtrTable[i]; + break; + } + if (!t) { + t = &SwigPtrTable[SwigPtrN]; + t->name = origtype; + t->len = strlen(origtype); + t->cast = 0; + t->next = 0; + SwigPtrN++; + } + while (t->next) { + if (strcmp(t->name,newtype) == 0) { + if (cast) t->cast = cast; + return; + } + t = t->next; + } + t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType)); + t1->name = newtype; + t1->len = strlen(newtype); + t1->cast = cast; + t1->next = 0; + t->next = t1; + SwigPtrSort = 0; +} + + +/*--------------------------------------------------------------------- + * void SWIG_SetPointerObj(Tcl_Obj *objPtr, void *ptr, char *type) + * + * Sets a Tcl object to a pointer value. + * ptr = void pointer value + * type = string representing type + * + *---------------------------------------------------------------------*/ + +SWIGSTATICRUNTIME(void) +SWIG_SetPointerObj(Tcl_Obj *objPtr, void *_ptr, char *type) { + static char _hex[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + unsigned long _p, _s; + char _result[20], *_r; /* Note : a 64-bit hex number = 16 digits */ + char _temp[20], *_c; + _r = _result; + _p = (unsigned long) _ptr; + if (_p > 0) { + while (_p > 0) { + _s = _p & 0xf; + *(_r++) = _hex[_s]; + _p = _p >> 4; + } + *_r = '_'; + _c = &_temp[0]; + while (_r >= _result) + *(_c++) = *(_r--); + *_c = 0; + Tcl_SetStringObj(objPtr,_temp,-1); + } else { + Tcl_SetStringObj(objPtr,"NULL",-1); + } + if (_ptr) + Tcl_AppendToObj(objPtr,type,-1); +} + +/* This is for backwards compatibility */ + +SWIGSTATICRUNTIME(int) +SWIG_MakePtr(char *_c, const void *_ptr, char *type) +{ + static char _hex[16] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f'}; + unsigned long _p, _s; + char _result[20], *_r; + int l = 0; + _r = _result; + _p = (unsigned long) _ptr; + if (_p > 0) { + while (_p > 0) { + _s = _p & 0xf; + *(_r++) = _hex[_s]; + _p = _p >> 4; + l++; + } + *_r = '_'; + l++; + while (_r >= _result) + *(_c++) = *(_r--); + _r = type; + while (*_r) + *(_c++) = *(_r++); + *(_c) = 0; + } else { + strcpy (_c, "NULL"); + } + return l; +} + +/*--------------------------------------------------------------------- + * char *SWIG_GetPointerObj(Tcl_Interp *interp, Tcl_Obj *objPtr, void **ptr, char *type) + * + * Attempts to extract a pointer value from our pointer type. + * Upon failure, returns a string corresponding to the actual datatype. + * Upon success, returns NULL and sets the pointer value in ptr. + *---------------------------------------------------------------------*/ + +SWIGSTATICRUNTIME(char *) +SWIG_GetPointerObj(Tcl_Interp *interp, Tcl_Obj *objPtr, void **ptr, char *_t) { + unsigned long _p; + char temp_type[256]; + char *name; + int i, len; + SwigPtrType *sp,*tp; + SwigCacheType *cache; + int start, end; + char *_c; + _p = 0; + + /* Extract the pointer value as a string */ + _c = Tcl_GetStringFromObj(objPtr, &i); + + /* Pointer values must start with leading underscore */ + if (*_c == '_') { + _c++; + /* Extract hex value from pointer */ + while (*_c) { + if ((*_c >= '0') && (*_c <= '9')) + _p = (_p << 4) + (*_c - '0'); + else if ((*_c >= 'a') && (*_c <= 'f')) + _p = (_p << 4) + ((*_c - 'a') + 10); + else + break; + _c++; + } + + if (_t) { + if (strcmp(_t,_c)) { + if (!SwigPtrSort) { + qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); + for (i = 0; i < 256; i++) { + SwigStart[i] = SwigPtrN; + } + for (i = SwigPtrN-1; i >= 0; i--) { + SwigStart[(int) (SwigPtrTable[i].name[1])] = i; + } + for (i = 255; i >= 1; i--) { + if (SwigStart[i-1] > SwigStart[i]) + SwigStart[i-1] = SwigStart[i]; + } + SwigPtrSort = 1; + for (i = 0; i < SWIG_CACHESIZE; i++) + SwigCache[i].stat = 0; + } + + /* First check cache for matches. Uses last cache value as starting point */ + cache = &SwigCache[SwigLastCache]; + for (i = 0; i < SWIG_CACHESIZE; i++) { + if (cache->stat) { + if (strcmp(_t,cache->name) == 0) { + if (strcmp(_c,cache->mapped) == 0) { + cache->stat++; + *ptr = (void *) _p; + if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr); + return (char *) 0; + } + } + } + SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK; + if (!SwigLastCache) cache = SwigCache; + else cache++; + } + /* We have a type mismatch. Will have to look through our type + mapping table to figure out whether or not we can accept this datatype */ + + start = SwigStart[(int) _t[1]]; + end = SwigStart[(int) _t[1]+1]; + sp = &SwigPtrTable[start]; + while (start < end) { + if (swigcmp(_t,sp) == 0) break; + sp++; + start++; + } + if (start > end) sp = 0; + /* Try to find a match for this */ + while (start <= end) { + if (swigcmp(_t,sp) == 0) { + name = sp->name; + len = sp->len; + tp = sp->next; + /* Try to find entry for our given datatype */ + while(tp) { + if (tp->len >= 255) { + return _c; + } + strcpy(temp_type,tp->name); + strncat(temp_type,_t+len,255-tp->len); + if (strcmp(_c,temp_type) == 0) { + + strcpy(SwigCache[SwigCacheIndex].mapped,_c); + strcpy(SwigCache[SwigCacheIndex].name,_t); + SwigCache[SwigCacheIndex].stat = 1; + SwigCache[SwigCacheIndex].tp = tp; + SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK; + + /* Get pointer value */ + *ptr = (void *) _p; + if (tp->cast) *ptr = (*(tp->cast))(*ptr); + return (char *) 0; + } + tp = tp->next; + } + } + sp++; + start++; + } + /* Didn't find any sort of match for this data. + Get the pointer value and return the received type */ + *ptr = (void *) _p; + return _c; + } else { + /* Found a match on the first try. Return pointer value */ + *ptr = (void *) _p; + return (char *) 0; + } + } else { + /* No type specified. Good luck */ + *ptr = (void *) _p; + return (char *) 0; + } + } else { + if (strcmp (_c, "NULL") == 0) { + *ptr = (void *) 0; + return (char *) 0; + } + *ptr = (void *) 0; + return _c; + } +} + +/*--------------------------------------------------------------------- + * void SWIG_RegisterType() + * + * Registers our new datatype with an interpreter. + *---------------------------------------------------------------------*/ + +SWIGSTATICRUNTIME(void) +SWIG_RegisterType() { + /* Does nothing at the moment */ +} + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/wxPython/wxSWIG/swig_lib/tcl/tclsh.i b/wxPython/wxSWIG/swig_lib/tcl/tclsh.i new file mode 100644 index 0000000000..07947d1ec4 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/tclsh.i @@ -0,0 +1,106 @@ +// +// $Header$ +// +// SWIG File for building new tclsh program +// Dave Beazley +// April 25, 1996 +// +/* Revision History + * $Log$ + * Revision 1.1 2002/04/29 19:56:57 RD + * Since I have made several changes to SWIG over the years to accomodate + * special cases and other things in wxPython, and since I plan on making + * several more, I've decided to put the SWIG sources in wxPython's CVS + * instead of relying on maintaining patches. This effectivly becomes a + * fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * doesn't have some things I rely on in 1.1, not to mention that my + * custom patches would all have to be redone, I felt that this is the + * easier road to take. + * + * Revision 1.1.1.1 1999/02/28 02:00:56 beazley + * Swig1.1 + * + * Revision 1.1 1996/05/22 19:47:45 beazley + * Initial revision + * + */ + +#ifdef AUTODOC +%subsection "tclsh.i" +%text %{ +This module provides the Tcl_AppInit() function needed to build a +new version of the tclsh executable. This file should not be used +when using dynamic loading. To make an interface file work with +both static and dynamic loading, put something like this in your +interface file : + + #ifdef STATIC + %include tclsh.i + #endif +%} +#endif + +%{ + +/* A TCL_AppInit() function that lets you build a new copy + * of tclsh. + * + * The macro SWIG_init contains the name of the initialization + * function in the wrapper file. + */ + +#ifndef SWIG_RcFileName +char *SWIG_RcFileName = "~/.myapprc"; +#endif + + +#ifdef MAC_TCL +extern int MacintoshInit _ANSI_ARGS_((void)); +#endif + +int Tcl_AppInit(Tcl_Interp *interp){ + + if (Tcl_Init(interp) == TCL_ERROR) + return TCL_ERROR; + + /* Now initialize our functions */ + + if (SWIG_init(interp) == TCL_ERROR) + return TCL_ERROR; +#if TCL_MAJOR_VERSION > 7 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 5 + Tcl_SetVar(interp,"tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY); +#else + tcl_RcFileName = SWIG_RcFileName; +#endif +#ifdef SWIG_RcRsrcName + Tcl_SetVar(interp,"tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL); +#endif + + return TCL_OK; +} + +#if TCL_MAJOR_VERSION > 7 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 4 +int main(int argc, char **argv) { +#ifdef MAC_TCL + char *newArgv[2]; + + if (MacintoshInit() != TCL_OK) { + Tcl_Exit(1); + } + + argc = 1; + newArgv[0] = "tclsh"; + newArgv[1] = NULL; + argv = newArgv; +#endif + + Tcl_Main(argc, argv, Tcl_AppInit); + return(0); + +} +#else +extern int main(); +#endif + +%} + diff --git a/wxPython/wxSWIG/swig_lib/tcl/tix.i b/wxPython/wxSWIG/swig_lib/tcl/tix.i new file mode 100644 index 0000000000..13aa8c520a --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/tix.i @@ -0,0 +1,29 @@ +// Initialization code for Tix + +%{ +#ifdef __cplusplus +extern "C" { +#endif +extern int Tix_Init(Tcl_Interp *); +#ifdef __cplusplus +} +#endif +%} + +#ifdef AUTODOC +%subsection "tix.i" +%text %{ +This module initializes the Tix extension. This is usually done in +combination with the wish.i or similar module. For example : + + %include wish.i // Build a new wish executable + %include tix.i // Initialize Tix +%} +#endif + +%init %{ + if (Tix_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +%} + diff --git a/wxPython/wxSWIG/swig_lib/tcl/typemaps.i b/wxPython/wxSWIG/swig_lib/tcl/typemaps.i new file mode 100644 index 0000000000..3132c02d3d --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/typemaps.i @@ -0,0 +1,555 @@ +// +// SWIG Typemap library +// Dave Beazley +// May 4, 1997 +// +// Tcl implementation +// +// This library provides standard typemaps for modifying SWIG's behavior. +// With enough entries in this file, I hope that very few people actually +// ever need to write a typemap. + +#ifdef AUTODOC +%section "Typemap Library (Tcl)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 +%text %{ +%include typemaps.i + +The SWIG typemap library provides a language independent mechanism for +supporting output arguments, input values, and other C function +calling mechanisms. The primary use of the library is to provide a +better interface to certain C function--especially those involving +pointers. +%} + +#endif + +// ------------------------------------------------------------------------ +// Pointer handling +// +// These mappings provide support for input/output arguments and common +// uses for C/C++ pointers. +// ------------------------------------------------------------------------ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + +#ifdef AUTODOC +%subsection "Input Methods" + +%text %{ +The following methods can be applied to turn a pointer into a simple +"input" value. That is, instead of passing a pointer to an object, +you would use a real value instead. + + int *INPUT + short *INPUT + long *INPUT + unsigned int *INPUT + unsigned short *INPUT + unsigned long *INPUT + unsigned char *INPUT + float *INPUT + double *INPUT + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + %include typemaps.i + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +%} +#endif + + +%typemap(tcl,in) double *INPUT(double temp) +{ + if (Tcl_GetDouble(interp,$source,&temp) == TCL_ERROR) { + return TCL_ERROR; + } + $target = &temp; +} + +%typemap(tcl,in) float *INPUT(double dvalue, float temp) +{ + if (Tcl_GetDouble(interp,$source,&dvalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (float) dvalue; + $target = &temp; +} + +%typemap(tcl,in) int *INPUT(int temp) +{ + if (Tcl_GetInt(interp,$source,&temp) == TCL_ERROR) { + return TCL_ERROR; + } + $target = &temp; +} + +%typemap(tcl,in) short *INPUT(int ivalue, short temp) +{ + if (Tcl_GetInt(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (short) ivalue; + $target = &temp; +} + +%typemap(tcl,in) long *INPUT(int ivalue, long temp) +{ + if (Tcl_GetInt(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (long) ivalue; + $target = &temp; +} + +%typemap(tcl,in) unsigned int *INPUT(int ivalue, unsigned int temp) +{ + if (Tcl_GetInt(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (unsigned int) ivalue; + $target = &temp; +} + +%typemap(tcl,in) unsigned short *INPUT(int ivalue, unsigned short temp) +{ + if (Tcl_GetInt(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (unsigned short) ivalue; + $target = &temp; +} + +%typemap(tcl,in) unsigned long *INPUT(int ivalue, unsigned long temp) +{ + if (Tcl_GetInt(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (unsigned long) ivalue; + $target = &temp; +} + +%typemap(tcl,in) unsigned char *INPUT(int ivalue, unsigned char temp) +{ + if (Tcl_GetInt(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (unsigned char) ivalue; + $target = &temp; +} + + + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + + +#ifdef AUTODOC +%subsection "Output Methods" + +%text %{ +The following methods can be applied to turn a pointer into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. In the case of +multiple output values, they are returned in the form of a Tcl list. + + int *OUTPUT + short *OUTPUT + long *OUTPUT + unsigned int *OUTPUT + unsigned short *OUTPUT + unsigned long *OUTPUT + unsigned char *OUTPUT + float *OUTPUT + double *OUTPUT + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters).K: + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include typemaps.i + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Tcl output of the function would be a list containing both +output values. + +%} + +#endif + +// Force the argument to be ignored. + +%typemap(tcl,ignore) int *OUTPUT(int temp), + short *OUTPUT(short temp), + long *OUTPUT(long temp), + unsigned int *OUTPUT(unsigned int temp), + unsigned short *OUTPUT(unsigned short temp), + unsigned long *OUTPUT(unsigned long temp), + unsigned char *OUTPUT(unsigned char temp), + float *OUTPUT(float temp), + double *OUTPUT(double temp) +{ + $target = &temp; +} + +%typemap(tcl,argout) int *OUTPUT, + short *OUTPUT, + long *OUTPUT +{ + char dtemp[64]; + sprintf(dtemp,"%ld",(long) *($source)); + Tcl_AppendElement(interp,dtemp); +} + +%typemap(tcl,argout) unsigned int *OUTPUT, + unsigned short *OUTPUT, + unsigned long *OUTPUT, + unsigned char *OUTPUT +{ + char dtemp[64]; + sprintf(dtemp,"%lu", (unsigned long) *($source)); + Tcl_AppendElement(interp,dtemp); +} + +%typemap(tcl,argout) float *OUTPUT, + double *OUTPUT +{ + char dtemp[TCL_DOUBLE_SPACE]; + Tcl_PrintDouble(interp, (double) *($source), dtemp); + Tcl_AppendElement(interp,dtemp); +} + +// BOTH +// Mappings for an argument that is both an input and output +// parameter + +#ifdef AUTODOC +%subsection "Input/Output Methods" + +%text %{ +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned in the form of a Tcl list. + + int *BOTH + short *BOTH + long *BOTH + unsigned int *BOTH + unsigned short *BOTH + unsigned long *BOTH + unsigned char *BOTH + float *BOTH + double *BOTH + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include typemaps.i + void neg(double *BOTH); + +or you can use the %apply directive : + + %include typemaps.i + %apply double *BOTH { double *x }; + void neg(double *x); + +Unlike C, this mapping does not directly modify the input value (since +this makes no sense in Tcl). Rather, the modified input value shows +up as the return value of the function. Thus, to apply this function +to a Tcl variable you might do this : + + set x [neg $x] + +%} + +#endif + +%typemap(tcl,in) int *BOTH = int *INPUT; +%typemap(tcl,in) short *BOTH = short *INPUT; +%typemap(tcl,in) long *BOTH = long *INPUT; +%typemap(tcl,in) unsigned int *BOTH = unsigned int *INPUT; +%typemap(tcl,in) unsigned short *BOTH = unsigned short *INPUT; +%typemap(tcl,in) unsigned long *BOTH = unsigned long *INPUT; +%typemap(tcl,in) unsigned char *BOTH = unsigned char *INPUT; +%typemap(tcl,in) float *BOTH = float *INPUT; +%typemap(tcl,in) double *BOTH = double *INPUT; + +%typemap(tcl,argout) int *BOTH = int *OUTPUT; +%typemap(tcl,argout) short *BOTH = short *OUTPUT; +%typemap(tcl,argout) long *BOTH = long *OUTPUT; +%typemap(tcl,argout) unsigned int *BOTH = unsigned int *OUTPUT; +%typemap(tcl,argout) unsigned short *BOTH = unsigned short *OUTPUT; +%typemap(tcl,argout) unsigned long *BOTH = unsigned long *OUTPUT; +%typemap(tcl,argout) unsigned char *BOTH = unsigned char *OUTPUT; +%typemap(tcl,argout) float *BOTH = float *OUTPUT; +%typemap(tcl,argout) double *BOTH = double *OUTPUT; + +// -------------------------------------------------------------------- +// Special types +// +// -------------------------------------------------------------------- + +// If interp * appears as a function argument, we ignore it and get +// it from the wrapper function. + +#ifdef AUTODOC +%subsection "Special Methods" + +%text %{ +The typemaps.i library also provides the following mappings : + +Tcl_Interp *interp + + Passes the current Tcl_Interp value directly to a C function. + This can be used to work with existing wrapper functions or + if you just need the interp value for some reason. When used, + the 'interp' parameter becomes hidden in the Tcl interface--that + is, you don't specify it explicitly. SWIG fills in its value + automatically. + +int Tcl_Result + + Makes the integer return code of a function the return value + of a SWIG generated wrapper function. For example : + + int foo() { + ... do stuff ... + return TCL_OK; + } + + could be wrapped as follows : + + %include typemaps.i + %apply int Tcl_Result { int foo }; + int foo(); + +%} + +#endif + +%typemap(tcl,ignore) Tcl_Interp *interp { + $target = interp; +} + +// If return code is a Tcl_Result, simply pass it on + +%typemap(tcl,out) int Tcl_Result { + interp->result = ""; + return $source; +} + +/*************************************************************************** + * Tcl 8.0 typemaps + ***************************************************************************/ + +// ------------------------------------------------------------------------ +// Pointer handling +// +// These mappings provide support for input/output arguments and common +// uses for C/C++ pointers. +// ------------------------------------------------------------------------ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + +%typemap(tcl8,in) double *INPUT(double temp) +{ + if (Tcl_GetDoubleFromObj(interp,$source,&temp) == TCL_ERROR) { + return TCL_ERROR; + } + $target = &temp; +} + +%typemap(tcl8,in) float *INPUT(double dvalue, float temp) +{ + if (Tcl_GetDoubleFromObj(interp,$source,&dvalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (float) dvalue; + $target = &temp; +} + +%typemap(tcl8,in) int *INPUT(int temp) +{ + if (Tcl_GetIntFromObj(interp,$source,&temp) == TCL_ERROR) { + return TCL_ERROR; + } + $target = &temp; +} + +%typemap(tcl8,in) short *INPUT(int ivalue, short temp) +{ + if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (short) ivalue; + $target = &temp; +} + +%typemap(tcl8,in) long *INPUT(int ivalue, long temp) +{ + if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (long) ivalue; + $target = &temp; +} + +%typemap(tcl8,in) unsigned int *INPUT(int ivalue, unsigned int temp) +{ + if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (unsigned int) ivalue; + $target = &temp; +} + +%typemap(tcl8,in) unsigned short *INPUT(int ivalue, unsigned short temp) +{ + if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (unsigned short) ivalue; + $target = &temp; +} + +%typemap(tcl8,in) unsigned long *INPUT(int ivalue, unsigned long temp) +{ + if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (unsigned long) ivalue; + $target = &temp; +} + +%typemap(tcl8,in) unsigned char *INPUT(int ivalue, unsigned char temp) +{ + if (Tcl_GetIntFromObj(interp,$source,&ivalue) == TCL_ERROR) { + return TCL_ERROR; + } + temp = (unsigned char) ivalue; + $target = &temp; +} + + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + +// Force the argument to be ignored. + +%typemap(tcl8,ignore) int *OUTPUT(int temp), + short *OUTPUT(short temp), + long *OUTPUT(long temp), + unsigned int *OUTPUT(unsigned int temp), + unsigned short *OUTPUT(unsigned short temp), + unsigned long *OUTPUT(unsigned long temp), + unsigned char *OUTPUT(unsigned char temp), + float *OUTPUT(float temp), + double *OUTPUT(double temp) +{ + $target = &temp; +} + +%typemap(tcl8,argout) int *OUTPUT, + short *OUTPUT, + long *OUTPUT, + unsigned int *OUTPUT, + unsigned short *OUTPUT, + unsigned long *OUTPUT, + unsigned char *OUTPUT +{ + Tcl_Obj *o; + o = Tcl_NewIntObj((int) *($source)); + Tcl_ListObjAppendElement(interp,$target,o); +} + +%typemap(tcl8,argout) float *OUTPUT, + double *OUTPUT +{ + Tcl_Obj *o; + o = Tcl_NewDoubleObj((double) *($source)); + Tcl_ListObjAppendElement(interp,$target,o); +} + +// BOTH +// Mappings for an argument that is both an input and output +// parameter + +%typemap(tcl8,in) int *BOTH = int *INPUT; +%typemap(tcl8,in) short *BOTH = short *INPUT; +%typemap(tcl8,in) long *BOTH = long *INPUT; +%typemap(tcl8,in) unsigned int *BOTH = unsigned int *INPUT; +%typemap(tcl8,in) unsigned short *BOTH = unsigned short *INPUT; +%typemap(tcl8,in) unsigned long *BOTH = unsigned long *INPUT; +%typemap(tcl8,in) unsigned char *BOTH = unsigned char *INPUT; +%typemap(tcl8,in) float *BOTH = float *INPUT; +%typemap(tcl8,in) double *BOTH = double *INPUT; + +%typemap(tcl8,argout) int *BOTH = int *OUTPUT; +%typemap(tcl8,argout) short *BOTH = short *OUTPUT; +%typemap(tcl8,argout) long *BOTH = long *OUTPUT; +%typemap(tcl8,argout) unsigned int *BOTH = unsigned int *OUTPUT; +%typemap(tcl8,argout) unsigned short *BOTH = unsigned short *OUTPUT; +%typemap(tcl8,argout) unsigned long *BOTH = unsigned long *OUTPUT; +%typemap(tcl8,argout) unsigned char *BOTH = unsigned char *OUTPUT; +%typemap(tcl8,argout) float *BOTH = float *OUTPUT; +%typemap(tcl8,argout) double *BOTH = double *OUTPUT; + +// -------------------------------------------------------------------- +// Special types +// +// -------------------------------------------------------------------- + +// If interp * appears as a function argument, we ignore it and get +// it from the wrapper function. + +%typemap(tcl8,ignore) Tcl_Interp *interp { + $target = interp; +} + +// If return code is a Tcl_Result, simply pass it on + +%typemap(tcl8,out) int Tcl_Result { + return $source; +} + + + + + + + + diff --git a/wxPython/wxSWIG/swig_lib/tcl/wish.i b/wxPython/wxSWIG/swig_lib/tcl/wish.i new file mode 100644 index 0000000000..39b3a63842 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/wish.i @@ -0,0 +1,170 @@ +// +// $Header$ +// +// SWIG File for making wish +// Dave Beazley +// April 25, 1996 +// +/* Revision History + * $Log$ + * Revision 1.1 2002/04/29 19:56:57 RD + * Since I have made several changes to SWIG over the years to accomodate + * special cases and other things in wxPython, and since I plan on making + * several more, I've decided to put the SWIG sources in wxPython's CVS + * instead of relying on maintaining patches. This effectivly becomes a + * fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * doesn't have some things I rely on in 1.1, not to mention that my + * custom patches would all have to be redone, I felt that this is the + * easier road to take. + * + * Revision 1.2 1999/11/05 21:45:14 beazley + * Minor Changes + * + * Revision 1.1.1.1 1999/02/28 02:00:56 beazley + * Swig1.1 + * + * Revision 1.1 1996/05/22 19:47:45 beazley + * Initial revision + * + */ + +#ifdef AUTODOC +%subsection "wish.i" +%text %{ +This module provides the Tk_AppInit() function needed to build a +new version of the wish executable. Like tclsh.i, this file should +not be used with dynamic loading. To make an interface file work with +both static and dynamic loading, put something like this in your +interface file : + + #ifdef STATIC + %include wish.i + #endif + +A startup file may be specified by defining the symbol SWIG_RcFileName +as follows (this should be included in a code-block) : + + #define SWIG_RcFileName "~/.mywishrc" +%} +#endif + +%{ + + +/* Initialization code for wish */ + +#include + +#ifndef SWIG_RcFileName +char *SWIG_RcFileName = "~/.wishrc"; +#endif + +#ifdef MAC_TCL +extern int MacintoshInit _ANSI_ARGS_((void)); +extern int SetupMainInterp _ANSI_ARGS_((Tcl_Interp *interp)); +#endif + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in interp->result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int Tcl_AppInit(Tcl_Interp *interp) +{ +#ifndef MAC_TCL + Tk_Window main; + main = Tk_MainWindow(interp); +#endif + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + + if (Tk_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + + if (SWIG_init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + +#ifdef MAC_TCL + SetupMainInterp(interp); +#endif + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + +#if TCL_MAJOR_VERSION >= 8 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 5 + Tcl_SetVar(interp,"tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY); +#else + tcl_RcFileName = SWIG_RcFileName; +#endif + +/* For Macintosh might also want this */ + +#ifdef MAC_TCL +#ifdef SWIG_RcRsrcName + Tcl_SetVar(interp,"tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL_ONLY); +#endif +#endif + return TCL_OK; +} + +#if TK_MAJOR_VERSION >= 4 +int main(int argc, char **argv) { + +#ifdef MAC_TCL + char *newArgv[2]; + if (MacintoshInit() != TCL_OK) { + Tcl_Exit(1); + } + argc = 1; + newArgv[0] = "Wish"; + newArgv[1] = NULL; + argv = newArgv; +#endif + Tk_Main(argc, argv, Tcl_AppInit); + return(0); +} +#else +extern int main(); +#endif + +%} + + + diff --git a/wxPython/wxSWIG/swig_lib/timers.i b/wxPython/wxSWIG/swig_lib/timers.i new file mode 100644 index 0000000000..3dbf160784 --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/timers.i @@ -0,0 +1,180 @@ +// +// $Header$ +// +// timers.i +// A SWIG file for adding various timing functions. +// Really, this is modeled after the timers in the CMMD +// message passing library for the CM-5. +// +// Dave Beazley +// April 2, 1996 +// +/* Revision history + * $Log$ + * Revision 1.1 2002/04/29 19:56:49 RD + * Since I have made several changes to SWIG over the years to accomodate + * special cases and other things in wxPython, and since I plan on making + * several more, I've decided to put the SWIG sources in wxPython's CVS + * instead of relying on maintaining patches. This effectivly becomes a + * fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still + * doesn't have some things I rely on in 1.1, not to mention that my + * custom patches would all have to be redone, I felt that this is the + * easier road to take. + * + * Revision 1.1.1.1 1999/02/28 02:00:53 beazley + * Swig1.1 + * + * Revision 1.1 1996/05/22 17:27:01 beazley + * Initial revision + * + */ + +%module timers +%{ + +#include +#define SWIG_NTIMERS 64 + +static clock_t telapsed[SWIG_NTIMERS]; +static clock_t tstart[SWIG_NTIMERS]; +static clock_t tend[SWIG_NTIMERS]; + +/*----------------------------------------------------------------- + * SWIG_timer_clear(int i) + * + * Clears timer i. + *----------------------------------------------------------------- */ + +void +SWIG_timer_clear(int i) +{ + if ((i >= 0) && (i < SWIG_NTIMERS)) + telapsed[i] = 0; +} + + +/*----------------------------------------------------------------- + * SWIG_timer_start(int i) + * + * Starts timer i + *----------------------------------------------------------------- */ + +void +SWIG_timer_start(int i) +{ + if ((i >= 0) && (i < SWIG_NTIMERS)) + tstart[i] = clock(); +} + + +/*----------------------------------------------------------------- + * SWIG_timer_stop(int i) + * + * Stops timer i and accumulates elapsed time + *----------------------------------------------------------------- */ + +void +SWIG_timer_stop(int i) +{ + if ((i >= 0) && (i < SWIG_NTIMERS)) { + tend[i] = clock(); + telapsed[i] += (tend[i] - tstart[i]); + } +} + +/*----------------------------------------------------------------- + * SWIG_timer_elapsed(int i) + * + * Returns the time elapsed on timer i in seconds. + *----------------------------------------------------------------- */ + +double +SWIG_timer_elapsed(int i) +{ + double t; + if ((i >= 0) && (i < SWIG_NTIMERS)) { + t = (double) telapsed[i]/(double) CLOCKS_PER_SEC; + return(t); + } else { + return 0; + } +} + +%} + +%section "Timer Functions",pre,after,chop_left=3,nosort,info,chop_right = 0, chop_top=0,chop_bottom=0 + +%text %{ +%include timers.i + +This module provides a collection of timing functions designed for +performance analysis and benchmarking of different code fragments. + +A total of 64 different timers are available. Each timer can be +managed independently using four functions : + + timer_clear(int n) Clears timer n + timer_start(int n) Start timer n + timer_stop(int n) Stop timer n + timer_elapsed(int n) Return elapsed time (in seconds) + +All timers measure CPU time. + +Since each timer can be accessed independently, it is possible +to use groups of timers for measuring different aspects of code +performance. To use a timer, simply use code like this : +%} + +#if defined(SWIGTCL) +%text %{ + timer_clear 0 + timer_start 0 + .. a bunch of Tcl code ... + timer_stop 0 + puts "[timer_elapsed 0] seconds of CPU time" +%} +#elif defined(SWIGPERL) +%text %{ + timer_clear(0); + timer_start(0); + .. a bunch of Perl code ... + timer_stop(0); + print timer_elapsed(0)," seconds of CPU time\n"; +%} +#elif defined(SWIGPYTHON) +%text %{ + timer_clear(0) + timer_start(0) + ... a bunch of Python code ... + timer_stop(0) + print timer_elapsed(0)," seconds of CPU time" +%} +#endif + +%text %{ +A single timer can be stopped and started repeatedly to provide +a cummulative timing effect. + +As a general performance note, making frequent calls to the timing +functions can severely degrade performance (due to operating system +overhead). The resolution of the timers may be poor for extremely +short code fragments. Therefore, the timers work best for +computationally intensive operations. +%} + + +%name(timer_clear) void SWIG_timer_clear(int n); +/* Clears timer n. */ + +%name(timer_start) void SWIG_timer_start(int n); +/* Starts timer n. */ + +%name(timer_stop) void SWIG_timer_stop(int n); +/* Stops timer n. */ + +%name(timer_elapsed) double SWIG_timer_elapsed(int n); +/* Return the elapsed time (in seconds) of timer n */ + + + + -- 2.45.2