blob: ee7d2785de87f61b8197494cc3a15185d5c3a989 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Modula-3</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="Modula3"></a>24 SWIG and Modula-3</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Modula3_modula3_overview">Overview</a>
<ul>
<li><a href="#Modula3_motivation">Motivation</a>
</ul>
<li><a href="#Modula3_conception">Conception</a>
<ul>
<li><a href="#Modula3_cinterface">Interfaces to C libraries</a>
<li><a href="#Modula3_cppinterface">Interfaces to C++ libraries</a>
</ul>
<li><a href="#Modula3_preliminaries">Preliminaries</a>
<ul>
<li><a href="#Modula3_compilers">Compilers</a>
<li><a href="#Modula3_commandline">Additional Commandline Options</a>
</ul>
<li><a href="#Modula3_typemaps">Modula-3 typemaps</a>
<ul>
<li><a href="#Modula3_inoutparam">Inputs and outputs</a>
<li><a href="#Modula3_ordinals">Subranges, Enumerations, Sets</a>
<li><a href="#Modula3_class">Objects</a>
<li><a href="#Modula3_imports">Imports</a>
<li><a href="#Modula3_exceptions">Exceptions</a>
<li><a href="#Modula3_typemap_example">Example</a>
</ul>
<li><a href="#Modula3_hints">More hints to the generator</a>
<ul>
<li><a href="#Modula3_features">Features</a>
<li><a href="#Modula3_pragmas">Pragmas</a>
</ul>
<li><a href="#Modula3_remarks">Remarks</a>
</ul>
</div>
<!-- INDEX -->
<p>
This chapter describes SWIG's support of
<a href="http://modula3.org/">Modula-3</a>.
You should be familiar with the
<a href="SWIG.html#SWIG">basics</a>
of SWIG,
especially
<a href="Typemaps.html#Typemaps">typemaps</a>.
</p>
<H2><a name="Modula3_modula3_overview"></a>24.1 Overview</H2>
<p>
Modula-3 is a compiled language in the tradition of Niklaus Wirth's Modula 2,
which is in turn a successor to Pascal.
</p>
<p>
SWIG's Modula-3 support is currently very basic and highly experimental!
Many features are still not designed satisfyingly
and I need more discussion about the odds and ends.
Don't rely on any feature, incompatible changes are likely in the future!
However, the Modula-3 generator was already useful for interfacing
to the libraries:
</p>
<ol>
<li>
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/">
PLPlot
</a>
</li>
<li>
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/fftw/">
FFTW
</a>
</li>
</ol>
<H3><a name="Modula3_motivation"></a>24.1.1 Motivation</H3>
<p>
Although it is possible to write Modula-3 code that performs as well as C/C++
most existing libraries are not written in Modula-3 but in C or C++, and
even libraries in other languages may provide C header files.
</p>
<p>
Fortunately Modula-3 can call C functions, but you have to write Modula-3
interfaces to them, and to make things comfortable you will also need
wrappers that convert between high-level features of Modula-3 (garbage
collecting, exceptions) and the explicit tracking of allocated memory and
exception codes used by C APIs.
</p>
<p>
SWIG converts C headers to Modula-3 interfaces for you, and using typemaps
you can pass <tt>TEXT</tt>s or open arrays, and convert error return codes
into exceptions.
</p>
<p>
If the library API is ill designed
writing appropriate typemaps can be still time-consuming.
E.g. C programmers are very creative to work-around
missing data types like (real) enumerations and sets.
You should turn such work-arounds back to the Modula-3 way
otherwise you lose static safety and consistency.
</p>
<p>
Without SWIG you would probably never consider trying to call C++ libraries
from Modula-3, but with SWIG this is becomes feasible.
SWIG can generate C wrappers to C++ functions and object methods
that may throw exceptions, and then wrap these C wrappers for Module-3.
To make it complete you can then hide the C interface with Modula-3 classes and
exceptions.
</p>
<p>
SWIG allows you to call C and C++ libraries from Modula-3 (even with call back
functions), but it doesn't allow you to easily integrate a Module-3 module into
a C/C++ project.
</p>
<H2><a name="Modula3_conception"></a>24.2 Conception</H2>
<H3><a name="Modula3_cinterface"></a>24.2.1 Interfaces to C libraries</H3>
<p>
Modula-3 has integrated support for calling C functions.
This is also extensively used by the standard Modula-3 libraries
to call OS functions.
The Modula-3 part of SWIG and the corresponding SWIG library
<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
contain code that uses these features.
Because of the built-in support there is no need
for calling the SWIG kernel to generate wrappers written in C.
All conversion and argument checking can be done in Modula-3
and the interfacing is quite efficient.
All you have to do is to write pieces of Modula-3 code
that SWIG puts together.
</p>
<table border summary="Modula-3 C library support">
<tr><th colspan=2>C library support integrated in Modula-3<th></tr>
<tr>
<td>Pragma <tt>&lt;* EXTERNAL *&gt;</tt></td>
<td>Precedes a declaration of a PROCEDURE that is implemented
in an external library instead of a Modula-3 module.</td>
</tr>
<tr>
<td>Pragma <tt>&lt;* CALLBACK *&gt;</tt></td>
<td>Precedes a declaration of a PROCEDURE that should be called
by external library code.</td>
</tr>
<tr>
<td>Module <tt>Ctypes</tt></td>
<td>Contains Modula-3 types that match some basic C types.</td>
</tr>
<tr>
<td>Module <tt>M3toC</tt></td>
<td>Contains routines that convert between Modula-3's <tt>TEXT</tt> type
and C's <tt>char *</tt> type.</td>
</tr>
</table>
<p>
In each run of SWIG the Modula-3 part
generates several files:
</p>
<table border summary="Modula-3 generated files">
<tr>
<th>Module name scheme</th>
<th>Identifier for <tt>%insert</tt></th>
<th>Description</th>
</tr>
<tr>
<td>Module<tt>Raw.i3</tt></td>
<td><tt>m3rawintf</tt></td>
<td>Declaration of types that are equivalent to those of the C library,
<tt>EXTERNAL</tt> procedures as interface to the C library functions</td>
</tr>
<tr>
<td>Module<tt>Raw.m3</tt></td>
<td><tt>m3rawimpl</tt></td>
<td>Almost empty.</td>
</tr>
<tr>
<td>Module<tt>.i3</tt></td>
<td><tt>m3wrapintf</tt></td>
<td>Declaration of comfortable wrappers to the C library functions.</td>
</tr>
<tr>
<td>Module<tt>.m3</tt></td>
<td><tt>m3wrapimpl</tt></td>
<td>Implementation of the wrappers that
convert between Modula-3 and C types,
check for validity of values,
hand-over resource management to the garbage collector using <tt>WeakRef</tt>s
and raises exceptions.</td>
</tr>
<tr>
<td><tt>m3makefile</tt></td>
<td><tt>m3makefile</tt></td>
<td>Add the modules above to the Modula-3 project and
specify the name of the Modula-3 wrapper library
to be generated.
Today I'm not sure if it is a good idea
to create a <tt>m3makefile</tt> in each run,
because SWIG must be started for each Modula-3 module it creates.
Thus the m3makefile is overwritten each time. :-(
</td>
</tr>
</table>
<p>
Here's a scheme of how the function calls to Modula-3 wrappers
are redirected to C library functions:
</p>
<table summary="Modula-3 C library">
<tr>
<td align=center>
Modula-3 wrapper<br>
Module<tt>.i3</tt><br>
generated by Modula-3 part of SWIG
</td>
<td></td>
<td align=center></td>
</tr>
<tr>
<td align=center>
<!-- pre tag overrides centering -->
|<br>
v
</td>
<td></td>
<td align=center></td>
</tr>
<tr>
<td align=center>
Modula-3 interface to C<br>
Module<tt>Raw.i3</tt><br>
generated by Modula-3 part of SWIG
</td>
<td>--&gt;</td>
<td align=center>
C library
</td>
</tr>
</table>
<p>
I have still no good conception how one can split C library interfaces
into type oriented interfaces.
A Module in Modula-3 represents an Abstract DataType
(or call it a static classes, i.e. a class without virtual methods).
E.g. if you have a principal type, say <tt>Database</tt>,
it is good Modula-3 style to set up one Module with the name <tt>Database</tt>
where the database type is declared with the name <tt>T</tt>
and where all functions are declared that operates on it.
</p>
<p>
The normal operation of SWIG is to generate a fixed set of files per call.
To generate multiple modules one has to write one SWIG interface
(different SWIG interfaces can share common data) per module.
Identifiers belonging to a different module may ignored (<tt>%ignore</tt>)
and the principal type must be renamed (<tt>%typemap</tt>).
</p>
<H3><a name="Modula3_cppinterface"></a>24.2.2 Interfaces to C++ libraries</H3>
<p>
Interfaces to C++ files are much more complicated and
there are some more design decisions that are not made, yet.
Modula-3 has no support for C++ functions
but C++ compilers should support generating C++ functions
with a C interface.
</p>
<p>
Here's a scheme of how the function calls to Modula-3 wrappers
are redirected to C library functions:
</p>
<table summary="Modula-3 C++ library">
<tr>
<td align=center>
Modula-3 wrapper<br>
Module<tt>.i3</tt><br>
generated by Modula-3 part of SWIG
</td>
<td></td>
<td align=center>C++ library</td>
</tr>
<tr>
<td align=center>
<!-- pre tag overrides centering -->
|<br>
v
</td>
<td></td>
<td align=center>
^<br>
|
</td>
</tr>
<tr>
<td align=center>
Modula-3 interface to C<br>
Module<tt>Raw.i3</tt><br>
generated by Modula-3 part of SWIG
</td>
<td>--&gt;</td>
<td align=center>
C interface to C++<br>
module<tt>_wrap.cxx</tt><br>
generated by the SWIG core
</td>
</tr>
</table>
<p>
Wrapping C++ libraries arises additional problems:
</p>
<ul>
<li>
Is it sensible to wrap C++ classes with Modula-3 classes?
</li>
<li>
How to find the wrapping Modula-3 class
for a class pointer that is returned by a C++ routine?
</li>
<li>
How to deal with multiple inheritance
which was neglected for Modula-3 for good reasons?
</li>
<li>
Is it possible to sub-class C++ classes with Modula-3 code?
This issue is addressed by directors,
a feature that was experimentally added to some Language modules
like
<a href="Java.html#Java_directors">Java</a> and
<a href="Python.html#Python_directors">Python</a>.
</li>
<li>
How to manage storage with the garbage collector of Modula-3?
Support for
<a href="Customization.html#Customization_ownership">
<tt>%newobject</tt> and <tt>%typemap(newfree)</tt></a>
isn't implemented, yet.
What's about resources that are managed by the garbage collector
but shall be passed back to the storage management of the C++ library?
This is a general issue which is not solved in a satisfying fashion
as far as I know.
</li>
<li>
How to turn C++ exceptions into Modula-3 exceptions?
There's also no support for
<a href="Customization.html#Customization_exception">
<tt>%exception</tt></a>, yet.
</li>
</ul>
<p>
Be warned:
There is no C++ library I wrote a SWIG interface for,
so I'm not sure if this is possible or sensible, yet.
</p>
<H2><a name="Modula3_preliminaries"></a>24.3 Preliminaries</H2>
<H3><a name="Modula3_compilers"></a>24.3.1 Compilers</H3>
<p>
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
<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
may do so.
For testing examples I use Critical Mass cm3.
</p>
<H3><a name="Modula3_commandline"></a>24.3.2 Additional Commandline Options</H3>
<p>
There are some experimental command line options
that prevent SWIG from generating interface files.
Instead files are emitted that may assist you
when writing SWIG interface files.
</p>
<table border summary="Modula-3 specific options">
<tr>
<th>Modula-3 specific options</th>
<th>Description</th>
</tr>
<tr>
<td valign=top>-generateconst &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead write code for computing numeric values of constants
to the specified file.
<br>
C code may contain several constant definitions
written as preprocessor macros.
Other language modules of SWIG use
compute-once-use-readonly variables or
functions to wrap such definitions.
All of them can invoke C code dynamically
for computing the macro values.
But if one wants to turn them into Modula-3
integer constants, enumerations or set types,
the values of these expressions has to be known statically.
Although definitions like <tt>(1 &lt;&lt; FLAG_MAXIMIZEWINDOW)</tt>
must be considered as good C style
they are hard to convert to Modula-3
since the value computation can use every feature of C.
<br>
Thus I implemented these switch
to extract all constant definitions
and write a C program that output the values of them.
It works for numeric constants only
and treats all of them as <tt>double</tt>.
Future versions may generate a C++ program
that can detect the type of the macros
by overloaded output functions.
Then strings can also be processed.
</td>
</tr>
<tr>
<td valign=top>-generaterename &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead generate suggestions for <tt>%rename</tt>.
<br>
C libraries use a naming style
that is neither homogeneous nor similar to that of Modula-3.
C function names often contain a prefix denoting the library
and some name components separated by underscores
or capitalization changes.
To get library interfaces that are really Modula-3 like
you should rename the function names with the <tt>%rename</tt> directive.
This switch outputs a list of such directives
with a name suggestion generated by a simple heuristic.
</td>
</tr>
<tr>
<td valign=top>-generatetypemap &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead generate templates for some basic typemaps.
</td>
</tr>
</table>
<H2><a name="Modula3_typemaps"></a>24.4 Modula-3 typemaps</H2>
<H3><a name="Modula3_inoutparam"></a>24.4.1 Inputs and outputs</H3>
<p>
Each C procedure has a bunch of inputs and outputs.
Inputs are passed as function arguments,
outputs are updated referential arguments and
the function value.
</p>
<p>
Each C type can have several typemaps
that apply only in case if a type is used
for an input argument, for an output argument,
or for a return value.
A further typemap may specify
the direction that is used for certain parameters.
I have chosen this separation
in order to be able to write general typemaps for the typemap library
<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
.
In the library code the final usage of the type is not known.
Using separate typemaps for each possible use
allows appropriate definitions for each case.
If these pre-definitions are fine
then the direction of the function parameter
is the only hint the user must give.
</p>
<p>
The typemaps specific to Modula-3 have a common name scheme:
A typemap name starts with "m3",
followed by "raw" or "wrap"
depending on whether it controls the generation
of the Module<tt>Raw.i3</tt> or the Module<tt>.i3</tt>, respectively.
It follows an "in" for typemaps applied to input argument,
"out" for output arguments, "arg" for all kind of arguments,
"ret" for returned values.
</p>
<p>
The main task of SWIG is to build wrapper function,
i.e. functions that convert values between C and Modula-3
and call the corresponding C function.
Modula-3 wrapper functions generated by SWIG
consist of the following parts:
</p>
<ul>
<li>Generate <tt>PROCEDURE</tt> signature.</li>
<li>Declare local variables.</li>
<li>Convert input values from Modula-3 to C.</li>
<li>Check for input value integrity.</li>
<li>Call the C function.</li>
<li>Check returned values, e.g. error codes.</li>
<li>Convert and write back values into Modula-3 records.</li>
<li>Free temporary storage.</li>
<li>Return values.</li>
</ul>
<table border summary="Modula-3 typemaps">
<tr>
<th>Typemap</th>
<th>Example</th>
<th>Description</th>
</tr>
<tr>
<td>m3wrapargvar</td>
<td><tt>$1: INTEGER := $1_name;</tt></td>
<td>
Declaration of some variables needed for temporary results.
</td>
</tr>
<tr>
<td>m3wrapargconst</td>
<td><tt>$1 = "$1_name";</tt></td>
<td>
Declaration of some constant, maybe for debug purposes.
</td>
</tr>
<tr>
<td>m3wrapargraw</td>
<td><tt>ORD($1_name)</tt></td>
<td>
The expression that should be passed as argument to the raw Modula-3 interface function.
</td>
</tr>
<tr>
<td>m3wrapargdir</td>
<td><tt>out</tt></td>
<td>
Referential arguments can be used for input, output, update.
???
</td>
</tr>
<tr>
<td>m3wrapinmode</td>
<td><tt>READONLY</tt></td>
<td>
One of Modula-3 parameter modes
<tt>VALUE</tt> (or empty),
<tt>VAR</tt>,
<tt>READONLY</tt>
</td>
</tr>
<tr>
<td>m3wrapinname</td>
<td></td>
<td>
New name of the input argument.
</td>
</tr>
<tr>
<td>m3wrapintype</td>
<td></td>
<td>
Modula-3 type of the input argument.
</td>
</tr>
<tr>
<td>m3wrapindefault</td>
<td></td>
<td>
Default value of the input argument
</td>
</tr>
<tr>
<td>m3wrapinconv</td>
<td><tt>$1 := M3toC.SharedTtoS($1_name);</tt></td>
<td>
Statement for converting the Modula-3 input value to C compliant value.
</td>
</tr>
<tr>
<td>m3wrapincheck</td>
<td><tt>IF Text.Length($1_name) &gt; 10 THEN RAISE E("str too long"); END;</tt></td>
<td>
Check the integrity of the input value.
</td>
</tr>
<tr>
<td>m3wrapoutname</td>
<td></td>
<td>
Name of the <tt>RECORD</tt> field to be used for returning multiple values.
This applies to referential output arguments that shall be turned
into return values.
</td>
</tr>
<tr>
<td>m3wrapouttype</td>
<td></td>
<td>
Type of the value that is returned instead of a referential output argument.
</td>
</tr>
<tr>
<td>m3wrapoutconv</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapoutcheck</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretraw</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretname</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wraprettype</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretvar</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretconv</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretcheck</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapfreearg</td>
<td><tt>M3toC.FreeSharedS(str,arg1);</tt></td>
<td>
Free resources that were temporarily used in the wrapper.
Since this step should never be skipped,
SWIG will put it in the <tt>FINALLY</tt> branch
of a <tt>TRY .. FINALLY</tt> structure.
</td>
</tr>
</table>
<H3><a name="Modula3_ordinals"></a>24.4.2 Subranges, Enumerations, Sets</H3>
<p>
Subranges, enumerations, and sets are machine oriented types
that make Modula very strong and expressive compared
with the type systems of many other languages.
</p>
<ul>
<li>
Subranges are used for statically restricted choices of integers.
</li>
<li>
Enumerations are used for named choices.
</li>
<li>
Sets are commonly used for flag (option) sets.
</li>
</ul>
<p>
Using them extensively makes Modula code very safe and readable.
</p>
<p>
C supports enumerations, too, but they are not as safe as the ones of Modula.
Thus they are abused for many things:
For named choices, for integer constant definitions, for sets.
To make it complete every way of defining a value in C
(<tt>#define</tt>, <tt>const int</tt>, <tt>enum</tt>)
is somewhere used for defining something
that must be handled completely different in Modula-3
(<tt>INTEGER</tt>, enumeration, <tt>SET</tt>).
</p>
<p>
I played around with several <tt>%feature</tt>s and <tt>%pragma</tt>s
that split the task up into converting
the C bit patterns (integer or bit set)
into Modula-3 bit patterns (integer or bit set)
and change the type as requested.
See the corresponding example in the
Examples/modula3/enum/example.i file.
This is quite messy and not satisfying.
So the best what you can currently do is
to rewrite constant definitions manually.
Though this is a tedious work
that I'd like to automate.
</p>
<H3><a name="Modula3_class"></a>24.4.3 Objects</H3>
<p>
Declarations of C++ classes are mapped to <tt>OBJECT</tt> types
while it is tried to retain the access hierarchy
"public - protected - private" using partial revelation.
Though the example in
Examples/modula3/class/example.i
is not really useful, yet.
</p>
<H3><a name="Modula3_imports"></a>24.4.4 Imports</H3>
<p>
Pieces of Modula-3 code provided by typemaps
may contain identifiers from foreign modules.
If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
contains code using the function <tt>M3toC.SharedTtoS</tt>
you may declare <tt>%typemap("m3wrapinconv:import") blah * %{M3toC%}</tt>.
Then the module <tt>M3toC</tt> is imported
if the <tt>m3wrapinconv</tt> typemap for <tt>blah *</tt>
is used at least once.
Use <tt>%typemap("m3wrapinconv:import") blah * %{MyConversions AS M3toC%}</tt>
if you need module renaming.
Unqualified import is not supported.
</p>
<p>
It is cumbersome to add this typemap to each piece of Modula-3 code.
It is especially useful when writing general typemaps
for the typemap library
<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
.
For a monolithic module you might be better off
if you add the imports directly:
</p>
<div class="code">
<pre>
%insert(m3rawintf) %{
IMPORT M3toC;
%}
</pre></div>
<H3><a name="Modula3_exceptions"></a>24.4.5 Exceptions</H3>
<p>
Modula-3 provides another possibility
of an output of a function: exceptions.
</p>
<p>
Any piece 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 a Modula-3 exception.
</p>
<p>
The <tt>RAISES</tt> clause is controlled
by typemaps with the <tt>throws</tt> extension.
If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
contains code that may raise the exceptions <tt>OSError.E</tt>
you should declare
<tt>%typemap("m3wrapinconv:throws") blah * %{OSError.E%}</tt>.
</p>
<H3><a name="Modula3_typemap_example"></a>24.4.6 Example</H3>
<p>
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:
</p>
<div class="code"><pre>
<I> (* %relabel m3wrapinmode m3wrapinname m3wrapintype m3wrapindefault *)</I>
PROCEDURE Name (READONLY str : TEXT := "" )
<I> (* m3wrapoutcheck:throws *)</I>
: NameResult RAISES {E} =
CONST
arg1name = "str"; <I>(* m3wrapargconst *)</I>
VAR
arg0 : C.char_star; <I>(* m3wrapretvar *)</I>
arg1 : C.char_star; <I>(* m3wrapargvar *)</I>
arg2 : C.int;
result : RECORD
<I> (*m3wrapretname m3wraprettype*)</I>
unixPath : TEXT;
<I> (*m3wrapoutname m3wrapouttype*)</I>
checksum : CARDINAL;
END;
BEGIN
TRY
arg1 := M3toC.SharedTtoS(str); <I>(* m3wrapinconv *)</I>
IF Text.Length(arg1) &gt; 10 THEN <I>(* m3wrapincheck *)</I>
RAISE E("str too long");
END;
<I> (* m3wrapretraw m3wrapargraw *)</I>
arg0 := MessyToUnix (arg1, arg2);
result.unixPath := M3toC.CopyStoT(arg0); <I>(* m3wrapretconv *)</I>
result.checksum := arg2; <I>(* m3wrapoutconv *)</I>
IF result.checksum = 0 THEN <I>(* m3wrapoutcheck *)</I>
RAISE E("invalid checksum");
END;
FINALLY
M3toC.FreeSharedS(str,arg1); <I>(* m3wrapfreearg *)</I>
END;
END Name;
</pre></div>
<H2><a name="Modula3_hints"></a>24.5 More hints to the generator</H2>
<H3><a name="Modula3_features"></a>24.5.1 Features</H3>
<table border summary="Modula-3 features">
<tr>
<th>Feature</th>
<th>Example</th>
<th>Description</th>
</tr>
<tr>
<td>multiretval</td>
<td><tt>%m3multiretval get_box;</tt> or
<tt>%feature("modula3:multiretval") get_box;</tt></td>
<td>Let the denoted function return a <tt>RECORD</tt>
rather than a plain value.
This <tt>RECORD</tt> contains all arguments with "out" direction
including the return value of the C function (if there is one).
If more than one argument is "out"
then the function <b>must</b> have the <tt>multiretval</tt> feature activated,
but it is explicitly requested from the user to prevent mistakes.</td>
</tr>
<tr>
<td>constnumeric</td>
<td><tt>%constnumeric(12) twelve;</tt> or
<tt>%feature("constnumeric","12") twelve;</tt></td>
<td>This feature can be used to tell Modula-3's back-end of SWIG
the value of an identifier.
This is necessary in the cases
where it was defined by a non-trivial C expression.
This feature is used by the
<tt>-generateconst</tt> <a href="#Modula3_commandline">option</a>.
In future it may be generalized to other kind of values
such as strings.
</td>
</tr>
</table>
<H3><a name="Modula3_pragmas"></a>24.5.2 Pragmas</H3>
<table border summary="Modula-3 pragmas">
<tr>
<th>Pragma</th>
<th>Example</th>
<th>Description</th>
</tr>
<tr>
<td>unsafe</td>
<td><tt>%pragma(modula3) unsafe="true";</tt></td>
<td>Mark the raw interface modules as <tt>UNSAFE</tt>.
This will be necessary in many cases.</td>
</tr>
<tr>
<td>library</td>
<td><tt>%pragma(modula3) library="m3fftw";</tt></td>
<td>Specifies the library name for the wrapper library to be created.
It should be distinct from the name of the library to be wrapped.</td>
</tr>
</table>
<H2><a name="Modula3_remarks"></a>24.6 Remarks</H2>
<ul>
<li>
The Modula-3 part of SWIG doesn't try to generate nicely formatted code.
If you need to read the generated code, use <tt>m3pp</tt> to postprocess the
Modula files.
</li>
</ul>
</body>
</html>