SWIG Preprocessor

# 6 Preprocessing

- File inclusion
- File imports
- Conditional Compilation
- Macro Expansion
- SWIG Macros
- C99 Extensions
- Preprocessing and %{ ... %} blocks
- Preprocessing and { ... }

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.

## 6.1 File inclusion

To include another file into a SWIG interface, use the `%include` directive like this:

>     %include "pointer.i"

Unlike, `#include`, `%include` includes each file once (and will not reload the file on subsequent `%include` declarations). Therefore, it is not necessary to use include-guards in SWIG interfaces.

By default, the `#include` is ignored unless you run SWIG with the `-includeall` 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.

## 6.2 File imports

SWIG provides another file inclusion directive with the `%import` directive. For example:

>     %import "foo.i"

The purpose of `%import` 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., `typedef`) as well as C++ classes that might be used as base-classes for class declarations in the interface. The use of `%import` 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.

The `-importall` directive tells SWIG to follow all `#include` statements as imports. This might be useful if you want to extract type definitions from system header files without generating any wrappers.

## 6.3 Conditional Compilation

SWIG fully supports the use of `#if`, `#ifdef`, `#ifndef`, `#else`, `#endif` to conditionally include parts of an interface. The following symbols are predefined by SWIG when it is parsing the interface:

>     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

In addition, SWIG defines the following set of standard C/C++ macros:

>     __LINE__                        Current line number
>     __FILE__                        Current file name
>     __STDC__                        Defined to indicate ANSI C
>     __cplusplus                     Defined when -c++ option used

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 ``SWIG`' which is only defined within the SWIG compiler).

## 6.4 Macro Expansion

Traditional preprocessor macros can be used in SWIG interfaces. Be aware that the `#define` statement is also used to try and detect constants. Therefore, if you have something like this in your file,

>     #ifndef _FOO_H 1
>     #define _FOO_H 1
>     ...
>     #endif

you may get some extra constants such as `_FOO_H` showing up in the scripting interface.

More complex macros can be defined in the standard way. For example:

>     #define EXTERN extern
>     #ifdef __STDC__
>     #define _ANSI(args)   (args)
>     #else
>     #define _ANSI(args) ()
>     #endif

The following operators can appear in macro definitions:

- `#x`
  Converts macro argument `x` to a string surrounded by double quotes ("x").

- `x ## y`
  Concatenates x and y together to form `xy`.

- ``x``
  If `x` is a string surrounded by double quotes, do nothing. Otherwise, turn into a string like `#x`. This is a non-standard SWIG extension.

## 6.5 SWIG Macros

SWIG provides an enhanced macro capability with the `%define` and `%enddef` directives. For example:

>     %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)

The primary purpose of `%define` 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 `%enddef`. 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 `%define` statements.

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).

## 6.6 C99 Extensions

SWIG-1.3.12 and newer releases support variadic preprocessor macros. For example:

>     #define DEBUGF(fmt,...)   fprintf(stderr,fmt,__VA_ARGS__)

When used, any extra arguments to `...` are placed into the special variable `__VA_ARGS__`. This also works with special SWIG macros defined using `%define`.

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:

>     DEBUGF("hello");   --> fprintf(stderr,"hello",);

To get rid of the extra comma, use `##` like this:

>     #define DEBUGF(fmt,...)   fprintf(stderr,fmt, ##__VA_ARGS__)

Comment: 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.

## 6.7 Preprocessing and %{ ... %} blocks

The SWIG preprocessor does not process any text enclosed in a code block %{ ... %}. Therefore, if you write code like this,

>     %{
>     #ifdef NEED_BLAH
>     int blah() {
>        ...
>     }
>     #endif
>     %}

the contents of the `%{ ... %}` block are copied without modification to the output (including all preprocessor directives).

## 6.8 Preprocessing and { ... }

SWIG always runs the preprocessor on text appearing inside `{ ... }`. However, sometimes it is desirable to make a preprocessor directive pass through to the output file. For example:

>     %extend Foo {
>        void bar() {
>           #ifdef DEBUG
>            printf("I'm in bar\n");
>           #endif
>        }
>     }

By default, SWIG will interpret the `#ifdef DEBUG` statement. However, if you really wanted that code to actually go into the wrapper file, prefix the preprocessor directives with `%` like this:

>     %extend Foo {
>        void bar() {
>           %#ifdef DEBUG
>            printf("I'm in bar\n");
>           %#endif
>        }
>     }

SWIG will strip the extra `%` and leave the preprocessor directive in the code.