The great merge
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4141 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
6fcc22a1f8
commit
516036631c
1508 changed files with 125983 additions and 44037 deletions
480
SWIG/Doc/Devel/engineering.html
Normal file
480
SWIG/Doc/Devel/engineering.html
Normal file
|
|
@ -0,0 +1,480 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>SWIG Engineering Manual</title>
|
||||
</head>
|
||||
<body bgcolor="#ffffff">
|
||||
<center>
|
||||
<h1>SWIG Engineering Manual</h1>
|
||||
|
||||
<b>David Beazley <br>
|
||||
Department of Computer Science <br>
|
||||
University of Chicago <br>
|
||||
Chicago, IL 60637 <br>
|
||||
beazley@cs.uchicago.edu <br>
|
||||
</b>
|
||||
</center>
|
||||
|
||||
<p>
|
||||
<b>$Header$</b>
|
||||
|
||||
<p>
|
||||
(Note : This is a work in progress.)
|
||||
|
||||
<h2>Table of Contents</h2>
|
||||
<ul>
|
||||
<li><a name="i1" href="#1">1. Introduction</a>
|
||||
<li><a name="i2" href="#2">2. Programming Languages and Libraries</a>
|
||||
<li><a name="i3" href="#3">3. The Source Directory and Module Names</a>
|
||||
<li><a name="i4" href="#4">4. Include Files</a>
|
||||
<li><a name="i5" href="#5">5. File Structure</a>
|
||||
<li><a name="i6" href="#6">6. Bottom-Up Design</a>
|
||||
<li><a name="i7" href="#7">7. Functions</a>
|
||||
<li><a name="i8" href="#8">8. Naming Conventions</a>
|
||||
<li><a name="i9" href="#9">9. Visibility</a>
|
||||
<li><a name="i10" href="#10">10. Miscellaneous Coding Guidelines</a>
|
||||
<li><a name="i11" href="#11">11. CVS Tagging Conventions</a>
|
||||
</ul>
|
||||
|
||||
<a name="1" href="#i1">
|
||||
<h2>1. Introduction</h2>
|
||||
</a>
|
||||
|
||||
The purpose of this document is to describe various coding conventions
|
||||
and organizational aspects for SWIG developers. The idea for this
|
||||
document is largely borrowed from John Ousterhout's Tcl/Tk Engineering
|
||||
Manual. It is not my intent to overly managerial about matters--rather I'm
|
||||
hoping to make life a little less chaotic for everyone.
|
||||
|
||||
<p>
|
||||
First a little background: SWIG was started in 1995 as a one-person
|
||||
project and continued in this mode of operation until about 1998.
|
||||
Most of this development was driven by ideas submitted by early SWIG
|
||||
users as opposed to being motivated by a grand design. As a result,
|
||||
the code ended up being a pretty horrible C++ coding disaster. A
|
||||
mostly working disaster perhaps, but a disaster nonetheless.
|
||||
|
||||
<p>
|
||||
With that said, the primary goal of future SWIG development is to
|
||||
reengineer the original system, fix most of its inherent design flaws,
|
||||
and to produce what I hope will become a highly extensible and modular
|
||||
interface compiler framework. To this do this, there are a few
|
||||
critical areas of work. First, I want to restructure SWIG as a
|
||||
collection of loosely coupled modules written in either ANSI C or an
|
||||
scripting language. Second, I want the system to be minimalistic in
|
||||
its use of data structures and interconnections. The primary reason
|
||||
for this is that the fewer data structures there are, the less users
|
||||
will have to remember. This will also make the system more accessible
|
||||
to non-experts. Finally, I want to reevaluate the whole idea of a
|
||||
SWIG module is and expand the definition to include just about
|
||||
anything from parsers, preprocessors, optimizers, interface editors,
|
||||
and code generators.
|
||||
|
||||
<p>
|
||||
The rest of this document outlines a few general rules of how code
|
||||
should be developed within the SWIG project. These rules are
|
||||
primarily drawn from my own experience developing software and
|
||||
observing the practices of other successful projects.
|
||||
|
||||
<a name="2" href="#i2">
|
||||
<h2>2. Programming Languages and Libraries </h2>
|
||||
</a>
|
||||
|
||||
All SWIG modules must be written in either ANSI C or one of the
|
||||
scripting languages for which SWIG can generate an interface (e.g.,
|
||||
Perl, Python, or Tcl). C++ is currently being used to write
|
||||
SWIG modules, but it is only being utilized to avoid working with
|
||||
a lot of pointers to functions. <b>Advanced C++ features like namespaces, templates,
|
||||
and overloading should not be used.</b>.
|
||||
|
||||
<p>
|
||||
Module writers should make every attempt to use only those functions
|
||||
described in the POSIX.1 standard. This includes most of the
|
||||
functions contained the Kernighan and Ritchie C programming book. Use
|
||||
of operating system dependent functionality such as socket libraries
|
||||
should always be included inside a conditional compilation block so
|
||||
that it can be omitted on problematic platforms. If you are unsure
|
||||
about a library call, check the man page or contact Dave.
|
||||
|
||||
<a name="3" href="#i3">
|
||||
<h2>3. The Source Directory and Module Names</h2>
|
||||
</a>
|
||||
|
||||
All SWIG modules are contained within the "Source" directory. Within
|
||||
this directory, each module is placed into its own subdirectory. The
|
||||
name of this subdirectory should exactly match the name of the module.
|
||||
For example, if you are creating a module called "Tcl", all of your
|
||||
files should be placed in a directory "Tcl".
|
||||
|
||||
<p>
|
||||
When choosing a module name, please pick a name that is not
|
||||
currently in use. As a general convention, the first letter of a
|
||||
module name is capitalized such as "Perl". Alternatives such as
|
||||
"perl" or "PERL" should be avoided. In certain instances, the first
|
||||
two letters may be capitalized as in "CParse." The exact usage of
|
||||
this is somewhat inconsistent and isn't terribly important--just make
|
||||
sure the first letter is capitalized. Also, module names should not
|
||||
start with numbers, include underscores or any other special
|
||||
non-alphanumeric characters.
|
||||
|
||||
<a name="4" href="#i4">
|
||||
<h2>4. Include Files </h2>
|
||||
</a>
|
||||
|
||||
All modules should include a header file that defines the public interface.
|
||||
The name of this header file should be of the form "swigmodule.h" where
|
||||
"module" is the name of your module. For example, if you created a
|
||||
module "Perl", the header file should be named "swigperl.h". This scheme
|
||||
should prevent header-file naming conflicts both within SWIG and when linking
|
||||
parts of SWIG to the outside world.
|
||||
|
||||
<p>
|
||||
All header files should include a short description, author information, copyright message,
|
||||
CVS version, include guards, and be C++ aware. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
/* -------------------------------------------------------------------------
|
||||
* swigperl.h
|
||||
*
|
||||
* All of the externally visible functions in the Perl module.
|
||||
*
|
||||
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||
*
|
||||
* Copyright (C) 1999-2000, The University of Chicago.
|
||||
* See the file LICENSE for information on usage and redistribution.
|
||||
*
|
||||
* $Header$
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef _SWIGPERL_H
|
||||
#define _SWIGPERL_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Your declarations here */
|
||||
...
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SWIGPERL_H */
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<p>
|
||||
To minimize compilation time, please include as few other header files as possible.
|
||||
|
||||
<a name="5" href="#i5">
|
||||
<h2>5. File Structure </h2>
|
||||
</a>
|
||||
|
||||
Each file in a module should be given a filename that is all lowercase letters
|
||||
such as "parser.c", not "Parser.c" or "PARSER.c". Please note that filenames
|
||||
are case-insensitive on Windows so this convention will prevent you from inadvertantly
|
||||
creating two files that differ in case-only.
|
||||
|
||||
<p>
|
||||
Each file should include a short abstract, author information, copyright information, and
|
||||
a CVS revision tag like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
/* -----------------------------------------------------------------------------
|
||||
* include.c
|
||||
*
|
||||
* This file implements the functions used to locate and include files in
|
||||
* the SWIG library. Functions for maintaining the library search path are
|
||||
* also located here.
|
||||
*
|
||||
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||
*
|
||||
* Copyright (C) 1999-2000, The University of Chicago.
|
||||
* See the file LICENSE for information on usage and redistribution.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static char cvsroot[] = "$Header$";
|
||||
|
||||
#include "swig.h"
|
||||
|
||||
/* Declarations */
|
||||
typedef struct {
|
||||
int x, y;
|
||||
} Foo;
|
||||
|
||||
...
|
||||
|
||||
/* Private Declarations (used only in this file) */
|
||||
static int avariable;
|
||||
|
||||
...
|
||||
|
||||
/* Functions */
|
||||
...
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
The CVS revision tag should be placed into a static string as shown
|
||||
above. This adds the revision information to the SWIG executable and
|
||||
makes it possible to extract version information from a raw binary
|
||||
(sometimes useful in debugging).
|
||||
|
||||
<p>
|
||||
As a general rule, files start to get unmanagable once they exceed
|
||||
about 2000 lines. Files larger than this should be broken up into
|
||||
multiple files. Similarly, you should avoid the temptation to create
|
||||
many small files as this increases compilation time and makes the
|
||||
directory structure too complicated.
|
||||
|
||||
<a name="6" href="#i6">
|
||||
<h2>6. Bottom-Up Design </h2>
|
||||
</a>
|
||||
|
||||
Within each source file, the preferred organization is to use what is
|
||||
known as "bottom-up" design. Under this scheme, lower-level functions
|
||||
appear first and the highest level function appears last. The easy
|
||||
way to remember is that the "main" function of your module should
|
||||
always appear last in the source file. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
/* Simple bottom-up program */
|
||||
#include <stdio.h>
|
||||
|
||||
int foo(int x, int y) {
|
||||
/* Implement foo */
|
||||
...
|
||||
}
|
||||
|
||||
int bar() {
|
||||
...
|
||||
foo(i,j);
|
||||
...
|
||||
}
|
||||
|
||||
...
|
||||
int main(int argc, char **argv) {
|
||||
...
|
||||
bar();
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
This choice of design is somewhat arbitrary however it has a number of
|
||||
benefits particular to C. In particular, a bottom-up design generally
|
||||
eliminates the need to include forward references--resulting in
|
||||
cleaner code and fewer compilation errors.
|
||||
|
||||
<a name="7" href="#i7">
|
||||
<h2>7. Functions</h2>
|
||||
</a>
|
||||
|
||||
All functions should have a function header that gives the function name
|
||||
and a short description like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
/* -------------------------------------------------------------------------
|
||||
* Swig_add_directory()
|
||||
*
|
||||
* Adds a directory to the SWIG search path.
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
Swig_add_directory(DOH *dirname) {
|
||||
...
|
||||
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In the function declaration, the return type and any specifiers
|
||||
(extern or static) should appear on a separate line followed by the
|
||||
function name and arguments as shown above. The left curly brace
|
||||
should appear on the same line as the function name.
|
||||
|
||||
<p>
|
||||
Function declarations should <b>NOT</b> use the pre-ANSI function
|
||||
declaration syntax. The ANSI standard has been around long enough for
|
||||
this to be a non-issue.
|
||||
|
||||
<a name="8" href="#i8">
|
||||
<h2>8. Naming Conventions</h2>
|
||||
</a>
|
||||
|
||||
The following conventions are used to name various objects throughout SWIG.
|
||||
|
||||
<h4>Functions</h4>
|
||||
|
||||
Functions should consist of the module name and the function name separated by an underscore like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
Preprocessor_define()
|
||||
Swig_add_directory()
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In general, the module name should match the name of the module
|
||||
subdirectory and the function name should be in all lowercase with
|
||||
words separated by underscores.
|
||||
|
||||
<h4>Structures and Types</h4>
|
||||
|
||||
If your module defines new structures, the structure name should include the name of the
|
||||
module and the name of the structure appended together like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
typedef struct SwigScanner {
|
||||
...
|
||||
} SwigScanner;
|
||||
|
||||
typedef struct LParseType {
|
||||
...
|
||||
} LParseType;
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
In this case, both the name of the module and the type should be capitalized. Also, whenever
|
||||
possible, you should use the "typedef struct Name { ... } Name" form when defining new
|
||||
data structures.
|
||||
|
||||
<h4>Global Variables</h4>
|
||||
|
||||
Global variables should be avoided if at all possible. However, if you must use a global
|
||||
variable, please prepend the module name and use the same naming scheme as for functions.
|
||||
|
||||
<h4>Constants</h4>
|
||||
|
||||
Constants should be created using #define and should be in all caps like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
#define SWIG_TOKEN_LPAREN 1
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Separate words in a constant should be separated by underscores as with functions.
|
||||
|
||||
<h4>Structure members</h4>
|
||||
|
||||
Structure members should be in all lower-case and follow the same word-separation convention
|
||||
as for function names. However, the module name does not have to be included.
|
||||
For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
typedef struct SwigScanner {
|
||||
DOH *text; /* Current token value */
|
||||
DOH *scanobjs; /* Objects being scanned */
|
||||
DOH *str; /* Current object being scanned */
|
||||
char *idstart; /* Optional identifier start characters */
|
||||
int next_token; /* Next token to be returned */
|
||||
int start_line; /* Starting line of certain declarations */
|
||||
int yylen; /* Length of text pushed into text */
|
||||
DOH *file; /* Current file name */
|
||||
} SwigScanner;
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h4>Static Functions and Variables </h4>
|
||||
|
||||
Static declarations are free to use any naming convention that is appropriate. However, most
|
||||
existing parts of SWIG use lower-case names and follow the same convention as described for functions.
|
||||
|
||||
<a name="9" href="#i9">
|
||||
<h2>9. Visibility</h2>
|
||||
</a>
|
||||
|
||||
Modules should keep the following rules in mind when exposing their internals:
|
||||
|
||||
<ul>
|
||||
<li>Only publicly accessible functions should be included in the module header file.
|
||||
<li>All non-static declarations must be prepended with some form of the module name
|
||||
to avoid potential linker namespace conflicts with other modules.
|
||||
<li>Modules should not expose global variables or use global variables in their
|
||||
public interface.
|
||||
<li>Similarly, modules should discourage the direct manipulation of data contained
|
||||
within data structures in favor of using function calls instead. For example,
|
||||
instead of providing a user with a structure like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
typedef struct Foo {
|
||||
int line;
|
||||
} Foo;
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
It is better to hide the implementation of Foo and provide an
|
||||
function-call interface like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
typedef struct Foo Foo;
|
||||
extern int Foo_getline(Foo *f);
|
||||
extern void Foo_setline(Foo *f, int line);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Although this results in worse performance, there are many practical
|
||||
reasons for doing this. The most important reason is that it allows
|
||||
you to change the internal representation of Foo without breaking all
|
||||
of the other modules or having to recompile the entire universe after
|
||||
making your changes.
|
||||
|
||||
</ul>
|
||||
|
||||
<a name="10" href="#i10">
|
||||
<h2>10. Miscellaneous Coding Guidelines</h2>
|
||||
</a>
|
||||
|
||||
<ul>
|
||||
<li> Do not use the ternary ?: operator. It is unnecessarily error prone,
|
||||
hard for people to read, and hard to maintain code that uses it.
|
||||
[I don't agree w/ this guideline. ?: operator can be abused
|
||||
just like everything else, but it can also be used cleanly. In some styles of
|
||||
programming, it is the best tool for the job. --ttn]
|
||||
</ul>
|
||||
|
||||
<a name="11" href="#i11">
|
||||
<h2>11. CVS Tagging Conventions</h2>
|
||||
</a>
|
||||
|
||||
Use <tt>cvs tag</tt> to declare some set of file revisions as related in some
|
||||
symbolic way. This eases reference, retrieval and manipulation of these files
|
||||
later. At the moment (2001/01/16 14:02:53), the conventions are very simple;
|
||||
let's hope they stay that way!
|
||||
|
||||
<p>
|
||||
There are two types of tags, internal (aka personal) and external.
|
||||
Internal tags are used by SWIG developers primarily, whereas external
|
||||
tags are used when communicating with people w/ anonymous cvs access.
|
||||
<ul>
|
||||
<li> Internal tags should start with the developer name and a hyphen.
|
||||
<li> External tags should start with "v-".
|
||||
</ul>
|
||||
|
||||
That's all there is to it. Some example tags:
|
||||
|
||||
<ul>
|
||||
<li> ttn-pre-xml-patch
|
||||
<li> ttn-post-xml-patch
|
||||
<li> ttn-going-on-vacation-so-dutifully-tagging-now
|
||||
<li> v-1-3-a37-fixes-bug-2432
|
||||
<li> v-1-3-a37-fixes-bug-2433
|
||||
<li> v-1-3-a37-fixes-bug-2432-again
|
||||
<li> v-1-3-a37-release
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
Copyright (C) 1999-2001
|
||||
<a href="mailto:swig-dev@cs.uchicago.edu">SWIG Development Team</a>
|
||||
</body>
|
||||
</html>
|
||||
20
SWIG/Doc/Devel/index.html
Normal file
20
SWIG/Doc/Devel/index.html
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>SWIG Documentation</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
This directory contains SWIG documentation:
|
||||
|
||||
<ul>
|
||||
<li><a href="engineering.html">Engineering Manual</a>
|
||||
<li><a href="internals.html">Internals Manual</a>
|
||||
<li><a href="migrate.txt">SWIG1.3 Migration Guide</a>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
Copyright (C) 1999-2001
|
||||
<a href="mailto:swig-dev@cs.uchicago.edu">SWIG Development Team</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
959
SWIG/Doc/Devel/internals.html
Normal file
959
SWIG/Doc/Devel/internals.html
Normal file
|
|
@ -0,0 +1,959 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>SWIG Internals</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<center>
|
||||
<h1>SWIG Internals Manual</h1>
|
||||
|
||||
<b>Thien-Thi Nguyen <br>
|
||||
ttn@glug.org <br>
|
||||
|
||||
<p>
|
||||
David M. Beazley <br>
|
||||
beazley@cs.uchicago.edu </br>
|
||||
|
||||
</b>
|
||||
</center>
|
||||
|
||||
<p>
|
||||
<b>$Header$</b>
|
||||
|
||||
<p>
|
||||
(Note : This is a work in progress.)
|
||||
|
||||
<h2>Table of Contents</h2>
|
||||
<ul>
|
||||
<li><a name="i1" href="#1">1. Introduction</a>
|
||||
<ul>
|
||||
<li><a name="i1.1" href="#1.1">1.1 Directory Guide</a>
|
||||
<li><a name="i1.2" href="#1.2">1.2 Overall Program Flow</a>
|
||||
</ul>
|
||||
<li><a name="i2" href="#2">2. DOH</a>
|
||||
<ul>
|
||||
<li><a name="i2.1" href="#2.1">2.1 Motivation and Background</a>
|
||||
<li><a name="i2.2" href="#2.2">2.2 Basic Types</a>
|
||||
<li><a name="i2.3" href="#2.3">2.3 Creating, Copying and Destroying Objects</a>
|
||||
<li><a name="i2.4" href="#2.4">2.4 A Word About Mutability and Copying</a>
|
||||
<li><a name="i2.5" href="#2.5">2.5 Strings</a>
|
||||
<li><a name="i2.6" href="#2.6">2.6 Lists</a>
|
||||
<li><a name="i2.7" href="#2.7">2.7 Hash Tables</a>
|
||||
<li><a name="i2.8" href="#2.8">2.8 Files</a>
|
||||
<li><a name="i2.9" href="#2.9">2.9 Void Objects</a>
|
||||
<li><a name="i2.10" href="#2.10">2.10 Utility Functions</a>
|
||||
</ul>
|
||||
<li><a name="i3" href="#3">3. Types and Typemaps</a>
|
||||
<li><a name="i4" href="#4">4. Parsing</a>
|
||||
<li><a name="i5" href="#5">5. Difference Between SWIG 1.1 and SWIG 1.3</a>
|
||||
<li><a name="i6" href="#6">6. Plans for SWIG 2.0</a>
|
||||
<li><a name="i7" href="#7">7. C/C++ Wrapper Support Functions</a>
|
||||
<li><a name="i8" href="#8">8. Reserved</a>
|
||||
<li><a name="i9" href="#9">9. Reserved</a>
|
||||
<li><a name="i10" href="#10">10. Guile Support</a>
|
||||
<li><a name="i11" href="#11">11. Python Support</a>
|
||||
<li><a name="i12" href="#12">12. Perl Support</a>
|
||||
<li><a name="i13" href="#13">13. Java Support</a>
|
||||
</ul>
|
||||
|
||||
<a name="1" href="#i1">
|
||||
<h2>1. Introduction</h2>
|
||||
</a>
|
||||
|
||||
This document details SWIG internals: architecture and sometimes
|
||||
implementation. The first few sections concentrate on data structures,
|
||||
interfaces, conventions and code shared by all language targets.
|
||||
Subsequent sections focus on a particular language.
|
||||
|
||||
<p>
|
||||
The audience is assumed to be SWIG developers (who should also read the
|
||||
<a href="engineering.html">SWIG Engineering Manual</a> before starting
|
||||
to code).
|
||||
|
||||
<a name="1.1" href="#i1.1">
|
||||
<h3>1.1 Directory Guide</h3>
|
||||
</a>
|
||||
|
||||
<table border=1>
|
||||
<tr><td><a href="index.html">Doc</a></td>
|
||||
<td>HTML documentation. If you find a documentation bug, please
|
||||
<a href="mailto:bug-swig-doc@glug.org">let us know</a>.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Examples</td>
|
||||
<td>This subdir tree contains examples of using SWIG w/ different
|
||||
scripting languages, including makefiles. Typically, there are the
|
||||
"simple" and "matrix" examples, w/ some languages offering additional
|
||||
examples. The GIFPlot example has its own set of per-language
|
||||
subdirectories. See the README more index.html file in each directory
|
||||
for more info. [FIXME: Ref SWIG user manual.]</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Lib</td>
|
||||
<td>These are the <tt>.i</tt> (interface) files that form the SWIG
|
||||
installed library. Language-specific files are in subdirectories (for
|
||||
example, guile/typemaps.i). Each language also has a <tt>.swg</tt> file
|
||||
implementing runtime type support for that language. The SWIG library
|
||||
is not versioned.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Misc</td>
|
||||
<td>Currently this subdir only contains file <tt>fileheader</tt>. See
|
||||
the <a href="engineering.html">Engineering Manual</a> for more
|
||||
info.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Runtime</td>
|
||||
<td>This subdir contains scripts and a makefile for creating runtime
|
||||
shared-object libraries used by various languages. Runtime/make.sh
|
||||
says: "The runtime libraries are only needed if you are building
|
||||
multiple extension modules that need to share information."</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Source</td>
|
||||
<td>SWIG source code is in this subdir tree. Directories marked w/ "(*)"
|
||||
are used in building the <tt>swig</tt> executable.
|
||||
|
||||
<table border=1>
|
||||
|
||||
<tr><td>DOH (*)</td>
|
||||
<td>C library providing memory allocation, file access and generic
|
||||
containers. Result: libdoh.a</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Experiment</td>
|
||||
<td>[TODO]</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Include (*)</td>
|
||||
<td>Configuration .h files</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>LParse</td>
|
||||
<td>Parser (lex / yacc) files and support [why not (*)?!]</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Modules</td>
|
||||
<td>[TODO]</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Modules1.1 (*)</td>
|
||||
<td>Language-specific callbacks that does actual code generation (each
|
||||
language has a .cxx and a .h file). Result: libmodules11.a</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Preprocessor (*)</td>
|
||||
<td>SWIG-specialized C/C++ preprocessor. Result: libcpp.a</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>SWIG1.1 (*)</td>
|
||||
<td>Parts of SWIG that are not language-specific, including option
|
||||
processing and the type-mapping system. Result: libswig11.a.
|
||||
Note: This directory is currently being phased out. </td>
|
||||
</tr>
|
||||
|
||||
<tr><td>SWIG1.3</td>
|
||||
<td>[TODO] [funny, nothing here is presently used for swig-1.3].
|
||||
This directory might turn into a compatibility interface between
|
||||
SWIG1.3 and the SWIG1.1 modules.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Swig (*)</td>
|
||||
<td>This directory contains the new ANSI C core of the system
|
||||
and contains generic functions related to types, file handling,
|
||||
scanning, and so forth.</td>
|
||||
</tr>
|
||||
|
||||
</table></td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Tools</td>
|
||||
<td>Libtool support and the mkdist.py script.</td>
|
||||
</tr>
|
||||
|
||||
<tr><td>Win</td>
|
||||
<td>This improperly-named (spit spit) subdir only has README.txt.</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<a name="1.2" href="#1.2">
|
||||
<h3>1.2 Overall Program Flow</h3>
|
||||
</a>
|
||||
|
||||
Here is the general control flow and where under subdir <tt>Source</tt>
|
||||
to look for code:
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <tt>Modules1.1/swigmain.cxx:main()</tt> is the program entry
|
||||
point. It parses the language-specifying command-line option (for
|
||||
example, <tt>-java</tt>), creating a new language-specific wrapping
|
||||
object (each language is a C++ class derived from base class
|
||||
<tt>Language</tt>). This object and the command-line is passed to
|
||||
<tt>SWIG_main()</tt>, whose return value is the program exit value.
|
||||
|
||||
<li> <tt>SWIG1.1/main.cxx:SWIG_main()</tt> is the "real" main. It
|
||||
initializes the preprocessor and typemap machinery, defines some
|
||||
preprocessor symbols, locates the SWIG library, processes common
|
||||
command-line options, and then calls the language-specific command-line
|
||||
parser. From here there are three paths: "help", "checkout" and
|
||||
everything else.
|
||||
<ul>
|
||||
<li> In "help" mode, clean up open files and exit.
|
||||
<li> In "checkout" mode, copy specified files from the SWIG library
|
||||
to the current directory. Errors cause error messages but no
|
||||
non-lcoal exits.
|
||||
<li> Otherwise, do wrapping: determine output file name(s), define
|
||||
some preprocessor symbols and run the preprocessor, initialize
|
||||
the interface-definition parser, set up the typemap for handling
|
||||
new return strings, and finally do the language-specific parse
|
||||
(by calling the language object's <tt>parse()</tt> method), which
|
||||
creates output files by side-effect.
|
||||
</ul>
|
||||
Afterwards, remove temporary files, and clean up. If the command-line
|
||||
included <tt>-freeze</tt>, go into an infinite loop; otherwise return the
|
||||
error count.
|
||||
|
||||
<li> The language-specific <tt>parse()</tt> (and all other
|
||||
language-specific code) lives in <tt>Modules1.1/foo.{h,cxx}</tt> for
|
||||
language Foo. Typically, <tt>FOO::parse()</tt> calls
|
||||
<tt>FOO::headers()</tt> and then the global function <tt>yyparse()</tt>,
|
||||
which uses the callbacks registered by <tt>SWIG_main()</tt> above.
|
||||
|
||||
</ul>
|
||||
|
||||
<a name="2" href="#i2">
|
||||
<h2>2. DOH</h2>
|
||||
</a>
|
||||
|
||||
DOH is a collection of low-level objects such as strings, lists, and
|
||||
hash tables upon which the rest of SWIG is built. The name 'DOH'
|
||||
unofficially stands for "Dave's Object Hack", but it's also a good
|
||||
expletive to use when things don't work (as in "SWIG core
|
||||
dumped---DOH!").
|
||||
|
||||
<a name="2.1" href="#2.1">
|
||||
<h3>2.1 Motivation and Background</h3>
|
||||
</a>
|
||||
|
||||
The development of DOH is influenced heavily by the problems
|
||||
encountered during earlier attempts to create a C++ based version of
|
||||
SWIG2.0. In each of these attempts (over a 3 year period), the
|
||||
resulting system always ended up growing into a collossal nightmare of
|
||||
large inheritance hierarchies and dozens of specialized classes for
|
||||
different types of objects (functions, variables, constants, etc.).
|
||||
The end result was that the system was tremendously complicated,
|
||||
difficult to understand, difficult to maintain, and fairly inflexible
|
||||
in the grand scheme of things.
|
||||
|
||||
<p>
|
||||
DOH takes a different approach to tackling the complexity problem.
|
||||
First, rather than going overboard with dozens of types and class
|
||||
definitions, DOH only defines a handful of simple yet very useful
|
||||
objects that are easy to remember. Second, DOH uses dynamic
|
||||
typing---one of the features that make scripting languages so useful
|
||||
and which make it possible to accomplish things with much less code.
|
||||
Finally, DOH utilizes a few coding tricks that allow it to perform
|
||||
a limited form of function overloading for certain C datatypes (more
|
||||
on that a little later).
|
||||
|
||||
<p>
|
||||
The key point to using DOH is that instead of thinking about code in
|
||||
terms of highly specialized C data structures, just about everything
|
||||
ends up being represented in terms of a just a few datatypes. For
|
||||
example, structures are replaced by DOH hash tables whereas arrays are
|
||||
replaced by DOH lists. At first, this is probably a little strange to
|
||||
most C/C++ programmers, but in the long run in makes the system
|
||||
extremely flexible and highly extensible. Also, in terms of coding,
|
||||
many of the newly DOH-based subsystems are less than half the size (in
|
||||
lines of code) of the earlier C++ implementation.
|
||||
|
||||
<a name="2.2" href="#i2.2">
|
||||
<h3>2.2 Basic Types</h3>
|
||||
</a>
|
||||
|
||||
The following built-in types are currently provided by DOH:
|
||||
|
||||
<ul>
|
||||
<li><b>String</b>. A string of characters with automatic memory
|
||||
management and high-level operations such as string replacement. In addition,
|
||||
strings support file I/O operations that make it possible to use them just
|
||||
about anyplace a file can be used.
|
||||
|
||||
<p>
|
||||
<li><b>List</b>. A list of arbitrary DOH objects (of possibly mixed types).
|
||||
|
||||
<p>
|
||||
<li><b>Hash</b>. A hash table that maps a set of string keys to a set of arbitrary
|
||||
DOH objects. The DOH version of an associative array for all of you Perl fans.
|
||||
|
||||
<p>
|
||||
<li><b>File</b>. A DOH wrapper around the C FILE * structure. This is provided
|
||||
since other objects sometimes want to behave like files (strings for instance).
|
||||
|
||||
<p>
|
||||
<li><b>Void</b>. A DOH wrapper around an arbitrary C pointer. This can be used
|
||||
if you want to place arbitrary C data structures in DOH lists and hash tables.
|
||||
</ul>
|
||||
|
||||
Due to dynamic typing, all of the objects in DOH are represented by pointers
|
||||
of type <tt>DOH *</tt>. Furthermore, all objects are completely
|
||||
opaque--that means that the only way to access the internals of an
|
||||
object is through a well-defined public API. For convenience, the following
|
||||
symbolic names are sometimes used to improve readability:
|
||||
|
||||
<ul>
|
||||
<Li><tt>DOHString *</tt>. A String object.
|
||||
<li><tt>DOHList *</tt>. A list object.
|
||||
<li><tt>DOHHash *</tt>. A hash object.
|
||||
<li><tt>DOHFile *</tt>. A file object.
|
||||
<li><tt>DOHVoid *</tt>. A void object.
|
||||
<li><tt>DOHString_or_char *</tt>. A DOH String object or a raw C "char *".
|
||||
</ul>
|
||||
|
||||
It should be stressed that all of these names are merely symbolic aliases to the
|
||||
type <tt>DOH *</tt> and that no compile-time type checking is performed (of course,
|
||||
a runtime error may occur if you screw up).
|
||||
|
||||
<a name="2.3" href="#i2.3">
|
||||
<h3>2.3 Creating, Copying, and Destroying Objects </h2>
|
||||
</a>
|
||||
|
||||
The following functions can be used to create new DOH objects
|
||||
|
||||
<ul>
|
||||
<Li><tt>NewString(DOHString_or_char *value)</tt><br>
|
||||
Create a new string object with contents initially
|
||||
set to value. value can be either a C string or a DOH string object.
|
||||
|
||||
<p>
|
||||
<li><tt>NewStringf(char *fmt, ...)</tt><br>
|
||||
Create a new string object with contents initially set to
|
||||
a formatted string. Think of this as being sprintf() combined with an object constructor.
|
||||
|
||||
<p>
|
||||
<li><tt>NewList()</tt><br>
|
||||
Create a new list object that is initially empty.
|
||||
|
||||
<p>
|
||||
<Li><tt>NewHash()</tt><br>
|
||||
Create a new hash object that is initially empty.
|
||||
|
||||
<p>
|
||||
<li><tt>NewFile(DOHString_or_char *filename, char *mode)</tt><br>
|
||||
Open a file and return a file object. This is a
|
||||
wrapper around the C <tt>fopen()</tt> library call.
|
||||
|
||||
<p>
|
||||
<li><tt>NewFileFromFile(FILE *f)</tt><br>
|
||||
Create a new file object given an already opened <tt>FILE *</tt> object.
|
||||
|
||||
<p>
|
||||
<li><tt>NewVoid(void *obj, void (*del)(void *))</tt><br>
|
||||
Create a new DOH object that is a wrapper around an
|
||||
arbitrary C pointer. <tt>del</tt> is an optional destructor function that will be called when the object
|
||||
is destroyed.
|
||||
|
||||
</ul>
|
||||
|
||||
Any object can be copied using the <tt>Copy()</tt> function. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
DOH *a, *b, *c, *d;
|
||||
a = NewString("Hello World");
|
||||
b = NewList();
|
||||
c = Copy(a); /* Copy the string a */
|
||||
d = Copy(b); /* Copy the list b */
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Copies of lists and hash tables are shallow. That is, their contents are only copied by reference.
|
||||
|
||||
<p>
|
||||
Objects can be deleted using the <tt>Delete()</tt> function. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
DOH *a = NewString("Hello World");
|
||||
...
|
||||
Delete(a); /* Destroy a */
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
All objects are referenced counted and given a reference count of 1 when initially created. The
|
||||
<tt>Delete()</tt> function only destroys an object when the reference count reaches zero. When
|
||||
an object is placed in a list or hash table, it's reference count is automatically increased. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
DOH *a, *b;
|
||||
a = NewString("Hello World");
|
||||
b = NewList();
|
||||
Append(b,a); /* Increases refcnt of a to 2 */
|
||||
Delete(a); /* Decreases refcnt of a to 1 */
|
||||
Delete(b); /* Destroys b, and destroys a */
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Should it ever be necessary to manually increase the reference count of an object, the DohIncref() function
|
||||
can be used:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
DOH *a = NewString("Hello");
|
||||
DohIncref(a);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<a name="2.4" href="#i2.4">
|
||||
<h3>2.4 A Word About Mutability and Copying</h3>
|
||||
</a>
|
||||
|
||||
All DOH objects are mutable regardless of their current reference
|
||||
count. For example, if you create a string and then create a 1000
|
||||
references to it (in lists and hash tables), changes to the string
|
||||
will be reflected in all of the references. Therefore, if you need to
|
||||
make any kind of local change, you should first make a copy using the
|
||||
Copy() function. Caveat: when copying lists and hash tables, elements
|
||||
are copied by reference.
|
||||
|
||||
<a name="2.5" href="#i2.5">
|
||||
<h3>2.5 Strings</h3>
|
||||
</a>
|
||||
|
||||
The DOH String type is perhaps the most flexible object. First, it supports a variety of string-oriented
|
||||
operations. Second, it supports many of the same operations as lists. Finally, strings provide file I/O
|
||||
operations that allow them to be used interchangably with DOH file objects.
|
||||
|
||||
[ TODO ]
|
||||
|
||||
<a name="2.6" href="#i2.6">
|
||||
<h3>2.6 Lists</h3>
|
||||
</a>
|
||||
|
||||
[ TODO ]
|
||||
|
||||
<a name="2.7" href="#i2.7">
|
||||
<h3>2.7 Hash tables </h3>
|
||||
</a>
|
||||
|
||||
[ TODO ]
|
||||
|
||||
<a name="2.8" href="#i2.8">
|
||||
<h3>2.8 Files </h3>
|
||||
</a>
|
||||
|
||||
[ TODO ]
|
||||
|
||||
<a name="2.9" href="#i2.9">
|
||||
<h3>2.9 Void objects </h3>
|
||||
</a>
|
||||
|
||||
[ TODO ]
|
||||
|
||||
<a name="2.10" href="#i2.10">
|
||||
<h3>2.10 Utility functions </h3>
|
||||
</a>
|
||||
|
||||
[ TODO ]
|
||||
|
||||
<a name="3" href="#i3">
|
||||
<h2>3. Types and Typemaps</h2>
|
||||
</a>
|
||||
|
||||
Revised: Dave Beazley (8/14/00)
|
||||
|
||||
<p>
|
||||
The representation and manipulation of types is currently in the
|
||||
process of being reorganized and (hopefully) simplified. The
|
||||
following list describes the current set of functions that are used to
|
||||
manipulate datatypes. These functions are different than in
|
||||
SWIG1.1 and may change names in the final SWIG1.3 release.
|
||||
|
||||
<ul>
|
||||
<li><tt>SwigType_str(SwigType *t, char *name)</tt>.<br>
|
||||
This function produces the exact string
|
||||
representation of the datatype <tt>t</tt>. <tt>name</tt> is an optional parameter that
|
||||
specifies a declaration name. This is used when dealing with more complicated datatypes
|
||||
such as arrays and pointers to functions where the output might look something like
|
||||
"<tt>int (*name)(int, double)</tt>".
|
||||
|
||||
<p>
|
||||
<li><tt>SwigType_lstr(SwigType *t, char *name)</tt>.<br>
|
||||
This function produces a string
|
||||
representation of a datatype that can be safely be assigned a value (i.e., can be used as the
|
||||
"lvalue" of an expression). To do this, qualifiers such as "const", arrays, and references
|
||||
are stripped away or converted into pointers. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
Original Datatype lstr()
|
||||
------------------ --------
|
||||
const char *a char *a
|
||||
double a[20] double *a
|
||||
double a[20][30] double *a
|
||||
double &a double *a
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
The intent of the lstr() function is to produce local variables inside wrapper functions--all
|
||||
of which must be reassignable types since they are the targets of conversions from a scripting
|
||||
representation.
|
||||
|
||||
<p>
|
||||
<li><tt>SwigType_rcaststr(SwigType *t, char *name)</tt>.
|
||||
<br> This function produces a string
|
||||
that casts a type produced by the <tt>lstr()</tt> function to the type produced by the
|
||||
<tt>str()</tt> function. You might view it as the inverse of lstr(). This function only produces
|
||||
output when it needs to (when str() and lstr() produce different results). Furthermore, an optional
|
||||
name can be supplied when the cast is to be applied to a specific name. Examples:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
Original Datatype rcaststr()
|
||||
------------------ ---------
|
||||
char *a
|
||||
const char *a (const char *) name
|
||||
double a[20] (double *) name
|
||||
double a[20][30] (double (*)[30]) name
|
||||
double &a (double &) *name
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<p>
|
||||
<li><tt>SwigType_lcaststr(SwigType *t, char *name)</tt>.
|
||||
<br> This function produces a string
|
||||
that casts a type produced by the <tt>str()</tt> function to the type produced by the
|
||||
<tt>lstr()</tt> function. This function only produces
|
||||
output when it needs to (when str() and lstr() produce different results). Furthermore, an optional
|
||||
name can be supplied when the cast is to be applied to a specific name.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
Original Datatype lcaststr()
|
||||
------------------ ---------
|
||||
char *a
|
||||
const char *a (char *) name
|
||||
double a[20] (double *) name
|
||||
double a[20][30] (double *) name
|
||||
double &a (double *) &name
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
<li><tt>SwigType_manglestr(SwigType *t)</tt>. <br>
|
||||
Produces a type-string that is used to identify this datatype in the target scripting language.
|
||||
Usually this string looks something like "<tt>_p_p_double</tt>" although the target language
|
||||
may redefine the output for its own purposes. Normally this function strips all qualifiers,
|
||||
references, and arrays---producing a mangled version of the type produced by the <tt>lstr()</tt> function.
|
||||
</ul>
|
||||
|
||||
The following example illustrates the intended use of the above functions when creating wrapper
|
||||
functions using shorthand pseudocode. Suppose you had a function like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
int foo(int a, double b[20][30], const char *c, double &d);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Here's how a wrapper function would be generated using the type generation functions above:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
wrapper_foo() {
|
||||
lstr("int","result")
|
||||
lstr("int","arg0")
|
||||
lstr("double [20][30]", "arg1")
|
||||
lstr("const char *", "arg2")
|
||||
lstr("double &", "arg3")
|
||||
...
|
||||
get arguments
|
||||
...
|
||||
result = (lcaststr("int")) foo(rcaststr("int","arg0"),
|
||||
rcaststr("double [20][30]","arg1"),
|
||||
rcaststr("const char *", "arg2"),
|
||||
rcaststr("double &", "arg3"))
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Here's how it would look with the corresponding output filled in:
|
||||
<blockquote>
|
||||
<pre>
|
||||
wrapper_foo() {
|
||||
int result;
|
||||
int arg0;
|
||||
double *arg1;
|
||||
char *arg2;
|
||||
double *arg3;
|
||||
...
|
||||
get arguments
|
||||
...
|
||||
result = (int) foo(arg0,
|
||||
(double (*)[30]) arg1,
|
||||
(const char *) arg2,
|
||||
(double &) *arg3);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<b>Notes:</b>
|
||||
|
||||
<ul>
|
||||
<li>For convenience, the string generation functions return a
|
||||
"<tt>char *</tt>" that points to statically allocated memory living
|
||||
inside the type library. Therefore, it is never necessary (and it's
|
||||
an error) to free the pointer returned by the functions. Also, if you
|
||||
need to save the result, you should make a copy of it. However, with
|
||||
that said, it is probably worth nothing that these functions do cache
|
||||
the last 8 results. Therefore, it's fairly safe to make a handful of
|
||||
repeated calls without making any copies.
|
||||
</ul>
|
||||
|
||||
[TODO]
|
||||
|
||||
<a name="4" href="#i4">
|
||||
<h2>4. Parsing</h2>
|
||||
</a>
|
||||
|
||||
[TODO]
|
||||
|
||||
<a name="5" href="#i5">
|
||||
<h2>5. Difference Between SWIG 1.1 and SWIG 1.3</h2>
|
||||
</a>
|
||||
|
||||
[TODO]
|
||||
|
||||
<a name="6" href="#i6">
|
||||
<h2>6. Plans for SWIG 2.0</h2>
|
||||
</a>
|
||||
|
||||
[TODO]
|
||||
|
||||
<a name="7" href="#i7">
|
||||
<h2>7. The C/C++ Wrapping Layer</h2>
|
||||
</a>
|
||||
|
||||
Added: Dave Beazley (July 22, 2000)
|
||||
|
||||
<p>
|
||||
When SWIG generates wrappers, it tries to provide a mostly seamless integration
|
||||
with the original code. However, there are a number of problematic features
|
||||
of C/C++ programs that complicate this interface.
|
||||
|
||||
<ul>
|
||||
<li><b>Passing and returning structures by value.</b> When used, SWIG converts
|
||||
all pass-by-value functions into wrappers that pass by reference. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
double dot_product(Vector a, Vector b);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
gets turned into a wrapper like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
double wrap_dot_product(Vector *a, Vector *b) {
|
||||
return dot_product(*a,*b);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Functions that return by value require a memory allocation to store the result. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
Vector cross_product(Vector *a, Vector *b);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
become
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
Vector *wrap_cross_product(Vector *a, Vector *b) {
|
||||
Vector *result = (Vector *) malloc(sizeof(Vector));
|
||||
*result = cross_product(a,b);
|
||||
return result;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Note: If C++ is being wrapped, the default copy constructor is used
|
||||
instead of malloc() to create a copy of the return result.
|
||||
|
||||
<p>
|
||||
<li><b>C++ references</b>. C++ references are handled exactly the same as
|
||||
pass/return by value except that a memory allocation is not made for functions
|
||||
that return a reference.
|
||||
|
||||
<p>
|
||||
<li><b>Qualifiers such as "const" and "volatile".</b> SWIG strips all
|
||||
qualifiers from the interface presented to the target language.
|
||||
Besides, what in the heck is "const" in Perl anyways?
|
||||
|
||||
<p>
|
||||
<li><b>Instance Methods</b>. Method invocations are handled as a function call in which
|
||||
a pointer to the object (the "this" pointer) appears as the first argument. For example, in
|
||||
the following class:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
double bar(double);
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
The "bar" method is wrapped by a function like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
double Foo_bar(Foo *self, double arg0) {
|
||||
return self->bar(arg0);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
<li><b>Structure/class data members</b>. Data members are handled by creating a pair
|
||||
of wrapper functions that set and get the value respectively. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
struct Foo {
|
||||
int x;
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
gets wrapped as follows:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
int Foo_x_get(Foo *self) {
|
||||
return self->x;
|
||||
}
|
||||
int Foo_x_set(Foo *self, int value) {
|
||||
return (self->x = value);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
<li><b>Constructors</b>. Constructors for C/C++ data structures are wrapped by
|
||||
a function like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
Foo *new_Foo() {
|
||||
return new Foo;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
Note: For C, new objects are created using the calloc() function.
|
||||
|
||||
<p>
|
||||
<li><b>Destructors</b>. Destructors for C/C++ data structures are wrapper like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
void delete_Foo(Foo *self) {
|
||||
delete self;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
Note: For C, objects are destroyed using free().
|
||||
|
||||
</ul>
|
||||
|
||||
The creation of wrappers and various type transformations are handled by a collection of functions
|
||||
found in the file <tt>Source/Swig/cwrap.c</tt>.
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<tt>char *Swig_clocal(DataType *t, char *name, char *value)</tt><br>
|
||||
This function creates a string containing the declaration of a local variable with
|
||||
type <tt>t</tt>, name <tt>name</tt>, and default value <tt>value</tt>. This local
|
||||
variable is stripped of all qualifiers and will be a pointer if the type is a reference
|
||||
or user defined type.
|
||||
|
||||
<p>
|
||||
<li>
|
||||
<tt>DataType *Swig_clocal_type(DataType *t)</tt><br>
|
||||
Returns a type object corresponding to the type string produced by the Swig_clocal() function.
|
||||
|
||||
<p>
|
||||
<li><tt>char *Swig_clocal_deref(DataType *t, char *name)</tt><br>
|
||||
This function is the inverse of the <tt>clocal()</tt> function. Given a type and a name,
|
||||
it produces a string containing the code needed to cast/convert the type produced by
|
||||
<tt>Swig_clocal()</tt> back into it's original type.
|
||||
|
||||
<p>
|
||||
<li><tt>char *Swig_clocal_assign(DataType *t, char *name)</tt><br>
|
||||
Given a type and name, this produces a string containing the code (and an optional cast)
|
||||
needed to make an assignment from the real datatype to the local datatype produced
|
||||
by <tt>Swig_clocal()</tt>. Kind of the opposite of deref().
|
||||
|
||||
<p>
|
||||
<li><tt>int Swig_cargs(Wrapper *w, ParmList *l)</tt><br>
|
||||
Given a wrapper function object and a list of parameters, this function declares a set
|
||||
of local variables for holding all of the parameter values (using Swig_clocal()). Returns
|
||||
the number of parameters. In addition, this function sets the local name of each parameter
|
||||
which can be retrieved using the <tt>Parm_Getlname()</tt> function.
|
||||
|
||||
<p>
|
||||
<li><tt>void Swig_cresult(Wrapper *w, DataType *t, char *resultname, char *decl)</tt><br>
|
||||
Generates the code needed to set the result of a wrapper function and performs all of
|
||||
the needed memory allocations for ANSI C (if necessary). <tt>t</tt> is the type of the
|
||||
result, <tt>resultname</tt> is the name of the result variable, and <tt>decl</tt> is
|
||||
a string that contains the C code which produces the result.
|
||||
|
||||
<p>
|
||||
<li><tt>void Swig_cppresult(Wrapper *w, DataType *t, char *resultname, char *decl)</tt><br>
|
||||
Generates the code needed to set the result of a wrapper function and performs all of
|
||||
the needed memory allocations for C++ (if necessary). <tt>t</tt> is the type of the
|
||||
result, <tt>resultname</tt> is the name of the result variable, and <tt>decl</tt> is
|
||||
a string that contains the C code which produces the result.
|
||||
|
||||
<p>
|
||||
<li><tt>Wrapper *Swig_cfunction_wrapper(char *fname, DataType *rtype, ParmList *parms, char *code)</tt><br>
|
||||
Create a wrapper around a normal function declaration. <tt>fname</tt> is the name of the wrapper,
|
||||
<tt>rtype</tt> is the return type, <tt>parms</tt> are the function parameters, and <tt>code</tt> is a
|
||||
string containing the code in the function body.
|
||||
|
||||
<p>
|
||||
<li><tt>Wrapper *Swig_cmethod_wrapper(char *classname, char *methodname, DataType *rtype, DataType *parms, char *code)</tt><br>
|
||||
|
||||
<p>
|
||||
<li><tt>char *Swig_cfunction_call(char *name, ParmList *parms)</tt>
|
||||
This function produces a string containing the code needed to call a C function.
|
||||
The string that is produced contains all of the transformations needed to convert
|
||||
pass-by-value into pass-by-reference as well as handle C++ references. Produces
|
||||
a string like "name(arg0, arg1, ..., argn)".
|
||||
|
||||
</ul>
|
||||
|
||||
Here is a short example showing how these functions could be used. Suppose you had a
|
||||
C function like this:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
double dot_product(Vector a, Vector b);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Here's how you might write a really simple wrapper function
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
ParmList *l = ... parameter list of the function ...
|
||||
DataType *t = ... return type of the function ...
|
||||
char *name = ... name of the function ...
|
||||
Wrapper *w = NewWrapper();
|
||||
Printf(w->def,"void wrap_%s() {\n", name);
|
||||
|
||||
/* Declare all of the local variables */
|
||||
Swig_cargs(w, l);
|
||||
|
||||
/* Convert all of the arguments */
|
||||
...
|
||||
|
||||
/* Make the function call and declare the result variable */
|
||||
Swig_cresult(w,t,"result",Swig_cfunction(name,l));
|
||||
|
||||
/* Convert the result into whatever */
|
||||
...
|
||||
|
||||
Printf(w->code,"}\n");
|
||||
Wrapper_print(w,out);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
The output of this would appear as follows:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
void wrap_dot_product() {
|
||||
Vector *arg0;
|
||||
Vector *arg1;
|
||||
double result;
|
||||
|
||||
...
|
||||
result = dot_product(*arg0, *arg1);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
Notice that the <tt>Swig_cargs()</tt>, <tt>Swig_cresult()</tt>, and <tt>Swig_cfunction()</tt> functions
|
||||
have taken care of the type conversions for the <tt>Vector</tt> type automatically.
|
||||
|
||||
<p>
|
||||
<b>Notes:</b>
|
||||
<ul>
|
||||
<Li>The intent of these functions is to provide <em>consistent</em> handling of function parameters
|
||||
and return values so that language module writers don't have to worry about it too much.
|
||||
|
||||
<p>
|
||||
<li>These functions may be superceded by features in the new typemap system which provide hooks
|
||||
for specifying local variable declarations and argument conversions.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="8" href="#i8">
|
||||
<h2>8. Reserved</h2>
|
||||
</a>
|
||||
|
||||
<a name="9" href="#i9">
|
||||
<h2>9. Reserved</h2>
|
||||
</a>
|
||||
|
||||
<a name="10" href="#i10">
|
||||
<h2>10. Guile Support</h2>
|
||||
</a>
|
||||
|
||||
The information that used to live here has moved to the user
|
||||
documentation, file <code>Guile.html</code>.
|
||||
|
||||
<a name="11" href="#i11">
|
||||
<h2>11. Python Support</h2>
|
||||
</a>
|
||||
|
||||
[TODO]
|
||||
|
||||
<a name="12" href="#i12">
|
||||
<h2>12. Perl Support</h2>
|
||||
</a>
|
||||
|
||||
[TODO]
|
||||
|
||||
<a name="13" href="#i13">
|
||||
<h2>13. Java Support</h2>
|
||||
</a>
|
||||
|
||||
[TODO]
|
||||
|
||||
<hr>
|
||||
Copyright (C) 1999-2001
|
||||
<a href="mailto:swig-dev@cs.uchicago.edu">SWIG Development Team</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
140
SWIG/Doc/Devel/migrate.txt
Normal file
140
SWIG/Doc/Devel/migrate.txt
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
SWIG1.3 Migration Guide
|
||||
(The not entirely complete guide to updating language modules to work with SWIG1.3).
|
||||
|
||||
Dave Beazley
|
||||
August 15, 2000
|
||||
|
||||
1. Introduction
|
||||
---------------
|
||||
|
||||
Virtually all of SWIG's internal data structures have now been
|
||||
rewritten. Take everything you thought you knew about SWIG1.1 and
|
||||
throw it out.
|
||||
|
||||
2. DataTypes
|
||||
------------
|
||||
The old 'DataType' data structure is gone. Therefore, direct
|
||||
manipulation of 'is_pointer', 'implicit_ptr', and 'arraystr'
|
||||
attributes no longer applies. Sorry.
|
||||
|
||||
Datatypes are now represented by the type 'SwigType' which has no
|
||||
public attributes. Actually, if you look at it closely, 'SwigType' is
|
||||
really just an alias for 'void' and if you look at it even closer than
|
||||
that you will realize that it's nothing more than a string!
|
||||
|
||||
The string encoding of types is described in more detail in the file
|
||||
Source/Swig/stype.c and is not so important here. What is important is
|
||||
the functions used to produce various types of output:
|
||||
|
||||
SwigType_str(type,name = 0);
|
||||
This produces an exact C representation of the datatype with all
|
||||
qualifiers, arrays, references, and so forth. name is an optional
|
||||
name that is given if you wanted to associate the type with a
|
||||
parameter name or something.
|
||||
|
||||
SwigType_lstr(type,name = 0);
|
||||
This function takes a type and produces a C string containing
|
||||
a type suitable for assignment (appearing as an lvalue in an
|
||||
expression). To do this, certain things such as 'const',
|
||||
arrays, and references are stripped away or converted into
|
||||
pointers.
|
||||
|
||||
SwigType_ltype(type);
|
||||
Returns a SwigType object corresponding to the type created
|
||||
by SwigType_lstr().
|
||||
|
||||
SwigType_lcaststr(type,name);
|
||||
Produces a string casting a value 'name' from the real datatype
|
||||
to the assignable type created by SwigType_lstr().
|
||||
|
||||
SwigType_rcaststr(type,name)
|
||||
Produces a string that casts a value 'name' from the type
|
||||
created by SwigType_lstr() to the real datatype.
|
||||
|
||||
SwigType_manglestr(type)
|
||||
Produces the 'mangled' version of a datatype.
|
||||
|
||||
|
||||
Getting the 'type' code. Most language modules still operate by
|
||||
looking at special integer type codes. This interface is a little
|
||||
ragged and will probably go away at some point. However, for now the
|
||||
following function can be used to get the type code:
|
||||
|
||||
int SwigType_type(type)
|
||||
|
||||
The codes are the same as the before, except that there are a few
|
||||
special codes:
|
||||
|
||||
T_STRING - The 'char *' type and variations.
|
||||
T_POINTER - Any pointer type (not char * though)
|
||||
T_REFERENCE - Any C++ reference
|
||||
T_ARRAY - Any array
|
||||
T_FUNCTION - A function (this is usually an error).
|
||||
|
||||
Because of the special codes, it is no longer necessary to have code like this:
|
||||
|
||||
if ((t->is_pointer == 1) and (t->type == T_CHAR)) {
|
||||
... get a string ...
|
||||
}
|
||||
|
||||
Instead, just use the type code above like this:
|
||||
|
||||
switch(SwigType_type(type)) {
|
||||
case T_STRING:
|
||||
... get a string ...
|
||||
break;
|
||||
case T_POINTER:
|
||||
... get a pointer ...
|
||||
break;
|
||||
}
|
||||
|
||||
There are about 2-dozen type manipulation functions that could also be useful.
|
||||
See Source/Swig/swig.h and Source/Swig/stype.c.
|
||||
|
||||
3. Parameter Lists
|
||||
------------------
|
||||
|
||||
The ParmList data structure is gone. In reality, parameter lists are nothing more than
|
||||
a linked list of parameters. The proper way to iterate over this list and get
|
||||
parameter values is as follows:
|
||||
|
||||
ParmList *l;
|
||||
Parm *p;
|
||||
|
||||
for (p = l; p; p = Getnext(p)) {
|
||||
SwigType *pt = Gettype(p); /* Get parameter type */
|
||||
String *pn = Getname(p); /* Get parameter name */
|
||||
String *value = Getvalue(p); /* Get parameter value */
|
||||
...
|
||||
do whatever
|
||||
...
|
||||
}
|
||||
|
||||
4. Typemaps
|
||||
-----------
|
||||
|
||||
Typemaps more or less work. However, the interface has changed slightly. Instead of
|
||||
|
||||
typemap_lookup("in","python",type,pname,"$source","$target",wrapper);
|
||||
|
||||
the function is
|
||||
|
||||
Swig_typemap_lookup("in",type,pname,"$source","$target",wrapper);
|
||||
|
||||
There are a variety of other changes to typemaps (see CHANGES).
|
||||
|
||||
5. Use of new types
|
||||
-------------------
|
||||
When possible, language modules should try to use the built in String,
|
||||
List, and Hash objects instead of C arrays or 'char *'. This will probably require a
|
||||
detailed pass through the code with an eye towards cleanup.
|
||||
|
||||
6. Miscellaneous
|
||||
----------------
|
||||
Language modules no longer need to concern themselves with formatting the
|
||||
wrapper code they produce (provided you are using the special Wrapper object).
|
||||
The function Wrapper_print() passes everything through a pretty-printer that
|
||||
automatically performs indentation and tries to clean things up. This especially
|
||||
works well when there are lots of typemaps.
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue