swig/Doc/Manual/Preprocessor.html

619 lines
18 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SWIG Preprocessor</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body bgcolor="#ffffff">
<H1><a name="Preprocessor">11 Preprocessing</a></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">Variadic Macros</a>
<li><a href="#Preprocessor_delimiters">Preprocessing and delimiters</a>
<ul>
<li><a href="#Preprocessor_nn8">Preprocessing and %{ ... %} &amp; " ... " delimiters</a>
<li><a href="#Preprocessor_nn9">Preprocessing and { ... } delimiters</a>
</ul>
<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>
<li><a href="#Preprocessor_trigraphs">Trigraphs</a>
<li><a href="#Preprocessor_digraphs">Digraphs</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">11.1 File inclusion</a></H2>
<p>
To include another file into a SWIG interface, use the <tt>%include</tt> directive
like this:
</p>
<div class="code">
<pre>
%include "cpointer.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">11.2 File imports</a></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 later in the <a href="Modules.html#Modules">Working with Modules</a> 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">11.3 Conditional Compilation</a></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.
</p>
<p>
SWIG's preprocessor conditionals support the standard C/C++ preprocessor
integer expressions. As a SWIG-specific extension, string equality and
inequality tests are also supported, for example:
</p>
<div class="code">
<pre>
#if defined __cplusplus &amp;&amp; (#__VA_ARGS__ != "" || #TYPE == "void")
</pre>
</div>
<p>
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>
SWIG_VERSION Hexadecimal (binary-coded decimal) number containing SWIG version,
such as 0x010311 (corresponding to SWIG-1.3.11).
SWIGCSHARP Defined when using C#
SWIGD Defined when using D
SWIGGO Defined when using Go
SWIGGUILE Defined when using Guile
SWIGJAVA Defined when using Java
SWIGJAVASCRIPT Defined when using Javascript
SWIG_JAVASCRIPT_JSC Defined when using Javascript with -jsc
SWIG_JAVASCRIPT_V8 Defined when using Javascript with -v8 or -node
SWIG_JAVASCRIPT_NAPI Defined when using Javascript with -napi
SWIGLUA Defined when using Lua
SWIGOCAML Defined when using OCaml
SWIGOCTAVE Defined when using Octave
SWIGPERL Defined when using Perl
SWIGPHP Defined when using PHP (any version)
SWIGPHP7 Defined when using PHP 7 or later (with a compatible C API)
SWIGPYTHON Defined when using Python
SWIGR Defined when using R
SWIGRUBY Defined when using Ruby
SWIGSCILAB Defined when using Scilab
SWIGTCL Defined when using Tcl
SWIGXML Defined when using XML
</pre></div>
<p>
SWIG also defines <tt>SWIG_VERSION</tt> and a target language macro in
the generated wrapper file (since SWIG 4.1.0 - in older versions these
were defined for some target languages but this wasn't consistent). Best
practice is to use SWIG-time conditional checks because that results in smaller
generated wrapper sources.
</p>
<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 ISO C/C++
__cplusplus Defined when -c++ option used, value controlled by <tt>-std=c++NN</tt>
__STDC_VERSION__ May be defined when -c++ option is not used, value controlled by <tt>-std=cNN</tt>
</pre>
</div>
<p>
Since SWIG 4.2.0, <tt>__STDC__</tt> is defined to <tt>1</tt> to match
the behaviour of ISO C/C++ compilers. Before this SWIG defined it to
have an empty value.
</p>
<p>
Since SWIG 4.2.0, <tt>__cplusplus</tt> is defined to <tt>199711L</tt>
(the value for C++98) by default. Before this SWIG always defined it to have
the <b>value</b> <tt>__cplusplus</tt>.
</p>
<p>
Since SWIG 4.2.0, SWIG supports command line options <tt>-std=cNN</tt> and
<tt>-std=c++NN</tt> to specify the C/C++ standards version. The only effect of
these options is to set appropriate values for <tt>__STDC_VERSION__</tt> and
<tt>__cplusplus</tt> respectively, which is useful if you're wrapping
headers which have preprocessor checks based on their values.
</p>
<p>
If your code requires these macros to be set to a version of the standard
that is not a final official version, or one that SWIG is not yet aware of,
you can simply redefine the appropriate macro to an alternative value at the
top of your interface file, for example:
</p>
<div class="code"><pre>
#undef __cplusplus
#define __cplusplus 202211L
</pre></div>
<p>
The following are language specific symbols that might be defined:
</p>
<div class="code"><pre>
SWIG_D_VERSION Unsigned integer target version when using D
SWIGGO_CGO Defined when using Go for cgo
SWIGGO_GCCGO Defined when using Go for gccgo
SWIGGO_INTGO_SIZE Size of the Go type int when using Go (32 or 64)
SWIGPYTHON_BUILTIN Defined when using Python with -builtin
SWIGPYTHON_NOGIL Defined when using Python with -nogil
SWIG_RUBY_AUTORENAME Defined when using Ruby with -autorename
</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.
</p>
<H2><a name="Preprocessor_nn5">11.4 Macro Expansion</a></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 ISOC_(args) (args)
#else
#define ISOC_(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">11.5 SWIG Macros</a></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">11.6 Variadic Macros</a></H2>
<p>
SWIG-1.3.12 and newer releases support variadic preprocessor macros which were
standardised by C99 and C++11. 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>
The variable arguments can be empty. However, this often results
in an extra comma (<tt>,</tt>) and syntax error in the resulting expansion. For
example:
</p>
<div class="code">
<pre>
DEBUGF("hello"); --&gt; fprintf(stderr, "hello", );
</pre>
</div>
<p>
C++20 and C23 added <tt>__VA_OPT__()</tt> as a solution to this, which SWIG
4.3.0 added support for. <tt>__VA_OPT__()</tt> expands to its argument if the
variable arguments contain any tokens, and to nothing otherwise. It can be
used to solve the problem above like so:
</p>
<div class="code">
<pre>
#define DEBUGF(fmt, ...) fprintf(stderr, fmt __VA_OPT__(,) __VA_ARGS__)
</pre>
</div>
<p>
An early non-standardised solution to this problem which gave a special
meaning to the token sequence <tt>, ## __VA_ARGS__</tt> is supported by
several C and C++ compilers, and also by SWIG 4.3.0 and later (it was
documented as supported by earlier SWIG versions, but didn't actually work in
at least SWIG 2.x and 3.x). Using this feature you can get rid of the extra
comma 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, which specify a name for the
variable arguments instead of using <tt>__VA_ARGS__</tt>. For example:
</p>
<div class="code">
<pre>
#define DEBUGF(fmt, args...) fprintf(stdout, fmt, args)
</pre>
</div>
<p>
SWIG supports <tt>__VA_OPT__()</tt> in combination with GNU-style variadic
macros (following the lead of GCC and clang which also support this, albeit
with a warning by default).
</p>
<H2><a name="Preprocessor_delimiters">11.7 Preprocessing and delimiters</a></H2>
<p>
The preprocessor handles { }, " " and %{ %} delimiters differently.
</p>
<H3><a name="Preprocessor_nn8">11.7.1 Preprocessing and %{ ... %} &amp; " ... " delimiters</a></H3>
<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>
<H3><a name="Preprocessor_nn9">11.7.2 Preprocessing and { ... } delimiters</a></H3>
<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">11.8 Preprocessor and Typemaps</a></H2>
<p>
<a href="Typemaps.html#Typemaps">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">11.9 Viewing preprocessor output</a></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> option 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">11.10 The #error and #warning directives</a></H2>
<p>
SWIG supports the standard <tt>#warning</tt> and <tt>#error</tt> preprocessor directives.
The <tt>#warning</tt> directive will cause SWIG to issue a warning then continue processing.
It was standardised in C++23 and C23, and has been widely supported as an extension by
most C and C++ compilers for a long time.
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>
<H2><a name="Preprocessor_trigraphs">11.11 Trigraphs</a></H2>
<p>
SWIG's preprocessor does not implement trigraphs (such as <tt>??!</tt> being
mapped to <tt>|</tt>). They are very rarely used deliberately but these
character sequences sometimes occur in code where they aren't intended as
trigraphs. Compilers typically don't enable trigraph support by default, and
they've been removed in C++17 and C23.
</p>
<H2><a name="Preprocessor_digraphs">11.12 Digraphs</a></H2>
<p>
SWIG's preprocessor does not currently implement digraphs (such as
<tt>&lt;%</tt> being an alternative way to write the token <tt>{</tt>).
These are standard in C++ and C95, but they're intended to support working with
code on systems with very restricted character sets which are really rare
these days so digraphs just don't seem to be used in practice.
</p>
</body>
</html>