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
--- /dev/null
+wxSWIG.dsp
--- /dev/null
+/*******************************************************************************
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#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
--- /dev/null
+
+/* SWIG version information */
+
+#define SWIG_MAJOR_VERSION 1
+#define SWIG_MINOR_VERSION 1
+#define SWIG_SPIN "(Build 883)"
--- /dev/null
+
+/* SWIG version information */
+
+#define SWIG_MAJOR_VERSION 1
+#define SWIG_MINOR_VERSION 1
+#define SWIG_SPIN "(@BUILD@)"
--- /dev/null
+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.
+
--- /dev/null
+#######################################################################
+# $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
+
+
+
--- /dev/null
+#######################################################################
+# $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
+
--- /dev/null
+/*******************************************************************************
+ * 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);
+}
+
+
--- /dev/null
+/*******************************************************************************
+ * 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 *);
+
+};
--- /dev/null
+/*******************************************************************************
+ * 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 <stdio.h>\n");
+ fprintf(f_header,"#include <string.h>\n");
+ fprintf(f_header,"#include <stdlib.h>\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);
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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 *) { };
+};
+
+
+
+
--- /dev/null
+# 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)
+
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+ }
+}
--- /dev/null
+/****************************************************************************
+ * 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);
+};
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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 \"<C " << class_name <<" instance at %s>\" % (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)));
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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
+
--- /dev/null
+/*******************************************************************************
+ * 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 <ctype.h>
+
+static char *usage = "\
+swig <options> 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
--- /dev/null
+/*******************************************************************************
+ * 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 *);
+};
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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 <ctype.h>
+
+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 <tcl.h>\n");
+ fprintf(f_header,"#include <string.h>\n");
+ fprintf(f_header,"#include <stdlib.h>\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));
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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 <ctype.h>
+
+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 <tcl.h>\n");
+ fprintf(f_header,"#include <string.h>\n");
+ fprintf(f_header,"#include <stdlib.h>\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));
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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 *);
+
+};
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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
+
+
+
+
+
--- /dev/null
+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
+
+
+
+
--- /dev/null
+
+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.
+
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+#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 <stdlib.h>
+
+#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
+
+
+
+
+
+
--- /dev/null
+/* 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 <stdlib.h>
+
+#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
+
+
+
+
+
+
--- /dev/null
+/***********************************************************************
+ * $Header$
+ * swig_lib/python/python.cfg
+ *
+ * Contains variable linking and pointer type-checking code.
+ ************************************************************************/
+
+#include <string.h>
+#include <stdlib.h>
+
+#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("<Global variables>");
+}
+
+/* ---------------------------------------------------------------------
+ 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
+
+
--- /dev/null
+/*
+ * $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 <stdlib.h>
+
+#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
+
--- /dev/null
+/**************************************************************************
+ * $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 <tcl.h>
+#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
--- /dev/null
+#!/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
+
--- /dev/null
+# 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
+
--- /dev/null
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
--- /dev/null
+#######################################################################
+# $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
+
+
--- /dev/null
+/*******************************************************************************
+ * 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 <ctype.h>
+
+/*******************************************************************************
+ * $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);
+ }
+ }
+ }
+}
+
+
--- /dev/null
+/*******************************************************************************
+ * 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);
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+ }
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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();
+ }
+ }
+ }
+ }
+ }
+}
+
--- /dev/null
+/*******************************************************************************
+ * 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;
+}
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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);
+}
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+}
+
+
--- /dev/null
+/*******************************************************************************
+ * 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 = "<BODY BGCOLOR=\"#ffffff\">:</BODY>";
+ tag_title = "<H1>:</H1>";
+ tag_contents = "<HR><H1>:</H1>";
+ tag_section = "<HR><H2>:</H2>";
+ tag_subsection = "<H3>:</H3>";
+ tag_subsubsection = "<H4>:</H4>";
+ tag_usage = "<P><TT><B>:</B></TT>";
+ tag_descrip = "<BLOCKQUOTE>:</BLOCKQUOTE>";
+ tag_text = "<P>";
+ tag_cinfo = "";
+ tag_preformat = "<PRE>:</PRE>";
+}
+
+// -----------------------------------------------------------------------------
+// char *HTML::start_tag(char *tag)
+//
+// Utility function for returning the first part of an HTML tag variable.
+// A tag must look like this :
+//
+// "<b>:</b>"
+//
+// The start tag for this would be "<b>"
+//
+// 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 << "<BR>";
+ }
+ }
+
+ 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 << "<HEAD>\n"
+ << "<TITLE>\n";
+ print_string(c,s_title,PRE);
+ s_title << "</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 << "<BR>\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 << "<UL>";
+ } else if (sect_count < last_section) {
+ for (i = 0; i < last_section - sect_count; i++)
+ contents << "</UL>";
+ }
+
+ last_section = sect_count;
+ contents << "<LI> <A HREF=\"#s";
+
+ s_doc << "<A name=\"s";
+ for (i = 0; i < sect_count; i++) {
+ s_doc << sect_num[i] << "_";
+ contents << sect_num[i] << "_";
+ }
+
+ 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) << "</A>\n";
+ contents << "</A>\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 << "<BR>\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,"<HTML>\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 << "</UL>\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,"</HTML>\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);
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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);
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+/*******************************************************************************
+ * $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;
+}
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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);
+
--- /dev/null
+/*******************************************************************************
+ * 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 <ctype.h>
+
+
+// -----------------------------------------------------------------------
+// $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
+
+}
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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);
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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);
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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 <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+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<dir> - Look for SWIG files in <dir>\n\
+ -l<ifile> - 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;
+}
+
--- /dev/null
+# 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)
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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 <limits.h>
+#include <ctype.h>
+
+// --------------------------------------------------------------------------------
+// $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;
+}
--- /dev/null
+/*******************************************************************************
+ * 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 <ctype.h>
+
+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);
+}
+
--- /dev/null
+/*******************************************************************************
+ * 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 *) { };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*******************************************************************************
+ * 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));
+ }
+ }
+}
+
+
+
+
+
--- /dev/null
+
+/* 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 <stdio.h>
+
+#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 <alloca.h>
+#else /* not sparc */
+#if defined (MSDOS) && !defined (__TURBOC__)
+#include <malloc.h>
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+#include <malloc.h>
+ #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
+\f
+#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
+\f
+#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,"<function ptr>");
+ 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,"<function ptr>");
+ 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,"<function ptr>");
+ 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,"<varargs>");
+ 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 <yyvsp[-1].ilist.count; i++) {
+ if (yyvsp[-1].ilist.names[i]) {
+ iname = make_name(yyvsp[-1].ilist.names[i]);
+ lang->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,"<function ptr>");
+ 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"
+\f
+ 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();
+}
+
--- /dev/null
+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;
--- /dev/null
+%{
+/*******************************************************************************
+ * 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> ID
+%token <id> HBLOCK WRAPPER POUND
+%token <id> STRING
+%token <id> NUM_INT NUM_FLOAT CHARCONST NUM_UNSIGNED NUM_LONG NUM_ULONG
+%token <ivalue> TYPEDEF
+%token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_TYPEDEF
+%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 <ivalue> TITLE SECTION SUBSECTION SUBSUBSECTION
+%token LESSTHAN GREATERTHAN
+%token <id> 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 <ivalue> extern array array2 parm_specifier parm_specifier_list;
+%type <pl> parms ptail;
+%type <p> parm parm_type;
+%type <tmparm> typemap_parm tm_list tm_tail;
+%type <id> pname cpptype base_specifier access_specifier typemap_name tm_method idstring;
+%type <type> type opt_signed opt_unsigned strict_type;
+%type <decl> declaration nested_decl;
+%type <ivalue> stars cpp_const_expr;
+%type <ilist> initlist base_list inherit;
+%type <dtype> definetype definetail def_args;
+%type <dtype> etype;
+%type <dtype> expr;
+%type <id> ename stylearg objc_inherit;
+%type <dlist> stylelist styletail;
+%type <type> objc_ret_type objc_arg_type;
+%type <id> objc_protolist objc_separator;
+%type <pl> 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,"<function ptr>");
+ $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,"<function ptr>");
+ $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,"<function ptr>");
+ 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,"<varargs>");
+ 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,"<function ptr>");
+ $$->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();
+}
+
--- /dev/null
+/*******************************************************************************
+ * 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 <string.h>
+#include <ctype.h>
+
+#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;
+}
--- /dev/null
+/*******************************************************************************
+ * 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 <ctype.h>
+
+//-----------------------------------------------------------------------
+// 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);
+}
--- /dev/null
+/*******************************************************************************
+ * 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);
+}
--- /dev/null
+/*******************************************************************************
+ * 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 <limits.h>
+
+// ------------------------------------------------------------------------
+// $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;
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * 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();
+ }
+ }
+}
+
--- /dev/null
+/*******************************************************************************
+ * 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 <ctype.h>
+
+// -------------------------------------------------------------------
+// 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;
+}
--- /dev/null
+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 <X11/XIntrinsic.h>], , 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 <X11/Intrinsic.h>], , 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 <tcl.h>], , 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)
+
+
+
+
+
+
--- /dev/null
+#######################################################################
+# $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
+
+
--- /dev/null
+#######################################################################
+# $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 <make_win.in>
+
+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
+
+
+
--- /dev/null
+//
+// 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 :
+
+ <type>_array(size) : Create a new array of given size
+ <type>_get(array, index) : Get an element from the array
+ <type>_set(array, index, value) : Set an element in the array
+ <type>_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 <limits.h>
+
+/* 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 <float.h>
+
+ /* 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;
+
--- /dev/null
+// 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="<hr><h2>:</h2>"
+%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
+
+
--- /dev/null
+//
+// $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 <string.h>
+
+/* 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. */
+
+
+
--- /dev/null
+/* 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;
+ }
+}
--- /dev/null
+//
+// 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.");
+ }
+}
+
+
--- /dev/null
+//
+// ctype.i
+// Dave Beazley
+// November 30, 1996
+// SWIG file for character tests
+//
+
+%module ctype
+%{
+#include <ctype.h>
+%}
+
+%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 <ctype.h> 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 */
--- /dev/null
+//
+// 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
+
+
--- /dev/null
+
+co::
+ co RCS/*.i* RCS/*.swg*
+
--- /dev/null
+/* -----------------------------------------------------------------------
+ * 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
+
--- /dev/null
+%{
+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);
+}
+%}
+
+
+
+
--- /dev/null
+//
+// $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 <stdio.h>
+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);
+}
+
+%}
+
+
+
--- /dev/null
+//
+// $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 <stdlib.h>
+%}
+
+%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. */
+
--- /dev/null
+//
+// $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 <math.h>
+%}
+
+%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 <math.h>. 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
+
--- /dev/null
+//
+// memory.i
+// Dave Beazley
+// November 30, 1996
+// SWIG file for memory operations
+//
+
+%module memory
+%{
+#include <string.h>
+%}
+
+%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
+<string.h> 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 */
+
+
--- /dev/null
+// 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");
+ }
+}
+
+
+
+
+
+
--- /dev/null
+# 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)
+
+
+
+
+
+
--- /dev/null
+# ---------------------------------------------------------------
+# $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)
+
+
+
+
+
+
--- /dev/null
+# 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
+);
+
+
--- /dev/null
+/* $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 <math.h>
+#include <stdlib.h>
+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 <string.h>
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/* 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 <stdlib.h>
+
+#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
+
+
+
+
+
+
--- /dev/null
+/* 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;
+}
+
--- /dev/null
+// $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
+ }
+}
+
+%}
--- /dev/null
+//
+// 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.
+
+
+
--- /dev/null
+//
+// 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
+//
+// --------------------------------------------------------------------
+
+
--- /dev/null
+//
+// 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
+
+
+
+
--- /dev/null
+# 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)
+
+
+
+
--- /dev/null
+# ---------------------------------------------------------------
+# $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)
+
+
+
+
--- /dev/null
+/* 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);
+
+}
--- /dev/null
+//
+// 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 <Python.h>
+
+#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 <config.c>
+
+#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);
+}
+
+%}
+
+
+
+
--- /dev/null
+//
+// 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 <unistd.h>
+#endif
+
+#include <pythonrun.h>
+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 <config.c>
+
+#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 ? "<stdin>" : filename) != 0;
+ if (filename != NULL)
+ fclose(fp);
+ }
+
+ if (inspect && isatty((int)fileno(stdin)) &&
+ (filename != NULL || command != NULL))
+ sts = PyRun_AnyFile(stdin, "<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 <getpath.c>
+#ifdef __cplusplus
+}
+#undef malloc
+#endif
+
+%}
+
+
+
--- /dev/null
+//
+// 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 <unistd.h>
+#endif
+
+#include <pythonrun.h>
+
+#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 <config.c>
+
+#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 ? "<stdin>" : filename) != 0;
+ if (filename != NULL)
+ fclose(fp);
+ }
+
+ if (inspect && isatty((int)fileno(stdin)) &&
+ (filename != NULL || command != NULL))
+ sts = PyRun_AnyFile(stdin, "<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 <getpath.c>
+#ifdef __cplusplus
+}
+#undef malloc
+#endif
+
+%}
+
+
+
+
--- /dev/null
+//
+// 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 <Python.h>
+
+#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 <config.c>
+
+#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);
+}
+
+%}
+
+
+
+
--- /dev/null
+//
+// SWIG pointer conversion and utility library
+//
+// Dave Beazley
+// April 19, 1997
+//
+// Python specific implementation. This file is included
+// by the file ../pointer.i
+
+%{
+
+#include <ctype.h>
+
+/*------------------------------------------------------------------
+ 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.
+
+
+
+
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+/* 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
--- /dev/null
+/***********************************************************************
+ * $Header$
+ * swig_lib/python/python.cfg
+ *
+ * Contains variable linking and pointer type-checking code.
+ ************************************************************************/
+
+#include <string.h>
+#include <stdlib.h>
+
+#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("<Global variables>");
+}
+
+/* ---------------------------------------------------------------------
+ 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
+
+
--- /dev/null
+//
+// 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;
+}
+
--- /dev/null
+//
+// $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 <stdlib.h>
+%}
+
+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);
+
--- /dev/null
+/*****************************************************************************
+ * $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 <stdlib.h>
+
+#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
+
--- /dev/null
+# 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)
+
+
+
+
--- /dev/null
+# ---------------------------------------------------------------
+# $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)
+
+
+
+
--- /dev/null
+// 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;
+ }
+%}
+
--- /dev/null
+/* 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;
+ }
+
--- /dev/null
+// 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);
+}
+
+
+
--- /dev/null
+// 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;
+ }
+}
+
+
+
+
--- /dev/null
+/* delcmd.swg : Tcl object deletion method */
+
+static void TclDelete@CLASS@(ClientData clientData) {
+ @DESTRUCTOR@((@CLASSTYPE@) clientData);
+}
+
--- /dev/null
+/* delcmd.swg : Tcl object deletion method */
+
+static void TclDelete@CLASS@(ClientData clientData) {
+ @DESTRUCTOR@((@CLASSTYPE@) clientData);
+}
+
--- /dev/null
+//
+// $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 <stdio.h>
+#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*/
+}
+
+%}
--- /dev/null
+//
+// $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 <tk.h>
+#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;i<argc;i++) {
+ argv[i] = argv[i+1];
+ }
+
+ return argc;
+}
+#endif /*TCL_DEBUGGER*/
+
+/*ARGSUSED*/
+int
+optcmd_eval(dst,interp,key,argc,argv)
+char *dst;
+Tcl_Interp *interp;
+char *key;
+int argc;
+char **argv;
+{
+ int i;
+ int rc;
+
+ exp_cmdlinecmds = 1;
+
+ rc = Tcl_Eval(interp,argv[0]);
+ if (rc == TCL_ERROR) return -1;
+
+ argc--;
+ for (i=0;i<argc;i++) {
+ argv[i] = argv[i+1];
+ }
+
+ return argc;
+}
+
+/*
+ * Declaration for Tcl command procedure to create demo widget. This
+ * procedure is only invoked if SQUARE_DEMO is defined.
+ */
+
+extern int SquareCmd _ANSI_ARGS_((ClientData clientData,
+ Tcl_Interp *interp, int argc, char *argv[]));
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+static void Prompt _ANSI_ARGS_((Tcl_Interp *interp, int partial));
+static void StdinProc _ANSI_ARGS_((ClientData clientData,
+ int mask));
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * main --
+ *
+ * Main program for Wish.
+ *
+ * Results:
+ * None. This procedure never returns (it exits the process when
+ * it's done
+ *
+ * Side effects:
+ * This procedure initializes the wish world and then starts
+ * interpreting commands; almost anything could happen, depending
+ * on the script being interpreted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+main(argc, argv)
+ int argc; /* Number of arguments. */
+ char **argv; /* Array of argument strings. */
+{
+ char *args, *p, *msg, *class;
+ char buf[20];
+ int code;
+ int SWIG_init(Tcl_Interp *);
+ extern char *exp_argv0;
+ int used_argv1_for_filename = 0; /* added for Expect - DEL */
+
+#ifdef TK_EXTENDED
+ tk_mainInterp = interp = Tcl_CreateExtendedInterp();
+#else
+ interp = Tcl_CreateInterp();
+#endif
+#ifdef TCL_MEM_DEBUG
+ Tcl_InitMemory(interp);
+#endif
+
+ if (Exp_Init(interp) == TCL_ERROR) {
+ fprintf(stderr,"Exp_Init failed: %s\n",interp->result);
+ 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*/
+}
+\f
+#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);
+ }
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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*/
+
+%}
--- /dev/null
+//
+// 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 */
+
+\f
+#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
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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;
+}
+
+%}
--- /dev/null
+//
+// 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
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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. */
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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;
+}
+
+%}
--- /dev/null
+//
+// 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 <tk.h>
+
+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;
+
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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. */
+}
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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;
+}
+
+%}
--- /dev/null
+//
+// 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 */
+
+\f
+#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
+\f
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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;
+}
+
+%}
--- /dev/null
+/*
+ * 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 <console.h>
+#elif defined(__MWERKS__)
+# include <SIOUX.h>
+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;
+}
--- /dev/null
+/* 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 <Gestalt.h>
+#include <ToolUtils.h>
+#include <Fonts.h>
+#include <Dialogs.h>
+#include <SegLoad.h>
+#include <Traps.h>
+
+#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;
+}
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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;
+}
+
+
+
--- /dev/null
+/* 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;
+ }
+ }
+}
+
--- /dev/null
+/* 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;
+ }
+ }
+}
+
--- /dev/null
+//
+// 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 <ctype.h>
+
+/*------------------------------------------------------------------
+ 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 *;
+
+
+
+
+
+
+
--- /dev/null
+/*
+ * $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 <stdlib.h>
+
+#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
+
--- /dev/null
+/**************************************************************************
+ * $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 <tcl.h>
+#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
--- /dev/null
+//
+// $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
+
+%}
+
--- /dev/null
+// 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;
+ }
+%}
+
--- /dev/null
+//
+// 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;
+}
+
+
+
+
+
+
+
+
--- /dev/null
+//
+// $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 <tk.h>
+
+#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
+
+%}
+
+
+
--- /dev/null
+//
+// $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 <time.h>
+#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 */
+
+
+
+