mirror of https://github.com/swig/swig
491 lines
13 KiB
HTML
491 lines
13 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<title>SWIG Preprocessor</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
<H1><a name="Preprocessor"></a>7 Preprocessing</H1>
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Preprocessor_nn2">File inclusion</a>
|
|
<li><a href="#Preprocessor_nn3">File imports</a>
|
|
<li><a href="#Preprocessor_condition_compilation">Conditional Compilation</a>
|
|
<li><a href="#Preprocessor_nn5">Macro Expansion</a>
|
|
<li><a href="#Preprocessor_nn6">SWIG Macros</a>
|
|
<li><a href="#Preprocessor_nn7">C99 and GNU Extensions</a>
|
|
<li><a href="#Preprocessor_nn8">Preprocessing and %{ ... %} & " ... " delimiters</a>
|
|
<li><a href="#Preprocessor_nn9">Preprocessing and { ... } delimiters</a>
|
|
<li><a href="#Preprocessor_typemap_delimiters">Preprocessor and Typemaps</a>
|
|
<li><a href="#Preprocessor_nn10">Viewing preprocessor output</a>
|
|
<li><a href="#Preprocessor_warning_error">The #error and #warning directives</a>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
<p>
|
|
SWIG includes its own enhanced version of the C preprocessor. The preprocessor
|
|
supports the standard preprocessor directives and macro expansion rules.
|
|
However, a number of modifications and enhancements have been made. This
|
|
chapter describes some of these modifications.
|
|
</p>
|
|
|
|
<H2><a name="Preprocessor_nn2"></a>7.1 File inclusion</H2>
|
|
|
|
|
|
<p>
|
|
To include another file into a SWIG interface, use the <tt>%include</tt> directive
|
|
like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%include "pointer.i"
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Unlike, <tt>#include</tt>, <tt>%include</tt> includes each file once (and will not
|
|
reload the file on subsequent <tt>%include</tt> declarations). Therefore, it
|
|
is not necessary to use include-guards in SWIG interfaces.
|
|
</p>
|
|
|
|
<p>
|
|
By default, the <tt>#include</tt> is ignored unless you run SWIG with the
|
|
<tt>-includeall</tt> option. The reason for ignoring traditional includes
|
|
is that you often don't want SWIG to try and wrap everything included
|
|
in standard header system headers and auxiliary files.
|
|
|
|
<H2><a name="Preprocessor_nn3"></a>7.2 File imports</H2>
|
|
|
|
|
|
<p>
|
|
SWIG provides another file inclusion directive with the <tt>%import</tt> directive.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%import "foo.i"
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The purpose of <tt>%import</tt> is to collect certain information from another
|
|
SWIG interface file or a header file without actually generating any wrapper code.
|
|
Such information generally includes type declarations (e.g., <tt>typedef</tt>) as well as
|
|
C++ classes that might be used as base-classes for class declarations in the interface.
|
|
The use of <tt>%import</tt> is also important when SWIG is used to generate
|
|
extensions as a collection of related modules. This is an advanced topic and is described
|
|
in a later chapter.
|
|
</p>
|
|
|
|
<P>
|
|
The <tt>-importall</tt> directive tells SWIG to follow all <tt>#include</tt> statements
|
|
as imports. This might be useful if you want to extract type definitions from system
|
|
header files without generating any wrappers.
|
|
|
|
<H2><a name="Preprocessor_condition_compilation"></a>7.3 Conditional Compilation</H2>
|
|
|
|
|
|
<p>
|
|
SWIG fully supports the use of <tt>#if</tt>, <tt>#ifdef</tt>,
|
|
<tt>#ifndef</tt>, <tt>#else</tt>, <tt>#endif</tt> to conditionally
|
|
include parts of an interface. The following symbols are predefined
|
|
by SWIG when it is parsing the interface:
|
|
</p>
|
|
|
|
<div class="code"><pre>
|
|
SWIG Always defined when SWIG is processing a file
|
|
SWIGIMPORTED Defined when SWIG is importing a file with <tt>%import</tt>
|
|
SWIGMAC Defined when running SWIG on the Macintosh
|
|
SWIGWIN Defined when running SWIG under Windows
|
|
SWIG_VERSION Hexadecimal number containing SWIG version,
|
|
such as 0x010311 (corresponding to SWIG-1.3.11).
|
|
|
|
SWIGCHICKEN Defined when using CHICKEN
|
|
SWIGCSHARP Defined when using C#
|
|
SWIGGUILE Defined when using Guile
|
|
SWIGJAVA Defined when using Java
|
|
SWIGLUA Defined when using Lua
|
|
SWIGMODULA3 Defined when using Modula-3
|
|
SWIGMZSCHEME Defined when using Mzscheme
|
|
SWIGOCAML Defined when using Ocaml
|
|
SWIGPERL Defined when using Perl
|
|
SWIGPERL5 Defined when using Perl5
|
|
SWIGPHP Defined when using PHP
|
|
SWIGPHP4 Defined when using PHP4
|
|
SWIGPHP5 Defined when using PHP5
|
|
SWIGPIKE Defined when using Pike
|
|
SWIGPYTHON Defined when using Python
|
|
SWIGRUBY Defined when using Ruby
|
|
SWIGSEXP Defined when using S-expressions
|
|
SWIGTCL Defined when using Tcl
|
|
SWIGTCL8 Defined when using Tcl8.0
|
|
SWIGXML Defined when using XML
|
|
</pre></div>
|
|
|
|
<p>
|
|
In addition, SWIG defines the following set of standard C/C++ macros:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
__LINE__ Current line number
|
|
__FILE__ Current file name
|
|
__STDC__ Defined to indicate ANSI C
|
|
__cplusplus Defined when -c++ option used
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Interface files can look at these symbols as necessary to change the
|
|
way in which an interface is generated or to mix SWIG directives with
|
|
C code. These symbols are also defined within the C code generated by
|
|
SWIG (except for the symbol `<tt>SWIG</tt>' which is only defined
|
|
within the SWIG compiler).
|
|
</p>
|
|
|
|
<H2><a name="Preprocessor_nn5"></a>7.4 Macro Expansion</H2>
|
|
|
|
|
|
<p>
|
|
Traditional preprocessor macros can be used in SWIG interfaces. Be aware that the <tt>#define</tt> statement
|
|
is also used to try and detect constants. Therefore, if you have something like this in your file,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#ifndef _FOO_H 1
|
|
#define _FOO_H 1
|
|
...
|
|
#endif
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
you may get some extra constants such as <tt>_FOO_H</tt> showing up in the scripting interface.
|
|
</p>
|
|
|
|
<p>
|
|
More complex macros can be defined in the standard way. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define EXTERN extern
|
|
#ifdef __STDC__
|
|
#define _ANSI(args) (args)
|
|
#else
|
|
#define _ANSI(args) ()
|
|
#endif
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The following operators can appear in macro definitions:
|
|
</p>
|
|
|
|
<ul>
|
|
<li><tt>#x</tt><br>
|
|
Converts macro argument <tt>x</tt> to a string surrounded by double quotes ("x").
|
|
</li>
|
|
|
|
<li><tt>x ## y</tt><br>
|
|
Concatenates x and y together to form <tt>xy</tt>.
|
|
</li>
|
|
|
|
<li><tt>`x`</tt><br>
|
|
If <tt>x</tt> is a string surrounded by double quotes, do nothing. Otherwise, turn into a string
|
|
like <tt>#x</tt>. This is a non-standard SWIG extension.
|
|
</li>
|
|
</ul>
|
|
|
|
<H2><a name="Preprocessor_nn6"></a>7.5 SWIG Macros</H2>
|
|
|
|
|
|
<p>
|
|
SWIG provides an enhanced macro capability with the <tt>%define</tt> and <tt>%enddef</tt> directives.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%define ARRAYHELPER(type,name)
|
|
%inline %{
|
|
type *new_ ## name (int nitems) {
|
|
return (type *) malloc(sizeof(type)*nitems);
|
|
}
|
|
void delete_ ## name(type *t) {
|
|
free(t);
|
|
}
|
|
type name ## _get(type *t, int index) {
|
|
return t[index];
|
|
}
|
|
void name ## _set(type *t, int index, type val) {
|
|
t[index] = val;
|
|
}
|
|
%}
|
|
%enddef
|
|
|
|
ARRAYHELPER(int, IntArray)
|
|
ARRAYHELPER(double, DoubleArray)
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The primary purpose of <tt>%define</tt> is to define large macros of code. Unlike normal C preprocessor
|
|
macros, it is not necessary to terminate each line with a continuation character (\)--the macro definition
|
|
extends to the first occurrence of <tt>%enddef</tt>. Furthermore, when such macros are expanded,
|
|
they are reparsed through the C preprocessor. Thus, SWIG macros can contain all other preprocessor
|
|
directives except for nested <tt>%define</tt> statements.
|
|
</p>
|
|
|
|
<p>
|
|
The SWIG macro capability is a very quick and easy way to generate large amounts of code. In fact,
|
|
many of SWIG's advanced features and libraries are built using this mechanism (such as C++ template
|
|
support).
|
|
</p>
|
|
|
|
<H2><a name="Preprocessor_nn7"></a>7.6 C99 and GNU Extensions</H2>
|
|
|
|
|
|
<p>
|
|
SWIG-1.3.12 and newer releases support variadic preprocessor macros. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define DEBUGF(fmt,...) fprintf(stderr,fmt,__VA_ARGS__)
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When used, any extra arguments to <tt>...</tt> are placed into the
|
|
special variable <tt>__VA_ARGS__</tt>. This also works with special SWIG
|
|
macros defined using <tt>%define</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
SWIG allows a variable number of arguments to be empty. However, this often results
|
|
in an extra comma (,) and syntax error in the resulting expansion. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
DEBUGF("hello"); --> fprintf(stderr,"hello",);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
To get rid of the extra comma, use <tt>##</tt> like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define DEBUGF(fmt,...) fprintf(stderr,fmt, ##__VA_ARGS__)
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
SWIG also supports GNU-style variadic macros. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define DEBUGF(fmt, args...) fprintf(stdout,fmt,args)
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>Comment:</b> It's not entirely clear how variadic macros might be useful to
|
|
interface building. However, they are used internally to implement a number of
|
|
SWIG directives and are provided to make SWIG more compatible with C99 code.
|
|
</p>
|
|
|
|
<H2><a name="Preprocessor_nn8"></a>7.7 Preprocessing and %{ ... %} & " ... " delimiters</H2>
|
|
|
|
|
|
<p>
|
|
The SWIG preprocessor does not process any text enclosed in a code block %{ ... %}. Therefore,
|
|
if you write code like this,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%{
|
|
#ifdef NEED_BLAH
|
|
int blah() {
|
|
...
|
|
}
|
|
#endif
|
|
%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
the contents of the <tt>%{ ... %}</tt> block are copied without
|
|
modification to the output (including all preprocessor directives).
|
|
</p>
|
|
|
|
<H2><a name="Preprocessor_nn9"></a>7.8 Preprocessing and { ... } delimiters</H2>
|
|
|
|
|
|
<p>
|
|
SWIG always runs the preprocessor on text appearing inside <tt>{ ... }</tt>. However,
|
|
sometimes it is desirable to make a preprocessor directive pass through to the output
|
|
file. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%extend Foo {
|
|
void bar() {
|
|
#ifdef DEBUG
|
|
printf("I'm in bar\n");
|
|
#endif
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
By default, SWIG will interpret the <tt>#ifdef DEBUG</tt> statement. However, if you really wanted that code
|
|
to actually go into the wrapper file, prefix the preprocessor directives with <tt>%</tt> like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%extend Foo {
|
|
void bar() {
|
|
%#ifdef DEBUG
|
|
printf("I'm in bar\n");
|
|
%#endif
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
SWIG will strip the extra <tt>%</tt> and leave the preprocessor directive in the code.
|
|
</p>
|
|
|
|
<H2><a name="Preprocessor_typemap_delimiters"></a>7.9 Preprocessor and Typemaps</H2>
|
|
|
|
|
|
<p>
|
|
<a href="Typemaps.html">Typemaps</a> support a special attribute called <tt>noblock</tt> where the { ... } delimiters can be used,
|
|
but the delimiters are not actually generated into the code.
|
|
The effect is then similar to using "" or %{ %} delimiters but the code <b>is</b> run through the preprocessor. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define SWIG_macro(CAST) (CAST)$input
|
|
%typemap(in) Int {$1= SWIG_macro(int);}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
might generate
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
{
|
|
arg1=(int)jarg1;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
whereas
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define SWIG_macro(CAST) (CAST)$input
|
|
%typemap(in,noblock=1) Int {$1= SWIG_macro(int);}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
might generate
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
arg1=(int)jarg1;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
and
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define SWIG_macro(CAST) (CAST)$input
|
|
%typemap(in) Int %{$1=SWIG_macro(int);%}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
would generate
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
arg1=SWIG_macro(int);
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<H2><a name="Preprocessor_nn10"></a>7.10 Viewing preprocessor output</H2>
|
|
|
|
|
|
<p>
|
|
Like many compilers, SWIG supports a <tt>-E</tt> command line option to display the output from the preprocessor.
|
|
When the <tt>-E</tt> switch is used, SWIG will not generate any wrappers.
|
|
Instead the results after the preprocessor has run are displayed.
|
|
This might be useful as an aid to debugging and viewing the results of macro expansions.
|
|
</p>
|
|
|
|
<H2><a name="Preprocessor_warning_error"></a>7.11 The #error and #warning directives</H2>
|
|
|
|
|
|
<p>
|
|
SWIG supports the commonly used <tt>#warning</tt> and <tt>#error</tt> preprocessor directives.
|
|
The <tt>#warning</tt> directive will cause SWIG to issue a warning then continue processing.
|
|
The <tt>#error</tt> directive will cause SWIG to exit with a fatal error.
|
|
Example usage:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#error "This is a fatal error message"
|
|
#warning "This is a warning message"
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The <tt>#error</tt> behaviour can be made to work like <tt>#warning</tt> if the <tt>-cpperraswarn</tt>
|
|
commandline option is used. Alternatively, the <tt>#pragma</tt> directive can be used to the same effect, for example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
/* Modified behaviour: #error does not cause SWIG to exit with error */
|
|
#pragma SWIG cpperraswarn=1
|
|
/* Normal behaviour: #error does cause SWIG to exit with error */
|
|
#pragma SWIG cpperraswarn=0
|
|
</pre>
|
|
</div>
|
|
|
|
</body>
|
|
</html>
|