From 39d92e49b2d91b250b6b63c0337b888b01c3e33d Mon Sep 17 00:00:00 2001 From: Henning Thielemann Date: Fri, 19 Mar 2004 11:45:29 +0000 Subject: [PATCH] added basic Modula-3 support git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5776 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Chicken.html | 32 +- Doc/Manual/Contents.html | 81 +- Doc/Manual/Contract.html | 3 +- Doc/Manual/Extending.html | 94 +- Doc/Manual/Introduction.html | 22 +- Doc/Manual/Java.html | 2 +- Doc/Manual/Modula3.html | 360 ++ Doc/Manual/Ocaml.html | 60 +- Doc/Manual/Perl5.html | 88 +- Doc/Manual/Php.html | 32 +- Doc/Manual/Preface.html | 4 +- Doc/Manual/Python.html | 128 +- Doc/Manual/Ruby.html | 102 +- Doc/Manual/SWIG.html | 2 +- Doc/Manual/SWIGPlus.html | 2 +- Doc/Manual/Tcl.html | 90 +- Doc/Manual/Warnings.html | 2 +- Doc/Manual/Windows.html | 36 +- Doc/Manual/chapters | 1 + Examples/Makefile.in | 25 + Examples/modula3/check.list | 7 + Examples/modula3/class/.cvsignore | 17 + Examples/modula3/class/Makefile | 25 + Examples/modula3/class/example.cxx | 28 + Examples/modula3/class/example.h | 44 + Examples/modula3/class/example.i | 32 + Examples/modula3/class/swig.tmpl | 11 + Examples/modula3/enum/.cvsignore | 18 + Examples/modula3/enum/Makefile | 26 + Examples/modula3/enum/example.cxx | 32 + Examples/modula3/enum/example.h | 83 + Examples/modula3/enum/example.i | 72 + Examples/modula3/exception/.cvsignore | 17 + Examples/modula3/exception/Makefile | 23 + Examples/modula3/exception/example.h | 18 + Examples/modula3/exception/example.i | 43 + Examples/modula3/reference/.cvsignore | 15 + Examples/modula3/reference/Makefile | 21 + Examples/modula3/reference/example.cxx | 41 + Examples/modula3/reference/example.h | 22 + Examples/modula3/reference/example.i | 32 + Examples/modula3/simple/.cvsignore | 8 + Examples/modula3/simple/Makefile | 21 + Examples/modula3/simple/example.c | 18 + Examples/modula3/simple/example.i | 5 + Examples/modula3/typemap/.cvsignore | 17 + Examples/modula3/typemap/Makefile | 21 + Examples/modula3/typemap/example.i | 90 + Lib/modula3/modula3.swg | 699 ++++ Lib/modula3/modula3head.swg | 69 + Lib/modula3/typemaps.i | 66 + Makefile.in | 13 +- Source/DOH/README | 4 +- Source/Include/swigwarn.h | 14 + Source/Makefile.am | 1 + Source/Modules/modula3.cxx | 4184 ++++++++++++++++++++++++ Source/Modules/swigmain.cxx | 2 + 57 files changed, 6645 insertions(+), 380 deletions(-) create mode 100644 Doc/Manual/Modula3.html create mode 100644 Examples/modula3/check.list create mode 100644 Examples/modula3/class/.cvsignore create mode 100644 Examples/modula3/class/Makefile create mode 100644 Examples/modula3/class/example.cxx create mode 100644 Examples/modula3/class/example.h create mode 100644 Examples/modula3/class/example.i create mode 100644 Examples/modula3/class/swig.tmpl create mode 100644 Examples/modula3/enum/.cvsignore create mode 100644 Examples/modula3/enum/Makefile create mode 100644 Examples/modula3/enum/example.cxx create mode 100644 Examples/modula3/enum/example.h create mode 100644 Examples/modula3/enum/example.i create mode 100644 Examples/modula3/exception/.cvsignore create mode 100644 Examples/modula3/exception/Makefile create mode 100644 Examples/modula3/exception/example.h create mode 100644 Examples/modula3/exception/example.i create mode 100644 Examples/modula3/reference/.cvsignore create mode 100644 Examples/modula3/reference/Makefile create mode 100644 Examples/modula3/reference/example.cxx create mode 100644 Examples/modula3/reference/example.h create mode 100644 Examples/modula3/reference/example.i create mode 100644 Examples/modula3/simple/.cvsignore create mode 100644 Examples/modula3/simple/Makefile create mode 100644 Examples/modula3/simple/example.c create mode 100644 Examples/modula3/simple/example.i create mode 100644 Examples/modula3/typemap/.cvsignore create mode 100644 Examples/modula3/typemap/Makefile create mode 100644 Examples/modula3/typemap/example.i create mode 100644 Lib/modula3/modula3.swg create mode 100644 Lib/modula3/modula3head.swg create mode 100644 Lib/modula3/typemaps.i create mode 100644 Source/Modules/modula3.cxx diff --git a/Doc/Manual/Chicken.html b/Doc/Manual/Chicken.html index 7bd536b34..9ff33699a 100644 --- a/Doc/Manual/Chicken.html +++ b/Doc/Manual/Chicken.html @@ -7,7 +7,7 @@ -

24 SWIG and Chicken

+

25 SWIG and Chicken

