diff options
Diffstat (limited to 'Doc/Manual/Preprocessor.html')
-rw-r--r-- | Doc/Manual/Preprocessor.html | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/Doc/Manual/Preprocessor.html b/Doc/Manual/Preprocessor.html new file mode 100644 index 000000000..3ef1f43c3 --- /dev/null +++ b/Doc/Manual/Preprocessor.html @@ -0,0 +1,302 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> +<title>SWIG Preprocessor</title> +</head> + +<body bgcolor="#ffffff"> +<a name="n1"></a><H1>6 Preprocessing</H1> +<!-- INDEX --> +<ul> +<li><a href="#n2">File inclusion</a> +<li><a href="#n3">File imports</a> +<li><a href="#n4">Conditional Compilation</a> +<li><a href="#n5">Macro Expansion</a> +<li><a href="#n6">SWIG Macros</a> +<li><a href="#n7">C99 Extensions</a> +<li><a href="#n8">Preprocessing and %{ ... %} blocks</a> +<li><a href="#n9">Preprocessing and { ... }</a> +</ul> +<!-- INDEX --> + + + +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. + +<a name="n2"></a><H2>6.1 File inclusion</H2> + + +To include another file into a SWIG interface, use the <tt>%include</tt> directive +like this: + +<blockquote> +<pre> +%include "pointer.i" +</pre> +</blockquote> + +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> +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 auxilliary files. + +<a name="n3"></a><H2>6.2 File imports</H2> + + +SWIG provides another file inclusion directive with the <tt>%import</tt> directive. +For example: + +<blockquote> +<pre> +%import "foo.i" +</pre> +</blockquote> + +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 advanced topic and is described +in a later chapter. + +<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. + +<a name="n4"></a><H2>6.3 Conditional Compilation</H2> + + +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> +<blockquote><pre> +SWIG Always defined when SWIG is processing a file +SWIGTCL Defined when using Tcl +SWIGTCL8 Defined when using Tcl8.0 +SWIGPERL Defined when using Perl +SWIGPERL5 Defined when using Perl5 +SWIGPYTHON Defined when using Python +SWIGGUILE Defined when using Guile +SWIGRUBY Defined when using Ruby +SWIGJAVA Defined when using Java +SWIGMZSCHEME Defined when using Mzscheme +SWIGWIN Defined when running SWIG under Windows +SWIGMAC Defined when running SWIG on the Macintosh +</pre></blockquote> + +In addition, SWIG defines the following set of standard C/C++ macros: + +<blockquote> +<pre> +__LINE__ Current line number +__FILE__ Current file name +__STDC__ Defined to indicate ANSI C +__cplusplus Defined when -c++ option used +</pre> +</blockquote> + +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> + +<a name="n5"></a><H2>6.4 Macro Expansion</H2> + + +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, + +<blockquote> +<pre> +#ifndef _FOO_H 1 +#define _FOO_H 1 +... +#endif +</pre> +</blockquote> +you may get some extra constants such as <tt>_FOO_H</tt> showing up in the scripting interface. + +<p> +More complex macros can be defined in the standard way. For example: + +<blockquote> +<pre> +#define EXTERN extern +#ifdef __STDC__ +#define _ANSI(args) (args) +#else +#define _ANSI(args) () +#endif +</pre> +</blockquote> + +The following operators can appear in macro definitions: + +<ul> +<li><tt>#x</tt><br> +Converts macro argument <tt>x</tt> to a string surrounded by double quotes ("x"). + +<p> +<li><tt>x ## y</tt><br> +Concatenates x and y together to form <tt>xy</tt>. + +<p> +<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. +</ul> + +<a name="n6"></a><H2>6.5 SWIG Macros</H2> + + +SWIG provides an enhanced macro capability with the <tt>%define</tt> and <tt>%enddef</tt> directives. +For example: + +<blockquote> +<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> +</blockquote> + +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> +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). + +<a name="n7"></a><H2>6.6 C99 Extensions</H2> + + +SWIG-1.3.12 and newer releases support variadic preprocessor macros. For example: + +<blockquote> +<pre> +#define DEBUGF(fmt,...) fprintf(stderr,fmt,__VA_ARGS__) +</pre> +</blockquote> + +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> +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: + +<blockquote> +<pre> +DEBUGF("hello"); --> fprintf(stderr,"hello",); +</pre> +</blockquote> + +To get rid of the extra comma, use <tt>##</tt> like this: + +<blockquote> +<pre> +#define DEBUGF(fmt,...) fprintf(stderr,fmt, ##__VA_ARGS__) +</pre> +</blockquote> + +<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. + +<a name="n8"></a><H2>6.7 Preprocessing and %{ ... %} blocks</H2> + + +The SWIG preprocessor does not process any text enclosed in a code block %{ ... %}. Therefore, +if you write code like this, + +<blockquote> +<pre> +%{ +#ifdef NEED_BLAH +int blah() { + ... +} +#endif +%} +</pre> +</blockquote> + +the contents of the <tt>%{ ... %}</tt> block are copied without +modification to the output (including all preprocessor directives). + +<a name="n9"></a><H2>6.8 Preprocessing and { ... }</H2> + + +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: + +<blockquote> +<pre> +%extend Foo { + void bar() { + #ifdef DEBUG + printf("I'm in bar\n"); + #endif + } +} +</pre> +</blockquote> + +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: + +<blockquote> +<pre> +%extend Foo { + void bar() { + %#ifdef DEBUG + printf("I'm in bar\n"); + %#endif + } +} +</pre> +</blockquote> + +SWIG will strip the extra <tt>%</tt> and leave the preprocessor directive in the code. + +<p><hr> + +<address>SWIG 1.3 - Last Modified : May 25, 2002</address> +</body> +</html>
\ No newline at end of file |