mirror of https://github.com/swig/swig
3780 lines
104 KiB
HTML
3780 lines
104 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<title>Extending SWIG to support new languages</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
<H1><a name="Extending"></a>34 Extending SWIG to support new languages</H1>
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Extending_nn2">Introduction</a>
|
|
<li><a href="#Extending_nn3">Prerequisites</a>
|
|
<li><a href="#Extending_nn4">The Big Picture</a>
|
|
<li><a href="#Extending_nn5">Execution Model</a>
|
|
<ul>
|
|
<li><a href="#Extending_nn6">Preprocessing</a>
|
|
<li><a href="#Extending_nn7">Parsing</a>
|
|
<li><a href="#Extending_nn8">Parse Trees</a>
|
|
<li><a href="#Extending_nn9">Attribute namespaces</a>
|
|
<li><a href="#Extending_nn10">Symbol Tables</a>
|
|
<li><a href="#Extending_nn11">The %feature directive</a>
|
|
<li><a href="#Extending_nn12">Code Generation</a>
|
|
<li><a href="#Extending_nn13">SWIG and XML</a>
|
|
</ul>
|
|
<li><a href="#Extending_nn14">Primitive Data Structures</a>
|
|
<ul>
|
|
<li><a href="#Extending_nn15">Strings</a>
|
|
<li><a href="#Extending_nn16">Hashes</a>
|
|
<li><a href="#Extending_nn17">Lists</a>
|
|
<li><a href="#Extending_nn18">Common operations</a>
|
|
<li><a href="#Extending_nn19">Iterating over Lists and Hashes</a>
|
|
<li><a href="#Extending_nn20">I/O</a>
|
|
</ul>
|
|
<li><a href="#Extending_nn21">Navigating and manipulating parse trees</a>
|
|
<li><a href="#Extending_nn22">Working with attributes</a>
|
|
<li><a href="#Extending_nn23">Type system</a>
|
|
<ul>
|
|
<li><a href="#Extending_nn24">String encoding of types</a>
|
|
<li><a href="#Extending_nn25">Type construction</a>
|
|
<li><a href="#Extending_nn26">Type tests</a>
|
|
<li><a href="#Extending_nn27">Typedef and inheritance</a>
|
|
<li><a href="#Extending_nn28">Lvalues</a>
|
|
<li><a href="#Extending_nn29">Output functions</a>
|
|
</ul>
|
|
<li><a href="#Extending_nn30">Parameters</a>
|
|
<li><a href="#Extending_nn31">Writing a Language Module</a>
|
|
<ul>
|
|
<li><a href="#Extending_nn32">Execution model</a>
|
|
<li><a href="#Extending_nn33">Starting out</a>
|
|
<li><a href="#Extending_nn34">Command line options</a>
|
|
<li><a href="#Extending_nn35">Configuration and preprocessing</a>
|
|
<li><a href="#Extending_nn36">Entry point to code generation</a>
|
|
<li><a href="#Extending_nn37">Module I/O and wrapper skeleton</a>
|
|
<li><a href="#Extending_nn38">Low-level code generators</a>
|
|
<li><a href="#Extending_nn39">Configuration files</a>
|
|
<li><a href="#Extending_nn40">Runtime support</a>
|
|
<li><a href="#Extending_nn41">Standard library files</a>
|
|
<li><a href="#Extending_nn42">Examples and test cases</a>
|
|
<li><a href="#Extending_nn43">Documentation</a>
|
|
<li><a href="#Extending_prerequisites">Prerequisites for adding a new language module to the SWIG distribution</a>
|
|
<li><a href="#Extending_coding_style_guidelines">Coding style guidelines</a>
|
|
</ul>
|
|
<li><a href="#Extending_nn44">Typemaps</a>
|
|
<ul>
|
|
<li><a href="#Extending_nn45">Proxy classes</a>
|
|
</ul>
|
|
<li><a href="#Extending_nn46">Guide to parse tree nodes</a>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
<H2><a name="Extending_nn2"></a>34.1 Introduction</H2>
|
|
|
|
|
|
<p>
|
|
This chapter describes SWIG's internal organization and the process by which
|
|
new target languages can be developed. First, a brief word of warning---SWIG
|
|
is continually evolving.
|
|
The information in this chapter is mostly up to
|
|
date, but changes are ongoing. Expect a few inconsistencies.
|
|
</p>
|
|
|
|
<p>
|
|
Also, this chapter is not meant to be a hand-holding tutorial. As a starting point,
|
|
you should probably look at one of SWIG's existing modules.
|
|
</p>
|
|
|
|
<H2><a name="Extending_nn3"></a>34.2 Prerequisites</H2>
|
|
|
|
|
|
<p>
|
|
In order to extend SWIG, it is useful to have the following background:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>An understanding of the C API for the target language.
|
|
<li>A good grasp of the C++ type system.
|
|
<li>An understanding of typemaps and some of SWIG's advanced features.
|
|
<li>Some familiarity with writing C++ (language modules are currently written in C++).
|
|
</ul>
|
|
|
|
<p>
|
|
Since SWIG is essentially a specialized C++ compiler, it may be useful
|
|
to have some prior experience with compiler design (perhaps even a
|
|
compilers course) to better understand certain parts of the system. A
|
|
number of books will also be useful. For example, "The C Programming
|
|
Language" by Kernighan and Ritchie (a.k.a, "K&R") and the C++ standard,
|
|
"ISO/IEC 14882 Programming Languages - C++" will be of great use.
|
|
</p>
|
|
|
|
<p>
|
|
Also, it is useful to keep in mind that SWIG primarily operates as an
|
|
extension of the C++ <em>type</em> system. At first glance, this might not be
|
|
obvious, but almost all SWIG directives as well as the low-level generation of
|
|
wrapper code are driven by C++ datatypes.
|
|
</p>
|
|
|
|
<H2><a name="Extending_nn4"></a>34.3 The Big Picture</H2>
|
|
|
|
|
|
<p>
|
|
SWIG is a special purpose compiler that parses C++ declarations to
|
|
generate wrapper code. To make this conversion possible, SWIG makes
|
|
three fundamental extensions to the C++ language:
|
|
</p>
|
|
|
|
<ul>
|
|
<li><b>Typemaps</b>. Typemaps are used to define the
|
|
conversion/marshalling behavior of specific C++ datatypes. All type conversion in SWIG is
|
|
based on typemaps. Furthermore, the association of typemaps to datatypes utilizes an advanced pattern matching
|
|
mechanism that is fully integrated with the C++ type system.
|
|
</li>
|
|
|
|
<li><b>Declaration Annotation</b>. To customize wrapper code
|
|
generation, most declarations can be annotated with special features.
|
|
For example, you can make a variable read-only, you can ignore a
|
|
declaration, you can rename a member function, you can add exception
|
|
handling, and so forth. Virtually all of these customizations are built on top of a low-level
|
|
declaration annotator that can attach arbitrary attributes to any declaration.
|
|
Code generation modules can look for these attributes to guide the wrapping process.
|
|
</li>
|
|
|
|
<li><b>Class extension</b>. SWIG allows classes and structures to be extended with new
|
|
methods and attributes (the <tt>%extend</tt> directive). This has the effect of altering
|
|
the API in the target language and can be used to generate OO interfaces to C libraries.
|
|
</ul>
|
|
|
|
<p>
|
|
It is important to emphasize that virtually all SWIG features reduce to one of these three
|
|
fundamental concepts. The type system and pattern matching rules also play a critical
|
|
role in making the system work. For example, both typemaps and declaration annotation are
|
|
based on pattern matching and interact heavily with the underlying type system.
|
|
</p>
|
|
|
|
<H2><a name="Extending_nn5"></a>34.4 Execution Model</H2>
|
|
|
|
|
|
<p>
|
|
When you run SWIG on an interface, processing is handled in stages by a series of system components:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>An integrated C preprocessor reads a collection of configuration
|
|
files and the specified interface file into memory. The preprocessor
|
|
performs the usual functions including macro expansion and file
|
|
inclusion. However, the preprocessor also performs some transformations of the
|
|
interface. For instance, <tt>#define</tt> statements are sometimes transformed into
|
|
<tt>%constant</tt> declarations. In addition, information related to file/line number
|
|
tracking is inserted.
|
|
</li>
|
|
|
|
<li>A C/C++ parser reads the preprocessed input and generates a full
|
|
parse tree of all of the SWIG directives and C declarations found.
|
|
The parser is responsible for many aspects of the system including
|
|
renaming, declaration annotation, and template expansion. However, the parser
|
|
does not produce any output nor does it interact with the target
|
|
language module as it runs. SWIG is not a one-pass compiler.
|
|
</li>
|
|
|
|
<li>A type-checking pass is made. This adjusts all of the C++ typenames to properly
|
|
handle namespaces, typedefs, nested classes, and other issues related to type scoping.
|
|
</li>
|
|
|
|
<li>A semantic pass is made on the parse tree to collect information
|
|
related to properties of the C++ interface. For example, this pass
|
|
would determine whether or not a class allows a default constructor.
|
|
</li>
|
|
|
|
<li>A code generation pass is made using a specific target language
|
|
module. This phase is responsible for generating the actual wrapper
|
|
code. All of SWIG's user-defined modules are invoked during this
|
|
latter stage of compilation.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
The next few sections briefly describe some of these stages.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn6"></a>34.4.1 Preprocessing</H3>
|
|
|
|
|
|
<p>
|
|
The preprocessor plays a critical role in the SWIG implementation. This is because a lot
|
|
of SWIG's processing and internal configuration is managed not by code written in C, but
|
|
by configuration files in the SWIG library. In fact, when you
|
|
run SWIG, parsing starts with a small interface file like this (note: this explains
|
|
the cryptic error messages that new users sometimes get when SWIG is misconfigured or installed
|
|
incorrectly):
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%include "swig.swg" // Global SWIG configuration
|
|
%include "<em>langconfig.swg</em>" // Language specific configuration
|
|
%include "yourinterface.i" // Your interface file
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The <tt>swig.swg</tt> file contains global configuration information. In addition, this file
|
|
defines many of SWIG's standard directives as macros. For instance, part of
|
|
of <tt>swig.swg</tt> looks like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
...
|
|
/* Code insertion directives such as %wrapper %{ ... %} */
|
|
|
|
#define %init %insert("init")
|
|
#define %wrapper %insert("wrapper")
|
|
#define %header %insert("header")
|
|
#define %runtime %insert("runtime")
|
|
|
|
/* Access control directives */
|
|
|
|
#define %immutable %feature("immutable","1")
|
|
#define %mutable %feature("immutable")
|
|
|
|
/* Directives for callback functions */
|
|
|
|
#define %callback(x) %feature("callback") `x`;
|
|
#define %nocallback %feature("callback");
|
|
|
|
/* %ignore directive */
|
|
|
|
#define %ignore %rename($ignore)
|
|
#define %ignorewarn(x) %rename("$ignore:" x)
|
|
...
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The fact that most of the standard SWIG directives are macros is
|
|
intended to simplify the implementation of the internals. For instance,
|
|
rather than having to support dozens of special directives, it is
|
|
easier to have a few basic primitives such as <tt>%feature</tt> or
|
|
<tt>%insert</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
The <em><tt>langconfig.swg</tt></em> file is supplied by the target
|
|
language. This file contains language-specific configuration
|
|
information. More often than not, this file provides run-time wrapper
|
|
support code (e.g., the type-checker) as well as a collection of
|
|
typemaps that define the default wrapping behavior. Note: the name of this
|
|
file depends on the target language and is usually something like <tt>python.swg</tt>
|
|
or <tt>perl5.swg</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
As a debugging aide, the text that SWIG feeds to its C++ parser can be
|
|
obtained by running <tt>swig -E interface.i</tt>. This output
|
|
probably isn't too useful in general, but it will show how macros have
|
|
been expanded as well as everything else that goes into the low-level
|
|
construction of the wrapper code.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn7"></a>34.4.2 Parsing</H3>
|
|
|
|
|
|
<p>
|
|
The current C++ parser handles a subset of C++. Most incompatibilities with C are due to
|
|
subtle aspects of how SWIG parses declarations. Specifically, SWIG expects all C/C++ declarations to follow this general form:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
<em>storage</em> <em>type</em> <em>declarator</em> <em>initializer</em>;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<tt><em>storage</em></tt> is a keyword such as <tt>extern</tt>,
|
|
<tt>static</tt>, <tt>typedef</tt>, or <tt>virtual</tt>. <tt><em>type</em></tt> is a primitive
|
|
datatype such as <tt>int</tt> or <tt>void</tt>. <tt><em>type</em></tt> may be optionally
|
|
qualified with a qualifier such as <tt>const</tt> or <tt>volatile</tt>. <tt><em>declarator</em></tt>
|
|
is a name with additional type-construction modifiers attached to it (pointers, arrays, references,
|
|
functions, etc.). Examples of declarators include <tt>*x</tt>, <tt>**x</tt>, <tt>x[20]</tt>, and
|
|
<tt>(*x)(int,double)</tt>. The <tt><em>initializer</em></tt> may be a value assigned using <tt>=</tt> or
|
|
body of code enclosed in braces <tt>{ ... }</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
This declaration format covers most common C++ declarations. However, the C++ standard
|
|
is somewhat more flexible in the placement of the parts. For example, it is technically legal, although
|
|
uncommon to write something like <tt>int typedef const a</tt> in your program. SWIG simply
|
|
doesn't bother to deal with this case.
|
|
</p>
|
|
|
|
<p>
|
|
The other significant difference between C++ and SWIG is in the
|
|
treatment of typenames. In C++, if you have a declaration like this,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int blah(Foo *x, Bar *y);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
it won't parse correctly unless <tt>Foo</tt> and <tt>Bar</tt> have
|
|
been previously defined as types either using a <tt>class</tt>
|
|
definition or a <tt>typedef</tt>. The reasons for this are subtle,
|
|
but this treatment of typenames is normally integrated at the level of the C
|
|
tokenizer---when a typename appears, a different token is returned to the parser
|
|
instead of an identifier.
|
|
</p>
|
|
|
|
<p>
|
|
SWIG does not operate in this manner--any legal identifier can be used
|
|
as a type name. The reason for this is primarily motivated by the use
|
|
of SWIG with partially defined data. Specifically,
|
|
SWIG is supposed to be easy to use on interfaces with missing type information.
|
|
</p>
|
|
|
|
<p>
|
|
Because of the different treatment of typenames, the most serious
|
|
limitation of the SWIG parser is that it can't process type declarations where
|
|
an extra (and unnecessary) grouping operator is used. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int (x); /* A variable x */
|
|
int (y)(int); /* A function y */
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The placing of extra parentheses in type declarations like this is
|
|
already recognized by the C++ community as a potential source of
|
|
strange programming errors. For example, Scott Meyers "Effective STL"
|
|
discusses this problem in a section on avoiding C++'s "most vexing
|
|
parse."
|
|
</p>
|
|
|
|
<p>
|
|
The parser is also unable to handle declarations with no return type or bare argument names.
|
|
For example, in an old C program, you might see things like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
foo(a,b) {
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this case, the return type as well as the types of the arguments
|
|
are taken by the C compiler to be an <tt>int</tt>. However, SWIG
|
|
interprets the above code as an abstract declarator for a function
|
|
returning a <tt>foo</tt> and taking types <tt>a</tt> and <tt>b</tt> as
|
|
arguments).
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn8"></a>34.4.3 Parse Trees</H3>
|
|
|
|
|
|
<p>
|
|
The SWIG parser produces a complete parse tree of the input file before any wrapper code
|
|
is actually generated. Each item in the tree is known as a "Node". Each node is identified
|
|
by a symbolic tag. Furthermore, a node may have an arbitrary number of children.
|
|
The parse tree structure and tag names of an interface can be displayed using <tt>swig -debug-tags</tt>.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
$ <b>swig -c++ -python -debug-tags example.i</b>
|
|
. top (example.i:1)
|
|
. top . include (example.i:1)
|
|
. top . include . typemap (/r0/beazley/Projects/lib/swig1.3/swig.swg:71)
|
|
. top . include . typemap . typemapitem (/r0/beazley/Projects/lib/swig1.3/swig.swg:71)
|
|
. top . include . typemap (/r0/beazley/Projects/lib/swig1.3/swig.swg:83)
|
|
. top . include . typemap . typemapitem (/r0/beazley/Projects/lib/swig1.3/swig.swg:83)
|
|
. top . include (example.i:4)
|
|
. top . include . insert (/r0/beazley/Projects/lib/swig1.3/python/python.swg:7)
|
|
. top . include . insert (/r0/beazley/Projects/lib/swig1.3/python/python.swg:8)
|
|
. top . include . typemap (/r0/beazley/Projects/lib/swig1.3/python/python.swg:19)
|
|
...
|
|
. top . include (example.i:6)
|
|
. top . include . module (example.i:2)
|
|
. top . include . insert (example.i:6)
|
|
. top . include . include (example.i:9)
|
|
. top . include . include . class (example.h:3)
|
|
. top . include . include . class . access (example.h:4)
|
|
. top . include . include . class . constructor (example.h:7)
|
|
. top . include . include . class . destructor (example.h:10)
|
|
. top . include . include . class . cdecl (example.h:11)
|
|
. top . include . include . class . cdecl (example.h:11)
|
|
. top . include . include . class . cdecl (example.h:12)
|
|
. top . include . include . class . cdecl (example.h:13)
|
|
. top . include . include . class . cdecl (example.h:14)
|
|
. top . include . include . class . cdecl (example.h:15)
|
|
. top . include . include . class (example.h:18)
|
|
. top . include . include . class . access (example.h:19)
|
|
. top . include . include . class . cdecl (example.h:20)
|
|
. top . include . include . class . access (example.h:21)
|
|
. top . include . include . class . constructor (example.h:22)
|
|
. top . include . include . class . cdecl (example.h:23)
|
|
. top . include . include . class . cdecl (example.h:24)
|
|
. top . include . include . class (example.h:27)
|
|
. top . include . include . class . access (example.h:28)
|
|
. top . include . include . class . cdecl (example.h:29)
|
|
. top . include . include . class . access (example.h:30)
|
|
. top . include . include . class . constructor (example.h:31)
|
|
. top . include . include . class . cdecl (example.h:32)
|
|
. top . include . include . class . cdecl (example.h:33)
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Even for the most simple interface, the parse tree structure is larger than you might expect. For example, in the
|
|
above output, a substantial number of nodes are actually generated by the <tt>python.swg</tt> configuration file
|
|
which defines typemaps and other directives. The contents of the user-supplied input file don't appear until the end
|
|
of the output.
|
|
</p>
|
|
|
|
<p>
|
|
The contents of each parse tree node consist of a collection of attribute/value
|
|
pairs. Internally, the nodes are simply represented by hash tables. A display of
|
|
the entire parse-tree structure can be obtained using <tt>swig -dump_tree</tt>.
|
|
There are a number of other parse tree display options, for example, <tt>swig -debug-module <n></tt> will
|
|
avoid displaying system parse information and only display the parse tree pertaining to the user's module at
|
|
stage <tt>n</tt> of processing.
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -c++ -python -debug-module 4 example.i
|
|
+++ include ----------------------------------------
|
|
| name - "example.i"
|
|
|
|
+++ module ----------------------------------------
|
|
| name - "example"
|
|
|
|
|
+++ insert ----------------------------------------
|
|
| code - "\n#include \"example.h\"\n"
|
|
|
|
|
+++ include ----------------------------------------
|
|
| name - "example.h"
|
|
|
|
+++ class ----------------------------------------
|
|
| abstract - "1"
|
|
| sym:name - "Shape"
|
|
| name - "Shape"
|
|
| kind - "class"
|
|
| symtab - 0x40194140
|
|
| sym:symtab - 0x40191078
|
|
|
|
+++ access ----------------------------------------
|
|
| kind - "public"
|
|
|
|
|
+++ constructor ----------------------------------------
|
|
| sym:name - "Shape"
|
|
| name - "Shape"
|
|
| decl - "f()."
|
|
| code - "{\n nshapes++;\n }"
|
|
| sym:symtab - 0x40194140
|
|
|
|
|
+++ destructor ----------------------------------------
|
|
| sym:name - "~Shape"
|
|
| name - "~Shape"
|
|
| storage - "virtual"
|
|
| code - "{\n nshapes--;\n }"
|
|
| sym:symtab - 0x40194140
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "x"
|
|
| name - "x"
|
|
| decl - ""
|
|
| type - "double"
|
|
| sym:symtab - 0x40194140
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "y"
|
|
| name - "y"
|
|
| decl - ""
|
|
| type - "double"
|
|
| sym:symtab - 0x40194140
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "move"
|
|
| name - "move"
|
|
| decl - "f(double,double)."
|
|
| parms - double ,double
|
|
| type - "void"
|
|
| sym:symtab - 0x40194140
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "area"
|
|
| name - "area"
|
|
| decl - "f(void)."
|
|
| parms - void
|
|
| storage - "virtual"
|
|
| value - "0"
|
|
| type - "double"
|
|
| sym:symtab - 0x40194140
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "perimeter"
|
|
| name - "perimeter"
|
|
| decl - "f(void)."
|
|
| parms - void
|
|
| storage - "virtual"
|
|
| value - "0"
|
|
| type - "double"
|
|
| sym:symtab - 0x40194140
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "nshapes"
|
|
| name - "nshapes"
|
|
| decl - ""
|
|
| storage - "static"
|
|
| type - "int"
|
|
| sym:symtab - 0x40194140
|
|
|
|
|
+++ class ----------------------------------------
|
|
| sym:name - "Circle"
|
|
| name - "Circle"
|
|
| kind - "class"
|
|
| bases - 0x40194510
|
|
| symtab - 0x40194538
|
|
| sym:symtab - 0x40191078
|
|
|
|
+++ access ----------------------------------------
|
|
| kind - "private"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| name - "radius"
|
|
| decl - ""
|
|
| type - "double"
|
|
|
|
|
+++ access ----------------------------------------
|
|
| kind - "public"
|
|
|
|
|
+++ constructor ----------------------------------------
|
|
| sym:name - "Circle"
|
|
| name - "Circle"
|
|
| parms - double
|
|
| decl - "f(double)."
|
|
| code - "{ }"
|
|
| sym:symtab - 0x40194538
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "area"
|
|
| name - "area"
|
|
| decl - "f(void)."
|
|
| parms - void
|
|
| storage - "virtual"
|
|
| type - "double"
|
|
| sym:symtab - 0x40194538
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "perimeter"
|
|
| name - "perimeter"
|
|
| decl - "f(void)."
|
|
| parms - void
|
|
| storage - "virtual"
|
|
| type - "double"
|
|
| sym:symtab - 0x40194538
|
|
|
|
|
+++ class ----------------------------------------
|
|
| sym:name - "Square"
|
|
| name - "Square"
|
|
| kind - "class"
|
|
| bases - 0x40194760
|
|
| symtab - 0x40194788
|
|
| sym:symtab - 0x40191078
|
|
|
|
+++ access ----------------------------------------
|
|
| kind - "private"
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| name - "width"
|
|
| decl - ""
|
|
| type - "double"
|
|
|
|
|
+++ access ----------------------------------------
|
|
| kind - "public"
|
|
|
|
|
+++ constructor ----------------------------------------
|
|
| sym:name - "Square"
|
|
| name - "Square"
|
|
| parms - double
|
|
| decl - "f(double)."
|
|
| code - "{ }"
|
|
| sym:symtab - 0x40194788
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "area"
|
|
| name - "area"
|
|
| decl - "f(void)."
|
|
| parms - void
|
|
| storage - "virtual"
|
|
| type - "double"
|
|
| sym:symtab - 0x40194788
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "perimeter"
|
|
| name - "perimeter"
|
|
| decl - "f(void)."
|
|
| parms - void
|
|
| storage - "virtual"
|
|
| type - "double"
|
|
| sym:symtab - 0x40194788
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn9"></a>34.4.4 Attribute namespaces</H3>
|
|
|
|
|
|
<p>
|
|
Attributes of parse tree nodes are often prepended with a namespace qualifier.
|
|
For example, the attributes
|
|
<tt>sym:name</tt> and <tt>sym:symtab</tt> are attributes related to
|
|
symbol table management and are prefixed with <tt>sym:</tt>. As a
|
|
general rule, only those attributes which are directly related to the raw declaration
|
|
appear without a prefix (type, name, declarator, etc.).
|
|
</p>
|
|
|
|
<p>
|
|
Target language modules may add additional attributes to nodes to assist the generation
|
|
of wrapper code. The convention for doing this is to place these attributes in a namespace
|
|
that matches the name of the target language. For example, <tt>python:foo</tt> or
|
|
<tt>perl:foo</tt>.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn10"></a>34.4.5 Symbol Tables</H3>
|
|
|
|
|
|
<p>
|
|
During parsing, all symbols are managed in the space of the target
|
|
language. The <tt>sym:name</tt> attribute of each node contains the symbol name
|
|
selected by the parser. Normally, <tt>sym:name</tt> and <tt>name</tt>
|
|
are the same. However, the <tt>%rename</tt> directive can be used to
|
|
change the value of <tt>sym:name</tt>. You can see the effect of
|
|
<tt>%rename</tt> by trying it on a simple interface and dumping the
|
|
parse tree. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%rename(foo_i) foo(int);
|
|
%rename(foo_d) foo(double);
|
|
|
|
void foo(int);
|
|
void foo(double);
|
|
void foo(Bar *b);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
There are various <tt>debug-</tt> options that can be useful for debugging and analysing the parse tree.
|
|
For example, the <tt>debug-top <n></tt> or <tt>debug-module <n></tt> options will
|
|
dump the entire/top of the parse tree or the module subtree at one of the four <tt>n</tt> stages of processing.
|
|
The parse tree can be viewed after the final stage of processing by running SWIG:
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
$ swig -debug-top 4 example.i
|
|
...
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "foo_i"
|
|
| name - "foo"
|
|
| decl - "f(int)."
|
|
| parms - int
|
|
| type - "void"
|
|
| sym:symtab - 0x40165078
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "foo_d"
|
|
| name - "foo"
|
|
| decl - "f(double)."
|
|
| parms - double
|
|
| type - "void"
|
|
| sym:symtab - 0x40165078
|
|
|
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "foo"
|
|
| name - "foo"
|
|
| decl - "f(p.Bar)."
|
|
| parms - Bar *
|
|
| type - "void"
|
|
| sym:symtab - 0x40165078
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
All symbol-related conflicts and complaints about overloading are based on <tt>sym:name</tt> values.
|
|
For instance, the following example uses <tt>%rename</tt> in reverse to generate a name clash.
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%rename(foo) foo_i(int);
|
|
%rename(foo) foo_d(double;
|
|
|
|
void foo_i(int);
|
|
void foo_d(double);
|
|
void foo(Bar *b);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When you run SWIG on this you now get:
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
$ ./swig example.i
|
|
example.i:6. Overloaded declaration ignored. foo_d(double )
|
|
example.i:5. Previous declaration is foo_i(int )
|
|
example.i:7. Overloaded declaration ignored. foo(Bar *)
|
|
example.i:5. Previous declaration is foo_i(int )
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn11"></a>34.4.6 The %feature directive</H3>
|
|
|
|
|
|
<p>
|
|
A number of SWIG directives such as <tt>%exception</tt> are implemented using the
|
|
low-level <tt>%feature</tt> directive. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%feature("except") getitem(int) {
|
|
try {
|
|
$action
|
|
} catch (badindex) {
|
|
...
|
|
}
|
|
}
|
|
|
|
...
|
|
class Foo {
|
|
public:
|
|
Object *getitem(int index) throws(badindex);
|
|
...
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The behavior of <tt>%feature</tt> is very easy to describe--it simply
|
|
attaches a new attribute to any parse tree node that matches the
|
|
given prototype. When a feature is added, it shows up as an attribute in the <tt>feature:</tt> namespace.
|
|
You can see this when running with the <tt>-debug-top 4</tt> option. For example:
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
+++ cdecl ----------------------------------------
|
|
| sym:name - "getitem"
|
|
| name - "getitem"
|
|
| decl - "f(int).p."
|
|
| parms - int
|
|
| type - "Object"
|
|
| feature:except - "{\n try {\n $action\n } catc..."
|
|
| sym:symtab - 0x40168ac8
|
|
|
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Feature names are completely arbitrary and a target language module can be
|
|
programmed to respond to any feature name that it wants to recognize. The
|
|
data stored in a feature attribute is usually just a raw unparsed string.
|
|
For example, the exception code above is simply
|
|
stored without any modifications.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn12"></a>34.4.7 Code Generation</H3>
|
|
|
|
|
|
<p>
|
|
Language modules work by defining handler functions that know how to respond to
|
|
different types of parse-tree nodes. These handlers simply look at the
|
|
attributes of each node in order to produce low-level code.
|
|
</p>
|
|
|
|
<p>
|
|
In reality, the generation of code is somewhat more subtle than simply
|
|
invoking handler functions. This is because parse-tree nodes might be
|
|
transformed. For example, suppose you are wrapping a class like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
class Foo {
|
|
public:
|
|
virtual int *bar(int x);
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When the parser constructs a node for the member <tt>bar</tt>, it creates a raw "cdecl" node with the following
|
|
attributes:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
nodeType : cdecl
|
|
name : bar
|
|
type : int
|
|
decl : f(int).p
|
|
parms : int x
|
|
storage : virtual
|
|
sym:name : bar
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
To produce wrapper code, this "cdecl" node undergoes a number of transformations. First, the node is recognized as a function declaration. This adjusts some of the type information--specifically, the declarator is joined with the base datatype to produce this:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
nodeType : cdecl
|
|
name : bar
|
|
type : p.int <-- Notice change in return type
|
|
decl : f(int).p
|
|
parms : int x
|
|
storage : virtual
|
|
sym:name : bar
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Next, the context of the node indicates that the node is really a
|
|
member function. This produces a transformation to a low-level
|
|
accessor function like this:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
nodeType : cdecl
|
|
name : bar
|
|
type : int.p
|
|
decl : f(int).p
|
|
parms : Foo *self, int x <-- Added parameter
|
|
storage : virtual
|
|
wrap:action : result = (arg1)->bar(arg2) <-- Action code added
|
|
sym:name : Foo_bar <-- Symbol name changed
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this transformation, notice how an additional parameter was added
|
|
to the parameter list and how the symbol name of the node has suddenly
|
|
changed into an accessor using the naming scheme described in the
|
|
"SWIG Basics" chapter. A small fragment of "action" code has also
|
|
been generated--notice how the <tt>wrap:action</tt> attribute defines
|
|
the access to the underlying method. The data in this transformed
|
|
node is then used to generate a wrapper.
|
|
</p>
|
|
|
|
<p>
|
|
Language modules work by registering handler functions for dealing with
|
|
various types of nodes at different stages of transformation. This is done by
|
|
inheriting from a special <tt>Language</tt> class and defining a collection
|
|
of virtual methods. For example, the Python module defines a class as
|
|
follows:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
class PYTHON : public Language {
|
|
protected:
|
|
public :
|
|
virtual void main(int, char *argv[]);
|
|
virtual int top(Node *);
|
|
virtual int functionWrapper(Node *);
|
|
virtual int constantWrapper(Node *);
|
|
virtual int variableWrapper(Node *);
|
|
virtual int nativeWrapper(Node *);
|
|
virtual int membervariableHandler(Node *);
|
|
virtual int memberconstantHandler(Node *);
|
|
virtual int memberfunctionHandler(Node *);
|
|
virtual int constructorHandler(Node *);
|
|
virtual int destructorHandler(Node *);
|
|
virtual int classHandler(Node *);
|
|
virtual int classforwardDeclaration(Node *);
|
|
virtual int insertDirective(Node *);
|
|
virtual int importDirective(Node *);
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The role of these functions is described shortly.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn13"></a>34.4.8 SWIG and XML</H3>
|
|
|
|
|
|
<p>
|
|
Much of SWIG's current parser design was originally motivated by
|
|
interest in using XML to represent SWIG parse trees. Although XML is
|
|
not currently used in any direct manner, the parse tree structure, use
|
|
of node tags, attributes, and attribute namespaces are all influenced
|
|
by aspects of XML parsing. Therefore, in trying to understand SWIG's
|
|
internal data structures, it may be useful to keep XML in the back of
|
|
your mind as a model.
|
|
</p>
|
|
|
|
<H2><a name="Extending_nn14"></a>34.5 Primitive Data Structures</H2>
|
|
|
|
|
|
<p>
|
|
Most of SWIG is constructed using three basic data structures:
|
|
strings, hashes, and lists. These data structures are dynamic in same way as
|
|
similar structures found in many scripting languages. For instance,
|
|
you can have containers (lists and hash tables) of mixed types and
|
|
certain operations are polymorphic.
|
|
</p>
|
|
|
|
<p>
|
|
This section briefly describes the basic structures so that later
|
|
sections of this chapter make more sense.
|
|
</p>
|
|
|
|
<p>
|
|
When describing the low-level API, the following type name conventions are
|
|
used:
|
|
</p>
|
|
|
|
<ul>
|
|
<li><tt>String</tt>. A string object.
|
|
<li><tt>Hash</tt>. A hash object.
|
|
<li><tt>List</tt>. A list object.
|
|
<li><tt>String_or_char</tt>. A string object or a <tt>char *</tt>.
|
|
<li><tt>Object_or_char</tt>. An object or a <tt>char *</tt>.
|
|
<li><tt>Object</tt>. Any object (string, hash, list, etc.)
|
|
</ul>
|
|
|
|
<p>
|
|
In most cases, other typenames in the source are aliases for one of these
|
|
primitive types. Specifically:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
typedef String SwigType;
|
|
typedef Hash Parm;
|
|
typedef Hash ParmList;
|
|
typedef Hash Node;
|
|
typedef Hash Symtab;
|
|
typedef Hash Typetab;
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn15"></a>34.5.1 Strings</H3>
|
|
|
|
|
|
<p>
|
|
<b><tt>String *NewString(const String_or_char *val)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Creates a new string with initial value <tt>val</tt>. <tt>val</tt> may
|
|
be a <tt>char *</tt> or another <tt>String</tt> object. If you want
|
|
to create an empty string, use "" for val.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>String *NewStringf(const char *fmt, ...)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Creates a new string whose initial value is set according to a C <tt>printf</tt> style
|
|
format string in <tt>fmt</tt>. Additional arguments follow depending
|
|
on <tt>fmt</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>String *Copy(String *s)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Make a copy of the string <tt>s</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Delete(String *s)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Deletes <tt>s</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Len(String_or_char *s)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the length of the string.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>char *Char(String_or_char *s)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns a pointer to the first character in a string.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Append(String *s, String_or_char *t)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Appends <tt>t</tt> to the end of string <tt>s</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Insert(String *s, int pos, String_or_char *t)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Inserts <tt>t</tt> into <tt>s</tt> at position <tt>pos</tt>. The contents
|
|
of <tt>s</tt> are shifted accordingly. The special value <tt>DOH_END</tt>
|
|
can be used for <tt>pos</tt> to indicate insertion at the end of the string (appending).
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Strcmp(const String_or_char *s, const String_or_char *t)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Compare strings <tt>s</tt> and <tt>t</tt>. Same as the C <tt>strcmp()</tt>
|
|
function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Strncmp(const String_or_char *s, const String_or_char *t, int len)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Compare the first <tt>len</tt> characters of strings <tt>s</tt> and <tt>t</tt>. Same as the C <tt>strncmp()</tt>
|
|
function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>char *Strstr(const String_or_char *s, const String_or_char *pat)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns a pointer to the first occurrence of <tt>pat</tt> in <tt>s</tt>.
|
|
Same as the C <tt>strstr()</tt> function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>char *Strchr(const String_or_char *s, char ch)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns a pointer to the first occurrence of character <tt>ch</tt> in <tt>s</tt>.
|
|
Same as the C <tt>strchr()</tt> function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Chop(String *s)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Chops trailing whitespace off the end of <tt>s</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Replace(String *s, const String_or_char *pat, const String_or_char *rep, int flags)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
<p>
|
|
Replaces the pattern <tt>pat</tt> with <tt>rep</tt> in string <tt>s</tt>.
|
|
<tt>flags</tt> is a combination of the following flags:</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
DOH_REPLACE_ANY - Replace all occurrences
|
|
DOH_REPLACE_ID - Valid C identifiers only
|
|
DOH_REPLACE_NOQUOTE - Don't replace in quoted strings
|
|
DOH_REPLACE_FIRST - Replace first occurrence only.
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Returns the number of replacements made (if any).
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn16"></a>34.5.2 Hashes</H3>
|
|
|
|
|
|
<p>
|
|
<b><tt>Hash *NewHash()</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Creates a new empty hash table.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>Hash *Copy(Hash *h)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Make a shallow copy of the hash <tt>h</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Delete(Hash *h)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Deletes <tt>h</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Len(Hash *h)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the number of items in <tt>h</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>Object *Getattr(Hash *h, String_or_char *key)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Gets an object from <tt>h</tt>. <tt>key</tt> may be a string or
|
|
a simple <tt>char *</tt> string. Returns NULL if not found.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Setattr(Hash *h, String_or_char *key, Object_or_char *val)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Stores <tt>val</tt> in <tt>h</tt>. <tt>key</tt> may be a string or
|
|
a simple <tt>char *</tt>. If <tt>val</tt> is not a standard
|
|
object (String, Hash, or List) it is assumed to be a <tt>char *</tt> in which
|
|
case it is used to construct a <tt>String</tt> that is stored in the hash.
|
|
If <tt>val</tt> is NULL, the object is deleted. Increases the reference count
|
|
of <tt>val</tt>. Returns 1 if this operation replaced an existing hash entry,
|
|
0 otherwise.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Delattr(Hash *h, String_or_char *key)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Deletes the hash item referenced by <tt>key</tt>. Decreases the
|
|
reference count on the corresponding object (if any). Returns 1
|
|
if an object was removed, 0 otherwise.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>List *Keys(Hash *h)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the list of hash table keys.
|
|
</div>
|
|
|
|
|
|
<H3><a name="Extending_nn17"></a>34.5.3 Lists</H3>
|
|
|
|
|
|
<p>
|
|
<b><tt>List *NewList()</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Creates a new empty list.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>List *Copy(List *x)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Make a shallow copy of the List <tt>x</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Delete(List *x)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Deletes <tt>x</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Len(List *x)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the number of items in <tt>x</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>Object *Getitem(List *x, int n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns an object from <tt>x</tt> with index <tt>n</tt>. If <tt>n</tt> is
|
|
beyond the end of the list, the last item is returned. If <tt>n</tt> is
|
|
negative, the first item is returned.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int *Setitem(List *x, int n, Object_or_char *val)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Stores <tt>val</tt> in <tt>x</tt>.
|
|
If <tt>val</tt> is not a standard
|
|
object (String, Hash, or List) it is assumed to be a <tt>char *</tt> in which
|
|
case it is used to construct a <tt>String</tt> that is stored in the list.
|
|
<tt>n</tt> must be in range. Otherwise, an assertion will be raised.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int *Delitem(List *x, int n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Deletes item <tt>n</tt> from the list, shifting items down if necessary.
|
|
To delete the last item in the list, use the special value <tt>DOH_END</tt>
|
|
for <tt>n</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Append(List *x, Object_or_char *t)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Appends <tt>t</tt> to the end of <tt>x</tt>. If <tt>t</tt> is not
|
|
a standard object, it is assumed to be a <tt>char *</tt> and is
|
|
used to create a String object.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Insert(String *s, int pos, Object_or_char *t)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Inserts <tt>t</tt> into <tt>s</tt> at position <tt>pos</tt>. The contents
|
|
of <tt>s</tt> are shifted accordingly. The special value <tt>DOH_END</tt>
|
|
can be used for <tt>pos</tt> to indicate insertion at the end of the list (appending).
|
|
If <tt>t</tt> is not a standard object, it is assumed to be a <tt>char *</tt>
|
|
and is used to create a String object.
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn18"></a>34.5.4 Common operations</H3>
|
|
|
|
|
|
The following operations are applicable to all datatypes.
|
|
|
|
<p>
|
|
<b><tt>Object *Copy(Object *x)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Make a copy of the object <tt>x</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Delete(Object *x)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Deletes <tt>x</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Setfile(Object *x, String_or_char *f)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Sets the filename associated with <tt>x</tt>. Used to track
|
|
objects and report errors.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>String *Getfile(Object *x)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Gets the filename associated with <tt>x</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void Setline(Object *x, int n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Sets the line number associated with <tt>x</tt>. Used to track
|
|
objects and report errors.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Getline(Object *x)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Gets the line number associated with <tt>x</tt>.
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn19"></a>34.5.5 Iterating over Lists and Hashes</H3>
|
|
|
|
|
|
To iterate over the elements of a list or a hash table, the following functions are used:
|
|
|
|
<p>
|
|
<b><tt>Iterator First(Object *x)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns an iterator object that points to the first item in a list or hash table. The
|
|
<tt>item</tt> attribute of the Iterator object is a pointer to the item. For hash tables, the <tt>key</tt> attribute
|
|
of the Iterator object additionally points to the corresponding Hash table key. The <tt>item</tt> and <tt>key</tt> attributes
|
|
are NULL if the object contains no items or if there are no more items.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>Iterator Next(Iterator i)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
<p>Returns an iterator that points to the next item in a list or hash table.
|
|
|
|
Here are two examples of iteration:</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
List *l = (some list);
|
|
Iterator i;
|
|
|
|
for (i = First(l); i.item; i = Next(i)) {
|
|
Printf(stdout,"%s\n", i.item);
|
|
}
|
|
|
|
Hash *h = (some hash);
|
|
Iterator j;
|
|
|
|
for (j = First(j); j.item; j= Next(j)) {
|
|
Printf(stdout,"%s : %s\n", j.key, j.item);
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn20"></a>34.5.6 I/O</H3>
|
|
|
|
|
|
Special I/O functions are used for all internal I/O. These operations
|
|
work on C <tt>FILE *</tt> objects, String objects, and special <tt>File</tt> objects
|
|
(which are merely a wrapper around <tt>FILE *</tt>).
|
|
|
|
<p>
|
|
<b><tt>int Printf(String_or_FILE *f, const char *fmt, ...)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Formatted I/O. Same as the C <tt>fprintf()</tt> function except that output
|
|
can also be directed to a string object. Note: the <tt>%s</tt> format
|
|
specifier works with both strings and <tt>char *</tt>. All other format
|
|
operators have the same meaning.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Printv(String_or_FILE *f, String_or_char *arg1,..., NULL)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Prints a variable number of strings arguments to the output. The last
|
|
argument to this function must be NULL. The other arguments can either
|
|
be <tt>char *</tt> or string objects.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Putc(int ch, String_or_FILE *f)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Same as the C <tt>fputc()</tt> function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Write(String_or_FILE *f, void *buf, int len)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Same as the C <tt>write()</tt> function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Read(String_or_FILE *f, void *buf, int maxlen)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Same as the C <tt>read()</tt> function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Getc(String_or_FILE *f)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Same as the C <tt>fgetc()</tt> function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Ungetc(int ch, String_or_FILE *f)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Same as the C <tt>ungetc()</tt> function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Seek(String_or_FILE *f, int offset, int whence)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Same as the C <tt>seek()</tt> function. <tt>offset</tt> is the number
|
|
of bytes. <tt>whence</tt> is one of <tt>SEEK_SET</tt>,<tt>SEEK_CUR</tt>,
|
|
or <tt>SEEK_END</tt>..
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>long Tell(String_or_FILE *f)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Same as the C <tt>tell()</tt> function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>File *NewFile(const char *filename, const char *mode)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Create a File object using the <tt>fopen()</tt> library call. This
|
|
file differs from <tt>FILE *</tt> in that it can be placed in the standard
|
|
SWIG containers (lists, hashes, etc.).
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>File *NewFileFromFile(FILE *f)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Create a File object wrapper around an existing <tt>FILE *</tt> object.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Close(String_or_FILE *f)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
<p>Closes a file. Has no effect on strings.</p>
|
|
|
|
<p>
|
|
The use of the above I/O functions and strings play a critical role in SWIG. It is
|
|
common to see small code fragments of code generated using code like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
/* Print into a string */
|
|
String *s = NewString("");
|
|
Printf(s,"Hello\n");
|
|
for (i = 0; i < 10; i++) {
|
|
Printf(s,"%d\n", i);
|
|
}
|
|
...
|
|
/* Print string into a file */
|
|
Printf(f, "%s\n", s);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Similarly, the preprocessor and parser all operate on string-files.
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<H2><a name="Extending_nn21"></a>34.6 Navigating and manipulating parse trees</H2>
|
|
|
|
|
|
Parse trees are built as collections of hash tables. Each node is a hash table in which
|
|
arbitrary attributes can be stored. Certain attributes in the hash table provide links to
|
|
other parse tree nodes. The following macros can be used to move around the parse tree.
|
|
|
|
<p>
|
|
<b><tt>String *nodeType(Node *n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the node type tag as a string. The returned string indicates the type of parse
|
|
tree node.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>Node *nextSibling(Node *n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the next node in the parse tree. For example, the next C declaration.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>Node *previousSibling(Node *n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the previous node in the parse tree. For example, the previous C declaration.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>Node *firstChild(Node *n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the first child node. For example, if <tt>n</tt> was a C++ class node, this would
|
|
return the node for the first class member.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>Node *lastChild(Node *n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the last child node. You might use this if you wanted to append a new
|
|
node to the of a class.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>Node *parentNode(Node *n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the parent of node <tt>n</tt>. Use this to move up the pass tree.
|
|
</div>
|
|
|
|
<p>
|
|
The following macros can be used to change all of the above attributes.
|
|
Normally, these functions are only used by the parser. Changing them without
|
|
knowing what you are doing is likely to be dangerous.
|
|
</p>
|
|
|
|
<p>
|
|
<b><tt>void set_nodeType(Node *n, const String_or_char)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Change the node type.
|
|
tree node.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void set_nextSibling(Node *n, Node *s)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Set the next sibling.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void set_previousSibling(Node *n, Node *s)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Set the previous sibling.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void set_firstChild(Node *n, Node *c)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Set the first child node.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void set_lastChild(Node *n, Node *c)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Set the last child node.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void set_parentNode(Node *n, Node *p)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Set the parent node.
|
|
</div>
|
|
|
|
<p>
|
|
The following utility functions are used to alter the parse tree (at your own risk)
|
|
</p>
|
|
|
|
<p>
|
|
<b><tt>void appendChild(Node *parent, Node *child)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Append a child to <tt>parent</tt>. The appended node becomes the last child.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void deleteNode(Node *node)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Deletes a node from the parse tree. Deletion reconnects siblings and properly updates
|
|
the parent so that sibling nodes are unaffected.
|
|
</div>
|
|
|
|
<H2><a name="Extending_nn22"></a>34.7 Working with attributes</H2>
|
|
|
|
|
|
<p>
|
|
Since parse tree nodes are just hash tables, attributes are accessed using the <tt>Getattr()</tt>,
|
|
<tt>Setattr()</tt>, and <tt>Delattr()</tt> operations. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int functionHandler(Node *n) {
|
|
String *name = Getattr(n,"name");
|
|
String *symname = Getattr(n,"sym:name");
|
|
SwigType *type = Getattr(n,"type");
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
New attributes can be freely attached to a node as needed. However, when new attributes
|
|
are attached during code generation, they should be prepended with a namespace prefix.
|
|
For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
...
|
|
Setattr(n,"python:docstring", doc); /* Store docstring */
|
|
...
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
A quick way to check the value of an attribute is to use the <tt>checkAttribute()</tt> function like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
if (checkAttribute(n,"storage","virtual")) {
|
|
/* n is virtual */
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Changing the values of existing attributes is allowed and is sometimes done to implement
|
|
node transformations. However, if a function/method modifies a node, it is required to restore
|
|
modified attributes to their original values. To simplify the task of saving/restoring attributes,
|
|
the following functions are used:
|
|
</p>
|
|
|
|
<p>
|
|
<b><tt>int Swig_save(const char *ns, Node *n, const char *name1, const char *name2, ..., NIL)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Saves a copy of attributes <tt>name1</tt>, <tt>name2</tt>, etc. from node <tt>n</tt>.
|
|
Copies of the attributes are actually resaved in the node in a different namespace which is
|
|
set by the <tt>ns</tt> argument. For example, if you call <tt>Swig_save("foo",n,"type",NIL)</tt>,
|
|
then the "type" attribute will be copied and saved as "foo:type". The namespace name itself is stored in
|
|
the "view" attribute of the node. If necessary, this can be examined to find out where previous
|
|
values of attributes might have been saved.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Swig_restore(Node *n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
|
|
<p>
|
|
Restores the attributes saved by the previous call to <tt>Swig_save()</tt>. Those
|
|
attributes that were supplied to <tt>Swig_save()</tt> will be restored to their
|
|
original values.
|
|
</p>
|
|
|
|
<p>
|
|
The <tt>Swig_save()</tt> and <tt>Swig_restore()</tt> functions must always be used as a pair.
|
|
That is, every call to <tt>Swig_save()</tt> must have a matching call to <tt>Swig_restore()</tt>.
|
|
Calls can be nested if necessary. Here is an example that shows how the functions might be used:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int variableHandler(Node *n) {
|
|
Swig_save("variableHandler",n,"type","sym:name",NIL);
|
|
String *symname = Getattr(n,"sym:name");
|
|
SwigType *type = Getattr(n,"type");
|
|
...
|
|
Append(symname,"_global"); // Change symbol name
|
|
SwigType_add_pointer(type); // Add pointer
|
|
...
|
|
generate wrappers
|
|
...
|
|
Swig_restore(n); // Restore original values
|
|
return SWIG_OK;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int Swig_require(const char *ns, Node *n, const char *name1, const char *name2, ..., NIL)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
This is an enhanced version of <tt>Swig_save()</tt> that adds error checking. If an attribute
|
|
name is not present in <tt>n</tt>, a failed assertion results and SWIG terminates with a fatal
|
|
error. Optionally, if an attribute name is specified as "*<em>name</em>", a copy of the
|
|
attribute is saved as with <tt>Swig_save()</tt>. If an attribute is specified as "?<em>name</em>",
|
|
the attribute is optional. <tt>Swig_restore()</tt> must always be called after using this
|
|
function.
|
|
</div>
|
|
|
|
<H2><a name="Extending_nn23"></a>34.8 Type system</H2>
|
|
|
|
|
|
<p>
|
|
SWIG implements the complete C++ type system including typedef, inheritance,
|
|
pointers, references, and pointers to members. A detailed discussion of
|
|
type theory is impossible here. However, let's cover the highlights.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn24"></a>34.8.1 String encoding of types</H3>
|
|
|
|
|
|
<p>
|
|
All types in SWIG consist of a base datatype and a collection of type
|
|
operators that are applied to the base. A base datatype is almost
|
|
always some kind of primitive type such as <tt>int</tt> or <tt>double</tt>.
|
|
The operators consist of things like pointers, references, arrays, and so forth.
|
|
Internally, types are represented as strings that are constructed in a very
|
|
precise manner. Here are some examples:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
C datatype SWIG encoding (strings)
|
|
----------------------------- --------------------------
|
|
int "int"
|
|
int * "p.int"
|
|
const int * "p.q(const).int"
|
|
int (*x)(int,double) "p.f(int,double).int"
|
|
int [20][30] "a(20).a(30).int"
|
|
int (F::*)(int) "m(F).f(int).int"
|
|
vector<int> * "p.vector<(int)>"
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Reading the SWIG encoding is often easier than figuring out the C code---just
|
|
read it from left to right. For a type of "p.f(int,double).int" is
|
|
a "pointer to a function(int,double) that returns int".
|
|
</p>
|
|
|
|
<p>
|
|
The following operator encodings are used in type strings:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
Operator Meaning
|
|
------------------- -------------------------------
|
|
p. Pointer to
|
|
a(n). Array of dimension n
|
|
r. C++ reference
|
|
m(class). Member pointer to class
|
|
f(args). Function.
|
|
q(qlist). Qualifiers
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In addition, type names may be parameterized by templates. This is
|
|
represented by enclosing the template parameters in <tt><(
|
|
... )></tt>. Variable length arguments are represented by the
|
|
special base type of <tt>v(...)</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
If you want to experiment with type encodings, the raw type strings can
|
|
be inserted into an interface file using backticks `` wherever a type
|
|
is expected. For instance, here is
|
|
an extremely perverted example:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
`p.a(10).p.f(int,p.f(int).int)` foo(int, int (*x)(int));
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
This corresponds to the immediately obvious C declaration:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
(*(*foo(int,int (*)(int)))[10])(int,int (*)(int));
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Aside from the potential use of this declaration on a C programming quiz,
|
|
it motivates the use of the special SWIG encoding of types. The SWIG
|
|
encoding is much easier to work with because types can be easily examined,
|
|
modified, and constructed using simple string operations (comparison,
|
|
substrings, concatenation, etc.). For example, in the parser, a declaration
|
|
like this
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int *a[30];
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
is processed in a few pieces. In this case, you have the base type
|
|
"<tt>int</tt>" and the declarator of type "<tt>a(30).p.</tt>". To
|
|
make the final type, the two parts are just joined together using
|
|
string concatenation.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn25"></a>34.8.2 Type construction</H3>
|
|
|
|
|
|
<p>
|
|
The following functions are used to construct types. You should use
|
|
these functions instead of trying to build the type strings yourself.
|
|
</p>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_add_pointer(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Adds a pointer to <tt>ty</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_del_pointer(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Removes a single pointer from <tt>ty</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_add_reference(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Adds a reference to <tt>ty</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_add_array(SwigType *ty, String_or_char *dim)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Adds an array with dimension <tt>dim</tt> to <tt>ty</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_del_array(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Removes a single array dimension from <tt>ty</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_array_ndim(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns number of array dimensions of <tt>ty</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>String* SwigType_array_getdim(SwigType *ty,int n)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns <tt>n</tt>th array dimension of <tt>ty</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_array_setdim(SwigType *ty, int n, const String_or_char *rep)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Sets <tt>n</tt>th array dimensions of <tt>ty</tt> to <tt>rep</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_add_qualifier(SwigType *ty, String_or_char *q)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Adds a type qualifier <tt>q</tt> to <tt>ty</tt>. <tt>q</tt> is typically
|
|
<tt>"const"</tt> or <tt>"volatile"</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_add_memberpointer(SwigType *ty, String_or_char *cls)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Adds a pointer to a member of class <tt>cls</tt> to <tt>ty</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_add_function(SwigType *ty, ParmList *p)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Adds a function to <tt>ty</tt>. <tt>p</tt> is a linked-list of parameter
|
|
nodes as generated by the parser. See the section on parameter lists
|
|
for details about the representation.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_add_template(SwigType *ty, ParmList *p)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Adds a template to <tt>ty</tt>. <tt>p</tt> is a linked-list of parameter
|
|
nodes as generated by the parser. See the section on parameter lists
|
|
for details about the representation.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>SwigType *SwigType_pop(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Removes the last type constructor from <tt>ty</tt> and returns it.
|
|
<tt>ty</tt> is modified.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>void SwigType_push(SwigType *ty, SwigType *op)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Pushes the type operators in <tt>op</tt> onto type <tt>ty</tt>. The
|
|
opposite of <tt>SwigType_pop()</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>SwigType *SwigType_pop_arrays(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Removes all leading array operators from <tt>ty</tt> and returns them.
|
|
<tt>ty</tt> is modified. For example, if <tt>ty</tt> is <tt>"a(20).a(10).p.int"</tt>,
|
|
then this function would return <tt>"a(20).a(10)."</tt> and modify <tt>ty</tt>
|
|
so that it has the value <tt>"p.int"</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>SwigType *SwigType_pop_function(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Removes a function operator from <tt>ty</tt> including any qualification.
|
|
<tt>ty</tt> is modified. For example, if <tt>ty</tt> is <tt>"f(int).int"</tt>,
|
|
then this function would return <tt>"f(int)."</tt> and modify <tt>ty</tt>
|
|
so that it has the value <tt>"int"</tt>.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>SwigType *SwigType_base(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the base type of a type. For example, if <tt>ty</tt> is
|
|
<tt>"p.a(20).int"</tt>, this function would return <tt>"int"</tt>.
|
|
<tt>ty</tt> is unmodified.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>SwigType *SwigType_prefix(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the prefix of a type. For example, if <tt>ty</tt> is
|
|
<tt>"p.a(20).int"</tt>, this function would return <tt>"p.a(20)."</tt>.
|
|
<tt>ty</tt> is unmodified.
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn26"></a>34.8.3 Type tests</H3>
|
|
|
|
|
|
<p>
|
|
The following functions can be used to test properties of a datatype.
|
|
</p>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_ispointer(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> is a standard pointer.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_ismemberpointer(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> is a member pointer.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_isreference(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> is a C++ reference.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_isarray(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> is an array.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_isfunction(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> is a function.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_isqualifier(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> is a qualifier.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_issimple(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> is a simple type. No operators applied.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_isconst(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> is a const type.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_isvarargs(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> is a varargs type.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int SwigType_istemplate(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> is a templatized type.
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn27"></a>34.8.4 Typedef and inheritance</H3>
|
|
|
|
|
|
<p>
|
|
The behavior of <tt>typedef</tt> declaration is to introduce a type alias.
|
|
For instance, <tt>typedef int Integer</tt> makes the identifier
|
|
<tt>Integer</tt> an alias for <tt>int</tt>. The treatment of typedef in
|
|
SWIG is somewhat complicated due to the pattern matching rules that get applied
|
|
in typemaps and the fact that SWIG prefers to generate wrapper code
|
|
that closely matches the input to simplify debugging (a user will see the
|
|
typedef names used in their program instead of the low-level primitive C
|
|
datatypes).
|
|
</p>
|
|
|
|
<p>
|
|
To handle <tt>typedef</tt>, SWIG builds a collection of trees containing typedef relations. For example,
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
typedef int Integer;
|
|
typedef Integer *IntegerPtr;
|
|
typedef int Number;
|
|
typedef int Size;
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
produces two trees like this:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
int p.Integer
|
|
^ ^ ^ ^
|
|
/ | \ |
|
|
/ | \ |
|
|
Integer Size Number IntegerPtr
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
To resolve a single typedef relationship, the following function is used:
|
|
</p>
|
|
|
|
<p>
|
|
<b><tt>SwigType *SwigType_typedef_resolve(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Checks if <tt>ty</tt> can be reduced to a new type via typedef. If so,
|
|
returns the new type. If not, returns NULL.
|
|
</div>
|
|
|
|
<p>
|
|
Typedefs are only resolved in simple typenames that appear in a type.
|
|
For example, the type base name and in function parameters. When
|
|
resolving types, the process starts in the leaf nodes and moves up
|
|
the tree towards the root. Here are a few examples that show how it works:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
Original type After typedef_resolve()
|
|
------------------------ -----------------------
|
|
Integer int
|
|
a(30).Integer int
|
|
p.IntegerPtr p.p.Integer
|
|
p.p.Integer p.p.int
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
For complicated types, the process can be quite involved. Here is the
|
|
reduction of a function pointer:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
p.f(Integer, p.IntegerPtr, Size).Integer : Start
|
|
p.f(Integer, p.IntegerPtr, Size).int
|
|
p.f(int, p.IntegerPtr, Size).int
|
|
p.f(int, p.p.Integer, Size).int
|
|
p.f(int, p.p.int, Size).int
|
|
p.f(int, p.p.int, int).int : End
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Two types are equivalent if their full type reductions are the same.
|
|
The following function will fully reduce a datatype:
|
|
</p>
|
|
|
|
<p>
|
|
<b><tt>SwigType *SwigType_typedef_resolve_all(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Fully reduces <tt>ty</tt> according to typedef rules. Resulting datatype
|
|
will consist only of primitive typenames.
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn28"></a>34.8.5 Lvalues</H3>
|
|
|
|
|
|
<p>
|
|
When generating wrapper code, it is necessary to emit datatypes that can
|
|
be used on the left-hand side of an assignment operator (an lvalue). However,
|
|
not all C datatypes can be used in this way---especially arrays and
|
|
const-qualified types. To generate a type that can be used as an lvalue,
|
|
use the following function:
|
|
</p>
|
|
|
|
<p>
|
|
<b><tt>SwigType *SwigType_ltype(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Converts type <tt>ty</tt> to a type that can be used as an lvalue in
|
|
assignment. The resulting type is stripped of qualifiers and arrays are
|
|
converted to a pointers.
|
|
</div>
|
|
|
|
<p>
|
|
The creation of lvalues is fully aware of typedef and other aspects
|
|
of the type system. Therefore, the creation of an lvalue may result in
|
|
unexpected results. Here are a few examples:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
typedef double Matrix4[4][4];
|
|
Matrix4 x; // type = 'Matrix4', ltype='p.a(4).double'
|
|
|
|
typedef const char * Literal;
|
|
Literal y; // type = 'Literal', ltype='p.char'
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn29"></a>34.8.6 Output functions</H3>
|
|
|
|
|
|
<p>
|
|
The following functions produce strings that are suitable for output.
|
|
</p>
|
|
|
|
<p>
|
|
<b><tt>String *SwigType_str(SwigType *ty, String_or_char *id = 0)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Generates a C string for a datatype. <tt>id</tt> is an optional declarator.
|
|
For example, if <tt>ty</tt> is "p.f(int).int" and <tt>id</tt> is "foo", then
|
|
this function produces "<tt>int (*foo)(int)</tt>". This function is
|
|
used to convert string-encoded types back into a form that is valid C syntax.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>String *SwigType_lstr(SwigType *ty, String_or_char *id = 0)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
This is the same as <tt>SwigType_str()</tt> except that the result
|
|
is generated from the type's lvalue (as generated from SwigType_ltype).
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>String *SwigType_lcaststr(SwigType *ty, String_or_char *id = 0)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Generates a casting operation that converts from type <tt>ty</tt> to its
|
|
lvalue. <tt>id</tt> is an optional name to include in the cast. For example,
|
|
if <tt>ty</tt> is "<tt>q(const).p.char</tt>" and <tt>id</tt> is "<tt>foo</tt>",
|
|
this function produces the string "<tt>(char *) foo</tt>".
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>String *SwigType_rcaststr(SwigType *ty, String_or_char *id = 0)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Generates a casting operation that converts from a type's lvalue to a
|
|
type equivalent to <tt>ty</tt>. <tt>id</tt> is an optional name to
|
|
include in the cast. For example, if <tt>ty</tt> is
|
|
"<tt>q(const).p.char</tt>" and <tt>id</tt> is "<tt>foo</tt>", this
|
|
function produces the string "<tt>(const char *) foo</tt>".
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>String *SwigType_manglestr(SwigType *ty)</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Generates a mangled string encoding of type <tt>ty</tt>. The
|
|
mangled string only contains characters that are part of a valid
|
|
C identifier. The resulting string is used in various parts of
|
|
SWIG, but is most commonly associated with type-descriptor objects
|
|
that appear in wrappers (e.g., <tt>SWIGTYPE_p_double</tt>).
|
|
</div>
|
|
|
|
<H2><a name="Extending_nn30"></a>34.9 Parameters</H2>
|
|
|
|
|
|
<p>
|
|
Several type-related functions involve parameter lists. These include
|
|
functions and templates. Parameter list are represented as a list of
|
|
nodes with the following attributes:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"type" - Parameter type (required)
|
|
"name" - Parameter name (optional)
|
|
"value" - Initializer (optional)
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Typically parameters are denoted in the source by using a typename of
|
|
<tt>Parm *</tt> or <tt>ParmList *</tt>. To walk a parameter list, simply use
|
|
code like this:
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
Parm *parms;
|
|
Parm *p;
|
|
for (p = parms; p; p = nextSibling(p)) {
|
|
SwigType *type = Getattr(p,"type");
|
|
String *name = Getattr(p,"name");
|
|
String *value = Getattr(p,"value");
|
|
...
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Note: this code is exactly the same as what you would use to walk parse tree nodes.
|
|
</p>
|
|
|
|
<p>
|
|
An empty list of parameters is denoted by a NULL pointer.
|
|
</p>
|
|
|
|
<p>
|
|
Since parameter lists are fairly common, the following utility functions are provided
|
|
to manipulate them:
|
|
</p>
|
|
|
|
<p>
|
|
<b><tt>Parm *CopyParm(Parm *p);</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Copies a single parameter.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>ParmList *CopyParmList(ParmList *p);</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Copies an entire list of parameters.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int ParmList_len(ParmList *p);</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the number of parameters in a parameter list.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>String *ParmList_str(ParmList *p);</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Converts a parameter list into a C string. For example,
|
|
produces a string like "<tt>(int *p, int n, double x);</tt>".
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>String *ParmList_protostr(ParmList *p);</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
The same as <tt>ParmList_str()</tt> except that parameter names are not
|
|
included. Used to emit prototypes.
|
|
</div>
|
|
|
|
<p>
|
|
<b><tt>int ParmList_numrequired(ParmList *p);</tt></b>
|
|
</p>
|
|
|
|
<div class="indent">
|
|
Returns the number of required (non-optional) arguments in <tt>p</tt>.
|
|
</div>
|
|
|
|
<H2><a name="Extending_nn31"></a>34.10 Writing a Language Module</H2>
|
|
|
|
|
|
<p>
|
|
One of the easiest routes to supporting a new language module is to copy an already
|
|
supported language module implementation and modify it.
|
|
Be sure to choose a language that is similar in nature to the new language.
|
|
All language modules follow a similar structure and
|
|
this section briefly outlines the steps needed to create a bare-bones
|
|
language module from scratch.
|
|
Since the code is relatively easy to read, this section
|
|
describes the creation of a minimal Python module. You should be able to extrapolate
|
|
this to other languages.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn32"></a>34.10.1 Execution model</H3>
|
|
|
|
|
|
<p>
|
|
Code generation modules are defined by inheriting from the <tt>Language</tt> class,
|
|
currently defined in the <tt>Source/Modules</tt> directory of SWIG. Starting from
|
|
the parsing of command line options, all aspects of code generation are controlled by
|
|
different methods of the <tt>Language</tt> that must be defined by your module.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn33"></a>34.10.2 Starting out</H3>
|
|
|
|
|
|
<p>
|
|
To define a new language module, first create a minimal implementation using
|
|
this example as a guide:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#include "swigmod.h"
|
|
|
|
class PYTHON : public Language {
|
|
public:
|
|
|
|
virtual void main(int argc, char *argv[]) {
|
|
printf("I'm the Python module.\n");
|
|
}
|
|
|
|
virtual int top(Node *n) {
|
|
printf("Generating code.\n");
|
|
return SWIG_OK;
|
|
}
|
|
|
|
};
|
|
|
|
extern "C" Language *
|
|
swig_python(void) {
|
|
return new PYTHON();
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The "swigmod.h" header file contains, among other things, the declaration
|
|
of the <tt>Language</tt> base class and so you should include it at the top
|
|
of your language module's source file. Similarly, the "swigconfig.h" header
|
|
file contains some other useful definitions that you may need. Note that you
|
|
should <em>not</em> include any header files that are installed with the
|
|
target language. That is to say, the implementation of the SWIG Python module
|
|
shouldn't have any dependencies on the Python header files. The wrapper code
|
|
generated by SWIG will almost always depend on some language-specific C/C++
|
|
header files, but SWIG itself does not.
|
|
</p>
|
|
|
|
<p>
|
|
Give your language class a reasonable name, usually the same as the target language.
|
|
By convention, these class names are all uppercase (e.g. "PYTHON" for the Python
|
|
language module) but this is not a requirement. This class will ultimately consist
|
|
of a number of overrides of the virtual functions declared in the <tt>Language</tt>
|
|
base class, in addition to any language-specific member functions and data you
|
|
need. For now, just use the dummy implementations shown above.
|
|
</p>
|
|
|
|
<p>
|
|
The language module ends with a factory function, <tt>swig_python()</tt>, that simply
|
|
returns a new instance of the language class. As shown, it should be declared with the
|
|
<tt>extern "C"</tt> storage qualifier so that it can be called from C code. It should
|
|
also return a pointer to the base class (<tt>Language</tt>) so that only the interface
|
|
(and not the implementation) of your language module is exposed to the rest of SWIG.
|
|
</p>
|
|
|
|
<p>
|
|
Save the code for your language module in a file named "<tt>python.cxx</tt>" and.
|
|
place this file in the <tt>Source/Modules</tt> directory of the SWIG distribution.
|
|
To ensure that your module is compiled into SWIG along with the other language modules,
|
|
modify the file <tt>Source/Modules/Makefile.am</tt> to include the additional source
|
|
files. In addition, modify the file <tt>Source/Modules/swigmain.cxx</tt>
|
|
with an additional command line option that activates the module. Read the source---it's straightforward.
|
|
</p>
|
|
|
|
<p>
|
|
Next, at the top level of the SWIG distribution, re-run the <tt>autogen.sh</tt> script
|
|
to regenerate the various build files:
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
$ <b>./autogen.sh</b>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Next re-run <tt>configure</tt> to regenerate all of the Makefiles:
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
$ <b>./configure</b>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Finally, rebuild SWIG with your module added:
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
$ <b>make</b>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Once it finishes compiling, try running SWIG with the command-line option
|
|
that activates your module. For example, <tt>swig -python foo.i</tt>. The
|
|
messages from your new module should appear.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn34"></a>34.10.3 Command line options</H3>
|
|
|
|
|
|
<p>
|
|
When SWIG starts, the command line options are passed to your language module. This occurs
|
|
before any other processing occurs (preprocessing, parsing, etc.). To capture the
|
|
command line options, simply use code similar to this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void Language::main(int argc, char *argv[]) {
|
|
for (int i = 1; i < argc; i++) {
|
|
if (argv[i]) {
|
|
if(strcmp(argv[i],"-interface") == 0) {
|
|
if (argv[i+1]) {
|
|
interface = NewString(argv[i+1]);
|
|
Swig_mark_arg(i);
|
|
Swig_mark_arg(i+1);
|
|
i++;
|
|
} else {
|
|
Swig_arg_error();
|
|
}
|
|
} else if (strcmp(argv[i],"-globals") == 0) {
|
|
if (argv[i+1]) {
|
|
global_name = NewString(argv[i+1]);
|
|
Swig_mark_arg(i);
|
|
Swig_mark_arg(i+1);
|
|
i++;
|
|
} else {
|
|
Swig_arg_error();
|
|
}
|
|
} else if ( (strcmp(argv[i],"-proxy") == 0)) {
|
|
proxy_flag = 1;
|
|
Swig_mark_arg(i);
|
|
} else if (strcmp(argv[i],"-keyword") == 0) {
|
|
use_kw = 1;
|
|
Swig_mark_arg(i);
|
|
} else if (strcmp(argv[i],"-help") == 0) {
|
|
fputs(usage,stderr);
|
|
}
|
|
...
|
|
}
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The exact set of options depends on what you want to do in your module. Generally,
|
|
you would use the options to change code generation modes or to print diagnostic information.
|
|
</p>
|
|
|
|
<p>
|
|
If a module recognizes an option, it should always call <tt>Swig_mark_arg()</tt>
|
|
to mark the option as valid. If you forget to do this, SWIG will terminate with an
|
|
unrecognized command line option error.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn35"></a>34.10.4 Configuration and preprocessing</H3>
|
|
|
|
|
|
<p>
|
|
In addition to looking at command line options, the <tt>main()</tt> method is responsible
|
|
for some initial configuration of the SWIG library and preprocessor. To do this,
|
|
insert some code like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
void main(int argc, char *argv[]) {
|
|
... command line options ...
|
|
|
|
/* Set language-specific subdirectory in SWIG library */
|
|
SWIG_library_directory("python");
|
|
|
|
/* Set language-specific preprocessing symbol */
|
|
Preprocessor_define("SWIGPYTHON 1", 0);
|
|
|
|
/* Set language-specific configuration file */
|
|
SWIG_config_file("python.swg");
|
|
|
|
/* Set typemap language (historical) */
|
|
SWIG_typemap_lang("python");
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The above code does several things--it registers the name of the
|
|
language module with the core, it supplies some preprocessor macro definitions
|
|
for use in input files (so that they can determine the target language), and
|
|
it registers a start-up file. In this case, the file <tt>python.swg</tt> will
|
|
be parsed before any part of the user-supplied input file.
|
|
</p>
|
|
|
|
<p>
|
|
Before proceeding any further, create a directory for your module in the SWIG
|
|
library (The <tt>Lib</tt> directory). Now, create a configuration file in the
|
|
directory. For example, <tt>python.swg</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
Just to review, your language module should now consist of two files--
|
|
an implementation file <tt>python.cxx</tt> and a configuration file
|
|
<tt>python.swg</tt>.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn36"></a>34.10.5 Entry point to code generation</H3>
|
|
|
|
|
|
<p>
|
|
SWIG is a multi-pass compiler. Once the <tt>main()</tt> method has
|
|
been invoked, the language module does not execute again until
|
|
preprocessing, parsing, and a variety of semantic analysis passes have
|
|
been performed. When the core is ready to start generating wrappers,
|
|
it invokes the <tt>top()</tt> method of your language class. The
|
|
argument to <tt>top</tt> is a single parse tree node that corresponds to
|
|
the top of the entire parse tree.
|
|
</p>
|
|
|
|
<p>
|
|
To get the code generation process started, the <tt>top()</tt> procedure needs
|
|
to do several things:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>Initialize the wrapper code output.
|
|
<li>Set the module name.
|
|
<li>Emit common initialization code.
|
|
<li>Emit code for all of the child nodes.
|
|
<li>Finalize the wrapper module and cleanup.
|
|
</ul>
|
|
|
|
<p>
|
|
An outline of <tt>top()</tt> might be as follows:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int Python::top(Node *n) {
|
|
|
|
/* Get the module name */
|
|
String *module = Getattr(n,"name");
|
|
|
|
/* Get the output file name */
|
|
String *outfile = Getattr(n,"outfile");
|
|
|
|
/* Initialize I/O (see next section) */
|
|
...
|
|
|
|
/* Output module initialization code */
|
|
...
|
|
|
|
/* Emit code for children */
|
|
Language::top(n);
|
|
|
|
...
|
|
/* Cleanup files */
|
|
...
|
|
|
|
return SWIG_OK;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn37"></a>34.10.6 Module I/O and wrapper skeleton</H3>
|
|
|
|
|
|
<!-- please report bugs in this section to mgossage -->
|
|
|
|
|
|
<p>
|
|
Within SWIG wrappers, there are four main sections. These are (in order)
|
|
</p>
|
|
|
|
<ul>
|
|
<li>runtime: This section has most of the common SWIG runtime code
|
|
<li>header: This section holds declarations and inclusions from the .i file
|
|
<li>wrapper: This section holds all the wrappering code
|
|
<li>init: This section holds the module initalisation function
|
|
(the entry point for the interpreter)
|
|
</ul>
|
|
<p>
|
|
Different parts of the SWIG code will fill different sections,
|
|
then upon completion of the wrappering all the sections will be saved
|
|
to the wrapper file.
|
|
</p>
|
|
<p>
|
|
To perform this will require several additions to the code in various places,
|
|
such as:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
class PYTHON : public Language {
|
|
protected:
|
|
/* General DOH objects used for holding the strings */
|
|
File *f_runtime;
|
|
File *f_header;
|
|
File *f_wrappers;
|
|
File *f_init;
|
|
|
|
public:
|
|
...
|
|
|
|
};
|
|
|
|
int Python::top(Node *n) {
|
|
|
|
...
|
|
|
|
/* Initialize I/O */
|
|
f_runtime = NewFile(outfile, "w");
|
|
if (!f_runtime) {
|
|
FileErrorDisplay(outfile);
|
|
SWIG_exit(EXIT_FAILURE);
|
|
}
|
|
f_init = NewString("");
|
|
f_header = NewString("");
|
|
f_wrappers = NewString("");
|
|
|
|
/* Register file targets with the SWIG file handler */
|
|
Swig_register_filebyname("header", f_header);
|
|
Swig_register_filebyname("wrapper", f_wrappers);
|
|
Swig_register_filebyname("runtime", f_runtime);
|
|
Swig_register_filebyname("init", f_init);
|
|
|
|
/* Output module initialization code */
|
|
...
|
|
|
|
/* Emit code for children */
|
|
Language::top(n);
|
|
|
|
...
|
|
/* Write all to the file */
|
|
Dump(f_header, f_runtime);
|
|
Dump(f_wrappers, f_runtime);
|
|
Wrapper_pretty_print(f_init, f_runtime);
|
|
|
|
/* Cleanup files */
|
|
Delete(f_header);
|
|
Delete(f_wrappers);
|
|
Delete(f_init);
|
|
Close(f_runtime);
|
|
Delete(f_runtime);
|
|
|
|
return SWIG_OK;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Using this to process a file will generate a wrapper file, however the
|
|
wrapper will only consist of the common SWIG code as well as any inline
|
|
code which was written in the .i file. It does not contain any wrappers for
|
|
any of the functions or classes.
|
|
</p>
|
|
|
|
<p>
|
|
The code to generate the wrappers are the various member functions, which
|
|
currently have not been touched. We will look at <tt>functionWrapper()</tt> as this
|
|
is the most commonly used function. In fact many of the other wrapper routines
|
|
will call this to do their work.
|
|
</p>
|
|
<p>
|
|
A simple modification to write some basic details to the wrapper looks like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int Python::functionWrapper(Node *n) {
|
|
/* Get some useful attributes of this function */
|
|
String *name = Getattr(n,"sym:name");
|
|
SwigType *type = Getattr(n,"type");
|
|
ParmList *parms = Getattr(n,"parms");
|
|
String *parmstr= ParmList_str_defaultargs(parms); // to string
|
|
String *func = SwigType_str(type, NewStringf("%s(%s)", name, parmstr));
|
|
String *action = Getattr(n,"wrap:action");
|
|
|
|
Printf(f_wrappers,"functionWrapper : %s\n", func);
|
|
Printf(f_wrappers," action : %s\n", action);
|
|
return SWIG_OK;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
This will now produce some useful information within your wrapper file.
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
functionWrapper : void delete_Shape(Shape *self)
|
|
action : delete arg1;
|
|
|
|
functionWrapper : void Shape_x_set(Shape *self,double x)
|
|
action : if (arg1) (arg1)->x = arg2;
|
|
|
|
functionWrapper : double Shape_x_get(Shape *self)
|
|
action : result = (double) ((arg1)->x);
|
|
|
|
functionWrapper : void Shape_y_set(Shape *self,double y)
|
|
action : if (arg1) (arg1)->y = arg2;
|
|
...
|
|
</pre>
|
|
</div>
|
|
|
|
<H3><a name="Extending_nn38"></a>34.10.7 Low-level code generators</H3>
|
|
|
|
|
|
<!-- please report bugs in this section to mgossage -->
|
|
|
|
<p>
|
|
As ingenious as SWIG is, and despite all its capabilities and the power of
|
|
its parser, the Low-level code generation takes a lot of work to write
|
|
properly. Mainly because every language insists on its own manner of
|
|
interfacing to C/C++. To write the code generators you will need a good
|
|
understanding of how to manually write an interface to your chosen
|
|
language, so make sure you have your documentation handy.
|
|
</p>
|
|
<p>
|
|
At this point it is also probably a good idea to take a very simple file
|
|
(just one function), and try letting SWIG generate wrappers for many
|
|
different languages. Take a look at all of the wrappers generated, and decide
|
|
which one looks closest to the language you are trying to wrap.
|
|
This may help you to decide which code to look at.
|
|
</p>
|
|
<p>
|
|
In general most language wrappers look a little like this:
|
|
</p>
|
|
<div class="code">
|
|
<pre>
|
|
/* wrapper for TYPE3 some_function(TYPE1,TYPE2); */
|
|
RETURN_TYPE _wrap_some_function(ARGS){
|
|
TYPE1 arg1;
|
|
TYPE2 arg2;
|
|
TYPE3 result;
|
|
|
|
if(ARG1 is not of TYPE1) goto fail;
|
|
arg1=(convert ARG1);
|
|
if(ARG2 is not of TYPE2) goto fail;
|
|
arg2=(convert ARG2);
|
|
|
|
result=some_function(arg1,arg2);
|
|
|
|
convert 'result' to whatever the language wants;
|
|
|
|
do any tidy up;
|
|
|
|
return ALL_OK;
|
|
|
|
fail:
|
|
do any tidy up;
|
|
return ERROR;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Yes, it is rather vague and not very clear. But each language works differently
|
|
so this will have to do for now.
|
|
</p>
|
|
<p>
|
|
Tackling this problem will be done in two stages:
|
|
</p>
|
|
<ul>
|
|
<li>The skeleton: the function wrapper, and call, but without the conversion
|
|
<li>The conversion: converting the arguments to-from what the language wants
|
|
</ul>
|
|
<p>
|
|
The first step will be done in the code, the second will be done in typemaps.
|
|
</p>
|
|
<p>
|
|
Our first step will be to write the code for <tt>functionWrapper()</tt>. What is
|
|
shown below is <b>NOT</b> the solution, merely a step in the right direction.
|
|
There are a lot of issues to address.
|
|
</p>
|
|
<ul>
|
|
<li>Variable length and default parameters
|
|
<li>Typechecking and number of argument checks
|
|
<li>Overloaded functions
|
|
<li>Inout and Output only arguments
|
|
</ul>
|
|
<div class="code">
|
|
<pre>
|
|
virtual int functionWrapper(Node *n) {
|
|
/* get useful atributes */
|
|
String *name = Getattr(n,"sym:name");
|
|
SwigType *type = Getattr(n,"type");
|
|
ParmList *parms = Getattr(n,"parms");
|
|
...
|
|
|
|
/* create the wrapper object */
|
|
Wrapper *wrapper = NewWrapper();
|
|
|
|
/* create the functions wrappered name */
|
|
String *wname = Swig_name_wrapper(iname);
|
|
|
|
/* deal with overloading */
|
|
....
|
|
|
|
/* write the wrapper function definition */
|
|
Printv(wrapper->def,"RETURN_TYPE ", wname, "(ARGS) {",NIL);
|
|
|
|
/* if any additional local variable needed, add them now */
|
|
...
|
|
|
|
/* write the list of locals/arguments required */
|
|
emit_args(type, parms, wrapper);
|
|
|
|
/* check arguments */
|
|
...
|
|
|
|
/* write typemaps(in) */
|
|
....
|
|
|
|
/* write constriants */
|
|
....
|
|
|
|
/* Emit the function call */
|
|
emit_action(n,wrapper);
|
|
|
|
/* return value if necessary */
|
|
....
|
|
|
|
/* write typemaps(out) */
|
|
....
|
|
|
|
/* add cleanup code */
|
|
....
|
|
|
|
/* Close the function(ok) */
|
|
Printv(wrapper->code, "return ALL_OK;\n", NIL);
|
|
|
|
/* add the failure cleanup code */
|
|
...
|
|
|
|
/* Close the function(error) */
|
|
Printv(wrapper->code, "return ERROR;\n", "}\n", NIL);
|
|
|
|
/* final substititions if applicable */
|
|
...
|
|
|
|
/* Dump the function out */
|
|
Wrapper_print(wrapper,f_wrappers);
|
|
|
|
/* tidy up */
|
|
Delete(wname);
|
|
DelWrapper(wrapper);
|
|
|
|
return SWIG_OK;
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Executing this code will produce wrappers which have our basic skeleton
|
|
but without the typemaps, there is still work to do.
|
|
</p>
|
|
|
|
|
|
<H3><a name="Extending_nn39"></a>34.10.8 Configuration files</H3>
|
|
|
|
|
|
<!-- please report bugs in this section to ttn -->
|
|
|
|
<p>
|
|
At the time of this writing, SWIG supports nearly a dozen languages,
|
|
which means that for continued sanity in maintaining the configuration
|
|
files, the language modules need to follow some conventions. These are
|
|
outlined here along with the admission that, yes it is ok to violate
|
|
these conventions in minor ways, as long as you know where to apply the
|
|
proper kludge to keep the overall system regular and running.
|
|
Engineering is the art of compromise, see...
|
|
</p>
|
|
|
|
<p>
|
|
Much of the maintenance regularity depends on choosing a suitable
|
|
nickname for your language module (and then using it in a controlled
|
|
way). Nicknames should be all lower case letters with an optional
|
|
numeric suffix (no underscores, no dashes, no spaces). Some examples
|
|
are: <TT>foo</TT>, <TT>bar</TT>, <TT>qux99</TT>.
|
|
</p>
|
|
|
|
<p>
|
|
The numeric suffix variant, as in the last example, is somewhat tricky
|
|
to work with because sometimes people expect to refer to the language
|
|
without this number but sometimes that number is extremely relevant
|
|
(especially when it corresponds to language implementation versions with
|
|
incompatible interfaces). New language modules that unavoidably require
|
|
a numeric suffix in their nickname should include that number in all
|
|
uses, or be prepared to kludge.
|
|
</p>
|
|
|
|
<p>
|
|
The nickname is used in four places:
|
|
</p>
|
|
|
|
<TABLE summary="nickname table">
|
|
<TR><TD><B>usage</B></TD><TD><B>transform</B></TD></TR>
|
|
<TR><TD>"skip" tag</TD><TD>(none)</TD></TR>
|
|
<TR><TD>Examples/ subdir name</TD><TD>(none)</TD></TR>
|
|
<TR><TD>Examples/GIFPlot/ subdir name</TD>
|
|
<TD>capitalize (upcase first letter)</TD></TR>
|
|
<TR><TD>Examples/test-suite/ subdir name</TD><TD>(none)</TD></TR>
|
|
<!-- add more uses here (remember to adjust header) -->
|
|
</TABLE>
|
|
|
|
<p>
|
|
As you can see, most usages are direct.
|
|
</p>
|
|
|
|
<dl>
|
|
|
|
<dt> <b>configure.in</b>
|
|
<dd> This file is processed by
|
|
|
|
<p>
|
|
<A HREF="http://www.gnu.org/software/autoconf/">autoconf</A>
|
|
to generate the <TT>configure</TT> script. This is where you
|
|
need to add shell script fragments and autoconf macros to detect the
|
|
presence of whatever development support your language module requires,
|
|
typically directories where headers and libraries can be found, and/or
|
|
utility programs useful for integrating the generated wrapper code.
|
|
</p>
|
|
|
|
<p>
|
|
Use the <TT>AC_ARG_WITH</TT>, <TT>AC_MSG_CHECKING</TT>, <TT>AC_SUBST</TT>
|
|
macros and so forth (see other languages for examples). Avoid using the
|
|
<TT>[</TT> and <TT>]</TT> character in shell script fragments. The
|
|
variable names passed to <TT>AC_SUBST</TT> should begin with the nickname,
|
|
entirely upcased.
|
|
</p>
|
|
|
|
<p>
|
|
At the end of the new section is the place to put the aforementioned
|
|
nickname kludges (should they be needed). See Perl5 and Php4 for
|
|
examples of what to do. [If this is still unclear after you've read
|
|
the code, ping me and I'll expand on this further. --ttn]
|
|
</p>
|
|
|
|
<dt> <b>Makefile.in</b>
|
|
<dd>
|
|
|
|
<p>
|
|
Some of the variables AC_SUBSTituted are essential to the
|
|
support of your language module. Fashion these into a shell script
|
|
"test" clause and assign that to a skip tag using "-z" and "-o":
|
|
</p>
|
|
|
|
<div class="code"><tt>
|
|
skip-qux99 = [ -z "@QUX99INCLUDE@" -o -z "@QUX99LIBS" ]
|
|
</tt></div>
|
|
|
|
<p>
|
|
This means if those vars should ever be empty, qux99 support should
|
|
be considered absent and so it would be a good idea to skip actions that
|
|
might rely on it.
|
|
</p>
|
|
|
|
<p>
|
|
Here is where you may also define an alias (but then you'll need to
|
|
kludge --- don't do this):
|
|
</p>
|
|
|
|
<div class="code"><tt>
|
|
skip-qux = $(skip-qux99)
|
|
</tt></div>
|
|
|
|
<p>
|
|
Lastly, you need to modify each of <TT>check-aliveness</TT>,
|
|
<TT>check-examples</TT>, <TT>check-test-suite</TT>,
|
|
<TT>check-gifplot</TT> (all targets) and <TT>lib-languages</TT> (var).
|
|
Use the nickname for these, not the alias.
|
|
Note that you can do this even before you have any tests or examples
|
|
set up; the Makefile rules do some sanity checking and skip around
|
|
these kinds of problems.
|
|
</p>
|
|
|
|
<dt> <b>Examples/Makefile.in</b>
|
|
<dd> Nothing special here; see comments at top the of this file
|
|
and look to the existing languages for examples.
|
|
|
|
<dt> <b>Examples/qux99/check.list</b>
|
|
<dd> Do <TT>cp ../python/check.list .</TT> and modify to taste.
|
|
One subdir per line.
|
|
|
|
<dt> <b>Examples/GIFPlot/Qux99/check.list</b>
|
|
<dd> Do <TT>cp ../Python/check.list .</TT> and modify to taste.
|
|
One subdir per line.
|
|
|
|
<dt> <b>Lib/qux99/extra-install.list</b>
|
|
<dd> If you add your language to the top-level Makefile.in var
|
|
<TT>lib-languages</TT>, then <TT>make install</TT> will install
|
|
all <TT>*.i</TT> and <TT>*.swg</TT> files from the language-specific
|
|
subdirectory of <TT>Lib</TT>. Use (optional) file
|
|
<TT>extra-install.list</TT> in that directory to name
|
|
additional files to install (see ruby for example).
|
|
|
|
<dt> <b>Source/Modules/Makefile.am</b>
|
|
<dd> Add appropriate files to this Automake file. That's it!
|
|
|
|
<p>
|
|
When you have modified these files, please make sure that the new language module is completely
|
|
ignored if it is not installed and detected on a box, that is, <tt>make check-examples</tt> and <tt>make check-test-suite</tt>
|
|
politely displays the ignoring language message.
|
|
</p>
|
|
|
|
</dl>
|
|
|
|
|
|
<H3><a name="Extending_nn40"></a>34.10.9 Runtime support</H3>
|
|
|
|
|
|
<p>
|
|
Discuss the kinds of functions typically needed for SWIG runtime support (e.g.
|
|
<tt>SWIG_ConvertPtr()</tt> and <tt>SWIG_NewPointerObj()</tt>) and the names of
|
|
the SWIG files that implement those functions.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn41"></a>34.10.10 Standard library files</H3>
|
|
|
|
|
|
<p>
|
|
The standard library files that most languages supply keeps growing as SWIG matures.
|
|
The following are the minimum that are usually supported:
|
|
</p>
|
|
|
|
<ul>
|
|
<li> typemaps.i </li>
|
|
<li> std_string.i </li>
|
|
<li> std_vector.i </li>
|
|
<li> stl.i </li>
|
|
</ul>
|
|
|
|
<p>
|
|
Please copy these and modify for any new language.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn42"></a>34.10.11 Examples and test cases</H3>
|
|
|
|
|
|
<p>
|
|
Each of the language modules provides one or more examples. These examples
|
|
are used to demonstrate different features of the language module to SWIG
|
|
end-users, but you'll find that they're useful during development and testing
|
|
of your language module as well. You can use examples from the existing SWIG
|
|
language modules for inspiration.
|
|
</p>
|
|
|
|
<p>
|
|
Each example is self-contained and consists of (at least) a <tt>Makefile</tt>,
|
|
a SWIG interface file for the example module, and a 'runme' script that demonstrates
|
|
the functionality for that module. All of these files are stored in the same
|
|
subdirectory under the <tt>Examples/[lang]</tt> directory.
|
|
There are two classic examples which should be the first to convert to a new
|
|
language module. These are the "simple" C example and the "class" C++ example.
|
|
These can be found, for example for Python, in
|
|
<tt>Examples/python/simple</tt> and <tt>Examples/python/class</tt>.
|
|
</p>
|
|
|
|
<p>
|
|
By default, all of the examples are built and run when the user types
|
|
<tt>make check</tt>. To ensure that your examples are automatically run
|
|
during this process, see the section on <a href="#n37a">configuration
|
|
files</a>.
|
|
</p>
|
|
|
|
<H3><a name="Extending_nn43"></a>34.10.12 Documentation</H3>
|
|
|
|
|
|
<p>
|
|
Don't forget to write end-user documentation for your language module. Currently,
|
|
each language module has a dedicated chapter
|
|
You shouldn't rehash things that are already covered in sufficient
|
|
detail in the <a href="SWIG.html#SWIG">SWIG Basics</a> and <a href="SWIGPlus.html#SWIGPlus">SWIG
|
|
and C++</a> chapters. There is no fixed format for <em>what</em>, exactly, you should
|
|
document about your language module, but you'll obviously want to cover issues that
|
|
are unique to your language.
|
|
</p>
|
|
|
|
<p>
|
|
Some topics that you'll want to be sure to address include:
|
|
</p>
|
|
|
|
<ul>
|
|
<li> Command line options unique to your language module.
|
|
<li> Non-obvious mappings between C/C++ and target language concepts.
|
|
For example, if your target language provides a single floating
|
|
point type, it should be no big surprise to find that C/C++
|
|
<tt>float</tt> and <tt>double</tt> types are mapped to it. On the other
|
|
hand, if your target language doesn't provide support for "classes"
|
|
or something similar, you'd want to discuss how C++ classes are handled.
|
|
<li> How to compile the SWIG-generated wrapper code into shared libraries
|
|
that can actually be used. For some languages, there are well-defined
|
|
procedures for doing this, but for others it's an ad hoc process.
|
|
Provide as much detail as appropriate, and links to other resources
|
|
if available.
|
|
</ul>
|
|
|
|
<H3><a name="Extending_prerequisites"></a>34.10.13 Prerequisites for adding a new language module to the SWIG distribution</H3>
|
|
|
|
|
|
<p>
|
|
If you wish for a new language module to be distributed with SWIG,
|
|
which we encourage for all popular languages, there are a few requirements.
|
|
While we appreciate that getting all aspects of a new language working
|
|
won't happen at the outset, there are a set of minimum requirements before
|
|
a module can be committed into the SVN repository for distribution with future
|
|
versions of SWIG. The following are really a summary of this whole section with
|
|
details being outlined earlier on.
|
|
</p>
|
|
|
|
<ol>
|
|
<li>
|
|
Demonstrate basic C code working by porting the "simple" example including
|
|
a runtime test, see for example <tt>Examples/python/simple</tt>.
|
|
</li>
|
|
<li>
|
|
Demonstrate basic C++ code working by porting the "class" example including
|
|
a runtime test, see for example <tt>Examples/python/class</tt>.
|
|
</li>
|
|
<li>
|
|
Modify <tt>configure.in</tt>, <tt>Makefile.in</tt> and <tt>Examples/Makefile.in</tt> to run
|
|
these examples. Please make sure that if the new language is not
|
|
installed properly on a box, <tt>make -k check</tt> should still work by
|
|
skipping the tests and examples for the new language module.
|
|
</li>
|
|
<li>
|
|
Get the test-suite running for the new language (<tt>make check-[lang]-test-suite</tt>).
|
|
While the test-suite tests many corner cases,
|
|
we'd expect the majority of it to work by compiling the generated code
|
|
correctly as most of the corner cases are covered in the SWIG core. Get
|
|
at least one C and one C++ runtime test running in the test-suite.
|
|
</li>
|
|
<li>
|
|
Provide a chapter in the html documentation on the basics of using
|
|
the language module.
|
|
</li>
|
|
<li>
|
|
Ensure your source code is formatted according to the <a href="#Extending_coding_style_guidelines">coding style guidelines</a>.
|
|
</li>
|
|
<li>
|
|
Finally, email the SWIG developers with a patch and a demonstration of
|
|
commitment to maintaining the language module,
|
|
certainly in the short term and ideally long term.
|
|
</li>
|
|
</ol>
|
|
|
|
<p>
|
|
Once accepted into SVN, development efforts should concentrate on
|
|
getting the entire test-suite to work with plenty of runtime tests.
|
|
Runtime tests should be for existing testcases and new test cases
|
|
should be added should there be an area not already covered by
|
|
the existing tests.
|
|
</p>
|
|
|
|
<H3><a name="Extending_coding_style_guidelines"></a>34.10.14 Coding style guidelines</H3>
|
|
|
|
|
|
<p>
|
|
The coding guidelines for the C/C++ source code are pretty much K&R C style.
|
|
The style can be inferred from the existing code base and is
|
|
largely dictated by the <tt>indent</tt> code beautifier tool set to K&R style.
|
|
The code can formatted using the make targets in the Source directory.
|
|
Below is an example of how to format the emit.cxx file:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
$ cd Source
|
|
$ make beautify-file INDENTFILE=Modules/emit.cxx
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>
|
|
Of particular note is indentation is set to 2 spaces and a tab is used instead of 8 spaces.
|
|
The generated C/C++ code should also follow this style as close as possible. However, tabs
|
|
should be avoided as unlike the SWIG developers, users will never have consistent tab settings.
|
|
</p>
|
|
|
|
<H2><a name="Extending_nn44"></a>34.11 Typemaps</H2>
|
|
|
|
|
|
<H3><a name="Extending_nn45"></a>34.11.1 Proxy classes</H3>
|
|
|
|
|
|
<H2><a name="Extending_nn46"></a>34.12 Guide to parse tree nodes</H2>
|
|
|
|
|
|
<p>
|
|
This section describes the different parse tree nodes and their attributes.
|
|
</p>
|
|
|
|
<p>
|
|
<b>cdecl</b>
|
|
</p>
|
|
|
|
<p>
|
|
Describes general C declarations including variables, functions, and typedefs.
|
|
A declaration is parsed as "storage T D" where storage is a storage class, T is a base type,
|
|
and D is a declarator.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Declarator name
|
|
"type" - Base type T
|
|
"decl" - Declarator type (abstract)
|
|
"storage" - Storage class (static, extern, typedef, etc.)
|
|
"parms" - Function parameters (if a function)
|
|
"code" - Function body code (if supplied)
|
|
"value" - Default value (if supplied)
|
|
</pre>
|
|
|
|
</div>
|
|
|
|
<p>
|
|
<b>constructor</b>
|
|
</p>
|
|
|
|
<p>
|
|
C++ constructor declaration.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name of constructor
|
|
"parms" - Parameters
|
|
"decl" - Declarator (function with parameters)
|
|
"code" - Function body code (if any)
|
|
"feature:new" - Set to indicate return of new object.
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>destructor</b>
|
|
</p>
|
|
|
|
<p>
|
|
C++ destructor declaration.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name of destructor
|
|
"code" - Function body code (if any)
|
|
"storage" - Storage class (set if virtual)
|
|
"value" - Default value (set if pure virtual).
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>access</b>
|
|
</p>
|
|
|
|
<p>
|
|
C++ access change.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"kind" - public, protected, private
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>constant</b>
|
|
</p>
|
|
|
|
<p>
|
|
Constant created by %constant or #define.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name of constant.
|
|
"type" - Base type.
|
|
"value" - Value.
|
|
"storage" - Set to %constant
|
|
"feature:immutable" - Set to indicate read-only
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>class</b>
|
|
</p>
|
|
|
|
<p>
|
|
C++ class definition or C structure definition.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name of the class.
|
|
"kind" - Class kind ("struct", "union", "class")
|
|
"symtab" - Enclosing symbol table.
|
|
"tdname" - Typedef name. Use for typedef struct { ... } A.
|
|
"abstract" - Set if class has pure virtual methods.
|
|
"baselist" - List of base class names.
|
|
"storage" - Storage class (if any)
|
|
"unnamed" - Set if class is unnamed.
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>enum</b>
|
|
</p>
|
|
|
|
<p>
|
|
Enumeration.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name of the enum (if supplied).
|
|
"storage" - Storage class (if any)
|
|
"tdname" - Typedef name (typedef enum { ... } name).
|
|
"unnamed" - Set if enum is unnamed.
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>enumitem</b>
|
|
</p>
|
|
|
|
<p>
|
|
Enumeration value.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name of the enum value.
|
|
"type" - Type (integer or char)
|
|
"value" - Enum value (if given)
|
|
"feature:immutable" - Set to indicate read-only
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>namespace</b>
|
|
</p>
|
|
|
|
<p>
|
|
C++ namespace.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name of the namespace.
|
|
"symtab" - Symbol table for enclosed scope.
|
|
"unnamed" - Set if unnamed namespace
|
|
"alias" - Alias name. Set for namespace A = B;
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>using</b>
|
|
</p>
|
|
|
|
<p>
|
|
C++ using directive.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name of the object being referred to.
|
|
"uname" - Qualified name actually given to using.
|
|
"node" - Node being referenced.
|
|
"namespace" - Namespace name being reference (using namespace name)
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>classforward</b>
|
|
</p>
|
|
|
|
<p>
|
|
A forward C++ class declaration.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name of the class.
|
|
"kind" - Class kind ("union", "struct", "class")
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>insert</b>
|
|
</p>
|
|
|
|
<p>
|
|
Code insertion directive. For example, %{ ... %} or
|
|
%insert(section).
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"code" - Inserted code
|
|
"section" - Section name ("header", "wrapper", etc.)
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>top</b>
|
|
</p>
|
|
|
|
<p>
|
|
Top of the parse tree.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"module" - Module name
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>extend</b>
|
|
</p>
|
|
|
|
<p>
|
|
%extend directive.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Module name
|
|
"symtab" - Symbol table of enclosed scope.
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>apply</b>
|
|
</p>
|
|
|
|
<p>
|
|
%apply pattern { patternlist }.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"pattern" - Source pattern.
|
|
"symtab" - Symbol table of enclosed scope.
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>clear</b>
|
|
</p>
|
|
|
|
<p>
|
|
%clear patternlist;
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"firstChild" - Patterns to clear
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>include</b>
|
|
</p>
|
|
|
|
<p>
|
|
%include directive.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Filename
|
|
"firstChild" - Children
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>import</b>
|
|
</p>
|
|
|
|
<p>
|
|
%import directive.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Filename
|
|
"firstChild" - Children
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>module</b>
|
|
</p>
|
|
|
|
<p>
|
|
%module directive.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name of the module
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>typemap</b>
|
|
</p>
|
|
|
|
<p>
|
|
%typemap directive.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"method" - Typemap method name.
|
|
"code" - Typemap code.
|
|
"kwargs" - Keyword arguments (if any)
|
|
"firstChild" - Typemap patterns
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>typemapcopy</b>
|
|
</p>
|
|
|
|
<p>
|
|
%typemap directive with copy.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"method" - Typemap method name.
|
|
"pattern" - Typemap source pattern.
|
|
"firstChild" - Typemap patterns
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>typemapitem</b>
|
|
</p>
|
|
|
|
<p>
|
|
%typemap pattern. Used with %apply, %clear, %typemap.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"pattern" - Typemap pattern (a parameter list)
|
|
"parms" - Typemap parameters.
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
<b>types</b>
|
|
</p>
|
|
|
|
<p>
|
|
%types directive.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"parms" - List of parameter types.
|
|
"convcode" - Code which replaces the default casting / conversion code
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<b>extern</b>
|
|
</p>
|
|
|
|
<p>
|
|
extern "X" { ... } declaration.
|
|
</p>
|
|
|
|
<div class="diagram">
|
|
<pre>
|
|
"name" - Name "C", "Fortran", etc.
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|