@@ -57,25 +57,26 @@
  • SWIG Windows Examples -
  • SWIG on Cygwin and MinGW +
  • SWIG on Cygwin and MinGW @@ -380,17 +381,18 @@
  • Enabling additional warnings
  • Issuing a warning message
  • Commentary -
  • Warning number reference +
  • Message output format +
  • Warning number reference -
  • History +
  • History @@ -603,7 +605,28 @@ -

    18 SWIG and Ocaml

    +

    18 SWIG and Modula-3

    + + + + + +

    19 SWIG and Ocaml

    -

    19 SWIG and Perl5

    +

    20 SWIG and Perl5

    -

    20 SWIG and PHP4

    +

    21 SWIG and PHP4

    -

    21 SWIG and Python

    +

    22 SWIG and Python

    -

    22 SWIG and Ruby

    +

    23 SWIG and Ruby

    -

    23 SWIG and Tcl

    +

    24 SWIG and Tcl

    -

    24 SWIG and Chicken

    +

    25 SWIG and Chicken

    -

    25 Extending SWIG

    +

    26 Extending SWIG

    -

    25.10.11 Examples and test cases

    +

    26.10.11 Examples and test cases

    Each of the language modules provides one or more examples. These examples @@ -2467,7 +2467,7 @@ By default, all of the examples are built and run when the user types during this process, see the section on configuration files. -

    25.10.12 Documentation

    +

    26.10.12 Documentation

    Don't forget to write end-user documentation for your language module. Currently, @@ -2494,13 +2494,13 @@ Some topics that you'll want to be sure to address include: if available. -

    25.11 Typemaps

    +

    26.11 Typemaps

    -

    25.11.1 Proxy classes

    +

    26.11.1 Proxy classes

    -

    25.12 Guide to parse tree nodes

    +

    26.12 Guide to parse tree nodes

    This section describes the different parse tree nodes and their attributes. @@ -2817,4 +2817,4 @@ extern "X" { ... } declaration.
    SWIG 1.3 - Last Modified : January 22, 2002
    - + \ No newline at end of file diff --git a/Doc/Manual/Introduction.html b/Doc/Manual/Introduction.html index 403c2486c..c57ae2b40 100644 --- a/Doc/Manual/Introduction.html +++ b/Doc/Manual/Introduction.html @@ -17,11 +17,11 @@
  • Building a Perl5 module
  • Building a Python module
  • Shortcuts -
  • Building libraries and modules -
  • Supported C/C++ language features -
  • Non-intrusive interface building -
  • Hands off code generation +
  • Supported C/C++ language features +
  • Non-intrusive interface building +
  • Hands off code generation +
  • SWIG and freedom @@ -67,6 +67,7 @@ in scientific and engineering projects.

    1.2 Why use SWIG?

    + As stated in the previous section, the primary purpose of SWIG is to simplify the task of integrating C/C++ with other programming languages. However, why would anyone want to do that? To answer that question, it is useful to list a few strengths @@ -286,7 +287,8 @@ print $example::My_variable + 4.5, "\n"; 7.5 -

    1.4 Supported C/C++ language features

    +

    1.4 Supported C/C++ language features

    + A primary goal of the SWIG project is to make the language binding process extremely easy. Although a few simple examples have been shown, @@ -321,7 +323,8 @@ wrapping simple C++ code. In fact, SWIG is able handle C++ code that stresses the very limits of many C++ compilers. -

    1.5 Non-intrusive interface building

    +

    1.5 Non-intrusive interface building

    + When used as intended, SWIG requires minimal (if any) modification to existing C code. This makes SWIG extremely easy to use with existing @@ -330,7 +333,7 @@ the C code independent of the high level interface, you can change the interface and reuse the code in other applications. It is also possible to support different types of interfaces depending on the application. -

    1.6 Hands off code generation

    +

    1.6 Hands off code generation

    SWIG is designed to produce working code that needs no @@ -343,7 +346,8 @@ file. While this approach may limit flexibility for hard-core hackers, it allows others to forget about the low-level implementation details. -

    SWIG and freedom

    +

    1.7 SWIG and freedom

    + No, this isn't a special section on the sorry state of world politics. However, it may be useful to know that SWIG was written with a @@ -371,4 +375,4 @@ non-portable or unreliable programming features.
    SWIG 1.3 - Last Modified : August 10, 2002
    - + \ No newline at end of file diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html index b55d82dd6..4c1e1d755 100644 --- a/Doc/Manual/Java.html +++ b/Doc/Manual/Java.html @@ -4789,4 +4789,4 @@ If your SWIG installation went well Unix users should be able to type makeWindows Examples. - + \ No newline at end of file diff --git a/Doc/Manual/Modula3.html b/Doc/Manual/Modula3.html new file mode 100644 index 000000000..310f2100d --- /dev/null +++ b/Doc/Manual/Modula3.html @@ -0,0 +1,360 @@ + + + +SWIG and Modula-3 + + +

    18 SWIG and Modula-3

    + + + + + + +This chapter describes SWIG's support of +Modula-3. +You should be familiar with the +basics +of SWIG, +especially typemaps. + + +

    18.1 Overview

    + + +

    +The Modula-3 support is very basic and highly experimental! +Many features are still not designed satisfyingly +and I need more discussion about the odds and ends. +The Modula-3 generator was already useful for interfacing +to the + +PLPlot + +library. + + + + +

    18.2 Preliminaries

    + + + +

    18.2.1 Compilers

    + + +There are different Modula-3 compilers around: +cm3, pm3, ezm3, Klagenfurth Modula-3, Cambridge Modula-3. +SWIG itself does not contain compiler specific code +but the library file +modula3.swg +may do so. +For testing examples I used Critical Mass' cm3. + + +

    18.2.2 Additional Commandline Options

    + + +There some experimental command line options +that prevent SWIG from generating interface files. +Instead files are emitted that may assist +writing SWIG interface files. + + + + + + + + + + + + + + + + + + + + +
    Modula-3 specific options
    -generateconst <file> +Disable generation of interfaces and wrappers. +Instead generate code for computing numeric values of constants. +
    -generaterename <file> +Disable generation of interfaces and wrappers. +Instead generate suggestions for %rename. +
    -generatetypemap <file> +Disable generation of interfaces and wrappers. +Instead generate templates for some basic typemaps. +
    + + +

    18.3 Modula-3 typemaps

    + + + +

    18.3.1 Inputs and outputs

    + + +Each C procedure has a bunch of inputs and outputs. +Aside from global variables +inputs are passed as call arguments, +outputs are updated reference arguments and +the function value. + +Each C type can have several typemaps +that apply only in case the types are used +as input argument, as output argument, +or as return value. +A further typemap may specify +the direction that is used for certain parameters. + + +

    18.3.2 Exceptions

    + + +Modula-3 provides another possibility +of an output of a function: exceptions. + +Any piecec of Modula-3 code that SWIG inserts +due to a typemap can raise an exception. +This way you can also convert an error code +from a C function into an Modula-3 exception. + +The RAISES clause is controlled +by typemaps with the except extension. + + +

    18.3.3 Subranges, Enumerations, Sets

    + + + +

    18.3.4 Objects

    + + + +

    18.3.5 Example

    + + +The generation of wrappers in Modula-3 needs very fine control +to take advantage of the language features. +Here is an example of a generated wrapper +where almost everything is generated by a typemap: + +
    +         (* %relabel  m3wrapinmode m3wrapinname m3wrapintype  m3wrapindefault *)
    +  PROCEDURE Name     (READONLY       str       :    TEXT    :=      ""       )
    +              (* m3wrapoutcheck:throws *)
    +     : NameResult RAISES {E} =
    +    VAR
    +      arg0   : C.char_star;              (* m3wrapretvar *)
    +      arg1   : C.char_star;              (* m3wrapargvar *)
    +      arg2   : C.int;
    +      result : RECORD
    +           (*m3wrapretname  m3wraprettype*)
    +                 unixPath : TEXT;
    +           (*m3wrapoutname  m3wrapouttype*)
    +                 checksum : CARDINAL;
    +               END;
    +    BEGIN
    +      TRY
    +        arg1 := M3toC.SharedTtoS(str);   (* m3wrapinconv *)
    +        IF Text.Length(arg1) > 10 THEN   (* m3wrapincheck *)
    +          RAISE E("str too long");
    +        END;
    + (* m3wrapretraw           m3wrapargraw *)
    +        arg0 := MessyToUnix  (arg1,   arg2);
    +        result.unixPath := M3toC.CopyStoT(arg0);  (* m3wrapretconv *)
    +        result.checksum := arg2;         (* m3wrapoutconv *)
    +        IF result.checksum = 0 THEN      (* m3wrapoutcheck *)
    +          RAISE E("invalid checksum");
    +        END;
    +      FINALLY
    +        M3toC.FreeSharedS(str,arg1);     (* m3wrapfreearg *)
    +      END;
    +    END Name;
    +
    + + + + \ No newline at end of file diff --git a/Doc/Manual/Ocaml.html b/Doc/Manual/Ocaml.html index 44eafcb0c..31a3c7eee 100644 --- a/Doc/Manual/Ocaml.html +++ b/Doc/Manual/Ocaml.html @@ -6,7 +6,7 @@ -

    18 SWIG and Ocaml

    +

    19 SWIG and Ocaml

    • Preliminaries @@ -73,7 +73,7 @@ If you're not familiar with the Objective Caml language, you can visit The Ocaml Website.

      -

      18.1 Preliminaries

      +

      19.1 Preliminaries

      SWIG 1.3 works with Ocaml 3.04 and above. Given the choice, @@ -90,7 +90,7 @@ usual -lxxx against libxxx.so, as well as with Gerd Stolpmann's file Examples/Makefile illustrate how to compile and link SWIG modules that will be loaded dynamically. This has only been tested on Linux so far. -

      18.1.1 Running SWIG

      +

      19.1.1 Running SWIG

      The basics of getting a SWIG Ocaml module up and running @@ -109,7 +109,7 @@ you will compile the file example_wrap.c with ocamlc or the resulting .ml and .mli files as well, and do the final link with -custom (not needed for native link).

      -

      18.1.2 Compiling the code

      +

      19.1.2 Compiling the code

      The O'Caml SWIG module now requires you to compile a module (Swig) @@ -141,7 +141,7 @@ the user more freedom with respect to custom typing.
      % cp example_wrap.cxx example_wrap.cxx.c
      % ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c
      % ...
      -

      18.1.3 The camlp4 module

      +

      19.1.3 The camlp4 module

      The camlp4 module (swigp4.ml -> swigp4.cmo) contains a simple rewriter which @@ -211,7 +211,7 @@ let b = C_string (getenv "PATH") -

      18.1.4 Using your module

      +

      19.1.4 Using your module

      You can test-drive your module by building a @@ -221,7 +221,7 @@ toplevel ocaml interpreter. Consult the ocaml manual for details. option to build your functions into the primitive list. This option is not needed when you build native code. -

      18.1.5 Compilation problems and compiling with C++

      +

      19.1.5 Compilation problems and compiling with C++

      As mentioned above, .cxx files need special @@ -230,7 +230,7 @@ that uses class as a non-keyword, and C code that is too liberal with pointer types may not compile under the C++ compiler. Most code meant to be compiled as C++ will not have problems. -

      18.2 The low-level Ocaml/C interface

      +

      19.2 The low-level Ocaml/C interface

      In order to provide access to overloaded functions, and @@ -317,7 +317,7 @@ is that you must append them to the return list with swig_result = caml_list_a value items pass through directly, but you must make your own type signature for a function that uses value in this way. -

      18.2.1 The generated module

      +

      19.2.1 The generated module

      The SWIG %module directive specifies the name of the Ocaml @@ -347,7 +347,7 @@ which should run when the module is loaded may be inserted here. it describes the output SWIG will generate for class definitions. -

      18.2.2 Enums

      +

      19.2.2 Enums

      SWIG will wrap enumerations as polymorphic variants in the output @@ -403,10 +403,10 @@ val x : Enum_test.c_obj = C_enum `a

      -

      18.2.3 Arrays

      +

      19.2.3 Arrays

      -

      18.2.3.1 Simple types of bounded arrays

      +

      19.2.3.1 Simple types of bounded arrays

      @@ -426,7 +426,7 @@ arrays of simple types with known bounds in your code, but this only works for arrays whose bounds are completely specified.

      -

      18.2.3.2 Complex and unbounded arrays

      +

      19.2.3.2 Complex and unbounded arrays

      @@ -439,7 +439,7 @@ SWIG can't predict which of these methods will be used in the array, so you have to specify it for yourself in the form of a typemap.

      -

      18.2.3.3 Using an object

      +

      19.2.3.3 Using an object

      @@ -453,7 +453,7 @@ Consider writing an object when the ending condition of your array is complex, such as using a required centinel, etc.

      -

      18.2.3.4 Example typemap for a function taking float * and int

      +

      19.2.3.4 Example typemap for a function taking float * and int

      @@ -503,7 +503,7 @@ void printfloats( float *tab, int len ); -

      18.2.4 C++ Classes

      +

      19.2.4 C++ Classes

      C++ classes, along with structs and unions are represented by C_obj @@ -541,7 +541,7 @@ the underlying pointer, so using create_[x]_from_ptr alters the returned value for the same object.

      -

      18.2.4.1 STL vector and string Example

      +

      19.2.4.1 STL vector and string Example

      Standard typemaps are now provided for STL vector and string. More are in @@ -613,7 +613,7 @@ baz # -

      18.2.4.2 C++ Class Example

      +

      19.2.4.2 C++ Class Example

      Here's a simple example using Trolltech's Qt Library: @@ -640,7 +640,7 @@ public: };

      -

      18.2.4.3 Compiling the example

      +

      19.2.4.3 Compiling the example

      @@ -658,7 +658,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
         -L$QTPATH/lib -cclib -lqt
       
      -

      18.2.4.4 Sample Session

      +

      19.2.4.4 Sample Session

      @@ -683,10 +683,10 @@ val hello : Qt.c_obj = C_obj 
       Assuming you have a working installation of QT, you will see a window
       containing the string "hi" in a button.  
       
      -

      18.2.5 Director Classes

      +

      19.2.5 Director Classes

      -

      18.2.5.1 Director Introduction

      +

      19.2.5.1 Director Introduction

      Director classes are classes which allow Ocaml code to override the public @@ -708,7 +708,7 @@ class foo { };

      -

      18.2.5.2 Overriding Methods in Ocaml

      +

      19.2.5.2 Overriding Methods in Ocaml

      @@ -732,7 +732,7 @@ In this example, I'll examine the objective caml code involved in providing an overloaded class. This example is contained in Examples/ocaml/shapes.

      -

      18.2.5.3 Director Usage Example

      +

      19.2.5.3 Director Usage Example

      example_prog.ml
      @@ -786,7 +786,7 @@ a tricky shape implementation, such as a boolean combination, to be expressed in a more effortless style in ocaml, while leaving the "engine" part of the program in C++.

      -

      18.2.5.4 Creating director objects

      +

      19.2.5.4 Creating director objects

      The definition of the actual object triangle can be described this way: @@ -820,7 +820,7 @@ new_derived_object, and throws NotObject). This prevents a deleted C++ object from causing a core dump, as long as the object is destroyed properly. -

      18.2.5.5 Typemaps for directors, directorin, directorout, directorargout

      +

      19.2.5.5 Typemaps for directors, directorin, directorout, directorargout

      @@ -830,7 +830,7 @@ direction is reversed. They provide for you to provide argout values, as well as a function return value in the same way you provide function arguments, and to receive arguments the same way you normally receive function returns.

      -

      18.2.5.6 directorin typemap

      +

      19.2.5.6 directorin typemap

      @@ -841,7 +841,7 @@ code receives when you are called. In general, a simple directorin typ can use the same body as a simple out typemap.

      -

      18.2.5.7 directorout typemap

      +

      19.2.5.7 directorout typemap

      @@ -852,7 +852,7 @@ for the same type, except when there are special requirements for object ownership, etc.

      -

      18.2.5.8 directorargout typemap

      +

      19.2.5.8 directorargout typemap

      @@ -869,7 +869,7 @@ In the event that you don't specify all of the necessary values, integral values will read zero, and struct or object returns have undefined results.

      -

      18.2.6 Exceptions

      +

      19.2.6 Exceptions

      Catching exceptions is now supported using SWIG's %exception feature. A simple diff --git a/Doc/Manual/Perl5.html b/Doc/Manual/Perl5.html index da708efb8..7f6ef58b7 100644 --- a/Doc/Manual/Perl5.html +++ b/Doc/Manual/Perl5.html @@ -5,7 +5,7 @@ -

      19 SWIG and Perl5

      +

      20 SWIG and Perl5

      • Overview @@ -78,7 +78,7 @@ best results, it is recommended that SWIG be used with Perl5.003 or later. Earlier versions are problematic and SWIG generated extensions may not compile or run correctly.

        -

        19.1 Overview

        +

        20.1 Overview

        To build Perl extension modules, SWIG uses a layered approach. At @@ -96,7 +96,7 @@ procedural interface is presented. Finally, proxy classes are described. Advanced customization features, typemaps, and other options are found near the end of the chapter. -

        19.2 Preliminaries

        +

        20.2 Preliminaries

        To build a Perl5 module, run Swig using the -perl option as @@ -116,7 +116,7 @@ properly load the module. To build the module, you will need to compile the file example_wrap.c and link it with the rest of your program. -

        19.2.1 Getting the right header files

        +

        20.2.1 Getting the right header files

        In order to compile, SWIG extensions need the following Perl5 header files :

        @@ -145,7 +145,7 @@ loaded, an easy way to find out is to run Perl itself. -

        19.2.2 Compiling a dynamic module

        +

        20.2.2 Compiling a dynamic module

        The preferred approach to building an extension module is to compile it into @@ -172,7 +172,7 @@ the SWIG interface file. If you used `%module example', then the target should be named `example.so', `example.sl', or the appropriate dynamic module name on your system. -

        19.2.3 Building a dynamic module with MakeMaker

        +

        20.2.3 Building a dynamic module with MakeMaker

        It is also possible to use Perl to build dynamically loadable modules @@ -204,7 +204,7 @@ the preferred approach to compilation. More information about MakeMaker can be found in "Programming Perl, 2nd ed." by Larry Wall, Tom Christiansen, and Randal Schwartz.

        -

        19.2.4 Building a static version of Perl

        +

        20.2.4 Building a static version of Perl

        If you machine does not support dynamic loading or if you've tried to @@ -267,7 +267,7 @@ should be functionality identical to Perl with your C/C++ extension added to it. Depending on your machine, you may need to link with additional libraries such as -lsocket, -lnsl, -ldl, etc. -

        19.2.5 Using the module

        +

        20.2.5 Using the module

        To use the module, simply use the Perl use statement. If @@ -398,7 +398,7 @@ Finally, you can use a command such as ldconfig (Linux) or system configuration (this requires root access and you will need to read the man pages). -

        19.2.6 Compilation problems and compiling with C++

        +

        20.2.6 Compilation problems and compiling with C++

        Compilation of C++ extensions has traditionally been a tricky problem. @@ -520,7 +520,7 @@ in Lib/perl5/noembed.h while compiling the wrapper, you will have to find the macro that conflicts and add an #undef into the .i file. Please report any conflicting macros you find to swig@cs.uchicago.edu. -

        19.2.7 Compiling for 64-bit platforms

        +

        20.2.7 Compiling for 64-bit platforms

        On platforms that support 64-bit applications (Solaris, Irix, etc.), @@ -543,7 +543,7 @@ that software. This may prevent the use of 64-bit extensions. It may also introduce problems on platforms that support more than one linking standard (e.g., -o32 and -n32 on Irix). -

        19.3 Building Perl Extensions under Windows

        +

        20.3 Building Perl Extensions under Windows

        Building a SWIG extension to Perl under Windows is roughly @@ -552,7 +552,7 @@ produce a DLL that can be loaded into the Perl interpreter. This section assumes you are using SWIG with Microsoft Visual C++ although the procedure may be similar with other compilers. -

        19.3.1 Running SWIG from Developer Studio

        +

        20.3.1 Running SWIG from Developer Studio

        If you are developing your application within Microsoft developer @@ -613,13 +613,13 @@ print "$a\n"; -

        19.3.2 Using other compilers

        +

        20.3.2 Using other compilers

        SWIG is known to work with Cygwin and may work with other compilers on Windows. For general hints and suggestions refer to the Windows chapter. -

        19.4 The low-level interface

        +

        20.4 The low-level interface

        At its core, the Perl module uses a simple low-level interface @@ -627,7 +627,7 @@ to C function, variables, constants, and classes. This low-level interface can be used to control your application. However, it is also used to construct more user-friendly proxy classes as described in the next section. -

        19.4.1 Functions

        +

        20.4.1 Functions

        C functions are converted into new Perl built-in commands (or @@ -645,7 +645,7 @@ Now, in Perl: $a = &example::fact(2); -

        19.4.2 Global variables

        +

        20.4.2 Global variables

        Global variables are handled using Perl's magic @@ -698,7 +698,7 @@ extern char *path; // Declared later in the input -

        19.4.3 Constants

        +

        20.4.3 Constants

        Constants are wrapped as read-only Perl variables. For example: @@ -721,7 +721,7 @@ $example::FOO = 2; # Error -

        19.4.4 Pointers

        +

        20.4.4 Pointers

        SWIG represents pointers as blessed references. A blessed reference @@ -820,7 +820,7 @@ C-style cast may return a bogus result whereas as the C++-style cast will return as XS and xsubpp. Given the advancement of the SWIG typesystem and the growing differences between SWIG and XS, this is no longer supported. -

        19.4.5 Structures

        +

        20.4.5 Structures

        Access to the contents of a structure are provided through a set of low-level @@ -941,7 +941,7 @@ void Bar_f_set(Bar *b, Foo *val) { -

        19.4.6 C++ classes

        +

        20.4.6 C++ classes

        C++ classes are wrapped by building a set of low level accessor functions. @@ -999,7 +999,7 @@ as the first argument. Although this interface is fairly primitive, it provides direct access to C++ objects. A higher level interface using Perl proxy classes can be built using these low-level accessors. This is described shortly. -

        19.4.7 C++ classes and type-checking

        +

        20.4.7 C++ classes and type-checking

        The SWIG type-checker is fully aware of C++ inheritance. Therefore, if you have @@ -1029,7 +1029,7 @@ then the function spam() accepts Foo * or a pointer to any cla If necesssary, the type-checker also adjusts the value of the pointer (as is necessary when multiple inheritance is used). -

        19.4.8 C++ overloaded functions

        +

        20.4.8 C++ overloaded functions

        If you have a C++ program with overloaded functions or methods, you will need to disambiguate @@ -1067,7 +1067,7 @@ example::Spam_foo_d($s,3.14); Please refer to the "SWIG Basics" chapter for more information. -

        19.4.9 Operators

        +

        20.4.9 Operators

        C++ operators can also be wrapped using the %rename directive. All you need to do is @@ -1094,7 +1094,7 @@ $c = example::add_complex($a,$b); Some preliminary work on mapping C++ operators into Perl operators has been completed. This is covered later. -

        19.4.10 Modules and packages

        +

        20.4.10 Modules and packages

        When you create a SWIG extension, everything gets placed into @@ -1149,7 +1149,7 @@ print Foo::fact(4),"\n"; # Call a function in package FooBar --> -

        19.5 Input and output parameters

        +

        20.5 Input and output parameters

        A common problem in some C programs is handling parameters passed as simple pointers. For @@ -1335,7 +1335,7 @@ print "$c\n"; Note: The REFERENCE feature is only currently supported for numeric types (integers and floating point). -

        19.6 Exception handling

        +

        20.6 Exception handling

        The SWIG %exception directive can be used to create a @@ -1484,7 +1484,7 @@ See the chapter on "Customization features" for This is still supported, but it is deprecated. The newer %exception directive provides the same functionality, but it has additional capabilities that make it more powerful. -

        19.7 Remapping datatypes with typemaps

        +

        20.7 Remapping datatypes with typemaps

        This section describes how you can modify SWIG's default wrapping behavior @@ -1498,7 +1498,7 @@ part of using SWIG---the default wrapping behavior is enough in most cases. Typemaps are only used if you want to change some aspect of the primitive C-Perl interface. -

        19.7.1 A simple typemap example

        +

        20.7.1 A simple typemap example

        A typemap is nothing more than a code generation rule that is attached to @@ -1588,7 +1588,7 @@ example::count("e","Hello World"); -

        19.7.2 Perl5 typemaps

        +

        20.7.2 Perl5 typemaps

        The previous section illustrated an "in" typemap for converting Perl objects to C. @@ -1668,7 +1668,7 @@ Return of C++ member data (all languages).

        Check value of input parameter.

        -

        19.7.3 Typemap variables

        +

        20.7.3 Typemap variables

        Within typemap code, a number of special variables prefaced with a $ may appear. @@ -1722,7 +1722,7 @@ properly assigned. The Perl name of the wrapper function being created. -

        19.7.4 Useful functions

        +

        20.7.4 Useful functions

        When writing typemaps, it is necessary to work directly with Perl5 @@ -1782,14 +1782,14 @@ int sv_isa(SV *, char *0; -

        19.8 Typemap Examples

        +

        20.8 Typemap Examples

        This section includes a few examples of typemaps. For more examples, you might look at the files "perl5.swg" and "typemaps.i" in the SWIG library. -

        19.8.1 Converting a Perl5 array to a char **

        +

        20.8.1 Converting a Perl5 array to a char **

        A common problem in many C programs is the processing of command line @@ -1877,7 +1877,7 @@ print @$b,"\n"; # Print it out -

        19.8.2 Return values

        +

        20.8.2 Return values

        Return values are placed on the argument stack of each wrapper @@ -1903,7 +1903,7 @@ can be done using the EXTEND() macro as in :

        } -

        19.8.3 Returning values from arguments

        +

        20.8.3 Returning values from arguments

        Sometimes it is desirable for a function to return a value in one of @@ -1954,7 +1954,7 @@ print "multout(7,13) = @r\n"; ($x,$y) = multout(7,13); -

        19.8.4 Accessing array structure members

        +

        20.8.4 Accessing array structure members

        Consider the following data structure :

        @@ -2006,7 +2006,7 @@ the "in" typemap in the previous section would be used to convert an int[] array to C whereas the "memberin" typemap would be used to copy the converted array into a C data structure. -

        19.8.5 Turning Perl references into C pointers

        +

        20.8.5 Turning Perl references into C pointers

        A frequent confusion on the SWIG mailing list is errors caused by the @@ -2064,7 +2064,7 @@ print "$c\n"; -

        19.8.6 Pointer handling

        +

        20.8.6 Pointer handling

        Occasionally, it might be necessary to convert pointer values that have @@ -2136,7 +2136,7 @@ For example: -

        19.9 Proxy classes

        +

        20.9 Proxy classes

        Out of date. Needs update. @@ -2149,7 +2149,7 @@ This is done by constructing a Perl proxy class that provides an OO wrapper to the underlying code. This section describes the implementation details of the proxy interface. -

        19.9.1 Preliminaries

        +

        20.9.1 Preliminaries

        To generate proxy classes, you need to use the -proxy command line option. @@ -2283,7 +2283,7 @@ $v->DESTROY(); -

        19.9.2 Object Ownership

        +

        20.9.2 Object Ownership

        In order for shadow classes to work properly, it is necessary for Perl @@ -2356,7 +2356,7 @@ As always, a little care is in order. SWIG does not provide reference counting, garbage collection, or advanced features one might find in sophisticated languages.

        -

        19.9.3 Nested Objects

        +

        20.9.3 Nested Objects

        Suppose that we have a new object that looks like this :

        @@ -2399,7 +2399,7 @@ $p->{f}->{x} = 0.0; %${$p->{v}} = ( x=>0, y=>0, z=>0);

        -

        19.9.4 Shadow Functions

        +

        20.9.4 Shadow Functions

        When functions take arguments involving a complex object, it is @@ -2429,7 +2429,7 @@ this :

        This function replaces the original function, but operates in an identical manner.

        -

        19.9.5 Inheritance

        +

        20.9.5 Inheritance

        Simple C++ inheritance is handled using the Perl @ISA array diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html index cc9423c8e..cf12a152a 100644 --- a/Doc/Manual/Php.html +++ b/Doc/Manual/Php.html @@ -6,7 +6,7 @@ -

        20 SWIG and PHP4

        +

        21 SWIG and PHP4

        • Preliminaries @@ -43,7 +43,7 @@ if you thought you were familiar with what it said. The major change is that shadow classes are implemented inside the php module in C++ instead of in the generated .php file in php. -

          20.1 Preliminaries

          +

          21.1 Preliminaries

          In order to use this module, you will need to have a copy of the PHP 4.0 (or @@ -53,7 +53,7 @@ need either the php binary or the Apache php module. If you want to build your extension into php directly (without having the overhead of loading it into each script), you will need the complete PHP source tree available. -

          20.2 Building PHP4 Extensions

          +

          21.2 Building PHP4 Extensions

          To build a PHP4 extension, run swig using the -php4 option as follows : @@ -86,7 +86,7 @@ the extension into the php executable/library so it will be available in every script. The first choice is the default, however it can be changed by passing the '-phpfull' command line switch to select the second build method. -

          20.2.1 Building a loadable extension

          +

          21.2.1 Building a loadable extension

          To build a dynamic module for PHP, you have two options. You can use the @@ -146,10 +146,10 @@ attempts to do the dl() call for you: A more complicated method which builds the module directly into the php executable is described below. -

          20.2.2 Basic PHP4 interface

          +

          21.2.2 Basic PHP4 interface

          -

          20.2.3 Functions

          +

          21.2.3 Functions

          C functions are converted into PHP functions. Default/optional arguments are @@ -170,7 +170,7 @@ $c = bar(3.5); # Use default argument for 2nd parameter -

          20.2.4 Global Variables

          +

          21.2.4 Global Variables

          Global variables are difficult for PHP to handle, unlike Perl, their is no @@ -198,7 +198,7 @@ example_func(); # Syncs C variable to PHP Variable, now both 4 SWIG supports global variables of all C datatypes including pointers and complex objects.

          -

          20.2.5 Pointers

          +

          21.2.5 Pointers

          Pointers to C/C++ objects no longer represented as character @@ -208,7 +208,7 @@ as PHP resources, rather like MySQL connection handles. You can also explicitly create a NULL pointer as a string "NULL" or by passing a null or empty value. -

          20.2.6 Structures and C++ classes

          +

          21.2.6 Structures and C++ classes

          For structures and classes, SWIG produces accessor fuction for each member function and data. For example :

          @@ -241,7 +241,7 @@ To use the class, simply use these functions. However, SWIG also has a mechanism for creating shadow classes that hides these functions and uses an object oriented interface instead - see below -

          20.2.7 Constants

          +

          21.2.7 Constants

          These work in much the same way as in C/C++, constants can be defined by using @@ -337,7 +337,7 @@ both point to the same value, without the case test taking place. -

          20.2.8 Shadow classes

          +

          21.2.8 Shadow classes

          To avoid having to call the various accessor function to get at structures or @@ -360,7 +360,7 @@ functions like before. .... ( more examples on the way ) .... -

          20.2.9 Constructors and Destructers

          +

          21.2.9 Constructors and Destructers

          Constructors are used in PHP as in C++, they are called when the object is @@ -384,7 +384,7 @@ object. 'RegisterShutdownFunction' is no longer needed for this. I am not sure if PHP resources are all freed at the end of a script, or when they each go out of scope. -

          20.2.10 Static Member Variables

          +

          21.2.10 Static Member Variables

          Class variables are not supported in PHP, however class functions are, using @@ -418,7 +418,7 @@ echo "There has now been " . Ko::threats() . " threats\n"; -

          20.2.11 PHP4 Pragmas

          +

          21.2.11 PHP4 Pragmas

          There are a few pragmas understood by the PHP4 module. The first, @@ -447,7 +447,7 @@ function is called. %include "example.h" -

          20.2.12 Building extensions into php

          +

          21.2.12 Building extensions into php

          This method, selected with the -phpfull command line switch, involves @@ -489,7 +489,7 @@ Once configure has completed, you can run make to build php. If this all compiles correctly, you should end up with a php executable/library which contains your new module. You can test it with a php script which does not have the 'dl' command as used above. -

          20.2.13 To be furthered...

          +

          21.2.13 To be furthered...

          diff --git a/Doc/Manual/Preface.html b/Doc/Manual/Preface.html index 11b27479f..0cbb51a33 100644 --- a/Doc/Manual/Preface.html +++ b/Doc/Manual/Preface.html @@ -105,6 +105,7 @@ about this can be obtained at:

          0.5 Prerequisites

          + This manual assumes that you know how to write C/C++ programs and that you have at least heard of scripting languages such as Tcl, Python, and Perl. A detailed knowledge of these scripting @@ -188,6 +189,7 @@ port.

          0.10 Bug reports

          + Although every attempt has been made to make SWIG bug-free, we are also trying to make feature improvements that may introduce bugs. To report a bug, either send mail to the SWIG developer @@ -201,4 +203,4 @@ can only fix bugs if we know about them.


          SWIG 1.3 - Last Modified : March 9, 2003
          - + \ No newline at end of file diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index 957a800a4..25f227879 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -5,7 +5,7 @@ -

          21 SWIG and Python

          +

          22 SWIG and Python

          • Overview @@ -107,7 +107,7 @@ are covered in less depth than in earlier chapters. At the very least, make sure you read the "SWIG Basics" chapter. -

            21.1 Overview

            +

            22.1 Overview

            To build Python extension modules, SWIG uses a layered approach in which @@ -130,10 +130,10 @@ described. Advanced customization features such as typemaps are then described followed by a discussion of low-level implementation details. -

            21.2 Preliminaries

            +

            22.2 Preliminaries

            -

            21.2.1 Running SWIG

            +

            22.2.1 Running SWIG

            Suppose that you defined a SWIG module such as the following: @@ -174,7 +174,7 @@ To change this, you can use the -o option. The name of the Python fil from the module name specified with %module. If the module name is example, then a file example.py is created. -

            21.2.2 Getting the right header files

            +

            22.2.2 Getting the right header files

            In order to compile the C/C++ wrappers, the compiler needs the Python.h header file. @@ -201,7 +201,7 @@ Type "copyright", "credits" or "license" for more information. -

            21.2.3 Compiling a dynamic module

            +

            22.2.3 Compiling a dynamic module

            The preferred approach to building an extension module is to compile it into @@ -239,10 +239,10 @@ other Python extension modules. For example, the socket module actually consists of two files; socket.py and _socket.so. Many other built-in Python modules follow a similar convention. -

            21.2.4 Using distutils

            +

            22.2.4 Using distutils

            -

            21.2.5 Static linking

            +

            22.2.5 Static linking

            An alternative approach to dynamic linking is to rebuild the Python @@ -310,7 +310,7 @@ appears to "work" with Python 2.1, no future support is guaranteed. If using static linking, you might want to rely on a different approach (perhaps using distutils). -

            21.2.6 Using your module

            +

            22.2.6 Using your module

            To use your module, simply use the Python import statement. If @@ -445,7 +445,7 @@ Finally, you can use a command such as ldconfig (Linux) or system configuration (this requires root access and you will need to read the man pages). -

            21.2.7 Compilation of C++ extensions

            +

            22.2.7 Compilation of C++ extensions

            Compilation of C++ extensions has traditionally been a tricky problem. @@ -518,7 +518,7 @@ you will need to take steps to avoid segmentation faults and other erratic program behavior. If working with lots of software components, you might want to investigate using a more formal standard such as COM. -

            21.2.8 Compiling for 64-bit platforms

            +

            22.2.8 Compiling for 64-bit platforms

            On platforms that support 64-bit applications (Solaris, Irix, etc.), @@ -541,7 +541,7 @@ that software. This may prevent the use of 64-bit extensions. It may also introduce problems on platforms that support more than one linking standard (e.g., -o32 and -n32 on Irix). -

            21.2.9 Building Python Extensions under Windows

            +

            22.2.9 Building Python Extensions under Windows

            Building a SWIG extension to Python under Windows is roughly @@ -623,14 +623,14 @@ compilers tends to be rather problematic. For the latest information, you may want to consult the SWIG Wiki. -

            21.3 A tour of basic C/C++ wrapping

            +

            22.3 A tour of basic C/C++ wrapping

            By default, SWIG tries to build a very natural Python interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping. -

            21.3.1 Modules

            +

            22.3.1 Modules

            The SWIG %module directive specifies the name of the Python @@ -641,7 +641,7 @@ extension module _example.so. When choosing a module name, make sure you don't use the same name as a built-in Python command or standard module name. -

            21.3.2 Functions

            +

            22.3.2 Functions

            Global functions are wrapped as new Python built-in functions. For example, @@ -662,7 +662,7 @@ like you think it does:

            >>> -

            21.3.3 Global variables

            +

            22.3.3 Global variables

            C/C++ global variables are fully supported by SWIG. However, the underlying @@ -774,7 +774,7 @@ module loaded. To prevent this, you might consider renaming that starts with a leading underscore. SWIG does not create cvar if there are no global variables in a module.

            -

            21.3.4 Constants and enums

            +

            22.3.4 Constants and enums

            C/C++ constants are installed as Python objects containing the @@ -808,7 +808,7 @@ of the constant could be accidentally reassigned to refer to some other object. Unfortunately, there is no easy way for SWIG to generate code that prevents this. You will just have to be careful. -

            21.3.5 Pointers

            +

            22.3.5 Pointers

            C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with @@ -940,7 +940,7 @@ to use the new C++ style casts. For example, in the above code, the C-style cast may return a bogus result whereas as the C++-style cast will return None if the conversion can't be performed. -

            21.3.6 Structures

            +

            22.3.6 Structures

            If you wrap a C structure, it is wrapped by a Python class. This provides @@ -1103,7 +1103,7 @@ everything works just like you would expect. For example: -

            21.3.7 C++ classes

            +

            22.3.7 C++ classes

            C++ classes are wrapped by Python classes as well. For example, if you have this class, @@ -1182,7 +1182,7 @@ they are accessed through cvar like this: -

            21.3.8 C++ inheritance

            +

            22.3.8 C++ inheritance

            SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have @@ -1228,7 +1228,7 @@ then the function spam() accepts Foo * or a pointer to any cla

            It is safe to use multiple inheritance with SWIG. -

            21.3.9 Pointers, references, values, and arrays

            +

            22.3.9 Pointers, references, values, and arrays

            In C++, there are many different ways a function might receive @@ -1275,7 +1275,7 @@ Since the third function (spam7) returns a value, newly allocated memory is used to hold the result and a pointer is returned (Python will release this memory when the return value is garbage collected). -

            21.3.10 C++ overloaded functions

            +

            22.3.10 C++ overloaded functions

            C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, @@ -1376,7 +1376,7 @@ first declaration takes precedence.

            Please refer to the "SWIG and C++" chapter for more information about overloading. -

            21.3.11 C++ operators

            +

            22.3.11 C++ operators

            Certain C++ overloaded operators can be handled automatically by SWIG. For example, @@ -1449,7 +1449,7 @@ Keep reading. Also, be aware that certain operators don't map cleanly to Python. For instance, overloaded assignment operators don't map to Python semantics and will be ignored. -

            21.3.12 C++ namespaces

            +

            22.3.12 C++ namespaces

            SWIG is aware of C++ namespaces, but namespace names do not appear in @@ -1508,7 +1508,7 @@ extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. -

            21.3.13 C++ templates

            +

            22.3.13 C++ templates

            C++ templates don't present a huge problem for SWIG. However, in order @@ -1555,7 +1555,7 @@ Obviously, there is more to template wrapping than shown in this example. More details can be found in the SWIG and C++ chapter. Some more complicated examples will appear later. -

            21.3.14 C++ Smart Pointers

            +

            22.3.14 C++ Smart Pointers

            In certain C++ programs, it is common to use classes that have been wrapped by @@ -1627,7 +1627,7 @@ simply use the __deref__() method. For example: -

            21.4 Further details on the Python class interface

            +

            22.4 Further details on the Python class interface

            In the previous section, a high-level view of Python wrapping was @@ -1638,7 +1638,7 @@ advanced features such as operator overloading. However, a number of low-level details were omitted. This section provides a brief overview of how the proxy classes work. -

            21.4.1 Proxy classes

            +

            22.4.1 Proxy classes

            In the "SWIG basics" and "SWIG and C++" chapters, @@ -1715,7 +1715,7 @@ The fact that the class has been wrapped by a real Python class offers certain a you can attach new Python methods to the class and you can even inherit from it (something not supported by Python built-in types until Python 2.2). -

            21.4.2 Memory management

            +

            22.4.2 Memory management

            Associated with proxy object, is an ownership flag .thisown The value of this @@ -1877,7 +1877,7 @@ To work around this, it is always possible to flip the ownership flag. For examp It is also possible to deal with situations like this using typemaps--an advanced topic discussed later. -

            21.4.3 Python 2.2 and classic classes

            +

            22.4.3 Python 2.2 and classic classes

            SWIG makes every attempt to preserve backwards compatibility with @@ -1909,7 +1909,7 @@ of static member functions. In Python-2.2, they can be accessed via the class itself. In Python-2.1 and earlier, they have to be accessed as a global function or through an instance (see the earlier section). -

            21.5 Cross language polymorphism (experimental)

            +

            22.5 Cross language polymorphism (experimental)

            Proxy classes provide a more natural, object-oriented way to access @@ -1937,7 +1937,7 @@ to know where a particular method is implemented: the combination of proxy classes, director classes, and C wrapper functions takes care of all the cross-language method routing transparently. -

            21.5.1 Enabling directors

            +

            22.5.1 Enabling directors

            The director feature is disabled by default. To use directors you @@ -2002,7 +2002,7 @@ public: -

            21.5.2 Director classes

            +

            22.5.2 Director classes

            For each class that has directors enabled, SWIG generates a new class @@ -2075,7 +2075,7 @@ unmodified proxy classes, all methods are ultimately implemented in C++ so there is no need for the extra overhead involved with routing the calls through Python. -

            21.5.3 Ownership and object destruction

            +

            22.5.3 Ownership and object destruction

            Memory management issues are slightly more complicated with directors @@ -2135,7 +2135,7 @@ deleting all the Foo pointers it contains at some point. Note that no hard references to the Foo objects remain in Python.

            -

            21.5.4 Exception unrolling

            +

            22.5.4 Exception unrolling

            With directors routing method calls to Python, and proxies routing them @@ -2187,7 +2187,7 @@ exception. Because the Python error state is still set when Swig::DirectorMethodException is thrown, Python will register the exception as soon as the C wrapper function returns. -

            21.5.5 Overhead and code bloat

            +

            22.5.5 Overhead and code bloat

            Enabling directors for a class will generate a new director method for @@ -2217,7 +2217,7 @@ optimized by selectively enabling director methods (using the %feature directive) for only those methods that are likely to be extended in Python. -

            21.5.6 Typemaps

            +

            22.5.6 Typemaps

            Typemaps for input and output of most of the basic types from director @@ -2233,10 +2233,10 @@ for std::string, std::vector, and std::complex, although there's no guarantee these are fully functional yet.

            -

            21.5.7 Miscellaneous

            +

            22.5.7 Miscellaneous

            -

            21.6 Common customization features

            +

            22.6 Common customization features

            The last section presented the absolute basics of C/C++ wrapping. If you do nothing @@ -2246,7 +2246,7 @@ types of functionality might be missing or the interface to certain functions mi be awkward. This section describes some common SWIG features that are used to improve your the interface to an extension module. -

            21.6.1 C/C++ helper functions

            +

            22.6.1 C/C++ helper functions

            Sometimes when you create a module, it is missing certain bits of functionality. For @@ -2317,7 +2317,7 @@ Admittedly, this is not the most elegant looking approach. However, it works an hard to implement. It is possible to clean this up using Python code, typemaps, and other customization features as covered in later sections. -

            21.6.2 Adding additional Python code

            +

            22.6.2 Adding additional Python code

            If writing support code in C isn't enough, it is also possible to write code in @@ -2365,7 +2365,7 @@ soon enough. For now, think of this example as an illustration of what can be done without having to rely on any of the more advanced customization features. -

            21.6.3 Class extension with %extend

            +

            22.6.3 Class extension with %extend

            One of the more interesting features of SWIG is that it can extend @@ -2444,7 +2444,7 @@ Vector(12,14,16) %extend works with both C and C++ code. It does not modify the underlying object in any way---the extensions only show up in the Python interface. -

            21.6.4 Exception handling with %exception

            +

            22.6.4 Exception handling with %exception

            If a C or C++ function throws an error, you may want to convert that error into a Python @@ -2557,7 +2557,7 @@ PyExc_ZeroDivisionError The language-independent exception.i library file can also be used to raise exceptions. See the SWIG Library chapter. -

            21.7 Tips and techniques

            +

            22.7 Tips and techniques

            Although SWIG is largely automatic, there are certain types of wrapping problems that @@ -2565,7 +2565,7 @@ require additional user input. Examples include dealing with output parameter strings, binary data, and arrays. This chapter discusses the common techniques for solving these problems. -

            21.7.1 Input and output parameters

            +

            22.7.1 Input and output parameters

            A common problem in some C programs is handling parameters passed as simple pointers. For @@ -2745,7 +2745,7 @@ void foo(Bar *OUTPUT); may not have the intended effect since typemaps.i does not define an OUTPUT rule for Bar. -

            21.7.2 Simple pointers

            +

            22.7.2 Simple pointers

            If you must work with simple pointers such as int * or double * and you don't want to use @@ -2801,7 +2801,7 @@ If you replace %pointer_functions() by %pointer_class(type,name)SWIG Library chapter for further details. -

            21.7.3 Unbounded C Arrays

            +

            22.7.3 Unbounded C Arrays

            Sometimes a C function expects an array to be passed as a pointer. For example, @@ -2855,7 +2855,7 @@ On the other hand, this low-level approach is extremely efficient and well suited for applications in which you need to create buffers, package binary data, etc. -

            21.7.4 String handling

            +

            22.7.4 String handling

            If a C function has an argument of char *, then a Python string @@ -2909,16 +2909,16 @@ If you need to return binary data, you might use the cstring.i library file. The cdata.i library can also be used to extra binary data from arbitrary pointers. -

            21.7.5 Arrays

            +

            22.7.5 Arrays

            -

            21.7.6 String arrays

            +

            22.7.6 String arrays

            -

            21.7.7 STL wrappers

            +

            22.7.7 STL wrappers

            -

            21.8 Typemaps

            +

            22.8 Typemaps

            This section describes how you can modify SWIG's default wrapping behavior @@ -2932,7 +2932,7 @@ part of using SWIG---the default wrapping behavior is enough in most cases. Typemaps are only used if you want to change some aspect of the primitive C-Python interface or if you want to elevate your guru status. -

            21.8.1 What is a typemap?

            +

            22.8.1 What is a typemap?

            A typemap is nothing more than a code generation rule that is attached to @@ -3030,7 +3030,7 @@ parameter is omitted): -

            21.8.2 Python typemaps

            +

            22.8.2 Python typemaps

            The previous section illustrated an "in" typemap for converting Python objects to C. @@ -3062,7 +3062,7 @@ $ cat python.swg Additional typemap examples can also be found in the typemaps.i file. -

            21.8.3 Typemap variables

            +

            22.8.3 Typemap variables

            Within typemap code, a number of special variables prefaced with a $ may appear. @@ -3116,7 +3116,7 @@ properly assigned. The Python name of the wrapper function being created. -

            21.8.4 Useful Python Functions

            +

            22.8.4 Useful Python Functions

            When you write a typemap, you usually have to work directly with Python objects. @@ -3213,14 +3213,14 @@ write me -

            21.9 Typemap Examples

            +

            22.9 Typemap Examples

            This section includes a few examples of typemaps. For more examples, you might look at the files "python.swg" and "typemaps.i" in the SWIG library. -

            21.9.1 Converting Python list to a char **

            +

            22.9.1 Converting Python list to a char **

            A common problem in many C programs is the processing of command line @@ -3293,7 +3293,7 @@ memory allocation is used to allocate memory for the array, the "freearg" typemap is used to later release this memory after the execution of the C function. -

            21.9.2 Expanding a Python object into multiple arguments

            +

            22.9.2 Expanding a Python object into multiple arguments

            Suppose that you had a collection of C functions with arguments @@ -3363,7 +3363,7 @@ to supply the argument count. This is automatically set by the typemap code. F -

            21.9.3 Using typemaps to return arguments

            +

            22.9.3 Using typemaps to return arguments

            A common problem in some C programs is that values may be returned in @@ -3441,7 +3441,7 @@ function can now be used as follows: >>> -

            21.9.4 Mapping Python tuples into small arrays

            +

            22.9.4 Mapping Python tuples into small arrays

            In some applications, it is sometimes desirable to pass small arrays @@ -3482,7 +3482,7 @@ Since our mapping copies the contents of a Python tuple into a C array, such an approach would not be recommended for huge arrays, but for small structures, this approach works fine.

            -

            21.9.5 Mapping sequences to C arrays

            +

            22.9.5 Mapping sequences to C arrays

            Suppose that you wanted to generalize the previous example to handle C @@ -3561,7 +3561,7 @@ static int convert_darray(PyObject *input, double *ptr, int size) { -

            21.9.6 Pointer handling

            +

            22.9.6 Pointer handling

            Occasionally, it might be necessary to convert pointer values that have diff --git a/Doc/Manual/Ruby.html b/Doc/Manual/Ruby.html index 355189388..0e1731f0c 100644 --- a/Doc/Manual/Ruby.html +++ b/Doc/Manual/Ruby.html @@ -5,7 +5,7 @@ -

            22 SWIG and Ruby

            +

            23 SWIG and Ruby

            • Preliminaries @@ -86,7 +86,7 @@ This chapter describes SWIG's support of Ruby.
              -

              22.1 Preliminaries

              +

              23.1 Preliminaries

              SWIG 1.3 is known to work with Ruby versions 1.6 and later. Given the choice, you should @@ -100,7 +100,7 @@ href="SWIG.html">SWIG Basics" chapter. It is also assumed that the reader has a basic understanding of Ruby. -

              22.1.1 Running SWIG

              +

              23.1.1 Running SWIG

              @@ -120,7 +120,7 @@ compiling a C++ extension) that contains all of the code needed to build a Ruby extension module. To finish building the module, you need to compile this file and link it with the rest of your program. -

              22.1.2 Getting the right header files

              +

              23.1.2 Getting the right header files

              In order to compile the wrapper code, the compiler needs the ruby.h @@ -147,7 +147,7 @@ $ ruby -e 'puts $:.join("\n")' -

              22.1.3 Compiling a dynamic module

              +

              23.1.3 Compiling a dynamic module

              Ruby extension modules are typically compiled into shared libraries that the @@ -206,7 +206,7 @@ pages for your compiler and linker to determine the correct set of options. You might also check the SWIG Wiki for additional information.

              -

              22.1.4 Using your module

              +

              23.1.4 Using your module

              Ruby module names must be capitalized, but the convention for Ruby @@ -231,7 +231,7 @@ extension. So for example, a SWIG interface file that begins with: will result in an extension module using the feature name "example" and Ruby module name "Example". -

              22.1.5 Static linking

              +

              23.1.5 Static linking

              An alternative approach to dynamic linking is to rebuild the Ruby @@ -247,7 +247,7 @@ the Ruby source, adding an entry to the ext/Setup file, adding your directory to the list of extensions in the file, and finally rebuilding Ruby.

              -

              22.1.6 Compilation of C++ extensions

              +

              23.1.6 Compilation of C++ extensions

              @@ -279,7 +279,7 @@ create_makefile('example')


              -

              22.2 Building Ruby Extensions under Windows 95/NT

              +

              23.2 Building Ruby Extensions under Windows 95/NT

              Building a SWIG extension to Ruby under Windows 95/NT is roughly similar to the @@ -300,7 +300,7 @@ IDE, instead of using the command line tools). In order to build extensions, you may need to download the source distribution to the Ruby package, as you will need the Ruby header files.

              -

              22.2.1 Running SWIG from Developer Studio

              +

              23.2.1 Running SWIG from Developer Studio

              If you are developing your application within Microsoft developer studio, SWIG @@ -364,13 +364,13 @@ Foo = 3.0
              -

              22.3 The Ruby-to-C/C++ Mapping

              +

              23.3 The Ruby-to-C/C++ Mapping

              This section describes the basics of how SWIG maps C or C++ declarations in your SWIG interface files to Ruby constructs. -

              22.3.1 Modules

              +

              23.3.1 Modules

              The SWIG %module directive specifies the name of the Ruby module. If @@ -396,7 +396,7 @@ using the -globalmodule option to wrap everything into the global modul take care that the names of your constants, classes and methods don't conflict with any of Ruby's built-in names. -

              22.3.2 Functions

              +

              23.3.2 Functions

              Global functions are wrapped as Ruby module methods. For example, given @@ -429,7 +429,7 @@ irb(main):002:0> Example.fact(4) 24 -

              22.3.3 Variable Linking

              +

              23.3.3 Variable Linking

              C/C++ global variables are wrapped as a pair of singleton methods for the @@ -490,7 +490,7 @@ extern char *path; The %immutable directive stays in effect until it is explicitly disabled using %mutable. -

              22.3.4 Constants

              +

              23.3.4 Constants

              C/C++ constants are wrapped as module constants initialized to the @@ -519,7 +519,7 @@ irb(main):002:0> Example::PI 3.14159 -

              22.3.5 Pointers

              +

              23.3.5 Pointers

              "Opaque" pointers to arbitrary C/C++ types (i.e. types that aren't explicitly @@ -540,7 +540,7 @@ irb(main):001:0> foo = Example::get_foo() A NULL pointer is always represented by the Ruby nil object. -

              22.3.6 Structures

              +

              23.3.6 Structures

              C/C++ structs are wrapped as Ruby classes, with accessor methods (i.e. "getters" @@ -655,7 +655,7 @@ void Bar_f_set(Bar *b, Foo *val) { -

              22.3.7 C++ classes

              +

              23.3.7 C++ classes

              Like structs, C++ classes are wrapped by creating a new Ruby class of the same @@ -707,7 +707,7 @@ Ale 3 -

              22.3.8 C++ Inheritance

              +

              23.3.8 C++ Inheritance

              The SWIG type-checker is fully aware of C++ inheritance. Therefore, if you have @@ -856,7 +856,7 @@ In most cases, this is not a serious problem since objects of type DerivedBase1 and Base2 (i.e. they exhibit "Duck Typing"). -

              22.3.9 C++ Overloaded Functions

              +

              23.3.9 C++ Overloaded Functions

              C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, @@ -957,7 +957,7 @@ first declaration takes precedence.

              Please refer to the "SWIG and C++" chapter for more information about overloading. -

              22.3.10 C++ Operators

              +

              23.3.10 C++ Operators

              For the most part, overloaded operators are handled automatically by SWIG @@ -1002,7 +1002,7 @@ c = Example.add_complex(a, b) More details about wrapping C++ operators into Ruby operators is discussed in the section on operator overloading. -

              22.3.11 C++ namespaces

              +

              23.3.11 C++ namespaces

              SWIG is aware of C++ namespaces, but namespace names do not appear in @@ -1063,7 +1063,7 @@ extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. -

              22.3.12 C++ templates

              +

              23.3.12 C++ templates

              C++ templates don't present a huge problem for SWIG. However, in order @@ -1140,7 +1140,7 @@ float sum(const std::vector<float>& values); Obviously, there is a lot more to template wrapping than shown in these examples. More details can be found in the SWIG and C++ chapter. -

              22.3.13 C++ Smart Pointers

              +

              23.3.13 C++ Smart Pointers

              In certain C++ programs, it is common to use classes that have been wrapped by @@ -1215,7 +1215,7 @@ irb(main):004:0> f = p.__deref__() # Returns underlying Foo * -

              22.3.14 Cross-Language Polymorphism

              +

              23.3.14 Cross-Language Polymorphism

              SWIG's Ruby module supports cross-language polymorphism (a.k.a. the "directors" @@ -1224,7 +1224,7 @@ information presented in the Python chapter, this secton just notes the differences that you need to be aware of when using this feature with Ruby. -

              22.3.14.1 Exception Unrolling

              +

              23.3.14.1 Exception Unrolling

              Whenever a C++ director class routes one of its virtual member function calls to a @@ -1245,7 +1245,7 @@ using the rb_rescue2() function from Ruby's C API. If any Ruby exceptio is raised, it will be caught here and a C++ exception is raised in its place.
              -

              22.4 Input and output parameters

              +

              23.4 Input and output parameters

              A common problem in some C programs is handling parameters passed as simple @@ -1403,7 +1403,7 @@ r, c = Example.get_dimensions(m)
              -

              22.5 Simple exception handling

              +

              23.5 Simple exception handling

              The SWIG %exception directive can be used to define a user-definable @@ -1521,7 +1521,7 @@ shown above) or one of the built-in Ruby exception types. For a list of the stan Ruby exception classes, consult a Ruby reference such as Programming Ruby.
              -

              22.6 Typemaps

              +

              23.6 Typemaps

              This section describes how you can modify SWIG's default wrapping behavior @@ -1535,7 +1535,7 @@ part of using SWIG---the default wrapping behavior is enough in most cases. Typemaps are only used if you want to change some aspect of the primitive C-Ruby interface. -

              22.6.1 What is a typemap?

              +

              23.6.1 What is a typemap?

              A typemap is nothing more than a code generation rule that is attached to @@ -1643,7 +1643,7 @@ puts Example.count('o','Hello World') -

              22.6.2 Ruby typemaps

              +

              23.6.2 Ruby typemaps

              The previous section illustrated an "in" typemap for converting Ruby objects to @@ -1725,7 +1725,7 @@ Initialize an argument to a value before any conversions occur. Examples of these typemaps appears in the section on typemap examples -

              22.6.3 Typemap variables

              +

              23.6.3 Typemap variables

              Within a typemap, a number of special variables prefaced with a $ @@ -1781,7 +1781,7 @@ so that their values can be properly assigned. The Ruby name of the wrapper function being created. -

              22.6.4 Useful Functions

              +

              23.6.4 Useful Functions

              When you write a typemap, you usually have to work directly with Ruby objects. @@ -1790,7 +1790,7 @@ more can be found in Programming R and Andrew Hunt.)

              -

              22.6.4.1 C Datatypes to Ruby Objects

              +

              23.6.4.1 C Datatypes to Ruby Objects

              @@ -1803,7 +1803,7 @@ rb_float_new(double) - double to Float
              -

              22.6.4.2 Ruby Objects to C Datatypes

              +

              23.6.4.2 Ruby Objects to C Datatypes

              @@ -1823,7 +1823,7 @@ unsigned long FIX2ULONG(Numeric)
              -

              22.6.4.3 Macros for VALUE

              +

              23.6.4.3 Macros for VALUE

              @@ -1842,7 +1842,7 @@ unsigned long FIX2ULONG(Numeric) RARRAY(arr)->ptr

              pointer to array storage
              -

              22.6.4.4 Exceptions

              +

              23.6.4.4 Exceptions

              @@ -1917,7 +1917,7 @@ unsigned long FIX2ULONG(Numeric) -

              22.6.4.5 Iterators

              +

              23.6.4.5 Iterators

              @@ -1964,13 +1964,13 @@ unsigned long FIX2ULONG(Numeric) -

              22.6.5 Typemap Examples

              +

              23.6.5 Typemap Examples

              This section includes a few examples of typemaps. For more examples, you might look at the examples in the Example/ruby directory. -

              22.6.6 Converting a Ruby array to a char **

              +

              23.6.6 Converting a Ruby array to a char **

              A common problem in many C programs is the processing of command line @@ -2034,7 +2034,7 @@ receive an input argument and convert it to a C array. Since dynamic memory allocation is used to allocate memory for the array, the "freearg" typemap is used to later release this memory after the execution of the C function. -

              22.6.7 Collecting arguments in a hash

              +

              23.6.7 Collecting arguments in a hash

              Ruby's solution to the "keyword arguments" capability of some other languages is @@ -2242,7 +2242,7 @@ All of the code for this example, as well as a sample Ruby program that uses the extension, can be found in the Examples/ruby/hashargs directory of the SWIG distribution. -

              22.6.8 Pointer handling

              +

              23.6.8 Pointer handling

              Occasionally, it might be necessary to convert pointer values that have been @@ -2301,7 +2301,7 @@ typemap variable $1_descriptor. For example: -

              22.6.8.1 Ruby Datatype Wrapping

              +

              23.6.8.1 Ruby Datatype Wrapping

              @@ -2322,7 +2322,7 @@ Retrieves the original C pointer of type c-type from the data object


              -

              22.7 Operator overloading

              +

              23.7 Operator overloading

              SWIG allows operator overloading with, by using the %extend or @@ -2380,7 +2380,7 @@ __ge__ - >= Note that although SWIG supports the __eq__ magic method name for defining an equivalence operator, there is no separate method for handling inequality since Ruby parses the expression a != b as !(a == b). -

              22.7.1 Example: STL Vector to Ruby Array

              +

              23.7.1 Example: STL Vector to Ruby Array

              FIXME: This example is out of place here!

              @@ -2469,10 +2469,10 @@ It is also possible to create a Ruby array from a vector of static data types: -

              22.8 Advanced Topics

              +

              23.8 Advanced Topics

              -

              22.8.1 Creating Multi-Module Packages

              +

              23.8.1 Creating Multi-Module Packages

              The chapter on Advanced Topics discusses the basics @@ -2597,7 +2597,7 @@ irb(main):005:0> c.getX() -

              22.8.2 Defining Aliases

              +

              23.8.2 Defining Aliases

              It's a fairly common practice in the Ruby built-ins and standard library to @@ -2665,7 +2665,7 @@ mechanism and so the same name matching rules used for other kinds of features apply (see the chapter on "Customization Features") for more details). -

              22.8.3 Predicate Methods

              +

              23.8.3 Predicate Methods

              Predicate methods in Ruby are those which return either true or @@ -2716,7 +2716,7 @@ Note that the %predicate directive is implemented using SWIG's of features apply (see the chapter on "Customization Features") for more details). -

              22.8.4 Specifying Mixin Modules

              +

              23.8.4 Specifying Mixin Modules

              The Ruby language doesn't support multiple inheritance, but it does allow you @@ -2788,7 +2788,7 @@ Note that the %mixin directive is implemented using SWIG's of features apply (see the chapter on "Customization Features") for more details). -

              22.8.5 Interacting with Ruby's Garbage Collector

              +

              23.8.5 Interacting with Ruby's Garbage Collector

              This section is still unfinished!

              diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html index 88752813f..cc9e7f0a4 100644 --- a/Doc/Manual/SWIG.html +++ b/Doc/Manual/SWIG.html @@ -2657,4 +2657,4 @@ The bottom line: don't do this.

              SWIG 1.3 - Last Modified : August 7, 2003
              - + \ No newline at end of file diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index 56bdf45cd..f38fae303 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -3723,4 +3723,4 @@ is the reference document we use to guide a lot of SWIG's C++ support.
              SWIG 1.3 - Last Modified : April 3, 2003
              - + \ No newline at end of file diff --git a/Doc/Manual/Tcl.html b/Doc/Manual/Tcl.html index 00a8a140a..538091cec 100644 --- a/Doc/Manual/Tcl.html +++ b/Doc/Manual/Tcl.html @@ -5,7 +5,7 @@ -

              23 SWIG and Tcl

              +

              24 SWIG and Tcl

              • Preliminaries @@ -76,7 +76,7 @@ This chapter discusses SWIG's support of Tcl. SWIG currently requires Tcl 8.0 or a later release. Earlier releases of SWIG supported Tcl 7.x, but this is no longer supported. -

                23.1 Preliminaries

                +

                24.1 Preliminaries

                To build a Tcl module, run SWIG using the -tcl option :

                @@ -97,7 +97,7 @@ This creates a file example_wrap.c or build a Tcl extension module. To finish building the module, you need to compile this file and link it with the rest of your program. -

                23.1.1 Getting the right header files

                +

                24.1.1 Getting the right header files

                In order to compile the wrapper code, the compiler needs the tcl.h header file. @@ -111,7 +111,7 @@ Be aware that some Tcl versions install this header file with a version number a this is the case, you should probably make a symbolic link so that tcl.h points to the correct header file. -

                23.1.2 Compiling a dynamic module

                +

                24.1.2 Compiling a dynamic module

                The preferred approach to building an extension module is to compile it into @@ -140,7 +140,7 @@ name of the corresponding object file should be The name of the module is specified using the %module directive or the -module command line option.

                -

                23.1.3 Static linking

                +

                24.1.3 Static linking

                An alternative approach to dynamic linking is to rebuild the Tcl @@ -196,7 +196,7 @@ However, the performance gained by static linking tends to be rather minimal in most situations (and quite frankly not worth the extra hassle in the opinion of this author). -

                23.1.4 Using your module

                +

                24.1.4 Using your module

                To use your module, simply use the Tcl load command. If @@ -305,7 +305,7 @@ Finally, you can use a command such as ldconfig to add additional searc to the default system configuration (this requires root access and you will need to read the man pages). -

                23.1.5 Compilation of C++ extensions

                +

                24.1.5 Compilation of C++ extensions

                Compilation of C++ extensions has traditionally been a tricky problem. @@ -378,7 +378,7 @@ you will need to take steps to avoid segmentation faults and other erratic program behavior. If working with lots of software components, you might want to investigate using a more formal standard such as COM. -

                23.1.6 Compiling for 64-bit platforms

                +

                24.1.6 Compiling for 64-bit platforms

                On platforms that support 64-bit applications (Solaris, Irix, etc.), @@ -401,7 +401,7 @@ that software. This may prevent the use of 64-bit extensions. It may also introduce problems on platforms that support more than one linking standard (e.g., -o32 and -n32 on Irix). -

                23.1.7 Setting a package prefix

                +

                24.1.7 Setting a package prefix

                To avoid namespace problems, you can instruct SWIG to append a package @@ -415,7 +415,7 @@ If you have a function "bar" in the SWIG file, the prefix option will append the prefix to the name when creating a command and call it "Foo_bar".

                -

                23.1.8 Using namespaces

                +

                24.1.8 Using namespaces

                Alternatively, you can have SWIG install your module into a Tcl @@ -430,7 +430,7 @@ name, but you can override it using the -prefix option.

                When the -namespace option is used, objects in the module are always accessed with the namespace name such as Foo::bar. -

                23.2 Building Tcl/Tk Extensions under Windows 95/NT

                +

                24.2 Building Tcl/Tk Extensions under Windows 95/NT

                Building a SWIG extension to Tcl/Tk under Windows 95/NT is roughly @@ -439,7 +439,7 @@ produce a DLL that can be loaded into tclsh or wish. This section covers the process of using SWIG with Microsoft Visual C++. although the procedure may be similar with other compilers.

                -

                23.2.1 Running SWIG from Developer Studio

                +

                24.2.1 Running SWIG from Developer Studio

                If you are developing your application within Microsoft developer @@ -496,7 +496,7 @@ MSDOS > tclsh80 % -

                23.2.2 Using NMAKE

                +

                24.2.2 Using NMAKE

                Alternatively, SWIG extensions can be built by writing a Makefile for @@ -553,7 +553,7 @@ first). This is a pretty minimal Makefile, but hopefully its enough to get you started. With a little practice, you'll be making lots of Tcl extensions.

                -

                23.3 A tour of basic C/C++ wrapping

                +

                24.3 A tour of basic C/C++ wrapping

                By default, SWIG tries to build a very natural Tcl interface to your @@ -562,7 +562,7 @@ in an interface that mimics the style of Tk widgets and [incr Tcl] classes. This section briefly covers the essential aspects of this wrapping. -

                23.3.1 Modules

                +

                24.3.1 Modules

                The SWIG %module directive specifies the name of the Tcl @@ -591,7 +591,7 @@ To fix this, supply an extra argument to load like this: -

                23.3.2 Functions

                +

                24.3.2 Functions

                Global functions are wrapped as new Tcl built-in commands. For example, @@ -614,7 +614,7 @@ like you think it does:

                % -

                23.3.3 Global variables

                +

                24.3.3 Global variables

                C/C++ global variables are wrapped by Tcl global variables. For example: @@ -675,7 +675,7 @@ extern char *path; // Read-only (due to %immutable) -

                23.3.4 Constants and enums

                +

                24.3.4 Constants and enums

                C/C++ constants are installed as global Tcl variables containing the @@ -746,7 +746,7 @@ proc blah {} { When an identifier name is given, it is used to perform an implicit hash-table lookup of the value during argument conversion. This allows the global statement to be ommitted. -

                23.3.5 Pointers

                +

                24.3.5 Pointers

                C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with @@ -831,7 +831,7 @@ to use the new C++ style casts. For example, in the above code, the C-style cast may return a bogus result whereas as the C++-style cast will return None if the conversion can't be performed. -

                23.3.6 Structures

                +

                24.3.6 Structures

                If you wrap a C structure, it is wrapped by a Tcl interface that somewhat resembles a Tk widget. @@ -1071,7 +1071,7 @@ or Note: Tcl only destroys the underlying object if it has ownership. See the memory management section that appears shortly. -

                23.3.7 C++ classes

                +

                24.3.7 C++ classes

                C++ classes are wrapped as an extension of structure wrapping. For example, if you have this class, @@ -1129,7 +1129,7 @@ In Tcl, the static member is accessed as follows: -

                23.3.8 C++ inheritance

                +

                24.3.8 C++ inheritance

                SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have @@ -1171,7 +1171,7 @@ For instance:

                It is safe to use multiple inheritance with SWIG. -

                23.3.9 Pointers, references, values, and arrays

                +

                24.3.9 Pointers, references, values, and arrays

                In C++, there are many different ways a function might receive @@ -1217,7 +1217,7 @@ Since the third function (spam7) returns a value, newly allocated memory is used to hold the result and a pointer is returned (Tcl will release this memory when the return value is garbage collected). -

                23.3.10 C++ overloaded functions

                +

                24.3.10 C++ overloaded functions

                C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, @@ -1318,7 +1318,7 @@ first declaration takes precedence.

                Please refer to the "SWIG and C++" chapter for more information about overloading. -

                23.3.11 C++ operators

                +

                24.3.11 C++ operators

                Certain C++ overloaded operators can be handled automatically by SWIG. For example, @@ -1408,7 +1408,7 @@ Complex operator+(double, const Complex &c); There are ways to make this operator appear as part of the class using the %extend directive. Keep reading. -

                23.3.12 C++ namespaces

                +

                24.3.12 C++ namespaces

                SWIG is aware of C++ namespaces, but namespace names do not appear in @@ -1464,7 +1464,7 @@ extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. -

                23.3.13 C++ templates

                +

                24.3.13 C++ templates

                C++ templates don't present a huge problem for SWIG. However, in order @@ -1510,7 +1510,7 @@ Obviously, there is more to template wrapping than shown in this example. More details can be found in the SWIG and C++ chapter. Some more complicated examples will appear later. -

                23.3.14 C++ Smart Pointers

                +

                24.3.14 C++ Smart Pointers

                In certain C++ programs, it is common to use classes that have been wrapped by @@ -1582,7 +1582,7 @@ simply use the __deref__() method. For example: -

                23.4 Further details on the Tcl class interface

                +

                24.4 Further details on the Tcl class interface

                In the previous section, a high-level view of Tcl wrapping was @@ -1593,7 +1593,7 @@ advanced features such as operator overloading. However, a number of low-level details were omitted. This section provides a brief overview of how the proxy classes work. -

                23.4.1 Proxy classes

                +

                24.4.1 Proxy classes

                In the "SWIG basics" and "SWIG and C++" chapters, @@ -1650,7 +1650,7 @@ However, in addition to this, the classname Foo is used as an object co function. This allows objects to be encapsulated objects that look a lot like Tk widgets as shown in the last section. -

                23.4.2 Memory management

                +

                24.4.2 Memory management

                Associated with each wrapped object, is an ownership flag thisown The value of this @@ -1814,7 +1814,7 @@ It is also possible to deal with situations like this using typemaps--an advanced topic discussed later. -

                23.5 Input and output parameters

                +

                24.5 Input and output parameters

                A common problem in some C programs is handling parameters passed as simple pointers. For @@ -1975,7 +1975,7 @@ set c [lindex $dim 1] -

                23.6 Exception handling

                +

                24.6 Exception handling

                The %exception directive can be used to create a user-definable @@ -2101,7 +2101,7 @@ For example: Since SWIG's exception handling is user-definable, you are not limited to C++ exception handling. See the chapter on "Customization Features" for more examples. -

                23.7 Typemaps

                +

                24.7 Typemaps

                This section describes how you can modify SWIG's default wrapping behavior @@ -2115,7 +2115,7 @@ part of using SWIG---the default wrapping behavior is enough in most cases. Typemaps are only used if you want to change some aspect of the primitive C-Tcl interface. -

                23.7.1 What is a typemap?

                +

                24.7.1 What is a typemap?

                A typemap is nothing more than a code generation rule that is attached to @@ -2212,7 +2212,7 @@ parameter is ommitted): -

                23.7.2 Tcl typemaps

                +

                24.7.2 Tcl typemaps

                The previous section illustrated an "in" typemap for converting Tcl objects to C. @@ -2302,7 +2302,7 @@ Initialize an argument to a value before any conversions occur. Examples of these methods will appear shortly. -

                23.7.3 Typemap variables

                +

                24.7.3 Typemap variables

                Within typemap code, a number of special variables prefaced with a $ may appear. @@ -2356,7 +2356,7 @@ properly assigned. The Tcl name of the wrapper function being created. -

                23.7.4 Converting a Tcl list to a char **

                +

                24.7.4 Converting a Tcl list to a char **

                A common problem in many C programs is the processing of command line @@ -2413,7 +2413,7 @@ argv[2] = Larry 3 -

                23.7.5 Returning values in arguments

                +

                24.7.5 Returning values in arguments

                The "argout" typemap can be used to return a value originating from a @@ -2451,7 +2451,7 @@ result, a Tcl function using these typemaps will work like this :

                % -

                23.7.6 Useful functions

                +

                24.7.6 Useful functions

                The following tables provide some functions that may be useful in @@ -2514,7 +2514,7 @@ int Tcl_IsShared(Tcl_Obj *obj); -

                23.7.7 Standard typemaps

                +

                24.7.7 Standard typemaps

                The following typemaps show how to convert a few common kinds of @@ -2587,7 +2587,7 @@ work)

                -

                23.7.8 Pointer handling

                +

                24.7.8 Pointer handling

                SWIG pointers are mapped into Tcl strings containing the @@ -2656,7 +2656,7 @@ For example: -

                23.8 Turning a SWIG module into a Tcl Package.

                +

                24.8 Turning a SWIG module into a Tcl Package.

                Tcl 7.4 introduced the idea of an extension package. By default, SWIG @@ -2717,7 +2717,7 @@ As a final note, most SWIG examples do not yet use the package commands. For simple extensions it may be easier just to use the load command instead.

                -

                23.9 Building new kinds of Tcl interfaces (in Tcl)

                +

                24.9 Building new kinds of Tcl interfaces (in Tcl)

                One of the most interesting aspects of Tcl and SWIG is that you can @@ -2809,7 +2809,7 @@ the Tcl code would simply return with an error so there is very little danger of blowing something up (although it is easily accomplished with an out of bounds array access).

                -

                23.9.1 Shadow classes

                +

                24.9.1 Shadow classes

                A similar approach can be applied to shadow classes. The following diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index ae12f86c9..445131592 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -438,4 +438,4 @@ The ability to control warning messages was first added to SWIG-1.3.12.


                SWIG 1.3 - Last Modified : June 28, 2003
                - + \ No newline at end of file diff --git a/Doc/Manual/Windows.html b/Doc/Manual/Windows.html index 506c271e8..ad2e98526 100644 --- a/Doc/Manual/Windows.html +++ b/Doc/Manual/Windows.html @@ -22,19 +22,19 @@
              • Perl
              • Java
              • Ruby -
              • C# +
              • C#
              -
            • Instructions for using the Examples with other compilers +
            • Instructions for using the Examples with other compilers
            -
          • SWIG on Cygwin and MinGW +
          • SWIG on Cygwin and MinGW
          @@ -169,23 +169,25 @@ RUBY_INCLUDE: D:\ruby\lib\ruby\1.6\i586-mswin32
          RUBY_LIB: D:\ruby\lib\mswin32-ruby16.lib
          -

          2.2.1.6 C#

          +

          2.2.1.6 C#

          + + The C# examples do not require any environment variables to be set as a C# project file is included. Just open up the .sln solution file in Visual Studio .NET 2003 and do a Rebuild All from the Build menu. The accompanying C# and C++ project file are automatically used by the solution file. -

          2.2.2 Instructions for using the Examples with other compilers

          +

          2.2.2 Instructions for using the Examples with other compilers

          If you do not have access to Visual C++ you will have to set up project files / Makefiles for your chosen compiler. There is a section in each of the language modules detailing what needs setting up using Visual C++ which may be of some guidance. Alternatively you may want to use Cygwin as described in the following section. -

          2.3 SWIG on Cygwin and MinGW

          +

          2.3 SWIG on Cygwin and MinGW

          SWIG can also be compiled and run using Cygwin or MinGW which provides a Unix like front end to Windows and comes free with gcc, an ANSI C/C++ compiler. However, this is not a recommended approach as the prebuilt executable is supplied. -

          2.3.1 Building swig.exe on Windows

          +

          2.3.1 Building swig.exe on Windows

          If you want to replicate the build of swig.exe that comes with the download, follow the MinGW instructions below. @@ -193,7 +195,7 @@ This is not necessary to use the supplied swig.exe. This information is provided for those that want to modify the SWIG source code in a Windows environment. Normally this is not needed, so most people will want to ignore this section. -

          2.3.1.1 Building swig.exe using MinGW and MSYS

          +

          2.3.1.1 Building swig.exe using MinGW and MSYS

            @@ -202,7 +204,7 @@ Normally this is not needed, so most people will want to ignore this section.
          -

          2.3.1.2 Building swig.exe using Cygwin

          +

          2.3.1.2 Building swig.exe using Cygwin

          Note that SWIG can also be built using Cygwin. @@ -213,7 +215,7 @@ Note that the Cygwin environment will also allow one to regenerate the autotool These files are generated using the autogen.sh script and will only need regenerating in circumstances such as changing the build system.

          -

          2.3.1.3 Building swig.exe alternatives

          +

          2.3.1.3 Building swig.exe alternatives

          If you don't want to install Cygwin or MinGW, use a different compiler to build @@ -222,7 +224,7 @@ file in order to build swig.exe from the Visual C++ IDE. -

          2.3.2 Running the examples on Windows using Cygwin

          +

          2.3.2 Running the examples on Windows using Cygwin

          The examples and test-suite work as successfully on Cygwin as on any other Unix operating system. @@ -232,4 +234,4 @@ Follow the Unix instructions in the README file in the SWIG root directory to bu

          - + \ No newline at end of file diff --git a/Doc/Manual/chapters b/Doc/Manual/chapters index 01fa3dfa8..ecdd86c39 100644 --- a/Doc/Manual/chapters +++ b/Doc/Manual/chapters @@ -16,6 +16,7 @@ Modules.html Advanced.html Guile.html Java.html +Modula3.html Ocaml.html Perl5.html Php.html diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 0a2346d57..e484b5659 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -494,6 +494,31 @@ java_multi_cpp: $(SRCS) java_clean: rm -f *.@OBJEXT@ *@JAVASO@ *_wrap* *~ .~* core @EXTRA_CLEAN@ *.class `find . -name \*.java | grep -v main.java` +################################################################## +##### MODULA3 ###### +################################################################## + +MODULA3_INCLUDE= @MODULA3INC@ + +# ---------------------------------------------------------------- +# Build a modula3 dynamically loadable module (C) +# ---------------------------------------------------------------- + +modula3: $(SRCS) + $(SWIG) -modula3 $(SWIGOPT) $(INTERFACE) +# $(CC) -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) \ +# $(OBJS) $(IOBJS) $(LIBS) + +modula3_cpp: $(SRCS) + $(SWIG) -modula3 -c++ $(SWIGOPT) $(INTERFACE) + +# ----------------------------------------------------------------- +# Cleaning the modula3 examples +# ----------------------------------------------------------------- + +modula3_clean: + rm -f *_wrap* *.i3 *.m3 + ################################################################## ##### MZSCHEME ###### ################################################################## diff --git a/Examples/modula3/check.list b/Examples/modula3/check.list new file mode 100644 index 000000000..37ac8c105 --- /dev/null +++ b/Examples/modula3/check.list @@ -0,0 +1,7 @@ +# see top-level Makefile.in +class +enum +exception +reference +simple +typemap diff --git a/Examples/modula3/class/.cvsignore b/Examples/modula3/class/.cvsignore new file mode 100644 index 000000000..b00748b1c --- /dev/null +++ b/Examples/modula3/class/.cvsignore @@ -0,0 +1,17 @@ +runme +*_wrap.c +*_wrap.cxx +*_wrap.xml +*.iltmp +*.cs +*.dll +*.dsw +*.exp +*.lib +*.ncb +*.opt +*.plg +Release +Debug +src +LINUXLIBC6 diff --git a/Examples/modula3/class/Makefile b/Examples/modula3/class/Makefile new file mode 100644 index 000000000..bb9cb26d8 --- /dev/null +++ b/Examples/modula3/class/Makefile @@ -0,0 +1,25 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +PLATFORM = LINUXLIBC6 +INTERFACE = example.i +SWIGOPT = -c++ +MODULA3SRCS = *.[im]3 + +all:: modula3 + +modula3:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3 + m3ppinplace $(MODULA3SRCS) +# compilation of example_wrap.cxx is started by cm3 +# $(CXX) -c $(TARGET)_wrap.cxx + mv example_wrap.cxx m3makefile $(MODULA3SRCS) src/ + ln -sf ../example.h src/example.h + cm3 + +clean:: + $(MAKE) -f $(TOP)/Makefile modula3_clean + +check: all diff --git a/Examples/modula3/class/example.cxx b/Examples/modula3/class/example.cxx new file mode 100644 index 000000000..1e8e203dd --- /dev/null +++ b/Examples/modula3/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/modula3/class/example.h b/Examples/modula3/class/example.h new file mode 100644 index 000000000..9c1f47995 --- /dev/null +++ b/Examples/modula3/class/example.h @@ -0,0 +1,44 @@ +/* File : example.h */ + +class Shape +{ +public: + Shape () + { + nshapes++; + } + virtual ~ Shape () + { + nshapes--; + }; + double x, y; + void move (double dx, double dy); + virtual double area (void) const = 0; + virtual double perimeter (void) const = 0; +protected: + static int nshapes; +}; + +class Circle:public Shape +{ +private: + double radius; +public: + Circle (double r):radius (r) + { + }; + virtual double area (void) const; + virtual double perimeter (void) const; +}; + +class Square:public Shape +{ +private: + double width; +public: + Square (double w):width (w) + { + }; + virtual double area (void) const; + virtual double perimeter (void) const; +}; diff --git a/Examples/modula3/class/example.i b/Examples/modula3/class/example.i new file mode 100644 index 000000000..2fafadbd6 --- /dev/null +++ b/Examples/modula3/class/example.i @@ -0,0 +1,32 @@ +/* File : example.i */ +%module Example + +%{ +#include "example.h" +%} + +%insert(m3makefile) %{template("../swig") +cxx_source("example_wrap")%} + +%typemap(m3rawinmode) Shape *, Circle *, Square * "" +%typemap(m3rawrettype) Shape *, Circle *, Square * "$1_basetype" + +%typemap(m3wrapinmode) Shape *, Circle *, Square * "" +%typemap(m3wrapargraw) Shape *, Circle *, Square * "self.cxxObj" + +%typemap(m3wrapretvar) Circle *, Square * "cxxObj : ExampleRaw.$1_basetype;" +%typemap(m3wrapretraw) Circle *, Square * "cxxObj" +%typemap(m3wrapretconv) Circle *, Square * "NEW($1_basetype,cxxObj:=cxxObj)" +%typemap(m3wraprettype) Circle *, Square * "$1_basetype" + +/* Should work with and without renaming +%rename(M3Shape) Shape; +%rename(M3Circle) Circle; +%rename(M3Square) Square; +%typemap(m3wrapintype) Shape *, Circle *, Square * "M3$1_basetype" +%typemap(m3wraprettype) Shape *, Circle *, Square * "M3$1_basetype" +%typemap(m3wrapretconv) Circle *, Square * "NEW(M3$1_basetype,cxxObj:=cxxObj)" +*/ + +/* Let's just grab the original header file here */ +%include "example.h" diff --git a/Examples/modula3/class/swig.tmpl b/Examples/modula3/class/swig.tmpl new file mode 100644 index 000000000..e3e9bf178 --- /dev/null +++ b/Examples/modula3/class/swig.tmpl @@ -0,0 +1,11 @@ + +readonly proc cxx_source (X) is + local cxxfile = X&".cxx" + local objfile = X&".o" + %exec("echo $PWD") + if stale(objfile,cxxfile) + exec("cd",path(),"; g++ -I.. -c -o",objfile,cxxfile) + end + import_obj(X) + %unlink_file(path()&SL&objfile) +end diff --git a/Examples/modula3/enum/.cvsignore b/Examples/modula3/enum/.cvsignore new file mode 100644 index 000000000..1d6709196 --- /dev/null +++ b/Examples/modula3/enum/.cvsignore @@ -0,0 +1,18 @@ +*.class +*.java +*_wrap.* +*_const* +*.i3 +*.m3 +m3makefile +src +LINUXLIBC6 +*.dll +*.dsw +*.exp +*.lib +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/modula3/enum/Makefile b/Examples/modula3/enum/Makefile new file mode 100644 index 000000000..78b4ad516 --- /dev/null +++ b/Examples/modula3/enum/Makefile @@ -0,0 +1,26 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i +CONSTNUMERIC = example_const +SWIGOPT = -c++ +MODULA3SRCS = *.[im]3 + +all:: modula3 + +modula3:: + $(SWIG) -modula3 $(SWIGOPT) -module Example -generateconst $(CONSTNUMERIC) $(TARGET).h + $(CXX) -Wall $(CONSTNUMERIC).c -o $(CONSTNUMERIC) + $(CONSTNUMERIC) >$(CONSTNUMERIC).i + + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3 + m3ppinplace $(MODULA3SRCS) + mv m3makefile $(MODULA3SRCS) src/ + cm3 + +clean:: + $(MAKE) -f $(TOP)/Makefile modula3_clean + +check: all diff --git a/Examples/modula3/enum/example.cxx b/Examples/modula3/enum/example.cxx new file mode 100644 index 000000000..bd808ff7c --- /dev/null +++ b/Examples/modula3/enum/example.cxx @@ -0,0 +1,32 @@ +/* File : example.cxx */ + +#include "example.h" +#include + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else if (s == HYPER) { + printf("HYPER speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + Foo obj; + obj.enum_test(s); +} diff --git a/Examples/modula3/enum/example.h b/Examples/modula3/enum/example.h new file mode 100644 index 000000000..2f44a6ccf --- /dev/null +++ b/Examples/modula3/enum/example.h @@ -0,0 +1,83 @@ +/* File : example.h */ + +#define PI 3.141 + +#define DAY_MONDAY 0 +#define DAY_TUESDAY 1 +#define DAY_WEDNESDAY 2 +#define DAY_THURSDAY 3 +#define DAY_FRIDAY 4 +#define DAY_SATURDAY 5 +#define DAY_SUNDAY 6 + +enum color { BLUE, RED, GREEN }; + +#define CLB_BLACK 0 +#define CLB_BLUE 1 +#define CLB_RED 2 +#define CLB_MAGENTA 3 +#define CLB_GREEN 4 +#define CLB_CYAN 5 +#define CLB_YELLOW 6 +#define CLB_WHITE 7 + +/* Using this would be good style + which cannot be expected for general C header files. + Instead I want to demonstrate how to live without it. +enum month { + MTHF_JANUARY, + MTHF_FEBRUARY, + MTHF_MARCH, + MTHF_APRIL, + MTHF_MAY, + MTHF_JUNE, + MTHF_JULY, + MTHF_AUGUST, + MTHF_SEPTEMBER, + MTHF_OCTOBER, + MTHF_NOVEMBER, + MTHF_DECEMBER, +} +*/ + +/* Since there are no compile time constants in C / C++ + it is a common abuse + to declare bit set (flag) constants + as enumerations. */ +enum calendar { + MTHB_JANUARY = 1 << 0, /* 1 << MTHF_JANUARY, */ + MTHB_FEBRUARY = 1 << 1, /* 1 << MTHF_FEBRUARY, */ + MTHB_MARCH = 1 << 2, /* 1 << MTHF_MARCH, */ + MTHB_APRIL = 1 << 3, /* 1 << MTHF_APRIL, */ + MTHB_MAY = 1 << 4, /* 1 << MTHF_MAY, */ + MTHB_JUNE = 1 << 5, /* 1 << MTHF_JUNE, */ + MTHB_JULY = 1 << 6, /* 1 << MTHF_JULY, */ + MTHB_AUGUST = 1 << 7, /* 1 << MTHF_AUGUST, */ + MTHB_SEPTEMBER = 1 << 8, /* 1 << MTHF_SEPTEMBER, */ + MTHB_OCTOBER = 1 << 9, /* 1 << MTHF_OCTOBER, */ + MTHB_NOVEMBER = 1 << 10, /* 1 << MTHF_NOVEMBER, */ + MTHB_DECEMBER = 1 << 11, /* 1 << MTHF_DECEMBER, */ + + MTHB_SPRING = MTHB_MARCH | MTHB_APRIL | MTHB_MAY, + MTHB_SUMMER = MTHB_JUNE | MTHB_JULY | MTHB_AUGUST, + MTHB_AUTUMN = MTHB_SEPTEMBER | MTHB_OCTOBER | MTHB_NOVEMBER, + MTHB_WINTER = MTHB_DECEMBER | MTHB_JANUARY | MTHB_FEBRUARY, +}; + + +namespace Answer { + enum { + UNIVERSE_AND_EVERYTHING = 42, + SEVENTEEN_AND_FOUR = 21, + TWOHUNDRED_PERCENT_OF_NOTHING = 0, + }; + + class Foo { + public: + Foo() { } + enum speed { IMPULSE = -2, WARP = 0, HYPER, LUDICROUS = 3}; + void enum_test(speed s); + }; +}; + +void enum_test(color c, Answer::Foo::speed s); diff --git a/Examples/modula3/enum/example.i b/Examples/modula3/enum/example.i new file mode 100644 index 000000000..f5947b3bc --- /dev/null +++ b/Examples/modula3/enum/example.i @@ -0,0 +1,72 @@ +/* File : example.i */ +%module Example + +%{ +#include "example.h" +%} + +%include "example_const.i" + +// such features are generated by the following pragmas +#if 0 +%feature("modula3:enumitem:enum","Days") DAY_MONDAY; +%feature("modula3:enumitem:name","monday") DAY_MONDAY; +%feature("modula3:enumitem:conv","int:int") DAY_MONDAY; + +%feature("modula3:enumitem:enum","Month") MTHB_JANUARY; +%feature("modula3:enumitem:name","january") MTHB_JANUARY; +%feature("modula3:enumitem:conv","set:int") MTHB_JANUARY; +//%feature("modula3:constset:type","MonthSet") MTHB_JANUARY; /*type in the constant definition*/ +%feature("modula3:constset:set", "MonthSet") MTHB_JANUARY; /*remarks that the 'type' is a set type*/ +%feature("modula3:constset:base","Month") MTHB_JANUARY; +%feature("modula3:constset:name","monthsJanuary") MTHB_JANUARY; +%feature("modula3:constset:conv","set:set") MTHB_JANUARY; /*conversion of the bit pattern: no change*/ + +%feature("modula3:enumitem:enum","Color") BLUE; +%feature("modula3:enumitem:name","blue") BLUE; +%feature("modula3:enumitem:conv","int:int") BLUE; + +%feature("modula3:constint:type","INTEGER") Foo::IMPULSE; +%feature("modula3:constint:name","impulse") Foo::IMPULSE; +%feature("modula3:constint:conv","int:int") Foo::IMPULSE; +#endif + +%rename(pi) PI; + +%pragma(modula3) enumitem="prefix=DAY_;int;srcstyle=underscore;Day"; + +%pragma(modula3) enumitem="enum=color;int;srcstyle=underscore;Color"; +%pragma(modula3) makesetofenum="Color"; +%pragma(modula3) constset="prefix=CLB_;set;srcstyle=underscore,prefix=clb;ColorSet,Color"; + +%pragma(modula3) enumitem="prefix=MTHB_,enum=calendar;set;srcstyle=underscore;Month"; +%pragma(modula3) makesetofenum="Month"; +%pragma(modula3) constset="prefix=MTHB_,enum=calendar;set;srcstyle=underscore,prefix=monthset;MonthSet,Month"; + +%pragma(modula3) constint="prefix=Answer::Foo::,enum=Answer::Foo::speed;int;srcstyle=underscore,prefix=speed;INTEGER"; + +%pragma(modula3) constint="prefix=Answer::,enum=Answer::;int;srcstyle=underscore,prefix=answer;CARDINAL"; + +%rename(AnswerFoo) Answer::Foo; +%typemap("m3rawrettype") Answer::Foo * %{AnswerFoo%} +%typemap("m3rawintype") Answer::Foo * %{AnswerFoo%} +%typemap("m3rawinmode") Answer::Foo * %{%} +%typemap("m3wraprettype") Answer::Foo * %{AnswerFoo%} +%typemap("m3wrapintype") Answer::Foo * %{AnswerFoo%} +%typemap("m3wrapinmode") Answer::Foo * %{%} +%typemap("m3wrapargraw") Answer::Foo * %{self.cxxObj%} + +%typemap("m3wrapretvar") Answer::Foo * %{cxxObj : ExampleRaw.AnswerFoo;%} +%typemap("m3wrapretraw") Answer::Foo * %{cxxObj%} +%typemap("m3wrapretconv") Answer::Foo * %{NEW(AnswerFoo,cxxObj:=cxxObj)%} + + +%typemap("m3rawintype") Answer::Foo::speed %{C.int%}; +%typemap("m3rawintype:import") Answer::Foo::speed %{Ctypes AS C%}; +%typemap("m3wrapintype") Answer::Foo::speed %{[-2..3]%}; + +%typemap("m3wrapintype") color %{Color%}; +%typemap("m3wrapargraw") color %{ORD($1_name)%}; + +/* Let's just grab the original header file here */ +%include "example.h" diff --git a/Examples/modula3/exception/.cvsignore b/Examples/modula3/exception/.cvsignore new file mode 100644 index 000000000..8aeb7ffe9 --- /dev/null +++ b/Examples/modula3/exception/.cvsignore @@ -0,0 +1,17 @@ +*.class +*.java +*_wrap.* +*.i3 +*.m3 +m3makefile +src +LINUXLIBC6 +*.dll +*.dsw +*.exp +*.lib +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/modula3/exception/Makefile b/Examples/modula3/exception/Makefile new file mode 100644 index 000000000..45c49ea32 --- /dev/null +++ b/Examples/modula3/exception/Makefile @@ -0,0 +1,23 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +SWIGOPT = +MODULA3SRCS = *.[im]3 +MODULA3FLAGS= -o runme + +all:: modula3 + +modula3:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3_cpp +# $(MAKE) -f $(TOP)/Makefile MODULA3SRCS='$(MODULA3SRCS)' MODULA3FLAGS='$(MODULA3FLAGS)' modula3_compile + m3ppinplace $(MODULA3SRCS) + mv m3makefile $(MODULA3SRCS) src/ + cm3 + +clean:: + $(MAKE) -f $(TOP)/Makefile modula3_clean + +check: all diff --git a/Examples/modula3/exception/example.h b/Examples/modula3/exception/example.h new file mode 100644 index 000000000..0e9e0e81d --- /dev/null +++ b/Examples/modula3/exception/example.h @@ -0,0 +1,18 @@ +/* File : example.h */ + +enum error {OK, OVERFLOW, DIVISION_BY_ZERO, NEGATIVE_RADICAND, NEGATIVE_BASE}; +typedef error errorstate; /* just to separate the typemaps */ + +error acc_add (double &x, double y); +error acc_sub (double &x, double y); +error acc_mul (double &x, double y); +error acc_div (double &x, double y); + +double op_add (double x, double y, errorstate &err); +double op_sub (double x, double y, errorstate &err); +double op_mul (double x, double y, errorstate &err); +double op_div (double x, double y, errorstate &err); +double op_sqrt (double x, errorstate &err); +double op_pow (double x, double y, errorstate &err); + +double op_noexc (double x, double y); diff --git a/Examples/modula3/exception/example.i b/Examples/modula3/exception/example.i new file mode 100644 index 000000000..92a716fae --- /dev/null +++ b/Examples/modula3/exception/example.i @@ -0,0 +1,43 @@ +/* File : example.i */ +%module Example + +%{ +#include "example.h" +%} + +%insert(m3wrapintf) %{ +EXCEPTION E(Error); +%} +%insert(m3wrapimpl) %{ +IMPORT Ctypes AS C; +%} + +%pragma(modula3) enumitem="enum=error;int;srcstyle=underscore;Error"; + +%typemap("m3rawintype") double & %{C.double%}; +%typemap("m3wrapintype") double & %{LONGREAL%}; + +%typemap("m3wraprettype") error "" +%typemap("m3wrapretvar") error "rawerr: C.int;" +%typemap("m3wrapretraw") error "rawerr" +%typemap("m3wrapretcheck:throws") error "E" +%typemap("m3wrapretcheck") error +%{VAR err := VAL(rawerr, Error); +BEGIN +IF err # Error.ok THEN +RAISE E(err); +END; +END;%} + +%typemap("m3rawintype") errorstate & %{C.int%}; +%typemap("m3wrapintype",numinputs=0) errorstate & %{%}; +%typemap("m3wrapargvar") errorstate & %{err:C.int:=ORD(Error.ok);%}; +%typemap("m3wrapoutcheck:throws") errorstate & "E"; +%typemap("m3wrapoutcheck") errorstate & +%{IF VAL(err,Error) # Error.ok THEN +RAISE E(VAL(err,Error)); +END;%} + +/* Let's just grab the original header file here */ + +%include "example.h" diff --git a/Examples/modula3/reference/.cvsignore b/Examples/modula3/reference/.cvsignore new file mode 100644 index 000000000..fb5be2da0 --- /dev/null +++ b/Examples/modula3/reference/.cvsignore @@ -0,0 +1,15 @@ +*.class +*.java +*_wrap.* +*.i3 +*.m3 +*.dll +*.dsw +*.exp +*.lib +*.ncb +*.opt +*.plg +src +Release +Debug diff --git a/Examples/modula3/reference/Makefile b/Examples/modula3/reference/Makefile new file mode 100644 index 000000000..d0eed7f33 --- /dev/null +++ b/Examples/modula3/reference/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i +SWIGOPT = -c++ +MODULA3SRCS = *.[im]3 + +all:: modula3 + +modula3:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3 + m3ppinplace $(MODULA3SRCS) + mv m3makefile $(MODULA3SRCS) src/ + cm3 + +clean:: + $(MAKE) -f $(TOP)/Makefile modula3_clean + +check: all diff --git a/Examples/modula3/reference/example.cxx b/Examples/modula3/reference/example.cxx new file mode 100644 index 000000000..2a63fbc52 --- /dev/null +++ b/Examples/modula3/reference/example.cxx @@ -0,0 +1,41 @@ +/* File : example.cxx */ + +#include "example.h" +#include +#include + +Vector operator+(const Vector &a, const Vector &b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +char *Vector::print() { + static char temp[512]; + sprintf(temp,"Vector %x (%g,%g,%g)", (int)this, x,y,z); + return temp; +} + +VectorArray::VectorArray(int size) { + items = new Vector[size]; + maxsize = size; +} + +VectorArray::~VectorArray() { + delete [] items; +} + +Vector &VectorArray::operator[](int index) { + if ((index < 0) || (index >= maxsize)) { + printf("Panic! Array index out of bounds.\n"); + exit(1); + } + return items[index]; +} + +int VectorArray::size() { + return maxsize; +} + diff --git a/Examples/modula3/reference/example.h b/Examples/modula3/reference/example.h new file mode 100644 index 000000000..0a9cd447f --- /dev/null +++ b/Examples/modula3/reference/example.h @@ -0,0 +1,22 @@ +/* File : example.h */ + +struct Vector { +private: + double x,y,z; +public: + Vector() : x(0), y(0), z(0) { }; + Vector(double x, double y, double z) : x(x), y(y), z(z) { }; + Vector operator+(const Vector &b) const; + char *print(); +}; + +struct VectorArray { +private: + Vector *items; + int maxsize; +public: + VectorArray(int maxsize); + ~VectorArray(); + Vector &operator[](int); + int size(); +}; diff --git a/Examples/modula3/reference/example.i b/Examples/modula3/reference/example.i new file mode 100644 index 000000000..002090918 --- /dev/null +++ b/Examples/modula3/reference/example.i @@ -0,0 +1,32 @@ +/* File : example.i */ + +/* This file has a few "typical" uses of C++ references. */ + +%module Example + +%{ +#include "example.h" +%} + +%pragma(modula3) unsafe="1"; + +%insert(m3wrapintf) %{FROM ExampleRaw IMPORT Vector, VectorArray;%} +%insert(m3wrapimpl) %{FROM ExampleRaw IMPORT Vector, VectorArray;%} + +%typemap(m3wrapretvar) Vector %{vec: UNTRACED REF Vector;%} +%typemap(m3wrapretraw) Vector %{vec%} +%typemap(m3wrapretconv) Vector %{vec^%} + + +/* This helper function calls an overloaded operator */ +%inline %{ +Vector addv(const Vector &a, const Vector &b) { + return a+b; +} +%} + +%rename(Vector_Clear) Vector::Vector(); +%rename(Add) Vector::operator+; +%rename(GetItem) VectorArray::operator[]; + +%include "example.h" diff --git a/Examples/modula3/simple/.cvsignore b/Examples/modula3/simple/.cvsignore new file mode 100644 index 000000000..25bc5fc2d --- /dev/null +++ b/Examples/modula3/simple/.cvsignore @@ -0,0 +1,8 @@ +*_wrap.c +*_wrap.xml +*.i3 +*.m3 +m3makefile +src +Release +Debug diff --git a/Examples/modula3/simple/Makefile b/Examples/modula3/simple/Makefile new file mode 100644 index 000000000..e4f9ad26d --- /dev/null +++ b/Examples/modula3/simple/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i +SWIGOPT = +MODULA3SRCS = *.[im]3 + +all:: modula3 + +modula3:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3 + m3ppinplace $(MODULA3SRCS) + mv m3makefile $(MODULA3SRCS) src/ + cm3 + +clean:: + $(MAKE) -f $(TOP)/Makefile modula3_clean + +check: all diff --git a/Examples/modula3/simple/example.c b/Examples/modula3/simple/example.c new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/Examples/modula3/simple/example.c @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/modula3/simple/example.i b/Examples/modula3/simple/example.i new file mode 100644 index 000000000..e78a0b6de --- /dev/null +++ b/Examples/modula3/simple/example.i @@ -0,0 +1,5 @@ +/* File : example.i */ +%module Example + +extern int gcd(int x, int y); +extern double Foo; diff --git a/Examples/modula3/typemap/.cvsignore b/Examples/modula3/typemap/.cvsignore new file mode 100644 index 000000000..8aeb7ffe9 --- /dev/null +++ b/Examples/modula3/typemap/.cvsignore @@ -0,0 +1,17 @@ +*.class +*.java +*_wrap.* +*.i3 +*.m3 +m3makefile +src +LINUXLIBC6 +*.dll +*.dsw +*.exp +*.lib +*.ncb +*.opt +*.plg +Release +Debug diff --git a/Examples/modula3/typemap/Makefile b/Examples/modula3/typemap/Makefile new file mode 100644 index 000000000..e4f9ad26d --- /dev/null +++ b/Examples/modula3/typemap/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = +TARGET = example +INTERFACE = example.i +SWIGOPT = +MODULA3SRCS = *.[im]3 + +all:: modula3 + +modula3:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3 + m3ppinplace $(MODULA3SRCS) + mv m3makefile $(MODULA3SRCS) src/ + cm3 + +clean:: + $(MAKE) -f $(TOP)/Makefile modula3_clean + +check: all diff --git a/Examples/modula3/typemap/example.i b/Examples/modula3/typemap/example.i new file mode 100644 index 000000000..2f454eff3 --- /dev/null +++ b/Examples/modula3/typemap/example.i @@ -0,0 +1,90 @@ +/* File : example.i */ +%module Example + +%pragma(modula3) unsafe="true"; + +%insert(m3wrapintf) %{FROM ExampleRaw IMPORT Window, Point; +%} +%insert(m3wrapimpl) %{FROM ExampleRaw IMPORT Window, Point; +IMPORT M3toC; +IMPORT Ctypes AS C; +%} + +/* Typemap applied to patterns of multiple arguments */ + +%typemap(m3rawinmode) (char *outstr) %{VAR%} +%typemap(m3rawintype) (char *outstr) %{CHAR%} +%typemap(m3wrapinmode) (char *outstr, int size) %{VAR%} +%typemap(m3wrapintype) (char *outstr, int size) %{ARRAY OF CHAR%} +%typemap(m3wrapargraw) (char *outstr, int size) %{$1_name[0], NUMBER($1_name)%} + + +%typemap(m3rawinmode) (const struct Window *) %{READONLY%} +%typemap(m3wrapinmode) (const struct Window *) %{READONLY%} +%typemap(m3rawintype) ( struct Window *) %{Window%} +%typemap(m3wrapintype) ( struct Window *) %{Window%} + +%typemap(m3rawinmode) (const char *str []) %{READONLY%} +%typemap(m3wrapinmode) (const char *str []) %{READONLY%} +%typemap(m3rawintype) (const char *str []) %{(*ARRAY OF*) C.char_star%} +%typemap(m3wrapintype) (const char *str []) %{ARRAY OF TEXT%} +%typemap(m3wrapargvar) (const char *str []) %{$1: REF ARRAY OF C.char_star;%} +%typemap(m3wrapargraw) (const char *str []) %{$1[0]%} +%typemap(m3wrapinconv) (const char *str []) %{$1:= NEW(REF ARRAY OF C.char_star,NUMBER($1_name)); +FOR i:=FIRST($1_name) TO LAST($1_name) DO +$1[i]:=M3toC.SharedTtoS($1_name[i]); +END;%} +%typemap(m3wrapfreearg) (const char *str []) +%{FOR i:=FIRST($1_name) TO LAST($1_name) DO +M3toC.FreeSharedS($1_name[i],$1[i]); +END;%} + +%typemap(m3wraprettype) char * %{TEXT%} +%typemap(m3wrapretvar) char * %{result_string: C.char_star;%} +%typemap(m3wrapretraw) char * %{result_string%} +%typemap(m3wrapretconv) char * %{M3toC.CopyStoT(result_string)%} + +struct Window { + char *label; + int left,top,width,height; +}; + + +%typemap(m3wrapinname) (int x, int y) %{p%} +%typemap(m3wrapinmode) (int x, int y) %{READONLY%} +%typemap(m3wrapintype) (int x, int y) %{Point%} +%typemap(m3wrapargraw) (int x, int y) %{p.$1_name, p.$2_name%} + +%typemap(m3wrapargraw) (int &x, int &y) %{p.$1_name, p.$2_name%} +%typemap(m3wrapintype) (int &x, int &y) %{Point%} +%typemap(m3wrapoutname) (int &x, int &y) %{p%} +%typemap(m3wrapouttype) (int &x, int &y) %{Point%} +%typemap(m3wrapargdir) (int &x, int &y) "out" + + +%typemap(m3wrapargvar) int &left, int &top, int &width, int &height "$1:C.int;" +%typemap(m3wrapargraw) int &left, int &top, int &width, int &height "$1" +%typemap(m3wrapoutconv) int &left, int &top, int &width, int &height "$1" + +%typemap(m3wrapargdir) int &left, int &top "out" + +%typemap(m3wrapouttype) int &width, int &height "CARDINAL" +%typemap(m3wrapargdir) int &width, int &height "out" + +struct Point { + int x,y; +}; + +%m3multiretval get_box; + +void set_label ( struct Window *win, const char *str, bool activate); +void set_multi_label ( struct Window *win, const char *str []); +void write_label (const struct Window *win, char *outstr, int size); +int get_label (const struct Window *win, char *outstr, int size); +char *get_label_ptr (const struct Window *win); +void move(struct Window *win, int x, int y); +int get_area(const struct Window *win); +void get_box(const struct Window *win, int &left, int &top, int &width, int &height); +void get_left(const struct Window *win, int &left); +void get_mouse(const struct Window *win, int &x, int &y); +int get_attached_data(const struct Window *win, const char *id); diff --git a/Lib/modula3/modula3.swg b/Lib/modula3/modula3.swg new file mode 100644 index 000000000..ba669b84b --- /dev/null +++ b/Lib/modula3/modula3.swg @@ -0,0 +1,699 @@ +/* ----------------------------------------------------------------------------- + * modula3.swg + * + * Modula3 typemaps + * ----------------------------------------------------------------------------- */ + +%include "modula3head.swg" + +/* The ctype, m3rawtype and m3wraptype typemaps work together and so there should be one of each. + * The ctype typemap contains the C type used in the signature of C wrappers for C++ functions. + * The m3rawtype typemap contains the M3 type used in the raw interface. + * The m3rawintype typemap contains the M3 type used as function argument. + * The m3rawrettype typemap contains the M3 type used as return value. + * The m3wraptype typemap contains the M3 type used in the M3 type wrapper classes and module class. */ + +/* Primitive types */ +%typemap(ctype) bool, const bool & "bool" +%typemap(ctype) char, const char & "char" +%typemap(ctype) signed char, const signed char & "signed char" +%typemap(ctype) unsigned char, const unsigned char & "unsigned short" +%typemap(ctype) short, const short & "short" +%typemap(ctype) unsigned short, const unsigned short & "unsigned short" +%typemap(ctype) int, const int & "int" +%typemap(ctype) unsigned int, const unsigned int & "unsigned int" +%typemap(ctype) long, const long & "long" +%typemap(ctype) unsigned long, const unsigned long & "unsigned long" +%typemap(ctype) long long, const long long & "long long" +%typemap(ctype) unsigned long long, const unsigned long long & "unsigned long long" +%typemap(ctype) float, const float & "float" +%typemap(ctype) double, const double & "double" +%typemap(ctype) char * "char *" +%typemap(ctype) void "void" + +%typemap(m3rawtype) bool, const bool & "BOOLEAN" +%typemap(m3rawtype) char, const char & "C.char" +%typemap(m3rawtype) signed char, const signed char & "C.signed_char" +%typemap(m3rawtype) unsigned char, const unsigned char & "C.unsigned_char" +%typemap(m3rawtype) short, const short & "C.short" +%typemap(m3rawtype) unsigned short, const unsigned short & "C.unsigned_short" +%typemap(m3rawtype) int, const int & "C.int" +%typemap(m3rawtype) unsigned int, const unsigned int & "C.unsigned_int" +%typemap(m3rawtype) long, const long & "C.long" +%typemap(m3rawtype) unsigned long, const unsigned long & "C.unsigned_long" +%typemap(m3rawtype) long long, const long long & "C.long_long" +%typemap(m3rawtype) unsigned long long, const unsigned long long & "C.unsigned_long_long" +%typemap(m3rawtype) float, const float & "C.float" +%typemap(m3rawtype) double, const double & "C.double" +%typemap(m3rawtype) long double, const long double & "C.long_double" +%typemap(m3rawtype) char * "C.char_star" +%typemap(m3rawtype) void "" + +%typemap(m3rawintype) bool *, bool &, bool "BOOLEAN" +%typemap(m3rawintype) char *, char &, char "C.char" +%typemap(m3rawintype) signed char *, signed char &, signed char "C.signed_char" +%typemap(m3rawintype) unsigned char *, unsigned char &, unsigned char "C.unsigned_char" +%typemap(m3rawintype) short *, short &, short "C.short" +%typemap(m3rawintype) unsigned short *, unsigned short &, unsigned short "C.unsigned_short" +%typemap(m3rawintype) int *, int &, int "C.int" +%typemap(m3rawintype) unsigned int *, unsigned int &, unsigned int "C.unsigned_int" +%typemap(m3rawintype) long *, long &, long "C.long" +%typemap(m3rawintype) unsigned long *, unsigned long &, unsigned long "C.unsigned_long" +%typemap(m3rawintype) long long *, long long &, long long "C.long_long" +%typemap(m3rawintype) unsigned long long *, unsigned long long &, unsigned long long "C.unsigned_long_long" +%typemap(m3rawintype) float *, float &, float "C.float" +%typemap(m3rawintype) double *, double &, double "C.double" +%typemap(m3rawintype) long double *, long double &, long double "C.long_double" +%typemap(m3rawintype) char * "C.char_star" +%typemap(m3rawintype) void "" + +%typemap(m3rawinmode) char * "" + +%typemap(m3rawrettype) bool, const bool & "BOOLEAN" +%typemap(m3rawrettype) char, const char & "C.char" +%typemap(m3rawrettype) signed char, const signed char & "C.signed_char" +%typemap(m3rawrettype) unsigned char, const unsigned char & "C.unsigned_char" +%typemap(m3rawrettype) short, const short & "C.short" +%typemap(m3rawrettype) unsigned short, const unsigned short & "C.unsigned_short" +%typemap(m3rawrettype) int, const int & "C.int" +%typemap(m3rawrettype) unsigned int, const unsigned int & "C.unsigned_int" +%typemap(m3rawrettype) long, const long & "C.long" +%typemap(m3rawrettype) unsigned long, const unsigned long & "C.unsigned_long" +%typemap(m3rawrettype) long long, const long long & "C.long_long" +%typemap(m3rawrettype) unsigned long long, const unsigned long long & "C.unsigned_long_long" +%typemap(m3rawrettype) float, const float & "C.float" +%typemap(m3rawrettype) double, const double & "C.double" +%typemap(m3rawrettype) long double, const long double & "C.long_double" +%typemap(m3rawrettype) char * "C.char_star" +%typemap(m3rawrettype) void "" + +%typemap("m3rawtype:import") + char, const char &, + signed char, const signed char &, + unsigned char, const unsigned char &, + short, const short &, + unsigned short, const unsigned short &, + int, const int &, + unsigned int, const unsigned int &, + long, const long &, + unsigned long, const unsigned long &, + long long, const long long &, + unsigned long long, const unsigned long long &, + float, const float &, + double, const double &, + long double, const long double &, + char * + "Ctypes AS C" + +%typemap("m3rawintype:import") + char, const char &, + signed char, const signed char &, + unsigned char, const unsigned char &, + short, const short &, + unsigned short, const unsigned short &, + int, const int &, + unsigned int, const unsigned int &, + long, const long &, + unsigned long, const unsigned long &, + long long, const long long &, + unsigned long long, const unsigned long long &, + float, const float &, + double, const double &, + long double, const long double &, + char * + "Ctypes AS C" + +%typemap("m3rawrettype:import") + char, const char &, + signed char, const signed char &, + unsigned char, const unsigned char &, + short, const short &, + unsigned short, const unsigned short &, + int, const int &, + unsigned int, const unsigned int &, + long, const long &, + unsigned long, const unsigned long &, + long long, const long long &, + unsigned long long, const unsigned long long &, + float, const float &, + double, const double &, + long double, const long double &, + char * + "Ctypes AS C" + +%typemap(m3wraptype) bool, const bool & "BOOLEAN" +%typemap(m3wraptype) char, const char & "CHAR" +%typemap(m3wraptype) signed char, const signed char & "CHAR" +%typemap(m3wraptype) unsigned char, const unsigned char & "CHAR" +%typemap(m3wraptype) short, const short & "Integer16.T" +%typemap(m3wraptype) unsigned short, const unsigned short & "Cardinal16.T" +%typemap(m3wraptype) int, const int & "INTEGER" +%typemap(m3wraptype) unsigned int, const unsigned int & "CARDINAL" +%typemap(m3wraptype) long, const long & "Integer32.T" +%typemap(m3wraptype) unsigned long, const unsigned long & "Cardinal32.T" +%typemap(m3wraptype) long long, const long long & "Integer64.T" +%typemap(m3wraptype) unsigned long long, const unsigned long long & "Cardinal64.T" +%typemap(m3wraptype) float, const float & "REAL" +%typemap(m3wraptype) double, const double & "LONGREAL" +%typemap(m3wraptype) long double, const long double & "EXTENDED" +%typemap(m3wraptype) char * "TEXT" +%typemap(m3wraptype) void "" + +%typemap(m3wrapintype) bool, const bool *, const bool & "BOOLEAN" +%typemap(m3wrapintype) char, const char *, const char & "CHAR" +%typemap(m3wrapintype) signed char, const signed char *, const signed char & "CHAR" +%typemap(m3wrapintype) unsigned char, const unsigned char *, const unsigned char & "CHAR" +%typemap(m3wrapintype) short, const short *, const short & "INTEGER" +%typemap(m3wrapintype) unsigned short, const unsigned short *, const unsigned short & "CARDINAL" +%typemap(m3wrapintype) int, const int *, const int & "INTEGER" +%typemap(m3wrapintype) unsigned int, const unsigned int *, const unsigned int & "CARDINAL" +%typemap(m3wrapintype) long, const long *, const long & "INTEGER" +%typemap(m3wrapintype) unsigned long, const unsigned long *, const unsigned long & "CARDINAL" +%typemap(m3wrapintype) long long, const long long *, const long long & "INTEGER" +%typemap(m3wrapintype) unsigned long long, const unsigned long long *, const unsigned long long & "CARDINAL" +%typemap(m3wrapintype) float, const float *, const float & "REAL" +%typemap(m3wrapintype) double, const double *, const double & "LONGREAL" +%typemap(m3wrapintype) long double, const long double *, const long double & "EXTENDED" +%typemap(m3wrapintype) const char *, const char [] "TEXT" +%typemap(m3wrapintype,numinputs=0) void "" + +%typemap(m3wrapouttype) bool, bool *, bool & "BOOLEAN" +%typemap(m3wrapouttype) char, char *, char & "CHAR" +%typemap(m3wrapouttype) signed char, signed char *, signed char & "CHAR" +%typemap(m3wrapouttype) unsigned char, unsigned char *, unsigned char & "CHAR" +%typemap(m3wrapouttype) short, short *, short & "INTEGER" +%typemap(m3wrapouttype) unsigned short, unsigned short *, unsigned short & "CARDINAL" +%typemap(m3wrapouttype) int, int *, int & "INTEGER" +%typemap(m3wrapouttype) unsigned int, unsigned int *, unsigned int & "CARDINAL" +%typemap(m3wrapouttype) long, long *, long & "INTEGER" +%typemap(m3wrapouttype) unsigned long, unsigned long *, unsigned long & "CARDINAL" +%typemap(m3wrapouttype) long long, long long *, long long & "INTEGER" +%typemap(m3wrapouttype) unsigned long long, unsigned long long *, unsigned long long & "CARDINAL" +%typemap(m3wrapouttype) float, float *, float & "REAL" +%typemap(m3wrapouttype) double, double *, double & "LONGREAL" +%typemap(m3wrapouttype) long double, long double *, long double & "EXTENDED" +%typemap(m3wrapouttype) char *, char [] "TEXT" +%typemap(m3wrapouttype,numinputs=0) void "" + +%typemap(m3wraprettype) bool, const bool & "BOOLEAN" +%typemap(m3wraprettype) char, const char & "CHAR" +%typemap(m3wraprettype) signed char, const signed char & "CHAR" +%typemap(m3wraprettype) unsigned char, const unsigned char & "CHAR" +%typemap(m3wraprettype) short, const short & "INTEGER" +%typemap(m3wraprettype) unsigned short, const unsigned short & "CARDINAL" +%typemap(m3wraprettype) int, const int & "INTEGER" +%typemap(m3wraprettype) unsigned int, const unsigned int & "CARDINAL" +%typemap(m3wraprettype) long, const long & "INTEGER" +%typemap(m3wraprettype) unsigned long, const unsigned long & "CARDINAL" +%typemap(m3wraprettype) long long, const long long & "INTEGER" +%typemap(m3wraprettype) unsigned long long, const unsigned long long & "CARDINAL" +%typemap(m3wraprettype) float, const float & "REAL" +%typemap(m3wraprettype) double, const double & "LONGREAL" +%typemap(m3wraprettype) long double, const long double & "EXTENDED" +%typemap(m3wraprettype) char * "TEXT" +%typemap(m3wraprettype) void "" + +%typemap(ctype) char[ANY] "char *" +%typemap(m3rawtype) char[ANY] "C.char_star" +%typemap(m3rawintype) char[ANY] "C.char_star" +%typemap(m3rawrettype) char[ANY] "C.char_star" +%typemap(m3wraptype) char[ANY] "TEXT" +%typemap(m3wrapintype) char[ANY] "TEXT" +%typemap(m3wrapouttype) char[ANY] "TEXT" +%typemap(m3wraprettype) char[ANY] "TEXT" + +%typemap(m3wrapinmode) const char * %{%} +%typemap(m3wrapargvar) const char * %{$1 : C.char_star;%} +%typemap(m3wrapinconv) const char * %{$1 := M3toC.SharedTtoS($1_name);%} +%typemap(m3wrapfreearg) const char * %{M3toC.FreeSharedS($1_name,$1);%} +%typemap(m3wrapargraw) const char * %{$1%} +%typemap("m3wrapargvar:import") const char * "Ctypes AS C" +%typemap("m3wrapinconv:import") const char * "M3toC" +%typemap("m3wrapfreearg:import") const char * "M3toC" + +%typemap(m3wrapretvar) char * %{result : C.char_star;%} +%typemap(m3wrapretraw) char * %{result%} +%typemap(m3wrapretconv) char * %{M3toC.CopyStoT(result)%} +%typemap("m3wrapretvar:import") char * "Ctypes AS C" +%typemap("m3wrapretconv:import") char * "M3toC" + +/* Composed types */ +%typemap(ctype) SWIGTYPE "$1_type" +%typemap(m3rawtype) SWIGTYPE "$1_basetype" +%typemap(m3rawrettype) SWIGTYPE "UNTRACED REF $1_basetype" +%typemap(m3wraptype) SWIGTYPE "$1_basetype" +%typemap(m3wrapintype) SWIGTYPE "$1_basetype" +%typemap(m3wrapouttype) SWIGTYPE "$1_basetype" +%typemap(m3wraprettype) SWIGTYPE "$1_basetype" + +%typemap(ctype) SWIGTYPE [] "$1_type" +%typemap(m3rawtype) const SWIGTYPE [] "UNTRACED REF ARRAY INTEGER OF $1_basetype" +%typemap(m3rawtype) SWIGTYPE [] "UNTRACED REF ARRAY INTEGER OF $1_basetype" +%typemap(m3rawintype) const SWIGTYPE [] "(*ARRAY OF*) $1_basetype" +%typemap(m3rawinmode) const SWIGTYPE [] "READONLY" +%typemap(m3rawintype) SWIGTYPE [] "(*ARRAY OF*) $1_basetype" +%typemap(m3rawinmode) SWIGTYPE [] "VAR" +%typemap(m3rawrettype) const SWIGTYPE [] "UNTRACED REF ARRAY INTEGER OF $1_basetype" +%typemap(m3rawrettype) SWIGTYPE [] "UNTRACED REF ARRAY INTEGER OF $1_basetype" +%typemap(m3wraptype) SWIGTYPE [] "$1_basetype" +%typemap(m3wrapintype) const SWIGTYPE [] "ARRAY OF $1_basetype" +%typemap(m3wrapinmode) const SWIGTYPE [] "READONLY" +%typemap(m3wrapintype) SWIGTYPE [] "ARRAY OF $1_basetype" +%typemap(m3wrapinmode) SWIGTYPE [] "VAR" +%typemap(m3wrapouttype) SWIGTYPE [] "ARRAY OF $1_basetype" +%typemap(m3wraprettype) SWIGTYPE [] "REF ARRAY OF $1_basetype" + +%typemap(ctype) SWIGTYPE * "$1_type" +%typemap(m3rawtype) const SWIGTYPE * "UNTRACED REF $1_basetype" +%typemap(m3rawtype) SWIGTYPE * "UNTRACED REF $1_basetype" +%typemap(m3rawintype) const SWIGTYPE * "$1_basetype" +%typemap(m3rawinmode) const SWIGTYPE * "READONLY" +%typemap(m3rawintype) SWIGTYPE * "$1_basetype" +%typemap(m3rawinmode) SWIGTYPE * "VAR" +%typemap(m3rawrettype) const SWIGTYPE * "UNTRACED REF $1_basetype" +%typemap(m3rawrettype) SWIGTYPE * "UNTRACED REF $1_basetype" +%typemap(m3wraptype) SWIGTYPE * "$1_basetype" +%typemap(m3wrapintype) const SWIGTYPE * "$1_basetype" +%typemap(m3wrapinmode) const SWIGTYPE * "READONLY" +%typemap(m3wrapintype) SWIGTYPE * "$1_basetype" +%typemap(m3wrapinmode) SWIGTYPE * "VAR" +%typemap(m3wrapouttype) SWIGTYPE * "$1_basetype" +%typemap(m3wraprettype) SWIGTYPE * "UNTRACED REF $1_basetype" + +%typemap(ctype) SWIGTYPE & "$1_type" +%typemap(m3rawtype) const SWIGTYPE & "UNTRACED REF $1_basetype" +%typemap(m3rawtype) SWIGTYPE & "UNTRACED REF $1_basetype" +%typemap(m3rawintype) const SWIGTYPE & "$1_basetype" +%typemap(m3rawinmode) const SWIGTYPE & "READONLY" +%typemap(m3rawintype) SWIGTYPE & "$1_basetype" +%typemap(m3rawinmode) SWIGTYPE & "VAR" +%typemap(m3rawrettype) const SWIGTYPE & "UNTRACED REF $1_basetype" +%typemap(m3rawrettype) SWIGTYPE & "UNTRACED REF $1_basetype" +%typemap(m3wraptype) SWIGTYPE & "$1_basetype" +%typemap(m3wrapintype) const SWIGTYPE & "$1_basetype" +%typemap(m3wrapinmode) const SWIGTYPE & "READONLY" +%typemap(m3wrapintype) SWIGTYPE & "$1_basetype" +%typemap(m3wrapinmode) SWIGTYPE & "VAR" +%typemap(m3wrapouttype) SWIGTYPE & "$1_basetype" +%typemap(m3wraprettype) SWIGTYPE & "UNTRACED REF $1_basetype" + +%typemap(ctype) enum SWIGTYPE "$1_type" +%typemap(m3rawtype) enum SWIGTYPE "C.int" +%typemap(m3rawintype) enum SWIGTYPE "C.int (* $1_type *)" +%typemap(m3rawrettype) enum SWIGTYPE "C.int" +%typemap(m3wraptype) enum SWIGTYPE "$*1_type" +%typemap(m3wrapintype) enum SWIGTYPE "$1_type" +%typemap(m3wrapouttype) enum SWIGTYPE "$1_type" +%typemap(m3wraprettype) enum SWIGTYPE "$*1_type" + +/* pointer to a class member */ +%typemap(ctype) SWIGTYPE (CLASS::*) "$1_type" +%typemap(m3rawtype) SWIGTYPE (CLASS::*) "REFANY" +%typemap(m3wraptype) SWIGTYPE (CLASS::*) "$1_basetype" + +/* The following are the in, out, freearg, argout typemaps. + These are the PInvoke code generating typemaps for converting from C# to C and visa versa. */ + +/* primitive types */ +%typemap(in) bool +%{ $1 = $input ? true : false; %} + +%typemap(in) char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long, + float, + double, + enum SWIGTYPE +%{ $1 = ($1_ltype)$input; %} + +%typemap(out) bool %{ $result = $1; %} +%typemap(out) char %{ $result = $1; %} +%typemap(out) signed char %{ $result = $1; %} +%typemap(out) unsigned char %{ $result = $1; %} +%typemap(out) short %{ $result = $1; %} +%typemap(out) unsigned short %{ $result = $1; %} +%typemap(out) int %{ $result = $1; %} +%typemap(out) unsigned int %{ $result = $1; %} +%typemap(out) long %{ $result = $1; %} +%typemap(out) unsigned long %{ $result = $1; %} +%typemap(out) long long %{ $result = $1; %} +%typemap(out) unsigned long long %{ $result = $1; %} +%typemap(out) float %{ $result = $1; %} +%typemap(out) double %{ $result = $1; %} +%typemap(out) enum SWIGTYPE %{ $result = $1; %} + +/* char * - treat as String */ +%typemap(in) char * { + $1 = $input; +} +//%typemap(freearg) char * { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, $1); } +//%typemap(out) char * { if($1) $result = JCALL1(NewStringUTF, jenv, $1); } + +%typemap(out) void "" + +/* primitive types by const reference */ +%typemap(in) const bool & (bool temp) +%{ temp = $input ? true : false; + $1 = &temp; %} + +%typemap(in) const char & (char temp), + const signed char & (signed char temp), + const unsigned char & (unsigned char temp), + const short & (short temp), + const unsigned short & (unsigned short temp), + const int & (int temp), + const unsigned int & (unsigned int temp), + const long & (long temp), + const unsigned long & (unsigned long temp), + const long long & ($*1_ltype temp), + const unsigned long long & ($*1_ltype temp), + const float & (float temp), + const double & (double temp) +%{ temp = ($*1_ltype)$input; +$1 = &temp; %} + +%typemap(out) const bool & %{ $result = *$1; %} +%typemap(out) const char & %{ $result = *$1; %} +%typemap(out) const signed char & %{ $result = *$1; %} +%typemap(out) const unsigned char & %{ $result = *$1; %} +%typemap(out) const short & %{ $result = *$1; %} +%typemap(out) const unsigned short & %{ $result = *$1; %} +%typemap(out) const int & %{ $result = *$1; %} +%typemap(out) const unsigned int & %{ $result = *$1; %} +%typemap(out) const long & %{ $result = *$1; %} +%typemap(out) const unsigned long & %{ $result = *$1; %} +%typemap(out) const long long & %{ $result = *$1; %} +%typemap(out) const unsigned long long & %{ $result = *$1; %} +%typemap(out) const float & %{ $result = *$1; %} +%typemap(out) const double & %{ $result = *$1; %} + +/* Default handling. Object passed by value. Convert to a pointer */ +%typemap(in) SWIGTYPE ($&1_type argp) +%{ argp = *($&1_ltype*)&$input; + if (!argp) { +// SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type"); + RETURN $null; + } + $1 = *argp; %} +%typemap(out) SWIGTYPE +#ifdef __cplusplus +%{*($&1_ltype*)&$result = new $1_ltype(($1_ltype &)$1); %} +#else +{ + $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype)); + memmove($1ptr, &$1, sizeof($1_type)); + *($&1_ltype*)&$result = $1ptr; +} +#endif + +/* Generic pointers and references */ +%typemap(in) SWIGTYPE *, SWIGTYPE (CLASS::*) %{ $1 = *($&1_ltype)&$input; %} +%typemap(in) SWIGTYPE & %{ $1 = *($&1_ltype)&$input; + if(!$1) { + //SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null"); + RETURN $null; + } %} +%typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE (CLASS::*) %{ *($&1_ltype)&$result = $1; %} + + +/* Default array handling */ +%typemap(in) SWIGTYPE [] %{ $1 = *($&1_ltype)&$input; %} +%typemap(out) SWIGTYPE [] %{ *($&1_ltype)&$result = $1; %} + +/* char[ANY] - treat as String */ +%typemap(in) char[ANY] { + $1 = $input; +} + +%typemap(argout) char[ANY] "" +%typemap(freearg) char[ANY] ""//{ if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, $1); } +%typemap(out) char[ANY] { if($1) $result = $1; } + + +/* Typecheck typemaps - The purpose of these is merely to issue a warning for overloaded C++ functions + * that cannot be overloaded in C# as more than one C++ type maps to a single C# type */ + +%typecheck(SWIG_TYPECHECK_BOOL) /* Java boolean */ + bool, + const bool & + "" + +%typecheck(SWIG_TYPECHECK_CHAR) /* Java char */ + char, + const char & + "" + +%typecheck(SWIG_TYPECHECK_INT8) /* Java byte */ + signed char, + const signed char & + "" + +%typecheck(SWIG_TYPECHECK_INT16) /* Java short */ + unsigned char, + short, + const unsigned char &, + const short & + "" + +%typecheck(SWIG_TYPECHECK_INT32) /* Java int */ + unsigned short, + int, + long, + const unsigned short &, + const int &, + const long &, + enum SWIGTYPE + "" + +%typecheck(SWIG_TYPECHECK_INT64) /* Java long */ + unsigned int, + unsigned long, + long long, + const unsigned int &, + const unsigned long &, + const long long & + "" + +%typecheck(SWIG_TYPECHECK_INT128) /* Java BigInteger */ + unsigned long long + "" + +%typecheck(SWIG_TYPECHECK_FLOAT) /* Java float */ + float, + const float & + "" + +%typecheck(SWIG_TYPECHECK_DOUBLE) /* Java double */ + double, + const double & + "" + +%typecheck(SWIG_TYPECHECK_STRING) /* Java String */ + char *, + char[ANY] + "" + +%typecheck(SWIG_TYPECHECK_POINTER) /* Default */ + SWIGTYPE, + SWIGTYPE *, + SWIGTYPE &, + SWIGTYPE [], + SWIGTYPE (CLASS::*) + "" + +/* Exception handling */ + +%typemap(throws) int, + long, + short, + unsigned int, + unsigned long, + unsigned short { + char error_msg[256]; + sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1); + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, error_msg); + RETURN $null; +} + +%typemap(throws) SWIGTYPE { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "C++ $1_type exception thrown"); + RETURN $null; +} + +%typemap(throws) char * { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1); + RETURN $null; +} + + +/* Typemaps for code generation in proxy classes and C# type wrapper classes */ + +/* The in typemap is used for converting function parameter types from the type + * used in the proxy, module or type wrapper class to the type used in the PInvoke class. */ +%typemap(m3in) bool, const bool &, + char, const char &, + signed char, const signed char &, + unsigned char, const unsigned char &, + short, const short &, + unsigned short, const unsigned short &, + int, const int &, + unsigned int, const unsigned int &, + long, const long &, + unsigned long, const unsigned long &, + long long, const long long &, + unsigned long long, const unsigned long long &, + float, const float &, + double, const double &, + char *, + char[ANY], + enum SWIGTYPE + "$input" +%typemap(m3in) SWIGTYPE "$&*1_type.getCPtr($input)" +%typemap(m3in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "$1_basetype.getCPtr($input)" + +/* The m3out typemap is used for converting function return types from the return type + * used in the PInvoke class to the type returned by the proxy, module or type wrapper class. */ +%typemap(m3out) bool, const bool &, + char, const char &, + signed char, const signed char &, + unsigned char, const unsigned char &, + short, const short &, + unsigned short, const unsigned short &, + int, const int &, + unsigned int, const unsigned int &, + long, const long &, + unsigned long, const unsigned long &, + long long, const long long &, + unsigned long long, const unsigned long long &, + float, const float &, + double, const double &, + char *, + char[ANY], + enum SWIGTYPE +%{$imcall%} + +%typemap(m3out) void %{$imcall%} + +%typemap(m3out) SWIGTYPE %{ + RETURN NEW(REF $1_basetype, $imcall); +%} +%typemap(m3out) SWIGTYPE & %{ + RETURN NEW($1_basetype, $imcall, $owner); +%} +%typemap(m3out) SWIGTYPE *, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ + cPtr := $imcall; + RETURN (cPtr = IntPtr.Zero) ? null : NEW($1_basetype, cPtr, $owner); +%} + +/* Properties */ +%typemap(m3varin) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ +PROCEDURE Set$var (value: $vartype) = + BEGIN + $imcall; + END Set$var; +%} + +%typemap(m3varout) bool, const bool &, + char, const char &, + signed char, const signed char &, + unsigned char, const unsigned char &, + short, const short &, + unsigned short, const unsigned short &, + int, const int &, + unsigned int, const unsigned int &, + long, const long &, + unsigned long, const unsigned long &, + long long, const long long &, + unsigned long long, const unsigned long long &, + float, const float &, + double, const double &, + char *, + char[ANY], + enum SWIGTYPE %{ +PROCEDURE Get$var (): $vartype = + BEGIN + RETURN $imcall; + END Get$var; +%} + +%typemap(m3varout) void %{ + get { + $imcall; + } %} +%typemap(m3varout) SWIGTYPE %{ + get { + RETURN new $&*1_mangle($imcall, true); + } %} +%typemap(m3varout) SWIGTYPE & %{ + get { + RETURN new $1_basetype($imcall, $owner); + } %} +%typemap(m3varout) SWIGTYPE *, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ + get { + IntPtr cPtr = $imcall; + RETURN (cPtr == IntPtr.Zero) ? null : new $1_basetype(cPtr, $owner); + } %} + +/* Typemaps used for the generation of proxy and type wrapper class code */ +%typemap(m3base) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(m3classmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "public" +%typemap(m3code) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(m3imports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "using System;" +%typemap(m3interfaces) SWIGTYPE "IDisposable" +%typemap(m3interfaces_derived) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(m3ptrconstructormodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "internal" + +%typemap(m3finalize) SWIGTYPE %{ + ~$1_basetype() { + Dispose(); + } +%} + +%typemap(m3destruct, methodname="Dispose") SWIGTYPE { + if(swigCPtr != IntPtr.Zero && swigCMemOwn) { + $imcall; + swigCMemOwn = false; + } + swigCPtr = IntPtr.Zero; + GC.SuppressFinalize(this); + } + +%typemap(m3destruct_derived, methodname="Dispose") SWIGTYPE { + if(swigCPtr != IntPtr.Zero && swigCMemOwn) { + $imcall; + swigCMemOwn = false; + } + swigCPtr = IntPtr.Zero; + GC.SuppressFinalize(this); + base.Dispose(); + } + +%typemap(m3getcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ + internal static IntPtr getCPtr($1_basetype obj) { + RETURN (obj == null) ? IntPtr.Zero : obj.swigCPtr; + } +%} + +/* M3 specific directives */ +#define %m3multiretval %feature("modula3:multiretval") +#define %constnumeric(num) %feature("constnumeric","num") + +%pragma(modula3) moduleimports=%{ +IMPORT BlaBla; +%} + +%pragma(modula3) imclassimports=%{ +FROM BlaBla IMPORT Bla; +%} + +/* Some ANSI C typemaps */ + +%apply long { size_t }; diff --git a/Lib/modula3/modula3head.swg b/Lib/modula3/modula3head.swg new file mode 100644 index 000000000..bb26ec5dc --- /dev/null +++ b/Lib/modula3/modula3head.swg @@ -0,0 +1,69 @@ +/* ----------------------------------------------------------------------------- + * modula3head.swg + * + * Modula3 support code + * ----------------------------------------------------------------------------- */ + +%insert(runtime) %{ + +#include +#include +#include +#ifdef WIN32 +# define DllExport __declspec( dllexport ) +#else +# define DllExport +#endif +%} + +#if 0 +%insert(runtime) %{ +/* Support for throwing Modula3 exceptions */ +typedef enum { + SWIG_JavaOutOfMemoryError = 1, + SWIG_JavaIOException, + SWIG_JavaRuntimeException, + SWIG_JavaIndexOutOfBoundsException, + SWIG_JavaArithmeticException, + SWIG_JavaIllegalArgumentException, + SWIG_JavaNullPointerException, + SWIG_JavaUnknownError +} SWIG_JavaExceptionCodes; + +typedef struct { + SWIG_JavaExceptionCodes code; + const char *java_exception; +} SWIG_JavaExceptions_t; + +#if defined(SWIG_NOINCLUDE) +void SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg); +#else +%} +%insert(runtime) { +void SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) { + jclass excep; + static const SWIG_JavaExceptions_t java_exceptions[] = { + { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" }, + { SWIG_JavaIOException, "java/io/IOException" }, + { SWIG_JavaRuntimeException, "java/lang/RuntimeException" }, + { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" }, + { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" }, + { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" }, + { SWIG_JavaNullPointerException, "java/lang/NullPointerException" }, + { SWIG_JavaUnknownError, "java/lang/UnknownError" }, + { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" } }; + const SWIG_JavaExceptions_t *except_ptr = java_exceptions; + + while (except_ptr->code != code && except_ptr->code) + except_ptr++; + + JCALL0(ExceptionClear, jenv); + excep = JCALL1(FindClass, jenv, except_ptr->java_exception); + if (excep) + JCALL2(ThrowNew, jenv, excep, msg); +} +} +%insert(runtime) %{ +#endif +%} +#endif diff --git a/Lib/modula3/typemaps.i b/Lib/modula3/typemaps.i new file mode 100644 index 000000000..2f7ded594 --- /dev/null +++ b/Lib/modula3/typemaps.i @@ -0,0 +1,66 @@ + +/* These typemaps will eventually probably maybe make their way into named typemaps + * OUTPUT * and OUTPUT & as they currently break functions that return a pointer or + * reference. */ + +%typemap(ctype) bool *, bool & "bool *" +%typemap(ctype) char & "char *" +%typemap(ctype) signed char *, signed char & "signed char *" +%typemap(ctype) unsigned char *, unsigned char & "unsigned short *" +%typemap(ctype) short *, short & "short *" +%typemap(ctype) unsigned short *, unsigned short & "unsigned short *" +%typemap(ctype) int *, int & "int *" +%typemap(ctype) unsigned int *, unsigned int & "unsigned int *" +%typemap(ctype) long *, long & "long *" +%typemap(ctype) unsigned long *, unsigned long & "unsigned long *" +%typemap(ctype) long long *, long long & "long long *" +%typemap(ctype) unsigned long long *, unsigned long long & "unsigned long long *" +%typemap(ctype) float *, float & "float *" +%typemap(ctype) double *, double & "double *" + +%typemap(imtype) bool *, bool & "ref bool" +%typemap(imtype) char & "ref char" +%typemap(imtype) signed char *, signed char & "ref sbyte" +%typemap(imtype) unsigned char *, unsigned char & "ref byte" +%typemap(imtype) short *, short & "ref short" +%typemap(imtype) unsigned short *, unsigned short & "ref ushort" +%typemap(imtype) int *, int & "ref int" +%typemap(imtype) unsigned int *, unsigned int & "ref uint" +%typemap(imtype) long *, long & "ref int" +%typemap(imtype) unsigned long *, unsigned long & "ref uint" +%typemap(imtype) long long *, long long & "ref long" +%typemap(imtype) unsigned long long *, unsigned long long & "ref ulong" +%typemap(imtype) float *, float & "ref float" +%typemap(imtype) double *, double & "ref double" + +%typemap(cstype) bool *, bool & "ref bool" +%typemap(cstype) char & "ref char" +%typemap(cstype) signed char *, signed char & "ref sbyte" +%typemap(cstype) unsigned char *, unsigned char & "ref byte" +%typemap(cstype) short *, short & "ref short" +%typemap(cstype) unsigned short *, unsigned short & "ref ushort" +%typemap(cstype) int *, int & "ref int" +%typemap(cstype) unsigned int *, unsigned int & "ref uint" +%typemap(cstype) long *, long & "ref int" +%typemap(cstype) unsigned long *, unsigned long & "ref uint" +%typemap(cstype) long long *, long long & "ref long" +%typemap(cstype) unsigned long long *, unsigned long long & "ref ulong" +%typemap(cstype) float *, float & "ref float" +%typemap(cstype) double *, double & "ref double" + +%typemap(csin) bool *, bool &, + char &, + signed char *, signed char &, + unsigned char *, unsigned char &, + short *, short &, + unsigned short *, unsigned short &, + int *, int &, + unsigned int *, unsigned int &, + long *, long &, + unsigned long *, unsigned long &, + long long *, long long &, + unsigned long long *, unsigned long long &, + float *, float &, + double *, double & + "ref $csinput" + diff --git a/Makefile.in b/Makefile.in index 205be569c..e2c629473 100644 --- a/Makefile.in +++ b/Makefile.in @@ -47,6 +47,7 @@ skip-ocaml = test -n "@SKIP_OCAML@" skip-pike = test -n "@SKIP_PIKE@" skip-chicken = test -n "@SKIP_CHICKEN@" skip-csharp = test -n "@SKIP_CSHARP@" +skip-modula3 = test -n "@SKIP_MODULA3@" ##################################################################### # CHECK @@ -78,6 +79,7 @@ check-aliveness: @$(skip-pike) || ./$(TARGET) -pike -help @$(skip-chicken) || ./$(TARGET) -chicken -help @$(skip-csharp) || ./$(TARGET) -csharp -help + @$(skip-modula3) || ./$(TARGET) -modula3 -help check-examples: \ check-tcl-examples \ @@ -91,7 +93,8 @@ check-examples: \ check-php4-examples \ check-pike-examples \ check-chicken-examples \ - check-csharp-examples + check-csharp-examples \ + check-modula3-examples check-%-examples: @passed=true; \ @@ -124,6 +127,7 @@ check-test-suite: \ check-php4-test-suite \ check-pike-test-suite \ check-csharp-test-suite \ + check-modula3-test-suite \ # check-chicken-test-suite check-%-test-suite: @@ -155,7 +159,8 @@ check-gifplot: \ check-php4-gifplot \ check-pike-gifplot \ check-chicken-gifplot \ -# check-csharp-gifplot +# check-csharp-gifplot \ +# check-modula3-gifplot check-%-gifplot: gifplot-library @passed=true; \ @@ -194,6 +199,7 @@ all-test-suite: \ all-php4-test-suite \ all-pike-test-suite \ all-csharp-test-suite \ + all-modula3-test-suite \ # all-chicken-test-suite all-%-test-suite: @@ -216,6 +222,7 @@ broken-test-suite: \ broken-php4-test-suite \ broken-pike-test-suite \ broken-csharp-test-suite \ + broken-modula3-test-suite \ # broken-chicken-test-suite broken-%-test-suite: @@ -327,7 +334,7 @@ install-main: @$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BIN_DIR)/$(TARGET) lib-languages = tcl perl5 python guile java mzscheme ruby php4 ocaml \ - pike chicken csharp + pike chicken csharp modula3 install-lib: @echo "Installing the SWIG library" diff --git a/Source/DOH/README b/Source/DOH/README index 18ef7da9c..1e948105c 100644 --- a/Source/DOH/README +++ b/Source/DOH/README @@ -39,9 +39,7 @@ Mapping Operations (for hash table behavior) Getattr(hash,key) Get an attribute Setattr(hash,key,value) Set an attribute Delattr(hash,key) Delete an attribute -Firstkey(hash) Get first key -Nextkey(hash) Get next key -First(hash) Get first object +First(hash) Get first object (iterator) Next(hash) Get next object GetInt(hash,key) Get attribute as an 'int' SetInt(hash,key,ivalue) Set attribute as an 'int' diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h index 33b764c1e..24dbec767 100644 --- a/Source/Include/swigwarn.h +++ b/Source/Include/swigwarn.h @@ -203,6 +203,20 @@ /* please leave 830-849 free for C# */ +#define WARN_MODULA3_TYPEMAP_TYPE_UNDEF 850 +#define WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF 851 +#define WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF 852 +#define WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF 853 +#define WARN_MODULA3_TYPEMAP_MULTIPLE_RETURN 854 +#define WARN_MODULA3_MULTIPLE_INHERITANCE 855 +#define WARN_MODULA3_TYPECONSTRUCTOR_UNKNOWN 856 +#define WARN_MODULA3_UNKNOWN_PRAGMA 857 +#define WARN_MODULA3_BAD_ENUMERATION 858 +#define WARN_MODULA3_DOUBLE_ID 859 +#define WARN_MODULA3_BAD_IMPORT 860 + +/* please leave 850-869 free for Modula 3 */ + /* Feel free to claim any number in this space that's not currently being used. Just make sure you diff --git a/Source/Makefile.am b/Source/Makefile.am index 1de835a03..6071b58ce 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -46,6 +46,7 @@ eswig_SOURCES = CParse/cscanner.c \ Modules/java.cxx \ Modules/lang.cxx \ Modules/main.cxx \ + Modules/modula3.cxx \ Modules/module.cxx \ Modules/mzscheme.cxx \ Modules/ocaml.cxx \ diff --git a/Source/Modules/modula3.cxx b/Source/Modules/modula3.cxx new file mode 100644 index 000000000..544979703 --- /dev/null +++ b/Source/Modules/modula3.cxx @@ -0,0 +1,4184 @@ +/* ----------------------------------------------------------------------------- + * modula3.cxx + * + * Modula3 wrapper module. + * + * Author(s) : Henning Thielemann + * + * Adapted from csharp.cxx + * ----------------------------------------------------------------------------- */ + +char cvsroot_modula3_cxx[] = + "$Header$"; + +/* + Text formatted with + indent -sob -br -ce -nut -npsl +*/ + + +/* + Report: + - It's not a good concept to use member variables or global variables + for passing parameters to functions. + It's not a good concept to use functions of superclasses for specific services. + E.g. For SWIG this means: Generating accessor functions for member variables + is the most common but no general task to be processed in membervariableHandler. + Better provide a service functions which generates accessor function code + and equip this service function with all parameters needed for input (parse node) + and output (generated code). + - How can I make globalvariableHandler not to generate + interface functions to two accessor functions + (that don't exist) + - How can I generate a typemap that turns every C reference argument into + its Modula 3 counterpart, that is + void test(Complex &z); + PROCEDURE test(VAR z:Complex); + - neither $*n_mangle nor $*n_type nor $*n_ltype return the type without + pointer converted to Modula3 equivalent, + $*n_mangle is the variant closest to what I expect + - using a typemap like + typemap(m3wrapintype) int * %{VAR $1_name: INTEGER%} + has the advantages: + - one C parameter can be turned into multiple M3 parameters + - the argument can be renamed + - using typemaps like + typemap(m3wrapinmode) int * "VAR" + typemap(m3wrapintype) int * "INTEGER" + has the advantages: + - multiple parameters with same type and default value can be bundled + - more conform to the other language modules + - Where takes the reduction of multi-typemaps place? + How can I preserve all parameters for functions of the intermediary class? + The answer is Getattrs(n,"tmap:m3rawintype:next") + - Char() can be used to transform a String to (char *) + which can be used for output with printf + - What is the while (checkAttribute()) loop in functionWrapper good for? + Appearently for skipping (numinputs=0) typemaps. + - SWIGTYPE const * - typemap is ignored, whereas + SWIGTYPE * - typemap is invoked, why? + Had it been (const SWIGTYPE *) instead? + - enumeration items should definitely be equipped + with its plain numerical value + One could add tag 'numvalue' in CParse/parser.y, + but it is still possible that someone declares an + enumeration using a symbolic constant. + I have quickly hacked + that the successive number is assigned + if "enumvalue" has suffix "+1". + The ultimate solution would be to generate a C program + which includes the header and outputs all constants. + This program might be compiled and run + by 'make' or by SWIG and the resulting output is fed back to SWIG. + - It's a bad idea to interpret feature value "" + 'disable feature' because the value "" + might be sensible in case of feature:modula3:oldprefix. + - What's the difference between "sym:name" and "name" ? + "name" is the original name and + "sym:name" is probably modified by the user using %rename + - Is it possible for 'configure' to find out if m3pp is installed + and to invoke it for generated Modula3 files? + - It would be better to separate an arguments purpose and its name, + because an output variable with name "OUTPUT" is not very descriptive. + In case of PLPlot this could be solved by typedefs + that assign special purposes to the array types. + - Can one interpret $n_basetype as the identifier matched with SWIGTYPE ? + + Swig's odds: + - arguments of type (Node *) for SWIG functions + should be most often better (const Node *): + Swig_symbol_qualified, Getattr, nodeType, parentNode + - unique identifier style instead of + NewString, Getattr, firstChild + - 'class'.name is qualified, + 'enum'.name and 'enumitem'.name is not + - Swig_symbol_qualified() returns NIL for enumeration nodes + + - Is there a function that creates a C representation of a SWIG type string? + + ToDo: + - clean typemap conception + - should a multi-typemap for m3wrapouttype skip the corresponding input parameters? + when yes - How to handle inout-arguments? In this case like in-argument. + - C++ classes + - C++ exceptions + - allow for moving RECORD and OBJECT definitions + to separate files, with the main type called T + - call-back functions + - special option: fast access to class members by pointer arithmetic, + member offsets can be determined by a C++ program that print them. + - emit enumeration definitions when its first item is declared, + currently enumerations are emitted at the beginning of the file + + Done: + - addThrow should convert the typemap by itself + - not possible because routine for attaching mapped types to parameter nodes + won't work for the function node + - turning error codes into exceptions + -> part of output value checking + - create WeakRefs for resources allocated by the library + -> part of output conversion + - TRY..FINALLY..END; can be omitted + - if there is no m3wrapfreearg + - no exception can be raised in the body (empty RAISES) list +*/ + +#include // for INT_MAX +#include "swigmod.h" +#ifndef MACSWIG +#include "swigconfig.h" +#endif +#include + +const char usageArgDir[] = + "m3wrapargdir typemap expect values: in, out, inout\n"; + +class MODULA3:public Language +{ + + enum block_type + { no_block, constant, variable, type, revelation }; + + struct M3File + { + String *f; + Hash *import; + block_type bt; + M3File ():f (NewString ("")), import (NewHash ()), bt (no_block) + { + }; + ~M3File () + { + Delete (f); + Delete (import); + }; + + /* ----------------------------------------------------------------------------- + * enterBlock() + * + * Make sure that a given declaration is written to the right declaration block, + * that is constants are written after "CONST" and so on ... + * ----------------------------------------------------------------------------- */ + void enterBlock (block_type newbt) + { + const static char *ident[] = + { "", "\nCONST\n", "\nVAR\n", "\nTYPE\n", "\nREVEAL\n" }; +#ifdef DEBUG + if ((bt < 0) || (4 < bt)) { + printf ("bt %d out of range\n", bt); + }; +#endif + if (newbt != bt) { + Append (f, ident[newbt]); + bt = newbt; + }; + }; + + }; + + static const char *usage; + const String *empty_string; + + Hash *swig_types_hash; + File *f_runtime; + File *f_header; + File *f_wrappers; + File *f_init; + + bool proxy_flag; // Flag for generating proxy classes + bool have_default_constructor_flag; + bool native_function_flag; // Flag for when wrapping a native function + bool enum_constant_flag; // Flag for when wrapping an enum or constant + bool static_flag; // Flag for when wrapping a static functions or member variables + bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable + bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const + bool global_variable_flag; // Flag for when wrapping a global variable + bool unsafe_module; + + String *m3raw_name; // raw interface name + M3File m3raw_intf; // raw interface + M3File m3raw_impl; // raw implementation (usually empty) + String *m3wrap_name; // wrapper module + M3File m3wrap_intf; + M3File m3wrap_impl; + String *m3makefile; + String *targetlibrary; + String *proxy_class_def; + String *proxy_class_code; + String *proxy_class_name; + String *variable_name; //Name of a variable being wrapped + String *variable_type; //Type of this variable + String *enumeration_name; //Name of the current enumeration type + Hash *enumeration_items; //and its members + int enumeration_max; + Hash *enumeration_coll; //Collection of all enumerations. + /* The items are nodes with members: + "items" - hash of with key 'itemname' and content 'itemvalue' + "max" - maximum value in item list + */ + String *constant_values; + String *constantfilename; + String *renamefilename; + String *typemapfilename; + String *m3raw_imports; //intermediary class imports from %pragma + String *module_imports; //module imports from %pragma + String *m3raw_baseclass; //inheritance for intermediary class class from %pragma + String *module_baseclass; //inheritance for module class from %pragma + String *m3raw_interfaces; //interfaces for intermediary class class from %pragma + String *module_interfaces; //interfaces for module class from %pragma + String *m3raw_class_modifiers; //class modifiers for intermediary class overriden by %pragma + String *m3wrap_modifiers; //class modifiers for module class overriden by %pragma + String *upcasts_code; //C++ casts for inheritance hierarchies C++ code + String *m3raw_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code + String *destructor_call; //C++ destructor call if any + String *outfile; + + enum type_additions + { none, pointer, reference }; + +public: + + /* ----------------------------------------------------------------------------- + * MODULA3() + * ----------------------------------------------------------------------------- */ + +MODULA3 (): + empty_string (NewString ("")), + swig_types_hash (NULL), + f_runtime (NULL), + f_header (NULL), + f_wrappers (NULL), + f_init (NULL), + proxy_flag (true), + have_default_constructor_flag (false), + native_function_flag (false), + enum_constant_flag (false), + static_flag (false), + variable_wrapper_flag (false), + wrapping_member_flag (false), + global_variable_flag (false), + unsafe_module (false), + m3raw_name (NULL), + m3raw_intf (), + m3raw_impl (), + m3wrap_name (NULL), + m3wrap_intf (), + m3wrap_impl (), + m3makefile (NULL), + targetlibrary (NULL), + proxy_class_def (NULL), + proxy_class_code (NULL), + proxy_class_name (NULL), + variable_name (NULL), + variable_type (NULL), + enumeration_name (NULL), + enumeration_items (NULL), + enumeration_max (0), + enumeration_coll (NULL), + constant_values (NULL), + constantfilename (NULL), + renamefilename (NULL), + typemapfilename (NULL), + m3raw_imports (NULL), + module_imports (NULL), + m3raw_baseclass (NULL), + module_baseclass (NULL), + m3raw_interfaces (NULL), + module_interfaces (NULL), + m3raw_class_modifiers (NULL), + m3wrap_modifiers (NULL), + upcasts_code (NULL), + m3raw_cppcasts_code (NULL), destructor_call (NULL), outfile (NULL) + { + } + + /************** some utility functions ***************/ + + /* ----------------------------------------------------------------------------- + * getMappedType() + * + * Return the type of 'p' mapped by 'map'. + * Print a standard warning if 'p' can't be mapped. + * ----------------------------------------------------------------------------- */ + + String *getMappedType (Node * p, const char *map) + { + String *mapattr = NewString ("tmap:"); + Append (mapattr, map); + + String *tm = Getattr (p, mapattr); + if (tm == NIL) { + Swig_warning (WARN_MODULA3_TYPEMAP_TYPE_UNDEF, input_file, line_number, + "No '%s' typemap defined for type '%s'\n", + map, SwigType_str (Getattr (p, "type"), 0)); + } + Delete (mapattr); + return tm; + } + + /* ----------------------------------------------------------------------------- + * getMappedTypeNew() + * + * Similar to getMappedType but uses Swig_type_lookup_new. + * ----------------------------------------------------------------------------- */ + + String *getMappedTypeNew (Node * n, const char *map, const char *lname = + "", bool warn = true) { + String *tm = Swig_typemap_lookup_new (map, n, lname, 0); + if ((tm == NIL) && warn) { + Swig_warning (WARN_MODULA3_TYPEMAP_TYPE_UNDEF, input_file, line_number, + "No '%s' typemap defined for type '%s'\n", + map, SwigType_str (Getattr (n, "type"), 0)); + } + return tm; + } + + /* ----------------------------------------------------------------------------- + * attachMappedType() + * + * Obtain the type mapped by 'map' and attach it to the node + * ----------------------------------------------------------------------------- */ + + void attachMappedType (Node * n, const char *map, const char *lname = "") { + String *tm = Swig_typemap_lookup_new (map, n, lname, 0); + if (tm != NIL) { + String *attr = NewStringf ("tmap:%s", map); + Setattr (n, attr, tm); + Delete (attr); + } + } + + /* ----------------------------------------------------------------------------- + * skipIgnored() + * + * Skip all parameters that have 'numinputs=0' + * with respect to a given typemap. + * ----------------------------------------------------------------------------- */ + + Node *skipIgnored (Node * p, const char *map) + { + String *niattr = NewStringf ("tmap:%s:numinputs", map); + String *nextattr = NewStringf ("tmap:%s:next", map); + + while ((p != NIL) && checkAttribute (p, niattr, "0")) { + p = Getattr (p, nextattr); + } + + Delete (nextattr); + Delete (niattr); + return p; + } + + /* ----------------------------------------------------------------------------- + * isInParam() + * isOutParam() + * + * Check if the parameter is intended for input or for output. + * ----------------------------------------------------------------------------- */ + + bool isInParam (Node * p) + { + String *dir = Getattr (p, "tmap:m3wrapargdir"); +//printf("dir for %s: %s\n", Char(Getattr(p,"name")), Char(dir)); + if ((dir == NIL) || (Strcmp (dir, "in") == 0) + || (Strcmp (dir, "inout") == 0)) { + return true; + } else if (Strcmp (dir, "out") == 0) { + return false; + } else { + printf (usageArgDir); + return false; + } + } + + bool isOutParam (Node * p) + { + String *dir = Getattr (p, "tmap:m3wrapargdir"); + if ((dir == NIL) || (Strcmp (dir, "in") == 0)) { + return false; + } else if ((Strcmp (dir, "out") == 0) || (Strcmp (dir, "inout") == 0)) { + return true; + } else { + printf (usageArgDir); + return false; + } + } + + /* ----------------------------------------------------------------------------- + * printAttrs() + * + * For debugging: Show all attributes of a node and their values. + * ----------------------------------------------------------------------------- */ + void printAttrs (Node * n) + { + Iterator it; + for (it = First (n); it.key != NIL; it = Next (it)) { + printf ("%s = %s\n", Char (it.key), Char (Getattr (n, it.key))); + } + } + + /* ----------------------------------------------------------------------------- + * hasPrefix() + * + * Check if a string have a given prefix. + * ----------------------------------------------------------------------------- */ + bool hasPrefix (const String * str, const String * prefix) + { + int len_prefix = Len (prefix); + return (Len (str) > len_prefix) + && (Strncmp (str, prefix, len_prefix) == 0); + } + + /* ----------------------------------------------------------------------------- + * getQualifiedName() + * + * Return fully qualified identifier of n. + * ----------------------------------------------------------------------------- */ +#if 0 + // Swig_symbol_qualified returns NIL for enumeration nodes + String *getQualifiedName (Node * n) + { + String *qual = Swig_symbol_qualified (n); + String *name = Getattr (n, "name"); + if (hasContent (qual)) { + return NewStringf ("%s::%s", qual, name); + } else { + return name; + } + } +#else + String *getQualifiedName (Node * n) + { + String *name = Copy (Getattr (n, "name")); + n = parentNode (n); + while (n != NIL) { + const String *type = nodeType (n); + if ((Strcmp (type, "class") == 0) || + (Strcmp (type, "struct") == 0) || + (Strcmp (type, "namespace") == 0)) { + String *newname = NewStringf ("%s::%s", Getattr (n, "name"), name); + Delete (name); + //name = newname; + // Hmpf, the class name is already qualified. + return newname; + } + n = parentNode (n); + } + //printf("qualified name: %s\n", Char(name)); + return name; + } +#endif + + /* ----------------------------------------------------------------------------- + * nameToModula3() + * + * Turn usual C identifiers like "this_is_an_identifier" + * into usual Modula 3 identifier like "thisIsAnIdentifier" + * ----------------------------------------------------------------------------- */ + String *nameToModula3 (const String * sym, bool leadingCap) + { + int len_sym = Len (sym); + char *csym = Char (sym); + char *m3sym = new char[len_sym + 1]; + int i, j; + bool cap = leadingCap; + for (i = 0, j = 0; j < len_sym; j++) { + char c = csym[j]; + if ((c == '_') || (c == ':')) { + cap = true; + } else { + if (cap) { + m3sym[i] = toupper (c); + } else { + m3sym[i] = tolower (c); + } + i++; + cap = false; + } + } + m3sym[i] = 0; + String *result = NewString (m3sym); + delete[]m3sym; + return result; + } + + /* ----------------------------------------------------------------------------- + * capitalizeFirst() + * + * Make the first character upper case. + * ----------------------------------------------------------------------------- */ + String *capitalizeFirst (const String * str) + { + return NewStringf ("%c%s", toupper (*Char (str)), Char (str) + 1); + } + + /* ----------------------------------------------------------------------------- + * prefixedNameToModula3() + * + * If feature modula3:oldprefix and modula3:newprefix is present + * and the C identifier has leading 'oldprefix' + * then it is replaced by the 'newprefix'. + * The rest is converted to Modula style. + * ----------------------------------------------------------------------------- */ + String *prefixedNameToModula3 (Node * n, const String * sym, + bool leadingCap) + { + String *oldPrefix = Getattr (n, "feature:modula3:oldprefix"); + String *newPrefix = Getattr (n, "feature:modula3:newprefix"); + String *result = NewString (""); + char *short_sym = Char (sym); + // if at least one prefix feature is present + // the replacement takes place + if ((oldPrefix != NIL) || (newPrefix != NIL)) { + if ((oldPrefix == NIL) || hasPrefix (sym, oldPrefix)) { + short_sym += Len (oldPrefix); + if (newPrefix != NIL) { + Append (result, newPrefix); + } + } + } + String *suffix = nameToModula3 (short_sym, leadingCap + || hasContent (newPrefix)); + Append (result, suffix); + Delete (suffix); + return result; + } + + /* ----------------------------------------------------------------------------- + * hasContent() + * + * Check if the string exists and contains something. + * ----------------------------------------------------------------------------- */ + bool hasContent (const String * str) + { + return (str != NIL) && (Strcmp (str, "") != 0); + } + + /* ----------------------------------------------------------------------------- + * openWriteFile() + * + * Caution: The file must be freshly allocated and will be destroyed + * by this routine. + * ----------------------------------------------------------------------------- */ + + File *openWriteFile (String * name) + { + File *file = NewFile (name, "w"); + if (file == NIL) { + Printf (stderr, "Unable to open <%s> for writing.\n", name); + SWIG_exit (EXIT_FAILURE); + } + Delete (name); + return file; + } + + /* ----------------------------------------------------------------------------- + * aToL() + * + * like atol but with additional user warning + * ----------------------------------------------------------------------------- */ + + long aToL (const String * value) + { + char *endptr; + long numvalue = strtol (Char (value), &endptr, 0); + if (*endptr != 0) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, + "The string <%s> does not denote a numeric value.\n", + value); + } + return numvalue; + } + + /* ----------------------------------------------------------------------------- + * strToL() + * + * like strtol but returns if the conversion was successful + * ----------------------------------------------------------------------------- */ + + bool strToL (const String * value, long &numvalue) + { + char *endptr; + numvalue = strtol (Char (value), &endptr, 0); + return (*endptr == 0); + } + + /* ----------------------------------------------------------------------------- + * evalExpr() + * + * Evaluate simple expression as they may occur in "enumvalue" attributes. + * ----------------------------------------------------------------------------- */ + + bool evalExpr (String * value, long &numvalue) + { + // Split changes file status of String and thus cannot receive 'const' strings +//printf("evaluate <%s>\n", Char(value)); + List *summands = Split (value, '+', INT_MAX); + Iterator sm = First (summands); + numvalue = 0; + for (; sm.item != NIL; sm = Next (sm)) { + String *smvalue = Getattr (constant_values, sm.item); + long smnumvalue; + if (smvalue != NIL) { + if (!strToL (smvalue, smnumvalue)) { +//printf("evaluation: abort 0 <%s>\n", Char(smvalue)); + return false; + } + } else { + if (!strToL (sm.item, smnumvalue)) { +//printf("evaluation: abort 1 <%s>\n", Char(sm)); + return false; + } + } + numvalue += smnumvalue; + } +//printf("evaluation: return %ld\n", numvalue); + return true; + } + + /* ----------------------------------------------------------------------------- + * log2() + * + * Determine the position of the single bit of a power of two. + * Returns true if the given number is a power of two. + * ----------------------------------------------------------------------------- */ + + bool log2 (long n, long &exp) + { + exp = 0; + while (n > 0) { + if ((n & 1) != 0) { + return n == 1; + } + exp++; + n >>= 1; + } + return false; + } + + /* ----------------------------------------------------------------------------- + * writeArg + * + * Write a function argument or RECORD entry definition. + * Bundles arguments of same type and default value. + * 'name.next==NIL' denotes the end of the entry or argument list. + * ----------------------------------------------------------------------------- */ + + bool equalNilStr (const String * str0, const String * str1) + { + if (str0 == NIL) { + return (str1 == NIL); + //return (str0==NIL) == (str1==NIL); + } else { + return (str1 != NIL) && (Cmp (str0, str1) == 0); + //return Cmp(str0,str1)==0; + } + } + + struct writeArgState + { + String *mode, *name, *type, *value; + bool hold; + writeArgState ():mode (NIL), name (NIL), type (NIL), value (NIL), + hold (false) + { + }; + }; + + void writeArg (File * f, writeArgState & state, + String * mode, String * name, String * type, String * value) + { + /* skip the first argument, + only store the information for the next call in this case */ + if (state.name != NIL) { + if ((!state.hold) && (state.mode != NIL)) { + Printf (f, "%s ", state.mode); + } + if ((name != NIL) && + equalNilStr (state.mode, mode) && + equalNilStr (state.type, type) && + (state.value == NIL) && (value == NIL) + /* the same expression may have different values + due to side effects of the called function */ + /*equalNilStr(state.value,value) */ + ) { + Printf (f, "%s, ", state.name); + state.hold = true; + } else { + Append (f, state.name); + if (state.type != NIL) { + Printf (f, ": %s", state.type); + } + if (state.value != NIL) { + Printf (f, ":= %s", state.value); + } + Append (f, ";\n"); + state.hold = false; + } + } + /* at the next call the current argument will be the previous one */ + state.mode = mode; + state.name = name; + state.type = type; + state.value = value; + } + + /* ----------------------------------------------------------------------------- + * getProxyName() + * + * Test to see if a type corresponds to something wrapped with a proxy class + * Return NULL if not otherwise the proxy class name + * ----------------------------------------------------------------------------- */ + + String *getProxyName (SwigType * t) + { + if (proxy_flag) { + Node *n = classLookup (t); + if (n) { + return Getattr (n, "sym:name"); + } + } + return NULL; + } + + /*************** language processing ********************/ + + /* ------------------------------------------------------------ + * main() + * ------------------------------------------------------------ */ + + virtual void main (int argc, char *argv[]) + { + + SWIG_library_directory ("modula3"); + + // Look for certain command line options + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp (argv[i], "-generateconst") == 0) { + if (argv[i + 1]) { + constantfilename = NewString (argv[i + 1]); + Swig_mark_arg (i); + Swig_mark_arg (i + 1); + i++; + } else { + Swig_arg_error (); + } + } else if (strcmp (argv[i], "-generaterename") == 0) { + if (argv[i + 1]) { + renamefilename = NewString (argv[i + 1]); + Swig_mark_arg (i); + Swig_mark_arg (i + 1); + i++; + } else { + Swig_arg_error (); + } + } else if (strcmp (argv[i], "-generatetypemap") == 0) { + if (argv[i + 1]) { + typemapfilename = NewString (argv[i + 1]); + Swig_mark_arg (i); + Swig_mark_arg (i + 1); + i++; + } else { + Swig_arg_error (); + } + } else if (strcmp (argv[i], "-noproxy") == 0) { + Swig_mark_arg (i); + proxy_flag = false; + } else if (strcmp (argv[i], "-help") == 0) { + Printf (stderr, "%s\n", usage); + } + } + } + + // Add a symbol to the parser for conditional compilation + Preprocessor_define ("SWIGMODULA3 1", 0); + + // Add typemap definitions + SWIG_typemap_lang ("modula3"); + SWIG_config_file ("modula3.swg"); + + allow_overloading (); + } + + /* --------------------------------------------------------------------- + * top() + * --------------------------------------------------------------------- */ + + virtual int top (Node * n) + { + if (hasContent (constantfilename) || + hasContent (renamefilename) || hasContent (typemapfilename)) { + int result = SWIG_OK; + if (hasContent (constantfilename)) { + result = generateConstantTop (n) && result; + } + if (hasContent (renamefilename)) { + result = generateRenameTop (n) && result; + } + if (hasContent (typemapfilename)) { + result = generateTypemapTop (n) && result; + } + return result; + } else { + return generateM3Top (n); + } + } + + void scanConstant (File * file, Node * n) + { + Node *child = firstChild (n); + while (child != NIL) { + String *constname = NIL; + String *type = nodeType (child); + if ((Strcmp (type, "enumitem") == 0) + || (Strcmp (type, "constant") == 0)) { +#if 1 + constname = getQualifiedName (child); +#else + constname = Getattr (child, "value"); + if ((!hasContent (constname)) + || (('0' <= *Char (constname)) && (*Char (constname) <= '9'))) { + constname = Getattr (child, "name"); + } +#endif + } + if (constname != NIL) { + Printf (file, + " printf(\"%%%%constnumeric(%%Lg) %s;\\n\", (long double)%s);\n", + constname, constname); + } + scanConstant (file, child); + child = nextSibling (child); + } + } + + int generateConstantTop (Node * n) + { + File *file = openWriteFile (NewStringf ("%s.c", constantfilename)); + if (CPlusPlus) { + Printf (file, "#include \n"); + } else { + Printf (file, "#include \n"); + } + Printf (file, "#include \"%s\"\n", input_file); + Printf (file, "\n"); + Printf (file, "int main (int argc, char *argv[]) {\n"); + Printf (file, "\ +/*This progam must work for floating point numbers and integers.\n\ + Thus all numbers are converted to double precision floating point format.*/\n"); + scanConstant (file, n); + Printf (file, " return 0;\n"); + Printf (file, "}\n"); + Close (file); + return SWIG_OK; + } + + void scanRename (File * file, Node * n) + { + Node *child = firstChild (n); + while (child != NIL) { + String *type = nodeType (child); + if (Strcmp (type, "cdecl") == 0) { + ParmList *p = Getattr (child, "parms"); + if (p != NIL) { + String *name = getQualifiedName (child); + String *m3name = nameToModula3 (name, true); + /*don't know how to get the original C type identifiers */ + String *arguments = createCSignature (child); + Printf (file, "%%rename(\"%s\") %s;\n", m3name, name); + /*Printf(file, "%%rename(\"%s\") %s %s(%s);\n", + m3name, Getattr(n,"type"), name, arguments); */ + Delete (name); + Delete (m3name); + Delete (arguments); + } + } + scanRename (file, child); + child = nextSibling (child); + } + } + + int generateRenameTop (Node * n) + { + File *file = openWriteFile (NewStringf ("%s.i", renamefilename)); + Printf (file, "\ +/* This file was generated from %s\n\ + by SWIG with option -generaterename. */\n\ +\n", input_file); + scanRename (file, n); + Close (file); + return SWIG_OK; + } + + void scanTypemap (File * file, Node * n) + { + Node *child = firstChild (n); + while (child != NIL) { + String *type = nodeType (child); + //printf("nodetype %s\n", Char(type)); + String *storage = Getattr (child, "storage"); + if ((Strcmp (type, "class") == 0) || + ((Strcmp (type, "cdecl") == 0) && (storage != NIL) + && (Strcmp (storage, "typedef") == 0))) { + String *name = getQualifiedName (child); + String *m3name = nameToModula3 (name, true); + Printf (file, "%%typemap(\"m3wrapintype\") %s %%{%s%%}\n", name, + m3name); + Printf (file, "%%typemap(\"m3rawintype\") %s %%{%s%%}\n", name, + m3name); + Printf (file, "\n"); + } + scanTypemap (file, child); + child = nextSibling (child); + } + } + + int generateTypemapTop (Node * n) + { + File *file = openWriteFile (NewStringf ("%s.i", typemapfilename)); + Printf (file, "\ +/* This file was generated from %s\n\ + by SWIG with option -generatetypemap. */\n\ +\n", input_file); + scanTypemap (file, n); + Close (file); + return SWIG_OK; + } + + int generateM3Top (Node * n) + { + /* Initialize all of the output files */ + outfile = Getattr (n, "outfile"); + + f_runtime = NewFile (outfile, "w"); + if (!f_runtime) { + Printf (stderr, "Unable to open %s\n", outfile); + SWIG_exit (EXIT_FAILURE); + } + f_init = NewString (""); + f_header = NewString (""); + f_wrappers = NewString (""); + + m3makefile = NewString (""); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname ("header", f_header); + Swig_register_filebyname ("wrapper", f_wrappers); + Swig_register_filebyname ("runtime", f_runtime); + Swig_register_filebyname ("init", f_init); + + Swig_register_filebyname ("m3rawintf", m3raw_intf.f); + Swig_register_filebyname ("m3rawimpl", m3raw_impl.f); + Swig_register_filebyname ("m3wrapintf", m3wrap_intf.f); + Swig_register_filebyname ("m3wrapimpl", m3wrap_impl.f); + Swig_register_filebyname ("m3makefile", m3makefile); + + swig_types_hash = NewHash (); + + String *name = Getattr (n, "name"); + // Make the intermediary class and module class names. The intermediary class name can be set in the module directive. + Node *optionsnode = Getattr (Getattr (n, "module"), "options"); + if (optionsnode != NIL) { + String *m3raw_name_tmp = Getattr (optionsnode, "m3rawname"); + if (m3raw_name_tmp != NIL) { + m3raw_name = Copy (m3raw_name_tmp); + } + } + if (m3raw_name == NIL) { + m3raw_name = NewStringf ("%sRaw", name); + } + Setattr (m3wrap_impl.import, m3raw_name, ""); + + m3wrap_name = Copy (name); + + proxy_class_def = NewString (""); + proxy_class_code = NewString (""); + m3raw_baseclass = NewString (""); + m3raw_interfaces = NewString (""); + m3raw_class_modifiers = NewString (""); // package access only to the intermediary class by default + m3raw_imports = NewString (""); + m3raw_cppcasts_code = NewString (""); + m3wrap_modifiers = NewString ("public"); + module_baseclass = NewString (""); + module_interfaces = NewString (""); + module_imports = NewString (""); + upcasts_code = NewString (""); + + Swig_banner (f_runtime); // Print the SWIG banner message + + if (NoInclude) { + Printf (f_runtime, "#define SWIG_NOINCLUDE\n"); + } + + String *wrapper_name = NewString (""); + + Printf (wrapper_name, "Modula3_%%f", m3raw_name); + Swig_name_register ((char *) "wrapper", Char (wrapper_name)); + Swig_name_register ((char *) "set", (char *) "set_%v"); + Swig_name_register ((char *) "get", (char *) "get_%v"); + Swig_name_register ((char *) "member", (char *) "%c_%m"); + + Delete (wrapper_name); + + Printf (f_wrappers, "\n#ifdef __cplusplus\n"); + Printf (f_wrappers, "extern \"C\" {\n"); + Printf (f_wrappers, "#endif\n\n"); + + constant_values = NewHash (); + scanForConstPragmas (n); + enumeration_coll = NewHash (); + collectEnumerations (enumeration_coll, n); + + /* Emit code */ + Language::top (n); + + // Generate m3makefile + // This will be unnecessary if SWIG is invoked from Quake. + { + File *file = + openWriteFile (NewStringf + ("%sm3makefile", Swig_file_dirname (outfile))); + + Printf (file, "%% automatically generated quake file for %s\n\n", name); + + /* Write the fragments written by '%insert' + collected while 'top' processed the parse tree */ + Printv (file, m3makefile, NIL); + + Printf (file, "import(\"libm3\")\n"); + //Printf(file, "import_lib(\"%s\",\"/usr/lib\")\n", name); + Printf (file, "module(\"%s\")\n", m3raw_name); + Printf (file, "module(\"%s\")\n\n", m3wrap_name); + + if (targetlibrary != NIL) { + Printf (file, "library(\"%s\")\n", targetlibrary); + } else { + Printf (file, "library(\"m3%s\")\n", name); + } + Close (file); + } + + // Generate the raw interface + { + File *file = + openWriteFile (NewStringf + ("%s%s.i3", Swig_file_dirname (outfile), m3raw_name)); + + emitBanner (file); + + Printf (file, "INTERFACE %s;\n\n", m3raw_name); + + emitImportStatements (m3raw_intf.import, file); + Printf (file, "\n"); + + // Write the interface generated within 'top' + Printv (file, m3raw_intf.f, NIL); + + Printf (file, "\nEND %s.\n", m3raw_name); + Close (file); + } + + // Generate the raw module + { + File *file = + openWriteFile (NewStringf + ("%s%s.m3", Swig_file_dirname (outfile), m3raw_name)); + + emitBanner (file); + + Printf (file, "MODULE %s;\n\n", m3raw_name); + + emitImportStatements (m3raw_impl.import, file); + Printf (file, "\n"); + + // will be empty usually + Printv (file, m3raw_impl.f, NIL); + + Printf (file, "BEGIN\nEND %s.\n", m3raw_name); + Close (file); + } + + // Generate the interface for the comfort wrappers + { + File *file = + openWriteFile (NewStringf + ("%s%s.i3", Swig_file_dirname (outfile), m3wrap_name)); + + emitBanner (file); + + Printf (file, "INTERFACE %s;\n", m3wrap_name); + + emitImportStatements (m3wrap_intf.import, file); + Printf (file, "\n"); + + { + Iterator it = First (enumeration_coll); + if (it.key != NIL) { + Printf (file, "TYPE\n"); + } + for (; it.key != NIL; it = Next (it)) { + Printf (file, "\n"); + emitEnumeration (file, it.key, it.item); + } + } + + // Add the wrapper methods + Printv (file, m3wrap_intf.f, NIL); + + // Finish off the class + Printf (file, "\nEND %s.\n", m3wrap_name); + Close (file); + } + + // Generate the wrapper routines implemented in Modula 3 + { + File *file = + openWriteFile (NewStringf + ("%s%s.m3", Swig_file_dirname (outfile), m3wrap_name)); + + emitBanner (file); + + if (unsafe_module) { + Printf (file, "UNSAFE "); + } + Printf (file, "MODULE %s;\n\n", m3wrap_name); + + emitImportStatements (m3wrap_impl.import, file); + Printf (file, "\n"); + + // Add the wrapper methods + Printv (file, m3wrap_impl.f, NIL); + + Printf (file, "\nBEGIN\nEND %s.\n", m3wrap_name); + Close (file); + } + + if (upcasts_code) + Printv (f_wrappers, upcasts_code, NIL); + + Printf (f_wrappers, "#ifdef __cplusplus\n"); + Printf (f_wrappers, "}\n"); + Printf (f_wrappers, "#endif\n"); + + // Output a Modula 3 type wrapper class for each SWIG type + for (Iterator swig_type = First (swig_types_hash); swig_type.item != NIL; + swig_type = Next (swig_type)) { + emitTypeWrapperClass (swig_type.key, swig_type.item); + } + + Delete (swig_types_hash); + swig_types_hash = NULL; + Delete (constant_values); + constant_values = NULL; + Delete (enumeration_coll); + enumeration_coll = NULL; + Delete (m3raw_name); + m3raw_name = NULL; + Delete (m3raw_baseclass); + m3raw_baseclass = NULL; + Delete (m3raw_interfaces); + m3raw_interfaces = NULL; + Delete (m3raw_class_modifiers); + m3raw_class_modifiers = NULL; + Delete (m3raw_imports); + m3raw_imports = NULL; + Delete (m3raw_cppcasts_code); + m3raw_cppcasts_code = NULL; + Delete (proxy_class_def); + proxy_class_def = NULL; + Delete (proxy_class_code); + proxy_class_code = NULL; + Delete (m3wrap_name); + m3wrap_name = NULL; + Delete (m3wrap_modifiers); + m3wrap_modifiers = NULL; + Delete (targetlibrary); + targetlibrary = NULL; + Delete (module_baseclass); + module_baseclass = NULL; + Delete (module_interfaces); + module_interfaces = NULL; + Delete (module_imports); + module_imports = NULL; + Delete (upcasts_code); + upcasts_code = NULL; + Delete (constantfilename); + constantfilename = NULL; + Delete (renamefilename); + renamefilename = NULL; + Delete (typemapfilename); + typemapfilename = NULL; + + /* Close all of the files */ + Dump (f_header, f_runtime); + Dump (f_wrappers, f_runtime); + Wrapper_pretty_print (f_init, f_runtime); + Delete (f_header); + Delete (f_wrappers); + Delete (f_init); + Close (f_runtime); + Delete (f_runtime); + return SWIG_OK; + } + + /* ----------------------------------------------------------------------------- + * emitBanner() + * ----------------------------------------------------------------------------- */ + + void emitBanner (File * f) + { + Printf (f, "\ +(*******************************************************************************\n\ + * This file was automatically generated by SWIG (http://www.swig.org/).\n\ + * Version: %s\n\ + *\n\ + * Do not make changes to this file unless you know what you are doing --\n\ + * modify the SWIG interface file instead.\n\ + *******************************************************************************)\n\n", PACKAGE_VERSION); + } + + /* ---------------------------------------------------------------------- + * nativeWrapper() + * ---------------------------------------------------------------------- */ + + virtual int nativeWrapper (Node * n) + { + String *wrapname = Getattr (n, "wrap:name"); + + if (!addSymbol (wrapname, n)) + return SWIG_ERROR; + + if (Getattr (n, "type")) { + Swig_save ("nativeWrapper", n, "name", NIL); + Setattr (n, "name", wrapname); + native_function_flag = true; + functionWrapper (n); + Swig_restore (n); + native_function_flag = false; + } else { + Printf (stderr, + "%s : Line %d. No return type for %%native method %s.\n", + input_file, line_number, Getattr (n, "wrap:name")); + } + + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * functionWrapper() + * ---------------------------------------------------------------------- */ + + virtual int functionWrapper (Node * n) + { + String *type = nodeType (n); + String *funcType = Getattr (n, "modula3:functype"); + String *rawname = Getattr (n, "name"); + String *symname = Getattr (n, "sym:name"); + String *capname = capitalizeFirst (symname); + //String *wname = Swig_name_wrapper(symname); + + //printf("function: %s\n", Char(symname)); + //printf(" purpose: %s\n", Char(funcType)); + + if (Strcmp (type, "cdecl") == 0) { + if (funcType == NIL) { + // no wrapper needed for plain functions + emitM3RawPrototype (n, rawname, symname); + emitM3Wrapper (n, symname); + } else if (Strcmp (funcType, "method") == 0) { + Setattr (n, "modula3:funcname", capname); + emitCWrapper (n, capname); + emitM3RawPrototype (n, capname, capname); + emitM3Wrapper (n, capname); + } else if (Strcmp (funcType, "accessor") == 0) { + /* + * Generate the proxy class properties for public member variables. + * Not for enums and constants. + */ + if (proxy_flag && wrapping_member_flag && !enum_constant_flag) { + // Capitalize the first letter in the function name + Setattr (n, "proxyfuncname", capname); + Setattr (n, "imfuncname", symname); + if (hasPrefix (capname, "Set")) { + Setattr (n, "modula3:setname", capname); + } else { + Setattr (n, "modula3:getname", capname); + } + + emitCWrapper (n, capname); + emitM3RawPrototype (n, capname, capname); + emitM3Wrapper (n, capname); + //proxyClassFunctionHandler(n); + } +#ifdef DEBUG + } else { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, + "Function type <%s> unknown.\n", Char (funcType)); +#endif + } + } else if ((Strcmp (type, "constructor") == 0) || + (Strcmp (type, "destructor") == 0)) { + emitCWrapper (n, capname); + emitM3RawPrototype (n, capname, capname); + emitM3Wrapper (n, capname); + } +// a Java relict +#if 0 + if (!(proxy_flag && is_wrapping_class ()) && !enum_constant_flag) { + emitM3Wrapper (n, capname); + } +#endif + + Delete (capname); + + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * emitCWrapper() + * + * Generate the wrapper in C which calls C++ methods. + * ---------------------------------------------------------------------- */ + + virtual int emitCWrapper (Node * n, const String * wname) + { + String *rawname = Getattr (n, "name"); + String *c_return_type = NewString (""); + String *cleanup = NewString (""); + String *outarg = NewString (""); + String *body = NewString (""); + Hash *throws_hash = NewHash (); + ParmList *l = Getattr (n, "parms"); + SwigType *t = Getattr (n, "type"); + + if (!Getattr (n, "sym:overloaded")) { + if (!addSymbol (wname, n)) { + return SWIG_ERROR; + } + } + // A new wrapper function object + Wrapper *f = NewWrapper (); + + /* Attach the non-standard typemaps to the parameter list. */ + Swig_typemap_attach_parms ("ctype", l, f); + + /* Get return types */ + { + String *tm = getMappedTypeNew (n, "ctype", ""); + if (tm != NIL) { + Printf (c_return_type, "%s", tm); + } + } + + bool is_void_return = (Cmp (c_return_type, "void") == 0); + if (!is_void_return) { + Wrapper_add_localv (f, "cresult", c_return_type, "cresult = 0", NIL); + } + + Printv (f->def, " DllExport ", c_return_type, " ", wname, "(", NIL); + + // Emit all of the local variables for holding arguments. + emit_args (t, l, f); + + /* Attach the standard typemaps */ + emit_attach_parmmaps (l, f); + Setattr (n, "wrap:parms", l); + + // Generate signature and argument conversion for C wrapper + { + Parm *p; + attachParameterNames (n, "tmap:name", "c:wrapname", "m3arg%d"); + bool gencomma = false; + for (p = skipIgnored (l, "in"); p != NULL; p = skipIgnored (p, "in")) { + + String *arg = Getattr (p, "c:wrapname"); + { + /* Get the ctype types of the parameter */ + String *c_param_type = getMappedType (p, "ctype"); + // Add parameter to C function + Printv (f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL); + Delete (c_param_type); + gencomma = true; + } + + // Get typemap for this argument + String *tm = getMappedType (p, "in"); + if (tm != NIL) { + addThrows (throws_hash, "in", p); + Replaceall (tm, "$input", arg); + Setattr (p, "emit:input", arg); /*??? */ + Printf (f->code, "%s\n", tm); + p = Getattr (p, "tmap:in:next"); + } else { + p = nextSibling (p); + } + } + } + + /* Insert constraint checking code */ + { + Parm *p; + for (p = l; p;) { + String *tm = Getattr (p, "tmap:check"); + if (tm != NIL) { + addThrows (throws_hash, "check", p); + Replaceall (tm, "$target", Getattr (p, "lname")); /* deprecated */ + Replaceall (tm, "$arg", Getattr (p, "emit:input")); /* deprecated? */ + Replaceall (tm, "$input", Getattr (p, "emit:input")); + Printv (f->code, tm, "\n", NIL); + p = Getattr (p, "tmap:check:next"); + } else { + p = nextSibling (p); + } + } + } + + /* Insert cleanup code */ + { + Parm *p; + for (p = l; p;) { + String *tm = Getattr (p, "tmap:freearg"); + if (tm != NIL) { + addThrows (throws_hash, "freearg", p); + Replaceall (tm, "$source", Getattr (p, "emit:input")); /* deprecated */ + Replaceall (tm, "$arg", Getattr (p, "emit:input")); /* deprecated? */ + Replaceall (tm, "$input", Getattr (p, "emit:input")); + Printv (cleanup, tm, "\n", NIL); + p = Getattr (p, "tmap:freearg:next"); + } else { + p = nextSibling (p); + } + } + } + + /* Insert argument output code */ + { + Parm *p; + for (p = l; p;) { + String *tm = Getattr (p, "tmap:argout"); + if (tm != NIL) { + addThrows (throws_hash, "argout", p); + Replaceall (tm, "$source", Getattr (p, "emit:input")); /* deprecated */ + Replaceall (tm, "$target", Getattr (p, "lname")); /* deprecated */ + Replaceall (tm, "$arg", Getattr (p, "emit:input")); /* deprecated? */ + Replaceall (tm, "$result", "cresult"); + Replaceall (tm, "$input", Getattr (p, "emit:input")); + Printv (outarg, tm, "\n", NIL); + p = Getattr (p, "tmap:argout:next"); + } else { + p = nextSibling (p); + } + } + } + + // Get any Modula 3 exception classes in the throws typemap + ParmList *throw_parm_list = NULL; + if ((throw_parm_list = Getattr (n, "throws"))) { + Swig_typemap_attach_parms ("throws", throw_parm_list, f); + Parm *p; + for (p = throw_parm_list; p; p = nextSibling (p)) { + addThrows (throws_hash, "throws", p); + } + } + + if (Cmp (nodeType (n), "constant") == 0) { + // Wrapping a constant hack + Swig_save ("functionWrapper", n, "wrap:action", NIL); + + // below based on Swig_VargetToFunction() + SwigType *ty = Swig_wrapped_var_type (Getattr (n, "type")); + Setattr (n, "wrap:action", + NewStringf ("result = (%s) %s;\n", SwigType_lstr (ty, 0), + Getattr (n, "value"))); + } + // Now write code to make the function call + if (!native_function_flag) { + emit_action (n, f); + } + + if (Cmp (nodeType (n), "constant") == 0) { + Swig_restore (n); + } + + /* Return value if necessary */ + if (!native_function_flag) { + String *tm = getMappedTypeNew (n, "out", "result"); + if (tm != NIL) { + addThrows (throws_hash, "out", n); + Replaceall (tm, "$source", "result"); /* deprecated */ + Replaceall (tm, "$target", "cresult"); /* deprecated */ + Replaceall (tm, "$result", "cresult"); + Printf (f->code, "%s", tm); + if (hasContent (tm)) + Printf (f->code, "\n"); + } else { + Swig_warning (WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, + "Unable to use return type %s in function %s.\n", + SwigType_str (t, 0), rawname); + } + } + + /* Output argument output code */ + Printv (f->code, outarg, NIL); + + /* Output cleanup code */ + Printv (f->code, cleanup, NIL); + + /* Look to see if there is any newfree cleanup code */ + if (Getattr (n, "feature:new")) { + String *tm = Swig_typemap_lookup_new ("newfree", n, "result", 0); + if (tm != NIL) { + addThrows (throws_hash, "newfree", n); + Replaceall (tm, "$source", "result"); /* deprecated */ + Printf (f->code, "%s\n", tm); + } + } + + /* See if there is any return cleanup code */ + if (!native_function_flag) { + String *tm = Swig_typemap_lookup_new ("ret", n, "result", 0); + if (tm != NIL) { + Replaceall (tm, "$source", "result"); /* deprecated */ + Printf (f->code, "%s\n", tm); + } + } + + /* Finish C wrapper */ + Printf (f->def, ") {"); + + if (!is_void_return) + Printv (f->code, " return cresult;\n", NIL); + Printf (f->code, "}\n"); + + /* Substitute the cleanup code */ + Replaceall (f->code, "$cleanup", cleanup); + + if (!is_void_return) { + Replaceall (f->code, "$null", "0"); + } else { + Replaceall (f->code, "$null", ""); + } + + /* Dump the function out */ + if (!native_function_flag) { + Wrapper_print (f, f_wrappers); + } + + Setattr (n, "wrap:name", wname); + + Delete (c_return_type); + Delete (cleanup); + Delete (outarg); + Delete (body); + Delete (throws_hash); + DelWrapper (f); + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * emitM3RawPrototype() + * + * Generate an EXTERNAL procedure declaration in Modula 3 + * which is the interface to an existing C routine or a C wrapper. + * ---------------------------------------------------------------------- */ + + virtual int emitM3RawPrototype (Node * n, const String * cname, + const String * m3name) + { + String *im_return_type = NewString (""); + //String *symname = Getattr(n,"sym:name"); + ParmList *l = Getattr (n, "parms"); + + /* Attach the non-standard typemaps to the parameter list. */ + Swig_typemap_attach_parms ("m3rawinmode", l, NULL); + Swig_typemap_attach_parms ("m3rawintype", l, NULL); + + /* Get return types */ + bool has_return; + { + String *tm = getMappedTypeNew (n, "m3rawrettype", ""); + if (tm != NIL) { + Printf (im_return_type, "%s", tm); + } + has_return = hasContent (tm); + } + + /* cname is the original name if 'n' denotes a C function + and it is the relabeled name (sym:name) if 'n' denotes a C++ method or similar */ + m3raw_intf.enterBlock (no_block); + Printf (m3raw_intf.f, "\n<* EXTERNAL %s *>\nPROCEDURE %s (", + cname, m3name); + + // Generate signature for raw interface + { + Parm *p; + writeArgState state; + attachParameterNames (n, "tmap:rawinname", "modula3:rawname", "arg%d"); + for (p = skipIgnored (l, "m3rawintype"); p != NULL; + p = skipIgnored (p, "m3rawintype")) { + + /* Get argument passing mode, should be one of VALUE, VAR, READONLY */ + String *mode = Getattr (p, "tmap:m3rawinmode"); + String *argname = Getattr (p, "modula3:rawname"); + String *im_param_type = getMappedType (p, "m3rawintype"); + addImports (m3raw_intf.import, "m3rawintype", p); + + writeArg (m3raw_intf.f, state, mode, argname, im_param_type, NIL); + if (im_param_type != NIL) { + p = Getattr (p, "tmap:m3rawintype:next"); + } else { + p = nextSibling (p); + } + } + writeArg (m3raw_intf.f, state, NIL, NIL, NIL, NIL); + } + + /* Finish M3 raw prototype */ + Printf (m3raw_intf.f, ")"); + // neither a C wrapper nor a plain C function may throw an exception + //generateThrowsClause(throws_hash, m3raw_intf.f); + if (has_return) { + Printf (m3raw_intf.f, ": %s", im_return_type); + } + Printf (m3raw_intf.f, ";\n"); + + Delete (im_return_type); + return SWIG_OK; + } + + /* ----------------------------------------------------------------------- + * variableWrapper() + * ----------------------------------------------------------------------- */ + + virtual int variableWrapper (Node * n) + { + Language::variableWrapper (n); + return SWIG_OK; + } + + /* ----------------------------------------------------------------------- + * globalvariableHandler() + * ----------------------------------------------------------------------- */ + + virtual int globalvariableHandler (Node * n) + { + SwigType *t = Getattr (n, "type"); + String *tm; + + // Get the variable type + if ((tm = getMappedTypeNew (n, "m3wraptype", ""))) { + substituteClassname (t, tm); + } + + variable_name = Getattr (n, "sym:name"); + variable_type = Copy (tm); + + // Get the variable type expressed in terms of Modula 3 equivalents of C types + if ((tm = getMappedTypeNew (n, "m3rawtype", ""))) { + m3raw_intf.enterBlock (no_block); + Printf (m3raw_intf.f, "\n<* EXTERNAL *> VAR %s: %s;\n", variable_name, + tm); + } + // Output the property's accessor methods + /* + global_variable_flag = true; + int ret = Language::globalvariableHandler(n); + global_variable_flag = false; + */ + + Printf (m3wrap_impl.f, "\n\n"); + + //return ret; + return 1; + } + + long getConstNumeric (Node * n) + { + String *constnumeric = Getfeature (n, "constnumeric"); + String *name = Getattr (n, "name"); + long numvalue; + if (constnumeric == NIL) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, + "Feature 'constnumeric' is necessary to obtain value of %s.\n", + name); + return 0; + } else if (!strToL (constnumeric, numvalue)) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, + "The feature 'constnumeric' of %s specifies value <%s> which is not an integer constant.\n", + name, constnumeric); + return 0; + } else { + return numvalue; + } + } + + /* ------------------------------------------------------------------------ + * generateIntConstant() + * + * Considers node as an integer constant definition + * and generate a Modula 3 constant definition. + * ------------------------------------------------------------------------ */ + void generateIntConstant (Node * n, String * name) + { + String *value = Getattr (n, "value"); + String *type = Getfeature (n, "modula3:constint:type"); + String *conv = Getfeature (n, "modula3:constint:conv"); + + if (name == NIL) { + name = Getattr (n, "sym:name"); + } + + long numvalue; + bool isSimpleNum = strToL (value, numvalue); + if (!isSimpleNum) { + numvalue = getConstNumeric (n); + } + + String *m3value; + if ((conv == NIL) || + ((Strcmp (conv, "set:int") != 0) && + (Strcmp (conv, "int:set") != 0))) { + /* The original value of the constant has precedence over + 'constnumeric' feature since we like to keep + the style (that is the base) of simple numeric constants */ + if (isSimpleNum) { + if (hasPrefix (value, "0x")) { + m3value = NewStringf ("16_%s", Char (value) + 2); + } else if ((Len (value) > 1) && (*Char (value) == '0')) { + m3value = NewStringf ("8_%s", Char (value) + 1); + } else { + m3value = Copy (value); + } + /* If we cannot easily obtain the value of a numeric constant, + we use the results given by a C compiler. */ + } else { + m3value = Copy (Getfeature (n, "constnumeric")); + } + } else { + // if the value can't be converted, it is ignored + if (convertInt (numvalue, numvalue, conv)) { + m3value = NewStringf ("%d", numvalue); + } else { + m3value = NIL; + } + } + + if (m3value != NIL) { + m3wrap_intf.enterBlock (constant); + Printf (m3wrap_intf.f, "%s", name); + if (hasContent (type)) { + Printf (m3wrap_intf.f, ": %s", type); + } + Printf (m3wrap_intf.f, " = %s;\n", m3value); + Delete (m3value); + } + } + + /* ----------------------------------------------------------------------- + * generateSetConstant() + * + * Considers node as a set constant definition + * and generate a Modula 3 constant definition. + * ------------------------------------------------------------------------ */ + void generateSetConstant (Node * n, String * name) + { + String *value = Getattr (n, "value"); + String *type = Getfeature (n, "modula3:constset:type"); + String *setname = Getfeature (n, "modula3:constset:set"); + String *basename = Getfeature (n, "modula3:constset:base"); + String *conv = Getfeature (n, "modula3:constset:conv"); + + m3wrap_intf.enterBlock (constant); + + Printf (m3wrap_intf.f, "%s", name); + if (type != NIL) { + Printf (m3wrap_intf.f, ":%s ", type); + } + Printf (m3wrap_intf.f, " = %s{", setname); + + long numvalue = 0; + if (!strToL (value, numvalue)) { + numvalue = getConstNumeric (n); + } + convertInt (numvalue, numvalue, conv); + + bool isIntType = Strcmp (basename, "CARDINAL") == 0; + Hash *items = NIL; + if (!isIntType) { + Hash *enumeration = Getattr (enumeration_coll, basename); + if (enumeration == NIL) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, + "There is no enumeration <%s> as needed for the set.\n", + setname); + isIntType = true; + } else { + items = Getattr (enumeration, "items"); + } + } + + bool gencomma = false; + int bitpos = 0; + while (numvalue > 0) { + if ((numvalue & 1) != 0) { + if (isIntType) { + if (gencomma) { + Printv (m3wrap_intf.f, ",", NIL); + } + gencomma = true; + Printf (m3wrap_intf.f, "%d", bitpos); + } else { + char bitval[15]; + sprintf (bitval, "%d", bitpos); + String *bitname = Getattr (items, bitval); + if (bitname == NIL) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, + line_number, + "Enumeration <%s> has no value <%s>.\n", setname, + bitval); + } else { + if (gencomma) { + Printv (m3wrap_intf.f, ",", NIL); + } + gencomma = true; + Printf (m3wrap_intf.f, "%s.%s", basename, bitname); + } + } + } + numvalue >>= 1; + bitpos++; + } + Printf (m3wrap_intf.f, "};\n"); + } + + void generateConstant (Node * n) + { + // any of the special interpretation disables the default behaviour + String *enumitem = Getfeature (n, "modula3:enumitem:name"); + String *constset = Getfeature (n, "modula3:constset:name"); + String *constint = Getfeature (n, "modula3:constint:name"); + if (hasContent (enumitem) || + hasContent (constset) || hasContent (constint)) { + if (hasContent (constset)) { + generateSetConstant (n, constset); + } + if (hasContent (constint)) { + generateIntConstant (n, constint); + } + } else { + String *value = Getattr (n, "value"); + String *name = Getattr (n, "sym:name"); + if (name == NIL) { + name = Getattr (n, "name"); + } + m3wrap_intf.enterBlock (constant); + Printf (m3wrap_intf.f, "%s = %s;\n", name, value); + } + } + +#if 0 + void generateEnumerationItem (const String * name, const String * value, + int numvalue) + { + String *oldsymname = Getattr (enumeration_items, value); + if (oldsymname != NIL) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, + "The value <%s> is already assigned to <%s>.\n", value, + oldsymname); + } + Setattr (enumeration_items, value, name); + if (enumeration_max < numvalue) { + enumeration_max = numvalue; + } + } +#endif + + void emitEnumeration (File * file, String * name, Node * n) + { + Printf (file, "%s = {", name); + int i; + bool gencomma = false; + int max = aToL (Getattr (n, "max")); + Hash *items = Getattr (n, "items"); + for (i = 0; i <= max; i++) { + if (gencomma) { + Printf (file, ","); + } + Printf (file, "\n"); + gencomma = true; + char numstr[15]; + sprintf (numstr, "%d", i); + String *name = Getattr (items, numstr); + if (name != NIL) { + Printv (file, name, NIL); + } else { + Printf (file, "dummy%d", i); + } + } + Printf (file, "\n};\n"); + } + + /* ----------------------------------------------------------------------- + * constantWrapper() + * + * Handles constants and enumeration items. + * ------------------------------------------------------------------------ */ + + virtual int constantWrapper (Node * n) + { + generateConstant (n); + return SWIG_OK; + } + +#if 0 +// enumerations are handled like constant definitions + /* ----------------------------------------------------------------------------- + * enumDeclaration() + * ----------------------------------------------------------------------------- */ + + virtual int enumDeclaration (Node * n) + { + String *symname = nameToModula3 (Getattr (n, "sym:name"), true); + enumerationStart (symname); + int result = Language::enumDeclaration (n); + enumerationStop (); + Delete (symname); + return result; + } +#endif + + /* ----------------------------------------------------------------------------- + * enumvalueDeclaration() + * ----------------------------------------------------------------------------- */ + + virtual int enumvalueDeclaration (Node * n) + { + generateConstant (n); + /* + This call would continue processing in the constantWrapper + which cannot handle values like "RED+1". + return Language::enumvalueDeclaration(n); + */ + return SWIG_OK; + } + + /* ----------------------------------------------------------------------------- + * pragmaDirective() + * + * Valid Pragmas: + * imclassbase - base (extends) for the intermediary class + * imclassclassmodifiers - class modifiers for the intermediary class + * imclasscode - text (Modula 3 code) is copied verbatim to the intermediary class + * imclassimports - import statements for the intermediary class + * imclassinterfaces - interface (implements) for the intermediary class + * + * modulebase - base (extends) for the module class + * moduleclassmodifiers - class modifiers for the module class + * modulecode - text (Modula 3 code) is copied verbatim to the module class + * moduleimports - import statements for the module class + * moduleinterfaces - interface (implements) for the module class + * + * ----------------------------------------------------------------------------- */ + + virtual int pragmaDirective (Node * n) + { + if (!ImportMode) { + String *lang = Getattr (n, "lang"); + String *code = Getattr (n, "name"); + String *value = Getattr (n, "value"); + + if (Strcmp (lang, "modula3") == 0) { + + String *strvalue = NewString (value); + Replaceall (strvalue, "\\\"", "\""); +/* + bool isEnumItem = Strcmp(code, "enumitem") == 0; + bool isSetItem = Strcmp(code, "setitem") == 0; +*/ + if (Strcmp (code, "imclassbase") == 0) { + Delete (m3raw_baseclass); + m3raw_baseclass = Copy (strvalue); + } else if (Strcmp (code, "imclassclassmodifiers") == 0) { + Delete (m3raw_class_modifiers); + m3raw_class_modifiers = Copy (strvalue); + } else if (Strcmp (code, "imclasscode") == 0) { + Printf (m3raw_intf.f, "%s\n", strvalue); + } else if (Strcmp (code, "imclassimports") == 0) { + Delete (m3raw_imports); + m3raw_imports = Copy (strvalue); + } else if (Strcmp (code, "imclassinterfaces") == 0) { + Delete (m3raw_interfaces); + m3raw_interfaces = Copy (strvalue); + } else if (Strcmp (code, "modulebase") == 0) { + Delete (module_baseclass); + module_baseclass = Copy (strvalue); + } else if (Strcmp (code, "moduleclassmodifiers") == 0) { + Delete (m3wrap_modifiers); + m3wrap_modifiers = Copy (strvalue); + } else if (Strcmp (code, "modulecode") == 0) { + Printf (m3wrap_impl.f, "%s\n", strvalue); + } else if (Strcmp (code, "moduleimports") == 0) { + Delete (module_imports); + module_imports = Copy (strvalue); + } else if (Strcmp (code, "moduleinterfaces") == 0) { + Delete (module_interfaces); + module_interfaces = Copy (strvalue); + } else if (Strcmp (code, "unsafe") == 0) { + unsafe_module = true; + } else if (Strcmp (code, "library") == 0) { + if (targetlibrary != NULL) { + Delete (targetlibrary); + } + targetlibrary = Copy (strvalue); + } else if (Strcmp (code, "enumitem") == 0) { + } else if (Strcmp (code, "constset") == 0) { + } else if (Strcmp (code, "constint") == 0) { + } else if (Strcmp (code, "makesetofenum") == 0) { + m3wrap_intf.enterBlock (type); + Printf (m3wrap_intf.f, "%sSet = SET OF %s;\n", value, value); + } else { + Swig_warning (WARN_MODULA3_UNKNOWN_PRAGMA, input_file, line_number, + "Unrecognized pragma <%s>.\n", code); + } + Delete (strvalue); + } + } + return Language::pragmaDirective (n); + } + + void Setfeature (Node * n, const char *feature, const String * value, + bool warn = false) { + //printf("tag feature <%s> with value <%s>\n", feature, Char(value)); + String *attr = NewStringf ("feature:%s", feature); + if ((Setattr (n, attr, value) != 0) && warn) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, + "Feature <%s> of %s did already exist.\n", feature, + Getattr (n, "name")); + } + Delete (attr); + } + + String *Getfeature (Node * n, const char *feature) + { + //printf("retrieve feature <%s> with value <%s>\n", feature, Char(value)); + String *attr = NewStringf ("feature:%s", feature); + String *result = Getattr (n, attr); + Delete (attr); + return result; + } + + bool convertInt (long in, long &out, const String * mode) + { + if ((mode == NIL) || + (Strcmp (mode, "int:int") == 0) || (Strcmp (mode, "set:set") == 0)) { + out = in; + return true; + } else if (Strcmp (mode, "set:int") == 0) { + return log2 (in, out); + } else if (Strcmp (mode, "int:set") == 0) { + out = 1L << in; + return unsigned (in) < (sizeof (out) * 8); + } else { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, + "Unknown integer conversion method <%s>.\n", mode); + return false; + } + } + + void collectEnumerations (Hash * enums, Node * n) + { + Node *child = firstChild (n); + while (child != NIL) { + String *name = Getattr (child, "name"); + const bool isConstant = Strcmp (nodeType (child), "constant") == 0; + const bool isEnumItem = Strcmp (nodeType (child), "enumitem") == 0; + if (isConstant || isEnumItem) { +//printf("%s%s name %s\n", isConstant?"constant":"", isEnumItem?"enumitem":"", Char(name)); + { + String *m3name = Getfeature (child, "modula3:enumitem:name"); + String *m3enum = Getfeature (child, "modula3:enumitem:enum"); + String *conv = Getfeature (child, "modula3:enumitem:conv"); + + if (m3enum != NIL) { +//printf("m3enum %s\n", Char(m3enum)); + if (m3name == NIL) { + m3name = name; + } + + long max = -1; + Hash *items; + Hash *enumnode = Getattr (enums, m3enum); + if (enumnode == NIL) { + enumnode = NewHash (); + items = NewHash (); + Setattr (enumnode, "items", items); + Setattr (enums, m3enum, enumnode); + } else { + String *maxstr = Getattr (enumnode, "max"); + if (maxstr != NIL) { + max = aToL (maxstr); + } + items = Getattr (enumnode, "items"); + } + long numvalue; + String *value = Getattr (child, "value"); +//printf("value: %s\n", Char(value)); + if ((value == NIL) || (!strToL (value, numvalue))) { + value = Getattr (child, "enumvalue"); + if ((value == NIL) || (!evalExpr (value, numvalue))) { + numvalue = getConstNumeric (child); + } +//printf("constnumeric: %s\n", Char(value)); + } + Setattr (constant_values, name, NewStringf ("%d", numvalue)); + if (convertInt (numvalue, numvalue, conv)) { + String *newvalue = NewStringf ("%d", numvalue); + String *oldname = Getattr (items, newvalue); + if (oldname != NIL) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, + line_number, + "The value <%s> is already assigned to <%s>.\n", + value, oldname); + } +//printf("items %lx, set %s = %s\n", (long) items, Char(newvalue), Char(m3name)); + Setattr (items, newvalue, m3name); + if (max < numvalue) { + max = numvalue; + } + Setattr (enumnode, "max", NewStringf ("%d", max)); + } + } + } + } + + collectEnumerations (enums, child); + child = nextSibling (child); + } + } + + enum const_pragma_type + { cpt_none, cpt_constint, cpt_constset, cpt_enumitem }; + + struct const_id_pattern + { + String *prefix, *parentEnum; + }; + + void tagConstants (Node * first, String * parentEnum, + const const_id_pattern & pat, const String * pragma, + List * convdesc) + { + Node *n = first; + while (n != NIL) { + String *name = getQualifiedName (n); + bool isConstant = Strcmp (nodeType (n), "constant") == 0; + bool isEnumItem = Strcmp (nodeType (n), "enumitem") == 0; + if ((isConstant || isEnumItem) && + ((pat.prefix == NIL) || (hasPrefix (name, pat.prefix))) && + ((pat.parentEnum == NIL) || + ((parentEnum != NIL) + && (Strcmp (pat.parentEnum, parentEnum) == 0)))) { + //printf("tag %s\n", Char(name)); + String *srctype = Getitem (convdesc, 1); + String *relationstr = Getitem (convdesc, 3); + List *relationdesc = Split (relationstr, ',', 2); + + // transform name from C to Modula3 style + String *srcstyle = NIL; + String *newprefix = NIL; + { + //printf("name conversion <%s>\n", Char(Getitem(convdesc,2))); + List *namedesc = Split (Getitem (convdesc, 2), ',', INT_MAX); + Iterator nameit = First (namedesc); + for (; nameit.item != NIL; nameit = Next (nameit)) { + List *nameassign = Split (nameit.item, '=', 2); + String *tag = Getitem (nameassign, 0); + String *data = Getitem (nameassign, 1); + //printf("name conv <%s> = <%s>\n", Char(tag), Char(data)); + if (Strcmp (tag, "srcstyle") == 0) { + srcstyle = Copy (data); + } else if (Strcmp (tag, "prefix") == 0) { + newprefix = Copy (data); + } else { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, + line_number, + "Unknown name conversion tag <%s> with value <%s>.\n", + tag, data); + } + Delete (nameassign); + }; + Delete (namedesc); + } + const char *stem = Char (name); + if (pat.prefix != NIL) { + //printf("pat.prefix %s for %s\n", Char(pat.prefix), Char(name)); + stem += Len (pat.prefix); + } + String *newname; + if (Strcmp (srcstyle, "underscore") == 0) { + if (newprefix != NIL) { + String *newstem = nameToModula3 (stem, true); + newname = NewStringf ("%s%s", newprefix, newstem); + Delete (newstem); + } else { + newname = nameToModula3 (stem, false); + } + } else { + if (srcstyle != NIL) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, + line_number, "Unknown C identifier style <%s>.\n", + srcstyle); + } + newname = Copy (name); + } + + if (Strcmp (pragma, "enumitem") == 0) { + if (Len (relationdesc) != 1) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, + line_number, "Expected , got <%s>.\n", + relationstr); + } + Setfeature (n, "modula3:enumitem:name", newname, true); + Setfeature (n, "modula3:enumitem:enum", relationstr, true); + Setfeature (n, "modula3:enumitem:conv", + NewStringf ("%s:int", srctype), true); + } else if (Strcmp (pragma, "constint") == 0) { + if (Len (relationdesc) != 1) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, + line_number, "Expected , got <%s>.\n", + relationstr); + } + Setfeature (n, "modula3:constint:name", newname, true); + Setfeature (n, "modula3:constint:type", Getitem (relationdesc, 0), + true); + Setfeature (n, "modula3:constint:conv", + NewStringf ("%s:int", srctype), true); + } else if (Strcmp (pragma, "constset") == 0) { + if (Len (relationdesc) != 2) { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, + line_number, + "Expected , got <%s>.\n", + relationstr); + } + String *settype = Getitem (relationdesc, 0); + Setfeature (n, "modula3:constset:name", newname, true); + //Setfeature(n,"modula3:constset:type",settype,true); + Setfeature (n, "modula3:constset:set", settype, true); + Setfeature (n, "modula3:constset:base", Getitem (relationdesc, 1), + true); + Setfeature (n, "modula3:constset:conv", + NewStringf ("%s:set", srctype), true); + } + + Delete (newname); + Delete (relationdesc); + } + + if (Strcmp (nodeType (n), "enum") == 0) { + //printf("explore enum %s, qualification %s\n", Char(name), Char(Swig_symbol_qualified(n))); + tagConstants (firstChild (n), name, pat, pragma, convdesc); + } else { + tagConstants (firstChild (n), NIL, pat, pragma, convdesc); + } + n = nextSibling (n); + } + } + + void scanForConstPragmas (Node * n) + { + Node *child = firstChild (n); + while (child != NIL) { + const String *type = nodeType (child); + if (Strcmp (type, "pragma") == 0) { + const String *lang = Getattr (child, "lang"); + const String *code = Getattr (child, "name"); + String *value = Getattr (child, "value"); + + if (Strcmp (lang, "modula3") == 0) { + const_pragma_type cpt = cpt_none; + if (Strcmp (code, "constint") == 0) { + cpt = cpt_constint; + } else if (Strcmp (code, "constset") == 0) { + cpt = cpt_constset; + } else if (Strcmp (code, "enumitem") == 0) { + cpt = cpt_enumitem; + } + if (cpt != cpt_none) { + const_id_pattern pat = { NIL, NIL }; + + List *convdesc = Split (value, ';', 4); + List *patterndesc = Split (Getitem (convdesc, 0), ',', INT_MAX); + Iterator patternit; + for (patternit = First (patterndesc); patternit.item != NIL; + patternit = Next (patternit)) { + String *patternassign = Split (patternit.item, '=', 2); + String *tag = Getitem (patternassign, 0); + String *data = Getitem (patternassign, 1); + if (Strcmp (tag, "prefix") == 0) { + pat.prefix = Copy (data); + } else if (Strcmp (tag, "enum") == 0) { + pat.parentEnum = Copy (data); + } else { + Swig_warning (WARN_MODULA3_BAD_ENUMERATION, input_file, + line_number, + "Unknown identification tag <%s> with value <%s>.\n", + tag, data); + } + Delete (patternassign); + } + tagConstants (child, NIL, pat, code, convdesc); + + Delete (patterndesc); + } + } + } + scanForConstPragmas (child); + child = nextSibling (child); + } + } + + /* ----------------------------------------------------------------------------- + * emitProxyClassDefAndCPPCasts() + * ----------------------------------------------------------------------------- */ + + void emitProxyClassDefAndCPPCasts (Node * n) + { + String *c_classname = SwigType_namestr (Getattr (n, "name")); + String *c_baseclass = NULL; + String *baseclass = NULL; + String *c_baseclassname = NULL; + String *classDeclarationName = Getattr (n, "classDeclaration:name"); + + /* Deal with inheritance */ + List *baselist = Getattr (n, "bases"); + if (baselist != NIL) { + Iterator base = First (baselist); + c_baseclassname = Getattr (base.item, "name"); + baseclass = Copy (getProxyName (c_baseclassname)); + if (baseclass) { + c_baseclass = SwigType_namestr (Getattr (base.item, "name")); + } + base = Next (base); + if (base.item != NIL) { + Swig_warning (WARN_MODULA3_MULTIPLE_INHERITANCE, input_file, + line_number, + "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", + classDeclarationName, Getattr (base.item, "name")); + } + } + + bool derived = baseclass && getProxyName (c_baseclassname); + if (!baseclass) + baseclass = NewString (""); + + // Inheritance from pure Modula 3 classes + const String *pure_baseclass = + typemapLookup ("m3base", classDeclarationName, WARN_NONE); + if (hasContent (pure_baseclass) && hasContent (baseclass)) { + Swig_warning (WARN_MODULA3_MULTIPLE_INHERITANCE, input_file, + line_number, + "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", + classDeclarationName, pure_baseclass); + } + // Pure Modula 3 interfaces + const String *pure_interfaces = + typemapLookup (derived ? "m3interfaces_derived" : "m3interfaces", + classDeclarationName, WARN_NONE); + + // Start writing the proxy class + Printv (proxy_class_def, typemapLookup ("m3imports", classDeclarationName, WARN_NONE), // Import statements + "\n", typemapLookup ("m3classmodifiers", classDeclarationName, WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers + " class $m3classname", // Class name and bases + (derived || *Char (pure_baseclass) || *Char (pure_interfaces)) ? " : " : "", baseclass, pure_baseclass, ((derived || *Char (pure_baseclass)) && *Char (pure_interfaces)) ? // Interfaces + ", " : "", pure_interfaces, " {\n", " private IntPtr swigCPtr;\n", // Member variables for memory handling + derived ? "" : " protected bool swigCMemOwn;\n", "\n", " ", typemapLookup ("m3ptrconstructormodifiers", classDeclarationName, WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers + " $m3classname(IntPtr cPtr, bool cMemoryOwn) ", // Constructor used for wrapping pointers + derived ? + ": base($imclassname.$m3classnameTo$baseclass(cPtr), cMemoryOwn) {\n" + : "{\n swigCMemOwn = cMemoryOwn;\n", " swigCPtr = cPtr;\n", + " }\n", NIL); + + if (!have_default_constructor_flag) { // All proxy classes need a constructor + Printv (proxy_class_def, + "\n", + " protected $m3classname() : this(IntPtr.Zero, false) {\n", + " }\n", NIL); + } + // C++ destructor is wrapped by the Dispose method + // Note that the method name is specified in a typemap attribute called methodname + String *destruct = NewString (""); + const String *tm = NULL; + Node *attributes = NewHash (); + String *destruct_methodname = NULL; + if (derived) { + tm = + typemapLookup ("m3destruct_derived", classDeclarationName, WARN_NONE, + attributes); + destruct_methodname = + Getattr (attributes, "tmap:m3destruct_derived:methodname"); + } else { + tm = + typemapLookup ("m3destruct", classDeclarationName, WARN_NONE, + attributes); + destruct_methodname = + Getattr (attributes, "tmap:m3destruct:methodname"); + } + if (!destruct_methodname) { + Swig_error (input_file, line_number, + "No methodname attribute defined in m3destruct%s typemap for %s\n", + (derived ? "_derived" : ""), proxy_class_name); + } + // Emit the Finalize and Dispose methods + if (tm) { + // Finalize method + if (*Char (destructor_call)) { + Printv (proxy_class_def, + typemapLookup ("m3finalize", classDeclarationName, WARN_NONE), + NIL); + } + // Dispose method + Printv (destruct, tm, NIL); + if (*Char (destructor_call)) + Replaceall (destruct, "$imcall", destructor_call); + else + Replaceall (destruct, "$imcall", + "throw new MethodAccessException(\"C++ destructor does not have public access\")"); + if (*Char (destruct)) + Printv (proxy_class_def, "\n public ", + derived ? "override" : "virtual", " void ", + destruct_methodname, "() ", destruct, "\n", NIL); + } + Delete (attributes); + Delete (destruct); + + // Emit various other methods + Printv (proxy_class_def, typemapLookup ("m3getcptr", classDeclarationName, WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF), // getCPtr method + typemapLookup ("m3code", classDeclarationName, WARN_NONE), // extra Modula 3 code + "\n", NIL); + + // Substitute various strings into the above template + Replaceall (proxy_class_def, "$m3classname", proxy_class_name); + Replaceall (proxy_class_code, "$m3classname", proxy_class_name); + + Replaceall (proxy_class_def, "$baseclass", baseclass); + Replaceall (proxy_class_code, "$baseclass", baseclass); + + Replaceall (proxy_class_def, "$imclassname", m3raw_name); + Replaceall (proxy_class_code, "$imclassname", m3raw_name); + + // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) + if (derived) { + Printv (m3raw_cppcasts_code, "\n [DllImport(\"", m3wrap_name, + "\", EntryPoint=\"Modula3_", proxy_class_name, "To", baseclass, + "\")]\n", NIL); + Printv (m3raw_cppcasts_code, " public static extern IntPtr ", + "$m3classnameTo$baseclass(IntPtr objectRef);\n", NIL); + + Replaceall (m3raw_cppcasts_code, "$m3classname", proxy_class_name); + Replaceall (m3raw_cppcasts_code, "$baseclass", baseclass); + + Printv (upcasts_code, + "DllExport long Modula3_$imclazznameTo$imbaseclass", + "(long objectRef) {\n", + " long baseptr = 0;\n" + " *($cbaseclass **)&baseptr = *($cclass **)&objectRef;\n" + " return baseptr;\n" "}\n", "\n", NIL); + + Replaceall (upcasts_code, "$imbaseclass", baseclass); + Replaceall (upcasts_code, "$cbaseclass", c_baseclass); + Replaceall (upcasts_code, "$imclazzname", proxy_class_name); + Replaceall (upcasts_code, "$cclass", c_classname); + } + Delete (baseclass); + } + + /* ---------------------------------------------------------------------- + * getAttrString() + * + * If necessary create and return the string + * associated with a certain attribute of 'n'. + * ---------------------------------------------------------------------- */ + + String *getAttrString (Node * n, const char *attr) + { + String *str = Getattr (n, attr); + if (str == NIL) { + str = NewString (""); + Setattr (n, attr, str); + } + return str; + } + + /* ---------------------------------------------------------------------- + * getMethodDeclarations() + * + * If necessary create and return the handle + * where the methods of the current access can be written to. + * 'n' must be a member of a struct or a class. + * ---------------------------------------------------------------------- */ + + String *getMethodDeclarations (Node * n) + { + String *acc_str = Getattr (n, "access"); + String *methodattr; + if (acc_str == NIL) { + methodattr = NewString ("modula3:method:public"); + } else { + methodattr = NewStringf ("modula3:method:%s", acc_str); + } + String *methods = getAttrString (parentNode (n), Char (methodattr)); + Delete (methodattr); + return methods; + } + + /* ---------------------------------------------------------------------- + * classHandler() + * ---------------------------------------------------------------------- */ + + virtual int classHandler (Node * n) + { + + File *f_proxy = NULL; + proxy_class_name = Copy (Getattr (n, "sym:name")); + //String *rawname = Getattr(n,"name"); + + if (proxy_flag) { + if (!addSymbol (proxy_class_name, n)) + return SWIG_ERROR; + + if (Cmp (proxy_class_name, m3raw_name) == 0) { + Printf (stderr, + "Class name cannot be equal to intermediary class name: %s\n", + proxy_class_name); + SWIG_exit (EXIT_FAILURE); + } + + if (Cmp (proxy_class_name, m3wrap_name) == 0) { + Printf (stderr, + "Class name cannot be equal to module class name: %s\n", + proxy_class_name); + SWIG_exit (EXIT_FAILURE); + } + + String *filen = + NewStringf ("%s%s.m3", Swig_file_dirname (outfile), proxy_class_name); + f_proxy = NewFile (filen, "w"); + if (!f_proxy) { + Printf (stderr, "Unable to create proxy class file: %s\n", filen); + SWIG_exit (EXIT_FAILURE); + } + Delete (filen); + filen = NULL; + + emitBanner (f_proxy); + + Clear (proxy_class_def); + Clear (proxy_class_code); + + have_default_constructor_flag = false; + destructor_call = NewString (""); + } + + /* This will invoke memberfunctionHandler, membervariableHandler ... + and finally it may invoke functionWrapper + for wrappers and member variable accessors. + It will invoke Language:constructorDeclaration + which decides whether to call MODULA3::constructorHandler */ + Language::classHandler (n); + + { + String *kind = Getattr (n, "kind"); + if (Cmp (kind, "struct") == 0) { + String *entries = NewString (""); + Node *child; + writeArgState state; + for (child = firstChild (n); child != NIL; + child = nextSibling (child)) { + String *childType = nodeType (child); + if (Strcmp (childType, "cdecl") == 0) { + String *member = Getattr (child, "sym:name"); + ParmList *pl = Getattr (child, "parms"); + if (pl == NIL) { + // Get the variable type in Modula 3 type equivalents + String *m3ct = getMappedTypeNew (child, "m3rawtype", ""); + + writeArg (entries, state, NIL, member, m3ct, NIL); + } + } + } + writeArg (entries, state, NIL, NIL, NIL, NIL); + + m3raw_intf.enterBlock (type); + Printf (m3raw_intf.f, "%s =\nRECORD\n%sEND;\n", proxy_class_name, + entries); + + Delete (entries); + + } else if (Cmp (kind, "class") == 0) { + enum access_privilege + { acc_public, acc_protected, acc_private }; + access_privilege max_acc = acc_public; + + const char *acc_name[3] = { "public", "protected", "private" }; + String *methods[3]; + access_privilege acc; + for (acc = acc_public; acc <= acc_private; int (acc)++) { + String *methodattr = + NewStringf ("modula3:method:%s", acc_name[acc]); + methods[acc] = Getattr (n, methodattr); + Delete (methodattr); + max_acc = max_acc > acc ? max_acc : acc; + } + + /* Determine the name of the base class */ + String *baseclassname = NewString (""); + { + List *baselist = Getattr (n, "bases"); + if (baselist) { + /* Look for the first (principal?) base class - + Modula 3 does not support multiple inheritance */ + Iterator base = First (baselist); + Append (baseclassname, Getattr (base.item, "sym:name")); + base = Next (base); + if (base.item != NIL) { + Swig_warning (WARN_MODULA3_MULTIPLE_INHERITANCE, input_file, + line_number, + "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Modula 3.\n", + proxy_class_name, Getattr (base.item, "name")); + } + } + } + + /* the private class of the base class and only this + need a pointer to the C++ object */ + bool need_private = !hasContent (baseclassname); + max_acc = need_private ? acc_private : max_acc; + + /* Declare C++ object as abstract pointer in Modula 3 */ + /* The revelation system does not allow us + to imitate the whole class hierarchy of the C++ library, + but at least we can distinguish between classes of different roots. */ + if (hasContent (baseclassname)) { + m3raw_intf.enterBlock (type); + Printf (m3raw_intf.f, "%s = %s;\n", proxy_class_name, + baseclassname); + } else { + m3raw_intf.enterBlock (type); + Printf (m3raw_intf.f, "%s <: ADDRESS;\n", proxy_class_name); + m3raw_impl.enterBlock (revelation); + Printf (m3raw_impl.f, + "%s = UNTRACED BRANDED REF RECORD (*Dummy*) END;\n", + proxy_class_name); + } + + String *superclass; + m3wrap_intf.enterBlock (type); + if (hasContent (methods[acc_public])) { + superclass = NewStringf ("%sPublic", proxy_class_name); + } else if (hasContent (baseclassname)) { + superclass = Copy (baseclassname); + } else { + superclass = NewString ("ROOT"); + } + Printf (m3wrap_intf.f, "%s <: %s;\n", proxy_class_name, superclass); + Delete (superclass); + + { + const static char *acc_m3suffix[] = + { "Public", "Protected", "Private" }; + access_privilege acc; + for (acc = acc_public; acc <= acc_private; int (acc)++) { + bool process_private = (acc == acc_private) && need_private; + if (hasContent (methods[acc]) || process_private) { + String *subclass = + NewStringf ("%s%s", proxy_class_name, acc_m3suffix[acc]); + /* + m3wrap_intf.enterBlock(revelation); + Printf(m3wrap_intf.f, "%s <: %s;\n", proxy_class_name, subclass); + */ + if (acc == max_acc) { + m3wrap_intf.enterBlock (revelation); + Printf (m3wrap_intf.f, "%s =\n", proxy_class_name); + } else { + m3wrap_intf.enterBlock (type); + Printf (m3wrap_intf.f, "%s =\n", subclass); + } + Printf (m3wrap_intf.f, "%s BRANDED OBJECT\n", baseclassname); + if (process_private) { + Setattr (m3wrap_intf.import, m3raw_name, ""); + Printf (m3wrap_intf.f, "cxxObj:%s.%s;\n", m3raw_name, + proxy_class_name); + } + if (hasContent (methods[acc])) { + Printf (m3wrap_intf.f, "METHODS\n%s", methods[acc]); + } + if (acc == max_acc) { + String *overrides = Getattr (n, "modula3:override"); + Printf (m3wrap_intf.f, "OVERRIDES\n%s", overrides); + } + Printf (m3wrap_intf.f, "END;\n"); + Delete (baseclassname); + baseclassname = subclass; + } + } + } + + Delete (methods[acc_public]); + Delete (methods[acc_protected]); + Delete (methods[acc_private]); + + } else { + Swig_warning (WARN_MODULA3_TYPECONSTRUCTOR_UNKNOWN, input_file, + line_number, "Unknown type constructor %s\n", kind); + } + } + + if (proxy_flag) { + + emitProxyClassDefAndCPPCasts (n); + + Printv (f_proxy, proxy_class_def, proxy_class_code, NIL); + + Printf (f_proxy, "}\n"); + Close (f_proxy); + f_proxy = NULL; + + Delete (proxy_class_name); + proxy_class_name = NULL; + Delete (destructor_call); + destructor_call = NULL; + } + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * memberfunctionHandler() + * ---------------------------------------------------------------------- */ + + virtual int memberfunctionHandler (Node * n) + { + //printf("begin memberfunctionHandler(%s)\n", Char(Getattr(n,"name"))); + Setattr (n, "modula3:functype", "method"); + Language::memberfunctionHandler (n); + + { + /* Language::memberfunctionHandler will remove the mapped types + that emitM3Wrapper may attach */ + ParmList *pl = Getattr (n, "parms"); + Swig_typemap_attach_parms ("m3wrapinmode", pl, NULL); + Swig_typemap_attach_parms ("m3wrapinname", pl, NULL); + Swig_typemap_attach_parms ("m3wrapintype", pl, NULL); + Swig_typemap_attach_parms ("m3wrapindefault", pl, NULL); + attachParameterNames (n, "tmap:m3wrapinname", "autoname", "arg%d"); + String *rettype = getMappedTypeNew (n, "m3wrapouttype", ""); + + String *methodname = Getattr (n, "sym:name"); +/* + if (methodname==NIL) { + methodname = Getattr(n,"name"); + } +*/ + String *arguments = createM3Signature (n); + String *storage = Getattr (n, "storage"); + String *overridden = Getattr (n, "virtual:derived"); + bool isVirtual = (storage != NIL) && (Strcmp (storage, "virtual") == 0); + bool isOverridden = (overridden != NIL) + && (Strcmp (overridden, "1") == 0); + if ((!isVirtual) || (!isOverridden)) { + { + String *methods = getMethodDeclarations (n); + Printf (methods, "%s(%s)%s%s;%s\n", + methodname, arguments, + hasContent (rettype) ? ": " : "", + hasContent (rettype) ? rettype : "", + isVirtual ? " (* base method *)" : ""); + } + { + /* this was attached by functionWrapper + invoked by Language::memberfunctionHandler */ + String *fname = Getattr (n, "modula3:funcname"); + String *overrides = + getAttrString (parentNode (n), "modula3:override"); + Printf (overrides, "%s := %s;\n", methodname, fname); + } + } + } + + if (proxy_flag) { + String *overloaded_name = getOverloadedName (n); + String *intermediary_function_name = + Swig_name_member (proxy_class_name, overloaded_name); + Setattr (n, "proxyfuncname", Getattr (n, "sym:name")); + Setattr (n, "imfuncname", intermediary_function_name); + proxyClassFunctionHandler (n); + Delete (overloaded_name); + } + //printf("end memberfunctionHandler(%s)\n", Char(Getattr(n,"name"))); + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * staticmemberfunctionHandler() + * ---------------------------------------------------------------------- */ + + virtual int staticmemberfunctionHandler (Node * n) + { + + static_flag = true; + Language::staticmemberfunctionHandler (n); + + if (proxy_flag) { + String *overloaded_name = getOverloadedName (n); + String *intermediary_function_name = + Swig_name_member (proxy_class_name, overloaded_name); + Setattr (n, "proxyfuncname", Getattr (n, "sym:name")); + Setattr (n, "imfuncname", intermediary_function_name); + proxyClassFunctionHandler (n); + Delete (overloaded_name); + } + static_flag = false; + + return SWIG_OK; + } + + /* ----------------------------------------------------------------------------- + * proxyClassFunctionHandler() + * + * Function called for creating a Modula 3 wrapper function around a c++ function in the + * proxy class. Used for both static and non-static C++ class functions. + * C++ class static functions map to Modula 3 static functions. + * Two extra attributes in the Node must be available. These are "proxyfuncname" - + * the name of the Modula 3 class proxy function, which in turn will call "imfuncname" - + * the intermediary (PInvoke) function name in the intermediary class. + * ----------------------------------------------------------------------------- */ + + void proxyClassFunctionHandler (Node * n) + { + SwigType *t = Getattr (n, "type"); + ParmList *l = Getattr (n, "parms"); + Hash *throws_hash = NewHash (); + String *intermediary_function_name = Getattr (n, "imfuncname"); + String *proxy_function_name = Getattr (n, "proxyfuncname"); + String *tm; + Parm *p; + int i; + String *imcall = NewString (""); + String *return_type = NewString (""); + String *function_code = NewString (""); + bool setter_flag = false; + + if (!proxy_flag) + return; + + if (l) { + if (SwigType_type (Getattr (l, "type")) == T_VOID) { + l = nextSibling (l); + } + } + + /* Attach the non-standard typemaps to the parameter list */ + Swig_typemap_attach_parms ("in", l, NULL); + Swig_typemap_attach_parms ("m3wraptype", l, NULL); + Swig_typemap_attach_parms ("m3in", l, NULL); + + /* Get return types */ + if ((tm = getMappedTypeNew (n, "m3wraptype", ""))) { + substituteClassname (t, tm); + Printf (return_type, "%s", tm); + } + + if (proxy_flag && wrapping_member_flag && !enum_constant_flag) { + // Properties + setter_flag = + (Cmp + (Getattr (n, "sym:name"), + Swig_name_set (Swig_name_member (proxy_class_name, variable_name))) + == 0); + } + + /* Start generating the proxy function */ + Printf (function_code, " %s ", + Getattr (n, "feature:modula3:methodmodifiers")); + if (static_flag) + Printf (function_code, "static "); + if (Getattr (n, "virtual:derived")) + Printf (function_code, "override "); + else if (checkAttribute (n, "storage", "virtual")) + Printf (function_code, "virtual "); + + Printf (function_code, "%s %s(", return_type, proxy_function_name); + + Printv (imcall, m3raw_name, ".", intermediary_function_name, "(", NIL); + if (!static_flag) + Printv (imcall, "swigCPtr", NIL); + + emit_mark_varargs (l); + + int gencomma = !static_flag; + + /* Output each parameter */ + for (i = 0, p = l; p; i++) { + + /* Ignored varargs */ + if (checkAttribute (p, "varargs:ignore", "1")) { + p = nextSibling (p); + continue; + } + + /* Ignored parameters */ + if (checkAttribute (p, "tmap:in:numinputs", "0")) { + p = Getattr (p, "tmap:in:next"); + continue; + } + + /* Ignore the 'this' argument for variable wrappers */ + if (!(variable_wrapper_flag && i == 0)) { + SwigType *pt = Getattr (p, "type"); + String *param_type = NewString (""); + + /* Get the Modula 3 parameter type */ + if ((tm = getMappedType (p, "m3wraptype"))) { + substituteClassname (pt, tm); + Printf (param_type, "%s", tm); + } + + if (gencomma) + Printf (imcall, ", "); + + String *arg = + variable_wrapper_flag ? NewString ("value") : makeParameterName (n, + p, + i); + + // Use typemaps to transform type used in Modula 3 wrapper function (in proxy class) to type used in PInvoke function (in intermediary class) + if ((tm = getMappedType (p, "in"))) { + addThrows (throws_hash, "in", p); + substituteClassname (pt, tm); + Replaceall (tm, "$input", arg); + Printv (imcall, tm, NIL); + } + + /* Add parameter to proxy function */ + if (gencomma >= 2) + Printf (function_code, ", "); + gencomma = 2; + Printf (function_code, "%s %s", param_type, arg); + + Delete (arg); + Delete (param_type); + } + p = Getattr (p, "tmap:in:next"); + } + + Printf (imcall, ")"); + Printf (function_code, ")"); + + // Transform return type used in PInvoke function (in intermediary class) to type used in Modula 3 wrapper function (in proxy class) + if ((tm = getMappedTypeNew (n, "m3out", ""))) { + addThrows (throws_hash, "m3out", n); + if (Getattr (n, "feature:new")) + Replaceall (tm, "$owner", "true"); + else + Replaceall (tm, "$owner", "false"); + substituteClassname (t, tm); + Replaceall (tm, "$imcall", imcall); + } + + generateThrowsClause (throws_hash, function_code); + Printf (function_code, " %s\n\n", tm ? tm : empty_string); + + if (proxy_flag && wrapping_member_flag && !enum_constant_flag) { + // Properties + if (setter_flag) { + // Setter method + if ((tm = getMappedTypeNew (n, "m3varin", ""))) { + if (Getattr (n, "feature:new")) + Replaceall (tm, "$owner", "true"); + else + Replaceall (tm, "$owner", "false"); + substituteClassname (t, tm); + Replaceall (tm, "$imcall", imcall); + Printf (proxy_class_code, "%s", tm); + } + } else { + // Getter method + if ((tm = getMappedTypeNew (n, "m3varout", ""))) { + if (Getattr (n, "feature:new")) + Replaceall (tm, "$owner", "true"); + else + Replaceall (tm, "$owner", "false"); + substituteClassname (t, tm); + Replaceall (tm, "$imcall", imcall); + Printf (proxy_class_code, "%s", tm); + } + } + } else { + // Normal function call + Printv (proxy_class_code, function_code, NIL); + } + + Delete (function_code); + Delete (return_type); + Delete (imcall); + Delete (throws_hash); + } + + /* ---------------------------------------------------------------------- + * constructorHandler() + * ---------------------------------------------------------------------- */ + + virtual int constructorHandler (Node * n) + { + // this invokes functionWrapper + Language::constructorHandler (n); + + if (proxy_flag) { + ParmList *l = Getattr (n, "parms"); + + Hash *throws_hash = NewHash (); + String *overloaded_name = getOverloadedName (n); + String *imcall = NewString (""); + + Printf (proxy_class_code, " %s %s(", + Getattr (n, "feature:modula3:methodmodifiers"), + proxy_class_name); + Printv (imcall, " : this(", m3raw_name, ".", + Swig_name_construct (overloaded_name), "(", NIL); + + /* Attach the non-standard typemaps to the parameter list */ + Swig_typemap_attach_parms ("in", l, NULL); + Swig_typemap_attach_parms ("m3wraptype", l, NULL); + Swig_typemap_attach_parms ("m3in", l, NULL); + + emit_mark_varargs (l); + + int gencomma = 0; + + String *tm; + Parm *p = l; + int i; + + /* Output each parameter */ + for (i = 0; p; i++) { + + /* Ignored varargs */ + if (checkAttribute (p, "varargs:ignore", "1")) { + p = nextSibling (p); + continue; + } + + /* Ignored parameters */ + if (checkAttribute (p, "tmap:in:numinputs", "0")) { + p = Getattr (p, "tmap:in:next"); + continue; + } + + SwigType *pt = Getattr (p, "type"); + String *param_type = NewString (""); + + /* Get the Modula 3 parameter type */ + if ((tm = getMappedType (p, "m3wraptype"))) { + substituteClassname (pt, tm); + Printf (param_type, "%s", tm); + } + + if (gencomma) + Printf (imcall, ", "); + + String *arg = makeParameterName (n, p, i); + + // Use typemaps to transform type used in Modula 3 wrapper function (in proxy class) to type used in PInvoke function (in intermediary class) + if ((tm = getMappedType (p, "in"))) { + addThrows (throws_hash, "in", p); + substituteClassname (pt, tm); + Replaceall (tm, "$input", arg); + Printv (imcall, tm, NIL); + } + + /* Add parameter to proxy function */ + if (gencomma) + Printf (proxy_class_code, ", "); + Printf (proxy_class_code, "%s %s", param_type, arg); + gencomma = 1; + + Delete (arg); + Delete (param_type); + p = Getattr (p, "tmap:in:next"); + } + + Printf (imcall, "), true)"); + + Printf (proxy_class_code, ")"); + Printf (proxy_class_code, "%s", imcall); + generateThrowsClause (throws_hash, proxy_class_code); + Printf (proxy_class_code, " {\n"); + Printf (proxy_class_code, " }\n\n"); + + if (!gencomma) // We must have a default constructor + have_default_constructor_flag = true; + + Delete (overloaded_name); + Delete (imcall); + Delete (throws_hash); + } + + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * destructorHandler() + * ---------------------------------------------------------------------- */ + + virtual int destructorHandler (Node * n) + { + Language::destructorHandler (n); + String *symname = Getattr (n, "sym:name"); + + if (proxy_flag) { + Printv (destructor_call, m3raw_name, ".", Swig_name_destroy (symname), + "(swigCPtr)", NIL); + } + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * membervariableHandler() + * ---------------------------------------------------------------------- */ + + virtual int membervariableHandler (Node * n) + { + //printf("begin membervariableHandler(%s)\n", Char(Getattr(n,"name"))); + SwigType *t = Getattr (n, "type"); + String *tm; + + // Get the variable type + if ((tm = getMappedTypeNew (n, "m3wraptype", ""))) { + substituteClassname (t, tm); + } + + variable_name = Getattr (n, "sym:name"); + //printf("member variable: %s\n", Char(variable_name)); + + // Output the property's field declaration and accessor methods + Printf (proxy_class_code, " public %s %s {", tm, variable_name); + + Setattr (n, "modula3:functype", "accessor"); + wrapping_member_flag = true; + variable_wrapper_flag = true; + Language::membervariableHandler (n); + wrapping_member_flag = false; + variable_wrapper_flag = false; + + Printf (proxy_class_code, "\n }\n\n"); + + { + String *methods = getMethodDeclarations (n); + String *overrides = getAttrString (parentNode (n), "modula3:override"); + SwigType *type = Getattr (n, "type"); + String *m3name = capitalizeFirst (variable_name); + //String *m3name = nameToModula3(variable_name,true); + if (!SwigType_isconst (type)) { + { + String *inmode = getMappedTypeNew (n, "m3wrapinmode", "", false); + String *intype = getMappedTypeNew (n, "m3wrapintype", ""); + Printf (methods, "set%s(%s val:%s);\n", + m3name, (inmode != NIL) ? inmode : "", intype); + } + { + /* this was attached by functionWrapper + invoked by Language::memberfunctionHandler */ + String *fname = Getattr (n, "modula3:setname"); + Printf (overrides, "set%s := %s;\n", m3name, fname); + } + } + { + { + String *outtype = getMappedTypeNew (n, "m3wrapouttype", ""); + Printf (methods, "get%s():%s;\n", m3name, outtype); + } + { + /* this was attached by functionWrapper + invoked by Language::memberfunctionHandler */ + String *fname = Getattr (n, "modula3:getname"); + Printf (overrides, "get%s := %s;\n", m3name, fname); + } + } + Delete (m3name); + } + //printf("end membervariableHandler(%s)\n", Char(Getattr(n,"name"))); + + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * staticmembervariableHandler() + * ---------------------------------------------------------------------- */ + + virtual int staticmembervariableHandler (Node * n) + { + + bool static_const_member_flag = (Getattr (n, "value") == 0); + if (static_const_member_flag) { + SwigType *t = Getattr (n, "type"); + String *tm; + + // Get the variable type + if ((tm = getMappedTypeNew (n, "m3wraptype", ""))) { + substituteClassname (t, tm); + } + // Output the property's field declaration and accessor methods + Printf (proxy_class_code, " public static %s %s {", tm, + Getattr (n, "sym:name")); + } + + variable_name = Getattr (n, "sym:name"); + wrapping_member_flag = true; + static_flag = true; + Language::staticmembervariableHandler (n); + wrapping_member_flag = false; + static_flag = false; + + if (static_const_member_flag) + Printf (proxy_class_code, "\n }\n\n"); + + return SWIG_OK; + } + + /* ---------------------------------------------------------------------- + * memberconstantHandler() + * ---------------------------------------------------------------------- */ + + virtual int memberconstantHandler (Node * n) + { + variable_name = Getattr (n, "sym:name"); + wrapping_member_flag = true; + Language::memberconstantHandler (n); + wrapping_member_flag = false; + return SWIG_OK; + } + + /* ----------------------------------------------------------------------------- + * getOverloadedName() + * ----------------------------------------------------------------------------- */ + + String *getOverloadedName (Node * n) + { + String *overloaded_name = Copy (Getattr (n, "sym:name")); + + if (Getattr (n, "sym:overloaded")) { + Printv (overloaded_name, Getattr (n, "sym:overname"), NIL); + } + + return overloaded_name; + } + + /* ----------------------------------------------------------------------------- + * emitM3Wrapper() + * It is also used for set and get methods of global variables. + * ----------------------------------------------------------------------------- */ + + void emitM3Wrapper (Node * n, const String * func_name) + { + SwigType *t = Getattr (n, "type"); + ParmList *l = Getattr (n, "parms"); + Hash *throws_hash = NewHash (); + int num_exceptions = 0; + int num_returns = 0; + String *rawcall = NewString (""); + String *reccall = NewString (""); + String *local_variables = NewString (""); + String *incheck = NewString (""); + String *outcheck = NewString (""); + String *setup = NewString (""); + String *cleanup = NewString (""); + String *outarg = NewString (""); /* don't mix up with 'autark' :-] */ + String *storeout = NewString (""); + String *result_name = NewString (""); + String *return_variables = NewString (""); + const char *result_return = "ret"; + String *function_code = NewString (""); + /*several names for the same function */ + String *raw_name = Getattr (n, "name"); /*original C function name */ + //String *func_name = Getattr(n,"sym:name"); /*final Modula3 name chosen by the user*/ + bool setter_flag = false; + bool multiretval = Getattr (n, "feature:modula3:multiretval") != NIL; + + if (l) { + if (SwigType_type (Getattr (l, "type")) == T_VOID) { + l = nextSibling (l); + } + } + + /* Attach the non-standard typemaps to the parameter list */ + Swig_typemap_attach_parms ("m3wrapargvar", l, NULL); + Swig_typemap_attach_parms ("m3wrapargraw", l, NULL); + Swig_typemap_attach_parms ("m3wrapargdir", l, NULL); + Swig_typemap_attach_parms ("m3wrapinmode", l, NULL); + Swig_typemap_attach_parms ("m3wrapinname", l, NULL); + Swig_typemap_attach_parms ("m3wrapintype", l, NULL); + Swig_typemap_attach_parms ("m3wrapindefault", l, NULL); + Swig_typemap_attach_parms ("m3wrapinconv", l, NULL); + Swig_typemap_attach_parms ("m3wrapincheck", l, NULL); + Swig_typemap_attach_parms ("m3wrapoutname", l, NULL); + Swig_typemap_attach_parms ("m3wrapouttype", l, NULL); + Swig_typemap_attach_parms ("m3wrapoutconv", l, NULL); + Swig_typemap_attach_parms ("m3wrapoutcheck", l, NULL); + + attachMappedType (n, "m3wrapretraw"); + attachMappedType (n, "m3wrapretname"); + attachMappedType (n, "m3wraprettype"); + attachMappedType (n, "m3wrapretvar"); + attachMappedType (n, "m3wrapretconv"); + attachMappedType (n, "m3wrapretcheck"); + + Swig_typemap_attach_parms ("m3wrapfreearg", l, NULL); + +/* + Swig_typemap_attach_parms("m3wrapargvar:throws", l, NULL); + Swig_typemap_attach_parms("m3wrapargraw:throws", l, NULL); + Swig_typemap_attach_parms("m3wrapinconv:throws", l, NULL); + Swig_typemap_attach_parms("m3wrapincheck:throws", l, NULL); + Swig_typemap_attach_parms("m3wrapoutconv:throws", l, NULL); + Swig_typemap_attach_parms("m3wrapoutcheck:throws", l, NULL); + + attachMappedType(n, "m3wrapretvar:throws"); + attachMappedType(n, "m3wrapretconv:throws"); + attachMappedType(n, "m3wrapretcheck:throws"); + + Swig_typemap_attach_parms("m3wrapfreearg:throws", l, NULL); +*/ + + /* Attach argument names to the parameter list */ + /* should be a separate procedure making use of hashes */ + attachParameterNames (n, "tmap:m3wrapinname", "autoname", "arg%d"); + + /* Get return types */ + String *result_m3rawtype = + Copy (getMappedTypeNew (n, "m3rawrettype", "")); + String *result_m3wraptype = + Copy (getMappedTypeNew (n, "m3wraprettype", "")); + bool has_return_raw = hasContent (result_m3rawtype); + bool has_return_m3 = hasContent (result_m3wraptype); + if (has_return_m3) { + num_returns++; + //printf("%s: %s\n", Char(func_name),Char(result_m3wraptype)); + } + + String *arguments = createM3Signature (n); + + /* Create local variables or RECORD fields for return values + and determine return type that might result from a converted VAR argument. */ + { + writeArgState state; + if (multiretval && has_return_m3) { + writeArg (return_variables, state, NIL, NewString (result_return), + result_m3wraptype, NIL); + } + + Parm *p = skipIgnored (l, "m3wrapouttype"); + while (p != NIL) { + + String *arg = Getattr (p, "tmap:m3wrapoutname"); + if (arg == NIL) { + arg = Getattr (p, "name"); + } + + String *tm = Getattr (p, "tmap:m3wrapouttype"); + if (tm != NIL) { + if (isOutParam (p)) { + if (!multiretval) { + if (num_returns == 0) { + Printv (result_name, arg, NIL); + Clear (result_m3wraptype); + Printv (result_m3wraptype, tm, NIL); + } else { + Swig_warning (WARN_MODULA3_TYPEMAP_MULTIPLE_RETURN, + input_file, line_number, + "Typemap m3wrapargdir set to 'out' for %s implies a RETURN value, but the routine %s has already one.\nUse %%multiretval feature.\n", + SwigType_str (Getattr (p, "type"), 0), + raw_name); + } + } + num_returns++; + addImports (m3wrap_intf.import, "m3wrapouttype", p); + writeArg (return_variables, state, NIL, arg, tm, NIL); + } + p = + skipIgnored (Getattr (p, "tmap:m3wrapouttype:next"), + "m3wrapouttype"); + } else { + p = nextSibling (p); + } + } + writeArg (return_variables, state, NIL, NIL, NIL, NIL); + + if (multiretval) { + Printv (result_name, "result", NIL); + Printf (result_m3wraptype, "%sResult", func_name); + m3wrap_intf.enterBlock (type); + Printf (m3wrap_intf.f, "%s =\nRECORD\n%sEND;\n", + result_m3wraptype, return_variables); + Printf (local_variables, "%s: %s;\n", result_name, result_m3wraptype); + } else { + Append (local_variables, return_variables); + } + } + + /* Create local variables e.g. for converted input values. */ + { + String *tm = getMappedTypeNew (n, "m3wrapretvar", "", false); + if (tm != NIL) { + addImports (m3wrap_impl.import, "m3wrapretvar", n); + addThrows (throws_hash, "m3wrapretvar", n); + Printv (local_variables, tm, "\n", NIL); + } + + Parm *p = l; + while (p != NIL) { + + String *arg = Getattr (p, "autoname"); + + tm = Getattr (p, "tmap:m3wrapargvar"); + if (tm != NIL) { + /* exceptions that may be raised but can't be catched, + thus we won't count them in num_exceptions */ + addImports (m3wrap_impl.import, "m3wrapargvar", p); + addThrows (throws_hash, "m3wrapargvar", p); + Replaceall (tm, "$input", arg); + Printv (local_variables, tm, "\n", NIL); + p = Getattr (p, "tmap:m3wrapargvar:next"); + } else { + p = nextSibling (p); + } + + } + } + + /* Converted input values from Modula 3 to C. */ + { + Parm *p = l; + while (p != NIL) { + + String *arg = Getattr (p, "autoname"); + + String *tm = Getattr (p, "tmap:m3wrapinconv"); + if (tm != NIL) { + addImports (m3wrap_impl.import, "m3wrapinconv", p); + num_exceptions += addThrows (throws_hash, "m3wrapinconv", p); + Replaceall (tm, "$input", arg); + Printv (setup, tm, "\n", NIL); + p = Getattr (p, "tmap:m3wrapinconv:next"); + } else { + p = nextSibling (p); + } + + } + } + + /* Generate checks for input value integrity. */ + { + Parm *p = l; + while (p != NIL) { + + String *arg = Getattr (p, "autoname"); + + String *tm = Getattr (p, "tmap:m3wrapincheck"); + if (tm != NIL) { + addImports (m3wrap_impl.import, "m3wrapincheck", p); + num_exceptions += addThrows (throws_hash, "m3wrapincheck", p); + Replaceall (tm, "$input", arg); + Printv (incheck, tm, "\n", NIL); + p = Getattr (p, "tmap:m3wrapincheck:next"); + } else { + p = nextSibling (p); + } + + } + } + + Printv (rawcall, m3raw_name, ".", func_name, "(", NIL); + /* Arguments to the raw C function */ + { + bool gencomma = false; + Parm *p = l; + while (p != NIL) { + if (gencomma) { + Printf (rawcall, ", "); + } + gencomma = true; + addImports (m3wrap_impl.import, "m3wrapargraw", p); + num_exceptions += addThrows (throws_hash, "m3wrapargraw", p); + + String *arg = Getattr (p, "autoname"); + String *qualarg = NewString (""); + if (!isInParam (p)) { + String *tmparg = Getattr (p, "tmap:m3wrapoutname"); + if (tmparg != NIL) { + arg = tmparg; + } + if (multiretval /*&& isOutParam(p) - automatically fulfilled */ ) { + Printf (qualarg, "%s.", result_name); + } + } + Append (qualarg, arg); + Setattr (p, "m3outarg", qualarg); + + String *tm = Getattr (p, "tmap:m3wrapargraw"); + if (tm != NIL) { + Replaceall (tm, "$input", arg); + Replaceall (tm, "$output", qualarg); + Printv (rawcall, tm, NIL); + p = Getattr (p, "tmap:m3wrapargraw:next"); + } else { + //Printv(rawcall, Getattr(p,"lname"), NIL); + Printv (rawcall, qualarg, NIL); + p = nextSibling (p); + } + Delete (qualarg); + } + } + Printf (rawcall, ")"); + + /* Check for error codes and integrity of results */ + { + String *tm = getMappedTypeNew (n, "m3wrapretcheck", "", false); + if (tm != NIL) { + addImports (m3wrap_impl.import, "m3wrapretcheck", n); + num_exceptions += addThrows (throws_hash, "m3wrapretcheck", n); + Printv (outcheck, tm, "\n", NIL); + } + + Parm *p = l; + while (p != NIL) { + tm = Getattr (p, "tmap:m3wrapoutcheck"); + if (tm != NIL) { + String *arg = Getattr (p, "autoname"); + String *outarg = Getattr (p, "m3outarg"); + addImports (m3wrap_impl.import, "m3wrapoutcheck", p); + num_exceptions += addThrows (throws_hash, "m3wrapoutcheck", p); + //substituteClassname(Getattr(p,"type"), tm); + Replaceall (tm, "$input", arg); + Replaceall (tm, "$output", outarg); + Printv (outcheck, tm, "\n", NIL); + p = Getattr (p, "tmap:m3wrapoutcheck:next"); + } else { + p = nextSibling (p); + } + } + } + + /* Convert the results to Modula 3 data structures and + put them in the record prepared for returning */ + { + /* m3wrapretconv is processed + when it is clear if there is some output conversion and checking code */ + Parm *p = l; + while (p != NIL) { + String *tm = Getattr (p, "tmap:m3wrapoutconv"); + if (tm != NIL) { + String *arg = Getattr (p, "autoname"); + String *outarg = Getattr (p, "m3outarg"); + addImports (m3wrap_impl.import, "m3wrapoutconv", n); + num_exceptions += addThrows (throws_hash, "m3wrapoutconv", p); + //substituteClassname(Getattr(p,"type"), tm); + Replaceall (tm, "$input", arg); + Replaceall (tm, "$output", outarg); + Printf (storeout, "%s := %s;\n", outarg, tm); + p = Getattr (p, "tmap:m3wrapoutconv:next"); + } else { + p = nextSibling (p); + } + } + } + + /* Generate cleanup code */ + { + Parm *p = l; + while (p != NIL) { + String *tm = Getattr (p, "tmap:m3wrapfreearg"); + if (tm != NIL) { + String *arg = Getattr (p, "autoname"); + String *outarg = Getattr (p, "m3outarg"); + addImports (m3wrap_impl.import, "m3wrapfreearg", p); + num_exceptions += addThrows (throws_hash, "m3wrapfreearg", p); + //substituteClassname(Getattr(p,"type"), tm); + Replaceall (tm, "$input", arg); + Replaceall (tm, "$output", outarg); + Printv (cleanup, tm, "\n", NIL); + p = Getattr (p, "tmap:m3wrapfreearg:next"); + } else { + p = nextSibling (p); + } + } + } + + { + /* Currently I don't know how a typemap similar to the original 'out' typemap + could help returning the return value. */ + /* Receive result from call to raw library function */ + if (!has_return_raw) { + /* + rawcall(arg1); + result.val := arg1; + RETURN result; + */ + /* + rawcall(arg1); + RETURN arg1; + */ + Printf (reccall, "%s;\n", rawcall); + + if (hasContent (result_name)) { + Printf (outarg, "RETURN %s;\n", result_name); + } + } else { + /* + arg0 := rawcall(arg1); + result.ret := Convert(arg0); + result.val := arg1; + RETURN result; + */ + /* + arg0 := rawcall(); + RETURN Convert(arg0); + */ + /* + RETURN rawcall(); + */ + String *return_raw = getMappedTypeNew (n, "m3wrapretraw", "", false); + String *return_conv = + getMappedTypeNew (n, "m3wrapretconv", "", false); + + /* immediate RETURN would skip result checking */ + if ((hasContent (outcheck) || hasContent (storeout) + || hasContent (cleanup)) && (!hasContent (result_name)) + && (return_raw == NIL)) { + Printv (result_name, "result", NIL); + Printf (local_variables, "%s: %s;\n", result_name, + result_m3wraptype); + } + + String *result_lvalue = Copy (result_name); + if (multiretval) { + Printf (result_lvalue, ".%s", result_return); + } + if (return_raw != NIL) { + Printf (reccall, "%s := %s;\n", return_raw, rawcall); + } else if (hasContent (result_name)) { + Printf (reccall, "%s := %s;\n", result_lvalue, rawcall); + } else { + Printf (outarg, "RETURN %s;\n", rawcall); + } + if (return_conv != NIL) { + addImports (m3wrap_impl.import, "m3wrapretconv", n); + num_exceptions += addThrows (throws_hash, "m3wrapretconv", n); + if (hasContent (result_name)) { + Printf (reccall, "%s := %s;\n", result_lvalue, return_conv); + Printf (outarg, "RETURN %s;\n", result_name); + } else { + Printf (outarg, "RETURN %s;\n", return_conv); + } + } else { + if (hasContent (result_name)) { + Printf (outarg, "RETURN %s;\n", result_name); + } + } + } + } + + /* Create procedure header */ + { + String *header = NewStringf ("PROCEDURE %s (%s)", + func_name, arguments); + + if ((num_returns > 0) || multiretval) { + Printf (header, ": %s", result_m3wraptype); + } + generateThrowsClause (throws_hash, header); + + Append (function_code, header); + + m3wrap_intf.enterBlock (no_block); + Printf (m3wrap_intf.f, "%s;\n\n", header, NIL); + } + + { + String *body = NewStringf ("%s%s%s%s%s", + incheck, + setup, + reccall, + outcheck, + storeout); + + String *exc_handler; + if (hasContent (cleanup) && (num_exceptions > 0)) { + exc_handler = NewStringf ("TRY\n%sFINALLY\n%sEND;\n", body, cleanup); + } else { + exc_handler = NewStringf ("%s%s", body, cleanup); + } + + Printf (function_code, " =\n%s%sBEGIN\n%s%sEND %s;\n\n", + hasContent (local_variables) ? "VAR\n" : empty_string, + local_variables, exc_handler, outarg, func_name); + + Delete (exc_handler); + Delete (body); + } + + m3wrap_impl.enterBlock (no_block); + if (proxy_flag && global_variable_flag) { + // Properties + if (setter_flag) { + // Setter method + String *tm = getMappedTypeNew (n, "m3varin", ""); + if (tm != NIL) { + if (Getattr (n, "feature:new")) { + Replaceall (tm, "$owner", "true"); + } else { + Replaceall (tm, "$owner", "false"); + } + substituteClassname (t, tm); + Replaceall (tm, "$rawcall", rawcall); + Replaceall (tm, "$vartype", variable_type); /* $type is already replaced by some super class */ + Replaceall (tm, "$var", variable_name); + Printf (m3wrap_impl.f, "%s", tm); + } + } else { + // Getter method + String *tm = getMappedTypeNew (n, "m3varout", ""); + if (tm != NIL) { + if (Getattr (n, "feature:new")) + Replaceall (tm, "$owner", "true"); + else + Replaceall (tm, "$owner", "false"); + substituteClassname (t, tm); + Replaceall (tm, "$rawcall", rawcall); + Replaceall (tm, "$vartype", variable_type); + Replaceall (tm, "$var", variable_name); + Printf (m3wrap_impl.f, "%s", tm); + } + } + } else { + // Normal function call + Printv (m3wrap_impl.f, function_code, NIL); + } + + Delete (arguments); + Delete (return_variables); + Delete (local_variables); + Delete (outarg); + Delete (incheck); + Delete (outcheck); + Delete (setup); + Delete (cleanup); + Delete (storeout); + Delete (function_code); + Delete (result_name); + Delete (result_m3wraptype); + Delete (reccall); + Delete (rawcall); + Delete (throws_hash); + } + + /* ----------------------------------------------------------------------------- + * substituteClassname() + * + * Substitute $m3classname with the proxy class name for classes/structs/unions that SWIG knows about. + * Otherwise use the $descriptor name for the Modula 3 class name. Note that the $&m3classname substitution + * is the same as a $&descriptor substitution, ie one pointer added to descriptor name. + * Inputs: + * pt - parameter type + * tm - m3wraptype typemap + * Outputs: + * tm - m3wraptype typemap with $m3classname substitution + * Return: + * substitution_performed - flag indicating if a substitution was performed + * ----------------------------------------------------------------------------- */ + + bool substituteClassname (SwigType * pt, String * tm) + { + bool substitution_performed = false; + if (Strstr (tm, "$m3classname") || Strstr (tm, "$&m3classname")) { + String *classname = getProxyName (pt); + if (classname) { + Replaceall (tm, "$&m3classname", classname); // getProxyName() works for pointers to classes too + Replaceall (tm, "$m3classname", classname); + } else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved. + String *descriptor = NULL; + SwigType *type = Copy (SwigType_typedef_resolve_all (pt)); + + if (Strstr (tm, "$&m3classname")) { + SwigType_add_pointer (type); + descriptor = NewStringf ("SWIGTYPE%s", SwigType_manglestr (type)); + Replaceall (tm, "$&m3classname", descriptor); + } else { // $m3classname + descriptor = NewStringf ("SWIGTYPE%s", SwigType_manglestr (type)); + Replaceall (tm, "$m3classname", descriptor); + } + + // Add to hash table so that the type wrapper classes can be created later + Setattr (swig_types_hash, descriptor, type); + Delete (descriptor); + Delete (type); + } + substitution_performed = true; + } + return substitution_performed; + } + + /* ----------------------------------------------------------------------------- + * makeParameterName() + * + * Inputs: + * n - Node + * p - parameter node + * arg_num - parameter argument number + * Return: + * arg - a unique parameter name + * ----------------------------------------------------------------------------- */ + + String *makeParameterName (Node * n, Parm * p, int arg_num) + { + + // Use C parameter name unless it is a duplicate or an empty parameter name + String *pn = Getattr (p, "name"); + int count = 0; + ParmList *plist = Getattr (n, "parms"); + while (plist) { + if ((Cmp (pn, Getattr (plist, "name")) == 0)) + count++; + plist = nextSibling (plist); + } + String *arg = (!pn + || (count > 1)) ? NewStringf ("arg%d", + arg_num) : Copy (Getattr (p, + "name")); + + return arg; + } + + /* ----------------------------------------------------------------------------- + * attachParameterNames() + * + * Inputs: + * n - Node of a function declaration + * tmid - attribute name for overriding C argument names, + * e.g. "tmap:m3wrapinname", + * don't forget to attach the mapped types before + * nameid - attribute for attaching the names, + * e.g. "modula3:inname" + * fmt - format for the argument name containing %d + * e.g. "arg%d" + * ----------------------------------------------------------------------------- */ + + void attachParameterNames (Node * n, const char *tmid, const char *nameid, + const char *fmt) + { + /* Use C parameter name if present and unique, + otherwise create an 'arg%d' name */ + Hash *hash = NewHash (); + Parm *p = Getattr (n, "parms"); + int count = 0; + while (p != NIL) { + String *name = Getattr (p, tmid); + if (name == NIL) { + name = Getattr (p, "name"); + } + String *newname; + if ((!hasContent (name)) || (Getattr (hash, name) != NIL)) { + newname = NewStringf (fmt, count); + } else { + newname = Copy (name); + } + if (1 == Setattr (hash, newname, "1")) { + Swig_warning (WARN_MODULA3_DOUBLE_ID, input_file, line_number, + "Argument '%s' twice.\n", newname); + } + Setattr (p, nameid, newname); +// Delete(newname); + p = nextSibling (p); + count++; + } + Delete (hash); + } + + /* ----------------------------------------------------------------------------- + * createM3Signature() + * + * Create signature of M3 wrapper procedure + * Call attachParameterNames and attach mapped types before! + * m3wrapintype, m3wrapinmode, m3wrapindefault + * ----------------------------------------------------------------------------- */ + + String *createM3Signature (Node * n) + { + String *arguments = NewString (""); + Parm *p = skipIgnored (Getattr (n, "parms"), "m3wrapintype"); + writeArgState state; + while (p != NIL) { + + /* Get the M3 parameter type */ + String *tm = getMappedType (p, "m3wrapintype"); + if (tm != NIL) { + if (isInParam (p)) { + addImports (m3wrap_intf.import, "m3wrapintype", p); + addImports (m3wrap_impl.import, "m3wrapintype", p); + String *mode = Getattr (p, "tmap:m3wrapinmode"); + String *deflt = Getattr (p, "tmap:m3wrapindefault"); + String *arg = Getattr (p, "autoname"); + SwigType *pt = Getattr (p, "type"); + substituteClassname (pt, tm); /* do we need this ? */ + + writeArg (arguments, state, mode, arg, tm, deflt); + } + p = + skipIgnored (Getattr (p, "tmap:m3wrapintype:next"), "m3wrapintype"); + } else { + p = nextSibling (p); + } + } + writeArg (arguments, state, NIL, NIL, NIL, NIL); + return (arguments); + } + + /* ----------------------------------------------------------------------------- + * createCSignature() + * + * Create signature of C function + * ----------------------------------------------------------------------------- */ + + String *createCSignature (Node * n) + { + String *arguments = NewString (""); + bool gencomma = false; + Node *p; + for (p = Getattr (n, "parms"); p != NIL; p = nextSibling (p)) { + if (gencomma) { + Append (arguments, ","); + } + gencomma = true; + String *type = Getattr (p, "type"); + String *ctype = getMappedTypeNew (type, "ctype"); + Append (arguments, ctype); + } + return arguments; + } + + /* ----------------------------------------------------------------------------- + * emitTypeWrapperClass() + * ----------------------------------------------------------------------------- */ + + void emitTypeWrapperClass (String * classname, SwigType * type) + { + String *filen = + NewStringf ("%s%s.m3", Swig_file_dirname (outfile), classname); + File *f_swigtype = NewFile (filen, "w"); + String *swigtype = NewString (""); + + // Emit banner name + emitBanner (f_swigtype); + + // Pure Modula 3 baseclass and interfaces + const String *pure_baseclass = typemapLookup ("m3base", type, WARN_NONE); + const String *pure_interfaces = + typemapLookup ("m3interfaces", type, WARN_NONE); + + // Emit the class + Printv (swigtype, typemapLookup ("m3imports", type, WARN_NONE), // Import statements + "\n", typemapLookup ("m3classmodifiers", type, WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers + " class $m3classname", // Class name and bases + *Char (pure_baseclass) ? " : " : "", pure_baseclass, *Char (pure_interfaces) ? // Interfaces + " : " : "", pure_interfaces, " {\n", " private IntPtr swigCPtr;\n", "\n", " ", typemapLookup ("m3ptrconstructormodifiers", type, WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers + " $m3classname(IntPtr cPtr, bool bFutureUse) {\n", // Constructor used for wrapping pointers + " swigCPtr = cPtr;\n", " }\n", "\n", " protected $m3classname() {\n", // Default constructor + " swigCPtr = IntPtr.Zero;\n", " }\n", typemapLookup ("m3getcptr", type, WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF), // getCPtr method + typemapLookup ("m3code", type, WARN_NONE), // extra Modula 3 code + "}\n", "\n", NIL); + + Replaceall (swigtype, "$m3classname", classname); + Printv (f_swigtype, swigtype, NIL); + + Close (f_swigtype); + Delete (filen); + Delete (swigtype); + } + + /* ----------------------------------------------------------------------------- + * typemapLookup() + * ----------------------------------------------------------------------------- */ + + const String *typemapLookup (const String * op, String * type, int warning, + Node * typemap_attributes = NULL) { + String *tm = NULL; + const String *code = NULL; + + if ((tm = Swig_typemap_search (op, type, NULL, NULL))) { + code = Getattr (tm, "code"); + if (typemap_attributes) + Swig_typemap_attach_kwargs (tm, op, typemap_attributes); + } + + if (!code) { + code = empty_string; + if (warning != WARN_NONE) + Swig_warning (warning, input_file, line_number, + "No %s typemap defined for %s\n", op, type); + } + + return code ? code : empty_string; + } + + /* ----------------------------------------------------------------------------- + * addThrows() + * + * Add all exceptions to a hash that are associated with the 'typemap'. + * Return number the number of these exceptions. + * ----------------------------------------------------------------------------- */ + + int addThrows (Hash * throws_hash, const String * typemap, Node * parameter) + { + // Get the comma separated throws clause - held in "throws" attribute in the typemap passed in + int len = 0; + String *throws_attribute = NewStringf ("%s:throws", typemap); + + addImports (m3wrap_intf.import, throws_attribute, parameter); + addImports (m3wrap_impl.import, throws_attribute, parameter); + + String *throws = + getMappedTypeNew (parameter, Char (throws_attribute), "", false); + //printf("got exceptions %s for %s\n", Char(throws), Char(throws_attribute)); + + if (throws) { + // Put the exception classes in the throws clause into a temporary List + List *temp_classes_list = Split (throws, ',', INT_MAX); + len = Len (temp_classes_list); + + // Add the exception classes to the node throws list, but don't duplicate if already in list + if (temp_classes_list /*&& hasContent(temp_classes_list) */ ) { + for (Iterator cls = First (temp_classes_list); cls.item != NIL; + cls = Next (cls)) { + String *exception_class = NewString (cls.item); + Replaceall (exception_class, " ", ""); // remove spaces + Replaceall (exception_class, "\t", ""); // remove tabs + if (hasContent (exception_class)) { + // $m3classname substitution + SwigType *pt = Getattr (parameter, "type"); + substituteClassname (pt, exception_class); + // Don't duplicate the exception class in the throws clause + //printf("add exception %s\n", Char(exception_class)); + Setattr (throws_hash, exception_class, "1"); + } + Delete (exception_class); + } + } + Delete (temp_classes_list); + } + Delete (throws_attribute); + return len; + } + + /* ----------------------------------------------------------------------------- + * generateThrowsClause() + * ----------------------------------------------------------------------------- */ + + void generateThrowsClause (Hash * throws_hash, String * code) + { + // Add the throws clause into code + if (Len (throws_hash) > 0) { + Iterator cls = First (throws_hash); + Printf (code, " RAISES {%s", cls.key); + for (cls = Next (cls); cls.key != NIL; cls = Next (cls)) { + Printf (code, ", %s", cls.key); + } + Printf (code, "}"); + } + } + + /* ----------------------------------------------------------------------------- + * addImports() + * + * Add all imports that are needed for contents of 'typemap'. + * ----------------------------------------------------------------------------- */ + + void addImports (Hash * imports_hash, const String * typemap, Node * node) + { + // Get the comma separated throws clause - held in "throws" attribute in the typemap passed in + String *imports_attribute = NewStringf ("%s:import", typemap); + String *imports = + getMappedTypeNew (node, Char (imports_attribute), "", false); + //printf("got imports %s for %s\n", Char(imports), Char(imports_attribute)); + + if (imports != NIL) { + List *import_list = Split (imports, ',', INT_MAX); + + // Add the exception classes to the node imports list, but don't duplicate if already in list + if (import_list != NIL) { + for (Iterator imp = First (import_list); imp.item != NIL; + imp = Next (imp)) { + List *import_pair = Split (imp.item, ' ', 3); + if (Len (import_pair) == 1) { + Setattr (imports_hash, Getitem (import_pair, 0), ""); + } else if ((Len (import_pair) == 3) + && Strcmp (Getitem (import_pair, 1), "AS") == 0) { + Setattr (imports_hash, Getitem (import_pair, 0), + Getitem (import_pair, 2)); + } else { + Swig_warning (WARN_MODULA3_BAD_IMPORT, input_file, line_number, + "Malformed import '%s' for typemap '%s' defined for type '%s'\n", + imp, typemap, SwigType_str (Getattr (node, "type"), + 0)); + } + Delete (import_pair); + } + } + Delete (import_list); + } + Delete (imports_attribute); + } + + /* ----------------------------------------------------------------------------- + * emitImportStatements() + * ----------------------------------------------------------------------------- */ + + void emitImportStatements (Hash * imports_hash, String * code) + { + // Add the imports statements into code + Iterator imp = First (imports_hash); + while (imp.key != NIL) { + Printf (code, "IMPORT %s", imp.key); + String *imp_as = imp.item; + if (hasContent (imp_as)) { + Printf (code, " AS %s", imp_as); + } + Printf (code, ";\n"); + imp = Next (imp); + } + } + +}; /* class MODULA3 */ + +/* ----------------------------------------------------------------------------- + * swig_modula3() - Instantiate module + * ----------------------------------------------------------------------------- */ + +extern "C" Language * swig_modula3 (void) +{ + return new MODULA3 (); +} + +/* ----------------------------------------------------------------------------- + * Static member variables + * ----------------------------------------------------------------------------- */ + +const char *MODULA3::usage = (char *) "\ +Modula 3 Options (available with -modula3)\n\ + -generateconst - generate code for computing numeric values of constants\n\ + -generaterename - generate suggestions for %rename\n\ + -generatetypemap - generate templates for some basic typemaps\n\ +\n"; + +/* + -generateconst - stem of the .c source file for computing the numeric values of constants\n\ + -generaterename - stem of the .i source file containing %rename suggestions\n\ + -generatetypemap - stem of the .i source file containing typemap patterns\n\ +*/ diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx index afc706af5..d80f3c2a8 100644 --- a/Source/Modules/swigmain.cxx +++ b/Source/Modules/swigmain.cxx @@ -36,6 +36,7 @@ extern "C" { Language *swig_perl5(void); Language *swig_ruby(void); Language *swig_guile(void); + Language *swig_modula3(void); Language *swig_mzscheme(void); Language *swig_java(void); Language *swig_php(void); @@ -62,6 +63,7 @@ swig_module modules[] = { {"-csharp", swig_csharp, "C#"}, {"-guile", swig_guile, "Guile"}, {"-java", swig_java, "Java"}, + {"-modula3", swig_modula3, "Modula 3"}, {"-mzscheme", swig_mzscheme, "Mzscheme"}, {"-ocaml", swig_ocaml, "Ocaml"}, {"-perl", swig_perl5, "Perl"},