Branch for development of -builtin option for python.

With this option, swig will produce new built-in python
types for all wrapped classes.  Built-in types offer a
substantial performance benefit compared to the current
shadow class implementation.



git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/szager-python-builtin@12331 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Stefan Zager 2010-12-07 21:36:40 +00:00
commit 25a1f9844b
3883 changed files with 432049 additions and 0 deletions

11
.project Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>SWIG</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>

34
ANNOUNCE Normal file
View file

@ -0,0 +1,34 @@
*** ANNOUNCE: SWIG 2.0.2 (in progress) ***
http://www.swig.org
We're pleased to announce SWIG-2.0.1, the latest SWIG release.
What is SWIG?
=============
SWIG is a software development tool that reads C/C++ header files and
generates the wrapper code needed to make C and C++ code accessible
from other languages including Perl, Python, Tcl, Ruby, PHP, Java,
Scheme (Guile, MzScheme, CHICKEN), Ocaml, Lua, Pike, C#, Modula-3, Octave, R,
Common Lisp (CLISP, Allegro CL, CFFI, UFFI). SWIG can also export its parse
tree in the form of XML and Lisp s-expressions. Major applications of
SWIG include generation of scripting language extension modules, rapid
prototyping, testing, and user interface development for large C/C++
systems.
Availability
============
The release is available for download on Sourceforge at
http://prdownloads.sourceforge.net/swig/swig-2.0.1.tar.gz
A Windows version is also available at
http://prdownloads.sourceforge.net/swig/swigwin-2.0.1.zip
Please report problems with this release to the swig-devel mailing list,
details at http://www.swig.org/mail.html.
--- The SWIG Developers

339
CCache/COPYING Normal file
View file

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

77
CCache/Makefile.in Normal file
View file

@ -0,0 +1,77 @@
datarootdir = @datarootdir@
srcdir=@srcdir@
VPATH=@srcdir@
prefix=@prefix@
exec_prefix=@exec_prefix@
bindir=@bindir@
mandir=@mandir@
INSTALLCMD=@INSTALL@
PACKAGE_NAME=@PACKAGE_NAME@
# Soft link test can be skipped on systems that don't support soft linking
NOSOFTLINKSTEST=
CC=@CC@
CFLAGS=@CFLAGS@ -I.
SWIG=swig
SWIG_LIB=../../Lib
EXEEXT=@EXEEXT@
# Use standard autoconf approach to transform executable name using --program-prefix and --program-suffix
transform = @program_transform_name@
LIBS= @LIBS@
OBJS= ccache.o mdfour.o hash.o execute.o util.o args.o stats.o \
cleanup.o snprintf.o unify.o
HEADERS = ccache.h mdfour.h
all: $(PACKAGE_NAME)$(EXEEXT)
# Note that HTML documentation is actually generated and used from the main SWIG documentation Makefile
docs: $(PACKAGE_NAME).1 web/ccache-man.html
$(PACKAGE_NAME)$(EXEEXT): $(OBJS) $(HEADERS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
$(PACKAGE_NAME).1: ccache.yo
-yodl2man -o $(PACKAGE_NAME).1 ccache.yo
web/ccache-man.html: ccache.yo
yodl2html -o web/ccache-man.html ccache.yo
install: $(PACKAGE_NAME)$(EXEEXT) $(PACKAGE_NAME).1
@echo "Installing $(PACKAGE_NAME)"
@echo "Installing $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)"
${INSTALLCMD} -d $(DESTDIR)${bindir}
${INSTALLCMD} -m 755 $(PACKAGE_NAME)$(EXEEXT) $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)
@echo "Installing $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1"
${INSTALLCMD} -d $(DESTDIR)${mandir}/man1
${INSTALLCMD} -m 644 ${srcdir}/$(PACKAGE_NAME).1 $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1
uninstall: $(PACKAGE_NAME)$(EXEEXT) $(PACKAGE_NAME).1
rm -f $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)
rm -f $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1
clean:
/bin/rm -f $(OBJS) *~ $(PACKAGE_NAME)$(EXEEXT)
check : test
test: test.sh
SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' NOSOFTLINKSTEST='$(NOSOFTLINKSTEST)' ./test.sh
check: test
distclean: clean
/bin/rm -f Makefile config.h config.sub config.log build-stamp config.status ccache_swig_config.h
/bin/rm -rf autom4te.cache
maintainer-clean: distclean
/bin/rm -f $(PACKAGE_NAME).1 web/ccache-man.html
# FIXME: To fix this, test.sh needs to be able to take ccache from the
# installed prefix, not from the source dir.
installcheck:
@echo "WARNING! This is not really \"installcheck\" yet."
$(MAKE) check

31
CCache/README Normal file
View file

@ -0,0 +1,31 @@
This is a re-implementation of "compilercache" in C
The original compilercache scripts were by Erik Thiele
(erikyyy@erikyyy.de) and I would like to thank him for an excellent
piece of work. See http://www.erikyyy.de/compilercache/ for the
original shell scripts.
I wrote ccache because I wanted to get a bit more speed out of a
compiler cache and I wanted to remove some of the limitations of the
shell-script version.
Please see the manual page and documentation at
http://ccache.samba.org/
INSTALLATION
------------
Please run:
./configure
make
make install
then read the ccache manual page
-----------
Andrew Tridgell
http://samba.org/~tridge/
bugs@ccache.samba.org

8
CCache/README.swig Normal file
View file

@ -0,0 +1,8 @@
This directory contains a version of ccache. The initial version was based on ccache-2.4 plus
debian patches 01-02, 04-14, see the debian/patches subdirectory. The ccache-win32-2.4 modifications
to ccache-2.4 have also been merged in.
Changes have been made to support cacheing the output from SWIG. The ability to cache c/c++ compiler
output has been retained.
Additional features added are the CCACHE_VERBOSE and CCACHE_SWIG environment variables, see docs.

91
CCache/args.c Normal file
View file

@ -0,0 +1,91 @@
/*
convenient routines for argument list handling
Copyright (C) Andrew Tridgell 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "ccache.h"
ARGS *args_init(int init_argc, char **init_args)
{
ARGS *args;
int i;
args = (ARGS *)x_malloc(sizeof(ARGS));
args->argc = 0;
args->argv = (char **)x_malloc(sizeof(char *));
args->argv[0] = NULL;
for (i=0;i<init_argc;i++) {
args_add(args, init_args[i]);
}
return args;
}
void args_add(ARGS *args, const char *s)
{
args->argv = (char**)x_realloc(args->argv, (args->argc + 2) * sizeof(char *));
args->argv[args->argc] = x_strdup(s);
args->argc++;
args->argv[args->argc] = NULL;
}
/* pop the last element off the args list */
void args_pop(ARGS *args, int n)
{
while (n--) {
args->argc--;
free(args->argv[args->argc]);
args->argv[args->argc] = NULL;
}
}
/* remove the first element of the argument list */
void args_remove_first(ARGS *args)
{
free(args->argv[0]);
memmove(&args->argv[0],
&args->argv[1],
args->argc * sizeof(args->argv[0]));
args->argc--;
}
/* add an argument into the front of the argument list */
void args_add_prefix(ARGS *args, const char *s)
{
args->argv = (char**)x_realloc(args->argv, (args->argc + 2) * sizeof(char *));
memmove(&args->argv[1], &args->argv[0],
(args->argc+1) * sizeof(args->argv[0]));
args->argv[0] = x_strdup(s);
args->argc++;
}
/* strip any arguments beginning with the specified prefix */
void args_strip(ARGS *args, const char *prefix)
{
int i;
for (i=0; i<args->argc; ) {
if (strncmp(args->argv[i], prefix, strlen(prefix)) == 0) {
free(args->argv[i]);
memmove(&args->argv[i],
&args->argv[i+1],
args->argc * sizeof(args->argv[i]));
args->argc--;
} else {
i++;
}
}
}

1388
CCache/ccache.c Normal file

File diff suppressed because it is too large Load diff

205
CCache/ccache.h Normal file
View file

@ -0,0 +1,205 @@
#include "ccache_swig_config.h"
#define CCACHE_VERSION SWIG_VERSION
#ifndef _WIN32
#include "config.h"
#else
#include <sys/locking.h>
#define PACKAGE_NAME "ccache-swig.exe"
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
#include <sys/wait.h>
#include <sys/mman.h>
#else
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <shlobj.h>
#endif
#include <sys/file.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <utime.h>
#include <stdarg.h>
#include <dirent.h>
#include <limits.h>
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef ENABLE_ZLIB
#include <zlib.h>
#endif
#define STATUS_NOTFOUND 3
#define STATUS_FATAL 4
#define STATUS_NOCACHE 5
#define MYNAME PACKAGE_NAME
#define LIMIT_MULTIPLE 0.8
/* default maximum cache size */
#ifndef DEFAULT_MAXSIZE
#define DEFAULT_MAXSIZE (1000*1000)
#endif
/* file copy mode */
#ifdef ENABLE_ZLIB
#define COPY_UNCOMPRESSED 0
#define COPY_FROM_CACHE 1
#define COPY_TO_CACHE 2
#endif
enum stats {
STATS_NONE=0,
STATS_STDOUT,
STATS_STATUS,
STATS_ERROR,
STATS_TOCACHE,
STATS_PREPROCESSOR,
STATS_COMPILER,
STATS_MISSING,
STATS_CACHED,
STATS_ARGS,
STATS_LINK,
STATS_NUMFILES,
STATS_TOTALSIZE,
STATS_MAXFILES,
STATS_MAXSIZE,
STATS_NOTC,
STATS_DEVICE,
STATS_NOINPUT,
STATS_ENVIRONMMENT,
STATS_MULTIPLE,
STATS_CONFTEST,
STATS_UNSUPPORTED,
STATS_OUTSTDOUT,
STATS_END
};
typedef unsigned uint32;
#include "mdfour.h"
void hash_start(void);
void hash_string(const char *s);
void hash_int(int x);
void hash_file(const char *fname);
char *hash_result(void);
void hash_buffer(const char *s, int len);
void cc_log(const char *format, ...);
void fatal(const char *msg);
void copy_fd(int fd_in, int fd_out);
int safe_rename(const char* oldpath, const char* newpath);
int move_file(const char *src, const char *dest);
int test_if_compressed(const char *filename);
int commit_to_cache(const char *src, const char *dest, int hardlink);
int retrieve_from_cache(const char *src, const char *dest, int hardlink);
int create_dir(const char *dir);
int create_cachedirtag(const char *dir);
void x_asprintf(char **ptr, const char *format, ...);
char *x_strdup(const char *s);
void *x_realloc(void *ptr, size_t size);
void *x_malloc(size_t size);
void traverse(const char *dir, void (*fn)(const char *, struct stat *));
char *str_basename(const char *s);
char *dirname(char *s);
int lock_fd(int fd);
size_t file_size(struct stat *st);
int safe_open(const char *fname);
char *x_realpath(const char *path);
char *gnu_getcwd(void);
int create_empty_file(const char *fname);
const char *get_home_directory(void);
int x_utimes(const char *filename);
#ifdef _WIN32
void perror_win32(LPTSTR pszFunction);
#endif
void stats_update(enum stats stat);
void stats_zero(void);
void stats_summary(void);
void stats_tocache(size_t size, size_t numfiles);
void stats_read(const char *stats_file, unsigned counters[STATS_END]);
int stats_set_limits(long maxfiles, long maxsize);
size_t value_units(const char *s);
void display_size(unsigned v);
void stats_set_sizes(const char *dir, size_t num_files, size_t total_size);
int unify_hash(const char *fname);
#ifndef HAVE_VASPRINTF
int vasprintf(char **, const char *, va_list );
#endif
#ifndef HAVE_ASPRINTF
int asprintf(char **ptr, const char *format, ...);
#endif
#ifndef HAVE_SNPRINTF
int snprintf(char *,size_t ,const char *, ...);
#endif
void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize);
void cleanup_all(const char *dir);
void wipe_all(const char *dir);
#ifdef _WIN32
char *argvtos(char **argv);
#endif
int execute(char **argv,
const char *path_stdout,
const char *path_stderr);
char *find_executable(const char *name, const char *exclude_name);
void display_execute_args(char **argv);
typedef struct {
char **argv;
int argc;
} ARGS;
ARGS *args_init(int , char **);
void args_add(ARGS *args, const char *s);
void args_add_prefix(ARGS *args, const char *s);
void args_pop(ARGS *args, int n);
void args_strip(ARGS *args, const char *prefix);
void args_remove_first(ARGS *args);
extern int ccache_verbose;
#if HAVE_COMPAR_FN_T
#define COMPAR_FN_T __compar_fn_t
#else
typedef int (*COMPAR_FN_T)(const void *, const void *);
#endif
/* work with silly DOS binary open */
#ifndef O_BINARY
#define O_BINARY 0
#endif
/* mkstemp() on some versions of cygwin don't handle binary files, so
override */
#ifdef __CYGWIN__
#undef HAVE_MKSTEMP
#endif

422
CCache/ccache.yo Normal file
View file

@ -0,0 +1,422 @@
whenman(
COMMENT(html output not great if included when using html2doc)
manpage(ccache-swig)(1)()()()
)
whenhtml(htmlcommand(
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ccache-swig(1) manpage</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="CCache"></a>Using SWIG with ccache - ccache-swig(1) manpage</H1>
<!-- INDEX -->
<div class="sectiontoc">
<!-- INDEX -->
))
manpagename(ccache-swig)(a fast compiler cache)
whenhtml(htmlcommand(
ccache-swig - a fast compiler cache
))
manpagesynopsis()
ccache-swig [OPTION]
ccache-swig <compiler> [COMPILER OPTIONS]
<compiler> [COMPILER OPTIONS]
manpagedescription()
ccache-swig is a compiler cache. It speeds up re-compilation of C/C++/SWIG code
by caching previous compiles and detecting when the same compile is
being done again. ccache-swig is ccache plus support for SWIG. ccache
and ccache-swig are used interchangeably in this document.
manpagesection(OPTIONS SUMMARY)
Here is a summary of the options to ccache-swig.
verb(
-s show statistics summary
-z zero statistics
-c run a cache cleanup
-C clear the cache completely
-F <n> set maximum files in cache
-M <n> set maximum size of cache (use G, M or K)
-h this help page
-V print version number
)
manpageoptions()
These options only apply when you invoke ccache as "ccache-swig". When
invoked as a compiler none of these options apply. In that case your
normal compiler options apply and you should refer to your compilers
documentation.
startdit()
dit(bf(-h)) Print a options summary page
dit(bf(-s)) Print the current statistics summary for the cache. The
statistics are stored spread across the subdirectories of the
cache. Using "ccache-swig -s" adds up the statistics across all
subdirectories and prints the totals.
dit(bf(-z)) Zero the cache statistics.
dit(bf(-V)) Print the ccache version number
dit(bf(-c)) Clean the cache and re-calculate the cache file count and
size totals. Normally the -c option should not be necessary as ccache
keeps the cache below the specified limits at runtime and keeps
statistics up to date on each compile. This option is mostly useful
if you manually modify the cache contents or believe that the cache
size statistics may be inaccurate.
dit(bf(-C)) Clear the entire cache, removing all cached files.
dit(bf(-F <maxfiles>)) This sets the maximum number of files allowed in
the cache. The value is stored inside the cache directory and applies
to all future compiles. Due to the way the value is stored the actual
value used is always rounded down to the nearest multiple of 16.
dit(bf(-M <maxsize>)) This sets the maximum cache size. You can specify
a value in gigabytes, megabytes or kilobytes by appending a G, M or K
to the value. The default is gigabytes. The actual value stored is
rounded down to the nearest multiple of 16 kilobytes.
enddit()
manpagesection(INSTALLATION)
There are two ways to use ccache. You can either prefix your compile
commands with "ccache-swig" or you can create a symbolic link between
ccache-swig and the names of your compilers. The first method is most
convenient if you just want to try out ccache or wish to use it for
some specific projects. The second method is most useful for when you
wish to use ccache for all your compiles.
To install for usage by the first method just copy ccache-swig to somewhere
in your path.
To install for the second method do something like this:
verb(
cp ccache-swig /usr/local/bin/
ln -s /usr/local/bin/ccache-swig /usr/local/bin/gcc
ln -s /usr/local/bin/ccache-swig /usr/local/bin/g++
ln -s /usr/local/bin/ccache-swig /usr/local/bin/cc
ln -s /usr/local/bin/ccache-swig /usr/local/bin/swig
)
This will work as long as /usr/local/bin comes before the path to gcc
(which is usually in /usr/bin). After installing you may wish to run
"which gcc" to make sure that the correct link is being used.
Note! Do not use a hard link, use a symbolic link. A hardlink will
cause "interesting" problems.
manpagesection(EXTRA OPTIONS)
When run as a compiler front end ccache usually just takes the same
command line options as the compiler you are using. The only exception
to this is the option '--ccache-skip'. That option can be used to tell
ccache that the next option is definitely not a input filename, and
should be passed along to the compiler as-is.
The reason this can be important is that ccache does need to parse the
command line and determine what is an input filename and what is a
compiler option, as it needs the input filename to determine the name
of the resulting object file (among other things). The heuristic
ccache uses in this parse is that any string on the command line that
exists as a file is treated as an input file name (usually a C
file). By using --ccache-skip you can force an option to not be
treated as an input file name and instead be passed along to the
compiler as a command line option.
manpagesection(ENVIRONMENT VARIABLES)
ccache uses a number of environment variables to control operation. In
most cases you won't need any of these as the defaults will be fine.
startdit()
dit(bf(CCACHE_DIR)) the CCACHE_DIR environment variable specifies
where ccache will keep its cached compiler output. The default is
"$HOME/.ccache".
dit(bf(CCACHE_TEMPDIR)) the CCACHE_TEMPDIR environment variable specifies
where ccache will put temporary files. The default is the same as
CCACHE_DIR. Note that the CCACHE_TEMPDIR path must be on the same
filesystem as the CCACHE_DIR path, so that renames of files between
the two directories can work.
dit(bf(CCACHE_LOGFILE)) If you set the CCACHE_LOGFILE environment
variable then ccache will write some log information on cache hits
and misses in that file. This is useful for tracking down problems.
dit(bf(CCACHE_VERBOSE)) If you set the CCACHE_VERBOSE environment
variable then ccache will display on stdout all the compiler invocations
that it makes. This can useful for debugging unexpected problems.
dit(bf(CCACHE_PATH)) You can optionally set CCACHE_PATH to a colon
separated path where ccache will look for the real compilers. If you
don't do this then ccache will look for the first executable matching
the compiler name in the normal PATH that isn't a symbolic link to
ccache itself.
dit(bf(CCACHE_CC)) You can optionally set CCACHE_CC to force the name
of the compiler to use. If you don't do this then ccache works it out
from the command line.
dit(bf(CCACHE_PREFIX)) This option adds a prefix to the command line
that ccache runs when invoking the compiler. Also see the section
below on using ccache with distcc.
dit(bf(CCACHE_DISABLE)) If you set the environment variable
CCACHE_DISABLE then ccache will just call the real compiler,
bypassing the cache completely.
dit(bf(CCACHE_READONLY)) the CCACHE_READONLY environment variable
tells ccache to attempt to use existing cached object files, but not
to try to add anything new to the cache. If you are using this because
your CCACHE_DIR is read-only, then you may find that you also need to
set CCACHE_TEMPDIR as otherwise ccache will fail to create the
temporary files.
dit(bf(CCACHE_CPP2)) If you set the environment variable CCACHE_CPP2
then ccache will not use the optimisation of avoiding the 2nd call to
the pre-processor by compiling the pre-processed output that was used
for finding the hash in the case of a cache miss. This is primarily a
debugging option, although it is possible that some unusual compilers
will have problems with the intermediate filename extensions used in
this optimisation, in which case this option could allow ccache to be
used.
dit(bf(CCACHE_NOCOMPRESS)) If you set the environment variable
CCACHE_NOCOMPRESS then there is no compression used on files that go
into the cache. However, this setting has no effect on how files are
retrieved from the cache, compressed results will still be usable.
dit(bf(CCACHE_NOSTATS)) If you set the environment variable
CCACHE_NOSTATS then ccache will not update the statistics files on
each compile.
dit(bf(CCACHE_NLEVELS)) The environment variable CCACHE_NLEVELS allows
you to choose the number of levels of hash in the cache directory. The
default is 2. The minimum is 1 and the maximum is 8.
dit(bf(CCACHE_HARDLINK)) If you set the environment variable
CCACHE_HARDLINK then ccache will attempt to use hard links from the
cache directory when creating the compiler output rather than using a
file copy. Using hard links is faster, but can confuse programs like
'make' that rely on modification times. Hard links are never made for
compressed cache files.
dit(bf(CCACHE_RECACHE)) This forces ccache to not use any cached
results, even if it finds them. New results are still cached, but
existing cache entries are ignored.
dit(bf(CCACHE_UMASK)) This sets the umask for ccache and all child
processes (such as the compiler). This is mostly useful when you wish
to share your cache with other users. Note that this also affects the
file permissions set on the object files created from your
compilations.
dit(bf(CCACHE_HASHDIR)) This tells ccache to hash the current working
directory when calculating the hash that is used to distinguish two
compiles. This prevents a problem with the storage of the current
working directory in the debug info of a object file, which can lead
ccache to give a cached object file that has the working directory in
the debug info set incorrectly. This option is off by default as the
incorrect setting of this debug info rarely causes problems. If you
strike problems with gdb not using the correct directory then enable
this option.
dit(bf(CCACHE_UNIFY)) If you set the environment variable CCACHE_UNIFY
then ccache will use the C/C++ unifier when hashing the pre-processor
output if -g is not used in the compile. The unifier is slower than a
normal hash, so setting this environment variable loses a little bit
of speed, but it means that ccache can take advantage of not
recompiling when the changes to the source code consist of
reformatting only. Note that using CCACHE_UNIFY changes the hash, so
cached compiles with CCACHE_UNIFY set cannot be used when
CCACHE_UNIFY is not set and vice versa. The reason the unifier is off
by default is that it can give incorrect line number information in
compiler warning messages.
dit(bf(CCACHE_EXTENSION)) Normally ccache tries to automatically
determine the extension to use for intermediate C pre-processor files
based on the type of file being compiled. Unfortunately this sometimes
doesn't work, for example when using the aCC compiler on HP-UX. On
systems like this you can use the CCACHE_EXTENSION option to override
the default. On HP-UX set this environment variable to "i" if you use
the aCC compiler.
dit(bf(CCACHE_STRIPC)) If you set the environment variable
CCACHE_STRIPC then ccache will strip the -c option when invoking
the preprocessor. This option is primarily for the Sun Workshop
C++ compiler as without this option an unwarranted warning is displayed:
CC: Warning: "-E" redefines product from "object" to "source (stdout)"
when -E and -c is used together.
dit(bf(CCACHE_SWIG)) When using SWIG as the compiler and it does not
have 'swig' in the executable name, then the CCACHE_SWIG environment
variable needs to be set in order for ccache to work correctly with
SWIG. The use of CCACHE_CPP2 is also recommended for SWIG due to some
preprocessor quirks, however, use of CCACHE_CPP2 can often be skipped
-- check your generated code with and without this option set. Known
problems are using preprocessor directives within %inline blocks and
the use of '#pragma SWIG'.
enddit()
manpagesection(CACHE SIZE MANAGEMENT)
By default ccache has a one gigabyte limit on the cache size and no
maximum number of files. You can set a different limit using the
"ccache -M" and "ccache -F" options, which set the size and number of
files limits.
When these limits are reached ccache will reduce the cache to 20%
below the numbers you specified in order to avoid doing the cache
clean operation too often.
manpagesection(CACHE COMPRESSION)
By default on most platforms ccache will compress all files it puts
into the cache
using the zlib compression. While this involves a negligible
performance slowdown, it significantly increases the number of files
that fit in the cache. You can turn off compression setting the
CCACHE_NOCOMPRESS environment variable.
manpagesection(HOW IT WORKS)
The basic idea is to detect when you are compiling exactly the same
code a 2nd time and use the previously compiled output. You detect
that it is the same code by forming a hash of:
itemization(
it() the pre-processor output from running the compiler with -E
it() the command line options
it() the real compilers size and modification time
it() any stderr output generated by the compiler
)
These are hashed using md4 (a strong hash) and a cache file is formed
based on that hash result. When the same compilation is done a second
time ccache is able to supply the correct compiler output (including
all warnings etc) from the cache.
ccache has been carefully written to always produce exactly the same
compiler output that you would get without the cache. If you ever
discover a case where ccache changes the output of your compiler then
please let me know.
manpagesection(USING CCACHE WITH DISTCC)
distcc is a very useful program for distributing compilation across a
range of compiler servers. It is often useful to combine distcc with
ccache, so that compiles that are done are sped up by distcc, but that
ccache avoids the compile completely where possible.
To use distcc with ccache I recommend using the CCACHE_PREFIX
option. You just need to set the environment variable CCACHE_PREFIX to
'distcc' and ccache will prefix the command line used with the
compiler with the command 'distcc'.
manpagesection(SHARING A CACHE)
A group of developers can increase the cache hit rate by sharing a
cache directory. The hard links however cause unwanted side effects,
as all links to a cached file share the file's modification timestamp.
This results in false dependencies to be triggered by timestamp-based
build systems whenever another user links to an existing
file. Typically, users will see that their libraries and binaries are
relinked without reason. To share a cache without side effects, the
following conditions need to be met:
itemization(
it() Use the same bf(CCACHE_DIR) environment variable setting
it() Unset the bf(CCACHE_HARDLINK) environment variable
it() Make sure everyone sets the CCACHE_UMASK environment variable
to 002, this ensures that cached files are accessible to everyone in
the group.
it() Make sure that all users have write permission in the entire
cache directory (and that you trust all users of the shared cache).
it() Make sure that the setgid bit is set on all directories in the
cache. This tells the filesystem to inherit group ownership for new
directories. The command "chmod g+s `find $CCACHE_DIR -type d`" might
be useful for this.
it() Set bf(CCACHE_NOCOMPRESS) for all users, if there are users with
versions of ccache that do not support compression.
)
manpagesection(HISTORY)
ccache was inspired by the compilercache shell script script written
by Erik Thiele and I would like to thank him for an excellent piece of
work. See
url(http://www.erikyyy.de/compilercache/)(http://www.erikyyy.de/compilercache/)
for the Erik's scripts.
ccache-swig is a port of the original ccache with support added for use
with SWIG.
I wrote ccache because I wanted to get a bit more speed out of a
compiler cache and I wanted to remove some of the limitations of the
shell-script version.
manpagesection(DIFFERENCES FROM COMPILERCACHE)
The biggest differences between Erik's compilercache script and ccache
are:
itemization(
it() ccache is written in C, which makes it a bit faster (calling out to
external programs is mostly what slowed down the scripts).
it() ccache can automatically find the real compiler
it() ccache keeps statistics on hits/misses
it() ccache can do automatic cache management
it() ccache can cache compiler output that includes warnings. In many
cases this gives ccache a much higher cache hit rate.
it() ccache can handle a much wider ranger of compiler options
it() ccache avoids a double call to cpp on a cache miss
)
manpagesection(CREDITS)
Thanks to the following people for their contributions to ccache
itemization(
it() Erik Thiele for the original compilercache script
it() Luciano Rocha for the idea of compiling the pre-processor output
to avoid a 2nd cpp pass
it() Paul Russell for many suggestions and the debian packaging
)
manpageauthor()
ccache was written by Andrew Tridgell
url(http://samba.org/~tridge/)(http://samba.org/~tridge/).
ccache was adapted to create ccache-swig for use with SWIG by William Fulton.
If you wish to report a problem or make a suggestion then please email
the SWIG developers on the swig-devel mailing list, see
url(http://www.swig.org/mail.html)(http://www.swig.org/mail.html)
ccache is released under the GNU General Public License version 2 or
later. Please see the file COPYING for license details.
whenhtml(htmlcommand(
</body>
</html>
))

View file

@ -0,0 +1 @@
#define SWIG_VERSION "@PACKAGE_VERSION@"

193
CCache/cleanup.c Normal file
View file

@ -0,0 +1,193 @@
/*
Copyright (C) Andrew Tridgell 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
functions to cleanup the cache directory when it gets too large
*/
#include "ccache.h"
static struct files {
char *fname;
time_t mtime;
size_t size;
} **files;
static unsigned allocated;
static unsigned num_files;
static size_t total_size;
static size_t total_files;
static size_t size_threshold;
static size_t files_threshold;
/* file comparison function to try to delete the oldest files first */
static int files_compare(struct files **f1, struct files **f2)
{
if ((*f2)->mtime == (*f1)->mtime) {
return strcmp((*f2)->fname, (*f1)->fname);
}
if ((*f2)->mtime > (*f1)->mtime) {
return -1;
}
return 1;
}
/* this builds the list of files in the cache */
static void traverse_fn(const char *fname, struct stat *st)
{
char *p;
if (!S_ISREG(st->st_mode)) return;
p = str_basename(fname);
if (strcmp(p, "stats") == 0) {
free(p);
return;
}
free(p);
if (num_files == allocated) {
allocated = 10000 + num_files*2;
files = (struct files **)x_realloc(files,
sizeof(struct files *)*allocated);
}
files[num_files] = (struct files *)x_malloc(sizeof(struct files));
files[num_files]->fname = x_strdup(fname);
files[num_files]->mtime = st->st_mtime;
files[num_files]->size = file_size(st) / 1024;
total_size += files[num_files]->size;
num_files++;
}
/* sort the files we've found and delete the oldest ones until we are
below the thresholds */
static void sort_and_clean(void)
{
unsigned i;
if (num_files > 1) {
/* sort in ascending data order */
qsort(files, num_files, sizeof(struct files *),
(COMPAR_FN_T)files_compare);
}
/* delete enough files to bring us below the threshold */
for (i=0;i<num_files; i++) {
if ((size_threshold==0 || total_size < size_threshold) &&
(files_threshold==0 || (num_files-i) < files_threshold)) break;
if (unlink(files[i]->fname) != 0 && errno != ENOENT) {
fprintf(stderr, "unlink %s - %s\n",
files[i]->fname, strerror(errno));
continue;
}
total_size -= files[i]->size;
}
total_files = num_files - i;
}
/* cleanup in one cache subdir */
void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize)
{
unsigned i;
size_threshold = maxsize * LIMIT_MULTIPLE;
files_threshold = maxfiles * LIMIT_MULTIPLE;
num_files = 0;
total_size = 0;
/* build a list of files */
traverse(dir, traverse_fn);
/* clean the cache */
sort_and_clean();
stats_set_sizes(dir, total_files, total_size);
/* free it up */
for (i=0;i<num_files;i++) {
free(files[i]->fname);
free(files[i]);
files[i] = NULL;
}
if (files) free(files);
allocated = 0;
files = NULL;
num_files = 0;
total_size = 0;
}
/* cleanup in all cache subdirs */
void cleanup_all(const char *dir)
{
unsigned counters[STATS_END];
char *dname, *sfile;
int i;
for (i=0;i<=0xF;i++) {
x_asprintf(&dname, "%s/%1x", dir, i);
x_asprintf(&sfile, "%s/%1x/stats", dir, i);
memset(counters, 0, sizeof(counters));
stats_read(sfile, counters);
cleanup_dir(dname,
counters[STATS_MAXFILES],
counters[STATS_MAXSIZE]);
free(dname);
free(sfile);
}
}
/* traverse function for wiping files */
static void wipe_fn(const char *fname, struct stat *st)
{
char *p;
if (!S_ISREG(st->st_mode)) return;
p = str_basename(fname);
if (strcmp(p, "stats") == 0) {
free(p);
return;
}
free(p);
unlink(fname);
}
/* wipe all cached files in all subdirs */
void wipe_all(const char *dir)
{
char *dname;
int i;
for (i=0;i<=0xF;i++) {
x_asprintf(&dname, "%s/%1x", dir, i);
traverse(dir, wipe_fn);
free(dname);
}
/* and fix the counters */
cleanup_all(dir);
}

87
CCache/configure.in Normal file
View file

@ -0,0 +1,87 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT([ccache-swig], [0.0]) # Get version from SWIG in ccache_swig_config.h.in
AC_PREREQ(2.52)
AC_CONFIG_SRCDIR([ccache.h])
AC_MSG_NOTICE([Configuring ccache])
AC_CONFIG_HEADER(config.h)
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_ARG_PROGRAM # for program_transform_name
AC_DEFINE([_GNU_SOURCE], 1,
[Define _GNU_SOURCE so that we get all necessary prototypes])
# If GCC, turn on warnings.
if test "x$GCC" = "xyes"
then
CFLAGS="$CFLAGS -Wall -W"
else
CFLAGS="$CFLAGS -O"
fi
AC_HEADER_DIRENT
AC_HEADER_TIME
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(ctype.h strings.h stdlib.h string.h pwd.h sys/time.h)
AC_CHECK_FUNCS(realpath snprintf vsnprintf vasprintf asprintf mkstemp)
AC_CHECK_FUNCS(gethostname getpwuid)
AC_CHECK_FUNCS(utimes)
AC_CACHE_CHECK([for compar_fn_t in stdlib.h],ccache_cv_COMPAR_FN_T, [
AC_TRY_COMPILE(
[#include <stdlib.h>],
[
void test_fn(void) { qsort(NULL, 0, 0, (__compar_fn_t)NULL); }
],
ccache_cv_COMPAR_FN_T=yes,ccache_cv_COMPAR_FN_T=no)])
if test x"$ccache_cv_COMPAR_FN_T" = x"yes"; then
AC_DEFINE(HAVE_COMPAR_FN_T, 1, [ ])
fi
dnl Note: This could be replaced by AC_FUNC_SNPRINTF() in the autoconf macro archive
AC_CACHE_CHECK([for C99 vsnprintf],ccache_cv_HAVE_C99_VSNPRINTF,[
AC_TRY_RUN([
#include <sys/types.h>
#include <stdarg.h>
void foo(const char *format, ...) {
va_list ap;
int len;
char buf[5];
va_start(ap, format);
len = vsnprintf(0, 0, format, ap);
va_end(ap);
if (len != 5) exit(1);
if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(1);
exit(0);
}
main() { foo("hello"); }
],
ccache_cv_HAVE_C99_VSNPRINTF=yes,ccache_cv_HAVE_C99_VSNPRINTF=no,ccache_cv_HAVE_C99_VSNPRINTF=cross)])
if test x"$ccache_cv_HAVE_C99_VSNPRINTF" = x"yes"; then
AC_DEFINE(HAVE_C99_VSNPRINTF, 1, [ ])
fi
dnl Check for zlib.
dnl Note: This could be replaced by CHECK_ZLIB() in the autoconf macro archive
AC_ARG_ENABLE([zlib],
AS_HELP_STRING([--enable-zlib], [enable zlib support for ccache compression]),,
[enable_zlib=yes])
if test x"$enable_zlib" = x"yes"; then
AC_CHECK_HEADER(zlib.h, AC_CHECK_LIB(z, gzdopen, [LIBS="-lz $LIBS"
AC_DEFINE([ENABLE_ZLIB], 1, [Define to 1 if you would like to have zlib compression for ccache.]) ] ))
fi
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

22
CCache/debian/NEWS Normal file
View file

@ -0,0 +1,22 @@
ccache (2.4-8) unstable; urgency=high
zlib compression is now enabled by default in order to increase the amount
of object files that can fit in the cache.
The impact on performance is supposed to be almost negligible
(see http://www.gustaebel.de/lars/ccache/). If you do want to disable
it however, simply export the CCACHE_NOCOMPRESS environment variable.
Note that a zlib-enabled ccache will still read your existing
uncompressed cache. If you want to compress/uncompress your cache,
see the manage-cache.sh script under /usr/share/doc/ccache/examples/.
-- Francois Marier <francois@debian.org> Sun, 20 May 2007 19:45:07 +1200
ccache (2.4-1) unstable; urgency=low
* This release changes the hash input slighly, so you will probably find
that you will not get any hits against your existing cache when you
upgrade.
-- Francois Marier <francois@debian.org> Sat, 11 Jun 2005 13:54:33 -0400

View file

@ -0,0 +1,59 @@
Installing ccache
-----------------
The recommended way to use this with Debian is to either create "cc"
and "gcc" symlinks to /usr/bin/ccache in your private bin directory
(which must be before the real cc and gcc in your path), or use
CC="ccache gcc" on the make command line.
Another option is to just prepend /usr/lib/ccache in your PATH
environment variable, like
export PATH="/usr/lib/ccache:$PATH"
Note that ccache works with both native and cross compilers.
Ignoring whitespace
-------------------
If you wish to set up ccache so that it ignores blank lines, have a
look at the CCACHE_UNIFY option. However, please note that this
option is off by default since the reported line numbers may not
match the source files anymore.
NFS Issues
----------
(from John Coiner <john.coiner@amd.com> on the ccache mailing list)
When CCache creates a hardlinked output file, it calls utime() to update
the timestamp on the object, so that Make realizes that the object has
changed.
On NFS, utime() has no coherency guarantee, AFAIK. When utime() runs on
host A, and our parallel implementation of Make is running on host B,
sometimes Make doesn't see the new timestamp soon enough -- and neglects
to relink the final binary. That's a one-way ticket to Silent Mysterious
Failure Town.
Instead of relying on the object file timestamp, we create a dummy file
with a reliable timestamp:
objs/foo.o objs/foo.o.built :
if ( ccache gcc -o foo.o -c foo.c ) ; \
then touch objs/foo.o.built ; \
else exit 1; \
fi
binary : objs/foo.o.built
gcc -o binary objs/foo.o
NFS does make a coherency guarantee, that if a file is written and
close()d on host A, and subsequently open()ed on host B, that the second
open() will reflect all modifications and attributes from the close().
Since Make does open() when checking timestamps, and the dummy file is
close()d when it's created, the binary will always relink after the
object is recompiled.
-- Francois Marier <francois@debian.org> Sun, 20 May 2007 17:35:36 +1200

221
CCache/debian/changelog Normal file
View file

@ -0,0 +1,221 @@
ccache (2.4-15) unstable; urgency=low
* Add a new patch which improve the consistency of timestamps on cached
objects to make sure clean-up is based on least recently used objects.
* Patch the set_limit call so that non-writable cache directories return
an error when attempting to size the max(files|size) (closes: #332527)
-- Francois Marier <francois@debian.org> Sun, 13 Apr 2008 15:07:05 +1200
ccache (2.4-14) unstable; urgency=low
* Mention the long options everywhere in the manpage
* Merge Gentoo patches:
- respect user's LDFLAGS
- use utimes() for timestamp if possible
-- Francois Marier <francois@debian.org> Sun, 23 Mar 2008 16:30:11 +1300
ccache (2.4-13) unstable; urgency=low
* Update CACHEDIR.TAG patch to avoid creating the tag file when the
CCACHE_READONLY environment variable is set. (closes: #464356)
* Mention the GNU-style long options in the manpage
-- Francois Marier <francois@debian.org> Thu, 07 Feb 2008 10:50:42 +1300
ccache (2.4-12) unstable; urgency=low
* Add symlink for gcc 4.3 (closes: #463590)
* Add support for the CACHEDIR.TAG spec, thanks to Karl Chen.
(see http://www.brynosaurus.com/cachedir/)
* Fix hyphens in manpage (lintian notice)
* Bump Standards-Version up to 3.7.3 (no changes)
* Bump debhelper compatibility to 6
-- Francois Marier <francois@debian.org> Sat, 02 Feb 2008 10:37:22 +1300
ccache (2.4-11) unstable; urgency=low
* Add the collab-maint repo to debian/control
-- Francois Marier <francois@debian.org> Tue, 20 Nov 2007 15:26:37 +1300
ccache (2.4-10) unstable; urgency=low
* Document where the patches are from in debian/patches/CREDITS
* debian/rules:
- Fixed "make distclean" lintian warning
- Removed commented-out entries
* Set debhelper compatibility to 5
* Add homepage field in debian/control
* Add symlinks for MinGW (closes: #445782)
* Bump the version to 5 in the debhelper dependency
-- Francois Marier <francois@debian.org> Fri, 19 Oct 2007 16:04:37 +1300
ccache (2.4-9) unstable; urgency=low
* Add a symlink for gcc 4.2 (closes: #431007)
* Fix dependencies when using -o (closes: #217713)
-- Francois Marier <francois@debian.org> Sat, 30 Jun 2007 17:58:44 +1200
ccache (2.4-8) unstable; urgency=low
* Enable zlib compression of the cache by default (closes: #409848).
Thanks to Sami Liedes for suggesting this.
* Disable ccache when profiling (closes: #215849).
Thanks to Ted Percival for the Patch.
* Fix NFS renaming issues and add instructions to the README.
Thanks to John Coiner and instructions.
* Put all patches in debian/patches and apply them at build time.
-- Francois Marier <francois@debian.org> Sun, 20 May 2007 19:42:34 +1200
ccache (2.4-7) unstable; urgency=low
* Use the real compiler when HOME is not set (closes: #396350)
* Include user script under doc/examples (closes: #392435)
Thanks to Behan Webster!
* Add support for GNU --long options (closes: #297126)
-- Francois Marier <francois@debian.org> Sat, 18 Nov 2006 00:50:59 -0500
ccache (2.4-6) unstable; urgency=low
* Include symlinks for gcc 4.1 (closes: #372838)
* Update watch file
-- Francois Marier <francois@debian.org> Tue, 13 Jun 2006 22:17:37 -0400
ccache (2.4-5) unstable; urgency=low
* Document the fact that cross-compiling is supported (closes: #349221)
* Bump Standards-Version up to 3.7.2 (no changes)
-- Francois Marier <francois@debian.org> Sun, 4 Jun 2006 01:20:07 -0400
ccache (2.4-4) unstable; urgency=low
* Mention another way to use ccache in README.Debian (thanks to Benjamin
Drieu for the suggestion) (closes: #267632)
* Update FSF address
* Fix watch file
-- Francois Marier <francois@debian.org> Sat, 26 Nov 2005 00:15:13 -0500
ccache (2.4-3) unstable; urgency=low
* Actually use the configuration flags in debian/rules
* Bump Standards-Version up to 3.6.2 (no changes)
-- Francois Marier <francois@debian.org> Sun, 26 Jun 2005 13:33:19 -0400
ccache (2.4-2) unstable; urgency=low
* Add gcc and g++ symlinks to /usr/lib/ccache (closes: #313490)
* Remove invalid entry from Depends
-- Francois Marier <francois@debian.org> Wed, 15 Jun 2005 20:51:03 -0400
ccache (2.4-1) unstable; urgency=low
* New maintainer (closes: #312867)
* New upstream version: (closes: #273753, #239640)
- New CCACHE_READONLY and CCACHE_TEMPDIR options
- Fixed handling of hard-linked compilers on AIX
- Fixed handling of HOME environment variable (closes: #299880)
- Show cache directory in stats output
* Fix copyright file
* Add 'distcc' to Suggests (closes: #269158)
* Add a note about whitespace in README.Debian (closes: #229116)
* Update rules to add symmlinks for gcc 3.4 & 4.0 (closes: #261177)
* Acknowledge NMUs (closes: #200185, #177129, #174417)
-- Francois Marier <francois@debian.org> Sun, 12 Jun 2005 12:05:34 -0400
ccache (2.3-1.1) unstable; urgency=low
* Non-maintainer upload during BSP
* Re-apply patch for
#200185 ccache: Incorrect symlinks in /usr/lib/ccache
(Closes: #200185)
-- Frank Lichtenheld <djpig@debian.org> Fri, 19 Mar 2004 11:14:50 +0100
ccache (2.3-1) unstable; urgency=low
* New upstream release: obsoletes existing caches.
* Tweak package description in arbitrary way (closes: #181721)
-- Paul Russell <prussell@debian.org> Mon, 29 Sep 2003 02:53:20 +0200
ccache (2.2-2) unstable; urgency=low
* Insert more symlinks in ccache dir (closes: #197468)
-- Paul Russell <prussell@debian.org> Mon, 16 Jun 2003 10:52:50 +0100
ccache (2.2-1) unstable; urgency=low
* New upstream release (closes: #150755)
* Insert more symlinks in ccache dir (closes: #144462)
-- Paul Russell <prussell@debian.org> Mon, 17 Feb 2003 07:19:36 +0100
ccache (2.1.1-2) unstable; urgency=low
* Restored /usr/lib/ccache symlinks (closes: #179393)
* Fixed manpage typo (closes: #179564)
* With thanks to Andreas Rottmann.
-- Paul Russell <prussell@debian.org> Wed, 5 Feb 2003 10:01:10 +0100
ccache (2.1.1-1) unstable; urgency=low
* NMU (with maintainer consent).
* New upstream release (closes: #174417, #177129).
* debian/control:
+ Build-Depend on and use dephelper 4 (DH_COMPAT = 4).
+ Bumped Standards-Version to 3.5.8.
+ No full stop on short package description (fixes linda warning).
* debian/copright:
+ Make lintian feel comfortable; fixes warnings:
- copyright-should-refer-to-common-license-file-for-gpl
- copyright-lists-upstream-authors-with-dh_make-boilerplate
* Built with g++ 3.2 :-).
-- Andreas Rottmann <rotty@debian.org> Thu, 16 Jan 2003 11:42:38 +0100
ccache (1.9-1) unstable; urgency=low
* New upstream release (closes: #144920)
-- Paul Russell <prussell@debian.org> Mon, 13 May 2002 10:01:09 +0200
ccache (1.8-1) unstable; urgency=low
* New upstream release (closes: #145401)
-- Paul Russell <prussell@debian.org> Fri, 3 May 2002 02:26:32 +0200
ccache (1.7-1) unstable; urgency=low
* New upstream release
* Install symlinks in /usr/lib/ccache (closes: #141337)
-- Paul Russell <prussell@debian.org> Wed, 10 Apr 2002 17:51:21 +0200
ccache (1.4-1) unstable; urgency=low
* New upstream release
-- Paul Russell <prussell@debian.org> Wed, 3 Apr 2002 03:41:46 +0200
ccache (1.2-1) unstable; urgency=low
* Initial Release.
-- Paul Russell <prussell@debian.org> Sun, 31 Mar 2002 14:08:57 +0200

1
CCache/debian/compat Normal file
View file

@ -0,0 +1 @@
6

20
CCache/debian/control Normal file
View file

@ -0,0 +1,20 @@
Source: ccache
Section: devel
Priority: optional
Maintainer: Francois Marier <francois@debian.org>
Build-Depends: debhelper (>> 6), autotools-dev, zlib1g-dev
Standards-Version: 3.7.3
Homepage: http://ccache.samba.org
Vcs-Svn: svn://svn.debian.org/svn/collab-maint/deb-maint/ccache/
Vcs-Browser: http://svn.debian.org/wsvn/collab-maint/deb-maint/ccache/
Package: ccache
Architecture: any
Depends: ${shlibs:Depends}
Suggests: distcc
Description: Compiler results cacher, for fast recompiles
ccache is a compiler cache. It speeds up re-compilation of C/C++ code
by caching previous compiles and detecting when the same compile is
being done again.
.
This is similar to, but faster than, the compilercache package.

29
CCache/debian/copyright Normal file
View file

@ -0,0 +1,29 @@
This package was debianized by Paul Russell <prussell@debian.org> on
Sun, 31 Mar 2002 14:08:57 +0200.
It was downloaded from http://ccache.samba.org/ftp/ccache/
The ccache-zlib patch was downloaded from http://www.gustaebel.de/lars/ccache/
Upstream Author: Andrew Tridgell <tridge@samba.org>
Copyright: 2002-2005 Andrew Tridgell <tridge@samba.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA
You are free to distribute this software under the terms of the GNU General
Public License. On Debian systems, the complete text of the GNU General
Public License can be found in /usr/share/common-licenses/GPL file.

3
CCache/debian/dirs Normal file
View file

@ -0,0 +1,3 @@
usr/bin
usr/lib/ccache
usr/share/man/man1

1
CCache/debian/docs Normal file
View file

@ -0,0 +1 @@
README

2
CCache/debian/examples Normal file
View file

@ -0,0 +1,2 @@
debian/update-ccache
manage-cache.sh

View file

@ -0,0 +1,100 @@
--- ccache.c
+++ ccache.c
@@ -836,6 +836,13 @@
{
/* find the real compiler */
find_compiler(argc, argv);
+
+ /* use the real compiler if HOME is not set */
+ if (!cache_dir) {
+ cc_log("Unable to determine home directory\n");
+ cc_log("ccache is disabled\n");
+ failed();
+ }
/* we might be disabled */
if (getenv("CCACHE_DISABLE")) {
@@ -895,6 +902,13 @@
printf("-V print version number\n");
}
+static void check_cache_dir(void)
+{
+ if (!cache_dir) {
+ fatal("Unable to determine home directory");
+ }
+}
+
/* the main program when not doing a compile */
static int ccache_main(int argc, char *argv[])
{
@@ -914,31 +928,37 @@
exit(0);
case 's':
+ check_cache_dir();
stats_summary();
break;
case 'c':
+ check_cache_dir();
cleanup_all(cache_dir);
printf("Cleaned cache\n");
break;
case 'C':
+ check_cache_dir();
wipe_all(cache_dir);
printf("Cleared cache\n");
break;
case 'z':
+ check_cache_dir();
stats_zero();
printf("Statistics cleared\n");
break;
case 'F':
+ check_cache_dir();
v = atoi(optarg);
stats_set_limits(v, -1);
printf("Set cache file limit to %u\n", (unsigned)v);
break;
case 'M':
+ check_cache_dir();
v = value_units(optarg);
stats_set_limits(-1, v);
printf("Set cache size limit to %uk\n", (unsigned)v);
@@ -983,7 +1003,10 @@
cache_dir = getenv("CCACHE_DIR");
if (!cache_dir) {
- x_asprintf(&cache_dir, "%s/.ccache", get_home_directory());
+ const char *home_directory = get_home_directory();
+ if (home_directory) {
+ x_asprintf(&cache_dir, "%s/.ccache", home_directory);
+ }
}
temp_dir = getenv("CCACHE_TEMPDIR");
@@ -1023,7 +1046,7 @@
}
/* make sure the cache dir exists */
- if (create_dir(cache_dir) != 0) {
+ if (cache_dir && (create_dir(cache_dir) != 0)) {
fprintf(stderr,"ccache: failed to create %s (%s)\n",
cache_dir, strerror(errno));
exit(1);
--- util.c
+++ util.c
@@ -448,7 +448,7 @@
}
}
#endif
- fatal("Unable to determine home directory");
+ cc_log("Unable to determine home directory");
return NULL;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,133 @@
Index: ccache.c
===================================================================
--- ccache.c (révision 7695)
+++ ccache.c (copie de travail)
@@ -22,6 +22,7 @@
*/
#include "ccache.h"
+#include <getopt.h>
/* the base cache directory */
char *cache_dir = NULL;
@@ -885,14 +886,14 @@
printf("\tcompiler [compile options] (via symbolic link)\n");
printf("\nOptions:\n");
- printf("-s show statistics summary\n");
- printf("-z zero statistics\n");
- printf("-c run a cache cleanup\n");
- printf("-C clear the cache completely\n");
- printf("-F <maxfiles> set maximum files in cache\n");
- printf("-M <maxsize> set maximum size of cache (use G, M or K)\n");
- printf("-h this help page\n");
- printf("-V print version number\n");
+ printf("-s, --show-stats show statistics summary\n");
+ printf("-z, --zero-stats zero statistics\n");
+ printf("-c, --cleanup run a cache cleanup\n");
+ printf("-C, --clear clear the cache completely\n");
+ printf("-F <n>, --max-files=<n> set maximum files in cache\n");
+ printf("-M <n>, --max-size=<n> set maximum size of cache (use G, M or K)\n");
+ printf("-h, --help this help page\n");
+ printf("-V, --version print version number\n");
}
/* the main program when not doing a compile */
@@ -901,7 +902,21 @@
int c;
size_t v;
- while ((c = getopt(argc, argv, "hszcCF:M:V")) != -1) {
+ static struct option long_options[] =
+ {
+ {"show-stats", no_argument, 0, 's'},
+ {"zero-stats", no_argument, 0, 'z'},
+ {"cleanup", no_argument, 0, 'c'},
+ {"clear", no_argument, 0, 'C'},
+ {"max-files", required_argument, 0, 'F'},
+ {"max-size", required_argument, 0, 'M'},
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'V'},
+ {0, 0, 0, 0}
+ };
+ int option_index = 0;
+
+ while ((c = getopt_long(argc, argv, "hszcCF:M:V", long_options, &option_index)) != -1) {
switch (c) {
case 'V':
printf("ccache version %s\n", CCACHE_VERSION);
Index: ccache.1
===================================================================
--- ccache.1 (révision 7695)
+++ ccache.1 (copie de travail)
@@ -23,14 +23,14 @@
.nf
--s show statistics summary
--z zero statistics
--c run a cache cleanup
--C clear the cache completely
--F <maxfiles> set maximum files in cache
--M <maxsize> set maximum size of cache (use G, M or K)
--h this help page
--V print version number
+\-s, \-\-show-stats show statistics summary
+\-z, \-\-zero-stats zero statistics
+\-c, \-\-cleanup run a cache cleanup
+\-C, \-\-clear clear the cache completely
+\-F <n>, \-\-max-files=<n> set maximum files in cache
+\-M <n>, \-\-max-size=<n> set maximum size of cache (use G, M or K)
+\-h, \-\-help this help page
+\-V, \-\-version print version number
.fi
@@ -43,22 +43,22 @@
normal compiler options apply and you should refer to your compilers
documentation\&.
.PP
-.IP "\fB-h\fP"
+.IP "\fB-h, --help\fP"
Print a options summary page
.IP
-.IP "\fB-s\fP"
+.IP "\fB-s, --show-stats\fP"
Print the current statistics summary for the cache\&. The
statistics are stored spread across the subdirectories of the
cache\&. Using "ccache -s" adds up the statistics across all
subdirectories and prints the totals\&.
.IP
-.IP "\fB-z\fP"
+.IP "\fB-z, --zero-stats\fP"
Zero the cache statistics\&.
.IP
-.IP "\fB-V\fP"
+.IP "\fB-V, --version\fP"
Print the ccache version number
.IP
-.IP "\fB-c\fP"
+.IP "\fB-c, --cleanup\fP"
Clean the cache and re-calculate the cache file count and
size totals\&. Normally the -c option should not be necessary as ccache
keeps the cache below the specified limits at runtime and keeps
@@ -66,16 +66,16 @@
if you manually modify the cache contents or believe that the cache
size statistics may be inaccurate\&.
.IP
-.IP "\fB-C\fP"
+.IP "\fB-C, --clear\fP"
Clear the entire cache, removing all cached files\&.
.IP
-.IP "\fB-F maxfiles\fP"
+.IP "\fB-F <maxfiles>, --max-files=<maxfiles>\fP"
This sets the maximum number of files allowed in
the cache\&. The value is stored inside the cache directory and applies
to all future compiles\&. Due to the way the value is stored the actual
value used is always rounded down to the nearest multiple of 16\&.
.IP
-.IP "\fB-M maxsize\fP"
+.IP "\fB-M <maxsize>, --max-size=<maxsize>\fP"
This sets the maximum cache size\&. You can specify
a value in gigabytes, megabytes or kilobytes by appending a G, M or K
to the value\&. The default is gigabytes\&. The actual value stored is

View file

@ -0,0 +1,13 @@
diff -ru ccache-2.4/ccache.c ccache-2.4-tp/ccache.c
--- ccache.c 2007-05-20 03:14:19.000000000 +1000
+++ ccache.c 2007-05-20 03:17:54.000000000 +1000
@@ -641,6 +641,9 @@
/* these are too hard */
if (strcmp(argv[i], "-fbranch-probabilities")==0 ||
+ strcmp(argv[i], "-fprofile-arcs") == 0 ||
+ strcmp(argv[i], "-ftest-coverage") == 0 ||
+ strcmp(argv[i], "--coverage") == 0 ||
strcmp(argv[i], "-M") == 0 ||
strcmp(argv[i], "-MM") == 0 ||
strcmp(argv[i], "-x") == 0) {

View file

@ -0,0 +1,45 @@
--- ccache.1.orig 2007-05-20 17:30:57.000000000 +1200
+++ ccache.1 2007-05-20 17:31:27.000000000 +1200
@@ -367,12 +367,6 @@
.IP o
ccache avoids a double call to cpp on a cache miss
.PP
-.SH "BUGS"
-.PP
-When the cache is stored on an NFS filesystem, the filesystem must be
-exported with the \fBno_subtree_check\fP option to make renames between
-directories reliable\&.
-.PP
.SH "CREDITS"
.PP
Thanks to the following people for their contributions to ccache
--- util.c.patched 2007-05-20 18:19:11.000000000 +1200
+++ util.c 2007-05-20 18:20:55.000000000 +1200
@@ -58,9 +58,26 @@
}
}
+static int safe_rename(const char* oldpath, const char* newpath)
+{
+ /* safe_rename is for creating entries in the cache.
+
+ Works like rename(), but it never overwrites an existing
+ cache entry. This avoids corruption on NFS. */
+ int status = link( oldpath, newpath );
+ if( status == 0 || errno == EEXIST )
+ {
+ return unlink( oldpath );
+ }
+ else
+ {
+ return -1;
+ }
+}
+
/* move a file using rename */
int move_file(const char *src, const char *dest) {
- return rename(src, dest);
+ return safe_rename(src, dest);
}
/* copy a file - used when hard links don't work

View file

@ -0,0 +1,77 @@
--- ccache.c Mon Sep 13 11:38:30 2004
+++ ccache.c Thu Jun 21 22:17:32 2007
@@ -627,6 +627,13 @@ static void process_args(int argc, char
int found_S_opt = 0;
struct stat st;
char *e;
+ /* is gcc being asked to output dependencies? */
+ int generating_dependencies = 0;
+ /* is the dependency makefile name overridden with -MF? */
+ int dependency_filename_specified = 0;
+ /* is the dependency makefile target name specified with -MQ or -MF? */
+ int dependency_target_specified = 0;
+
stripped_args = args_init(0, NULL);
@@ -702,6 +709,18 @@ static void process_args(int argc, char
continue;
}
+ /* These options require special handling, because they
+ behave differently with gcc -E, when the output
+ file is not specified. */
+
+ if (strcmp(argv[i], "-MD") == 0 || strcmp(argv[i], "-MMD") == 0) {
+ generating_dependencies = 1;
+ } else if (strcmp(argv[i], "-MF") == 0) {
+ dependency_filename_specified = 1;
+ } else if (strcmp(argv[i], "-MQ") == 0 || strcmp(argv[i], "-MT") == 0) {
+ dependency_target_specified = 1;
+ }
+
/* options that take an argument */
{
const char *opts[] = {"-I", "-include", "-imacros", "-iprefix",
@@ -812,6 +831,41 @@ static void process_args(int argc, char
}
p[1] = found_S_opt ? 's' : 'o';
p[2] = 0;
+ }
+
+ /* If dependencies are generated, configure the preprocessor */
+
+ if (generating_dependencies && output_file) {
+ if (!dependency_filename_specified) {
+ char *default_depfile_name = x_strdup(output_file);
+ char *p = strrchr(default_depfile_name, '.');
+
+ if (p) {
+ if (strlen(p) < 2) {
+ stats_update(STATS_ARGS);
+ failed();
+ return;
+ }
+ *p = 0;
+ }
+ else {
+ int len = p - default_depfile_name;
+
+ p = x_malloc(len + 3);
+ strncpy(default_depfile_name, p, len - 1);
+ free(default_depfile_name);
+ default_depfile_name = p;
+ }
+
+ strcat(default_depfile_name, ".d");
+ args_add(stripped_args, "-MF");
+ args_add(stripped_args, default_depfile_name);
+ }
+
+ if (!dependency_target_specified) {
+ args_add(stripped_args, "-MT");
+ args_add(stripped_args, output_file);
+ }
}
/* cope with -o /dev/null */

View file

@ -0,0 +1,75 @@
Index: ccache.c
===================================================================
--- ccache.c (révision 7695)
+++ ccache.c (copie de travail)
@@ -1029,6 +1029,14 @@
exit(1);
}
+ if (!getenv("CCACHE_READONLY")) {
+ if (create_cachedirtag(cache_dir) != 0) {
+ fprintf(stderr,"ccache: failed to create %s/CACHEDIR.TAG (%s)\n",
+ cache_dir, strerror(errno));
+ exit(1);
+ }
+ }
+
ccache(argc, argv);
return 1;
}
Index: ccache.h
===================================================================
--- ccache.h (révision 7695)
+++ ccache.h (copie de travail)
@@ -81,6 +81,7 @@
int copy_file(const char *src, const char *dest);
int create_dir(const char *dir);
+int create_cachedirtag(const char *dir);
void x_asprintf(char **ptr, const char *format, ...);
char *x_strdup(const char *s);
void *x_realloc(void *ptr, size_t size);
Index: util.c
===================================================================
--- util.c (révision 7695)
+++ util.c (copie de travail)
@@ -138,6 +138,39 @@
return 0;
}
+char const CACHEDIR_TAG[] =
+ "Signature: 8a477f597d28d172789f06886806bc55\n"
+ "# This file is a cache directory tag created by ccache.\n"
+ "# For information about cache directory tags, see:\n"
+ "# http://www.brynosaurus.com/cachedir/\n";
+
+int create_cachedirtag(const char *dir)
+{
+ char *filename;
+ struct stat st;
+ FILE *f;
+ x_asprintf(&filename, "%s/CACHEDIR.TAG", dir);
+ if (stat(filename, &st) == 0) {
+ if (S_ISREG(st.st_mode)) {
+ goto success;
+ }
+ errno = EEXIST;
+ goto error;
+ }
+ f = fopen(filename, "w");
+ if (!f) goto error;
+ if (fwrite(CACHEDIR_TAG, sizeof(CACHEDIR_TAG)-1, 1, f) != 1) {
+ goto error;
+ }
+ if (fclose(f)) goto error;
+success:
+ free(filename);
+ return 0;
+error:
+ free(filename);
+ return 1;
+}
+
/*
this is like asprintf() but dies if the malloc fails
note that we use vsnprintf in a rather poor way to make this more portable

View file

@ -0,0 +1,89 @@
Index: ccache.1
===================================================================
--- ccache.1 (révision 7695)
+++ ccache.1 (copie de travail)
@@ -49,7 +49,7 @@
.IP "\fB-s\fP"
Print the current statistics summary for the cache\&. The
statistics are stored spread across the subdirectories of the
-cache\&. Using "ccache -s" adds up the statistics across all
+cache\&. Using "ccache \-s" adds up the statistics across all
subdirectories and prints the totals\&.
.IP
.IP "\fB-z\fP"
@@ -60,7 +60,7 @@
.IP
.IP "\fB-c\fP"
Clean the cache and re-calculate the cache file count and
-size totals\&. Normally the -c option should not be necessary as ccache
+size totals\&. Normally the \-c option should not be necessary as ccache
keeps the cache below the specified limits at runtime and keeps
statistics up to date on each compile\&. This option is mostly useful
if you manually modify the cache contents or believe that the cache
@@ -100,9 +100,9 @@
cp ccache /usr/local/bin/
- ln -s /usr/local/bin/ccache /usr/local/bin/gcc
- ln -s /usr/local/bin/ccache /usr/local/bin/g++
- ln -s /usr/local/bin/ccache /usr/local/bin/cc
+ ln \-s /usr/local/bin/ccache /usr/local/bin/gcc
+ ln \-s /usr/local/bin/ccache /usr/local/bin/g++
+ ln \-s /usr/local/bin/ccache /usr/local/bin/cc
.fi
@@ -118,7 +118,7 @@
.PP
When run as a compiler front end ccache usually just takes the same
command line options as the compiler you are using\&. The only exception
-to this is the option \&'--ccache-skip\&'\&. That option can be used to tell
+to this is the option \&'\-\-ccache-skip\&'\&. That option can be used to tell
ccache that the next option is definitely not a input filename, and
should be passed along to the compiler as-is\&.
.PP
@@ -128,7 +128,7 @@
of the resulting object file (among other things)\&. The heuristic
ccache uses in this parse is that any string on the command line that
exists as a file is treated as an input file name (usually a C
-file)\&. By using --ccache-skip you can force an option to not be
+file)\&. By using \-\-ccache-skip you can force an option to not be
treated as an input file name and instead be passed along to the
compiler as a command line option\&.
.PP
@@ -238,7 +238,7 @@
.IP "\fBCCACHE_UNIFY\fP"
If you set the environment variable CCACHE_UNIFY
then ccache will use the C/C++ unifier when hashing the pre-processor
-output if -g is not used in the compile\&. The unifier is slower than a
+output if \-g is not used in the compile\&. The unifier is slower than a
normal hash, so setting this environment variable loses a little bit
of speed, but it means that ccache can take advantage of not
recompiling when the changes to the source code consist of
@@ -262,7 +262,7 @@
.PP
By default ccache has a one gigabyte limit on the cache size and no
maximum number of files\&. You can set a different limit using the
-"ccache -M" and "ccache -F" options, which set the size and number of
+"ccache \-M" and "ccache \-F" options, which set the size and number of
files limits\&.
.PP
When these limits are reached ccache will reduce the cache to 20%
@@ -276,7 +276,7 @@
that it is the same code by forming a hash of:
.PP
.IP o
-the pre-processor output from running the compiler with -E
+the pre-processor output from running the compiler with \-E
.IP o
the command line options
.IP o
@@ -331,7 +331,7 @@
.IP o
Make sure that the setgid bit is set on all directories in the
cache\&. This tells the filesystem to inherit group ownership for new
-directories\&. The command "chmod g+s `find $CCACHE_DIR -type d`" might
+directories\&. The command "chmod g+s `find $CCACHE_DIR \-type d`" might
be useful for this\&.
.PP
.SH "HISTORY"

View file

@ -0,0 +1,11 @@
--- Makefile.in.orig 2008-03-23 17:01:19.000000000 +1300
+++ Makefile.in 2008-03-23 17:03:03.000000000 +1300
@@ -21,7 +21,7 @@
docs: ccache.1 web/ccache-man.html
ccache$(EXEEXT): $(OBJS) $(HEADERS)
- $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
ccache.1: ccache.yo
-yodl2man -o ccache.1 ccache.yo

View file

@ -0,0 +1,23 @@
--- ccache.c (révision 8804)
+++ ccache.c (copie de travail)
@@ -481,6 +481,9 @@
return;
}
+ /* update timestamps for LRU cleanup
+ also gives output_file a sensible mtime when hard-linking (for make) */
+ utime(hashname, NULL);
utime(stderr_file, NULL);
if (strcmp(output_file, "/dev/null") == 0) {
@@ -513,10 +516,6 @@
failed();
}
}
- if (ret == 0) {
- /* update the mtime on the file so that make doesn't get confused */
- utime(output_file, NULL);
- }
/* get rid of the intermediate preprocessor file */
if (i_tmpfile) {

View file

@ -0,0 +1,85 @@
--- ccache.c 2004-09-13 03:38:30.000000000 -0700
+++ ccache.c 2006-06-09 16:29:16.695117780 -0700
@@ -481,8 +481,13 @@
/* update timestamps for LRU cleanup
also gives output_file a sensible mtime when hard-linking (for make) */
+#ifdef HAVE_UTIMES
+ utimes(hashname, NULL);
+ utimes(stderr_file, NULL);
+#else
utime(hashname, NULL);
utime(stderr_file, NULL);
+#endif
if (strcmp(output_file, "/dev/null") == 0) {
ret = 0;
--- ccache.h 2004-09-13 03:38:30.000000000 -0700
+++ ccache.h 2006-06-09 16:28:16.601658626 -0700
@@ -22,6 +22,9 @@
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
#define STATUS_NOTFOUND 3
#define STATUS_FATAL 4
--- config.h.in 2003-09-27 21:48:17.000000000 -0700
+++ config.h.in 2006-06-09 16:25:43.000000000 -0700
@@ -19,6 +19,9 @@
/* Define to 1 if you have the `gethostname' function. */
#undef HAVE_GETHOSTNAME
+/* Define to 1 if you have the `getpwuid' function. */
+#undef HAVE_GETPWUID
+
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@@ -31,6 +34,9 @@
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
@@ -60,6 +66,9 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
@@ -69,6 +78,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the `utimes' function. */
+#undef HAVE_UTIMES
+
/* Define to 1 if you have the `vasprintf' function. */
#undef HAVE_VASPRINTF
--- configure.in 2004-09-13 03:38:30.000000000 -0700
+++ configure.in 2006-06-09 16:25:15.541288184 -0700
@@ -27,10 +27,11 @@
AC_HEADER_TIME
AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(ctype.h strings.h stdlib.h string.h pwd.h)
+AC_CHECK_HEADERS(ctype.h strings.h stdlib.h string.h pwd.h sys/time.h)
AC_CHECK_FUNCS(realpath snprintf vsnprintf vasprintf asprintf mkstemp)
AC_CHECK_FUNCS(gethostname getpwuid)
+AC_CHECK_FUNCS(utimes)
AC_CACHE_CHECK([for compar_fn_t in stdlib.h],ccache_cv_COMPAR_FN_T, [
AC_TRY_COMPILE(

View file

@ -0,0 +1,83 @@
--- stats.c (révision 8804)
+++ stats.c (copie de travail)
@@ -286,7 +286,7 @@
/* set the per directory limits */
-void stats_set_limits(long maxfiles, long maxsize)
+int stats_set_limits(long maxfiles, long maxsize)
{
int dir;
unsigned counters[STATS_END];
@@ -298,7 +298,9 @@
maxsize /= 16;
}
- create_dir(cache_dir);
+ if (create_dir(cache_dir) != 0) {
+ return 1;
+ }
/* set the limits in each directory */
for (dir=0;dir<=0xF;dir++) {
@@ -306,7 +308,9 @@
int fd;
x_asprintf(&cdir, "%s/%1x", cache_dir, dir);
- create_dir(cdir);
+ if (create_dir(cdir) != 0) {
+ return 1;
+ }
x_asprintf(&fname, "%s/stats", cdir);
free(cdir);
@@ -326,6 +330,8 @@
}
free(fname);
}
+
+ return 0;
}
/* set the per directory sizes */
--- ccache.c (révision 8804)
+++ ccache.c (copie de travail)
@@ -935,15 +934,23 @@
case 'F':
check_cache_dir();
v = atoi(optarg);
- stats_set_limits(v, -1);
- printf("Set cache file limit to %u\n", (unsigned)v);
+ if (stats_set_limits(v, -1) == 0) {
+ printf("Set cache file limit to %u\n", (unsigned)v);
+ } else {
+ printf("Could not set cache file limit.\n");
+ exit(1);
+ }
break;
case 'M':
check_cache_dir();
v = value_units(optarg);
- stats_set_limits(-1, v);
- printf("Set cache size limit to %uk\n", (unsigned)v);
+ if (stats_set_limits(-1, v) == 0) {
+ printf("Set cache size limit to %uk\n", (unsigned)v);
+ } else {
+ printf("Could not set cache size limit.\n");
+ exit(1);
+ }
break;
default:
--- ccache.h (révision 8804)
+++ ccache.h (copie de travail)
@@ -101,7 +101,7 @@
void stats_summary(void);
void stats_tocache(size_t size);
void stats_read(const char *stats_file, unsigned counters[STATS_END]);
-void stats_set_limits(long maxfiles, long maxsize);
+int stats_set_limits(long maxfiles, long maxsize);
size_t value_units(const char *s);
void display_size(unsigned v);
void stats_set_sizes(const char *dir, size_t num_files, size_t total_size);

View file

@ -0,0 +1,33 @@
--- web/index.html~ 2004-09-13 13:38:30.000000000 +0300
+++ web/index.html 2004-09-26 01:04:38.458008118 +0300
@@ -29,10 +29,10 @@
<li>fixed handling of HOME environment variable
</ul>
-See the <a href="/ccache/ccache-man.html">manual page</a> for details
+See the <a href="ccache-man.html">manual page</a> for details
on the new options.<p>
-You can get this release from the <a href="/ftp/ccache/">download directory</a>
+You can get this release from the <a href="http://ccache.samba.org/ftp/ccache/">download directory</a>
<p>NOTE! This release changes the hash input slighly, so you will
probably find that you will not get any hits against your existing
@@ -87,7 +87,7 @@
<h2>Documentation</h2>
-See the <a href="/ccache/ccache-man.html">manual page</a>
+See the <a href="ccache-man.html">manual page</a>
<h2>Performance</h2>
@@ -116,7 +116,7 @@
<h2>Download</h2>
You can download the latest release from the <a
-href="/ftp/ccache/">download directory</a>.<p>
+href="http://ccache.samba.org/ftp/ccache/">download directory</a>.<p>
For the bleeding edge, you can fetch ccache via CVS or
rsync. To fetch via cvs use the following command:

View file

@ -0,0 +1,48 @@
Index: ccache.1
===================================================================
RCS file: /cvsroot/ccache/ccache.1,v
retrieving revision 1.26
diff -u -r1.26 ccache.1
--- ccache.1 24 Nov 2005 21:10:08 -0000 1.26
+++ ccache.1 21 Jul 2007 21:03:32 -0000
@@ -330,7 +330,7 @@
.IP o
Use the same \fBCCACHE_DIR\fP environment variable setting
.IP o
-Set the \fBCCACHE_NOLINK\fP environment variable
+Unset the \fBCCACHE_HARDLINK\fP environment variable
.IP o
Make sure everyone sets the CCACHE_UMASK environment variable
to 002, this ensures that cached files are accessible to everyone in
Index: ccache.yo
===================================================================
RCS file: /cvsroot/ccache/ccache.yo,v
retrieving revision 1.27
diff -u -r1.27 ccache.yo
--- ccache.yo 24 Nov 2005 21:54:09 -0000 1.27
+++ ccache.yo 21 Jul 2007 21:03:32 -0000
@@ -289,7 +289,7 @@
itemize(
it() Use the same bf(CCACHE_DIR) environment variable setting
- it() Set the bf(CCACHE_NOLINK) environment variable
+ it() Unset the bf(CCACHE_HARDLINK) environment variable
it() Make sure everyone sets the CCACHE_UMASK environment variable
to 002, this ensures that cached files are accessible to everyone in
the group.
Index: web/ccache-man.html
===================================================================
RCS file: /cvsroot/ccache/web/ccache-man.html,v
retrieving revision 1.25
diff -u -r1.25 ccache-man.html
--- web/ccache-man.html 13 Sep 2004 10:38:17 -0000 1.25
+++ web/ccache-man.html 21 Jul 2007 21:03:32 -0000
@@ -256,7 +256,7 @@
following conditions need to be met:
<p><ul>
<li > Use the same <strong>CCACHE_DIR</strong> environment variable setting
- <li > Set the <strong>CCACHE_NOLINK</strong> environment variable
+ <li > Unset the <strong>CCACHE_HARDLINK</strong> environment variable
<li > Make sure everyone sets the CCACHE_UMASK environment variable
to 002, this ensures that cached files are accessible to everyone in
the group.

View file

@ -0,0 +1,47 @@
01_no_home.diff:
Francois Marier <francois@debian.org>
Made especially for the Debian package.
02_ccache_compressed.diff:
Lars Gustäbel <lars@gustaebel.de>
http://www.gustaebel.de/lars/ccache/ (downloaded on 2007-05-20)
03_long_options.diff:
Francois Marier <francois@debian.org>
Made especially for the Debian package.
04_ignore_profile.diff:
Ted Percival <ted@midg3t.net>
http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=20;filename=ccache-profile.patch;att=1;bug=215849
05_nfs_fix.diff:
John Coiner <john.coiner@amd.com>
http://lists.samba.org/archive/ccache/2007q1/000265.html
06_md.diff:
Andrea Bittau <a.bittau@cs.ucl.ac.uk>
http://darkircop.org/ccache/ccache-2.4-md.patch (downloaded on 2007-06-30)
07_cachedirtag.diff:
Karl Chen <quarl@cs.berkeley.edu>
http://lists.samba.org/archive/ccache/2008q1/000316.html (downloaded on 2008-02-02)
08_manpage_hyphens.diff:
Francois Marier <francois@debian.org>
Made especially for the Debian package.
09_respect_ldflags.diff:
Lisa Seelye <lisa@gentoo.org>
http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-util/ccache/files/ccache-2.4-respectflags.patch?rev=1.1&view=markup
10_lru_cleanup.diff:
RW <fbsd06@mlists.homeunix.com>
http://lists.samba.org/archive/ccache/2008q2/000339.html (downloaded on 2008-04-11)
11_utimes.diff:
Robin H. Johnson <robbat2@gentoo.org>
http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-util/ccache/files/ccache-2.4-utimes.patch?rev=1.1&view=markup
12_cachesize_permissions.diff:
Francois Marier <francois@debian.org>
Made especially for the Debian package to fix http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=332527

141
CCache/debian/rules Normal file
View file

@ -0,0 +1,141 @@
#!/usr/bin/make -f
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 to 1999 by Joey Hess.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
export DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
export DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE))
confflags += --build $(DEB_HOST_GNU_TYPE)
else
confflags += --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE)
endif
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
CFLAGS += -g
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
config.status: configure
dh_testdir
# Apply Debian specific patches
cp $(CURDIR)/ccache.c $(CURDIR)/ccache.c.unpatched
cp $(CURDIR)/util.c $(CURDIR)/util.c.unpatched
cp $(CURDIR)/ccache.1 $(CURDIR)/ccache.1.unpatched
cp $(CURDIR)/ccache.h $(CURDIR)/ccache.h.unpatched
cp $(CURDIR)/ccache.yo $(CURDIR)/ccache.yo.unpatched
cp $(CURDIR)/config.h.in $(CURDIR)/config.h.in.unpatched
cp $(CURDIR)/configure $(CURDIR)/configure.unpatched
cp $(CURDIR)/configure.in $(CURDIR)/configure.in.unpatched
cp $(CURDIR)/Makefile.in $(CURDIR)/Makefile.in.unpatched
if test ! -f patch-stamp; then \
for patch in $(CURDIR)/debian/patches/*.diff ;\
do \
echo APPLYING PATCH\: $${patch##*/};\
patch -p0 < $$patch ;\
done ;\
touch patch-stamp ;\
fi
chmod +x $(CURDIR)/manage-cache.sh
./configure $(confflags) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
build: build-stamp
build-stamp: config.status
dh_testdir
$(MAKE)
touch build-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp
# Unapply patches
-test -r $(CURDIR)/ccache.c.unpatched && mv $(CURDIR)/ccache.c.unpatched $(CURDIR)/ccache.c
-test -r $(CURDIR)/util.c.unpatched && mv $(CURDIR)/util.c.unpatched $(CURDIR)/util.c
-test -r $(CURDIR)/ccache.1.unpatched && mv $(CURDIR)/ccache.1.unpatched $(CURDIR)/ccache.1
-test -r $(CURDIR)/ccache.h.unpatched && mv $(CURDIR)/ccache.h.unpatched $(CURDIR)/ccache.h
-test -r $(CURDIR)/ccache.yo.unpatched && mv $(CURDIR)/ccache.yo.unpatched $(CURDIR)/ccache.yo
-test -r $(CURDIR)/config.h.in.unpatched && mv $(CURDIR)/config.h.in.unpatched $(CURDIR)/config.h.in
-test -r $(CURDIR)/configure.unpatched && mv $(CURDIR)/configure.unpatched $(CURDIR)/configure
-test -r $(CURDIR)/configure.in.unpatched && mv $(CURDIR)/configure.in.unpatched $(CURDIR)/configure.in
-test -r $(CURDIR)/Makefile.in.unpatched && mv $(CURDIR)/Makefile.in.unpatched $(CURDIR)/Makefile.in
-rm -f $(CURDIR)/manage-cache.sh
-rm -f patch-stamp
[ ! -f Makefile ] || $(MAKE) distclean
dh_clean
# Update config.sub and config.guess
-test -r /usr/share/misc/config.sub && \
cp -f /usr/share/misc/config.sub config.sub
-test -r /usr/share/misc/config.guess && \
cp -f /usr/share/misc/config.guess config.guess
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/ccache.
$(MAKE) install prefix=$(CURDIR)/debian/ccache/usr
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/$(DEB_BUILD_GNU_TYPE)-gcc
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/$(DEB_BUILD_GNU_TYPE)-g++
set -e; for ver in 2.95 3.0 3.2 3.3 3.4 4.0 4.1 4.2 4.3; do \
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/$(DEB_BUILD_GNU_TYPE)-gcc-$$ver; \
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/gcc-$$ver; \
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/$(DEB_BUILD_GNU_TYPE)-g++-$$ver; \
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/g++-$$ver; \
done
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/cc
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/c++
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/gcc
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/g++
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/i586-mingw32msvc-c++
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/i586-mingw32msvc-cc
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/i586-mingw32msvc-g++
ln -s ../../bin/ccache $(CURDIR)/debian/ccache/usr/lib/ccache/i586-mingw32msvc-gcc
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installdocs
dh_installexamples
dh_installmenu
dh_installcron
dh_installman
dh_installinfo
dh_installchangelogs
dh_link
dh_strip
dh_compress
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

View file

@ -0,0 +1,43 @@
#!/bin/sh
#
# Update compiler links to ccache (in /usr/local/bin)
#
# The idea is that /usr/local/bin is ahead of /usr/bin in your PATH, so adding
# the link /usr/local/bin/cc -> /usr/bin/ccache means that it is run instead of
# /usr/bin/cc
#
# Written by: Behan Webster <behanw@websterwood.com>
#
DIRECTORY=/usr/local/bin
CCACHE=/usr/bin/ccache
CCDIR=/usr/lib/ccache
usage() {
echo "Usage: `basename $0` [--directory <dir>] [--remove]"
exit 0
}
while [ $# -gt 0 ] ; do
case "$1" in
-d*|--d*|--directory) DIRECTORY=$2; shift; shift;;
-h*|--h*|--help) usage;;
-r*|--r*|--remove) REMOVE=1; shift;;
-t*|--t*|--test) TEST=echo; shift;;
esac
done
for FILE in `cd $CCDIR; ls` ; do
LINK=$DIRECTORY/$FILE
if [ -z "$REMOVE" ] ; then
# Add link
$TEST ln -fs $CCACHE $LINK
else
# Remove link
if [ -L "$LINK" ] ; then
$TEST rm -f $LINK
fi
fi
done
# vim: sw=4 ts=4

2
CCache/debian/watch Normal file
View file

@ -0,0 +1,2 @@
version=2
http://samba.org/ftp/ccache/ccache-(.*)\.tar\.gz

286
CCache/execute.c Normal file
View file

@ -0,0 +1,286 @@
/*
Copyright (C) Andrew Tridgell 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "ccache.h"
#ifdef _WIN32
char *argvtos(char **argv)
{
int i, len;
char *ptr, *str;
for (i = 0, len = 0; argv[i]; i++) {
len += strlen(argv[i]) + 3;
}
str = ptr = (char *)malloc(len + 1);
if (str == NULL)
return NULL;
for (i = 0; argv[i]; i++) {
len = strlen(argv[i]);
*ptr++ = '"';
memcpy(ptr, argv[i], len);
ptr += len;
*ptr++ = '"';
*ptr++ = ' ';
}
*ptr = 0;
return str;
}
#endif
/*
execute a compiler backend, capturing all output to the given paths
the full path to the compiler to run is in argv[0]
*/
int execute(char **argv,
const char *path_stdout,
const char *path_stderr)
{
#ifdef _WIN32
#if 1
PROCESS_INFORMATION pinfo;
STARTUPINFO sinfo;
BOOL ret;
DWORD exitcode;
char *args;
HANDLE fd_out, fd_err;
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
/* TODO: needs moving after possible exit() below, but before stdout is redirected */
if (ccache_verbose) {
display_execute_args(argv);
}
fd_out = CreateFile(path_stdout, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (fd_out == INVALID_HANDLE_VALUE) {
return STATUS_NOCACHE;
}
fd_err = CreateFile(path_stderr, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (fd_err == INVALID_HANDLE_VALUE) {
return STATUS_NOCACHE;
}
ZeroMemory(&pinfo, sizeof(PROCESS_INFORMATION));
ZeroMemory(&sinfo, sizeof(STARTUPINFO));
sinfo.cb = sizeof(STARTUPINFO);
sinfo.hStdError = fd_err;
sinfo.hStdOutput = fd_out;
sinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
sinfo.dwFlags |= STARTF_USESTDHANDLES;
args = argvtos(argv);
ret = CreateProcessA(argv[0], args, NULL, NULL, TRUE, 0, NULL, NULL,
&sinfo, &pinfo);
free(args);
CloseHandle(fd_out);
CloseHandle(fd_err);
if (ret == 0)
return -1;
WaitForSingleObject(pinfo.hProcess, INFINITE);
GetExitCodeProcess(pinfo.hProcess, &exitcode);
CloseHandle(pinfo.hProcess);
CloseHandle(pinfo.hThread);
return exitcode;
#else /* possibly slightly faster */
/* needs fixing to quote commandline options to handle spaces in CCACHE_DIR etc */
int status = -2;
int fd, std_od = -1, std_ed = -1;
/* TODO: needs moving after possible exit() below, but before stdout is redirected */
if (ccache_verbose) {
display_execute_args(argv);
}
unlink(path_stdout);
std_od = _dup(1);
fd = _open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
if (fd == -1) {
exit(STATUS_NOCACHE);
}
_dup2(fd, 1);
_close(fd);
unlink(path_stderr);
fd = _open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
std_ed = _dup(2);
if (fd == -1) {
exit(STATUS_NOCACHE);
}
_dup2(fd, 2);
_close(fd);
/* Spawn process (_exec* familly doesn't return) */
status = _spawnv(_P_WAIT, argv[0], (const char **)argv);
/* Restore descriptors */
if (std_od != -1) _dup2(std_od, 1);
if (std_ed != -1) _dup2(std_ed, 2);
_flushall();
return (status>0);
#endif
#else
pid_t pid;
int status;
pid = fork();
if (pid == -1) fatal("Failed to fork");
if (pid == 0) {
int fd;
/* TODO: needs moving after possible exit() below, but before stdout is redirected */
if (ccache_verbose) {
display_execute_args(argv);
}
unlink(path_stdout);
fd = open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
if (fd == -1) {
exit(STATUS_NOCACHE);
}
dup2(fd, 1);
close(fd);
unlink(path_stderr);
fd = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
if (fd == -1) {
exit(STATUS_NOCACHE);
}
dup2(fd, 2);
close(fd);
exit(execv(argv[0], argv));
}
if (waitpid(pid, &status, 0) != pid) {
fatal("waitpid failed");
}
if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) {
return -1;
}
return WEXITSTATUS(status);
#endif
}
/*
find an executable by name in $PATH. Exclude any that are links to exclude_name
*/
char *find_executable(const char *name, const char *exclude_name)
{
#if _WIN32
(void)exclude_name;
DWORD ret;
char namebuf[MAX_PATH];
ret = SearchPathA(getenv("CCACHE_PATH"), name, ".exe",
sizeof(namebuf), namebuf, NULL);
if (ret != 0) {
return x_strdup(namebuf);
}
return NULL;
#else
char *path;
char *tok;
struct stat st1, st2;
if (*name == '/') {
return x_strdup(name);
}
path = getenv("CCACHE_PATH");
if (!path) {
path = getenv("PATH");
}
if (!path) {
cc_log("no PATH variable!?\n");
stats_update(STATS_ENVIRONMMENT);
return NULL;
}
path = x_strdup(path);
/* search the path looking for the first compiler of the right name
that isn't us */
for (tok=strtok(path,":"); tok; tok = strtok(NULL, ":")) {
char *fname;
x_asprintf(&fname, "%s/%s", tok, name);
/* look for a normal executable file */
if (access(fname, X_OK) == 0 &&
lstat(fname, &st1) == 0 &&
stat(fname, &st2) == 0 &&
S_ISREG(st2.st_mode)) {
/* if its a symlink then ensure it doesn't
point at something called exclude_name */
if (S_ISLNK(st1.st_mode)) {
char *buf = x_realpath(fname);
if (buf) {
char *p = str_basename(buf);
if (strcmp(p, exclude_name) == 0) {
/* its a link to "ccache" ! */
free(p);
free(buf);
continue;
}
free(buf);
free(p);
}
}
/* found it! */
free(path);
return fname;
}
free(fname);
}
return NULL;
#endif
}
void display_execute_args(char **argv)
{
if (argv) {
printf("ccache executing: ");
while (*argv) {
printf("%s ", *argv);
++argv;
}
printf("\n");
fflush(stdout);
}
}

80
CCache/hash.c Normal file
View file

@ -0,0 +1,80 @@
/*
Copyright (C) Andrew Tridgell 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
simple front-end functions to mdfour code
*/
#include "ccache.h"
static struct mdfour md;
void hash_buffer(const char *s, int len)
{
mdfour_update(&md, (unsigned char *)s, len);
}
void hash_start(void)
{
mdfour_begin(&md);
}
void hash_string(const char *s)
{
hash_buffer(s, strlen(s));
}
void hash_int(int x)
{
hash_buffer((char *)&x, sizeof(x));
}
/* add contents of a file to the hash */
void hash_file(const char *fname)
{
char buf[1024];
int fd, n;
fd = open(fname, O_RDONLY|O_BINARY);
if (fd == -1) {
cc_log("Failed to open %s\n", fname);
fatal("hash_file");
}
while ((n = read(fd, buf, sizeof(buf))) > 0) {
hash_buffer(buf, n);
}
close(fd);
}
/* return the hash result as a static string */
char *hash_result(void)
{
unsigned char sum[16];
static char ret[53];
int i;
hash_buffer(NULL, 0);
mdfour_result(&md, sum);
for (i=0;i<16;i++) {
sprintf(&ret[i*2], "%02x", (unsigned)sum[i]);
}
sprintf(&ret[i*2], "-%u", (unsigned)md.totalN);
return ret;
}

238
CCache/install-sh Executable file
View file

@ -0,0 +1,238 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

284
CCache/mdfour.c Normal file
View file

@ -0,0 +1,284 @@
/*
a implementation of MD4 designed for use in the SMB authentication protocol
Copyright (C) Andrew Tridgell 1997-1998.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "ccache.h"
/* NOTE: This code makes no attempt to be fast!
It assumes that a int is at least 32 bits long
*/
static struct mdfour *m;
#define MASK32 (0xffffffff)
#define F(X,Y,Z) ((((X)&(Y)) | ((~(X))&(Z))))
#define G(X,Y,Z) ((((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z))))
#define H(X,Y,Z) (((X)^(Y)^(Z)))
#define lshift(x,s) (((((x)<<(s))&MASK32) | (((x)>>(32-(s)))&MASK32)))
#define ROUND1(a,b,c,d,k,s) a = lshift((a + F(b,c,d) + M[k])&MASK32, s)
#define ROUND2(a,b,c,d,k,s) a = lshift((a + G(b,c,d) + M[k] + 0x5A827999)&MASK32,s)
#define ROUND3(a,b,c,d,k,s) a = lshift((a + H(b,c,d) + M[k] + 0x6ED9EBA1)&MASK32,s)
/* this applies md4 to 64 byte chunks */
static void mdfour64(uint32 *M)
{
uint32 AA, BB, CC, DD;
uint32 A,B,C,D;
A = m->A; B = m->B; C = m->C; D = m->D;
AA = A; BB = B; CC = C; DD = D;
ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);
ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);
ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);
ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19);
ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13);
ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);
ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);
ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);
ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);
ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);
ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);
ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);
A += AA; B += BB;
C += CC; D += DD;
A &= MASK32; B &= MASK32;
C &= MASK32; D &= MASK32;
m->A = A; m->B = B; m->C = C; m->D = D;
}
static void copy64(uint32 *M, const unsigned char *in)
{
int i;
for (i=0;i<16;i++)
M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
(in[i*4+1]<<8) | (in[i*4+0]<<0);
}
static void copy4(unsigned char *out,uint32 x)
{
out[0] = x&0xFF;
out[1] = (x>>8)&0xFF;
out[2] = (x>>16)&0xFF;
out[3] = (x>>24)&0xFF;
}
void mdfour_begin(struct mdfour *md)
{
md->A = 0x67452301;
md->B = 0xefcdab89;
md->C = 0x98badcfe;
md->D = 0x10325476;
md->totalN = 0;
md->tail_len = 0;
}
static void mdfour_tail(const unsigned char *in, int n)
{
unsigned char buf[128];
uint32 M[16];
uint32 b;
m->totalN += n;
b = m->totalN * 8;
memset(buf, 0, 128);
if (n) memcpy(buf, in, n);
buf[n] = 0x80;
if (n <= 55) {
copy4(buf+56, b);
copy64(M, buf);
mdfour64(M);
} else {
copy4(buf+120, b);
copy64(M, buf);
mdfour64(M);
copy64(M, buf+64);
mdfour64(M);
}
}
void mdfour_update(struct mdfour *md, const unsigned char *in, int n)
{
uint32 M[16];
m = md;
if (in == NULL) {
mdfour_tail(md->tail, md->tail_len);
return;
}
if (md->tail_len) {
int len = 64 - md->tail_len;
if (len > n) len = n;
memcpy(md->tail+md->tail_len, in, len);
md->tail_len += len;
n -= len;
in += len;
if (md->tail_len == 64) {
copy64(M, md->tail);
mdfour64(M);
m->totalN += 64;
md->tail_len = 0;
}
}
while (n >= 64) {
copy64(M, in);
mdfour64(M);
in += 64;
n -= 64;
m->totalN += 64;
}
if (n) {
memcpy(md->tail, in, n);
md->tail_len = n;
}
}
void mdfour_result(struct mdfour *md, unsigned char *out)
{
m = md;
copy4(out, m->A);
copy4(out+4, m->B);
copy4(out+8, m->C);
copy4(out+12, m->D);
}
void mdfour(unsigned char *out, const unsigned char *in, int n)
{
struct mdfour md;
mdfour_begin(&md);
mdfour_update(&md, in, n);
mdfour_update(&md, NULL, 0);
mdfour_result(&md, out);
}
#ifdef TEST_MDFOUR
static void file_checksum1(char *fname)
{
int fd, i;
struct mdfour md;
unsigned char buf[1024], sum[16];
unsigned chunk;
fd = open(fname,O_RDONLY|O_BINARY);
if (fd == -1) {
perror("fname");
exit(1);
}
chunk = 1 + random() % (sizeof(buf) - 1);
mdfour_begin(&md);
while (1) {
int n = read(fd, buf, chunk);
if (n >= 0) {
mdfour_update(&md, buf, n);
}
if (n < chunk) break;
}
close(fd);
mdfour_update(&md, NULL, 0);
mdfour_result(&md, sum);
for (i=0;i<16;i++)
printf("%02x", sum[i]);
printf("\n");
}
#if 0
#include "../md4.h"
static void file_checksum2(char *fname)
{
int fd, i;
MDstruct md;
unsigned char buf[64], sum[16];
fd = open(fname,O_RDONLY|O_BINARY);
if (fd == -1) {
perror("fname");
exit(1);
}
MDbegin(&md);
while (1) {
int n = read(fd, buf, sizeof(buf));
if (n <= 0) break;
MDupdate(&md, buf, n*8);
}
if (!md.done) {
MDupdate(&md, buf, 0);
}
close(fd);
memcpy(sum, md.buffer, 16);
for (i=0;i<16;i++)
printf("%02x", sum[i]);
printf("\n");
}
#endif
int main(int argc, char *argv[])
{
file_checksum1(argv[1]);
#if 0
file_checksum2(argv[1]);
#endif
return 0;
}
#endif

36
CCache/mdfour.h Normal file
View file

@ -0,0 +1,36 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
a implementation of MD4 designed for use in the SMB authentication protocol
Copyright (C) Andrew Tridgell 1997-1998.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
struct mdfour {
uint32 A, B, C, D;
uint32 totalN;
unsigned char tail[64];
unsigned tail_len;
};
void mdfour_begin(struct mdfour *md);
void mdfour_update(struct mdfour *md, const unsigned char *in, int n);
void mdfour_result(struct mdfour *md, unsigned char *out);
void mdfour(unsigned char *out, const unsigned char *in, int n);

5
CCache/packaging/README Normal file
View file

@ -0,0 +1,5 @@
These packaging files are contributd by users of ccache. I do not
maintain them, and they may well need updating before you use them.
I don't distribute binary packages of ccache myself, but if you wish
to add ccache to a distribution then that's OK

View file

@ -0,0 +1,37 @@
Summary: Compiler Cache
Name: ccache
Version: 2.3
Release: 1
Group: Development/Languages
License: GPL
URL: http://ccache.samba.org/
Source: ccache-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-root
%description
ccache caches gcc output files
%prep
%setup -q
%build
%configure
make
install -d -m 0755 $RPM_BUILD_ROOT%{_bindir}
install -m 0755 ccache $RPM_BUILD_ROOT%{_bindir}
install -d -m 0755 $RPM_BUILD_ROOT%{_mandir}/man1
install -m 0644 ccache.1 $RPM_BUILD_ROOT%{_mandir}/man1
%files
%defattr(-,root,root)
%doc README
%{_mandir}/man1/ccache.1*
%{_bindir}/ccache
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
%changelog
* Mon Apr 01 2002 Peter Jones <pjones@redhat.com>
- Created the package

962
CCache/snprintf.c Normal file
View file

@ -0,0 +1,962 @@
/*
* Copyright Patrick Powell 1995
* This code is based on code written by Patrick Powell (papowell@astart.com)
* It may be used for any purpose as long as this notice remains intact
* on all source code distributions
*/
/**************************************************************
* Original:
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
* A bombproof version of doprnt (dopr) included.
* Sigh. This sort of thing is always nasty do deal with. Note that
* the version here does not include floating point...
*
* snprintf() is used instead of sprintf() as it does limit checks
* for string length. This covers a nasty loophole.
*
* The other functions are there to prevent NULL pointers from
* causing nast effects.
*
* More Recently:
* Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
* This was ugly. It is still ugly. I opted out of floating point
* numbers, but the formatter understands just about everything
* from the normal C string format, at least as far as I can tell from
* the Solaris 2.5 printf(3S) man page.
*
* Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
* Ok, added some minimal floating point support, which means this
* probably requires libm on most operating systems. Don't yet
* support the exponent (e,E) and sigfig (g,G). Also, fmtint()
* was pretty badly broken, it just wasn't being exercised in ways
* which showed it, so that's been fixed. Also, formated the code
* to mutt conventions, and removed dead code left over from the
* original. Also, there is now a builtin-test, just compile with:
* gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
* and run snprintf for results.
*
* Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
* The PGP code was using unsigned hexadecimal formats.
* Unfortunately, unsigned formats simply didn't work.
*
* Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
* The original code assumed that both snprintf() and vsnprintf() were
* missing. Some systems only have snprintf() but not vsnprintf(), so
* the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
*
* Andrew Tridgell (tridge@samba.org) Oct 1998
* fixed handling of %.0f
* added test for HAVE_LONG_DOUBLE
*
* tridge@samba.org, idra@samba.org, April 2001
* got rid of fcvt code (twas buggy and made testing harder)
* added C99 semantics
*
**************************************************************/
#ifndef NO_CONFIG_H /* for some tests */
#include "config.h"
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#include <sys/types.h>
#include <stdarg.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF)
/* only include stdio.h if we are not re-defining snprintf or vsnprintf */
#include <stdio.h>
/* make the compiler happy with an empty file */
void dummy_snprintf(void) {}
#else
#ifdef HAVE_LONG_DOUBLE
#define LDOUBLE long double
#else
#define LDOUBLE double
#endif
#ifdef HAVE_LONG_LONG
#define LLONG long long
#else
#define LLONG long
#endif
static size_t dopr(char *buffer, size_t maxlen, const char *format,
va_list args);
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max);
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags);
static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags);
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
/*
* dopr(): poor man's version of doprintf
*/
/* format read states */
#define DP_S_DEFAULT 0
#define DP_S_FLAGS 1
#define DP_S_MIN 2
#define DP_S_DOT 3
#define DP_S_MAX 4
#define DP_S_MOD 5
#define DP_S_CONV 6
#define DP_S_DONE 7
/* format flags - Bits */
#define DP_F_MINUS (1 << 0)
#define DP_F_PLUS (1 << 1)
#define DP_F_SPACE (1 << 2)
#define DP_F_NUM (1 << 3)
#define DP_F_ZERO (1 << 4)
#define DP_F_UP (1 << 5)
#define DP_F_UNSIGNED (1 << 6)
/* Conversion Flags */
#define DP_C_SHORT 1
#define DP_C_LONG 2
#define DP_C_LDOUBLE 3
#define DP_C_LLONG 4
#define char_to_int(p) ((p)- '0')
#ifndef MAX
#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
#endif
static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args)
{
char ch;
LLONG value;
LDOUBLE fvalue;
char *strvalue;
int min;
int max;
int state;
int flags;
int cflags;
size_t currlen;
state = DP_S_DEFAULT;
currlen = flags = cflags = min = 0;
max = -1;
ch = *format++;
while (state != DP_S_DONE) {
if (ch == '\0')
state = DP_S_DONE;
switch(state) {
case DP_S_DEFAULT:
if (ch == '%')
state = DP_S_FLAGS;
else
dopr_outch (buffer, &currlen, maxlen, ch);
ch = *format++;
break;
case DP_S_FLAGS:
switch (ch) {
case '-':
flags |= DP_F_MINUS;
ch = *format++;
break;
case '+':
flags |= DP_F_PLUS;
ch = *format++;
break;
case ' ':
flags |= DP_F_SPACE;
ch = *format++;
break;
case '#':
flags |= DP_F_NUM;
ch = *format++;
break;
case '0':
flags |= DP_F_ZERO;
ch = *format++;
break;
default:
state = DP_S_MIN;
break;
}
break;
case DP_S_MIN:
if (isdigit((unsigned char)ch)) {
min = 10*min + char_to_int (ch);
ch = *format++;
} else if (ch == '*') {
min = va_arg (args, int);
ch = *format++;
state = DP_S_DOT;
} else {
state = DP_S_DOT;
}
break;
case DP_S_DOT:
if (ch == '.') {
state = DP_S_MAX;
ch = *format++;
} else {
state = DP_S_MOD;
}
break;
case DP_S_MAX:
if (isdigit((unsigned char)ch)) {
if (max < 0)
max = 0;
max = 10*max + char_to_int (ch);
ch = *format++;
} else if (ch == '*') {
max = va_arg (args, int);
ch = *format++;
state = DP_S_MOD;
} else {
state = DP_S_MOD;
}
break;
case DP_S_MOD:
switch (ch) {
case 'h':
cflags = DP_C_SHORT;
ch = *format++;
break;
case 'l':
cflags = DP_C_LONG;
ch = *format++;
if (ch == 'l') { /* It's a long long */
cflags = DP_C_LLONG;
ch = *format++;
}
break;
case 'L':
cflags = DP_C_LDOUBLE;
ch = *format++;
break;
default:
break;
}
state = DP_S_CONV;
break;
case DP_S_CONV:
switch (ch) {
case 'd':
case 'i':
if (cflags == DP_C_SHORT)
value = va_arg (args, int);
else if (cflags == DP_C_LONG)
value = va_arg (args, long int);
else if (cflags == DP_C_LLONG)
value = va_arg (args, LLONG);
else
value = va_arg (args, int);
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break;
case 'o':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned int);
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
value = (long)va_arg (args, unsigned LLONG);
else
value = (long)va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
break;
case 'u':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned int);
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
value = (LLONG)va_arg (args, unsigned LLONG);
else
value = (long)va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break;
case 'X':
flags |= DP_F_UP;
case 'x':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned int);
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
value = (LLONG)va_arg (args, unsigned LLONG);
else
value = (long)va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
break;
case 'f':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
/* um, floating point? */
fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break;
case 'E':
flags |= DP_F_UP;
case 'e':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
break;
case 'G':
flags |= DP_F_UP;
case 'g':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
break;
case 'c':
dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
break;
case 's':
strvalue = va_arg (args, char *);
if (!strvalue) strvalue = "(NULL)";
if (max == -1) {
max = strlen(strvalue);
}
if (min > 0 && max >= 0 && min > max) max = min;
fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
break;
case 'p':
strvalue = (char *)va_arg(args, void *);
fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
break;
case 'n':
if (cflags == DP_C_SHORT) {
short int *num;
num = va_arg (args, short int *);
*num = currlen;
} else if (cflags == DP_C_LONG) {
long int *num;
num = va_arg (args, long int *);
*num = (long int)currlen;
} else if (cflags == DP_C_LLONG) {
LLONG *num;
num = va_arg (args, LLONG *);
*num = (LLONG)currlen;
} else {
int *num;
num = va_arg (args, int *);
*num = currlen;
}
break;
case '%':
dopr_outch (buffer, &currlen, maxlen, ch);
break;
case 'w':
/* not supported yet, treat as next char */
ch = *format++;
break;
default:
/* Unknown, skip */
break;
}
ch = *format++;
state = DP_S_DEFAULT;
flags = cflags = min = 0;
max = -1;
break;
case DP_S_DONE:
break;
default:
/* hmm? */
break; /* some picky compilers need this */
}
}
if (maxlen != 0) {
if (currlen < maxlen - 1)
buffer[currlen] = '\0';
else if (maxlen > 0)
buffer[maxlen - 1] = '\0';
}
return currlen;
}
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max)
{
int padlen, strln; /* amount to pad */
int cnt = 0;
#ifdef DEBUG_SNPRINTF
printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value);
#endif
if (value == 0) {
value = "<NULL>";
}
for (strln = 0; value[strln]; ++strln); /* strlen */
padlen = min - strln;
if (padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justify */
while ((padlen > 0) && (cnt < max)) {
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
++cnt;
}
while (*value && (cnt < max)) {
dopr_outch (buffer, currlen, maxlen, *value++);
++cnt;
}
while ((padlen < 0) && (cnt < max)) {
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
++cnt;
}
}
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags)
{
int signvalue = 0;
unsigned long uvalue;
char convert[20];
int place = 0;
int spadlen = 0; /* amount to space pad */
int zpadlen = 0; /* amount to zero pad */
int caps = 0;
if (max < 0)
max = 0;
uvalue = value;
if(!(flags & DP_F_UNSIGNED)) {
if( value < 0 ) {
signvalue = '-';
uvalue = -value;
} else {
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
signvalue = '+';
else if (flags & DP_F_SPACE)
signvalue = ' ';
}
}
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
do {
convert[place++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")
[uvalue % (unsigned)base ];
uvalue = (uvalue / (unsigned)base );
} while(uvalue && (place < 20));
if (place == 20) place--;
convert[place] = 0;
zpadlen = max - place;
spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
if (zpadlen < 0) zpadlen = 0;
if (spadlen < 0) spadlen = 0;
if (flags & DP_F_ZERO) {
zpadlen = MAX(zpadlen, spadlen);
spadlen = 0;
}
if (flags & DP_F_MINUS)
spadlen = -spadlen; /* Left Justifty */
#ifdef DEBUG_SNPRINTF
printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
zpadlen, spadlen, min, max, place);
#endif
/* Spaces */
while (spadlen > 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
--spadlen;
}
/* Sign */
if (signvalue)
dopr_outch (buffer, currlen, maxlen, signvalue);
/* Zeros */
if (zpadlen > 0) {
while (zpadlen > 0) {
dopr_outch (buffer, currlen, maxlen, '0');
--zpadlen;
}
}
/* Digits */
while (place > 0)
dopr_outch (buffer, currlen, maxlen, convert[--place]);
/* Left Justified spaces */
while (spadlen < 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
++spadlen;
}
}
static LDOUBLE abs_val(LDOUBLE value)
{
LDOUBLE result = value;
if (value < 0)
result = -value;
return result;
}
static LDOUBLE POW10(int exp)
{
LDOUBLE result = 1;
while (exp) {
result *= 10;
exp--;
}
return result;
}
static LLONG ROUND(LDOUBLE value)
{
LLONG intpart;
intpart = (LLONG)value;
value = value - intpart;
if (value >= 0.5) intpart++;
return intpart;
}
/* a replacement for modf that doesn't need the math library. Should
be portable, but slow */
static double my_modf(double x0, double *iptr)
{
int i;
long l;
double x = x0;
double f = 1.0;
for (i=0;i<100;i++) {
l = (long)x;
if (l <= (x+1) && l >= (x-1)) break;
x *= 0.1;
f *= 10.0;
}
if (i == 100) {
/* yikes! the number is beyond what we can handle. What do we do? */
(*iptr) = 0;
return 0;
}
if (i != 0) {
double i2;
double ret;
ret = my_modf(x0-l*f, &i2);
(*iptr) = l*f + i2;
return ret;
}
(*iptr) = l;
return x - (*iptr);
}
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags)
{
int signvalue = 0;
double ufvalue;
char iconvert[311];
char fconvert[311];
int iplace = 0;
int fplace = 0;
int padlen = 0; /* amount to pad */
int zpadlen = 0;
int caps = 0;
int index;
double intpart;
double fracpart;
double temp;
/*
* AIX manpage says the default is 0, but Solaris says the default
* is 6, and sprintf on AIX defaults to 6
*/
if (max < 0)
max = 6;
ufvalue = abs_val (fvalue);
if (fvalue < 0) {
signvalue = '-';
} else {
if (flags & DP_F_PLUS) { /* Do a sign (+/i) */
signvalue = '+';
} else {
if (flags & DP_F_SPACE)
signvalue = ' ';
}
}
#if 0
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
#endif
#if 0
if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */
#endif
/*
* Sorry, we only support 16 digits past the decimal because of our
* conversion method
*/
if (max > 16)
max = 16;
/* We "cheat" by converting the fractional part to integer by
* multiplying by a factor of 10
*/
temp = ufvalue;
my_modf(temp, &intpart);
fracpart = ROUND((POW10(max)) * (ufvalue - intpart));
if (fracpart >= POW10(max)) {
intpart++;
fracpart -= POW10(max);
}
/* Convert integer part */
do {
temp = intpart;
my_modf(intpart*0.1, &intpart);
temp = temp*0.1;
index = (int) ((temp -intpart +0.05)* 10.0);
/* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
/* printf ("%llf, %f, %x\n", temp, intpart, index); */
iconvert[iplace++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")[index];
} while (intpart && (iplace < 311));
if (iplace == 311) iplace--;
iconvert[iplace] = 0;
/* Convert fractional part */
if (fracpart)
{
do {
temp = fracpart;
my_modf(fracpart*0.1, &fracpart);
temp = temp*0.1;
index = (int) ((temp -fracpart +0.05)* 10.0);
/* index = (int) ((((temp/10) -fracpart) +0.05) *10); */
/* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */
fconvert[fplace++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")[index];
} while(fracpart && (fplace < 311));
if (fplace == 311) fplace--;
}
fconvert[fplace] = 0;
/* -1 for decimal point, another -1 if we are printing a sign */
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
zpadlen = max - fplace;
if (zpadlen < 0) zpadlen = 0;
if (padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justifty */
if ((flags & DP_F_ZERO) && (padlen > 0)) {
if (signvalue) {
dopr_outch (buffer, currlen, maxlen, signvalue);
--padlen;
signvalue = 0;
}
while (padlen > 0) {
dopr_outch (buffer, currlen, maxlen, '0');
--padlen;
}
}
while (padlen > 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
}
if (signvalue)
dopr_outch (buffer, currlen, maxlen, signvalue);
while (iplace > 0)
dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
#ifdef DEBUG_SNPRINTF
printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen);
#endif
/*
* Decimal point. This should probably use locale to find the correct
* char to print out.
*/
if (max > 0) {
dopr_outch (buffer, currlen, maxlen, '.');
while (fplace > 0)
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
}
while (zpadlen > 0) {
dopr_outch (buffer, currlen, maxlen, '0');
--zpadlen;
}
while (padlen < 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
}
}
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
{
if (*currlen < maxlen) {
buffer[(*currlen)] = c;
}
(*currlen)++;
}
/* yes this really must be a ||. Don't muck with this (tridge) */
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
{
return dopr(str, count, fmt, args);
}
#endif
/* yes this really must be a ||. Don't muck wiith this (tridge)
*
* The logic for these two is that we need our own definition if the
* OS *either* has no definition of *sprintf, or if it does have one
* that doesn't work properly according to the autoconf test. Perhaps
* these should really be smb_snprintf to avoid conflicts with buggy
* linkers? -- mbp
*/
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_SNPRINTF)
int snprintf(char *str,size_t count,const char *fmt,...)
{
size_t ret;
va_list ap;
va_start(ap, fmt);
ret = vsnprintf(str, count, fmt, ap);
va_end(ap);
return ret;
}
#endif
#endif
#ifndef HAVE_VASPRINTF
int vasprintf(char **ptr, const char *format, va_list ap)
{
int ret;
ret = vsnprintf(0, 0, format, ap);
if (ret <= 0) return ret;
(*ptr) = (char *)malloc(ret+1);
if (!*ptr) return -1;
ret = vsnprintf(*ptr, ret+1, format, ap);
return ret;
}
#endif
#ifndef HAVE_ASPRINTF
int asprintf(char **ptr, const char *format, ...)
{
va_list ap;
int ret;
*ptr = 0;
va_start(ap, format);
ret = vasprintf(ptr, format, ap);
va_end(ap);
return ret;
}
#endif
#ifndef HAVE_VSYSLOG
#ifdef HAVE_SYSLOG
void vsyslog (int facility_priority, char *format, va_list arglist)
{
char *msg = 0;
vasprintf(&msg, format, arglist);
if (!msg)
return;
syslog(facility_priority, "%s", msg);
free(msg);
}
#endif /* HAVE_SYSLOG */
#endif /* HAVE_VSYSLOG */
#ifdef TEST_SNPRINTF
int sprintf(char *str,const char *fmt,...);
int main (void)
{
char buf1[1024];
char buf2[1024];
char *fp_fmt[] = {
"%1.1f",
"%-1.5f",
"%1.5f",
"%123.9f",
"%10.5f",
"% 10.5f",
"%+22.9f",
"%+4.9f",
"%01.3f",
"%4f",
"%3.1f",
"%3.2f",
"%.0f",
"%f",
"-16.16f",
0
};
double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
0.9996, 1.996, 4.136, 0};
char *int_fmt[] = {
"%-1.5d",
"%1.5d",
"%123.9d",
"%5.5d",
"%10.5d",
"% 10.5d",
"%+22.33d",
"%01.3d",
"%4d",
"%d",
0
};
long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
char *str_fmt[] = {
"10.5s",
"5.10s",
"10.1s",
"0.10s",
"10.0s",
"1.10s",
"%s",
"%.1s",
"%.10s",
"%10s",
0
};
char *str_vals[] = {"hello", "a", "", "a longer string", 0};
int x, y;
int fail = 0;
int num = 0;
printf ("Testing snprintf format codes against system sprintf...\n");
for (x = 0; fp_fmt[x] ; x++) {
for (y = 0; fp_nums[y] != 0 ; y++) {
int l1 = snprintf(0, 0, fp_fmt[x], fp_nums[y]);
int l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);
sprintf (buf2, fp_fmt[x], fp_nums[y]);
if (strcmp (buf1, buf2)) {
printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n",
fp_fmt[x], buf1, buf2);
fail++;
}
if (l1 != l2) {
printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]);
fail++;
}
num++;
}
}
for (x = 0; int_fmt[x] ; x++) {
for (y = 0; int_nums[y] != 0 ; y++) {
int l1 = snprintf(0, 0, int_fmt[x], int_nums[y]);
int l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);
sprintf (buf2, int_fmt[x], int_nums[y]);
if (strcmp (buf1, buf2)) {
printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n",
int_fmt[x], buf1, buf2);
fail++;
}
if (l1 != l2) {
printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]);
fail++;
}
num++;
}
}
for (x = 0; str_fmt[x] ; x++) {
for (y = 0; str_vals[y] != 0 ; y++) {
int l1 = snprintf(0, 0, str_fmt[x], str_vals[y]);
int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]);
sprintf (buf2, str_fmt[x], str_vals[y]);
if (strcmp (buf1, buf2)) {
printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n",
str_fmt[x], buf1, buf2);
fail++;
}
if (l1 != l2) {
printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]);
fail++;
}
num++;
}
}
printf ("%d tests failed out of %d.\n", fail, num);
printf("seeing how many digits we support\n");
{
double v0 = 0.12345678901234567890123456789012345678901;
for (x=0; x<100; x++) {
snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x));
sprintf(buf2, "%1.1f", v0*pow(10, x));
if (strcmp(buf1, buf2)) {
printf("we seem to support %d digits\n", x-1);
break;
}
}
}
return 0;
}
#endif /* SNPRINTF_TEST */

361
CCache/stats.c Normal file
View file

@ -0,0 +1,361 @@
/*
Copyright (C) Andrew Tridgell 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
routines to handle the stats files
the stats file is stored one per cache subdirectory to make this more
scalable
*/
#include "ccache.h"
extern char *stats_file;
extern char *cache_dir;
#define STATS_VERSION 1
#define FLAG_NOZERO 1 /* don't zero with the -z option */
#define FLAG_ALWAYS 2 /* always show, even if zero */
static struct {
enum stats stat;
char *message;
void (*fn)(unsigned );
unsigned flags;
} stats_info[] = {
{ STATS_CACHED, "cache hit ", NULL, FLAG_ALWAYS },
{ STATS_TOCACHE, "cache miss ", NULL, FLAG_ALWAYS },
{ STATS_LINK, "called for link ", NULL, 0 },
{ STATS_MULTIPLE, "multiple source files ", NULL, 0 },
{ STATS_STDOUT, "compiler produced stdout ", NULL, 0 },
{ STATS_STATUS, "compile failed ", NULL, 0 },
{ STATS_ERROR, "ccache internal error ", NULL, 0 },
{ STATS_PREPROCESSOR, "preprocessor error ", NULL, 0 },
{ STATS_COMPILER, "couldn't find the compiler ", NULL, 0 },
{ STATS_MISSING, "cache file missing ", NULL, 0 },
{ STATS_ARGS, "bad compiler arguments ", NULL, 0 },
{ STATS_NOTC, "not a C/C++ file ", NULL, 0 },
{ STATS_CONFTEST, "autoconf compile/link ", NULL, 0 },
{ STATS_UNSUPPORTED, "unsupported compiler option ", NULL, 0 },
{ STATS_OUTSTDOUT, "output to stdout ", NULL, 0 },
{ STATS_DEVICE, "output to a non-regular file ", NULL, 0 },
{ STATS_NOINPUT, "no input file ", NULL, 0 },
{ STATS_ENVIRONMMENT, "error due to bad env variable ", NULL, 0 },
{ STATS_NUMFILES, "files in cache ", NULL, FLAG_NOZERO|FLAG_ALWAYS },
{ STATS_TOTALSIZE, "cache size ", display_size , FLAG_NOZERO|FLAG_ALWAYS },
{ STATS_MAXFILES, "max files ", NULL, FLAG_NOZERO },
{ STATS_MAXSIZE, "max cache size ", display_size, FLAG_NOZERO },
{ STATS_NONE, NULL, NULL, 0 }
};
/* parse a stats file from a buffer - adding to the counters */
static void parse_stats(unsigned counters[STATS_END], char *buf)
{
int i;
char *p, *p2;
p = buf;
for (i=0;i<STATS_END;i++) {
counters[i] += strtol(p, &p2, 10);
if (!p2 || p2 == p) break;
p = p2;
}
}
/* write out a stats file */
static void write_stats(int fd, unsigned counters[STATS_END])
{
int i;
int len = 0;
char buf[1024];
for (i=0;i<STATS_END;i++) {
len += snprintf(buf+len, sizeof(buf)-(len+1), "%u ", counters[i]);
if (len >= (int)sizeof(buf)-1) fatal("stats too long?!");
}
len += snprintf(buf+len, sizeof(buf)-(len+1), "\n");
if (len >= (int)sizeof(buf)-1) fatal("stats too long?!");
lseek(fd, 0, SEEK_SET);
if (write(fd, buf, len) == -1) fatal("could not write stats");
}
/* fill in some default stats values */
static void stats_default(unsigned counters[STATS_END])
{
counters[STATS_MAXSIZE] += DEFAULT_MAXSIZE / 16;
}
/* read in the stats from one dir and add to the counters */
static void stats_read_fd(int fd, unsigned counters[STATS_END])
{
char buf[1024];
int len;
len = read(fd, buf, sizeof(buf)-1);
if (len <= 0) {
stats_default(counters);
return;
}
buf[len] = 0;
parse_stats(counters, buf);
}
/* update the stats counter for this compile */
static void stats_update_size(enum stats stat, size_t size, size_t numfiles)
{
int fd;
unsigned counters[STATS_END];
int need_cleanup = 0;
if (getenv("CCACHE_NOSTATS")) return;
if (!stats_file) {
if (!cache_dir) return;
x_asprintf(&stats_file, "%s/stats", cache_dir);
}
/* open safely to try to prevent symlink races */
fd = safe_open(stats_file);
/* still can't get it? don't bother ... */
if (fd == -1) return;
memset(counters, 0, sizeof(counters));
if (lock_fd(fd) != 0) return;
/* read in the old stats */
stats_read_fd(fd, counters);
/* update them */
counters[stat]++;
/* on a cache miss we up the file count and size */
if (stat == STATS_TOCACHE) {
counters[STATS_NUMFILES] += numfiles;
counters[STATS_TOTALSIZE] += size;
}
/* and write them out */
write_stats(fd, counters);
close(fd);
/* we might need to cleanup if the cache has now got too big */
if (counters[STATS_MAXFILES] != 0 &&
counters[STATS_NUMFILES] > counters[STATS_MAXFILES]) {
need_cleanup = 1;
}
if (counters[STATS_MAXSIZE] != 0 &&
counters[STATS_TOTALSIZE] > counters[STATS_MAXSIZE]) {
need_cleanup = 1;
}
if (need_cleanup) {
char *p = dirname(stats_file);
cleanup_dir(p, counters[STATS_MAXFILES], counters[STATS_MAXSIZE]);
free(p);
}
}
/* record a cache miss */
void stats_tocache(size_t size, size_t numfiles)
{
/* convert size to kilobytes */
size = size / 1024;
stats_update_size(STATS_TOCACHE, size, numfiles);
}
/* update a normal stat */
void stats_update(enum stats stat)
{
stats_update_size(stat, 0, 0);
}
/* read in the stats from one dir and add to the counters */
void stats_read(const char *stats_file, unsigned counters[STATS_END])
{
int fd;
fd = open(stats_file, O_RDONLY|O_BINARY);
if (fd == -1) {
stats_default(counters);
return;
}
lock_fd(fd);
stats_read_fd(fd, counters);
close(fd);
}
/* sum and display the total stats for all cache dirs */
void stats_summary(void)
{
int dir, i;
unsigned counters[STATS_END];
memset(counters, 0, sizeof(counters));
/* add up the stats in each directory */
for (dir=-1;dir<=0xF;dir++) {
char *fname;
if (dir == -1) {
x_asprintf(&fname, "%s/stats", cache_dir);
} else {
x_asprintf(&fname, "%s/%1x/stats", cache_dir, dir);
}
stats_read(fname, counters);
free(fname);
/* oh what a nasty hack ... */
if (dir == -1) {
counters[STATS_MAXSIZE] = 0;
}
}
printf("cache directory %s\n", cache_dir);
/* and display them */
for (i=0;stats_info[i].message;i++) {
enum stats stat = stats_info[i].stat;
if (counters[stat] == 0 &&
!(stats_info[i].flags & FLAG_ALWAYS)) {
continue;
}
printf("%s ", stats_info[i].message);
if (stats_info[i].fn) {
stats_info[i].fn(counters[stat]);
printf("\n");
} else {
printf("%8u\n", counters[stat]);
}
}
}
/* zero all the stats structures */
void stats_zero(void)
{
int dir, fd;
unsigned i;
char *fname;
unsigned counters[STATS_END];
x_asprintf(&fname, "%s/stats", cache_dir);
unlink(fname);
free(fname);
for (dir=0;dir<=0xF;dir++) {
x_asprintf(&fname, "%s/%1x/stats", cache_dir, dir);
fd = safe_open(fname);
if (fd == -1) {
free(fname);
continue;
}
memset(counters, 0, sizeof(counters));
lock_fd(fd);
stats_read_fd(fd, counters);
for (i=0;stats_info[i].message;i++) {
if (!(stats_info[i].flags & FLAG_NOZERO)) {
counters[stats_info[i].stat] = 0;
}
}
write_stats(fd, counters);
close(fd);
free(fname);
}
}
/* set the per directory limits */
int stats_set_limits(long maxfiles, long maxsize)
{
int dir;
unsigned counters[STATS_END];
if (maxfiles != -1) {
maxfiles /= 16;
}
if (maxsize != -1) {
maxsize /= 16;
}
if (create_dir(cache_dir) != 0) {
return 1;
}
/* set the limits in each directory */
for (dir=0;dir<=0xF;dir++) {
char *fname, *cdir;
int fd;
x_asprintf(&cdir, "%s/%1x", cache_dir, dir);
if (create_dir(cdir) != 0) {
return 1;
}
x_asprintf(&fname, "%s/stats", cdir);
free(cdir);
memset(counters, 0, sizeof(counters));
fd = safe_open(fname);
if (fd != -1) {
lock_fd(fd);
stats_read_fd(fd, counters);
if (maxfiles != -1) {
counters[STATS_MAXFILES] = maxfiles;
}
if (maxsize != -1) {
counters[STATS_MAXSIZE] = maxsize;
}
write_stats(fd, counters);
close(fd);
}
free(fname);
}
return 0;
}
/* set the per directory sizes */
void stats_set_sizes(const char *dir, size_t num_files, size_t total_size)
{
int fd;
unsigned counters[STATS_END];
char *stats_file;
create_dir(dir);
x_asprintf(&stats_file, "%s/stats", dir);
memset(counters, 0, sizeof(counters));
fd = safe_open(stats_file);
if (fd != -1) {
lock_fd(fd);
stats_read_fd(fd, counters);
counters[STATS_NUMFILES] = num_files;
counters[STATS_TOTALSIZE] = total_size;
write_stats(fd, counters);
close(fd);
}
free(stats_file);
}

452
CCache/test.sh Executable file
View file

@ -0,0 +1,452 @@
#!/bin/sh
# a simple test suite for ccache
# tridge@samba.org
if test -n "$CC"; then
COMPILER="$CC"
else
COMPILER=cc
fi
if test -n "$SWIG"; then
SWIG="$SWIG"
else
SWIG=swig
fi
CCACHE=../ccache-swig
TESTDIR=test.$$
test_failed() {
reason="$1"
echo $1
$CCACHE -s
cd ..
rm -rf $TESTDIR
echo TEST FAILED
exit 1
}
randcode() {
outfile="$1"
nlines=$2
i=0;
(
while [ $i -lt $nlines ]; do
echo "int foo$nlines$i(int x) { return x; }"
i=`expr $i + 1`
done
) >> "$outfile"
}
genswigcode() {
outfile="$1"
nlines=$2
i=0;
(
echo "%module swigtest$2;"
while [ $i -lt $nlines ]; do
echo "int foo$nlines$i(int x);"
echo "struct Bar$nlines$i { int y; };"
i=`expr $i + 1`
done
) >> "$outfile"
}
getstat() {
stat="$1"
value=`$CCACHE -s | grep "$stat" | cut -c34-40`
echo $value
}
checkstat() {
stat="$1"
expected_value="$2"
value=`getstat "$stat"`
# echo "exp: $expected_value got: $value $testname"
if [ "$expected_value" != "$value" ]; then
test_failed "SUITE: $testsuite TEST: $testname - Expected $stat to be $expected_value got $value"
fi
}
basetests() {
echo "starting testsuite $testsuite"
rm -rf "$CCACHE_DIR"
checkstat 'cache hit' 0
checkstat 'cache miss' 0
j=1
rm -f *.c
while [ $j -lt 32 ]; do
randcode test$j.c $j
j=`expr $j + 1`
done
testname="BASIC"
$CCACHE_COMPILE -c test1.c
checkstat 'cache hit' 0
checkstat 'cache miss' 1
testname="BASIC2"
$CCACHE_COMPILE -c test1.c
checkstat 'cache hit' 1
checkstat 'cache miss' 1
testname="debug"
$CCACHE_COMPILE -c test1.c -g
checkstat 'cache hit' 1
checkstat 'cache miss' 2
testname="debug2"
$CCACHE_COMPILE -c test1.c -g
checkstat 'cache hit' 2
checkstat 'cache miss' 2
testname="output"
$CCACHE_COMPILE -c test1.c -o foo.o
checkstat 'cache hit' 3
checkstat 'cache miss' 2
testname="link"
$CCACHE_COMPILE test1.c -o test 2> /dev/null
checkstat 'called for link' 1
testname="multiple"
$CCACHE_COMPILE -c test1.c test2.c
checkstat 'multiple source files' 1
testname="find"
$CCACHE blahblah -c test1.c 2> /dev/null
checkstat "couldn't find the compiler" 1
testname="bad"
$CCACHE_COMPILE -c test1.c -I 2> /dev/null
checkstat 'bad compiler arguments' 1
testname="c/c++"
ln -f test1.c test1.ccc
$CCACHE_COMPILE -c test1.ccc 2> /dev/null
checkstat 'not a C/C++ file' 1
testname="unsupported"
$CCACHE_COMPILE -M foo -c test1.c > /dev/null 2>&1
checkstat 'unsupported compiler option' 1
testname="stdout"
$CCACHE echo foo -c test1.c > /dev/null
checkstat 'compiler produced stdout' 1
testname="non-regular"
mkdir testd
$CCACHE_COMPILE -o testd -c test1.c > /dev/null 2>&1
rmdir testd
checkstat 'output to a non-regular file' 1
testname="no-input"
$CCACHE_COMPILE -c -O2 2> /dev/null
checkstat 'no input file' 1
testname="CCACHE_DISABLE"
CCACHE_DISABLE=1 $CCACHE_COMPILE -c test1.c 2> /dev/null
checkstat 'cache hit' 3
$CCACHE_COMPILE -c test1.c
checkstat 'cache hit' 4
testname="CCACHE_CPP2"
CCACHE_CPP2=1 $CCACHE_COMPILE -c test1.c -O -O
checkstat 'cache hit' 4
checkstat 'cache miss' 3
CCACHE_CPP2=1 $CCACHE_COMPILE -c test1.c -O -O
checkstat 'cache hit' 5
checkstat 'cache miss' 3
testname="CCACHE_NOSTATS"
CCACHE_NOSTATS=1 $CCACHE_COMPILE -c test1.c -O -O
checkstat 'cache hit' 5
checkstat 'cache miss' 3
testname="CCACHE_RECACHE"
CCACHE_RECACHE=1 $CCACHE_COMPILE -c test1.c -O -O
checkstat 'cache hit' 5
checkstat 'cache miss' 4
# strictly speaking should be 6 - RECACHE causes a double counting!
checkstat 'files in cache' 8
$CCACHE -c > /dev/null
checkstat 'files in cache' 6
testname="CCACHE_HASHDIR"
CCACHE_HASHDIR=1 $CCACHE_COMPILE -c test1.c -O -O
checkstat 'cache hit' 5
checkstat 'cache miss' 5
CCACHE_HASHDIR=1 $CCACHE_COMPILE -c test1.c -O -O
checkstat 'cache hit' 6
checkstat 'cache miss' 5
checkstat 'files in cache' 8
testname="comments"
echo '/* a silly comment */' > test1-comment.c
cat test1.c >> test1-comment.c
$CCACHE_COMPILE -c test1-comment.c
rm -f test1-comment*
checkstat 'cache hit' 6
checkstat 'cache miss' 6
testname="CCACHE_UNIFY"
CCACHE_UNIFY=1 $CCACHE_COMPILE -c test1.c
checkstat 'cache hit' 6
checkstat 'cache miss' 7
mv test1.c test1-saved.c
echo '/* another comment */' > test1.c
cat test1-saved.c >> test1.c
CCACHE_UNIFY=1 $CCACHE_COMPILE -c test1.c
mv test1-saved.c test1.c
checkstat 'cache hit' 7
checkstat 'cache miss' 7
testname="cache-size"
for f in *.c; do
$CCACHE_COMPILE -c $f
done
checkstat 'cache hit' 8
checkstat 'cache miss' 37
checkstat 'files in cache' 72
$CCACHE -F 48 -c > /dev/null
if [ `getstat 'files in cache'` -gt 48 ]; then
test_failed '-F test failed'
fi
testname="cpp call"
$CCACHE_COMPILE -c test1.c -E > test1.i
checkstat 'cache hit' 8
checkstat 'cache miss' 37
testname="direct .i compile"
$CCACHE_COMPILE -c test1.c
checkstat 'cache hit' 8
checkstat 'cache miss' 38
$CCACHE_COMPILE -c test1.i
checkstat 'cache hit' 9
checkstat 'cache miss' 38
$CCACHE_COMPILE -c test1.i
checkstat 'cache hit' 10
checkstat 'cache miss' 38
# removed these tests as some compilers (including newer versions of gcc)
# determine which language to use based on .ii/.i extension, and C++ may
# not be installed
# testname="direct .ii file"
# mv test1.i test1.ii
# $CCACHE_COMPILE -c test1.ii
# checkstat 'cache hit' 10
# checkstat 'cache miss' 39
# $CCACHE_COMPILE -c test1.ii
# checkstat 'cache hit' 11
# checkstat 'cache miss' 39
testname="stripc" # This test might not be portable
CCACHE_STRIPC=1 $CCACHE_COMPILE -c test1.c
checkstat 'cache hit' 10
checkstat 'cache miss' 39
CCACHE_STRIPC=1 $CCACHE_COMPILE -c test1.c
checkstat 'cache hit' 11
checkstat 'cache miss' 39
testname="zero-stats"
$CCACHE -z > /dev/null
checkstat 'cache hit' 0
checkstat 'cache miss' 0
testname="clear"
$CCACHE -C > /dev/null
checkstat 'files in cache' 0
rm -f test1.c
}
swigtests() {
echo "starting swig testsuite $testsuite"
rm -rf "$CCACHE_DIR"
checkstat 'cache hit' 0
checkstat 'cache miss' 0
j=1
rm -f *.i
genswigcode testswig1.i 1
testname="BASIC"
$CCACHE_COMPILE -java testswig1.i
checkstat 'cache hit' 0
checkstat 'cache miss' 1
checkstat 'files in cache' 6
testname="BASIC2"
$CCACHE_COMPILE -java testswig1.i
checkstat 'cache hit' 1
checkstat 'cache miss' 1
testname="output"
$CCACHE_COMPILE -java testswig1.i -o foo_wrap.c
checkstat 'cache hit' 1
checkstat 'cache miss' 2
testname="bad"
$CCACHE_COMPILE -java testswig1.i -I 2> /dev/null
checkstat 'bad compiler arguments' 1
testname="stdout"
$CCACHE_COMPILE -v -java testswig1.i > /dev/null
checkstat 'compiler produced stdout' 1
testname="non-regular"
mkdir testd
$CCACHE_COMPILE -o testd -java testswig1.i > /dev/null 2>&1
rmdir testd
checkstat 'output to a non-regular file' 1
testname="no-input"
$CCACHE_COMPILE -java 2> /dev/null
checkstat 'no input file' 1
testname="CCACHE_DISABLE"
CCACHE_DISABLE=1 $CCACHE_COMPILE -java testswig1.i 2> /dev/null
checkstat 'cache hit' 1
$CCACHE_COMPILE -java testswig1.i
checkstat 'cache hit' 2
testname="CCACHE_CPP2"
CCACHE_CPP2=1 $CCACHE_COMPILE -java -O -O testswig1.i
checkstat 'cache hit' 2
checkstat 'cache miss' 3
CCACHE_CPP2=1 $CCACHE_COMPILE -java -O -O testswig1.i
checkstat 'cache hit' 3
checkstat 'cache miss' 3
testname="CCACHE_NOSTATS"
CCACHE_NOSTATS=1 $CCACHE_COMPILE -java -O -O testswig1.i
checkstat 'cache hit' 3
checkstat 'cache miss' 3
testname="CCACHE_RECACHE"
CCACHE_RECACHE=1 $CCACHE_COMPILE -java -O -O testswig1.i
checkstat 'cache hit' 3
checkstat 'cache miss' 4
# strictly speaking should be 3x6=18 instead of 4x6=24 - RECACHE causes a double counting!
checkstat 'files in cache' 24
$CCACHE -c > /dev/null
checkstat 'files in cache' 18
testname="CCACHE_HASHDIR"
CCACHE_HASHDIR=1 $CCACHE_COMPILE -java -O -O testswig1.i
checkstat 'cache hit' 3
checkstat 'cache miss' 5
CCACHE_HASHDIR=1 $CCACHE_COMPILE -java -O -O testswig1.i
checkstat 'cache hit' 4
checkstat 'cache miss' 5
checkstat 'files in cache' 24
testname="cpp call"
$CCACHE_COMPILE -java -E testswig1.i > testswig1-preproc.i
checkstat 'cache hit' 4
checkstat 'cache miss' 5
testname="direct .i compile"
$CCACHE_COMPILE -java testswig1.i
checkstat 'cache hit' 5
checkstat 'cache miss' 5
# No cache hit due to different input file name, -nopreprocess should not be given twice to SWIG
$CCACHE_COMPILE -java -nopreprocess testswig1-preproc.i
checkstat 'cache hit' 5
checkstat 'cache miss' 6
$CCACHE_COMPILE -java -nopreprocess testswig1-preproc.i
checkstat 'cache hit' 6
checkstat 'cache miss' 6
testname="stripc"
CCACHE_STRIPC=1 $CCACHE_COMPILE -java -O -O testswig1.i
checkstat 'cache hit' 7
checkstat 'cache miss' 6
CCACHE_STRIPC=1 $CCACHE_COMPILE -java -O -O -O testswig1.i
checkstat 'cache hit' 7
checkstat 'cache miss' 7
rm -f testswig1-preproc.i
rm -f testswig1.i
}
######
# main program
rm -rf $TESTDIR
mkdir $TESTDIR
cd $TESTDIR || exit 1
CCACHE_DIR="ccache dir" # with space in directory name (like Windows default)
mkdir "$CCACHE_DIR"
export CCACHE_DIR
testsuite="base"
CCACHE_COMPILE="$CCACHE $COMPILER"
basetests
CCACHE_COMPILE="$CCACHE $SWIG"
swigtests
if test -z "$NOSOFTLINKSTEST"; then
testsuite="link"
ln -s $CCACHE $COMPILER
CCACHE_COMPILE="./$COMPILER"
basetests
rm "./$COMPILER"
ln -s $CCACHE $SWIG
CCACHE_COMPILE="./$SWIG"
swigtests
rm "./$SWIG"
else
echo "skipping testsuite link"
fi
testsuite="hardlink"
CCACHE_COMPILE="env CCACHE_NOCOMPRESS=1 CCACHE_HARDLINK=1 $CCACHE $COMPILER"
basetests
CCACHE_COMPILE="env CCACHE_NOCOMPRESS=1 CCACHE_HARDLINK=1 $CCACHE $SWIG"
swigtests
testsuite="cpp2"
CCACHE_COMPILE="env CCACHE_CPP2=1 $CCACHE $COMPILER"
basetests
CCACHE_COMPILE="env CCACHE_CPP2=1 $CCACHE $SWIG"
swigtests
testsuite="nlevels4"
CCACHE_COMPILE="env CCACHE_NLEVELS=4 $CCACHE $COMPILER"
basetests
testsuite="nlevels1"
CCACHE_COMPILE="env CCACHE_NLEVELS=1 $CCACHE $COMPILER"
basetests
cd ..
rm -rf $TESTDIR
echo test done - OK
exit 0

307
CCache/unify.c Normal file
View file

@ -0,0 +1,307 @@
/*
Copyright (C) Andrew Tridgell 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
C/C++ unifier
the idea is that changes that don't affect the resulting C code
should not change the hash. This is achieved by folding white-space
and other non-semantic fluff in the input into a single unified format.
This unifier was design to match the output of the unifier in
compilercache, which is flex based. The major difference is that
this unifier is much faster (about 2x) and more forgiving of
syntactic errors. Continuing on syntactic errors is important to
cope with C/C++ extensions in the local compiler (for example,
inline assembly systems).
*/
#include "ccache.h"
static char *s_tokens[] = {
"...", ">>=", "<<=", "+=", "-=", "*=", "/=", "%=", "&=", "^=",
"|=", ">>", "<<", "++", "--", "->", "&&", "||", "<=", ">=",
"==", "!=", ";", "{", "<%", "}", "%>", ",", ":", "=",
"(", ")", "[", "<:", "]", ":>", ".", "&", "!", "~",
"-", "+", "*", "/", "%", "<", ">", "^", "|", "?",
0
};
#define C_ALPHA 1
#define C_SPACE 2
#define C_TOKEN 4
#define C_QUOTE 8
#define C_DIGIT 16
#define C_HEX 32
#define C_FLOAT 64
#define C_SIGN 128
static struct {
unsigned char type;
unsigned char num_toks;
char *toks[7];
} tokens[256];
/* build up the table used by the unifier */
static void build_table(void)
{
unsigned char c;
int i;
static int done;
if (done) return;
done = 1;
memset(tokens, 0, sizeof(tokens));
for (c=0;c<128;c++) {
if (isalpha(c) || c == '_') tokens[c].type |= C_ALPHA;
if (isdigit(c)) tokens[c].type |= C_DIGIT;
if (isspace(c)) tokens[c].type |= C_SPACE;
if (isxdigit(c)) tokens[c].type |= C_HEX;
}
tokens['\''].type |= C_QUOTE;
tokens['"'].type |= C_QUOTE;
tokens['l'].type |= C_FLOAT;
tokens['L'].type |= C_FLOAT;
tokens['f'].type |= C_FLOAT;
tokens['F'].type |= C_FLOAT;
tokens['U'].type |= C_FLOAT;
tokens['u'].type |= C_FLOAT;
tokens['-'].type |= C_SIGN;
tokens['+'].type |= C_SIGN;
for (i=0;s_tokens[i];i++) {
c = s_tokens[i][0];
tokens[c].type |= C_TOKEN;
tokens[c].toks[tokens[c].num_toks] = s_tokens[i];
tokens[c].num_toks++;
}
}
/* buffer up characters before hashing them */
static void pushchar(unsigned char c)
{
static unsigned char buf[64];
static int len;
if (c == 0) {
if (len > 0) {
hash_buffer((char *)buf, len);
len = 0;
}
hash_buffer(NULL, 0);
return;
}
buf[len++] = c;
if (len == 64) {
hash_buffer((char *)buf, len);
len = 0;
}
}
/* hash some C/C++ code after unifying */
static void unify(unsigned char *p, size_t size)
{
size_t ofs;
unsigned char q;
int i;
build_table();
for (ofs=0; ofs<size;) {
if (p[ofs] == '#') {
if ((size-ofs) > 2 && p[ofs+1] == ' ' && isdigit(p[ofs+2])) {
do {
ofs++;
} while (ofs < size && p[ofs] != '\n');
ofs++;
} else {
do {
pushchar(p[ofs]);
ofs++;
} while (ofs < size && p[ofs] != '\n');
pushchar('\n');
ofs++;
}
continue;
}
if (tokens[p[ofs]].type & C_ALPHA) {
do {
pushchar(p[ofs]);
ofs++;
} while (ofs < size &&
(tokens[p[ofs]].type & (C_ALPHA|C_DIGIT)));
pushchar('\n');
continue;
}
if (tokens[p[ofs]].type & C_DIGIT) {
do {
pushchar(p[ofs]);
ofs++;
} while (ofs < size &&
((tokens[p[ofs]].type & C_DIGIT) || p[ofs] == '.'));
if (ofs < size && (p[ofs] == 'x' || p[ofs] == 'X')) {
do {
pushchar(p[ofs]);
ofs++;
} while (ofs < size && (tokens[p[ofs]].type & C_HEX));
}
if (ofs < size && (p[ofs] == 'E' || p[ofs] == 'e')) {
pushchar(p[ofs]);
ofs++;
while (ofs < size &&
(tokens[p[ofs]].type & (C_DIGIT|C_SIGN))) {
pushchar(p[ofs]);
ofs++;
}
}
while (ofs < size && (tokens[p[ofs]].type & C_FLOAT)) {
pushchar(p[ofs]);
ofs++;
}
pushchar('\n');
continue;
}
if (tokens[p[ofs]].type & C_SPACE) {
do {
ofs++;
} while (ofs < size && (tokens[p[ofs]].type & C_SPACE));
continue;
}
if (tokens[p[ofs]].type & C_QUOTE) {
q = p[ofs];
pushchar(p[ofs]);
do {
ofs++;
while (ofs < size-1 && p[ofs] == '\\') {
pushchar(p[ofs]);
pushchar(p[ofs+1]);
ofs+=2;
}
pushchar(p[ofs]);
} while (ofs < size && p[ofs] != q);
pushchar('\n');
ofs++;
continue;
}
if (tokens[p[ofs]].type & C_TOKEN) {
q = p[ofs];
for (i=0;i<tokens[q].num_toks;i++) {
unsigned char *s = (unsigned char *)tokens[q].toks[i];
int len = strlen((char *)s);
if (size >= ofs+len && memcmp(&p[ofs], s, len) == 0) {
int j;
for (j=0;s[j];j++) {
pushchar(s[j]);
ofs++;
}
pushchar('\n');
break;
}
}
if (i < tokens[q].num_toks) {
continue;
}
}
pushchar(p[ofs]);
pushchar('\n');
ofs++;
}
pushchar(0);
}
/* hash a file that consists of preprocessor output, but remove any line
number information from the hash
*/
int unify_hash(const char *fname)
{
#ifdef _WIN32
HANDLE file;
HANDLE section;
DWORD filesize_low;
char *map;
int ret = -1;
file = CreateFileA(fname, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (file != INVALID_HANDLE_VALUE) {
filesize_low = GetFileSize(file, NULL);
if (!(filesize_low == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)) {
section = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
CloseHandle(file);
if (section != NULL) {
map = MapViewOfFile(section, FILE_MAP_READ, 0, 0, 0);
CloseHandle(section);
if (map != NULL)
ret = 0;
}
}
}
if (ret == -1) {
cc_log("Failed to open preprocessor output %s\n", fname);
stats_update(STATS_PREPROCESSOR);
return -1;
}
/* pass it through the unifier */
unify((unsigned char *)map, filesize_low);
UnmapViewOfFile(map);
return 0;
#else
int fd;
struct stat st;
char *map;
fd = open(fname, O_RDONLY|O_BINARY);
if (fd == -1 || fstat(fd, &st) != 0) {
cc_log("Failed to open preprocessor output %s\n", fname);
stats_update(STATS_PREPROCESSOR);
return -1;
}
/* we use mmap() to make it easy to handle arbitrarily long
lines in preprocessor output. I have seen lines of over
100k in length, so this is well worth it */
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map == (char *)-1) {
cc_log("Failed to mmap %s\n", fname);
stats_update(STATS_PREPROCESSOR);
return -1;
}
close(fd);
/* pass it through the unifier */
unify((unsigned char *)map, st.st_size);
munmap(map, st.st_size);
return 0;
#endif
}

884
CCache/util.c Normal file
View file

@ -0,0 +1,884 @@
/*
Copyright (C) Andrew Tridgell 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "ccache.h"
static FILE *logfile;
/* log a message to the CCACHE_LOGFILE location */
void cc_log(const char *format, ...)
{
va_list ap;
extern char *cache_logfile;
if (!cache_logfile) return;
if (!logfile) logfile = fopen(cache_logfile, "a");
if (!logfile) return;
va_start(ap, format);
vfprintf(logfile, format, ap);
va_end(ap);
fflush(logfile);
}
/* something went badly wrong! */
void fatal(const char *msg)
{
cc_log("FATAL: %s\n", msg);
exit(1);
}
int safe_rename(const char* oldpath, const char* newpath)
{
/* safe_rename is for creating entries in the cache.
Works like rename(), but it never overwrites an existing
cache entry. This avoids corruption on NFS. */
#ifndef _WIN32
int status = link(oldpath, newpath);
if( status == 0 || errno == EEXIST )
#else
int status = CreateHardLinkA(newpath, oldpath, NULL) ? 0 : -1;
if( status == 0 || GetLastError() == ERROR_ALREADY_EXISTS )
#endif
{
return unlink( oldpath );
}
else
{
return -1;
}
}
#ifndef ENABLE_ZLIB
/* copy all data from one file descriptor to another */
void copy_fd(int fd_in, int fd_out)
{
char buf[10240];
int n;
while ((n = read(fd_in, buf, sizeof(buf))) > 0) {
if (write(fd_out, buf, n) != n) {
fatal("Failed to copy fd");
}
}
}
#ifndef HAVE_MKSTEMP
/* cheap and nasty mkstemp replacement */
static int mkstemp(char *template)
{
mktemp(template);
return open(template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
}
#endif
/* move a file using rename */
int move_file(const char *src, const char *dest) {
return safe_rename(src, dest);
}
/* copy a file - used when hard links don't work
the copy is done via a temporary file and atomic rename
*/
static int copy_file(const char *src, const char *dest)
{
int fd1, fd2;
char buf[10240];
int n;
char *tmp_name;
mode_t mask;
x_asprintf(&tmp_name, "%s.XXXXXX", dest);
fd1 = open(src, O_RDONLY|O_BINARY);
if (fd1 == -1) {
free(tmp_name);
return -1;
}
fd2 = mkstemp(tmp_name);
if (fd2 == -1) {
close(fd1);
free(tmp_name);
return -1;
}
while ((n = read(fd1, buf, sizeof(buf))) > 0) {
if (write(fd2, buf, n) != n) {
close(fd2);
close(fd1);
unlink(tmp_name);
free(tmp_name);
return -1;
}
}
close(fd1);
/* get perms right on the tmp file */
#ifndef _WIN32
mask = umask(0);
fchmod(fd2, 0666 & ~mask);
umask(mask);
#else
(void)mask;
#endif
/* the close can fail on NFS if out of space */
if (close(fd2) == -1) {
unlink(tmp_name);
free(tmp_name);
return -1;
}
unlink(dest);
if (rename(tmp_name, dest) == -1) {
unlink(tmp_name);
free(tmp_name);
return -1;
}
free(tmp_name);
return 0;
}
/* copy a file to the cache */
static int copy_file_to_cache(const char *src, const char *dest) {
return copy_file(src, dest);
}
/* copy a file from the cache */
static int copy_file_from_cache(const char *src, const char *dest) {
return copy_file(src, dest);
}
#else /* ENABLE_ZLIB */
/* copy all data from one file descriptor to another
possibly decompressing it
*/
void copy_fd(int fd_in, int fd_out) {
char buf[10240];
int n;
gzFile gz_in;
gz_in = gzdopen(dup(fd_in), "rb");
if (!gz_in) {
fatal("Failed to copy fd");
}
while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) {
if (write(fd_out, buf, n) != n) {
fatal("Failed to copy fd");
}
}
}
static int _copy_file(const char *src, const char *dest, int mode) {
int fd_in, fd_out;
gzFile gz_in, gz_out = NULL;
char buf[10240];
int n, ret;
char *tmp_name;
mode_t mask;
struct stat st;
x_asprintf(&tmp_name, "%s.XXXXXX", dest);
if (getenv("CCACHE_NOCOMPRESS")) {
mode = COPY_UNCOMPRESSED;
}
/* open source file */
fd_in = open(src, O_RDONLY);
if (fd_in == -1) {
return -1;
}
gz_in = gzdopen(fd_in, "rb");
if (!gz_in) {
close(fd_in);
return -1;
}
/* open destination file */
fd_out = mkstemp(tmp_name);
if (fd_out == -1) {
gzclose(gz_in);
free(tmp_name);
return -1;
}
if (mode == COPY_TO_CACHE) {
/* The gzip file format occupies at least 20 bytes. So
it will always occupy an entire filesystem block,
even for empty files.
Since most stderr files will be empty, we turn off
compression in this case to save space.
*/
if (fstat(fd_in, &st) != 0) {
gzclose(gz_in);
close(fd_out);
free(tmp_name);
return -1;
}
if (file_size(&st) == 0) {
mode = COPY_UNCOMPRESSED;
}
}
if (mode == COPY_TO_CACHE) {
gz_out = gzdopen(dup(fd_out), "wb");
if (!gz_out) {
gzclose(gz_in);
close(fd_out);
free(tmp_name);
return -1;
}
}
while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) {
if (mode == COPY_TO_CACHE) {
ret = gzwrite(gz_out, buf, n);
} else {
ret = write(fd_out, buf, n);
}
if (ret != n) {
gzclose(gz_in);
if (gz_out) {
gzclose(gz_out);
}
close(fd_out);
unlink(tmp_name);
free(tmp_name);
return -1;
}
}
gzclose(gz_in);
if (gz_out) {
gzclose(gz_out);
}
/* get perms right on the tmp file */
mask = umask(0);
fchmod(fd_out, 0666 & ~mask);
umask(mask);
/* the close can fail on NFS if out of space */
if (close(fd_out) == -1) {
unlink(tmp_name);
free(tmp_name);
return -1;
}
unlink(dest);
if (rename(tmp_name, dest) == -1) {
unlink(tmp_name);
free(tmp_name);
return -1;
}
free(tmp_name);
return 0;
}
/* move a file to the cache, compressing it */
int move_file(const char *src, const char *dest) {
int ret;
ret = _copy_file(src, dest, COPY_TO_CACHE);
if (ret != -1) unlink(src);
return ret;
}
/* copy a file to the cache, compressing it */
static int copy_file_to_cache(const char *src, const char *dest) {
return _copy_file(src, dest, COPY_TO_CACHE);
}
/* copy a file from the cache, decompressing it */
static int copy_file_from_cache(const char *src, const char *dest) {
return _copy_file(src, dest, COPY_FROM_CACHE);
}
#endif /* ENABLE_ZLIB */
/* test if a file is zlib compressed */
int test_if_compressed(const char *filename) {
FILE *f;
f = fopen(filename, "rb");
if (!f) {
return 0;
}
/* test if file starts with 1F8B, which is zlib's
* magic number */
if ((fgetc(f) != 0x1f) || (fgetc(f) != 0x8b)) {
fclose(f);
return 0;
}
fclose(f);
return 1;
}
/* copy file to the cache with error checking taking into account compression and hard linking if desired */
int commit_to_cache(const char *src, const char *dest, int hardlink)
{
int ret = -1;
struct stat st;
if (stat(src, &st) == 0) {
unlink(dest);
if (hardlink) {
#ifdef _WIN32
ret = CreateHardLinkA(dest, src, NULL) ? 0 : -1;
#else
ret = link(src, dest);
#endif
}
if (ret == -1) {
ret = copy_file_to_cache(src, dest);
if (ret == -1) {
cc_log("failed to commit %s -> %s (%s)\n", src, dest, strerror(errno));
stats_update(STATS_ERROR);
}
}
} else {
cc_log("failed to put %s in the cache (%s)\n", src, strerror(errno));
stats_update(STATS_ERROR);
}
return ret;
}
/* copy file out of the cache with error checking taking into account compression and hard linking if desired */
int retrieve_from_cache(const char *src, const char *dest, int hardlink)
{
int ret = 0;
x_utimes(src);
if (strcmp(dest, "/dev/null") == 0) {
ret = 0;
} else {
unlink(dest);
/* only make a hardlink if the cache file is uncompressed */
if (hardlink && test_if_compressed(src) == 0) {
#ifdef _WIN32
ret = CreateHardLinkA(dest, src, NULL) ? 0 : -1;
#else
ret = link(src, dest);
#endif
} else {
ret = copy_file_from_cache(src, dest);
}
}
/* the cached file might have been deleted by some external process */
if (ret == -1 && errno == ENOENT) {
cc_log("hashfile missing for %s\n", dest);
stats_update(STATS_MISSING);
return -1;
}
if (ret == -1) {
ret = copy_file_from_cache(src, dest);
if (ret == -1) {
cc_log("failed to retrieve %s -> %s (%s)\n", src, dest, strerror(errno));
stats_update(STATS_ERROR);
return -1;
}
}
return ret;
}
/* make sure a directory exists */
int create_dir(const char *dir)
{
struct stat st;
if (stat(dir, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
return 0;
}
errno = ENOTDIR;
return 1;
}
#ifdef _WIN32
if (mkdir(dir) != 0 && errno != EEXIST) {
return 1;
}
#else
if (mkdir(dir, 0777) != 0 && errno != EEXIST) {
return 1;
}
#endif
return 0;
}
char const CACHEDIR_TAG[] =
"Signature: 8a477f597d28d172789f06886806bc55\n"
"# This file is a cache directory tag created by ccache.\n"
"# For information about cache directory tags, see:\n"
"# http://www.brynosaurus.com/cachedir/\n";
int create_cachedirtag(const char *dir)
{
char *filename;
struct stat st;
FILE *f;
x_asprintf(&filename, "%s/CACHEDIR.TAG", dir);
if (stat(filename, &st) == 0) {
if (S_ISREG(st.st_mode)) {
goto success;
}
errno = EEXIST;
goto error;
}
f = fopen(filename, "w");
if (!f) goto error;
if (fwrite(CACHEDIR_TAG, sizeof(CACHEDIR_TAG)-1, 1, f) != 1) {
goto error;
}
if (fclose(f)) goto error;
success:
free(filename);
return 0;
error:
free(filename);
return 1;
}
/*
this is like asprintf() but dies if the malloc fails
note that we use vsnprintf in a rather poor way to make this more portable
*/
void x_asprintf(char **ptr, const char *format, ...)
{
va_list ap;
*ptr = NULL;
va_start(ap, format);
if (vasprintf(ptr, format, ap) == -1) {
fatal("out of memory in x_asprintf");
}
va_end(ap);
if (!ptr) fatal("out of memory in x_asprintf");
}
/*
this is like strdup() but dies if the malloc fails
*/
char *x_strdup(const char *s)
{
char *ret;
ret = strdup(s);
if (!ret) {
fatal("out of memory in strdup\n");
}
return ret;
}
/*
this is like malloc() but dies if the malloc fails
*/
void *x_malloc(size_t size)
{
void *ret;
ret = malloc(size);
if (!ret) {
fatal("out of memory in malloc\n");
}
return ret;
}
/*
this is like realloc() but dies if the malloc fails
*/
void *x_realloc(void *ptr, size_t size)
{
void *p2;
#if 1
/* Avoid invalid read in memcpy below */
p2 = realloc(ptr, size);
if (!p2) {
fatal("out of memory in x_realloc");
}
#else
if (!ptr) return x_malloc(size);
p2 = malloc(size);
if (!p2) {
fatal("out of memory in x_realloc");
}
if (ptr) {
/* Note invalid read as the memcpy reads beyond the memory allocated by ptr */
memcpy(p2, ptr, size);
free(ptr);
}
#endif
return p2;
}
/*
revsusive directory traversal - used for cleanup
fn() is called on all files/dirs in the tree
*/
void traverse(const char *dir, void (*fn)(const char *, struct stat *))
{
DIR *d;
struct dirent *de;
d = opendir(dir);
if (!d) return;
while ((de = readdir(d))) {
char *fname;
struct stat st;
if (strcmp(de->d_name,".") == 0) continue;
if (strcmp(de->d_name,"..") == 0) continue;
if (strlen(de->d_name) == 0) continue;
x_asprintf(&fname, "%s/%s", dir, de->d_name);
#ifdef _WIN32
if (stat(fname, &st))
#else
if (lstat(fname, &st))
#endif
{
if (errno != ENOENT) {
perror(fname);
}
free(fname);
continue;
}
if (S_ISDIR(st.st_mode)) {
traverse(fname, fn);
}
fn(fname, &st);
free(fname);
}
closedir(d);
}
/* return the base name of a file - caller frees */
char *str_basename(const char *s)
{
char *p = strrchr(s, '/');
if (p) {
s = (p+1);
}
#ifdef _WIN32
p = strrchr(s, '\\');
if (p) {
s = (p+1);
}
#endif
return x_strdup(s);
}
/* return the dir name of a file - caller frees */
char *dirname(char *s)
{
char *p;
s = x_strdup(s);
p = strrchr(s, '/');
#ifdef _WIN32
p = strrchr(s, '\\');
#endif
if (p) {
*p = 0;
}
return s;
}
/*
http://www.ecst.csuchico.edu/~beej/guide/ipc/flock.html
http://cvs.php.net/viewvc.cgi/php-src/win32/flock.c?revision=1.2&view=markup
Should return 0 for success, >0 otherwise
*/
int lock_fd(int fd)
{
#ifdef _WIN32
# if 1
return _locking(fd, _LK_NBLCK, 1);
# else
HANDLE fl = (HANDLE)_get_osfhandle(fd);
OVERLAPPED o;
memset(&o, 0, sizeof(o));
return (LockFileEx(fl, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &o))
? 0 : GetLastError();
# endif
#else
struct flock fl;
int ret;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 1;
fl.l_pid = 0;
/* not sure why we would be getting a signal here,
but one user claimed it is possible */
do {
ret = fcntl(fd, F_SETLKW, &fl);
} while (ret == -1 && errno == EINTR);
return ret;
#endif
}
/* return size on disk of a file */
size_t file_size(struct stat *st)
{
#ifdef _WIN32
return (st->st_size + 1023) & ~1023;
#else
size_t size = st->st_blocks * 512;
if ((size_t)st->st_size > size) {
/* probably a broken stat() call ... */
size = (st->st_size + 1023) & ~1023;
}
return size;
#endif
}
/* a safe open/create for read-write */
int safe_open(const char *fname)
{
int fd = open(fname, O_RDWR|O_BINARY);
if (fd == -1 && errno == ENOENT) {
fd = open(fname, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0666);
if (fd == -1 && errno == EEXIST) {
fd = open(fname, O_RDWR|O_BINARY);
}
}
return fd;
}
/* display a kilobyte unsigned value in M, k or G */
void display_size(unsigned v)
{
if (v > 1024*1024) {
printf("%8.1f Gbytes", v/((double)(1024*1024)));
} else if (v > 1024) {
printf("%8.1f Mbytes", v/((double)(1024)));
} else {
printf("%8u Kbytes", v);
}
}
/* return a value in multiples of 1024 give a string that can end
in K, M or G
*/
size_t value_units(const char *s)
{
char m;
double v = atof(s);
m = s[strlen(s)-1];
switch (m) {
case 'G':
case 'g':
default:
v *= 1024*1024;
break;
case 'M':
case 'm':
v *= 1024;
break;
case 'K':
case 'k':
v *= 1;
break;
}
return (size_t)v;
}
/*
a sane realpath() function, trying to cope with stupid path limits and
a broken API
*/
char *x_realpath(const char *path)
{
#ifdef _WIN32
char namebuf[MAX_PATH];
DWORD ret;
ret = GetFullPathNameA(path, sizeof(namebuf), namebuf, NULL);
if (ret == 0 || ret >= sizeof(namebuf)) {
return NULL;
}
return x_strdup(namebuf);
#else
int maxlen;
char *ret, *p;
#ifdef PATH_MAX
maxlen = PATH_MAX;
#elif defined(MAXPATHLEN)
maxlen = MAXPATHLEN;
#elif defined(_PC_PATH_MAX)
maxlen = pathconf(path, _PC_PATH_MAX);
#endif
if (maxlen < 4096) maxlen = 4096;
ret = x_malloc(maxlen);
#if HAVE_REALPATH
p = realpath(path, ret);
#else
/* yes, there are such systems. This replacement relies on
the fact that when we call x_realpath we only care about symlinks */
{
int len = readlink(path, ret, maxlen-1);
if (len == -1) {
free(ret);
return NULL;
}
ret[len] = 0;
p = ret;
}
#endif
if (p) {
p = x_strdup(p);
free(ret);
return p;
}
free(ret);
return NULL;
#endif
}
/* a getcwd that will returns an allocated buffer */
char *gnu_getcwd(void)
{
unsigned size = 128;
while (1) {
char *buffer = (char *)x_malloc(size);
if (getcwd(buffer, size) == buffer) {
return buffer;
}
free(buffer);
if (errno != ERANGE) {
return 0;
}
size *= 2;
}
}
/* create an empty file */
int create_empty_file(const char *fname)
{
int fd;
fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
if (fd == -1) {
return -1;
}
close(fd);
return 0;
}
/*
return current users home directory or die
*/
const char *get_home_directory(void)
{
#ifdef _WIN32
static char home_path[MAX_PATH] = {0};
HRESULT ret;
/* we already have the path */
if (home_path[0] != 0) {
return home_path;
}
/* get the path to "Application Data" folder */
ret = SHGetFolderPathA(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, home_path);
if (SUCCEEDED(ret)) {
return home_path;
}
fprintf(stderr, "ccache: Unable to determine home directory\n");
return NULL;
#else
const char *p = getenv("HOME");
if (p) {
return p;
}
#ifdef HAVE_GETPWUID
{
struct passwd *pwd = getpwuid(getuid());
if (pwd) {
return pwd->pw_dir;
}
}
#endif
fatal("Unable to determine home directory");
return NULL;
#endif
}
int x_utimes(const char *filename)
{
#ifdef HAVE_UTIMES
return utimes(filename, NULL);
#else
return utime(filename, NULL);
#endif
}
#ifdef _WIN32
/* perror for Win32 API calls, using GetLastError() instead of errno */
void perror_win32(LPTSTR pszFunction)
{
LPTSTR pszMessage;
DWORD dwLastError = GetLastError();
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&pszMessage,
0, NULL );
fprintf(stderr, "%s: %s\n", pszFunction, pszMessage);
LocalFree(pszMessage);
}
#endif

158
CCache/web/index.html Normal file
View file

@ -0,0 +1,158 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<TITLE>ccache</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffff" TEXT="#000000" VLINK="#292555" LINK="#292555" ALINK="#cc0033">
<h2>ccache</h2>
ccache is a compiler cache. It acts as a caching pre-processor to
C/C++ compilers, using the -E compiler switch and a hash to detect
when a compilation can be satisfied from cache. This often results in
a 5 to 10 times speedup in common compilations.<p>
The idea came from Erik Thiele wrote the original <a
href="http://compilercache.sourceforge.net/">compilercache</a> program
as a bourne shell script. ccache is a re-implementation of Erik's idea
in C with more features and better performance.<p>
<h2>Latest release</h2>
The latest release is ccache 2.4.
<ul>
<li>Added CCACHE_READONLY option
<li>Added CCACHE_TEMPDIR option
<li>fixed handling of hard-linked compilers on AIX
<li>added O_BINARY support, to try and support win32 compiles
<li>show cache directory in stats output
<li>fixed handling of HOME environment variable
</ul>
See the <a href="ccache-man.html">manual page</a> for details
on the new options.<p>
You can get this release from the <a href="http://ccache.samba.org/ftp/ccache/">download directory</a>
<p>NOTE! This release changes the hash input slighly, so you will
probably find that you will not get any hits against your existing
cache when you upgrade.
<h2>Why bother?</h2>
Why bother with a compiler cache? If you ever run "make clean; make"
then you can probably benefit from ccache. It is very common for
developers to do a clean build of a project for a whole host of
reasons, and this throws away all the information from your previous
compiles.<p>
By using ccache you can get exactly the same effect as "make clean;
make" but much faster. It also helps a lot when doing RPM builds,
as RPM can make doing incremental builds tricky.<p>
I put the effort into writing ccache for 2 reasons. The first is the
Samba build farm
(<a href="http://build.samba.org/">http://build.samba.org/</a>)
which constantly does clean builds of Samba on about 30 machines after each
CVS commit. On some of those machines the build took over an hour. By
using ccache we get the same effect as clean builds but about 6 times
faster.<p>
The second reason is the autobuild system I used to run for
Quantum. That system builds our whole Linux based OS from scratch
after every CVS commit to catch compilation problems quickly. Using
ccache those builds are much faster.
<h2>Is it safe?</h2>
Yes. The most important aspect of a compiler cache is to <b>always</b>
produce exactly the same output that the real compiler would
produce. The includes providing exactly the same object files and
exactly the same compiler warnings that would be produced if you use
the real compiler. The only way you should be able to tell that you
are using ccache is the speed.<p>
I have coded ccache very carefully to try to provide these guarantees.
<h2>Features</h2>
<ul>
<li> keeps statistics on hits/misses
<li> automatic cache size management
<li> can cache compiles that generate warnings
<li> easy installation
<li> very low overhead
<li> uses hard links where possible to avoid copies
</ul>
<h2>Documentation</h2>
See the <a href="ccache-man.html">manual page</a>
<h2>Performance</h2>
Here are some results for compiling Samba on my Linux laptop. I have
also included the results of using Erik's compilercache program
(version 1.0.10) for comparison.<p>
<table border=1>
<tr><th> </th> <th>&nbsp;&nbsp;&nbsp;&nbsp;ccache</th> <th>&nbsp;compilercache</th> </tr>
<tr><td>normal </td> <td align=right>13m 4s </td><td align=right>13m 4s</td> </tr>
<tr><td>uncached </td> <td align=right>13m 15s </td><td align=right>15m 41s</td> </tr>
<tr><td>cached </td> <td align=right>2m 45s </td><td align=right>4m 26s</td> </tr>
</table>
<h2>How to use it</h2>
You can use ccache in two ways. The first is just to prefix your
compile commands with "ccache". For example, you could change the
"CC=gcc" line in your Makefile to be "CC=ccache gcc".<p>
Alternatively, you can create symbolic links from your compilers name
to ccache. This allows you to use ccache without any changes to your
build system.
<h2>Download</h2>
You can download the latest release from the <a
href="http://ccache.samba.org/ftp/ccache/">download directory</a>.<p>
For the bleeding edge, you can fetch ccache via CVS or
rsync. To fetch via cvs use the following command:
<pre>
cvs -d :pserver:cvs@pserver.samba.org:/cvsroot co ccache
</pre>
To fetch via rsync use this command:
<pre>
rsync -Pavz samba.org::ftp/unpacked/ccache .
</pre>
<h2>Related projects</h2>
Here are some related programs you may find interesting
<ul>
<li> <a href="http://distcc.samba.org/">distcc</a> - a distributed compilation system
<li> <a href="http://cachecc1.sourceforge.net/">cachecc1</a> - a gcc specific cache
<li> <a href="http://sourceforge.net/projects/gocache/">gocache</a> - a cross platform compiler cache
</ul>
<p>
<h2>Mailing list</h2>
<p>A <a href="http://lists.samba.org/mailman/listinfo/ccache/">mailing
list</a> is available for discussion of ccache.
<hr>
<tiny>
<a href="http://samba.org/~tridge/">Andrew Tridgell</a><br>
<a href="mailto:bugs@ccache.samba.org">bugs@ccache.samba.org</a>
</tiny>
</BODY>
</HTML>

21418
CHANGES Normal file

File diff suppressed because it is too large Load diff

41
CHANGES.current Normal file
View file

@ -0,0 +1,41 @@
This file contains the changes for the current release.
See the CHANGES file for changes in older releases.
See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.2 (in progress)
===========================
2010-12-07: iant
*** POTENTIAL INCOMPATIBILITY ***
Check that we are using a sufficiently new version of the
6g or 8g Go compiler. If not, disable Go.
2010-12-06: wsfulton
Fix #3127394 - use of network paths on Windows/MSys.
2010-11-18: klickverbot
[D] Added the D language module.
2010-11-12: vadz
Fix handling of multiple regex-using %renames attached to the same
declaration. For example, now
%rename("%(regex/^Set(.*)/put\\1/)s") "";
%rename("%(regex/^Get(.*)/get\\1/)s") "";
works as expected whereas before only the last anonymous rename was
taken into account.
2010-10-17: drjoe
[R] Fix failure in overloaded functions which was breaking
QuantLib-SWIG
2010-10-14: olly
[PHP] Allow compilation on non-conforming Microsoft C++ compilers
which don't accept: return function_returning_void();
Reported by Frank Vanden Berghen on the SWIG mailing list.
2010-10-12: wsfulton
Fix unary scope operator (::) (global scope) regression introduced in 2.0.0, reported by
Ben Walker. The mangled symbol names were incorrect, sometimes resulting in types being
incorrectly treated as opaque types.

101
COPYRIGHT Normal file
View file

@ -0,0 +1,101 @@
SWIG Copyright and Authors
--------------------------
Copyright (c) 1995-2010 The SWIG Developers
Copyright (c) 2005-2006 Arizona Board of Regents (University of Arizona).
Copyright (c) 1998-2005 University of Chicago.
Copyright (c) 1995-1998 The University of Utah and the Regents of the University of California
Portions also copyrighted by:
Network Applied Communication Laboratory, Inc
Information-technology Promotion Agency, Japan
Active SWIG Developers:
William Fulton (wsf@fultondesigns.co.uk) (SWIG core, Java, C#, Windows, Cygwin)
Olly Betts (olly@survex.com) (PHP)
Joseph Wang (joequant@gmail.com) (R)
Xavier Delacour (xavier.delacour@gmail.com) (Octave)
Past SWIG developers and major contributors include:
Dave Beazley (dave-swig@dabeaz.com) (SWIG core, Python, Tcl, Perl)
Henning Thielemann (swig@henning-thielemann.de) (Modula3)
Matthias Köppe (mkoeppe@mail.math.uni-magdeburg.de) (Guile, MzScheme)
Luigi Ballabio (luigi.ballabio@fastwebnet.it) (STL wrapping)
Mikel Bancroft (mikel@franz.com) (Allegro CL)
Surendra Singhi (efuzzyone@netscape.net) (CLISP, CFFI)
Marcelo Matus (mmatus@acms.arizona.edu) (SWIG core, Python, UTL[python,perl,tcl,ruby])
Art Yerkes (ayerkes@speakeasy.net) (Ocaml)
Lyle Johnson (lyle@users.sourceforge.net) (Ruby)
Charlie Savage (cfis@interserv.com) (Ruby)
Thien-Thi Nguyen (ttn@glug.org) (build/test/misc)
Richard Palmer (richard@magicality.org) (PHP)
Sam Liddicott - Ananova Ltd (saml@liddicott.com) (PHP)
Tim Hockin - Sun Microsystems (thockin@sun.com) (PHP)
Kevin Ruland (PHP)
Shibukawa Yoshiki (Japanese Translation)
Jason Stewart (jason@openinformatics.com) (Perl5)
Loic Dachary (Perl5)
David Fletcher (Perl5)
Gary Holt (Perl5)
Masaki Fukushima (Ruby)
Scott Michel (scottm@cs.ucla.edu) (Java directors)
Tiger Feng (songyanf@cs.uchicago.edu) (SWIG core)
Mark Rose (mrose@stm.lbl.gov) (Directors)
Jonah Beckford (beckford@usermail.com) (CHICKEN)
Ahmon Dancy (dancy@franz.com) (Allegro CL)
Dirk Gerrits (Allegro CL)
Neil Cawse (C#)
Harco de Hilster (Java)
Alexey Dyachenko (dyachenko@fromru.com) (Tcl)
Bob Techentin (Tcl)
Martin Froehlich <MartinFroehlich@ACM.org> (Guile)
Marcio Luis Teixeira <marciot@holly.colostate.edu> (Guile)
Duncan Temple Lang (R)
Miklos Vajna <vmiklos@frugalware.org> (PHP directors)
Mark Gossage (mark@gossage.cjb.net) (Lua)
Gonzalo Garramuno (ggarra@advancedsl.com.ar) (Ruby, Ruby's UTL)
John Lenz (Guile, MzScheme updates, Chicken module, runtime system)
Ian Lance Taylor (Go)
Vadim Zeitlin (PCRE)
Past contributors include:
James Michael DuPont, Clark McGrew, Dustin Mitchell, Ian Cooke, Catalin Dumitrescu, Baran
Kovuk, Oleg Tolmatcev, Tal Shalif, Lluis Padro, Chris Seatory, Igor Bely, Robin Dunn,
Edward Zimmermann, David Ascher, Dominique Dumont, Pier Giorgio Esposito, Hasan Baran Kovuk,
Klaus Wiederänders
(See CHANGES and CHANGES.current and the bug tracker for a more complete list).
Past students:
Songyan Feng (Chicago).
Xinghua Shi (Chicago).
Jing Cao (Chicago).
Aquinas Hobor (Chicago).
Historically, the following people contributed to early versions of SWIG.
Peter Lomdahl, Brad Holian, Shujia Zhou, Niels Jensen, and Tim Germann
at Los Alamos National Laboratory were the first users. Patrick
Tullmann at the University of Utah suggested the idea of automatic
documentation generation. John Schmidt and Kurtis Bleeker at the
University of Utah tested out the early versions. Chris Johnson
supported SWIG's developed at the University of Utah. John Buckman,
Larry Virden, and Tom Schwaller provided valuable input on the first
releases and improving the portability of SWIG. David Fletcher and
Gary Holt have provided a great deal of input on improving SWIG's
Perl5 implementation. Kevin Butler contributed the first Windows NT
port.
Early bug reports and patches:
Adam Hupp, Arthur Smyles, Brad Clements, Brett Williams, Buck Hodges,
Burkhard Kloss, Chia-Liang Kao, Craig Files, Dennis Marsa, Dieter Baron,
Drake Diedrich, Fleur Diana Dragan, Gary Pennington, Geoffrey Hort, Gerald Williams,
Greg Anderson, Greg Kochanski, Greg Troxel, Henry Rowley, Irina Kotlova,
Israel Taller, James Bailey, Jim Fulton, Joel Reed, Jon Travis,
Junio Hamano, Justin Heyes-Jones, Karl Forner, Keith Davidson,
Krzysztof Kozminski, Larry Virden, Luke J Crook, Magnus Ljung, Marc Zonzon,
Mark Howson, Micahel Scharf, Michel Sanner, Mike Romberg, Mike Simons,
Mike Weiblen, Paul Brannan, Ram Bhamidipaty, Reinhard Fobbe, Rich Wales,
Richard Salz, Roy Lecates, Rudy Albachten, Scott Drummonds
Scott Michel, Shaun Lowry, Steve Galser, Tarn Weisner Burton,
Thomas Weidner, Tony Seward, Uwe Steinmann, Vadim Chugunov, Wyss Clemens,
Zhong Ren.

79
Doc/Devel/cmdopt.html Normal file
View file

@ -0,0 +1,79 @@
<html>
<head>
<title>SWIG Command Line Handling</title>
</head>
<body>
<center>
<h1>SWIG Command Line Handling</h1>
<p>
David M. Beazley <br>
dave-swig@dabeaz.com<br>
December, 2006<br>
</b>
</center>
<h2>Introduction</h2>
This document describes the functions related to the handling of
command line options passed to SWIG. These functions are defined in
the header file <tt>Source/Swig/swigopt.h</tt>. This API is
considered to be stable.
<h2>Initialization</h2>
Upon SWIG startup, the following function is called:
<p>
<b><tt>void Swig_init_args(int argc, char **argv_)</tt></b>
<blockquote>
Registers command line options with the SWIG core. This creates an internal array that is used by other
functions to mark whether or not a particular command line option was used. This is ultimately used to issue error messages about unused or unknown command line options. This function is currently invoked in the SWIG main() function that is found in <tt>Source/Modules/swigmain.cxx</tt>.
</blockquote>
<h2>Argument Marking</h2>
As command line options are processed by language modules, the following functions are used
to mark the arguments as used:
<p>
<b><tt>void Swig_mark_arg(int n)</tt></b>
<blockquote>
Mark argument number <tt>n</tt> as used.
</blockquote>
<p>
<b><tt>int Swig_check_marked(int n)</tt></b>
<blockquote>
Check to see if argument <tt>n</tt> has been marked. Returns 0 or 1.
</blockquote>
<h2>Argument Checking</h2>
The following function is used to check all of the command line options after parsing. It looks at the marked list
and issues an error message if any unconsumed arguments are found.
<p>
<b><tt>void Swig_check_options()</tt></b>
<blockquote>
Checks all command line options to see if they have all been processed. If not, an error message is generated and
execution terminates with a call to <tt>exit()</tt>. This function is currently invoked in <tt>Source/Modules/main.cxx</tt> just before SWIG starts any processing of input files.
</blockquote>
<h2>Utility Function</h2>
<p>
<b><tt>void Swig_arg_error())</tt></b>
<blockquote>
A generic function that issues an error message about being unable to parse command line options. SWIG is terminated by a call to <tt>exit()</tt>.
</body>
</html>

414
Doc/Devel/engineering.html Normal file
View file

@ -0,0 +1,414 @@
<html>
<head>
<title>SWIG Engineering Manual</title>
</head>
<body bgcolor="#ffffff">
<center>
<h1>SWIG Engineering Manual</h1>
<b>David Beazley <br>
</b>
</center>
<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. SVN 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="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 inadvertently
creating two files that differ in case-only.
<p>
Each file should include a short abstract, license information and
a SVN revision tag like this:
<blockquote>
<pre>
/* -----------------------------------------------------------------------------
* This file is part of SWIG, which is licensed as a whole under version 3
* (or any later version) of the GNU General Public License. Some additional
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
* included with the SWIG source code as distributed by the SWIG developers
* and at http://www.swig.org/legal.html.
*
* xxx.c
*
* This file defines ...
* ----------------------------------------------------------------------------- */
static char cvs[] = "&#36Id&#36";
#include "swig.h"
/* Declarations */
typedef struct {
int x, y;
} Foo;
...
/* Private Declarations (used only in this file) */
static int avariable;
...
/* Functions */
...
</pre>
</blockquote>
The SVN revision tag should be placed into a static string as shown
above mangled with the name of the file.
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 unmanageable 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 &lt;stdio.h&gt;
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>
These are largely covered in the main documentation in the Extending.html file.
<a name="11" href="#i11">
<h2>11. SVN Tagging Conventions</h2>
</a>
Use <tt>svn 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 svn 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-2004 SWIG Development Team.
</body>
</html>

181
Doc/Devel/file.html Normal file
View file

@ -0,0 +1,181 @@
<html>
<head>
<title>SWIG File Handling</title>
</head>
<body>
<center>
<h1>SWIG File Handling</h1>
<p>
David M. Beazley <br>
dave-swig@dabeaz.com<br>
December, 2006<br>
</b>
</center>
<h2>Introduction</h2>
This document describes the functions related to file and filename handling in the SWIG core. These functions are
defined in the header file <tt>Source/Swig/swigfile.h</tt>. This API is considered to be stable.
<h2>File Search Path</h2>
These functions manipulate the search path for locating files.
<p>
<b><tt>List *Swig_add_directory(const String_or_char *dirname)</tt></b>
<blockquote>
Adds a new directory to the system search path. The directory is appended to
the end of the search path. Returns a list containing the current
system search path.
</blockquote>
<p>
<b><tt>void Swig_push_directory(const String_or_char *dirname)</tt></b>
<blockquote>
Pushes a temporary directory onto the search path. This directory is searched before
directories added with <tt>Swig_add_directory()</tt> except when including a system
file explicitly (either using #include &lt;file&gt; or calling <tt>Swig_include_sys()</tt>).
This function is normally used by the preprocessor to add temporary directories when
processing #include statements.
</blockquote>
<p>
<b><tt>void Swig_pop_directory()</tt></b>
<blockquote>
Pops off the last pushed directory with <tt>Swig_push_directory()</tt>
</blockquote>
<p>
<b><tt>int Swig_get_push_dir()</tt></b>
<blockquote>
Returns a flag that indicates whether directory pushing is enabled or not.
</blockquote>
<p>
<b><tt>void Swig_set_push_dir(int dopush)</tt></b>
<blockquote>
Enables or disables directory pushing. By default, it is turned on. However, the <tt>-I-</tt> command line
option to SWIG disables it.
</blockquote>
<p>
<b><tt>List *Swig_search_path()</tt></b>
<blockquote>
Returns the current search path.
</blockquote>
<h2>File access functions</h2>
<p>
<b><tt>FILE *Swig_open(const String_or_char *name)</tt></b>
<blockquote>
Opens a file, using the applicable search paths, and returns an open <tt>FILE *</tt> object if found. Returns NULL if the file is not found.
</blockquote>
<p>
<b><tt>String *Swig_read_file(FILE *f)</tt></b>
<blockquote>
Reads all of the data from an open file into a string which is returned.
</blockquote>
<p>
<b><tt>String *Swig_include(const String_or_char *name)</tt></b>
<blockquote>
Searches for an include file <tt>name</tt> and returns its contents as
a string if found. Returns NULL if not found. All of the applicable
search paths are searched when trying to locate the file.
</blockquote>
<p>
<b><tt>String *Swig_include_sys(const String_or_char *name)</tt></b>
<blockquote>
Searches for an include file <tt>name</tt> and returns its contents as
a string if found. Returns NULL if not found. All of the applicable
search paths are searched when trying to locate the file, but
preference is given to system paths first. This mimics the behavior
of <tt>#include &lt;file&gt;</tt> in the preprocessor.
</blockquote>
<p>
<b><tt>int Swig_insert_file(const String_or_char *name, File *outfile)</tt></b>
<blockquote>
Searches for a file <tt>name</tt> and dumps its contents to <tt>outfile</tt> if found.
Returns 0 on success, -1 if the file couldn't be found.
</blockquote>
<h2>Query functions</h2>
<p>
<b><tt>String *Swig_last_file()</tt></b>
<blockquote>
Returns the full pathname of the file last opened or included.
</blockquote>
<h2>Named files</h2>
<p>
<b><tt>void *Swig_register_filebyname(const String_or_char *filename, File *outfile)</tt></b>
<blockquote>
Registers a file object <tt>outfile</tt> with a specific name <tt>filename</tt>. This function is
used to implement the SWIG %insert directive and to manage different sections of the output
file such as "runtime","header","wrapper","init", etc. Different language modules may add their own
sections for generating Python code, Perl code, etc.
</blockquote>
<p>
<b><tt>File *Swig_filebyname(const String_or_char *filename)</tt></b>
<blockquote>
This looks up a file object previously registered using <tt>Swig_register_filebyname()</tt>. This
is used to implement the %insert directive.
</blockquote>
<h2>Filename utilities</h2>
<p>
<b><tt>char *Swig_file_suffix(const String_or_char *filename)</tt></b>
<blockquote>
Returns the suffix of a filename. For instance, if the filename is "foo.txt", it returns ".txt".
</blockquote>
<p>
<b><tt>char *Swig_file_basename(const String_or_char *filename)</tt></b>
<blockquote>
Returns the filename without the suffix attached to it. For instance, if the filename is "foo.txt", it returns
"foo". The result is stored in a static variable. If you need to save it, make your own copy.
</blockquote>
<p>
<b><tt>char *Swig_file_filename(const String_or_char *filename)</tt></b>
<blockquote>
Returns the filename without any leading directories. For instance, if the filename is "/bar/spam/foo.txt", it
returns "foo.txt". This function is aware of local naming conventions on the machine (e.g., forward versus back slashes on Unix and Windows). The result is stored in a static variable. If you need to save the value, make a copy.
</blockquote>
<p>
<b><tt>char *Swig_file_dirname(const String_or_char *filename)</tt></b>
<blockquote>
Returns the directory name (if any). For instance, if the filename is "/bar/spam/foo.txt", it
returns "/bar/spam/". This function is aware of local naming conventions on the machine (e.g., forward versus back slashes on Unix and Windows). The result is stored in a static variable. If you need to save the value, make a copy.
</blockquote>
<p>
<b><tt>SWIG_FILE_DELIMITER</tt></b>
<blockquote>
This macro contains the file delimiter string for the local machine. On Unix it is "/", on Windows it is "\\".
</blockquote>
</body>
</html>

30
Doc/Devel/index.html Normal file
View file

@ -0,0 +1,30 @@
<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>
The following documentation describe the internal APIs used by SWIG. These may be useful to module developers.
<ul>
<li><a href="file.html">File handling functions</a>
<li><a href="cmdopt.html">Command line arguments</a>
<li><a href="tree.html">Parse tree navigation and manipulation</a>
<li><a href="parm.html">Parameter and Parameter list handling functions</a>
<li><a href="scanner.html">Generic C/C++ Scanner interface</a>
<li><a href="wrapobj.html">Wrapper objects</a>.
</ul>
<hr>
Copyright (C) 1999-2007 SWIG Development Team.
</body>
</html>

1186
Doc/Devel/internals.html Normal file

File diff suppressed because it is too large Load diff

140
Doc/Devel/migrate.txt Normal file
View 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.

102
Doc/Devel/parm.html Normal file
View file

@ -0,0 +1,102 @@
<html>
<head>
<title>SWIG Parameter Handling</title>
</head>
<body>
<center>
<h1>SWIG Parameter Handling</h1>
<p>
David M. Beazley <br>
dave-swig@dabeaz.com<br>
January 9, 2007<br>
</b>
</center>
<h2>Introduction</h2>
This document describes the functions related to management of function parameters and parameter lists in the SWIG core. These functions are declared in <tt>Source/Swig/swigparm.h</tt>. This API is considered to be stable.
<h2>Parameters</h2>
The following utility functions are used to create and copy individual parameters. In their most basic form, a parameter merely contains a type, a name, and an optional default value.
<p>
<b><tt>Parm *NewParm(SwigType *type, const String_or_char *name)</tt></b>
<blockquote>
Creates a new parameter object with type <tt>type</tt> and name <tt>name</tt>. The type is stored in the attribute "type" and the name is stored in the attribute "name".
</blockquote>
<p>
<b><tt>Parm *CopyParm(Parm *p)</tt></b>
<blockquote>
Copies a parameter object. All string attributes are copied in the
process of making the copy. However, no complex attributes (lists,
hashes, etc.) are copied.
</blockquote>
<h2>Parameter Lists</h2>
<p>
<b><tt>ParmList *CopyParmList(ParmList *p)</tt></b>
<blockquote>
Creates a copy of a parameter list. A parameter list is merely a linked list of parameters created by NewParm().
</blockquote>
<p>
<b><tt>ParmList *CopyParmListMax(ParmList *p, int count)</tt></b>
<blockquote>
Copies at most <tt>count</tt> parameters from the parameter list <tt>p</tt>.
</blockquote>
<p>
<b><tt>int ParmList_len(ParmList *p)</tt></b>
<blockquote>
Returns the total number of parameters in a parameter list.
</blockquote>
<p>
<b><tt>int ParmList_numrequired(ParmList *p)</tt></b>
<blockquote>
Returns the number of required parameters in a parameter list. This pertains to invoking a function/method in C/C++.
</blockquote>
<p>
<b><tt>int ParmList_has_defaultargs(ParmList *p)</tt></b>
<blockquote>
Returns 1 if the parameter list has any default arguments. Otherwise returns 0.
</blockquote>
<h2>Code Generation Functions</h2>
<p>
<b><tt>String *ParmList_str(ParmList *p)</tt></b>
<blockquote>
Creates a C prototype string of the parameters, but without any default values.
</blockquote>
<p>
<b><tt>String *ParmList_str_defaultargs(ParmList *p)</tt></b>
<blockquote>
Creates a C prototype string of the parameters and includes the default values (if any).
</blockquote>
<p>
<b><tt>String *ParmList_protostr(ParmList *p)</tt></b>
<blockquote>
Creates a C prototype string of the parameters.
</blockquote>
</body>
</html>

169
Doc/Devel/runtime.txt Normal file
View file

@ -0,0 +1,169 @@
This file describes the necessary functions and interfaces a language module
needs to implement to take advantage of the run time type system. I assume you
have read the run-time section of the Typemaps chapter in the SWIG
documentation.
Last updated: February 23, 2005
The file we are concerned with here should be named langrun.swg. A good example
of a simple file is the Lib/mzscheme/mzrun.swg file. First, a few requirements
and notes:
1) Every function in this file should be declared static.
2) It should be inserted into the runtime section of the _wrap file from your
config file. The Lib/swigrun.swg file should be included before this file.
That is, you need to have
%runtime "swigrun.swg"
%runtime "langrun.swg"
3) You must also include the swiginit.swg file in the init section of the
wrapper. That is, you should have
%insert(init) "swiginit.swg"
4) From module.cxx, you need to call the SwigType_emit_type_table function, as
well as register types with SwigType_remember or SwigType_remember_clientdata
5) By convention, all functions in this file are of the form
SWIG_Language_Whatever, and #defines are used to rename SWIG API functions to
these function names
6) You need to call void SWIG_InitializeModule(void *clientdata) from your init
function.
7) You need to implement the runtimeCode() and defaultExternalRuntimeFilename()
functions inside module.cxx. runtimeCode should return all the language
specific runtime code as a string, and defaultExternalRuntimeFilename should
return a string for the default name of the external runtime header. This is
usually "swigpyrun.h", where "py" is replaced by the language name. These
two functions are used by the -external-runtime argument.
-------------------------------------------------------------------------------
Required Functions
-------------------------------------------------------------------------------
swig_module_info *SWIG_GetModule(void *clientdata);
void SWIG_SetModule(void *clientdata, swig_module_info *mod);
The SetModule function should store the mod argument into some globally
accessible variable in the target language. The action of these two functions
is to provide a way for multiple modules to share information. The SetModule
function should create a new global var named something like
"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME
SWIG_RUNTIME_VERSION is currently defined as "2", and SWIG_TYPE_TABLE_NAME is
defined by the -DSWIG_TYPE_TABLE=mytable option when compiling the wrapper.
Alternatively, if the language supports modules, a module named
"swig_runtime_data" SWIG_RUNTIME_VERSION can be created, and a global variable
named "type_table" SWIG_TYPE_TABLE_NAME can be created inside it. The most
common approach is to store the mod pointer in some global variable in the
target language, but if the language provides an alternative place to store data
(like the chicken module), then that is good too.
The way the code is set up, SetModule should only be called when GetModule
returns NULL, and if SetModule is called a second time, the behavior is
undefined. Just make sure it doesn't crash in the random chance occurrence that
SetModule is called twice.
There are two options here.
1) The preferred approach is for GetModule and SetModule to not require a
clientdata pointer. If you can at all avoid it, please do so. Here, you would
write swig_module_info *SWIG_Language_GetModule();
void SWIG_Language_SetModule(swig_module_info *mod);
and then add
#define SWIG_GetModule(clientdata) SWIG_Language_GetModule()
#define SWIG_SetModule(cd, ptr) SWIG_Language_SetModule(ptr)
You would then call
SWIG_InitializeModule(0)
2) If GetModule and SetModule need to take a custom pointer (most notably an
environment pointer, see tcl or mzscheme), then you should write
swig_module_info *SWIG_Language_GetModule(void *clientdata)
void SWIG_Language_SetModule(void *clientdata, swig_module_info *mod);
and also define
#define SWIG_GetModule(cd) SWIG_Language_GetModule(cd)
#define SWIG_SetModule(cd, ptr) SWIG_Language_SetModule(cd, ptr)
#define SWIG_MODULE_CLIENTDATA_TYPE Whatever
SWIG_MODULE_CLIENTDATA_TYPE should be defined to whatever the type of
clientdata is.
You would then call SWIG_InitializeModule(clientdata), and clientdata would get
passed to GetModule and SetModule. clientdata will not be stored and will only
be referenced during the InitializeModule call. After InitializeModule returns,
clientdata does not need to be valid any more.
This method is not preferred, because it makes external access to the type
system more complicated. See the Modules chapter of the documentation, and read
the "External access to the run-time" section. Then take a look at
Lib/runtime.swg. Anybody that calls SWIG_TypeQuery needs to pass along the
clientdata pointer, and that is the reason for defining
SWIG_MODULE_CLIENTDATA_TYPE.
-------------------------------------------------------------------------------
Standard Functions
-------------------------------------------------------------------------------
These functions are not required and their API is not formalized, but almost all
language modules implement them for consistency across languages. Throughout
this discussion, I will use LangType to represent the underlying language type
(C_word in chicken, Scheme_Object * in mzscheme, PyObject * in python, etc)
LangObj SWIG_NewPointerObj(void *ptr, swig_type_info *type, int flags);
Create and return a new pointer object that has both ptr and type. For almost
all language modules, flags is used for ownership. If flags==1, then the
created pointer should be registered to be garbage collected.
int SWIG_ConvertPtr(LangType obj, void **result, swig_type_info *type, int flags);
Convert a language wrapped pointer into a void *. The pointer is returned in
result, and the function should return 0 on success, non-zero on error.
A sample ConvertPtr is given here:
swig_cast_info *cast;
if (<obj is a wrapped pointer type>) {
cast = SWIG_TypeCheck(<obj type name>, type);
cast = SWIG_TypeCheckStruct(<obj type structure>, type);
if (cast) {
*result = SWIG_TypeCast(cast, <obj pointer>);
return 0;
}
}
return 1;
Either TypeCheck or TypeCheckStruct can be called, depending on how the pointer
is wrapped in langtype. If obj stores the void pointer and the type name, then
the TypeCheck function should be used, while if obj stores the void pointer and
a pointer to the swig_type_info structure, then the TypeCheckStruct function
should be called. The TypeCheckStruct is slightly faster, since it does a
pointer comparison instead of a strcmp.
The flag argument to ConvertPtr is used in some languages for disowning a
pointer. If the wrapped C function is taking ownership of the pointer (that
means, the wrapped C function is responsible for deleting the object), then that
pointer should be removed from the garbage collector. We do that in the
ConvertPtr function. The pointer is still valid in the target language, but
when the target language type is garbage collected, it will not call the
associated destructor. Languages have a special typemap called DISOWN that can be
applied which passes this argument. All the languages have the flags argument
for consistency, and the flags argument can be ignored or used for some other
purpose.
void *SWIG_MustGetPtr(LangType obj, swig_type_info *type, int flags,
int argnum, const char *func_name) {
void *result;
if (SWIG_ConvertPtr(s, &result, type, flags)) {
generate runtime type error ("Error in func_name, expected a" +
type->str ? type->str : "void *" +
"at argument number" + argnum);
}
return result;
}
This function is optional, and the number and type of parameters can be
different, but is useful for typemap purposes:
%typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] {
$1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, 0, $argnum, FUNC_NAME);
}

283
Doc/Devel/scanner.html Normal file
View file

@ -0,0 +1,283 @@
<html>
<head>
<title>SWIG C Scanner</title>
</head>
<body>
<center>
<h1>SWIG C/C++ Scanning</h1>
<p>
David M. Beazley <br>
dave-swig@dabeaz.com<br>
January 11, 2007<br>
</b>
</center>
<h2>Introduction</h2>
This document describes functions that can be used to tokenize C/C++
input text. These functions are relatively low-level and are meant to
be used in the implementation of scanners that can be plugged into yacc or used for
other purposes. For instance, the preprocessor uses these functions to evaluate and test
constant expressions.
<p>
All of these functions are declared in <tt>Source/Swig/swigscan.h</tt>. This API is considered to be stable.
<h2>Creation and Deletion of Scanners</h2>
The following functions are used to create and destroy a scanner object. More than one scanner object can be created and used
as necessary.
<p>
<b><tt>Scanner *NewScanner()</tt></b>
<blockquote>
Creates a new scanner object. The scanner contains initially contains no text. To feed text to the scanner use <tt>Scanner_push()</tt>.
</blockquote>
<p>
<b><tt>Scanner *DelScanner()</tt></b>
<blockquote>
Deletes a scanner object.
</blockquote>
<h2>Scanner Functions</h2>
<p>
<b><tt>void Scanner_clear(Scanner *s)</tt></b>
<blockquote>
Clears all text from the scanner. This can be used to reset a scanner to its initial state, ready to receive new input text.
</blockquote>
<p>
<b><tt>void Scanner_push(Scanner *s, String *text)</tt></b>
<blockquote>
Pushes an input string into the scanner. Subsequent tokens will be
returned from the new string. If the scanner is already processing a
string, the pushed string takes precedence--in effect, interrupting
the scanning of the previous string. This behavior is used to
implement certain SWIG features such as the <tt>%inline</tt>
directive. Once the pushed string has been completely scanned, the
scanner will return to scanning the previous string (if any). The
scanning of text relies upon the DOH file interface to strings
(<tt>Getc()</tt>, <tt>Ungetc()</tt>, etc.). Prior to calling this
function, the input string should be set so that its file pointer is
in the location where you want scanning to begin. You may have to
use <tt>Seek()</tt> to set the file pointer back to the beginning of a
string prior to using this function.
</blockquote>
<p>
<b><tt>void Scanner_pushtoken(Scanner *s, int tokvalue, String_or_char *val)</tt></b>
<blockquote>
Pushes a token into the scanner. This exact token will be returned by the next call to <tt>Scanner_token()</tt>.
<tt>tokvalue</tt> is the integer token value to return and <tt>val</tt> is the token text to return. This
function is only used to handle very special parsing cases. For instance, if you need the scanner to
return a fictitious token into order to enter a special parsing case.
</blockquote>
<p>
<b><tt>int Scanner_token(Scanner *s)</tt></b>
<blockquote>
Returns the next token. An integer token code is returned (see table below) on success. If no more input text is
available 0 is returned. If a scanning error occurred, -1 is returned. In this case, error information can be
obtained using <tt>Scanner_errinfo()</tt>.
</blockquote>
<p>
<b><tt>String *Scanner_text(Scanner *s)</tt></b>
<blockquote>
Returns the scanned text corresponding to the last token returned by <tt>Scanner_token()</tt>. The returned string
is only valid until the next call to <tt>Scanner_token()</tt>. If you need to save it, make a copy.
</blockquote>
<p>
<b><tt>void Scanner_skip_line(Scanner *s)</tt></b>
<blockquote>
Skips to the end of the current line. The text skipped can be obtained using <tt>Scanner_text()</tt> afterwards.
</blockquote>
<p>
<b><tt>void Scanner_skip_balanced(Scanner *s, int startchar, int endchar)</tt></b>
<blockquote>
Skips to the end of a block of text denoted by starting and ending characters. For example, <tt>{</tt> and <tt>}</tt>. The
function is smart about how it skips text. String literals and comments are ignored. The function also is aware of nesting. The
skipped text can be obtained using <tt>Scanner_text()</tt> afterwards. Returns 0 on success, -1 if no matching <tt>endchar</tt> could be found.
</blockquote>
<p>
<b><tt>void Scanner_set_location(Scanner *s, int startchar, int endchar)</tt></b>
<blockquote>
Changes the current filename and line number of the scanner.
</blockquote>
<p>
<b><tt>String *Scanner_file(Scanner *s)</tt></b>
<blockquote>
Gets the current filename associated with text in the scanner.
</blockquote>
<p>
<b><tt>int Scanner_line(Scanner *s)</tt></b>
<blockquote>
Gets the current line number associated with text in the scanner.
</blockquote>
<p>
<b><tt>int Scanner_start_line(Scanner *s)</tt></b>
<blockquote>
Gets the starting line number of the last token returned by the scanner.
</blockquote>
<p>
<b><tt>void Scanner_idstart(Scanner *s, char *idchar)</tt></b>
<blockquote>
Sets additional characters (other than the C default) that may be used to start C identifiers. <tt>idchar</tt> is a string
containing the characters (e.g., "%@"). The purpose of this function is to up special keywords such as "%module" or "@directive" as
simple identifiers.
</blockquote>
<p>
<b><tt>String *Scanner_errmsg(Scanner *s)</tt></b>
<blockquote>
Returns the error message associated with the last scanner error (if any). This will only return a meaningful result
if <tt>Scanner_token()</tt> returned -1.
</blockquote>
<p>
<b><tt>int Scanner_errline(Scanner *s)</tt></b>
<blockquote>
Returns the line number associated with the last scanner error (if any). This will only return a meaningful result
if <tt>Scanner_token()</tt> returned -1. The line number usually corresponds to the starting line number of a particular
token (e.g., for unterminated strings, comments, etc.).
</blockquote>
<p>
<b><tt>int Scanner_isoperator(int tokval)</tt></b>
<blockquote>
A convenience function that returns 0 or 1 depending on whether <tt>tokval</tt> is a valid C/C++ operator (i.e., a candidate for
operator overloading).
</blockquote>
<p>
<b><tt>void Scanner_freeze_line(int val)</tt></b>
<blockquote>
Freezes the current line number depending upon whether or not <tt>val</tt> is 1 or 0. When the line number is frozen, newline characters will not result in
updates to the line number. This is sometimes useful in tracking line numbers through complicated macro expansions.
</blockquote>
<h2>Token Codes</h2>
The following table shows token codes returned by the scanner. These are integer codes returned by
the <tt>Scanner_token()</tt> function.
<blockquote>
<pre>
Token code C Token
------------------------- -------------
SWIG_TOKEN_LPAREN (
SWIG_TOKEN_RPAREN )
SWIG_TOKEN_SEMI ;
SWIG_TOKEN_COMMA ,
SWIG_TOKEN_STAR *
SWIG_TOKEN_TIMES *
SWIG_TOKEN_LBRACE {
SWIG_TOKEN_RBRACE }
SWIG_TOKEN_EQUAL =
SWIG_TOKEN_EQUALTO ==
SWIG_TOKEN_NOTEQUAL !=
SWIG_TOKEN_PLUS +
SWIG_TOKEN_MINUS -
SWIG_TOKEN_AND &amp;
SWIG_TOKEN_LAND &amp;&amp;
SWIG_TOKEN_OR |
SWIG_TOKEN_LOR ||
SWIG_TOKEN_XOR ^
SWIG_TOKEN_LESSTHAN &lt;
SWIG_TOKEN_GREATERTHAN &gt;
SWIG_TOKEN_LTEQUAL &lt;=
SWIG_TOKEN_GTEQUAL &gt;=
SWIG_TOKEN_NOT ~
SWIG_TOKEN_LNOT !
SWIG_TOKEN_LBRACKET [
SWIG_TOKEN_RBRACKET ]
SWIG_TOKEN_SLASH /
SWIG_TOKEN_DIVIDE /
SWIG_TOKEN_BACKSLASH \
SWIG_TOKEN_POUND #
SWIG_TOKEN_PERCENT %
SWIG_TOKEN_MODULO %
SWIG_TOKEN_COLON :
SWIG_TOKEN_DCOLON ::
SWIG_TOKEN_DCOLONSTAR ::*
SWIG_TOKEN_LSHIFT &lt;&lt;
SWIG_TOKEN_RSHIFT &gt;&gt;
SWIG_TOKEN_QUESTION ?
SWIG_TOKEN_PLUSPLUS ++
SWIG_TOKEN_MINUSMINUS --
SWIG_TOKEN_PLUSEQUAL +=
SWIG_TOKEN_MINUSEQUAL -=
SWIG_TOKEN_TIMESEQUAL *=
SWIG_TOKEN_DIVEQUAL /=
SWIG_TOKEN_ANDEQUAL &amp;=
SWIG_TOKEN_OREQUAL |=
SWIG_TOKEN_XOREQUAL ^=
SWIG_TOKEN_LSEQUAL &lt;&lt;=
SWIG_TOKEN_RSEQUAL &gt;&gt;=
SWIG_TOKEN_MODEQUAL %=
SWIG_TOKEN_ARROW -&gt;
SWIG_TOKEN_ARROWSTAR -&gt;*
SWIG_TOKEN_PERIOD .
SWIG_TOKEN_AT @
SWIG_TOKEN_DOLLAR $
SWIG_TOKEN_ENDLINE Literal newline
SWIG_TOKEN_ID identifier
SWIG_TOKEN_FLOAT Floating point with F suffix (e.g., 3.1415F)
SWIG_TOKEN_DOUBLE Floating point (e.g., 3.1415 )
SWIG_TOKEN_INT Integer (e.g., 314)
SWIG_TOKEN_UINT Unsigned integer (e.g., 314U)
SWIG_TOKEN_LONG Long integer (e.g., 314L)
SWIG_TOKEN_ULONG Unsigned long integer (e.g., 314UL)
SWIG_TOKEN_LONGLONG Long long integer (e.g., 314LL )
SWIG_TOKEN_ULONGLONG Unsigned long long integer (e.g., 314ULL)
SWIG_TOKEN_CHAR Character literal in single quotes ('c')
SWIG_TOKEN_STRING String literal in double quotes ("str")
SWIG_TOKEN_RSTRING Reverse quote string (`str`)
SWIG_TOKEN_CODEBLOCK SWIG code literal block %{ ... %}
SWIG_TOKEN_COMMENT C or C++ comment (// or /* ... */)
SWIG_TOKEN_ILLEGAL Illegal character
</pre>
</blockquote>
<b>Notes</b>
<ul>
<li>When more than one token code exist for the same token text, those codes are identical (e.g., <tt>SWIG_TOKEN_STAR</tt> and <tt>SWIG_TOKEN_TIMES</tt>).
<p>
<li>
String literals are returned in their exact representation in which escape codes (if any) have been interpreted.
<p>
<li>
All C identifiers and keywords are simply returned as <tt>SWIG_TOKEN_ID</tt>. To check for specific keywords, you will need to
add extra checking on the returned text.
<p>
<li>C and C++ comments include the comment starting and ending text (e.g., "//", "/*").
<p>
<li>The maximum token integer value is found in the constant <tt>SWIG_MAXTOKENS</tt>. This can be used if you wanted to create
an array or table for the purposes of remapping tokens to a different set of codes. For instance, if you are
using these functions to write a yacc-compatible lexer.
</ul>
</body>
</html>

284
Doc/Devel/tree.html Normal file
View file

@ -0,0 +1,284 @@
<html>
<head>
<title>SWIG Parse Tree Handling</title>
</head>
<body>
<center>
<h1>SWIG Parse Tree Handling</h1>
</center>
<h2>Introduction</h2>
This document describes the functions related to the handling of
parse trees in SWIG. The structure of SWIG parse trees has been influenced heavily by ideas
from XML-DOM trees. In fact, the functions in the API and attribute names are nearly identical.
The header file <tt>Source/swig/swigtree.h</tt> contains the functions and macros described in
this document. This API is
considered to be stable.
<h2>Parse tree navigation</h2>
The following macros are used to navigate the parse tree.
<p>
<b><tt>nodeType(n)</tt></b>
<blockquote>
Returns the type of a node as a String object. The type is stored in the "nodeType" attribute of <tt>n</tt>.
</blockquote>
<p>
<b><tt>parentNode(n)</tt></b>
<blockquote>
Returns the parent of a node. This is found in the "parentNode" attribute of <tt>n</tt>.
</blockquote>
<p>
<b><tt>previousSibling(n)</tt></b>
<blockquote>
Returns the previous sibling of a node (if any). This is found in the "previousSibling" attribute of <tt>n</tt>.
</blockquote>
<p>
<b><tt>nextSibling(n)</tt></b>
<blockquote>
Returns the next sibling of a node (if any). This is found in the "nextSibling" attribute of <tt>n</tt>.
</blockquote>
<p>
<b><tt>firstChild(n)</tt></b>
<blockquote>
Returns the first child of a node (if any). This is found in the "firstChild" attribute of <tt>n</tt>.
</blockquote>
<p>
<b><tt>lastChild(n)</tt></b>
<blockquote>
Returns the last child of a node (if any). This is found in the "lastChild" attribute of <tt>n</tt>.
</blockquote>
<h2>Parse Tree Construction</h2>
The following macros are used to construct parse trees.
<p>
<b><tt>set_nodeType(n, val)</tt></b>
<blockquote>
Sets the nodeType attribute of n. val is a string containing the type.
</blockquote>
<p>
<b><tt>set_parentNode(n, parent)</tt></b>
<blockquote>
Sets the parent of node n.
</blockquote>
<p>
<b><tt>set_previousSibling(n, prev)</tt></b>
<blockquote>
Sets the previous sibling of node n.
</blockquote>
<p>
<b><tt>set_nextSibling(n, next)</tt></b>
<blockquote>
Sets the next sibling of node n.
</blockquote>
<p>
<b><tt>set_firstChild(n, chd)</tt></b>
<blockquote>
Sets the first child of node n.
</blockquote>
<p>
<b><tt>set_lastChild(n, chd)</tt></b>
<blockquote>
Sets the last child of node n.
</blockquote>
<h2>Tree Management Functions</h2>
The following functions are used to help with the management and construction of parse trees.
<p>
<b><tt>void appendChild(Node *node, Node *child)</tt></b>
<blockquote>
Adds a new child to <tt>node</tt>. This function takes care of adjusting the "firstChild" and "lastChild" attributes of <tt>node</tt> to appropriate values. After calling this function, the "lastChild" attribute will point to <tt>child</tt>.
</blockquote>
<p>
<b><tt>void prependChild(Node *node, Node *child)</tt></b>
<blockquote>
Prepends a new child to <tt>node</tt>. The new child is added so that it becomes the first child of <tt>node</tt>.
</blockquote>
<p>
<b><tt>void removeNode(Node *node)</tt></b>
<blockquote>
Removes a node from the parse tree. The removal process detaches a node from its parent by removing it from the parent's child list. Upon return, <tt>node</tt> will have no parent and no siblings. This function does NOT delete <tt>node</tt> or modify children of <tt>node</tt>. If desired, <tt>node</tt> could be reattached to a different part of the parse tree.
</blockquote>
<p>
<b><tt>Node *copyNode(Node *node)</tt></b>
<blockquote>
Copies a node, but only copies those attributes that are simple strings. Thus, the new node will not contain any references to other nodes, lists, hashes, or other complex data structures. This function may be useful if you want to copy the data contents of a node in the process of creating a new parse tree node.
</blockquote>
<h2>Attribute Checking</h2>
The following utility is provided since this is an extremely common operation.
<p>
<b><tt>int checkAttribute(Node *n, const String_or_char *name, const String_or_char *value)</tt></b>
<blockquote>
This function checks to see whether node <tt>n</tt> has a given
attribute name and that the attribute has a given value. Returns 0 or
1.
</blockquote>
<h2>Node Transformation</h2>
In the course of processing, SWIG often applies a transform to a node.
This transformation process made modify many of the attributes--even
changing the type of a node. The following functions are used to help
manage this transformation process. In addition to provide sanity
checks, they save the old contents of the node so that they can be
restored later.
<p>
<b><tt>void Swig_save(const char *namespace, Node *n, ...)</tt></b>
<blockquote>
This function takes a node and a list of attribute names and saves their contents in a specified namespace. For example,
the call
<pre>
Swig_save("temp",n,"type","parms","name",NIL)
</pre>
takes the attributes "type","parms", and "name" and saves their
contents under the attribute names "temp:type","temp:parms","temp:name". In addition, this function sets
an attribute "view" to hold the name of the current namespace. In this example, the "view" attribute would be set
to "temp". The attribute names specified are all optional. If one or more of the attributes don't exist,
this function merely records that those attributes did not exist in the original node.
</blockquote>
<p>
<b><tt>void Swig_require(const char *namespace, Node *n, ...)</tt></b>
<blockquote>
This function is similar to <tt>Swig_save()</tt> except that adds additional attribute checking. There are different interpretations
of the attribute names. A name of "attr" merely requests that the function check for the presence of an attribute. If the attribute is missing, SWIG will exit with a failed assertion. An attribute name of "?attr" specifies that the attribute "attr" is optional and
that it's old value must be saved (if any). An attribute name of "*attr" specifies that the attribute is required and that
its value must be saved. The saving of attributes is performed in the same manner as with <tt>Swig_save()</tt>. Here is an example:
<pre>
Swig_require("temp",n,"type","*name","?parms",NIL);
</pre>
</blockquote>
<p>
<b><tt>void Swig_restore(Node *n)</tt></b>
<blockquote>
This function restores a node to the state it was in prior to the last <tt>Swig_save()</tt> or <tt>Swig_require()</tt> call. This is used to undo node transformations.
</blockquote>
<h2>Debugging Functions</h2>
<p>
The following functions can be used to help debug any SWIG DOH object.
</p>
<b><tt>void Swig_print(DOH *object, int count = -1)</tt></b>
<blockquote>
Prints to stdout a string representation of any DOH type.
The number of nested Hash types to expand is set by count (default is 1 if count&lt;0). See Swig_set_max_hash_expand() to change default.
<pre>
</pre>
</blockquote>
<b><tt>void Swig_print_with_location(DOH *object, int count = -1)</tt></b>
<blockquote>
Prints to stdout a string representation of any DOH type, within [] brackets
for Hash and List types, prefixed by line and file information.
The number of nested Hash types to expand is set by count (default is 1 if count&lt;0). See Swig_set_max_hash_expand() to change default.
<pre>
</pre>
</blockquote>
<p>
The following functions can be used to help debug SWIG parse trees.
</p>
<p>
<b><tt>void Swig_print_tags(Node *node, String_or_char *prefix)</tt></b>
<blockquote>
Prints the tag-structure of the parse tree to standard output. <tt>node</tt> is the top-level parse tree node. <tt>prefix</tt> is
a string prefix thats added to the start of each line. Normally, you would specify the empty string or NIL for <tt>prefix</tt>.
This function is called by the <tt>-debug-tags</tt> option to SWIG.
<pre>
% swig -debug-tags -python example.i
. top (:1)
. top . include (/Users/beazley/Projects/share/swig/1.3.31/swig.swg:0)
. top . include . include (/Users/beazley/Projects/share/swig/1.3.31/swigwarnings.swg:0)
. top . include . include . include (/Users/beazley/Projects/share/swig/1.3.31/swigwarn.swg:0)
...
...
. top . include (example.i:0)
. top . include . module (example.i:2)
. top . include . insert (example.i:7)
. top . include . cdecl (example.i:5)
. top . include . cdecl (example.i:6)
</pre>
Since many language modules include hundreds of typemaps and other information, the output of this can be significantly more complicated than you might expect.
</blockquote>
<p>
<b><tt>void Swig_print_node(Node *node)</tt></b>
<blockquote>
Prints the contents of a parse tree node, including all children, to standard output. The output includes all attributes
and other details.
</blockquote>
<p>
<b><tt>void Swig_print_tree(Node *node)</tt></b>
<blockquote>
Prints the same output as <tt>Swig_print_node()</tt> except that it also processes all of the siblings of <tt>node</tt>. This can
be used to dump the entire parse tree to standard output. The command line options <tt>-debug-module</tt>
and <tt>-debug-top</tt> use this function to display the parse tree for a SWIG input file.
</blockquote>
</body>
</html>

223
Doc/Devel/wrapobj.html Normal file
View file

@ -0,0 +1,223 @@
<html>
<head>
<title>Wrapper Objects</title>
</head>
<body>
<center>
<h1>Wrapper Objects</h1>
<p>
David M. Beazley <br>
dave-swig@dabeaz.com<br>
January 15, 2007<br>
</b>
</center>
<h2>Introduction</h2>
This document describes the functions related to management of
wrapper objects. A wrapper object is a low-level
data structure used to contain the C/C++ code that is emitted during the
wrapping process. It contains not only the emitted code, but information
about local variables. These objects are a critical component of almost all
SWIG target language modules.
<p>
The functions described here are declared
in <tt>Source/Swig/swigwrap.h</tt>. This API is considered to be
stable.
<h2>Creating and Destroying Wrappers</h2>
The following functions create and destroy wrapper objects.
<p>
<b><tt>Wrapper *NewWrapper()</tt></b>
<blockquote>
Creates a new wrapper object.
</blockquote>
<p>
<b><tt>void DelWrapper(Wrapper *w)</tt></b>
<blockquote>
Destroys a wrapper object.
</blockquote>
<h2>Wrapper Objects</h2>
The <tt>Wrapper</tt> object returned by <tt>NewWrapper()</tt> has
three public attributes.
<blockquote><pre>
typedef struct Wrapper {
String *def;
String *locals;
String *code;
} Wrapper;
</pre></blockquote>
The <tt>def</tt> attribute is a string that holds the function
definition line. This line declares the function name, return type,
and parameters. Language modules create this declaration by simply printing
the appropriate text into this attribute.
<p>
The <tt>locals</tt> attribute is a string that holds the code
related to any local variables declaration. Normally, language modules
do not emit code to this string directly. They use <tt>Wrapper_add_local()</tt> or <tt>Wrapper_new_local()</tt> to do this.
<p>
The <tt>code</tt> attribute is a string that holds code related to the body of the function. Almost all code emitted by SWIG language modules is printed into this attribute.
<h2>Creating Local Variables</h2>
Perhaps the most useful aspect of <tt>Wrapper</tt> objects is the
management of local variables. When creating a wrapper, it is often
necessary to emit local variables related to the API of the target
language. In addition to this, typemaps and other aspects of SWIG
rely upon their own local variables. The following functions are used
to create local variables, but also provide support for renaming
variables in order to avoid name clashes.
<p>
<b><tt>int Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl)</tt></b>
<blockquote>
Adds a new local variable to the wrapper object. <tt>name</tt> is the
name of the local variable. <tt>decl</tt> is a string containing the
actual variable declaration code. For example, if you wanted to
declare a variable "<tt>int x = 42;</tt>", you would set <tt>name</tt>
to <tt>"x"</tt> and
<tt>decl</tt> to <tt>"int x = 42;"</tt>. On success, the text in
<tt>decl</tt> is added to the <tt>locals</tt> attribute of <tt>w</tt>
and 0 is returned. -1 is returned if a variable with the given name
has already been declared.
</blockquote>
<p>
<b><tt>int Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...)</tt></b>
<blockquote>
The same as <tt>Wrapper_add_local()</tt> except that instead of
passing a single string for the declaration, a NULL-terminated list of
strings can be passed. These strings are joined together when
producing the output. This convention turns out to be fairly useful
since language modules often create their output into pieces.
</blockquote>
<p>
<b><tt>char * Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_char *decl)</tt></b>
<blockquote>
The same as <tt>Wrapper_add_local()</tt> except that if a local variable
with the given name already exists, this function picks a new name and adds
the declaration using the new name. The actual name used for the variable
is returned. This function is used when generating code originating from
typemaps. For instance, if a typemap declares a local variable, that variable
might have to be renamed if the same typemap is used more than once in the same function.
</blockquote>
<p>
<b><tt>char * Wrapper_new_localv(Wrapper *w, const String_or_char *name,...)</tt></b>
<blockquote>
The same as <tt>Wrapper_new_localv()</tt>, but accepts a NULL-terminated list
of strings as code output.
</blockquote>
<p>
<b><tt>int Wrapper_check_local(Wrapper *w, const String_or_char *name)</tt></b>
<blockquote>
Checks to see if a local variable with name <tt>name</tt> has been declared. Returns 1 if the local is defined, 0 otherwise.
</blockquote>
<h2>Output</h2>
<p>
<b><tt>void Wrapper_print(Wrapper *w, File *f)</tt></b>
<blockquote>
This function is used to format a wrapper function for output. The
formatted wrapper function is emitted to <tt>f</tt> which may be any
file-like object including a <tt>FILE *</tt> object or a <tt>String
*</tt> object. When emitting the wrapper, the code printed to the
wrapper object is automatically formatted. By default, the formatting
is done according to a "pretty printing" style in which lines are split onto
multiple lines and indented according to reasonable C formatting rules. This produces code that is moderately readable should you want to look at the wrapper
code output. An alternative output mode is "compact printing" in which
lines are collected and compacted. This may result in multiple C statements
appearing on the same line. This mode is sometimes used when the size of
a wrapper file is too large for certain compilers. For example, some compilers
might impose a limit of 65536 lines per source file.
</blockquote>
<p>
<b><tt>void Wrapper_compact_print_mode_set(int flag)</tt></b>
<blockquote>
Sets the output mode of the <tt>Wrapper_print()</tt>
function. If <tt>flag</tt> is set to 1, then wrapper code is formatted
to be compact.
</blockquote>
<p>
<b><tt>void Wrapper_pretty_print(String *str, File *f)</tt></b>
<blockquote>
Utility function that reformats a string containing C/C++ code and outputs
it to the file-like object <tt>f</tt>. The formatting process indents the code
and structures it according to reasonable C formatting rules.
</blockquote>
<p>
<b><tt>void Wrapper_compact_print(String *str, File *f)</tt></b>
<blockquote>
Utility function that reformats a string containing C/C++ code and outputs
it to the file-like object <tt>f</tt>. The formatting process tries to
make the code as compact as possible, without going completely overboard. For
example, multiple C statements may be combined onto a single line and braces may be aligned to not use up extra lines.
</blockquote>
<h2>An Example</h2>
Here is a simple example of how these functions are used. Suppose
you wanted to emit the following C function:
<blockquote>
<pre>
void foo(int n) {
int i;
for (i = 0; i &lt; n; i++) {
printf("%d\n", i);
}
}
</pre>
</blockquote>
Here is code that generates the above function:
<blockquote>
<pre>
Wrapper *w = NewWrapper();
Printf(w-&gt;def,"void foo(int n) {");
Wrapper_add_local(w,"n",""); /* parameter n */
Wrapper_add_local(w,"i", "int i;"); /* local i */
Printv(w-&gt;code,"for (i = 0; i &lt; n; i++) {",
"printf(\"%d\n",i);",
"}\n", NIL);
Printf(w-&gt;code,"}\n");
/* Emit wrapper code */
Wrapper_print(w,outf);
DelWrapper(w);
</pre>
</blockquote>
Within different language modules, this process is obviously much more
involved. However, this example shows the basic idea of how C/C++
code is prepared for output.
</body>
</html>

2150
Doc/Manual/Allegrocl.html Normal file

File diff suppressed because it is too large Load diff

496
Doc/Manual/Arguments.html Normal file
View file

@ -0,0 +1,496 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Argument Handling</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Arguments"></a>9 Argument Handling</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Arguments_nn2">The typemaps.i library</a>
<ul>
<li><a href="#Arguments_nn3">Introduction</a>
<li><a href="#Arguments_nn4">Input parameters</a>
<li><a href="#Arguments_nn5">Output parameters</a>
<li><a href="#Arguments_nn6">Input/Output parameters</a>
<li><a href="#Arguments_nn7">Using different names</a>
</ul>
<li><a href="#Arguments_nn8">Applying constraints to input values</a>
<ul>
<li><a href="#Arguments_nn9">Simple constraint example</a>
<li><a href="#Arguments_nn10">Constraint methods</a>
<li><a href="#Arguments_nn11">Applying constraints to new datatypes</a>
</ul>
</ul>
</div>
<!-- INDEX -->
<p>
In Chapter 3, SWIG's treatment of basic datatypes and pointers was
described. In particular, primitive types such as <tt>int</tt> and
<tt>double</tt> are mapped to corresponding types in the target
language. For everything else, pointers are used to refer to
structures, classes, arrays, and other user-defined datatypes.
However, in certain applications it is desirable to change SWIG's
handling of a specific datatype. For example, you might want to
return multiple values through the arguments of a function. This chapter
describes some of the techniques for doing this.
</p>
<H2><a name="Arguments_nn2"></a>9.1 The typemaps.i library</H2>
<p>
This section describes the <tt>typemaps.i</tt> library file--commonly used to
change certain properties of argument conversion.
</p>
<H3><a name="Arguments_nn3"></a>9.1.1 Introduction</H3>
<p>
Suppose you had a C function like this:
</p>
<div class="code"><pre>
void add(double a, double b, double *result) {
*result = a + b;
}
</pre></div>
<p>
From reading the source code, it is clear that the function is storing
a value in the <tt>double *result</tt> parameter. However, since SWIG
does not examine function bodies, it has no way to know that this is
the underlying behavior.
</p>
<p>
One way to deal with this is to use the
<tt>typemaps.i</tt> library file and write interface code like this:
</p>
<div class="code"><pre>
// Simple example using typemaps
%module example
%include "typemaps.i"
%apply double *OUTPUT { double *result };
%inline %{
extern void add(double a, double b, double *result);
%}
</pre></div>
<p>
The <tt>%apply</tt> directive tells SWIG that you are going to apply
a special type handling rule to a type. The "<tt>double *OUTPUT</tt>" specification is the
name of a rule that defines how to return an output value from an argument of type
<tt>double *</tt>. This rule gets applied to all of the datatypes
listed in curly braces-- in this case "<tt>double *result</tt>".</p>
<p>
When the resulting module is created, you can now use the function
like this (shown for Python):
</p>
<div class="targetlang"><pre>
&gt;&gt;&gt; a = add(3,4)
&gt;&gt;&gt; print a
7
&gt;&gt;&gt;
</pre></div>
<p>
In this case, you can see how the output value normally returned in
the third argument has magically been transformed into a function
return value. Clearly this makes the function much easier to use
since it is no longer necessary to manufacture a special <tt>double
*</tt> object and pass it to the function somehow.
</p>
<p>
Once a typemap has been applied to a type, it stays in effect for all future occurrences
of the type and name. For example, you could write the following:
</p>
<div class="code"><pre>
%module example
%include "typemaps.i"
%apply double *OUTPUT { double *result };
%inline %{
extern void add(double a, double b, double *result);
extern void sub(double a, double b, double *result);
extern void mul(double a, double b, double *result);
extern void div(double a, double b, double *result);
%}
...
</pre></div>
<p>
In this case, the <tt>double *OUTPUT</tt> rule is applied to all of the functions that follow.
</p>
<p>
Typemap transformations can even be extended to multiple return values.
For example, consider this code:
</p>
<div class="code">
<pre>
%include "typemaps.i"
%apply int *OUTPUT { int *width, int *height };
// Returns a pair (width,height)
void getwinsize(int winid, int *width, int *height);
</pre>
</div>
<p>
In this case, the function returns multiple values, allowing it to be used like this:
</p>
<div class="targetlang"><pre>
&gt;&gt;&gt; w,h = genwinsize(wid)
&gt;&gt;&gt; print w
400
&gt;&gt;&gt; print h
300
&gt;&gt;&gt;
</pre>
</div>
<p>
It should also be noted that although the <tt>%apply</tt> directive is
used to associate typemap rules to datatypes, you can also use the
rule names directly in arguments. For example, you could write this:
</p>
<div class="code"><pre>
// Simple example using typemaps
%module example
%include "typemaps.i"
%{
extern void add(double a, double b, double *OUTPUT);
%}
extern void add(double a, double b, double *OUTPUT);
</pre></div>
<p>
Typemaps stay in effect until they are explicitly deleted or redefined to something
else. To clear a typemap, the <tt>%clear</tt> directive should be used. For example:
</p>
<div class="code">
<pre>
%clear double *result; // Remove all typemaps for double *result
</pre>
</div>
<H3><a name="Arguments_nn4"></a>9.1.2 Input parameters</H3>
<p>
The following typemaps instruct SWIG that a pointer really only holds a single
input value:
</p>
<div class="code"><pre>
int *INPUT
short *INPUT
long *INPUT
unsigned int *INPUT
unsigned short *INPUT
unsigned long *INPUT
double *INPUT
float *INPUT
</pre></div>
<p>
When used, it allows values to be passed instead of pointers. For example, consider this
function:
</p>
<div class="code"><pre>
double add(double *a, double *b) {
return *a+*b;
}
</pre></div>
<p>
Now, consider this SWIG interface:
</p>
<div class="code"><pre>
%module example
%include "typemaps.i"
...
%{
extern double add(double *, double *);
%}
extern double add(double *INPUT, double *INPUT);
</pre></div>
<p>
When the function is used in the scripting language interpreter, it will work like this:
</p>
<div class="targetlang"><pre>
result = add(3,4)
</pre></div>
<H3><a name="Arguments_nn5"></a>9.1.3 Output parameters</H3>
<p>
The following typemap rules tell SWIG that pointer is the output value of a
function. When used, you do not need to supply the argument when
calling the function. Instead, one or more output values are returned.
</p>
<div class="code"><pre>
int *OUTPUT
short *OUTPUT
long *OUTPUT
unsigned int *OUTPUT
unsigned short *OUTPUT
unsigned long *OUTPUT
double *OUTPUT
float *OUTPUT
</pre></div>
<p>
These methods can be used as shown in an earlier example. For example, if you have this C function :</p>
<div class="code"><pre>
void add(double a, double b, double *c) {
*c = a+b;
}
</pre></div>
<p>
A SWIG interface file might look like this :</p>
<div class="code"><pre>
%module example
%include "typemaps.i"
...
%inline %{
extern void add(double a, double b, double *OUTPUT);
%}
</pre></div>
<p>
In this case, only a single output value is returned, but this is not
a restriction. An arbitrary number of output values can be returned by applying
the output rules to more than one argument (as shown previously).
</p>
<p>
If the function also returns a value, it is returned along with the argument. For example,
if you had this:
</p>
<div class="code"><pre>
extern int foo(double a, double b, double *OUTPUT);
</pre></div>
<p>
The function will return two values like this:
</p>
<div class="targetlang">
<pre>
iresult, dresult = foo(3.5, 2)
</pre>
</div>
<H3><a name="Arguments_nn6"></a>9.1.4 Input/Output parameters</H3>
<p>
When a pointer serves as both an input and output value you can use
the following typemaps :</p>
<div class="code"><pre>
int *INOUT
short *INOUT
long *INOUT
unsigned int *INOUT
unsigned short *INOUT
unsigned long *INOUT
double *INOUT
float *INOUT
</pre></div>
<p>
A C function that uses this might be something like this:</p>
<div class="code"><pre>
void negate(double *x) {
*x = -(*x);
}
</pre></div>
<p>
To make x function as both and input and output value, declare the
function like this in an interface file :</p>
<div class="code"><pre>
%module example
%include "typemaps.i"
...
%{
extern void negate(double *);
%}
extern void negate(double *INOUT);
</pre></div>
<p>
Now within a script, you can simply call the function normally :</p>
<div class="targetlang"><pre>
a = negate(3); # a = -3 after calling this
</pre></div>
<p>
One subtle point of the <tt>INOUT</tt> rule is that many scripting languages
enforce mutability constraints on primitive objects (meaning that simple objects
like integers and strings aren't supposed to change). Because of this, you can't
just modify the object's value in place as the underlying C function does in this example.
Therefore, the <tt>INOUT</tt> rule returns the modified value as a new object
rather than directly overwriting the value of the original input object.
</p>
<p>
<b>Compatibility note :</b> The <tt>INOUT</tt> rule used to be known as <tt>BOTH</tt> in earlier versions of
SWIG. Backwards compatibility is preserved, but deprecated.
</p>
<H3><a name="Arguments_nn7"></a>9.1.5 Using different names</H3>
<p>
As previously shown, the <tt>%apply</tt> directive can be used to apply the <tt>INPUT</tt>, <tt>OUTPUT</tt>, and
<tt>INOUT</tt> typemaps to different argument names. For example:
</p>
<div class="code"><pre>
// Make double *result an output value
%apply double *OUTPUT { double *result };
// Make Int32 *in an input value
%apply int *INPUT { Int32 *in };
// Make long *x inout
%apply long *INOUT {long *x};
</pre></div>
<p>
To clear a rule, the <tt>%clear</tt> directive is used:
</p>
<div class="code"><pre>
%clear double *result;
%clear Int32 *in, long *x;
</pre></div>
<p>
Typemap declarations are lexically scoped so a typemap takes effect from the point of definition to the end of the
file or a matching <tt>%clear</tt> declaration.
</p>
<H2><a name="Arguments_nn8"></a>9.2 Applying constraints to input values</H2>
<p>
In addition to changing the handling of various input values, it is
also possible to use typemaps to apply constraints. For example, maybe you want to
insure that a value is positive, or that a pointer is non-NULL. This
can be accomplished including the <tt>constraints.i</tt> library file.
</p>
<H3><a name="Arguments_nn9"></a>9.2.1 Simple constraint example</H3>
<p>
The constraints library is best illustrated by the following interface
file :</p>
<div class="code"><pre>
// Interface file with constraints
%module example
%include "constraints.i"
double exp(double x);
double log(double POSITIVE); // Allow only positive values
double sqrt(double NONNEGATIVE); // Non-negative values only
double inv(double NONZERO); // Non-zero values
void free(void *NONNULL); // Non-NULL pointers only
</pre></div>
<p>
The behavior of this file is exactly as you would expect. If any of
the arguments violate the constraint condition, a scripting language
exception will be raised. As a result, it is possible to catch bad
values, prevent mysterious program crashes and so on.</p>
<H3><a name="Arguments_nn10"></a>9.2.2 Constraint methods</H3>
<p>
The following constraints are currently available</p>
<div class="code"><pre>
POSITIVE Any number &gt; 0 (not zero)
NEGATIVE Any number &lt; 0 (not zero)
NONNEGATIVE Any number &gt;= 0
NONPOSITIVE Any number &lt;= 0
NONZERO Nonzero number
NONNULL Non-NULL pointer (pointers only).
</pre></div>
<H3><a name="Arguments_nn11"></a>9.2.3 Applying constraints to new datatypes</H3>
<p>
The constraints library only supports the primitive C datatypes, but it
is easy to apply it to new datatypes using <tt>%apply</tt>. For
example :</p>
<div class="code"><pre>
// Apply a constraint to a Real variable
%apply Number POSITIVE { Real in };
// Apply a constraint to a pointer type
%apply Pointer NONNULL { Vector * };
</pre></div>
<p>
The special types of "Number" and "Pointer" can be applied to any
numeric and pointer variable type respectively. To later remove a
constraint, the <tt>%clear</tt> directive can be used :</p>
<div class="code"><pre>
%clear Real in;
%clear Vector *;
</pre></div>
</body>
</html>

2438
Doc/Manual/CSharp.html Normal file

File diff suppressed because it is too large Load diff

597
Doc/Manual/Chicken.html Normal file
View file

@ -0,0 +1,597 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Hand-written HTML -->
<html>
<head>
<title>SWIG and Chicken</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Chicken"></a>19 SWIG and Chicken</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Chicken_nn2">Preliminaries</a>
<ul>
<li><a href="#Chicken_nn3">Running SWIG in C mode</a>
<li><a href="#Chicken_nn4">Running SWIG in C++ mode</a>
</ul>
<li><a href="#Chicken_nn5">Code Generation</a>
<ul>
<li><a href="#Chicken_nn6">Naming Conventions</a>
<li><a href="#Chicken_nn7">Modules</a>
<li><a href="#Chicken_nn8">Constants and Variables</a>
<li><a href="#Chicken_nn9">Functions</a>
<li><a href="#Chicken_nn10">Exceptions</a>
</ul>
<li><a href="#Chicken_nn11">TinyCLOS</a>
<li><a href="#Chicken_nn12">Linkage</a>
<ul>
<li><a href="#Chicken_nn13">Static binary or shared library linked at compile time</a>
<li><a href="#Chicken_nn14">Building chicken extension libraries</a>
<li><a href="#Chicken_nn15">Linking multiple SWIG modules with TinyCLOS</a>
</ul>
<li><a href="#Chicken_nn16">Typemaps</a>
<li><a href="#Chicken_nn17">Pointers</a>
<ul>
<li><a href="#Chicken_collection">Garbage collection</a>
</ul>
<li><a href="#Chicken_nn18">Unsupported features and known problems</a>
<ul>
<li><a href="#Chicken_nn19">TinyCLOS problems with Chicken version &lt;= 1.92</a>
</ul>
</ul>
</div>
<!-- INDEX -->
<p>
This chapter describes SWIG's support of CHICKEN. CHICKEN is a
Scheme-to-C compiler supporting most of the language features as
defined in the <i>Revised^5 Report on Scheme</i>. Its main
attributes are that it
</p>
<ol>
<li>generates portable C code</li>
<li>includes a customizable interpreter</li>
<li>links to C libraries with a simple Foreign Function Interface</li>
<li>supports full tail-recursion and first-class continuations</li>
</ol>
<p>
When confronted with a large C library, CHICKEN users can use
SWIG to generate CHICKEN wrappers for the C library. However,
the real advantages of using SWIG with CHICKEN are its
<strong>support for C++</strong> -- object-oriented code is
difficult to wrap by hand in CHICKEN -- and its <strong>typed
pointer representation</strong>, essential for C and C++
libraries involving structures or classes.
</p>
<H2><a name="Chicken_nn2"></a>19.1 Preliminaries</H2>
<p>
CHICKEN support was introduced to SWIG in version 1.3.18. SWIG
relies on some recent additions to CHICKEN, which are only
present in releases of CHICKEN with version number
<strong>greater than or equal to 1.89</strong>.
To use a chicken version between 1.40 and 1.89, see the <a href="#Chicken_collection">Garbage collection</a>
section below.
</p>
<p>
You may want to look at any of the examples in Examples/chicken/
directory for the basic steps to run SWIG CHICKEN.
</p>
<H3><a name="Chicken_nn3"></a>19.1.1 Running SWIG in C mode</H3>
<p>
To run SWIG CHICKEN in C mode, use
the -chicken option.
</p>
<div class="shell">
<pre>% swig -chicken example.i</pre>
</div>
<p>
To allow the wrapper to take advantage of future CHICKEN code
generation improvements, part of the wrapper is direct CHICKEN
function calls (<tt>example_wrap.c</tt>) and part is CHICKEN
Scheme (<tt>example.scm</tt>). The basic Scheme code must
be compiled to C using your system's CHICKEN compiler or
both files can be compiled directly using the much simpler <tt>csc</tt>.
</p>
<div class="shell">
<pre>
% chicken example.scm -output-file oexample.c
</pre>
</div>
<p>
So for the C mode of SWIG CHICKEN, <tt>example_wrap.c</tt> and
<tt>oexample.c</tt> are the files that must be compiled to
object files and linked into your project.
</p>
<H3><a name="Chicken_nn4"></a>19.1.2 Running SWIG in C++ mode</H3>
<p>
To run SWIG CHICKEN in C++ mode, use
the -chicken -c++ option.
</p>
<div class="shell">
<pre>% swig -chicken -c++ example.i</pre>
</div>
<p>
This will generate <tt>example_wrap.cxx</tt> and
<tt>example.scm</tt>. The basic Scheme code must be
compiled to C using your system's CHICKEN compiler or
both files can be compiled directly using the much simpler <tt>csc</tt>.
</p>
<div class="shell">
<pre>% chicken example.scm -output-file oexample.c</pre>
</div>
<p>
So for the C++ mode of SWIG CHICKEN, <tt>example_wrap.cxx</tt>
and <tt>oexample.c</tt> are the files that must be compiled to
object files and linked into your project.
</p>
<H2><a name="Chicken_nn5"></a>19.2 Code Generation</H2>
<H3><a name="Chicken_nn6"></a>19.2.1 Naming Conventions</H3>
<p>
Given a C variable, function or constant declaration named
<tt>Foo_Bar</tt>, the declaration will be available
in CHICKEN as an identifier ending with
<tt>Foo-Bar</tt>. That is, an underscore is converted
to a dash.
</p>
<p>
You may control what the CHICKEN identifier will be by using the
<tt>%rename</tt> SWIG directive in the SWIG interface file.
</p>
<H3><a name="Chicken_nn7"></a>19.2.2 Modules</H3>
<p>
The name of the module must be declared one of two ways:
<ul>
<li>Placing <tt>%module example</tt> in the SWIG interface
file.</li>
<li>Using <tt>-module example</tt> on the SWIG command
line.</li>
</ul>
<p>
The generated example.scm file then exports <code>(declare (unit modulename))</code>.
If you do not want SWIG to export the <code>(declare (unit modulename))</code>, pass
the -nounit option to SWIG.
<p>
CHICKEN will be able to access the module using the <code>(declare
(uses <i>modulename</i>))</code> CHICKEN Scheme form.
</p>
<H3><a name="Chicken_nn8"></a>19.2.3 Constants and Variables</H3>
<p>
Constants may be created using any of the four constructs in
the interface file:
</p>
<ol>
<li><code>#define MYCONSTANT1 ...</code></li>
<li><code>%constant int MYCONSTANT2 = ...</code></li>
<li><code>const int MYCONSTANT3 = ...</code></li>
<li><code>enum { MYCONSTANT4 = ... };</code></li>
</ol>
<p>
In all cases, the constants may be accessed from within CHICKEN
using the form <tt>(MYCONSTANT1)</tt>; that is, the constants
may be accessed using the read-only parameter form.
</p>
<p>
Variables are accessed using the full parameter form.
For example, to set the C variable "int my_variable;", use the
Scheme form <tt>(my-variable 2345)</tt>. To get the C variable,
use <tt>(my-variable)</tt>.
</p>
<p>
The <tt>%feature("constasvar")</tt> can be applied to any constant
or immutable variable. Instead of exporting the constant as
a function that must be called, the constant will appear as a
scheme variable. This causes the generated .scm file to just contain the code
<tt>(set! MYCONSTANT1 (MYCONSTANT1))</tt>. See
<a href="Customization.html#Customization_features">Features and the %feature directive</a>
for info on how to apply the %feature.
</p>
<H3><a name="Chicken_nn9"></a>19.2.4 Functions</H3>
<p>
C functions declared in the SWIG interface file will have
corresponding CHICKEN Scheme procedures. For example, the C
function "int sqrt(double x);" will be available using the
Scheme form <tt>(sqrt 2345.0)</tt>. A <code>void</code> return
value will give C_SCHEME_UNDEFINED as a result.
</p>
<p>
A function may return more than one value by using the
<code>OUTPUT</code> specifier (see Lib/chicken/typemaps.i).
They will be returned as multiple values using <code>(values)</code> if there is more than one
result (that is, a non-void return value and at least one argout
parameter, or a void return value and at least two argout
parameters). The return values can then be accessed with <code>(call-with-values)</code>.
</p>
<H3><a name="Chicken_nn10"></a>19.2.5 Exceptions</H3>
<p>The SWIG chicken module has support for exceptions thrown from
C or C++ code to be caught in scheme.
See <a href="Customization.html#Customization_exception">Exception handling with %exception</a>
for more information about declaring exceptions in the interface file.
</p>
<p>Chicken supports both the <code>SWIG_exception(int code, const char *msg)</code> interface
as well as a <code>SWIG_ThrowException(C_word val)</code> function for throwing exceptions from
inside the %exception blocks. <code>SWIG_exception</code> will throw a list consisting of the code
(as an integer) and the message. Both of these will throw an exception using <code>(abort)</code>,
which can be handled by <code>(handle-exceptions)</code>. See
the Chicken manual on Exceptions
and <a href="http://srfi.schemers.org/srfi-12/srfi-12.html">SFRI-12</a>. Since the exception values are thrown
directly, if <code>(condition-case)</code> is used to catch an exception the exception will come through in the <code>val ()</code> case.
</p>
<p>The following simple module</p>
<div class="code"><pre>
%module exception_test
%inline %{
void test_throw(int i) throws (int) {
if (i == 1) throw 15;
}
%}
</pre></div>
<p>could be run with</p>
<div class="targetlang"><pre>
(handle-exceptions exvar
(if (= exvar 15)
(print "Correct!")
(print "Threw something else " exvar))
(test-throw 1))
</pre></div>
<H2><a name="Chicken_nn11"></a>19.3 TinyCLOS</H2>
<p>
The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as:
"Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a
metaobject protocol. The implementation is even simpler than
the simple CLOS found in `The Art of the Metaobject Protocol,'
weighing in at around 850 lines of code, including (some)
comments and documentation."
</p>
<p>
Almost all good Scheme books describe how to use metaobjects and
generic procedures to implement an object-oriented Scheme
system. Please consult a Scheme book if you are unfamiliar
with the concept.
</p>
<p>
CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN
uses if the -proxy argument is given. If -proxy is passed, then
the generated example.scm file will contain TinyCLOS class definitions.
A class named Foo is declared as &lt;Foo&gt;, and each member variable
is allocated a slot. Member functions are exported as generic functions.
<p>
Primitive symbols and functions (the interface that would be presented if
-proxy was not passed) are hidden and no longer accessible. If the -unhideprimitive
command line argument is passed to SWIG, then the primitive symbols will be
available, but each will be prefixed by the string "primitive:"
<p>
The exported symbol names can be controlled with the -closprefix and -useclassprefix arguments.
If -useclassprefix is passed to SWIG, every member function will be generated with the class name
as a prefix. If the -closprefix mymod: argument is passed to SWIG, then the exported functions will
be prefixed by the string "mymod:". If -useclassprefix is passed, -closprefix is ignored.
</p>
<H2><a name="Chicken_nn12"></a>19.4 Linkage</H2>
<p>
Please refer to <em>CHICKEN - A practical and portable Scheme
system - User's manual</em> for detailed help on how to link
object files to create a CHICKEN Scheme program. Briefly, to
link object files, be sure to add <tt>`chicken-config
-extra-libs -libs`</tt> or <tt>`chicken-config -shared
-extra-libs -libs`</tt>to your linker options. Use the
<tt>-shared</tt> option if you want to create a dynamically
loadable module. You might also want to use the much simpler
<tt>csc</tt> or <tt>csc.bat</tt>.
</p>
<p>Each scheme file that is generated
by SWIG contains <code>(declare (uses <i>modname</i>))</code>. This means that to load the
module from scheme code, the code must include <code>(declare (uses <i>modname</i>))</code>.
</p>
<H3><a name="Chicken_nn13"></a>19.4.1 Static binary or shared library linked at compile time</H3>
<p>We can easily use csc to build a static binary.</p>
<div class="shell">
<pre>
$ swig -chicken example.i
$ csc -v example.scm example_impl.c example_wrap.c test_script.scm -o example
$ ./example
</pre>
</div>
<p>Similar to the above, any number of <tt>module.scm</tt> files could be compiled
into a shared library, and then that shared library linked when compiling the
main application.</p>
<div class="shell">
<pre>
$ swig -chicken example.i
$ csc -sv example.scm example_wrap.c example_impl.c -o example.so
</pre>
</div>
<p>The <tt>example.so</tt> file can then linked with <tt>test_script.scm</tt> when it
is compiled, in which case <tt>test_script.scm</tt> must have <code>(declare (uses example))</code>.
Multiple SWIG modules could have been linked into <tt>example.so</tt> and each
one accessed with a <code>(declare (uses ... ))</code>.
</p>
<div class="shell">
<pre>
$ csc -v test_script.scm -lexample
</pre>
</div>
<p>An alternative is that the test_script.scm can have the code <code>(load-library 'example "example.so")</code>,
in which case the test script does not need to be linked with example.so. The test_script.scm file can then
be run with <tt>csi</tt>.
</p>
<H3><a name="Chicken_nn14"></a>19.4.2 Building chicken extension libraries</H3>
<p>Building a shared library like in the above section only works if the library
is linked at compile time with a script containing <code>(declare (uses ...))</code> or is
loaded explicitly with <code>(load-library 'example "example.so")</code>. It is
not the format that CHICKEN expects for extension libraries and eggs. The problem is the
<code>(declare (unit <i>modname</i>))</code> inside the <tt>modname.scm</tt> file. There are
two possible solutions to this.</p>
<p>First, SWIG accepts a <tt>-nounit</tt> argument, in which case the <code>(declare (unit <i>modname</i>))</code>
is not generated. Then, the <tt>modname.scm</tt> and <tt>modname_wrap.c</tt> files <b>must</b> be compiled into
their own shared library.</p>
<div class="shell">
<pre>
$ csc -sv modname.scm modname_wrap.c modname_impl.c -o modname.so
</pre>
</div>
<p>This library can then be loaded by scheme code with the <code>(require 'modname)</code> function.
See the
Loading-extension-libraries in the eval unit inside the CHICKEN manual for more information.</p>
<p>Another alternative is to run SWIG normally and create a scheme file that contains <code>(declare (uses <i>modname</i>))</code>
and then compile that file into the shared library as well. For example, inside the <tt>mod_load.scm</tt> file,</p>
<div class="targetlang">
<pre>
(declare (uses mod1))
(declare (uses mod2))
</pre>
</div>
<p>Which would then be compiled with</p>
<div class="shell">
<pre>
$ swig -chicken mod1.i
$ swig -chicken mod2.i
$ csc -sv mod_load.scm mod1.scm mod2.scm mod1_wrap.c mod2_wrap.c mod1_impl.c mod2_impl.c -o mod.so
</pre>
</div>
<p>Then the extension library can be loaded with <code>(require 'mod)</code>. As we can see here,
<tt>mod_load.scm</tt> contains the code that gets executed when the module is loaded. All this code
does is load both mod1 and mod2. As we can see, this technique is more useful when you want to
combine a few SWIG modules into one chicken extension library, especially if modules are related by
<code>%import</code></p>
<p>In either method, the files that are compiled into the shared library could also be
packaged into an egg. The <tt>mod1_wrap.c</tt> and <tt>mod2_wrap.c</tt> files that are created by SWIG
are stand alone and do not need SWIG to be installed to be compiled. Thus the egg could be
distributed and used by anyone, even if SWIG is not installed.</p>
<p>See the <tt>Examples/chicken/egg</tt> directory in the SWIG source for an example that builds
two eggs, one using the first method and one using the second method.</p>
<H3><a name="Chicken_nn15"></a>19.4.3 Linking multiple SWIG modules with TinyCLOS</H3>
<p>Linking together multiple modules that share type information using the <code>%import</code>
directive while also using <tt>-proxy</tt> is more complicated. For example, if <tt>mod2.i</tt> imports <tt>mod1.i</tt>, then the
<tt>mod2.scm</tt> file contains references to symbols declared in <tt>mod1.scm</tt>,
and thus a <code>(declare (uses <i>mod1</i>))</code> or <code>(require '<i>mod1</i>)</code> must be exported
to the top of <tt>mod2.scm</tt>. By default, when SWIG encounters an <code>%import "modname.i"</code> directive,
it exports <code>(declare (uses <i>modname</i>))</code> into the scm file. This works fine unless mod1 was compiled with
the <tt>-nounit</tt> argument or was compiled into an extension library with other modules under a different name.</p>
<p>One option is to override the automatic generation of <code>(declare (uses mod1))</code>
by passing the <tt>-noclosuses</tt> option to SWIG when compiling <tt>mod2.i</tt>.
SWIG then provides the <code>%insert(closprefix) %{ %}</code> directive. Any scheme code inside that directive is inserted into the
generated .scm file, and if <tt>mod1</tt> was compiled with <tt>-nounit</tt>, the directive should contain <code>(require 'mod1)</code>.
This option allows for mixed loading as well, where some modules are imported with <code>(declare (uses <i>modname</i>))</code>
(which means they were compiled without -nounit) and some are imported with <code>(require 'modname)</code>.</p>
<p>The other option is to use the second idea in the above section. Compile all the modules normally, without any
<code>%insert(closprefix)</code>, <tt>-nounit</tt>, or <tt>-noclosuses</tt>. Then the modules will import each other correctly
with <code>(declare (uses ...))</code>.
To create an extension library or an egg, just create a <tt>module_load.scm</tt> file that <code>(declare (uses ...))</code>
all the modules.</p>
<H2><a name="Chicken_nn16"></a>19.5 Typemaps</H2>
<p>
The Chicken module handles all types via typemaps. This information is
read from <code>Lib/chicken/typemaps.i</code> and
<code>Lib/chicken/chicken.swg</code>.
</p>
<H2><a name="Chicken_nn17"></a>19.6 Pointers</H2>
<p>
For pointer types, SWIG uses CHICKEN tagged pointers.
A tagged pointer is an ordinary CHICKEN pointer with an
extra slot for a void *. With SWIG
CHICKEN, this void * is a pointer to a type-info
structure. So each pointer used as input or output from
the SWIG-generated CHICKEN wrappers will have type
information attached to it. This will let the wrappers
correctly determine which method should be called
according to the object type hierarchy exposed in the SWIG
interface files.
</p>
<p>
To construct a Scheme object from a C pointer, the wrapper code
calls the function
<code>SWIG_NewPointerObj(void *ptr, swig_type_info *type, int owner)</code>,
The function that calls <code>SWIG_NewPointerObj</code> must have a variable declared
<code>C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);</code>
It is ok to call <code>SWIG_NewPointerObj</code> more than once,
just make sure known_space has enough space for all the created pointers.
</p>
<p>
To get the pointer represented by a CHICKEN tagged pointer, the
wrapper code calls the function
<code>SWIG_ConvertPtr(C_word s, void **result, swig_type_info *type, int flags)</code>,
passing a pointer to a struct representing the expected pointer
type. flags is either zero or SWIG_POINTER_DISOWN (see below).
</p>
<H3><a name="Chicken_collection"></a>19.6.1 Garbage collection</H3>
<p>If the owner flag passed to <code>SWIG_NewPointerObj</code> is 1, <code>NewPointerObj</code> will add a
finalizer to the type which will call the destructor or delete method of
that type. The destructor and delete functions are no longer exported for
use in scheme code, instead SWIG and chicken manage pointers.
In situations where SWIG knows that a function is returning a type that should
be garbage collected, SWIG will automatically set the owner flag to 1. For other functions,
the <code>%newobject</code> directive must be specified for functions whose return values
should be garbage collected. See
<a href="Customization.html#Customization_ownership">Object ownership and %newobject</a> for more information.
</p>
<p>In situations where a C or C++ function will assume ownership of a pointer, and thus
chicken should no longer garbage collect it, SWIG provides the <code>DISOWN</code> input typemap.
After applying this typemap (see the <a href="Typemaps.html#Typemaps">Typemaps chapter</a> for more information on how to apply typemaps),
any pointer that gets passed in will no longer be garbage collected.
An object is disowned by passing the <code>SWIG_POINTER_DISOWN</code> flag to <code>SWIG_ConvertPtr</code>.
<b>Warning:</b> Since the lifetime of the object is now controlled by the underlying code, the object might
get deleted while the scheme code still holds a pointer to it. Further use of this pointer
can lead to a crash.
</p>
<p>Adding a finalizer function from C code was added to chicken in the 1.89 release, so garbage collection
does not work for chicken versions below 1.89. If you would like the SWIG generated code to work with
chicken 1.40 to 1.89, pass the <code>-nocollection</code> argument to SWIG. This will not export code
inside the _wrap.c file to register finalizers, and will then export destructor functions which
must be called manually.
</p>
<H2><a name="Chicken_nn18"></a>19.7 Unsupported features and known problems</H2>
<ul>
<li>No director support.</li>
<li>No support for c++ standard types like std::vector.</li>
<li>The TinyCLOS wrappers for overloaded functions will not work correctly when using
<a href="SWIGPlus.html#SWIGPlus_default_args">%feature(compactdefaultargs)</a>.</li>
</ul>
<H3><a name="Chicken_nn19"></a>19.7.1 TinyCLOS problems with Chicken version &lt;= 1.92</H3>
<p>In Chicken versions equal to or below 1.92, TinyCLOS has a limitation such that generic methods do not properly work on methods
with different number of specializers: TinyCLOS assumes that every method added to a generic function
will have the same number of specializers. SWIG generates functions with different lengths of specializers
when C/C++ functions are overloaded. For example, the code</p>
<div class="code">
<pre>
class Foo {};
int foo(int a, Foo *b);
int foo(int a);
</pre></div>
<p>will produce scheme code</p>
<div class="targetlang">
<pre>
(define-method (foo (arg0 &lt;top&gt;) (arg1 &lt;Foo&gt;)) (<i>call primitive function</i>))
(define-method (foo (arg0 &lt;top&gt;)) (<i>call primitive function</i>))
</pre></div>
<p>Using unpatched TinyCLOS, the second <code>(define-method)</code> will replace the first one,
so calling <code>(foo 3 f)</code> will produce an error.</p>
<p>There are three solutions to this. The easist is to upgrade to the latest Chicken version. Otherwise, the
file <tt>Lib/chicken/tinyclos-multi-generic.patch</tt> in the SWIG source contains a patch against
tinyclos.scm inside the 1.92 chicken source to add support into TinyCLOS for multi-argument generics. (This patch was accepted into Chicken)
This requires chicken to be rebuilt and custom install of chicken. An alternative is the <tt>Lib/chicken/multi-generic.scm</tt>
file in the SWIG source. This file can be loaded after TinyCLOS is loaded, and it will override some functions
inside TinyCLOS to correctly support multi-argument generics. Please see the comments at the top of both files for more information.</p>
</body>
</html>

1650
Doc/Manual/Contents.html Normal file

File diff suppressed because it is too large Load diff

274
Doc/Manual/Contract.html Normal file
View file

@ -0,0 +1,274 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Contract Checking</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Contract"></a>12 Contracts</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Contract_nn2">The %contract directive</a>
<li><a href="#Contract_nn3">%contract and classes</a>
<li><a href="#Contract_nn4">Constant aggregation and %aggregate_check</a>
<li><a href="#Contract_nn5">Notes</a>
</ul>
</div>
<!-- INDEX -->
<p>
A common problem that arises when wrapping C libraries is that of maintaining
reliability and checking for errors. The fact of the matter is that many
C programs are notorious for not providing error checks. Not only that,
when you expose the internals of an application as a library, it
often becomes possible to crash it simply by providing bad inputs or
using it in a way that wasn't intended.
</p>
<p>
This chapter describes SWIG's support for software contracts. In the context
of SWIG, a contract can be viewed as a runtime constraint that is attached
to a declaration. For example, you can easily attach argument checking rules,
check the output values of a function and more.
When one of the rules is violated by a script, a runtime exception is
generated rather than having the program continue to execute.
</p>
<H2><a name="Contract_nn2"></a>12.1 The %contract directive</H2>
<p>
Contracts are added to a declaration using the %contract directive. Here
is a simple example:
</p>
<div class="code">
<pre>
%contract sqrt(double x) {
require:
x &gt;= 0;
ensure:
sqrt &gt;= 0;
}
...
double sqrt(double);
</pre>
</div>
<p>
In this case, a contract is being added to the <tt>sqrt()</tt> function.
The <tt>%contract</tt> directive must always appear before the declaration
in question. Within the contract there are two sections, both of which
are optional. The <tt>require:</tt>
section specifies conditions that must hold before the function is called.
Typically, this is used to check argument values. The <tt>ensure:</tt> section
specifies conditions that must hold after the function is called. This is
often used to check return values or the state of the program. In both
cases, the conditions that must hold must be specified as boolean expressions.
</p>
<p>
In the above example, we're simply making sure that sqrt() returns a non-negative
number (if it didn't, then it would be broken in some way).
</p>
<p>
Once a contract has been specified, it modifies the behavior of the
resulting module. For example:
</p>
<div class="shell">
<pre>
&gt;&gt;&gt; example.sqrt(2)
1.4142135623730951
&gt;&gt;&gt; example.sqrt(-2)
Traceback (most recent call last):
File "&lt;stdin&gt;", line 1, in ?
RuntimeError: Contract violation: require: (arg1&gt;=0)
&gt;&gt;&gt;
</pre>
</div>
<H2><a name="Contract_nn3"></a>12.2 %contract and classes</H2>
<p>
The <tt>%contract</tt> directive can also be applied to class methods and constructors. For example:
</p>
<div class="code">
<pre>
%contract Foo::bar(int x, int y) {
require:
x &gt; 0;
ensure:
bar &gt; 0;
}
%contract Foo::Foo(int a) {
require:
a &gt; 0;
}
class Foo {
public:
Foo(int);
int bar(int, int);
};
</pre>
</div>
<p>
The way in which <tt>%contract</tt> is applied is exactly the same as the <tt>%feature</tt> directive.
Thus, any contract that you specified for a base class will also be attached to inherited methods. For example:
</p>
<div class="code">
<pre>
class Spam : public Foo {
public:
int bar(int,int); // Gets contract defined for Foo::bar(int,int)
};
</pre>
</div>
<p>
In addition to this, separate contracts can be applied to both the base class and a derived class. For example:
</p>
<div class="code">
<pre>
%contract Foo::bar(int x, int) {
require:
x &gt; 0;
}
%contract Spam::bar(int, int y) {
require:
y &gt; 0;
}
class Foo {
public:
int bar(int,int); // Gets Foo::bar contract.
};
class Spam : public Foo {
public:
int bar(int,int); // Gets Foo::bar and Spam::bar contract
};
</pre>
</div>
<p>
When more than one contract is applied, the conditions specified in a
"require:" section are combined together using a logical-AND operation.
In other words conditions specified for the base class and conditions
specified for the derived class all must hold. In the above example,
this means that both the arguments to <tt>Spam::bar</tt> must be positive.
</p>
<H2><a name="Contract_nn4"></a>12.3 Constant aggregation and %aggregate_check</H2>
<p>
Consider an interface file that contains the following code:
</p>
<div class="code">
<pre>
#define UP 1
#define DOWN 2
#define RIGHT 3
#define LEFT 4
void move(SomeObject *, int direction, int distance);
</pre>
</div>
<p>
One thing you might want to do is impose a constraint on the direction parameter to
make sure it's one of a few accepted values. To do that, SWIG provides an easy to
use macro %aggregate_check() that works like this:
</p>
<div class="code">
<pre>
%aggregate_check(int, check_direction, UP, DOWN, LEFT, RIGHT);
</pre>
</div>
<p>
This merely defines a utility function of the form
</p>
<div class="code">
<pre>
int check_direction(int x);
</pre>
</div>
<p>
That checks the argument x to see if it is one of the values listed. This utility
function can be used in contracts. For example:
</p>
<div class="code">
<pre>
%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
%contract move(SomeObject *, int direction, in) {
require:
check_direction(direction);
}
#define UP 1
#define DOWN 2
#define RIGHT 3
#define LEFT 4
void move(SomeObject *, int direction, int distance);
</pre>
</div>
<p>
Alternatively, it can be used in typemaps and other directives. For example:
</p>
<div class="code">
<pre>
%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
%typemap(check) int direction {
if (!check_direction($1)) SWIG_exception(SWIG_ValueError, "Bad direction");
}
#define UP 1
#define DOWN 2
#define RIGHT 3
#define LEFT 4
void move(SomeObject *, int direction, int distance);
</pre>
</div>
<p>
Regrettably, there is no automatic way to perform similar checks with enums values. Maybe in a future
release.
</p>
<H2><a name="Contract_nn5"></a>12.4 Notes</H2>
<p>
Contract support was implemented by Songyan (Tiger) Feng and first appeared
in SWIG-1.3.20.
</p>
</body>
</html>

File diff suppressed because it is too large Load diff

430
Doc/Manual/D.html Normal file
View file

@ -0,0 +1,430 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and D</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="D"></a>20 SWIG and D</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#D_introduction">Introduction</a>
<li><a href="#D_command_line_invocation">Command line invocation</a>
<li><a href="#D_typemaps">Typemaps</a>
<ul>
<li><a href="#D_typemap_name_comparison">C# &lt;-&gt; D name comparison</a>
<li><a href="#D_ctype_imtype_dtype">ctype, imtype, dtype</a>
<li><a href="#D_in_out_directorin_direcetorout">in, out, directorin, directorout</a>
<li><a href="#D_din_dout_ddirectorin_ddirectorout">din, dout, ddirectorin, ddirectorout</a>
<li><a href="#D_typecheck_typemaps">typecheck typemaps</a>
<li><a href="#D_code_injection_typemaps">Code injection typemaps</a>
<li><a href="#D_special_variables">Special variable macros</a>
</ul>
<li><a href="#D_features"><tt>%feature</tt>s</a>
<li><a href="#D_pragmas">Pragmas</a>
<li><a href="#D_exceptions">D Exceptions</a>
<li><a href="#D_directors">D Directors</a>
<li><a href="#D_other_features">Other features</a>
<ul>
<li><a href="#D_native_pointer_support">Native pointer support</a>
<li><a href="#D_test_suite">Running the test-suite</a>
</ul>
<li><a href="#D_typemap_examples">D Typemap examples</a>
<li><a href="#D_planned_features">Work in progress and planned features</a>
</ul>
</div>
<!-- INDEX -->
<H2><a name="D_introduction"></a>20.1 Introduction</H2>
<p>From the <a href="http://www.digitalmars.com/d/">D Programming Language</a> web site: <em>»D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. […] The D language is statically typed and compiles directly to machine code.«</em> As such, it is not very surprising that D is able to directly <a href="http://www.digitalmars.com/d/1.0/interfaceToC.html">interface with C libraries</a>. Why would a SWIG module for D be needed then in the first place?</p>
<p>Well, besides the obvious downside that the C header files have to be manually converted to D modules for this to work, there is one major inconvenience with this approach: D code usually is on a higher abstraction level than C, and many of the features that make D interesting are simply not available when dealing with C libraries, requiring you e.g. to manually convert strings between pointers to <tt>\0</tt>-terminated char arrays and D char arrays, making the algorithms from the D2 standard library unusable with C arrays and data structures, and so on.</p>
<p>While these issues can be worked around relatively easy by hand-coding a thin wrapper layer around the C library in question, there is another issue where writing wrapper code per hand is not feasible: C++ libraries. D did not support interfacing to C++ in version 1 at all, and even if <tt>extern(C++)</tt> has been added to D2, the support is still very limited, and a custom wrapper layer is still required in many cases. </p>
<p>To help addressing these issues, the SWIG C# module has been forked to support D. Is has evolved quite a lot since then, but there are still many similarities, so if you do not find what you are looking for on this page, it might be worth having a look at the chapter on <a href="CSharp.html">C#</a> (and also on <a href="Java.html">Java</a>, since the C# module was in turn forked from it).</p>
<H2><a name="D_command_line_invocation"></a>20.2 Command line invocation</H2>
<p>To activate the D module, pass the <tt>-d</tt> option to SWIG at the command line. The same standard command line switches as with any other language module are available, plus the following D specific ones:</p>
<dl>
<dt><tt>-d2</tt></dt>
<dd>
<p>By default, SWIG generates code for D1/Tango. Use the <tt>-d2</tt> flag to target D2/Phobos instead.</p>
</dd>
<dt id="D_splitproxy"><tt>-splitproxy</tt></dt>
<dd>
<p>By default, SWIG generates two D modules: the <em>proxy</em> module, named like the source module (either specified via the <tt>%module</tt> directive or via the <tt>module</tt> command line switch), which contains all the proxy classes, functions, enums, etc., and the <em>intermediary</em> module (named like the proxy module, but suffixed with <tt>_im</tt>), which contains all the <tt>extern(C)</tt> function declarations and other private parts only used internally by the proxy module.</p>
<p>If the split proxy mode is enabled by passing this switch at the command line, all proxy classes and enums are emitted to their own D module instead. The main proxy module only contains free functions and constants in this case.</p>
</dd>
<dt><tt>-package &lt;pkg&gt;</tt></dt>
<dd>
<p>By default, the proxy D modules and the intermediary D module are written to the root package. Using this option, you can specify another target package instead.</p>
</dd>
<dt><tt>-wrapperlibrary &lt;wl&gt;</tt></dt>
<dd>
<p>The code SWIG generates to dynamically load the C/C++ wrapper layer looks for a library called <tt>$module_wrap</tt> by default. With this switch, you can override the name of the file the wrapper code loads at runtime (the <tt>lib</tt> prefix and the suffix for shared libraries are appended automatically, depending on the OS).</p>
<p>This might especially be useful if you want to invoke SWIG several times on separate modules, but compile the resulting code into a single shared library.</p>
</dd>
</dl>
<H2><a name="D_typemaps"></a>20.3 Typemaps</H2>
<H3><a name="D_typemap_name_comparison"></a>20.3.1 C# &lt;-&gt; D name comparison</H3>
<p>If you already know the SWIG C# module, you might find the following name comparison table useful:</p>
<div class="diagram"><pre>
ctype &lt;-&gt; ctype
imtype &lt;-&gt; imtype
cstype &lt;-&gt; dtype
csin &lt;-&gt; din
csout &lt;-&gt; dout
csdirectorin &lt;-&gt; ddirectorin
csdirectorout &lt;-&gt; ddirectorout
csinterfaces &lt;-&gt; dinterfaces
csinterfaces_derived &lt;-&gt; dinterfaces_derived
csbase &lt;-&gt; dbase
csclassmodifiers &lt;-&gt; dclassmodifiers
cscode &lt;-&gt; dcode
csimports &lt;-&gt; dimports
csbody &lt;-&gt; dbody
csfinalize &lt;-&gt; ddestructor
csdestruct &lt;-&gt; ddispose
csdestruct_derived &lt;-&gt; ddispose_derived
</pre></div>
<H3><a name="D_ctype_imtype_dtype"></a>20.3.2 ctype, imtype, dtype</H3>
<p>Mapping of types between the C/C++ library, the C/C++ library wrapper exposing the C functions, the D wrapper module importing these functions and the D proxy code.</p>
<p>The <tt>ctype</tt> typemap is used to determine the types to use in the C wrapper functions. The types from the <tt>imtype</tt> typemap are used in the extern(C) declarations of these functions in the intermediary D module. The <tt>dtype</tt> typemap contains the D types used in the D proxy module/class.</p>
<H3><a name="D_in_out_directorin_direcetorout"></a>20.3.3 in, out, directorin, directorout</H3>
<p>Used for converting between the types for C/C++ and D when generating the code for the wrapper functions (on the C++ side).</p>
<p>The code from the <tt>in</tt> typemap is used to convert arguments to the C wrapper function to the type used in the wrapped code (<tt>ctype</tt>->original C++ type), the <tt>out</tt> typemap is utilized to convert values from the wrapped code to wrapper function return types (original C++ type-><tt>ctype</tt>).</p>
<p>The <tt>directorin</tt> typemap is used to convert parameters to the type used in the D director callback function, its return value is processed by <tt>directorout</tt> (see below).</p>
<H3><a name="D_din_dout_ddirectorin_ddirectorout"></a>20.3.4 din, dout, ddirectorin, ddirectorout</H3>
<p>Typemaps for code generation in D proxy and type wrapper classes.</p>
<p id="D_din">The <tt>din</tt> typemap is used for converting function parameter types from the type used in the proxy module or class to the type used in the intermediary D module (the <a href="D.html#D_dinput"><tt>$dinput</tt></a> macro is replaced).</p>
<p id="D_dout">The <tt>dout</tt> typemap is used for converting function return values from the return type used in the intermediary D module to the type returned by the proxy function. The <tt>$excode</tt> special variable in <tt>dout</tt> typemaps is replaced by the <tt>excode</tt> typemap attribute code if the method can throw any exceptions from unmanaged code, otherwise by nothing (the <a href="D.html#D_wcall"><tt>$imcall</tt> and <tt>$owner</tt></a> macros are replaced).</p>
<p id="D_ddirectorinout">The code from the <tt>ddirectorin</tt> and <tt>ddirectorout</tt> typemaps is used for conversion in director callback functions. Arguments are converted to the type used in the proxy class method they are calling by using the code from <tt>ddirectorin</tt>, the proxy class method return value is converted to the type the C++ code expects via the <tt>ddirectorout</tt> typemap (the <a href="D.html#D_dpcall"><tt>$dcall</tt> and <tt>$winput</tt></a> macros are replaced).</p>
<p>The full chain of type conversions when a director callback is invoked looks like this:</p>
<div class="diagram"><pre> type CPPClass::method(type a)
↑ ↓
&lt;directorout&gt; &lt;directorin&gt;
↑ ↓
ctype methodCallback(ctype a) C++
::::::::::::::::::::::::::::::::::::::::::
imtype methodCallback(imtype a) D
↑ ↓
&lt;ddirectorout&gt; &lt;ddirectorin&gt;
↑ ↓
dtype DClass.method(dtype a)</pre></div>
<H3><a name="D_typecheck_typemaps"></a>20.3.5 typecheck typemaps</H3>
<p>Because, unlike many scripting languages supported by SWIG, D does not need any dynamic dispatch helper to access an overloaded function, the purpose of these is merely to issue a warning for overloaded C++ functions that cannot be overloaded in D (as more than one C++ type maps to a single D type).</p>
<H3><a name="D_code_injection_typemaps"></a>20.3.6 Code injection typemaps</H3>
<p>These typemaps are used for generating the skeleton of proxy classes for C++ types.</p>
<p>By overriding <tt>dbase</tt>, <tt>dinterfaces</tt> or <tt>dinterfaces_derived</tt>, the inheritance chain of the generated proxy class for a type can be modified. <tt>dclassmodifiers</tt> allows you to add any custom modifiers around the class keyword.</p>
<p>Using <tt>dcode</tt> and <tt>dimports</tt>, you can specify additional D code which will be emitted into the class body respectively the imports section of the D module the class is written to.</p>
<p id="D_class_code_typemaps"><tt>dconstructor</tt>, <tt>ddestructor</tt>, <tt>ddispose</tt> and <tt>ddispose_derived</tt> are used to generate the class constructor, destructor and <tt>dispose()</tt> method, respectively. The auxiliary code for handling the pointer to the C++ object is stored in <tt>dbody</tt> and <tt>dbody_derived</tt>. You can override them for specific types.</p>
<H3><a name="D_special_variables"></a>20.3.7 Special variable macros</H3>
<p>The standard SWIG special variables are available for use within typemaps as described in the <a href="Typemaps.html#Typemaps">Typemaps documentation</a>, for example <tt>$1</tt>, <tt>$input</tt>, <tt>$result</tt> etc.</p>
<p>When generating D wrappers, a few additional macros are available:</p>
<dl>
<dt><tt>$dclassname</tt> (C#: <tt>$csclassname</tt>)</dt>
<dd>
<p>This special variable works similar to <a href="Typemaps.html#Typemaps_special_variables"><tt>$n_type</tt></a> in that it returns the name of a type it expands to the D proxy class name of the type being wrapped. If the type does not have an associated proxy class, it expands to the type wrapper class name, for example, <tt>SWIGTYPE_p_p_SomeCppClass</tt> is generated when wrapping <tt>SomeCppClass **</tt>.</p>
<p>There are two other variants available, <tt>$&amp;dclassname</tt> and <tt>$*dclassname</tt>. The former adds a level of indirection, while the latter removes one. For instance, when wrapping <tt>Foo **</tt>, <tt>$*dclassname</tt> would be replaced by the proxy class name corresponding to <tt>Foo *</tt>.</p>
</dd>
<dt><tt>$null</tt></dt>
<dd><p>In code inserted into the generated C/C++ wrapper functions, this variable is replaced by either <tt>0</tt> or nothing at all, depending on whether the function has a return value or not. It can be used to bail out early e.g. in case of errors (<tt>return $null;</tt>).</p></dd>
<dt id="D_dinput"><tt>$dinput</tt> (C#: <tt>$csinput</tt>)</dt>
<dd>
<p>This variable is used in <tt><a href="D.html#D_din">din</a></tt> typemaps and is replaced by the expression which is to be passed to C/C++.</p>
<p>For example, this input</p>
<div class="code"><pre>
%typemap(din) SomeClass * "SomeClass.getCPointer($dinput)"
%inline %{
class SomeClass {};
void foo(SomeClass *arg);
%}</pre></div>
<p>leads to the following D proxy code being generated:</p>
<div class="targetlang"><pre>
void foo(SomeClass arg) {
example_im.foo(SomeClass.getCPointer(arg));
}</pre></div></dd>
<dt id="D_wcall"><tt>$imcall</tt> and <tt>$owner</tt> (C#: <tt>$imcall</tt>)</dt>
<dd>
<p>These variables are used in <tt><a href="D.html#D_dout">dout</a></tt> typemaps. <tt>$imcall</tt> contains the call to the intermediary module which provides the value to be used, and <tt>$owner</tt> signals if the caller is responsible for managing the object lifetime (that is, if the called method is a constructor or has been marked via <tt>%newobject</tt>).</p>
<p>Consider the following example:</p>
<div class="code"><pre>
%typemap(dout) SomeClass * {
return new SomeClass($imcall, $owner);
}
%inline %{
class SomeClass;
SomeClass *foo();
%newobject bar();
SomeClass *bar();
%}</pre></div>
<p>The code generated for <tt>foo()</tt> and <tt>bar()</tt> looks like this:</p>
<div class="targetlang"><pre>
SomeClass foo() {
return new SomeClass(example_im.foo(), false);
}
SomeClass bar() {
return new SomeClass(example_im.bar(), true);
}
</pre></div>
</dd>
<dt><tt>$dcall</tt> and <tt>$winput</tt> (C#: <tt>$cscall</tt>, <tt>$iminput</tt>)</dt>
<dd id="D_dpcall"><p>These variables are used in the director-specific typemaps <a href="D.html#D_ddirectorinout"><tt>ddirectorin</tt></a> and <a href="D.html#D_ddirectorinout"><tt>ddirectorout</tt></a>. They are more or less the reverse of the <tt>$imcall</tt> and <tt>$dinput</tt> macros: <tt>$dcall</tt> contains the invocation of the D proxy method of which the return value is to be passed back to C++, <tt>$winput</tt> contains the parameter value from C++.</p></dd>
<dt><tt>$excode</tt></dt>
<dd><p>This variable is used in <tt>dout</tt> and <tt>dconstructor</tt> typemaps and is filled with the contents of the <tt>excode</tt> typemap attribute if an exception could be thrown from the C++ side. See the <a href="CSharp.html#CSharp_exceptions">C# documentation</a> for details.</p></dd>
<dt><tt>$dbaseclass</tt></dt>
<dd><p>Currently for internal use only, it contains the D name of the C++ base class (if any) inside proxy classes.</p></dd>
<dt><tt>$directorconnect</tt></dt>
<dd>
<p>This macro is only valid inside the <tt><a href="D.html#D_class_code_typemaps">dconstructor</a></tt> typemap and contains the value of the <tt>dconstructor</tt> typemap attribute if the currently wrapped class has directors enabled.</p>
<p>This is how the default <tt>dconstructor</tt> typemap looks like (you usually do not want to specify a custom one):</p>
<div class="code"><pre>
%typemap(dconstructor, excode=SWIGEXCODE,directorconnect="\n swigDirectorConnect();") SWIGTYPE {
this($imcall, true);$excode$directorconnect
}
</pre></div>
</dd>
<dt id="D_importtype"><tt>$importtype(SomeDType)</tt></dt>
<dd>
<p>This macro is used in the <tt>dimports</tt> typemap if a dependency on another D type generated by SWIG is added by a custom typemap.</p>
<p>Consider the following code snippet:</p>
<div class="code"><pre>
%typemap(dinterfaces) SomeClass "AnInterface, AnotherInterface";
</pre></div>
<p>This causes SWIG to add <tt>AnInterface</tt> and <tt>AnotherInterface</tt> to the base class list of <tt>SomeClass</tt>:</p>
<div class="targetlang"><pre>
class SomeClass : AnInterface, AnotherInterface {
}
</pre></div>
<p>For this to work, <tt>AnInterface</tt> and <tt>AnotherInterface</tt> have to be in scope. If SWIG is not in split proxy mode, this is already the case, but it it is, they have to be added to the import list via the <tt>dimports</tt> typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.</p>
<p>The <tt>$importtype</tt> macro helps you to elegantly solve this problem:</p>
<div class="code"><pre>
%typemap(dimports) RemoteMpe %{
$importtype(AnInterface)
$importtype(AnotherInterface)
%}
</pre></div>
<p>If SWIG is in split proxy mode, it expands to an <tt>import</tt> statement for the specified type, to nothing if not.</p>
</dd>
<dt><tt>$module</tt></dt>
<dd><p>Expands to the name of the main proxy D module.</p></dd>
<dt><tt>$imdmodule</tt></dt>
<dd><p>Contains the fully qualified name of the intermediary D module.</p></dd>
</dl>
<H2><a name="D_features"></a>20.4 <tt>%feature</tt>s</H2>
<p>The D module defines a number of directives which modify the <a href="Customization.html#Customization_features">SWIG features</a> set globally or for a specific declaration:</p>
<dl>
<dt><tt>%dmanifestconst</tt> and <tt>%dconstvalue(value)</tt></dt>
<dd>
<p>Out of the box, SWIG generates accessor methods for C <tt>#defines</tt> and C++ constants. The <tt>%dmanifestconst</tt> directive enables wrapping these constants as D manifest constants (<tt>const</tt> in D1, <tt>enum</tt> in D2).</p>
<p>For this to work, the C/C++ code for the constant value must directly compile as D code, though. If this is not the case, you can manually override the expression written to the D proxy module using the <tt>%dconstvalue</tt> directive, passing the new value as parameter.</p>
<p>For <tt>enum</tt>s, again <tt>%dconstvalue</tt> can be used to override the value of an enum item if the initializer should not compile in D.</p>
</dd>
<dt><tt>%dmethodmodifiers</tt></dt>
<dd>
<p>This directive can be used to override the modifiers for a proxy function. For instance, you could make a <tt>public</tt> C++ member function <tt>private</tt> in D like this:</p>
<div class="code"><pre>
%dmethodmodifiers A::foo "private";
%inline %{
struct A {
void foo();
};
%}
</pre></div>
</dd>
</dl>
<H2><a name="D_pragmas"></a>20.5 Pragmas</H2>
<p>There are a few SWIG pragmas specific to the D module, which you can use to influence the D code SWIG generates:</p>
<dl>
<dt><tt>%pragma(d) imdmodulecode</tt></dt>
<dd><p>The passed text (D code) is copied verbatim to the intermediary D module. For example, it can be (and is, internally) used to emit additional private helper code for the use by proxy typemaps.</p></dd>
<dt><tt>%pragma(d) imdmoduleimports</tt></dt>
<dd><p>Additional code to be emitted to the imports section of the intermediary D module (the <a href="D.html#D_importtype">$importtype</a> macro can be used here). You probably want to use this in conjunction with the <tt>imdmodulecode</tt> pragma.</p></dd>
<dt><tt>%pragma(d) proxydmodulecode</tt></dt>
<dd><p>Just like <tt>proxydmodulecode</tt>, the argument is copied to the proxy D module (if SWIG is in <a href="D.html#D_splitproxy">split proxy mode</a>, it is emitted to the main proxy D module only).</p></dd>
<dt><tt>%pragma(d) globalproxyimports</tt></dt>
<dd>
<p>The D module currently does not support specifying dependencies on external modules (e.g. from the standard library) for the D typemaps. To add the import statements to the proxy modules (resp. to <em>all</em> proxy modules if in split proxy mode), you can use the <tt>globalproxyimports</tt> directive.</p>
<p>For example:</p>
<div class="code"><pre>
%typemap(din) char[] "($dinput ? tango.stdc.stringz.toStringz($dinput) : null)"
%pragma(d) globalproxyimports = "static import tango.stdc.stringz;";
</pre></div>
</dd>
<dt><tt>%pragma(d) wrapperloadercode</tt></dt>
<dd>
<p>The D code for loading the wrapper library (it is copied to the intermediary D module). The <tt>$wrapperloaderbindcode</tt> variable is replaced by the list of commands for binding the functions from the wrapper library to the symbols in the intermediary D module.</p>
<p>Each time this pragma is specified, the previous value is overwritten.</p>
</dd>
<dt><tt>%pragma(d) wrapperloaderbindcommand</tt></dt>
<dd>
<p>The D command to use for binding the wrapper functions from the C/C++ library to the symbols in the intermediary D module. The <tt>$function</tt> variable contains the name of the D function in the wrap module, the <tt>$symbol</tt> variable is replaced by the name of the symbol in the library.</p>
<p>Each time this pragma is specified, the previous value is overwritten.</p>
</dd>
</dl>
<H2><a name="D_exceptions"></a>20.6 D Exceptions</H2>
<p>Out of the box, C++ exceptions are fundamentally incompatible to their equivalent in the D world and cannot simply be propagated to a calling D method. There is, however, an easy way to solve this problem: Just catch the exception in the C/C++ wrapper layer, pass the contents to D, and make the wrapper code rethrow the exception in the D world.</p>
<p>The implementation details of this are a bit crude, but the SWIG D module automatically takes care of this, as long as it is able to detect that an exception could potentially be thrown (e.g. because the C++ method has a <tt>throw(…)</tt> exception specification).</p>
<p>As this feature is implemented in exactly the same way it is for C#, please see the <a href="CSharp.html#CSharp_exceptions">C# documentation</a> for a more detailed explanation.</p>
<H2><a name="D_directors"></a>20.7 D Directors</H2>
<p>When the directors feature is activated, SWIG generates extra code on both the C++ and the D side to enable cross-language polymorphism. Essentially, this means that if you subclass a proxy class in D, C++ code can access any overridden virtual methods just as if you created a derived class in C++.</p>
<p>There is no D specific documentation yet, but the way the feature is implemented is very similar to how it is done in <a href="Java.html#Java_directors">Java</a> and <a href="CSharp.html#CSharp_directors">C#</a>.
</p>
<H2><a name="D_other_features"></a>20.8 Other features</H2>
<p>The <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature of SWIG is not yet supported for D all class modules are written to the same package, regardless of which C++ namespace they are in.</p>
<H3><a name="D_native_pointer_support"></a>20.8.1 Native pointer support</H3>
<p>Contrary to many of the scripting languages supported by SWIG, D fully supports C-style pointers. The D module thus includes a custom mechanism to wrap C pointers directly as D pointers where applicable, that is, if the type that is pointed to is represented the same in C and D (on the bit-level), dubbed a »primtive type« below.</p>
<p>Central to this custom pointer handling scheme are two typemap attributes: the <tt>cprimitive</tt> attribute on the <tt>dtype</tt> typemap and the <tt>nativepointer</tt> attribute on all the typemaps which influence the D side of the code (<tt>dtype</tt>, <tt>din</tt>, <tt>dout</tt>, …). When a D typemap is looked up, the following happens behind the scenes:</p>
<p>First, the matching typemap is determined by the usual typemap lookup rules. Then, it is checked if the result has the <tt>nativepointer</tt> attribute set. If it is present, it means that its value should replace the typemap value <em>if and only if</em> the actual type the typemap is looked up for is a primitive type, a pointer to a primitive type (through an arbitrary level of indirections), or a function pointer with only primitive types in its signature.</p>
<p>To determine if a type should be considered primitive, the <tt>cprimitive</tt> attribute on its <tt>dtype</tt> attribute is used. For example, the <tt>dtype</tt> typemap for <tt>float</tt> has <tt>cprimitive="1"</tt>, so the code from the <tt>nativepointer</tt> attribute is taken into account e.g. for <tt>float **</tt> or the function pointer <tt>float (*)(float *)</tt>.</p>
<H3><a name="D_test_suite"></a>20.8.2 Running the test-suite</H3>
<p>As with any other language, the SWIG test-suite can be built for D using the <tt>*-d-test-suite</tt> targets of the top-level Makefile. By default, D1 is targeted, to build it with D2, use the optional <tt>D_VERSION</tt> variable, e.g. <tt>make check-d-test-suite D_VERSION=2</tt>.</p>
<p>Note: If you want to use GDC on Linux or another platform which requires you to link <tt>libdl</tt> for dynamically loading the shared library, you might have to add <tt>-ldl</tt> manually to the <tt>d_compile</tt> target in <tt>Examples/Makefile</tt>, because GDC does not currently honor the <tt>pragma(lib,…)</tt> statement.</p>
<H2><a name="D_typemap_examples"></a>20.9 D Typemap examples</H2>
<p>There are no D-specific typemap examples yet. However, with the above <a href="D.html#D_typemap_name_comparison">name comparison table</a>, you should be able to get an idea what can be done by looking at the <a href="CSharp.html#CSharp_typemap_examples">corresponding C# section</a>.</p>
<H2><a name="D_planned_features"></a>20.10 Work in progress and planned features</H2>
<p>There are a couple of features which are not implemented yet, but would be very useful and might be added in the near future:</p>
<ul>
<li><em>Static linking:</em> Currently, the C wrapper code is compiled into a dynamic library, out of which the symbol addresses are looked up at runtime by the D part. If statically linking the different languages into one binary was supported, a tool-chain capable of performing IPO at link time could inline the wrapping code, effectively reducing the overhead for simple calls to zero.</li>
<li><em>C array handling:</em> Many data structures in some C/C++ libraries contain array containing of a pointer to the first element and the element count. Currently, one must manually writing wrapper code to be able to access these from D. It should be possible to add a set of SWIG macros to semi-automatically generate conversion code.</li>
<li><em>Operator overloading:</em> Currently, operator overloading is supported only to a very limited extent many C++ operators are just ignored with a warning. The problem here is that the way D handles operator overloading differs quite a lot from the way C++ does it, both syntactically and semantically, and even more so since the advent of template-based operator overloading in D2.</li>
</ul>
<p>Some generated code might also be a bit rough around the edges, particularly in the following areas:</p>
<ul>
<li><em>Memory management:</em> Although the currently generated wrapper code works fine with regard to the GC for the test-suite, there might be issues coming up in real-world multi-threaded usage.</li>
<li><em>D2 support</em>: Originally, the module has been developed for the use with D1, D2/Phobos support has been added in later. The basic features should work equally well for both, but there <em>could</em> be issues concerning const-correctness etc.</li>
</ul>
</body>
</html>

4057
Doc/Manual/Extending.html Normal file

File diff suppressed because it is too large Load diff

454
Doc/Manual/Go.html Normal file
View file

@ -0,0 +1,454 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Go</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="Go"></a>20 SWIG and Go</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Go_overview">Overview</a>
<li><a href="#Go_running_swig">Running SWIG with Go</a>
<ul>
<li><a href="#Go_commandline">Additional Commandline Options</a>
<li><a href="#Go_outputs">Go Output Files</a>
</ul>
<li><a href="#Go_basic_tour">A tour of basic C/C++ wrapping</a>
<ul>
<li><a href="#Go_package">Go Package Name</a>
<li><a href="#Go_names">Go Names</a>
<li><a href="#Go_constants">Go Constants</a>
<li><a href="#Go_enumerations">Go Enumerations</a>
<li><a href="#Go_classes">Go Classes</a>
<ul>
<li><a href="#Go_class_inheritance">Go Class Inheritance</a>
</ul>
<li><a href="#Go_templates">Go Templates</a>
<li><a href="#Go_director_classes">Go Director Classes</a>
<li><a href="#Go_primitive_type_mappings">Default Go primitive type mappings</a>
</ul>
</ul>
</div>
<!-- INDEX -->
<p>
This chapter describes SWIG's support of Go. For more information on
the Go programming language
see <a href="http://golang.org/">golang.org</a>.
</p>
<H2><a name="Go_overview"></a>20.1 Overview</H2>
<p>
Go is a compiled language, not a scripting language. However, it does
not support direct calling of functions written in C/C++. The cgo
program may be used to generate wrappers to call C code from Go, but
there is no convenient way to call C++ code. SWIG fills this gap.
</p>
<p>
There are (at least) two different Go compilers. One is the gc
compiler, normally invoked under the names 6g, 8g, or 5g. The other
is the gccgo compiler, which is a frontend to the gcc compiler suite.
The interface to C/C++ code is completely different for the two Go
compilers. SWIG supports both, selected by a command line option.
</p>
<p>
Because Go is a type-safe compiled language, SWIG's runtime type
checking and runtime library are not used with Go. This should be
borne in mind when reading the rest of the SWIG documentation.
</p>
<H2><a name="Go_running_swig"></a>20.2 Running SWIG with Go</H2>
<p>
To generate Go code, use the <tt>-go</tt> option with SWIG. By
default SWIG will generate code for the gc compilers. To generate
code for gccgo, you should also use the <tt>-gccgo</tt> option.
</p>
<H3><a name="Go_commandline"></a>20.2.1 Additional Commandline Options</H3>
<p>
These are the command line options for SWIG's GO module. They can
also be seen by using:
</p>
<div class="code"><pre>
swig -go -help
</pre></div>
<table summary="Go specific options">
<tr>
<th>Go specific options</th>
</tr>
<tr>
<td>-gccgo</td>
<td>Generate code for gccgo. The default is to generate code for
6g/8g/6g.</td>
</tr>
<tr>
<td>-package &lt;name&gt;</td>
<td>Set the name of the Go package to &lt;name&gt;. The default
package name is the SWIG module name.</td>
</tr>
<tr>
<td>-go-prefix &lt;prefix&gt;</td>
<td>When generating code for gccgo, set the prefix to use. This
corresponds to the <tt>-fgo-prefix</tt> option to gccgo.</td>
</tr>
<tr>
<td>-long-type-size &lt;s&gt;</td>
<td>Set the size for the C/C++ type <tt>long</tt>. This controls
whether <tt>long</tt> is converted to the Go type <tt>int32</tt>
or <tt>int64</tt>. The &lt;s&gt; argument should be 32 or 64.</td>
</tr>
</table>
<H3><a name="Go_outputs"></a>20.2.2 Go Output Files</H3>
<p> When generating Go code, SWIG will generate the following
files:</p>
<ul>
<li>
MODULE.go will contain the Go functions that your Go code will call.
These functions will be wrappers for the C++ functions defined by your
module. This file should, of course, be compiled with the Go
compiler.
<li>
MODULE_wrap.c or MODULE_wrap.cxx will contain C/C++ functions will be
invoked by the Go wrapper code. This file should be compiled with the
usual C or C++ compiler and linked into a shared library.
<li>
MODULE_wrap.h will be generated if you use the directors feature. It
provides a definition of the generated C++ director classes. It is
generally not necessary to use this file, but in some special cases it
may be helpful to include it in your code, compiled with the usual C
or C++ compiler.
<li>
If using the gc compiler, MODULE_gc.c will contain C code which should
be compiled with the C compiler distributed as part of the gc compiler: 6c, 8c,
or 5c. It should then be combined with the compiled MODULE.go using
gopack. This file will not be generated when using gccgo.
</ul>
<p>
A typical command sequence would look like this:
</p>
<div class="code"><pre>
% swig -go example.i
% gcc -c -fpic example.c
% gcc -c -fpic example_wrap.c
% gcc -shared example.o example_wrap.o -o example.so
% 6g example.go
% 6c example_gc.c
% gopack grc example.a example.6 example_gc.6
% 6g main.go # your code, not generated by SWIG
% 6l main.6
</pre></div>
<H2><a name="Go_basic_tour"></a>20.3 A tour of basic C/C++ wrapping</H2>
<p>
By default, SWIG attempts to build a natural Go interface to your
C/C++ code. However, the languages are somewhat different, so some
modifications have to occur. This section briefly covers the
essential aspects of this wrapping.
</p>
<H3><a name="Go_package"></a>20.3.1 Go Package Name</H3>
<p>
All Go source code lives in a package. The name of this package will
default to the name of the module from SWIG's <tt>%module</tt>
directive. You may override this by using SWIG's <tt>-package</tt>
command line option.
</p>
<H3><a name="Go_names"></a>20.3.2 Go Names</H3>
<p>
In Go, a function is only visible outside the current package if the
first letter of the name is uppercase. This is quite different from
C/C++. Because of this, C/C++ names are modified when generating the
Go interface: the first letter is forced to be uppercase if it is not
already. This affects the names of functions, methods, variables,
constants, enums, and classes.
</p>
<p>
C/C++ variables are wrapped with setter and getter functions in Go.
First the first letter of the variable name will be forced to
uppercase, and then <tt>Get</tt> or <tt>Set</tt> will be prepended.
For example, if the C/C++ variable is called <tt>var</tt>, then SWIG
will define the functions <tt>GetVar</tt> and <tt>SetVar</tt>. If a
variable is declared as <tt>const</tt>, or if
SWIG's <a href="SWIG.html#SWIG_readonly_variables">
<tt>%immutable</tt> directive</a> is used for the variable, then only
the getter will be defined.
</p>
<p>
C++ classes will be discussed further below. Here we'll note that the
first letter of the class name will be forced to uppercase to give the
name of a type in Go. A constructor will be named <tt>New</tt>
followed by that name, and the destructor will be
named <tt>Delete</tt> followed by that name.
</p>
<H3><a name="Go_constants"></a>20.3.3 Go Constants</H3>
<p>
C/C++ constants created via <tt>#define</tt> or the <tt>%constant</tt>
directive become Go constants, declared with a <tt>const</tt>
declaration.
<H3><a name="Go_enumerations"></a>20.3.4 Go Enumerations</H3>
<p>
C/C++ enumeration types will cause SWIG to define an integer type with
the name of the enumeration (with first letter forced to uppercase as
usual). The values of the enumeration will become variables in Go;
code should avoid modifying those variables.
</p>
<H3><a name="Go_classes"></a>20.3.5 Go Classes</H3>
<p>
Go has interfaces, methods and inheritance, but it does not have
classes in the same sense as C++. This sections describes how SWIG
represents C++ classes represented in Go.
</p>
<p>
For a C++ class <tt>ClassName</tt>, SWIG will define two types in Go:
an underlying type, which will just hold a pointer to the C++ type,
and an interface type. The interface type will be
named <tt>ClassName</tt>. SWIG will define a
function <tt>NewClassName</tt> which will take any constructor
arguments and return a value of the interface
type <tt>ClassName</tt>. SWIG will also define a
destructor <tt>DeleteClassName</tt>.
</p>
<p>
SWIG will represent any methods of the C++ class as methods on the
underlying type, and also as methods of the interface type. Thus C++
methods may be invoked directly using the
usual <tt>val.MethodName</tt> syntax. Public members of the C++ class
will be given getter and setter functions defined as methods of the
class.
</p>
<p>
SWIG will represent static methods of C++ classes as ordinary Go
functions. SWIG will use names like <tt>ClassName_MethodName</tt>.
SWIG will give static members getter and setter functions with names
like <tt>GetClassName_VarName</tt>.
</p>
<p>
Given a value of the interface type, Go code can retrieve the pointer
to the C++ type by calling the <tt>Swigcptr</tt> method. This will
return a value of type <tt>SwigcptrClassName</tt>, which is just a
name for <tt>uintptr</tt>. A Go type conversion can be used to
convert this value to a different C++ type, but note that this
conversion will not be type checked and is essentially equivalent
to <tt>reinterpret_cast</tt>. This should only be used for very
special cases, such as where C++ would use a <tt>dynamic_cast</tt>.
</p>
<H4><a name="Go_class_inheritance"></a>20.3.5.1 Go Class Inheritance</H4>
<p>
C++ class inheritance is automatically represented in Go due to its
use of interfaces. The interface for a child class will be a superset
of the interface of its parent class. Thus a value of the child class
type in Go may be passed to a function which expects the parent class.
Doing the reverse will require an explicit type assertion, which will
be checked dynamically.
</p>
<H3><a name="Go_templates"></a>20.3.6 Go Templates</H3>
<p>
In order to use C++ templates in Go, you must tell SWIG to create
wrappers for a particular template instantation. To do this, use
the <tt>%template</tt> directive.
<H3><a name="Go_director_classes"></a>20.3.7 Go Director Classes</H3>
<p>
SWIG's director feature permits a Go type to act as the subclass of a
C++ class with virtual methods. This is complicated by the fact that
C++ and Go define inheritance differently. In Go, structs can inherit
methods via anonymous field embedding. However, when a method is
called for an embedded struct, if that method calls any other methods,
they are called for the embedded struct, not for the original type.
Therefore, SWIG must use Go interfaces to represent C++ inheritance.
</p>
<p>
In order to use the director feature in Go, you must define a type in
your Go code. You must then add methods for the type. Define a
method in Go for each C++ virtual function that you want to override.
You must then create a value of your new type, and pass a pointer to
it to the function <tt>NewDirectorClassName</tt>,
where <tt>ClassName</tt> is the name of the C++ class. That will
return a value of type <tt>ClassName</tt>.
</p>
<p>
For example:
</p>
<div class="code">
<pre>
type GoClass struct { }
func (p *GoClass) VirtualFunction() { }
func MakeClass() ClassName {
return NewDirectorClassName(&amp;GoClass{})
}
</pre>
</div>
<p>
Any call in C++ code to the virtual function will wind up calling the
method defined in Go. The Go code may of course call other methods on
itself, and those methods may be defined either in Go or in C++.
</p>
<H3><a name="Go_primitive_type_mappings"></a>20.3.8 Default Go primitive type mappings</H3>
<p>
The following table lists the default type mapping from C/C++ to Go.
This table will tell you which Go type to expect for a function which
uses a given C/C++ type.
</p>
<table BORDER summary="Go primitive type mappings">
<tr>
<td><b>C/C++ type</b></td>
<td><b>Go type</b></td>
</tr>
<tr>
<td>bool</td>
<td>bool</td>
</tr>
<tr>
<td>char</td>
<td>byte</td>
</tr>
<tr>
<td>signed char</td>
<td>int8</td>
</tr>
<tr>
<td>unsigned char</td>
<td>byte</td>
</tr>
<tr>
<td>short</td>
<td>int16</td>
</tr>
<tr>
<td>unsigned short</td>
<td>uint16</td>
</tr>
<tr>
<td>int</td>
<td>int</td>
</tr>
<tr>
<td>unsigned int</td>
<td>uint</td>
</tr>
<tr>
<td>long</td>
<td>int32 or int64, depending on <tt>-long-type-size</tt></td>
</tr>
<tr>
<td>unsigned long</td>
<td>uint32 or uint64, depending on <tt>-long-type-size</tt></td>
</tr>
<tr>
<td>long long</td>
<td>int64</td>
</tr>
<tr>
<td>unsigned long long</td>
<td>uint64</td>
</tr>
<tr>
<td>float</td>
<td>float32</td>
</tr>
<tr>
<td>double</td>
<td>float64</td>
</tr>
<tr>
<td>char *<br>char []</td>
<td>string</td>
</tr>
</table>
<p>
Note that SWIG wraps the C <tt>char</tt> type as a character. Pointers
and arrays of this type are wrapped as strings. The <tt>signed
char</tt> type can be used if you want to treat <tt>char</tt> as a
signed number rather than a character. Also note that all const
references to primitive types are treated as if they are passed by
value.
</p>
<p>
These type mappings are defined by the "gotype" typemap. You may change
that typemap, or add new values, to control how C/C++ types are mapped
into Go types.
</p>
</body>
</html>

893
Doc/Manual/Guile.html Normal file
View file

@ -0,0 +1,893 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Hand-written HTML -->
<html>
<head>
<title>SWIG and Guile</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Guile"></a>21 SWIG and Guile</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Guile_nn2">Meaning of "Module"</a>
<li><a href="#Guile_nn3">Using the SCM or GH Guile API</a>
<li><a href="#Guile_nn4">Linkage</a>
<ul>
<li><a href="#Guile_nn5">Simple Linkage</a>
<li><a href="#Guile_nn6">Passive Linkage</a>
<li><a href="#Guile_nn7">Native Guile Module Linkage</a>
<li><a href="#Guile_nn8">Old Auto-Loading Guile Module Linkage</a>
<li><a href="#Guile_nn9">Hobbit4D Linkage</a>
</ul>
<li><a href="#Guile_nn10">Underscore Folding</a>
<li><a href="#Guile_nn11">Typemaps</a>
<li><a href="#Guile_nn12">Representation of pointers as smobs</a>
<ul>
<li><a href="#Guile_nn13">GH Smobs</a>
<li><a href="#Guile_nn14">SCM Smobs</a>
<li><a href="#Guile_nn15">Garbage Collection</a>
</ul>
<li><a href="#Guile_nn16">Exception Handling</a>
<li><a href="#Guile_nn17">Procedure documentation</a>
<li><a href="#Guile_nn18">Procedures with setters</a>
<li><a href="#Guile_nn19">GOOPS Proxy Classes</a>
<ul>
<li><a href="#Guile_nn20">Naming Issues</a>
<li><a href="#Guile_nn21">Linking</a>
</ul>
</ul>
</div>
<!-- INDEX -->
<p>
This section details guile-specific support in SWIG.
<H2><a name="Guile_nn2"></a>21.1 Meaning of "Module"</H2>
<p>
There are three different concepts of "module" involved, defined
separately for SWIG, Guile, and Libtool. To avoid horrible confusion,
we explicitly prefix the context, e.g., "guile-module".
<H2><a name="Guile_nn3"></a>21.2 Using the SCM or GH Guile API</H2>
<p>The guile module can currently export wrapper files that use the guile GH interface or the
SCM interface. This is controlled by an argument passed to swig. The "-gh" argument causes swig
to output GH code, and the "-scm" argument causes swig to output SCM code. Right now the "-scm" argument
is the default. The "-scm" wrapper generation assumes a guile version &gt;= 1.6 and has several advantages over
the "-gh" wrapper generation including garbage collection and GOOPS support.
The "-gh" wrapper generation can be used for older versions of guile.
The guile GH wrapper code generation is depreciated and the
SCM interface is the default. The SCM and GH interface differ greatly in how they store
pointers and have completely different run-time code. See below for more info.
<p>The GH interface to guile is deprecated. Read more about why in the
<a href="http://www.gnu.org/software/guile/docs/docs-1.6/guile-ref/GH.html#GH">Guile manual</a>.
The idea of the GH interface was to provide a high level API that other languages and projects
could adopt. This was a good idea, but didn't pan out well for general development. But for the
specific, minimal uses that the SWIG typemaps put the GH interface to use is ideal for
using a high level API. So even though the GH interface is depreciated, SWIG will continue to use
the GH interface and provide mappings from the GH interface to whatever API we need.
We can maintain this mapping where guile failed because SWIG uses a small subset of all the GH functions
which map easily. All the guile typemaps like typemaps.i and std_vector.i
will continue to use the GH functions to do things like create lists of values, convert strings to
integers, etc. Then every language module will define a mapping between the GH interface and
whatever custom API the language uses. This is currently implemented by the guile module to use
the SCM guile API rather than the GH guile API.
For example, here are some of the current mapping file for the SCM API</p>
<div class="code"><pre>
#define gh_append2(a, b) scm_append(scm_listify(a, b, SCM_UNDEFINED))
#define gh_apply(a, b) scm_apply(a, b, SCM_EOL)
#define gh_bool2scm SCM_BOOL
#define gh_boolean_p SCM_BOOLP
#define gh_car SCM_CAR
#define gh_cdr SCM_CDR
#define gh_cons scm_cons
#define gh_double2scm scm_make_real
...
</pre></div>
<p>This file is parsed by SWIG at wrapper generation time, so every reference to a gh_ function is replaced
by a scm_ function in the wrapper file. Thus the gh_ function calls will never be seen in the wrapper;
the wrapper will look exactly like it was generated
for the specific API. Currently only the guile language module has created a mapping policy from gh_ to scm_,
but there is no reason other languages (like mzscheme or chicken) couldn't also use this.
If that happens, there is A LOT less code duplication in the standard typemaps.</p>
<H2><a name="Guile_nn4"></a>21.3 Linkage</H2>
<p>
Guile support is complicated by a lack of user community cohesiveness,
which manifests in multiple shared-library usage conventions. A set of
policies implementing a usage convention is called a <b>linkage</b>.
<H3><a name="Guile_nn5"></a>21.3.1 Simple Linkage</H3>
<p>
The default linkage is the simplest; nothing special is done. In this
case the function <code>SWIG_init()</code> is exported. Simple linkage
can be used in several ways:
</p>
<ul>
<li><b>Embedded Guile, no modules.</b> You want to embed a Guile
interpreter into your program; all bindings made by SWIG shall show up
in the root module. Then call <code>SWIG_init()</code> in the
<code>inner_main()</code> function. See the "simple" and "matrix" examples under
<code>Examples/guile</code>.
<li><p><b>Dynamic module mix-in.</b> You want to create a Guile module
using <code>define-module</code>, containing both Scheme code and
bindings made by SWIG; you want to load the SWIG modules as shared
libraries into Guile.</p>
<div class="targetlang">
<pre>
(define-module (my module))
(define my-so (dynamic-link "./example.so"))
(dynamic-call "SWIG_init" my-so) ; make SWIG bindings
;; Scheme definitions can go here
</pre>
</div>
<p>
Newer Guile versions provide a shorthand for <code>dynamic-link</code>
and <code>dynamic-call</code>:
</p>
<div class="targetlang">
<pre>
(load-extension "./example.so" "SWIG_init")
</pre>
</div>
<p>
You need to explicitly export those bindings made by SWIG that you
want to import into other modules:
</p>
<div class="targetlang">
<pre>
(export foo bar)
</pre>
</div>
<p>
In this example, the procedures <code>foo</code> and <code>bar</code>
would be exported. Alternatively, you can export all bindings with the
following module-system hack:
</p>
<div class="targetlang">
<pre>
(module-map (lambda (sym var)
(module-export! (current-module) (list sym)))
(current-module))
</pre>
</div>
<p>SWIG can also generate this Scheme stub (from
<code>define-module</code> up to <code>export</code>)
semi-automagically if you pass it the command-line argument
<code>-scmstub</code>. The code will be exported in a file called
<code><i>module</i>.scm</code> in the directory specified by <code>-outdir</code>
or the current directory if <code>-outdir</code> is not specified.
Since SWIG doesn't know how
to load your extension module (with <code>dynamic-link</code> or
<code>load-extension</code>), you need to supply this
information by including a directive like this in the interface file:
</p>
<div class="code">
<pre>
%scheme %{ (load-extension "./example.so" "SWIG_init") %}
</pre>
</div>
<p>
(The <code>%scheme</code> directive allows to insert arbitrary Scheme
code into the generated file <code><var>module.scm</var></code>; it is
placed between the <code>define-module</code> form and the
<code>export</code> form.)
</p>
</ul>
<p>If you want to include several SWIG modules, you would need to rename
<code>SWIG_init</code> via a preprocessor define to avoid symbol
clashes. For this case, however, passive linkage is available.
<H3><a name="Guile_nn6"></a>21.3.2 Passive Linkage</H3>
<p>Passive linkage is just like simple linkage, but it generates an
initialization function whose name is derived from the module and
package name (see below).
<p>You should use passive linkage rather than simple linkage when you
are using multiple modules.
<H3><a name="Guile_nn7"></a>21.3.3 Native Guile Module Linkage</H3>
<p>SWIG can also generate wrapper code that does all the Guile module
declarations on its own if you pass it the <code>-Linkage
module</code> command-line option. This requires Guile 1.5.0 or later.
<p>The module name is set with the <code>-package</code> and
<code>-module</code> command-line options. Suppose you want to define
a module with name <code>(my lib foo)</code>; then you would have to
pass the options <code>-package <var>my</var>/<var>lib</var> -module
<var>foo</var></code>. Note that the last part of the name can also be set
via the SWIG directive <code>%module</code>.
<p>You can use this linkage in several ways:
<ul>
<li><b>Embedded Guile with SWIG modules.</b> You want to embed a Guile
interpreter into your program; the SWIG bindings shall be put into
different modules. Simply call the function
<code>scm_init_<var>my</var>_<var>modules</var>_<var>foo</var>_module</code>
in the <code>inner_main()</code> function.
<li><b>Dynamic Guile modules.</b> You want to load the SWIG modules as
shared libraries into Guile; all bindings are automatically put in
newly created Guile modules.
<div class="targetlang">
<pre>
(define my-so (dynamic-link "./foo.so"))
;; create new module and put bindings there:
(dynamic-call "scm_init_my_modules_foo_module" my-so)
</pre>
</div>
Newer Guile versions have a shorthand procedure for this:
<div class="targetlang">
<pre>
(load-extension "./foo.so" "scm_init_my_modules_foo_module")
</pre>
</div>
</ul>
<H3><a name="Guile_nn8"></a>21.3.4 Old Auto-Loading Guile Module Linkage</H3>
<p>Guile used to support an autoloading facility for object-code
modules. This support has been marked deprecated in version 1.4.1 and
is going to disappear sooner or later. SWIG still supports building
auto-loading modules if you pass it the <code>-Linkage ltdlmod</code>
command-line option.
<p>Auto-loading worked like this: Suppose a module with name <code>(my
lib foo)</code> is required and not loaded yet. Guile will then search
all directories in its search path
for a Scheme file <code>my/modules/foo.scm</code> or a shared library
<code><var>my</var>/<var>modules</var>/lib<var>foo</var>.so</code> (or
<code><var>my</var>/<var>modules</var>/lib<var>foo</var>.la</code>;
see the GNU libtool documentation). If a
shared library is found that contains the symbol
<code>scm_init_<var>my</var>_<var>modules</var>_<var>foo</var>_module</code>,
the library is loaded, and the function at that symbol is called with
no arguments in order to initialize the module.
<p>When invoked with the <code>-Linkage ltdlmod</code> command-line
option, SWIG generates an exported module initialization function with
an appropriate name.
<H3><a name="Guile_nn9"></a>21.3.5 Hobbit4D Linkage</H3>
<p>
The only other linkage supported at this time creates shared object
libraries suitable for use by hobbit's <code>(hobbit4d link)</code>
guile module. This is called the "hobbit" linkage, and requires also
using the "-package" command line option to set the part of the module
name before the last symbol. For example, both command lines:
</p>
<div class="shell">
<pre>
swig -guile -package my/lib foo.i
swig -guile -package my/lib -module foo foo.i
</pre>
</div>
<p>
would create module <code>(my lib foo)</code> (assuming in the first
case foo.i declares the module to be "foo"). The installed files are
my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very
experimental; the (hobbit4d link) conventions are not well understood.
</p>
<H2><a name="Guile_nn10"></a>21.4 Underscore Folding</H2>
<p>
Underscores are converted to dashes in identifiers. Guile support may
grow an option to inhibit this folding in the future, but no one has
complained so far.
<p>You can use the SWIG directives <code>%name</code> and
<code>%rename</code> to specify the Guile name of the wrapped
functions and variables (see CHANGES).
<H2><a name="Guile_nn11"></a>21.5 Typemaps</H2>
<p>
The Guile module handles all types via typemaps. This
information is read from <code>Lib/guile/typemaps.i</code>.
Some non-standard typemap substitutions are supported:
<ul>
<li><code>$descriptor</code> expands to a type descriptor for use with
the <code>SWIG_NewPointerObj()</code> and
<code>SWIG_ConvertPtr</code> functions.
<li>For pointer types, <code>$*descriptor</code> expands to a
descriptor for the direct base type (i.e., one pointer is stripped),
whereas <code>$basedescriptor</code> expands to a
descriptor for the base type (i.e., all pointers are stripped).
</ul>
<p>A function returning <code>void</code> (more precisely, a function
whose <code>out</code> typemap returns <code>SCM_UNSPECIFIED</code>) is
treated as returning no values. In <code>argout</code> typemaps, one
can use the macro <code>GUILE_APPEND_RESULT</code> in order to append
a value to the list of function return values.
<p>Multiple values can be passed up to Scheme in one of three ways:
<ul>
<li><p><em>Multiple values as lists.</em>
By default, if more than one value is to
be returned, a list of the values is created and returned; to switch
back to this behavior, use</p>
<div class="code">
<pre>
%values_as_list;</pre>
</div>
<li><p><em>Multiple values as vectors.</em>
By issuing
</p>
<div class="code">
<pre>
%values_as_vector;</pre>
</div>
<p>
vectors instead of lists will be used.
<li><p><em>Multiple values for multiple-value continuations.</em>
<strong>This is the most elegant way.</strong> By issuing
</p>
<div class="code">
<pre>
%multiple_values;</pre>
</div>
<p>
multiple values are passed to the multiple-value
continuation, as created by <code>call-with-values</code> or the
convenience macro <code>receive</code>. The latter is available if you
issue <code>(use-modules (srfi srfi-8))</code>. Assuming that your
<code>divide</code> function
wants to return two values, a quotient and a remainder, you can write:
</p>
<div class="targetlang">
<pre>
(receive (quotient remainder)
(divide 35 17)
<var>body</var>...)
</pre>
</div>
<p>
In <code><var>body</var></code>, the first result of
<code>divide</code> will be bound to the variable
<code>quotient</code>, and the second result to <code>remainder</code>.
</p>
</ul>
<p>
See also the "multivalue" example.
</p>
<p>Constants are exported as a function that returns the value. The
%feature("constasvar") can be applied to any constant, immutable variable, or enum.
Instead of exporting the constant as a function that must be called, the
constant will appear as a scheme variable. See
<a href="Customization.html#Customization_features">Features and the %feature directive</a>
for info on how to apply the %feature.</p>
<H2><a name="Guile_nn12"></a>21.6 Representation of pointers as smobs</H2>
<p>
For pointer types, SWIG uses Guile smobs. SWIG smobs print
like this: <code>#&lt;swig struct xyzzy * 0x1234affe&gt;</code> Two of
them are <code>equal?</code> if and only if they have the same type
and value.
<p>
To construct a Scheme object from a C pointer, the wrapper code calls
the function <code>SWIG_NewPointerObj()</code>, passing a pointer to a
struct representing the pointer type. The type index to store in the
upper half of the CAR is read from this struct.
To get the pointer represented by a smob, the wrapper code calls the
function <code>SWIG_ConvertPtr()</code>, passing a pointer to a struct
representing the expected pointer type. See also
<a href="Typemaps.html#runtime_type_checker">The run-time type checker</a>.
If the Scheme object passed was not a SWIG smob representing a compatible
pointer, a <code>wrong-type-arg</code> exception is raised.
<H3><a name="Guile_nn13"></a>21.6.1 GH Smobs</H3>
<p>
In earlier versions of SWIG, C pointers were represented as Scheme
strings containing a hexadecimal rendering of the pointer value and a
mangled type name. As Guile allows registering user types, so-called
"smobs" (small objects), a much cleaner representation has been
implemented now. The details will be discussed in the following.
</p>
<p> A smob is a cons cell where the lower half of the CAR contains the smob type
tag, while the upper half of the CAR and the whole CDR are available. Every
module creates its own smob type in the clientdata field of the module. So the
lower 16 bits of the car of the smob store the tag and the upper 16 bits store
the index this type is in the array. We can then, given a smob, find its
swig_type_info struct by using the tag (lower 16 bits of car) to find which
module this type is in (since each tag is unique for the module). Then we use
the upper 16 bits to index into the array of types attached to this module.
Looking up the module from the tag is worst case O(# of modules) but average
case O(1). This is because the modules are stored in a circularly linked list,
and when we start searching the modules for the tag, we start looking with the
module that the function doing the lookup is in. SWIG_Guile_ConvertPtr() takes
as its first argument the swig_module_info * of the calling function, which is
where we start comparing tags. Most types will be looked up in the same module
that created them, so the first module we check will most likely be correct.
Once we have a swig_type_info structure, we loop through the linked list of
casts, using pointer comparisons.</p>
<H3><a name="Guile_nn14"></a>21.6.2 SCM Smobs</H3>
<p>The SCM interface (using the "-scm" argument to swig) uses swigrun.swg.
The whole type system, when it is first initialized, creates two smobs named "swig" and "collected_swig".
The swig smob is used for non-garbage collected smobs, while the collected_swig smob is used as described
below. Each smob has the same format, which is a double cell created by SCM_NEWSMOB2()
The first word of data is the pointer to the object and the second word of data is the swig_type_info *
structure describing this type. This is a lot easier than the GH interface above because we can store
a pointer to the type info structure right in the type. With the GH interface, there was not enough
room in the smob to store two whole words of data so we needed to store part of the "swig_type_info address"
in the smob tag. If a generated GOOPS module has been loaded, smobs will be wrapped by the corresponding
GOOPS class.</p>
<H3><a name="Guile_nn15"></a>21.6.3 Garbage Collection</H3>
<p>Garbage collection is a feature of the new SCM interface, and it is automatically included
if you pass the "-scm" flag to swig. Thus the swig garbage collection support requires guile &gt;1.6.
Garbage collection works like this. Every swig_type_info structure stores in its clientdata field a pointer
to the destructor for this type. The destructor is the generated wrapper around the delete function.
So swig still exports a wrapper for the destructor, it just does not call scm_c_define_gsubr() for
the wrapped delete function. So the only way to delete an object is from the garbage collector, since the
delete function is not available to scripts. How swig determines if a type should be garbage collected
is exactly like described in <a href="Customization.html#Customization_ownership">
Object ownership and %newobject</a> in the SWIG manual. All typemaps use an $owner var, and
the guile module replaces $owner with 0 or 1 depending on feature:new.</p>
<H2><a name="Guile_nn16"></a>21.7 Exception Handling</H2>
<p>
SWIG code calls <code>scm_error</code> on exception, using the following
mapping:
<div class="code">
<pre>
MAP(SWIG_MemoryError, "swig-memory-error");
MAP(SWIG_IOError, "swig-io-error");
MAP(SWIG_RuntimeError, "swig-runtime-error");
MAP(SWIG_IndexError, "swig-index-error");
MAP(SWIG_TypeError, "swig-type-error");
MAP(SWIG_DivisionByZero, "swig-division-by-zero");
MAP(SWIG_OverflowError, "swig-overflow-error");
MAP(SWIG_SyntaxError, "swig-syntax-error");
MAP(SWIG_ValueError, "swig-value-error");
MAP(SWIG_SystemError, "swig-system-error");
</pre>
</div>
<p>
The default when not specified here is to use "swig-error".
See Lib/exception.i for details.
<H2><a name="Guile_nn17"></a>21.8 Procedure documentation</H2>
<p>If invoked with the command-line option <code>-procdoc
<var>file</var></code>, SWIG creates documentation strings for the
generated wrapper functions, describing the procedure signature and
return value, and writes them to <var>file</var>. You need Guile 1.4
or later to make use of the documentation files.
<p>SWIG can generate documentation strings in three formats, which are
selected via the command-line option <code>-procdocformat
<var>format</var></code>:
<ul>
<li><code>guile-1.4</code> (default): Generates a format suitable for Guile 1.4.
<li><code>plain</code>: Generates a format suitable for Guile 1.4.1 and
later.
<li><code>texinfo</code>: Generates texinfo source, which must be run
through texinfo in order to get a format suitable for Guile 1.4.1 and
later.
</ul>
<p>You need to register the generated documentation file with Guile
like this:
<div class="targetlang">
<pre>
(use-modules (ice-9 documentation))
(set! documentation-files
(cons "<var>file</var>" documentation-files))
</pre>
</div>
<p>Documentation strings can be configured using the Guile-specific
typemap argument <code>doc</code>. See <code>Lib/guile/typemaps.i</code> for
details.
<H2><a name="Guile_nn18"></a>21.9 Procedures with setters</H2>
<p>For global variables, SWIG creates a single wrapper procedure
<code>(<var>variable</var> :optional value)</code>, which is used for
both getting and setting the value. For struct members, SWIG creates
two wrapper procedures <code>(<var>struct</var>-<var>member</var>-get
pointer)</code> and <code>(<var>struct-member</var>-set pointer value)</code>.
<p>If invoked with the command-line option <code>-emit-setters</code>
(<em>recommended</em>),
SWIG will additionally create procedures with setters. For global
variables, the procedure-with-setter <code><var>variable</var></code>
is created, so you can use <code>(<var>variable</var>)</code> to get
the value and <code>(set! (<var>variable</var>)
<var>value</var>)</code> to set it. For struct members, the
procedure-with-setter <code><var>struct</var>-<var>member</var></code>
is created, so you can use <code>(<var>struct</var>-<var>member</var>
<var>pointer</var>)</code> to get the value and <code>(set!
(<var>struct</var>-<var>member</var> <var>pointer</var>)
<var>value</var>)</code> to set it.
<p>If invoked with the command-line option <code>-only-setters</code>,
SWIG will <em>only</em> create procedures with setters, i.e., for
struct members, the procedures <code>(<var>struct</var>-<var>member</var>-get
pointer)</code> and <code>(<var>struct-member</var>-set pointer
value)</code> are <em>not</em> generated.
<H2><a name="Guile_nn19"></a>21.10 GOOPS Proxy Classes</H2>
<p>SWIG can also generate classes and generic functions for use with
Guile's Object-Oriented Programming System (GOOPS). GOOPS is a
sophisticated object system in the spirit of the Common Lisp Object
System (CLOS).
<p>GOOPS support is
only available with the new SCM interface (enabled with the
<code>-scm</code> command-line option of SWIG). To enable GOOPS
support, pass the <code>-proxy</code> argument to
swig. This will export the GOOPS wrapper definitions into the
<code><i>module</i>.scm</code> file in the directory specified by -outdir or the
current directory. GOOPS support requires either passive or module linkage.</p>
<p>The generated file will contain definitions of GOOPS classes mimicking the C++ class hierarchy.
<p>Enabling GOOPS support implies <code>-emit-setters</code>.
<p>If <code>-emit-slot-accessors</code> is also passed as an argument,
then the generated file will contain accessor methods for all the
slots in the classes and for global variables. The input class</p>
<div class="code"><pre>
class Foo {
public:
Foo(int i) : a(i) {}
int a;
int getMultBy(int i) { return a * i; }
Foo getFooMultBy(int i) { return Foo(a * i); }
};
Foo getFooPlus(int i) { return Foo(a + i); }
</pre></div>
<p>
will produce (if <code>-emit-slot-accessors</code> is not passed as a parameter)
</p>
<div class="targetlang"><pre>
(define-class &lt;Foo&gt; (&lt;swig&gt;)
(a #:allocation #:swig-virtual
#:slot-ref primitive:Foo-a-get
#:slot-set! primitive:Foo-a-set)
#:metaclass &lt;swig-metaclass&gt;
#:new-function primitive:new-Foo
)
(define-method (getMultBy (swig_smob &lt;Foo&gt;) i)
(primitive:Foo-getMultBy (slot-ref swig_smob 'smob) i))
(define-method (getFooMultBy (swig_smob &lt;Foo&gt;) i)
(make &lt;Foo&gt; #:init-smob (primitive:Foo-getFooMultBy (slot-ref swig_smob 'smob) i)))
(define-method (getFooPlus i)
(make &lt;Foo&gt; #:init-smob (primitive:getFooPlus i)))
(export &lt;Foo&gt; getMultBy getFooMultBy getFooPlus )
</pre></div>
<p>
and will produce (if <code>-emit-slot-accessors</code> is passed as a parameter)
</p>
<div class="targetlang"><pre>
(define-class &lt;Foo&gt; (&lt;swig&gt;)
(a #:allocation #:swig-virtual
#:slot-ref primitive:Foo-a-get
#:slot-set! primitive:Foo-a-set
<b>#:accessor a</b>)
#:metaclass &lt;swig-metaclass&gt;
#:new-function primitive:new-Foo
)
(define-method (getMultBy (swig_smob &lt;Foo&gt;) i)
(primitive:Foo-getMultBy (slot-ref swig_smob 'smob) i))
(define-method (getFooMultBy (swig_smob &lt;Foo&gt;) i)
(make &lt;Foo&gt; #:init-smob (primitive:Foo-getFooMultBy (slot-ref swig_smob 'smob) i)))
(define-method (getFooPlus i)
(make &lt;Foo&gt; #:init-smob (primitive:getFooPlus i)))
(export &lt;Foo&gt; <b>a</b> getMultBy getFooMultBy getFooPlus )
</pre></div>
<p>
which can then be used by this code
</p>
<div class="targetlang"><pre>
;; not using getters and setters
(define foo (make &lt;Foo&gt; #:args '(45)))
(slot-ref foo 'a)
(slot-set! foo 'a 3)
(getMultBy foo 4)
(define foo2 (getFooMultBy foo 7))
(slot-ref foo 'a)
(slot-ref (getFooPlus foo 4) 'a)
;; using getters and setters
(define foo (make &lt;Foo&gt; #:args '(45)))
(a foo)
(set! (a foo) 5)
(getMultBy foo 4)
(a (getFooMultBy foo 7))
</pre></div>
<p>Notice that constructor arguments are passed as a list after the <code>#:args</code> keyword. Hopefully in
the future the following will be valid <code>(make &lt;Foo&gt; #:a 5 #:b 4)</code></p>
<p>Also note that the order the declarations occur in the .i file make a difference. For example,
</p>
<div class="code"><pre>
%module test
%{ #include "foo.h" %}
%inline %{
int someFunc(Foo &amp;a) {
...
}
%}
%include "foo.h"
</pre></div>
<p>
This is a valid SWIG file it will work as you think it will for primitive support, but the generated
GOOPS file will be broken. Since the <code>someFunc</code> definition is parsed by SWIG before all the
declarations in foo.h, the generated GOOPS file will contain the definition of <code>someFunc()</code>
before the definition of &lt;Foo&gt;. The generated GOOPS file would look like
</p>
<div class="targetlang"><pre>
;;...
(define-method (someFunc (swig_smob &lt;Foo&gt;))
(primitive:someFunc (slot-ref swig_smob 'smob)))
;;...
(define-class &lt;Foo&gt; (&lt;swig&gt;)
;;...
)
;;...
</pre></div>
<p>
Notice that &lt;Foo&gt; is used before it is defined. The fix is to just put the
<code>%import "foo.h"</code> before the <code>%inline</code> block.
</p>
<H3><a name="Guile_nn20"></a>21.10.1 Naming Issues</H3>
<p>As you can see in the example above, there are potential naming conflicts. The default exported
accessor for the <code>Foo::a</code> variable is named <code>a</code>. The name of the wrapper global
function is <code>getFooPlus</code>.
If the <code>-useclassprefix</code> option is passed to swig, the name of all accessors and member
functions will be prepended with the class name. So the accessor will be called <code>Foo-a</code> and
the member functions will be called <code>Foo-getMultBy</code>. Also, if the
<code>-goopsprefix goops:</code> argument is passed to swig, every identifier will be prefixed by
<code>goops:</code></p>
<p>Two guile-modules are created by SWIG. The first module contains the primitive definitions
of all the wrapped functions and variables, and is located either in the _wrap.cxx file (with <code>-Linkage
module</code>) or in the scmstub file (if <code>-Linkage passive -scmstub</code>). The name of this
guile-module is the swig-module name (given on the command line with the -module argument or with the
%module directive) concatenated with the string "-primitive". For
example, if <code>%module Test</code> is set in the swig interface file, the name of the guile-module in
the scmstub or <code>-Linkage module</code> will be <code>Test-primitive</code>. Also, the scmstub
file will be named <code>Test-primitive.scm</code>.
The string "primitive" can be changed by the <code>-primsuffix</code> swig
argument. So the same interface, with the <code>-primsuffix base</code> will produce a module called
<code>Test-base</code>.
The second generated guile-module contains all the GOOPS class definitions and is located in
a file named <i>module</i>.scm in the directory specified with -outdir or the current directory.
The name of this guile-module is the name of the
swig-module (given on the command line or with the <code>%module</code> directive).
In the previous example, the GOOPS definitions will be in a file named Test.scm.</p>
<p>Because of the naming conflicts, you can't in general use both the <code>-primitive</code> and the GOOPS
guile-modules at the same time. To do this, you need to rename the exported symbols from one or both
guile-modules. For example,</p>
<div class="targetlang"><pre>
(use-modules ((Test-primitive) #:renamer (symbol-prefix-proc 'primitive:)))
(use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:)))
</pre></div>
<H3><a name="Guile_nn21"></a>21.10.2 Linking</H3>
<p>The guile-modules generated above all need to be linked together. GOOPS support requires
either passive or module linkage. The exported GOOPS guile-module will be the name of the swig-module
and should be located in a file called <i>Module</i>.scm. This should be installed on the autoload
path for guile, so that <code>(use-modules (<i>Package Module</i>))</code> will load everything needed.
Thus, the top of the GOOPS guile-module will contain code to load everything needed by the interface
(the shared library, the scmstub module, etc.).
The <code>%goops</code> directive inserts arbitrary code into the generated GOOPS guile-module, and
should be used to load the dependent libraries.</p>
<p>This breaks up into three cases</p>
<ul>
<li><b>Passive Linkage without -scmstub</b>: Note that this linkage style has the potential for naming
conflicts, since the primitive exported function and variable names are not wrapped in a guile-module
and might conflict with names from the GOOPS guile-module (see above). Pass the -goopsprefix
argument to solve this problem. If the <code>-exportprimitive</code> option is passed to SWIG the
<code>(export ...)</code> code that would be exported into the scmstub file is exported at the bottom
of the generated GOOPS guile-module.
The <code>%goops</code> directive should contain code to load the .so library.
<div class="code"><pre>
%goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
</pre></div>
<p>
Produces the following code at the top of the generated GOOPS guile-module
(with the <code>-package my/modules -module foo</code> command line arguments)
</p>
<div class="targetlang"><pre>
(define-module (my modules foo))
;; %goops directive goes here
(load-extension "./foo.so" "scm_init_my_modules_foo_module")
(use-modules (oop goops) (Swig common))
</pre></div>
</li>
<li><p><b>Passive Linkage with -scmstub</b>: Here, the name of the scmstub file should be
<code>Module-primitive.scm</code> (with <i>primitive</i> replaced with whatever is given with the <code>-primsuffix</code>
argument. The code to load the <code>.so</code> library should be located in the <code>%scheme</code> directive,
which will then be added to the scmstub file.
SWIG will automatically generate the line <code>(use-modules (<i>Package</i> <i>Module-primitive</i>))</code>
into the GOOPS guile-module. So if <i>Module-primitive.scm</i> is on the autoload path for guile, the
<code>%goops</code> directive can be empty. Otherwise, the <code>%goops</code> directive should contain
whatever code is needed to load the <i>Module-primitive.scm</i> file into guile.</p>
<div class="targetlang"><pre>
%scheme %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
// only include the following definition if (my modules foo) cannot
// be loaded automatically
%goops %{
(primitive-load "/path/to/foo-primitive.scm")
(primitive-load "/path/to/Swig/common.scm")
%}
</pre></div>
<p>
Produces the following code at the top of the generated GOOPS guile-module
</p>
<div class="targetlang"><pre>
(define-module (my modules foo))
;; %goops directive goes here (if any)
(primitive-load "/path/to/foo-primitive.scm")
(primitive-load "/path/to/Swig/common.scm")
(use-modules (oop goops) (Swig common))
(use-modules ((my modules foo-primitive) :renamer (symbol-prefix-proc
'primitive:)))
</pre></div>
</li>
<li><p><b>Module Linkage</b>: This is very similar to passive linkage with a scmstub file.
SWIG will also automatically generate the line <code>(use-modules
(<i>Package</i> <i>Module-primitive</i>))</code> into the GOOPS guile-module. Again the <code>%goops</code>
directive should contain whatever code is needed to get that module loaded into guile.</p>
<div class="code"><pre>
%goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
</pre></div>
<p>
Produces the following code at the top of the generated GOOPS guile-module
</p>
<div class="targetlang"><pre>
(define-module (my modules foo))
;; %goops directive goes here (if any)
(load-extension "./foo.so" "scm_init_my_modules_foo_module")
(use-modules (oop goops) (Swig common))
(use-modules ((my modules foo-primitive) :renamer (symbol-prefix-proc
'primitive:)))
</pre></div>
</li>
</ul>
<p><b>(Swig common)</b>: The generated GOOPS guile-module also imports definitions from the
(Swig common) guile-module.
This module is included with SWIG and should be installed by SWIG into the autoload path for
guile (based on the configure script and whatever arguments are passed). If it is not, then the
<code>%goops</code> directive also needs to contain code to load the <code>common.scm</code> file
into guile. Also note that if you are trying to install the generated wrappers on a computer without
SWIG installed, you will need to include the common.swg file along with the install.</p>
<p><b>Multiple Modules</b>: Type dependencies between modules is supported. For example, if
<code>mod1</code> includes definitions of some classes, and <code>mod2</code> includes some classes
derived from classes in <code>mod1</code>, the generated GOOPS file for <code>mod2</code> will declare
the correct superclasses. The only problem is that since <code>mod2</code> uses symbols from
<code>mod1</code>, the <code>mod2</code> GOOPS file must include a <code>(use-modules (mod2))</code>.
Currently, SWIG does not automatically export this line; it must be included in the <code>%goops</code>
directive of <code>mod2</code>. Maybe in the future SWIG can detect dependencies and export this line.
(how do other language modules handle this problem?)</p>
</body>
</html>

View file

@ -0,0 +1,463 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Introduction</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Introduction"></a>2 Introduction</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Introduction_nn2">What is SWIG?</a>
<li><a href="#Introduction_nn3">Why use SWIG?</a>
<li><a href="#Introduction_nn4">A SWIG example</a>
<ul>
<li><a href="#Introduction_nn5">SWIG interface file</a>
<li><a href="#Introduction_nn6">The swig command</a>
<li><a href="#Introduction_nn7">Building a Perl5 module</a>
<li><a href="#Introduction_nn8">Building a Python module</a>
<li><a href="#Introduction_nn9">Shortcuts</a>
</ul>
<li><a href="#Introduction_nn10">Supported C/C++ language features</a>
<li><a href="#Introduction_nn11">Non-intrusive interface building</a>
<li><a href="#Introduction_build_system">Incorporating SWIG into a build system</a>
<li><a href="#Introduction_nn12">Hands off code generation</a>
<li><a href="#Introduction_nn13">SWIG and freedom</a>
</ul>
</div>
<!-- INDEX -->
<H2><a name="Introduction_nn2"></a>2.1 What is SWIG?</H2>
<p>
SWIG is a software development tool that simplifies the task of
interfacing different languages to C and C++ programs. In a
nutshell, SWIG is a compiler that takes C/C++ declarations and creates
the wrappers needed to access those declarations from other languages including
including Perl, Python, Tcl, Ruby, Guile, and Java. SWIG normally
requires no modifications to existing code and can often be used to
build a usable interface in only a few minutes. Possible applications
of SWIG include:
</p>
<ul>
<li>Building interpreted interfaces to existing C programs.
<li>Rapid prototyping and application development.
<li>Interactive debugging.
<li>Reengineering or refactoring of legacy software into a scripting language components.
<li>Making a graphical user interface (using Tk for example).
<li>Testing of C libraries and programs (using scripts).
<li>Building high performance C modules for scripting languages.
<li>Making C programming more enjoyable (or tolerable depending on your point of view).
<li>Impressing your friends.
<li>Obtaining vast sums of research funding (although obviously not applicable to the author).
</ul>
<p>
SWIG was originally designed to make it extremely easy for scientists
and engineers to build extensible scientific software without having to get a
degree in software engineering. Because of this, the use of
SWIG tends to be somewhat informal and ad-hoc (e.g., SWIG does not
require users to provide formal interface specifications as you would find in
a dedicated IDL compiler). Although
this style of development isn't appropriate for every
project, it is particularly well suited to software development in the
small; especially the research and development work that is commonly found
in scientific and engineering projects. However, nowadays SWIG is known to be used in many
large open source and commercial projects.
<H2><a name="Introduction_nn3"></a>2.2 Why use SWIG?</H2>
<p>
As stated in the previous section, the primary purpose of SWIG is to simplify
the task of integrating C/C++ with other programming languages. However, why would
anyone want to do that? To answer that question, it is useful to list a few strengths
of C/C++ programming:
</p>
<ul>
<li>Excellent support for writing programming libraries.
<li>High performance (number crunching, data processing, graphics, etc.).
<li>Systems programming and systems integration.
<li>Large user community and software base.
</ul>
<p>
Next, let's list a few problems with C/C++ programming
</p>
<ul>
<li>Writing a user interface is rather painful (i.e., consider programming with MFC, X11, GTK, or any number
of other libraries).
<li>Testing is time consuming (the compile/debug cycle).
<li>Not easy to reconfigure or customize without recompilation.
<li>Modularization can be tricky.
<li>Security concerns (buffer overflow for instance).
</ul>
<p>
To address these limitations, many programmers have arrived at the
conclusion that it is much easier to use different programming
languages for different tasks. For instance, writing a graphical user
interface may be significantly easier in a scripting language like
Python or Tcl (consider the reasons why millions of programmers have used languages like
Visual Basic if you need more proof). An interactive interpreter might also serve as a
useful debugging and testing tool. Other languages like Java might
greatly simplify the task of writing distributed computing software.
The key point is that different programming languages offer different
strengths and weaknesses. Moreover, it is extremely unlikely that any
programming is ever going to be perfect. Therefore, by combining
languages together, you can utilize the best features of each language
and greatly simplify certain aspects of software development.
</p>
<p>
From the standpoint of C/C++, a lot of people use SWIG because they want to break
out of the traditional monolithic C programming model which usually results
in programs that resemble this:
<ul>
<li>A collection of functions and variables that do something useful.
<li>A <tt>main()</tt> program that starts everything.
<li>A horrible collection of hacks that form some kind of user interface (but
which no-one really wants to touch).
</ul>
<p>
Instead of going down that route, incorporating C/C++ into a higher level language
often results in a more modular design, less code, better flexibility, and increased
programmer productivity.
</p>
<p>
SWIG tries to make the problem of C/C++ integration as painless as possible.
This allows you to focus on the underlying C
program and using the high-level language interface, but not
the tedious and complex chore of making the two languages talk to each
other. At the same time, SWIG recognizes that all applications are different. Therefore,
it provides a wide variety of customization features that let you change almost
every aspect of the language bindings. This is the main reason why SWIG has such a large
user manual ;-).
<H2><a name="Introduction_nn4"></a>2.3 A SWIG example</H2>
<p>
The best way to illustrate SWIG is with a simple example. Consider the
following C code:
</p>
<div class="code"><pre>
/* File : example.c */
double My_variable = 3.0;
/* Compute factorial of n */
int fact(int n) {
if (n &lt;= 1) return 1;
else return n*fact(n-1);
}
/* Compute n mod m */
int my_mod(int n, int m) {
return(n % m);
}
</pre></div>
<p>
Suppose that you wanted to access these functions and the global
variable <tt>My_variable</tt> from Tcl. You start by making a SWIG
interface file as shown below (by convention, these files carry a .i
suffix) :
<H3><a name="Introduction_nn5"></a>2.3.1 SWIG interface file</H3>
<div class="code"><pre>
/* File : example.i */
%module example
%{
/* Put headers and other declarations here */
extern double My_variable;
extern int fact(int);
extern int my_mod(int n, int m);
%}
extern double My_variable;
extern int fact(int);
extern int my_mod(int n, int m);
</pre></div>
<p>
The interface file contains ANSI C function prototypes and variable
declarations. The <tt>%module</tt> directive defines the name of the
module that will be created by SWIG. The <tt>%{ %}</tt> block
provides a location for inserting additional code, such as C header
files or additional C declarations, into the generated C wrapper code.
<H3><a name="Introduction_nn6"></a>2.3.2 The swig command</H3>
<p>
SWIG is invoked using the <tt>swig</tt> command. We can use this to
build a Tcl module (under Linux) as follows :
</p>
<div class="shell"><pre>
unix &gt; <b>swig -tcl example.i</b>
unix &gt; <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include</b>
unix &gt; <b>gcc -shared example.o example_wrap.o -o example.so</b>
unix &gt; <b>tclsh</b>
% <b>load ./example.so</b>
% <b>fact 4</b>
24
% <b>my_mod 23 7</b>
2
% <b>expr $My_variable + 4.5</b>
7.5
%
</pre></div>
<p>
The <tt>swig</tt> command produced a new file called
<tt>example_wrap.c</tt> that should be compiled along with the
<tt>example.c</tt> file. Most operating systems and scripting
languages now support dynamic loading of modules. In our example, our
Tcl module has been compiled into a shared library that can be loaded
into Tcl. When loaded, Tcl can now access the functions
and variables declared in the SWIG interface. A look at the file
<tt>example_wrap.c</tt> reveals a hideous mess. However, you
almost never need to worry about it.
<H3><a name="Introduction_nn7"></a>2.3.3 Building a Perl5 module</H3>
<p>
Now, let's turn these functions into a Perl5 module. Without making
any changes type the following (shown for Solaris):
</p>
<div class="shell"><pre>
unix &gt; <b>swig -perl5 example.i</b>
unix &gt; <b>gcc -c example.c example_wrap.c \
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
unix &gt; <b>ld -G example.o example_wrap.o -o example.so</b> # This is for Solaris
unix &gt; <b>perl5.003
use example;
print example::fact(4), "\n";
print example::my_mod(23,7), "\n";
print $example::My_variable + 4.5, "\n";
&lt;ctrl-d&gt;</b>
24
2
7.5
unix &gt;
</pre></div>
<H3><a name="Introduction_nn8"></a>2.3.4 Building a Python module</H3>
<p>
Finally, let's build a module for Python (shown for Irix).
</p>
<div class="shell"><pre>
unix &gt; <b>swig -python example.i</b>
unix &gt; <b>gcc -c -fpic example.c example_wrap.c -I/usr/local/include/python2.0</b>
unix &gt; <b>gcc -shared example.o example_wrap.o -o _example.so</b>
unix &gt; <b>python</b>
Python 2.0 (#6, Feb 21 2001, 13:29:45)
[GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2
Type "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; <b>import example</b>
&gt;&gt;&gt; <b>example.fact(4)</b>
24
&gt;&gt;&gt; <b>example.my_mod(23,7)</b>
2
&gt;&gt;&gt; <b>example.cvar.My_variable + 4.5</b>
7.5
</pre></div>
<H3><a name="Introduction_nn9"></a>2.3.5 Shortcuts</H3>
<p>
To the truly lazy programmer, one may wonder why we needed the extra
interface file at all. As it turns out, you can often do without
it. For example, you could also build a Perl5 module by just running
SWIG on the C header file and specifying a module name as follows
</p>
<div class="shell"><pre>
unix &gt; <b>swig -perl5 -module example example.h</b>
unix &gt; <b>gcc -c example.c example_wrap.c \
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
unix &gt; <b>ld -G example.o example_wrap.o -o example.so</b>
unix &gt; <b>perl5.003
use example;
print example::fact(4), "\n";
print example::my_mod(23,7), "\n";
print $example::My_variable + 4.5, "\n";
&lt;ctrl-d&gt;</b>
24
2
7.5
</pre></div>
<H2><a name="Introduction_nn10"></a>2.4 Supported C/C++ language features</H2>
<p>
A primary goal of the SWIG project is to make the language binding
process extremely easy. Although a few simple examples have been shown,
SWIG is quite capable in supporting most of C++. Some of the
major features include:
</p>
<ul>
<li>Full C99 preprocessing.
<li>All ANSI C and C++ datatypes.
<li>Functions, variables, and constants.
<li>Classes.
<li>Single and multiple inheritance.
<li>Overloaded functions and methods.
<li>Overloaded operators.
<li>C++ templates (including member templates, specialization, and partial specialization).
<li>Namespaces.
<li>Variable length arguments.
<li>C++ smart pointers.
</ul>
<p>
Currently, the only major C++ feature not supported is nested classes--a limitation
that should be removed in a future release, but has some workarounds for the moment.
</p>
<p>
It is important to stress that SWIG is not a simplistic C++ lexing
tool like several apparently similar wrapper generation tools. SWIG
not only parses C++, it implements the full C++ type system and it is
able to understand C++ semantics. SWIG generates its wrappers with
full knowledge of this information. As a result, you will find SWIG
to be just as capable of dealing with nasty corner cases as it is in
wrapping simple C++ code. In fact, SWIG is able handle C++ code that
stresses the very limits of many C++ compilers.
<H2><a name="Introduction_nn11"></a>2.5 Non-intrusive interface building</H2>
<p>
When used as intended, SWIG requires minimal (if any) modification to
existing C or C++ code. This makes SWIG extremely easy to use with existing
packages and promotes software reuse and modularity. By making
the C/C++ code independent of the high level interface, you can change the
interface and reuse the code in other applications. It is also
possible to support different types of interfaces depending on the application.
</p>
<H2><a name="Introduction_build_system"></a>2.6 Incorporating SWIG into a build system</H2>
<p>
SWIG is a command line tool and as such can be incorporated into any build system that supports invoking external tools/compilers.
SWIG is most commonly invoked from within a Makefile, but is also known to be invoked from popular IDEs such as
Microsoft Visual Studio.
</p>
<p>
If you are using the GNU Autotools
(<a href="http://www.gnu.org/software/autoconf">Autoconf</a>/
<a href="http://www.gnu.org/software/automake">Automake</a>/
<a href="http://www.gnu.org/software/libtool">Libtool</a>)
to configure SWIG use in your project, the SWIG Autoconf macros can be used.
The primary macro is <tt>ax_pkg_swig</tt>, see
<a href="http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig">http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig</a>.
The <tt>ax_python_devel</tt> macro is also helpful for generating Python extensions. See the
<a href="http://www.gnu.org/software/autoconf-archive/">Autoconf Archive</a>
for further information on this and other Autoconf macros.
</p>
<p>
There is growing support for SWIG in some build tools, for example <a href="http://www.cmake.org">CMake</a>
is a cross-platform, open-source build manager with built in support for SWIG. CMake can detect the SWIG executable
and many of the target language libraries for linking against.
CMake knows how to build shared libraries and loadable modules on many different operating systems.
This allows easy cross platform SWIG development. It also can generate the custom commands necessary for
driving SWIG from IDE's and makefiles. All of this can be done from a single cross platform input file.
The following example is a CMake input file for creating a python wrapper for the SWIG interface file, example.i:
</p>
<div class="code"><pre>
# This is a CMake example for Python
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(example python example.i example.cxx)
SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})
</pre></div>
<p>
The above example will generate native build files such as makefiles, nmake files and Visual Studio projects
which will invoke SWIG and compile the generated C++ files into _example.so (UNIX) or _example.pyd (Windows).
For other target languages on Windows a dll, instead of a .pyd file, is usually generated.
</p>
<H2><a name="Introduction_nn12"></a>2.7 Hands off code generation</H2>
<p>
SWIG is designed to produce working code that needs no
hand-modification (in fact, if you look at the output, you probably
won't want to modify it). You should think of your target language interface being
defined entirely by the input to SWIG, not the resulting output
file. While this approach may limit flexibility for hard-core hackers,
it allows others to forget about the low-level implementation
details.
</p>
<H2><a name="Introduction_nn13"></a>2.8 SWIG and freedom</H2>
<p>
No, this isn't a special section on the sorry state of world politics.
However, it may be useful to know that SWIG was written with a
certain "philosophy" about programming---namely that programmers are
smart and that tools should just stay out of their way. Because of
that, you will find that SWIG is extremely permissive in what it lets
you get away with. In fact, you can use SWIG to go well beyond
"shooting yourself in the foot" if dangerous programming is your goal.
On the other hand, this kind of freedom may be exactly what is needed
to work with complicated and unusual C/C++ applications.
</p>
<p>
Ironically, the freedom that SWIG provides is countered by an
extremely conservative approach to code generation. At it's core, SWIG
tries to distill even the most advanced C++ code down to a small
well-defined set of interface building techniques based on ANSI C
programming. Because of this, you will find that SWIG interfaces can
be easily compiled by virtually every C/C++ compiler and that they can
be used on any platform. Again, this is an important part of staying out
of the programmer's way----the last thing any developer wants to do is
to spend their time debugging the output of a tool that relies on
non-portable or unreliable programming features.
</body>
</html>

7795
Doc/Manual/Java.html Normal file

File diff suppressed because it is too large Load diff

1894
Doc/Manual/Library.html Normal file

File diff suppressed because it is too large Load diff

802
Doc/Manual/Lisp.html Normal file
View file

@ -0,0 +1,802 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Common Lisp</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Lisp"></a>23 SWIG and Common Lisp</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Lisp_nn2">Allegro Common Lisp</a>
<li><a href="#Lisp_nn3">Common Foreign Function Interface(CFFI)</a>
<ul>
<li><a href="#Lisp_nn4">Additional Commandline Options </a>
<li><a href="#Lisp_nn5">Generating CFFI bindings</a>
<li><a href="#Lisp_nn6">Generating CFFI bindings for C++ code</a>
<li><a href="#Lisp_nn7">Inserting user code into generated files</a>
</ul>
<li><a href="#Lisp_nn8">CLISP</a>
<ul>
<li><a href="#Lisp_nn9">Additional Commandline Options </a>
<li><a href="#Lisp_nn10">Details on CLISP bindings</a>
</ul>
<li><a href="#Lisp_nn11">UFFI </a>
</ul>
</div>
<!-- INDEX -->
<p>
Common Lisp is a high-level, all-purpose, object-oriented,
dynamic, functional programming language with long history.
Common Lisp is used in many fields, ranging from web development to
finance, and also common in computer science education.
There are more than 9 different implementations of common lisp which
are available, all have different foreign function
interfaces. SWIG currently supports only the Allegro Common
Lisp, Common Foreign Function Interface(CFFI), CLisp and UFFI
foreign function interfaces.
</p>
<H2><a name="Lisp_nn2"></a>23.1 Allegro Common Lisp</H2>
<p>
Allegro Common Lisp support in SWIG has been updated to include
support for both C and C++. You can read about the interface
<a href="Allegrocl.html#Allegrocl">here</a>
</p>
<H2><a name="Lisp_nn3"></a>23.2 Common Foreign Function Interface(CFFI)</H2>
<p>
CFFI, the Common Foreign Function Interface, is a portable foreign
function interface for ANSI Common Lisp systems, similar in
spirit to UFFI. Unlike UFFI, CFFI requires only a small set of
low-level functionality from the Lisp implementation, such as
calling a foreign function by name, allocating foreign memory,
and dereferencing pointers.
</p>
<p>
To run the cffi module of SWIG requires very little effort, you
just need to run:
</p>
<div class="code"><pre>
swig -cffi -module <i>module-name</i> <i>file-name</i>
</pre></div>
<p>
But a better was of using all the power of SWIG is to write SWIG
interface files. Below we will explain how to write interface
files and the various things which you can do with them.
</p>
<H3><a name="Lisp_nn4"></a>23.2.1 Additional Commandline Options </H3>
<p>
The following table list the additional commandline options available for the CLISP module. They can also be seen by using:
</p>
<div class="code"><pre>
swig -cffi -help
</pre></div>
<br/>
<table summary="CFFI specific options">
<tr>
<th> CFFI specific options</th>
</tr>
<tr>
<td>-generate-typedef</td>
<td>If this option is given then defctype will be used to generate<br/>
shortcuts according to the typedefs in the input.
</td>
</tr>
<tr>
<td>-[no]cwrap</td>
<td>Turn on or turn off generation of an intermediate C file when<br/>
creating a C interface. By default this is only done for C++ code.
</td>
</tr>
<tr>
<td>-[no]swig-lisp</td>
<td>Turns on or off generation of code for helper lisp macro, functions,
etc. which SWIG uses while generating wrappers. These macros, functions
may still be used by generated wrapper code.
</td>
</tr>
</table>
<H3><a name="Lisp_nn5"></a>23.2.2 Generating CFFI bindings</H3>
As we mentioned earlier the ideal way to use SWIG is to use interface
files. To illustrate the use of it, lets assume that we have a
file named <i>test.h</i> with the following C code:
<div class="code"><pre>
#define y 5
#define x (y &gt;&gt; 1)
typedef int days;
struct bar {
short p, q;
char a, b;
int *z[1000];
struct bar * n;
};
struct bar * my_struct;
struct foo {
int a;
struct foo * b[100];
};
int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int p);
int func123(div_t * p,int **q[100],int r[][1000][10]);
void lispsort_double (int n, double * array);
enum color { RED, BLUE, GREEN};
</pre></div>
Corresponding to this we will write a simple interface file:
<div class="code"><pre>
%module test
%include "test.h"
</pre></div>
The generated SWIG Code will be:
<div class="targetlang"><pre>
;;;SWIG wrapper code starts here
(cl:defmacro defanonenum (&amp;body enums)
"Converts anonymous enums to defconstants."
`(cl:progn ,@(cl:loop for value in enums
for index = 0 then (cl:1+ index)
when (cl:listp value) do (cl:setf index (cl:second value)
value (cl:first value))
collect `(cl:defconstant ,value ,index))))
(cl:eval-when (:compile-toplevel :load-toplevel)
(cl:unless (cl:fboundp 'swig-lispify)
(cl:defun swig-lispify (name flag cl:&amp;optional (package cl:*package*))
(cl:labels ((helper (lst last rest cl:&amp;aux (c (cl:car lst)))
(cl:cond
((cl:null lst)
rest)
((cl:upper-case-p c)
(helper (cl:cdr lst) 'upper
(cl:case last
((lower digit) (cl:list* c #\- rest))
(cl:t (cl:cons c rest)))))
((cl:lower-case-p c)
(helper (cl:cdr lst) 'lower (cl:cons (cl:char-upcase c) rest)))
((cl:digit-char-p c)
(helper (cl:cdr lst) 'digit
(cl:case last
((upper lower) (cl:list* c #\- rest))
(cl:t (cl:cons c rest)))))
((cl:char-equal c #\_)
(helper (cl:cdr lst) '_ (cl:cons #\- rest)))
(cl:t
(cl:error "Invalid character: ~A" c)))))
(cl:let ((fix (cl:case flag
((constant enumvalue) "+")
(variable "*")
(cl:t ""))))
(cl:intern
(cl:concatenate
'cl:string
fix
(cl:nreverse (helper (cl:concatenate 'cl:list name) cl:nil cl:nil))
fix)
package))))))
;;;SWIG wrapper code ends here
(cl:defconstant y 5)
(cl:defconstant x (cl:ash 5 -1))
(cffi:defcstruct bar
(p :short)
(q :short)
(a :char)
(b :char)
(z :pointer)
(n :pointer))
(cffi:defcvar ("my_struct" my_struct)
:pointer)
(cffi:defcstruct foo
(a :int)
(b :pointer))
(cffi:defcfun ("pointer_func" pointer_func) :int
(ClosureFun :pointer)
(p :int))
(cffi:defcfun ("func123" func123) :int
(p :pointer)
(q :pointer)
(r :pointer))
(cffi:defcfun ("lispsort_double" lispsort_double) :void
(n :int)
(array :pointer))
(cffi:defcenum color
:RED
:BLUE
:GREEN)
</pre></div>
<p>
The <i>SWIG wrapper</i> code refers to the special code which SWIG
may need to use while wrapping C code. You can turn on/off the
generation of this code by using the <i>-[no]swig-lisp</i>
option. You must have noticed that SWIG goes one extra step to
ensure that CFFI does not do automatic lispification of the C
function names. The reason SWIG does this is because quite often
developers want to build a nice CLOS based lispy API, and this one
to one correspondence between C function names and lisp function
name helps.
</p>
<p> Maybe you want to have your own convention for generating lisp
function names for corresponding C function names, or you just
want to lispify the names, also, before we forget you want to
export the generated lisp names. To do this, we will use the
SWIG <a
href="Customization.html#Customization_features">feature directive</a>.
Let's edit the interface file such that the C type "div_t*" is changed
to Lisp type ":my-pointer", we lispify all names,
export everything, and do some more stuff.
</p>
<div class="code"><pre>
%module test
%typemap(cin) div_t* ":my-pointer";
%feature("intern_function","1");
%feature("export");
%feature("inline") lispsort_double;
%feature("intern_function", "my-lispify") lispsort_double;
%rename func123 renamed_cool_func;
%ignore "pointer_func";
%include "test.h"
</pre></div>
<p>
The <i>typemap(cin)</i> ensures that for all arguments which are input
to C with the type "div_t*", the ":my-pointer" type be
used. Similarly <i>typemap(cout)</i> are used for all types which
are returned from C.
</p>
<p>
The feature <i>intern_function</i> ensures that all C names are
interned using the <b>swig-lispify</b> function. The "1" given
to the feature is optional. The use of feature like
<i>%feature("intern_function","1");</i> globally enables
interning for everything. If you want to target a single
function, or declaration then use the targeted version of
feature, <i>%feature("intern_function", "my-lispify")
lispsort_double;</i>, here we are using an additional feature
which allows us to use our lispify function.
</p>
<p>The <i>export</i> feature allows us to export the symbols. The <i>inline</i>
feature declaims the declared function as inline. The <i>rename</i>
directive allows us to change the name(it is useful when
generating C wrapper code for handling overloaded
functions). The <i>ignore</i> directive ignores a certain
declaration.
</p>
<p>There are several other things which are possible, to see some
example of usage of SWIG look at the Lispbuilder and wxCL
projects. The generated code with 'noswig-lisp' option is:
</p>
<div class="targetlang"><pre>
(cl:defconstant #.(swig-lispify "y" 'constant) 5)
(cl:export '#.(swig-lispify "y" 'constant))
(cl:defconstant #.(swig-lispify "x" 'constant) (cl:ash 5 -1))
(cl:export '#.(swig-lispify "x" 'constant))
(cffi:defcstruct #.(swig-lispify "bar" 'classname)
(#.(swig-lispify "p" 'slotname) :short)
(#.(swig-lispify "q" 'slotname) :short)
(#.(swig-lispify "a" 'slotname) :char)
(#.(swig-lispify "b" 'slotname) :char)
(#.(swig-lispify "z" 'slotname) :pointer)
(#.(swig-lispify "n" 'slotname) :pointer))
(cl:export '#.(swig-lispify "bar" 'classname))
(cl:export '#.(swig-lispify "p" 'slotname))
(cl:export '#.(swig-lispify "q" 'slotname))
(cl:export '#.(swig-lispify "a" 'slotname))
(cl:export '#.(swig-lispify "b" 'slotname))
(cl:export '#.(swig-lispify "z" 'slotname))
(cl:export '#.(swig-lispify "n" 'slotname))
(cffi:defcvar ("my_struct" #.(swig-lispify "my_struct" 'variable))
:pointer)
(cl:export '#.(swig-lispify "my_struct" 'variable))
(cffi:defcstruct #.(swig-lispify "foo" 'classname)
(#.(swig-lispify "a" 'slotname) :int)
(#.(swig-lispify "b" 'slotname) :pointer))
(cl:export '#.(swig-lispify "foo" 'classname))
(cl:export '#.(swig-lispify "a" 'slotname))
(cl:export '#.(swig-lispify "b" 'slotname))
(cffi:defcfun ("renamed_cool_func" #.(swig-lispify "renamed_cool_func" 'function)) :int
(p :my-pointer)
(q :pointer)
(r :pointer))
(cl:export '#.(swig-lispify "renamed_cool_func" 'function))
(cl:declaim (cl:inline #.(my-lispify "lispsort_double" 'function)))
(cffi:defcfun ("lispsort_double" #.(my-lispify "lispsort_double" 'function)) :void
(n :int)
(array :pointer))
(cl:export '#.(my-lispify "lispsort_double" 'function))
(cffi:defcenum #.(swig-lispify "color" 'enumname)
#.(swig-lispify "RED" 'enumvalue :keyword)
#.(swig-lispify "BLUE" 'enumvalue :keyword)
#.(swig-lispify "GREEN" 'enumvalue :keyword))
(cl:export '#.(swig-lispify "color" 'enumname))
</pre></div>
<H3><a name="Lisp_nn6"></a>23.2.3 Generating CFFI bindings for C++ code</H3>
<p>This feature to SWIG (for CFFI) is very new and still far from
complete. Pitch in with your patches, bug reports and feature
requests to improve it.
</p>
<p> Generating bindings for C++ code, requires <i>-c++</i> option to be
present and it first generates C binding which will wrap the C++
code, and then generates the
corresponding CFFI wrapper code. In the generated C wrapper
code, you will often want to put your own C code, such as the
code to include various files. This can be done by making use of
"%{" and "%}" as shown below.
</p>
<div class="code"><pre>
%{
#include "Test/test.h"
%}
</pre></div>
<p>
Also, while parsing the C++ file and generating C wrapper code SWIG
may need to be able to understand various symbols used in other
header files. To help SWIG in doing this while ensuring that
wrapper code is generated for the target file, use the "import"
directive. The "include" directive specifies the target file for
which wrapper code will be generated.
</p>
<div class="code"><pre>
%import "ancillary/header.h"
%include "target/header.h"
</pre></div>
Various features which were available for C headers can also be used
here. The target header which we are going to use here is:
<div class="code"><pre>
namespace OpenDemo {
class Test
{
public:
float x;
// constructors
Test (void) {x = 0;}
Test (float X) {x = X;}
// vector addition
Test operator+ (const Test&amp; v) const {return Test (x+v.x);}
// length squared
float lengthSquared (void) const {return this-&gt;dot (*this);}
static float distance (const Test&amp; a, const Test&amp; b){return(a-b).length();}
inline Test parallelComponent (const Test&amp; unitBasis) const {
return unitBasis * projection;
}
Test setYtoZero (void) const {return Test (this-&gt;x);}
static const Test zero;
};
inline Test operator* (float s, const Test&amp; v) {return v*s;}
inline std::ostream&amp; operator&lt;&lt; (std::ostream&amp; o, const Test&amp; v)
{
return o &lt;&lt; "(" &lt;&lt; v.x &lt;&lt; ")";
}
inline Test RandomUnitVectorOnXZPlane (void)
{
return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
}
}
</pre></div>
<p>The interface used is: </p>
<div class="code"><pre>
%module test
%include "test.cpp"
</pre></div>
SWIG generates 3 files, the first one is a C wrap which we don't show,
the second is the plain CFFI wrapper which is as shown below:
<div class="targetlang"><pre>
(cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void
(self :pointer)
(x :float))
(cffi:defcfun ("_wrap_Test_x_get" Test_x_get) :float
(self :pointer))
(cffi:defcfun ("_wrap_new_Test__SWIG_0" new_Test) :pointer)
(cffi:defcfun ("_wrap_new_Test__SWIG_1" new_Test) :pointer
(X :float))
(cffi:defcfun ("_wrap_Test___add__" Test___add__) :pointer
(self :pointer)
(v :pointer))
(cffi:defcfun ("_wrap_Test_lengthSquared" Test_lengthSquared) :float
(self :pointer))
(cffi:defcfun ("_wrap_Test_distance" Test_distance) :float
(a :pointer)
(b :pointer))
(cffi:defcfun ("_wrap_Test_parallelComponent" Test_parallelComponent) :pointer
(self :pointer)
(unitBasis :pointer))
(cffi:defcfun ("_wrap_Test_setYtoZero" Test_setYtoZero) :pointer
(self :pointer))
(cffi:defcvar ("Test_zero" Test_zero)
:pointer)
(cffi:defcfun ("_wrap_delete_Test" delete_Test) :void
(self :pointer))
(cffi:defcfun ("_wrap___mul__" __mul__) :pointer
(s :float)
(v :pointer))
(cffi:defcfun ("_wrap___lshift__" __lshift__) :pointer
(o :pointer)
(v :pointer))
(cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer)
</pre></div>
The output is pretty good but it fails in disambiguating overloaded
functions such as the constructor, in this case. One way of
resolving this problem is to make the interface use the rename
directiv, but hopefully there are better solutions.
In addition SWIG also generates, a CLOS file
<div class="targetlang"><pre>
(clos:defclass test()
((ff :reader ff-pointer)))
(clos:defmethod (cl:setf x) (arg0 (obj test))
(Test_x_set (ff-pointer obj) arg0))
(clos:defmethod x ((obj test))
(Test_x_get (ff-pointer obj)))
(cl:shadow "+")
(clos:defmethod + ((obj test) (self test) (v test))
(Test___add__ (ff-pointer obj) (ff-pointer self) (ff-pointer v)))
(clos:defmethod length-squared ((obj test) (self test))
(Test_lengthSquared (ff-pointer obj) (ff-pointer self)))
(clos:defmethod parallel-component ((obj test) (self test) (unitBasis test))
(Test_parallelComponent (ff-pointer obj) (ff-pointer self) (ff-pointer unitBasis)))
(clos:defmethod set-yto-zero ((obj test) (self test))
(Test_setYtoZero (ff-pointer obj) (ff-pointer self)))
</pre></div>
<p>I agree that the CFFI C++ module needs lot more work. But I hope it
provides a starting point, on which you can base your work of
importing C++ libraries to Lisp.
</p>
<p>
If you have any questions, suggestions, patches, etc., related to CFFI
module feel free to contact us on the SWIG mailing list, and
also please add a "[CFFI]" tag in the subject line.
<H3><a name="Lisp_nn7"></a>23.2.4 Inserting user code into generated files</H3>
<p>
It is often necessary to <a href="SWIG.html#SWIG_nn40">include user-defined code</a>
into the automatically generated interface files. For example, when building
a C++ interface, example_wrap.cxx will likely not compile unless
you add a <tt>#include "header.h"</tt> directive. This can be done
using the SWIG <tt>%insert(section) %{ ...code... %}</tt> directive:
</p>
<div class="code">
<pre>
%module example
%{
#include "header.h"
%}
%include "header.h"
int fact(int n);
</pre>
</div>
<p>
Additional sections have been added for inserting into the
generated lisp interface file:
</p>
<ul>
<li><tt>lisphead</tt> - inserts before type declarations</li>
<li><tt>swiglisp</tt> - inserts after type declarations according to
where it appears in the .i file</li>
</ul>
<p>
Note that the block <tt>%{ ... %}</tt> is effectively a shortcut for
<tt>%insert("header") %{ ... %}</tt>.
</p>
<H2><a name="Lisp_nn8"></a>23.3 CLISP</H2>
<p>
<a href="http://clisp.cons.org">CLISP</a> is a feature-loaded
implementation of common lisp which is portable across most of the
operating system environments and hardware. CLISP includes an
interpreter, a compiler, a debugger, CLOS, MOP, a foreign
language interface, i18n, regular expressions, a socket
interface, and more. An X11 interface is available through CLX,
Garnet and CLUE/CLIO. Command line editing is provided by
readline. CLISP runs Maxima, ACL2 and many other Common Lisp
packages.
</p>
<p>
To run the clisp module of SWIG requires very little effort, you
just need to execute:
</p>
<div class="code"><pre>
swig -clisp -module <i>module-name</i> <i>file-name</i>
</pre></div>
<p>
Because of the high level nature of the CLISP FFI, the bindings
generated by SWIG may not be absolutely correct, and you may need
to modify them. The good thing is that you don't need to complex
interface file for the CLISP module. The CLISP module tries to
produce code which is both human readable and easily modifyable.
</p>
<H3><a name="Lisp_nn9"></a>23.3.1 Additional Commandline Options </H3>
<p>
The following table list the additional commandline options available for the CLISP module. They can also be seen by using:
</p>
<div class="code"><pre>
swig -clisp -help
</pre></div>
<br/>
<table summary="CLISP specific options">
<tr>
<th>CLISP specific options</th>
</tr>
<tr>
<td>-extern-all</td>
<td>If this option is given then clisp definitions for all the functions<br/>
and global variables will be created otherwise only definitions for<br/>
externed functions and variables are created.
</td>
</tr>
<tr>
<td>-generate-typedef</td>
<td>If this option is given then def-c-type will be used to generate<br/>
shortcuts according to the typedefs in the input.
</td>
</tr>
</table>
<H3><a name="Lisp_nn10"></a>23.3.2 Details on CLISP bindings</H3>
<p>
As mentioned earlier the CLISP bindings generated by SWIG may need
some modifications. The clisp module creates a lisp file with
the same name as the module name. This
lisp file contains a 'defpackage' declaration, with the
package name same as the module name. This package uses the
'common-lisp' and 'ffi' packages. Also, package exports all
the functions, structures and variables for which an ffi
binding was generated.<br/>
After generating the defpackage statement, the clisp module also
sets the default language.
<div class="targetlang"><pre>
(defpackage :test
(:use :common-lisp :ffi)
(:export
:make-bar
:bar-x
:bar-y
:bar-a
:bar-b
:bar-z
:bar-n
:pointer_func
:func123
:make-cfunr
:lispsort_double
:test123))
(in-package :test)
(default-foreign-language :stdc)
</pre></div>
<p>
The ffi wrappers for functions and variables are generated as shown
below. When functions have arguments of type "double * array",
SWIG doesn't knows whether it is an 'out' argument or it is
an array which will be passed, so SWIG plays it safe by
declaring it as an '(array (ffi:c-ptr DOUBLE-FLOAT))'. For
arguments of type "int **z[100]" where SWIG has more
information, i.e., it knows that 'z' is an array of pointers to
pointers of integers, SWIG defines it to be '(z (ffi:c-ptr
(ffi:c-array (ffi:c-ptr (ffi:c-ptr ffi:int)) 100)))'
</p>
<div class="code"><pre>
extern "C" {
int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int y);
int func123(div_t * x,int **z[100],int y[][1000][10]);
void lispsort_double (int n, double * array);
void test123(float x , double y);
}
</pre></div>
<div class="targetlang"><pre>
(ffi:def-call-out pointer_func
(:name "pointer_func")
(:arguments (ClosureFun (ffi:c-function (:arguments (arg0 (ffi:c-pointer NIL))
(arg1 (ffi:c-pointer NIL))
(arg2 (ffi:c-pointer NIL)))
(:return-type NIL)))
(y ffi:int))
(:return-type ffi:int)
(:library +library-name+))
(ffi:def-call-out func123
(:name "func123")
(:arguments (x (ffi:c-pointer div_t))
(z (ffi:c-ptr (ffi:c-array (ffi:c-ptr (ffi:c-ptr ffi:int)) 100)))
(y (ffi:c-ptr (ffi:c-ptr (ffi:c-array ffi:int (1000 10))))))
(:return-type ffi:int)
(:library +library-name+))
(ffi:def-call-out lispsort_double
(:name "lispsort_double")
(:arguments (n ffi:int)
(array (ffi:c-ptr DOUBLE-FLOAT)))
(:return-type NIL)
(:library +library-name+))
(ffi:def-call-out test123
(:name "test")
(:arguments (x SINGLE-FLOAT)
(y DOUBLE-FLOAT))
(:return-type NIL)
(:library +library-name+))
</pre></div>
<p>
The module also handles strutcures and #define constants as shown
below. SWIG automatically adds the constructors and accessors
created for the struct to the list of symbols exported by the
package.
</p>
<div class="code"><pre>
struct bar {
short x, y;
char a, b;
int *z[1000];
struct bar * n;
};
#define max 1000
</pre></div>
<div class="targetlang"><pre>
(ffi:def-c-struct bar
(x :type ffi:short)
(y :type ffi:short)
(a :type character)
(b :type character)
(z :type (ffi:c-array (ffi:c-ptr ffi:int) 1000))
(n :type (ffi:c-pointer bar)))
(defconstant max 1000)
</pre></div>
<H2><a name="Lisp_nn11"></a>23.4 UFFI </H2>
</body>
</html>

1598
Doc/Manual/Lua.html Normal file

File diff suppressed because it is too large Load diff

75
Doc/Manual/Makefile Normal file
View file

@ -0,0 +1,75 @@
# Makefile for generating the SWIG documentation
#
# Note that the htmldoc package needs to be installed, but requires patching (using the
# margin-left.patch file from this directory) in order to correctly generate the pdf docs.
# The .html files are first processed and updated with chapter numbering and anchor names
# are added to the HTML headings using the python scripts. The htmldoc program is then
# used to generate the PDF document and single page HTML version of the documentation.
# HTML TIDY (package also known as tidy) is also required and is used as an aid to HTML
# validation.
#
# Additional html validation can be done using the validate target.
# Additional link checking can be done using the linkchecker target.
#
# Note the # and " are escaped
HTMLDOC_OPTIONS = "--book --toclevels 4 --no-numbered --toctitle \"Table of Contents\" --title --titleimage swig16.png --linkcolor \#0000ff --linkstyle underline --size Universal --left 0.50in --right 0.50in --top 0.50in --bottom 0.50in --header .t. --footer h.1 --nup 1 --tocheader .t. --tocfooter ..i --portrait --color --no-pscommands --no-xrxcomments --compression=1 --jpeg=0 --fontsize 10.0 --fontspacing 1.2 --headingfont Helvetica --bodyfont Times --headfootsize 10.0 --headfootfont Helvetica --charset iso-8859-1 --links --no-embedfonts --pagemode outline --pagelayout single --firstpage c1 --pageeffect none --pageduration 10 --effectduration 1.0 --no-encryption --permissions all --owner-password \"\" --user-password \"\" --browserwidth 680"
.PHONY: maketoc check generate all maintainer-clean validate test
all: maketoc check generate
maketoc: CCache.html
python maketoc.py
CCache.html: ../../CCache/ccache.yo
yodl2html -o CCache.html ../../CCache/ccache.yo
# Use htmltidy to warn about some HTML errors. Note that it is not used to clean/tidy the HTML,
# it is just used as a primitive HTML checker.
# CCache.html is generated by yodl2html and has a few insignificant problems, so we don't put it through tidy
check:
tidy -errors --gnu-emacs yes -quiet index.html
tidy -errors --gnu-emacs yes -quiet Sections.html
all=`sed '/^#/d' chapters | grep -v CCache.html`; for a in $$all; do tidy -errors --gnu-emacs yes -quiet $$a; done;
generate: swightml.book swigpdf.book
htmldoc --batch swightml.book || true
htmldoc --batch swigpdf.book || true
python fixstyle.py SWIGDocumentation.html
swigpdf.book: chapters Sections.html
echo "#HTMLDOC 1.8.24" > swigpdf.book
echo -t pdf13 -f SWIGDocumentation.pdf $(HTMLDOC_OPTIONS) --stylesheet style.css >> swigpdf.book
echo "Sections.html" >> swigpdf.book
cat chapters >> swigpdf.book
swightml.book: chapters Sections.html
echo "#HTMLDOC 1.8.24" > swightml.book
echo -t html -f SWIGDocumentation.html $(HTMLDOC_OPTIONS) >> swightml.book
echo "Sections.html" >> swightml.book
cat chapters >> swightml.book
maintainer-clean: clean-baks
rm -f swightml.book
rm -f swigpdf.book
rm -f CCache.html
rm -f SWIGDocumentation.html
rm -f SWIGDocumentation.pdf
clean-baks:
rm -f *.bak
test:
grep "href=\".*\.html\"" index.html
grep "href=\".*\.html\"" Sections.html
all=`sed '/^#/d' chapters`; for a in $$all; do grep -l "href=\".*\.html\"" $$a; done;
# Validating using the WDG offline validator - http://www.htmlhelp.com/tools/validator/offline/
validate:
all=`sed '/^#/d' chapters`; for a in $$all; do validate --emacs $$a; done;
# Link checking using linkchecker (can take a while - 30 mins)
linkchecker:
linkchecker --anchors Contents.html

946
Doc/Manual/Modula3.html Normal file
View file

@ -0,0 +1,946 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Modula-3</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="Modula3"></a>25 SWIG and Modula-3</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Modula3_modula3_overview">Overview</a>
<ul>
<li><a href="#Modula3_motivation">Motivation</a>
</ul>
<li><a href="#Modula3_conception">Conception</a>
<ul>
<li><a href="#Modula3_cinterface">Interfaces to C libraries</a>
<li><a href="#Modula3_cppinterface">Interfaces to C++ libraries</a>
</ul>
<li><a href="#Modula3_preliminaries">Preliminaries</a>
<ul>
<li><a href="#Modula3_compilers">Compilers</a>
<li><a href="#Modula3_commandline">Additional Commandline Options</a>
</ul>
<li><a href="#Modula3_typemaps">Modula-3 typemaps</a>
<ul>
<li><a href="#Modula3_inoutparam">Inputs and outputs</a>
<li><a href="#Modula3_ordinals">Subranges, Enumerations, Sets</a>
<li><a href="#Modula3_class">Objects</a>
<li><a href="#Modula3_imports">Imports</a>
<li><a href="#Modula3_exceptions">Exceptions</a>
<li><a href="#Modula3_typemap_example">Example</a>
</ul>
<li><a href="#Modula3_hints">More hints to the generator</a>
<ul>
<li><a href="#Modula3_features">Features</a>
<li><a href="#Modula3_pragmas">Pragmas</a>
</ul>
<li><a href="#Modula3_remarks">Remarks</a>
</ul>
</div>
<!-- INDEX -->
<p>
This chapter describes SWIG's support of
<a href="http://modula3.org/">Modula-3</a>.
You should be familiar with the
<a href="SWIG.html#SWIG">basics</a>
of SWIG,
especially
<a href="Typemaps.html#Typemaps">typemaps</a>.
</p>
<H2><a name="Modula3_modula3_overview"></a>25.1 Overview</H2>
<p>
Modula-3 is a compiled language in the tradition of Niklaus Wirth's Modula 2,
which is in turn a successor to Pascal.
</p>
<p>
SWIG's Modula-3 support is currently very basic and highly experimental!
Many features are still not designed satisfyingly
and I need more discussion about the odds and ends.
Don't rely on any feature, incompatible changes are likely in the future!
However, the Modula-3 generator was already useful for interfacing
to the libraries:
</p>
<ol>
<li>
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/">
PLPlot
</a>
</li>
<li>
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/fftw/">
FFTW
</a>
</li>
</ol>
<H3><a name="Modula3_motivation"></a>25.1.1 Motivation</H3>
<p>
Although it is possible to write Modula-3 code that performs as well as C/C++
most existing libraries are not written in Modula-3 but in C or C++, and
even libraries in other languages may provide C header files.
</p>
<p>
Fortunately Modula-3 can call C functions, but you have to write Modula-3
interfaces to them, and to make things comfortable you will also need
wrappers that convert between high-level features of Modula-3 (garbage
collecting, exceptions) and the explicit tracking of allocated memory and
exception codes used by C APIs.
</p>
<p>
SWIG converts C headers to Modula-3 interfaces for you, and using typemaps
you can pass <tt>TEXT</tt>s or open arrays, and convert error return codes
into exceptions.
</p>
<p>
If the library API is ill designed
writing appropriate typemaps can be still time-consuming.
E.g. C programmers are very creative to work-around
missing data types like (real) enumerations and sets.
You should turn such work-arounds back to the Modula-3 way
otherwise you lose static safety and consistency.
</p>
<p>
Without SWIG you would probably never consider trying to call C++ libraries
from Modula-3, but with SWIG this is becomes feasible.
SWIG can generate C wrappers to C++ functions and object methods
that may throw exceptions, and then wrap these C wrappers for Module-3.
To make it complete you can then hide the C interface with Modula-3 classes and
exceptions.
</p>
<p>
SWIG allows you to call C and C++ libraries from Modula-3 (even with call back
functions), but it doesn't allow you to easily integrate a Module-3 module into
a C/C++ project.
</p>
<H2><a name="Modula3_conception"></a>25.2 Conception</H2>
<H3><a name="Modula3_cinterface"></a>25.2.1 Interfaces to C libraries</H3>
<p>
Modula-3 has integrated support for calling C functions.
This is also extensively used by the standard Modula-3 libraries
to call OS functions.
The Modula-3 part of SWIG and the corresponding SWIG library
<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
contain code that uses these features.
Because of the built-in support there is no need
for calling the SWIG kernel to generate wrappers written in C.
All conversion and argument checking can be done in Modula-3
and the interfacing is quite efficient.
All you have to do is to write pieces of Modula-3 code
that SWIG puts together.
</p>
<table border summary="Modula-3 C library support">
<tr><th colspan=2>C library support integrated in Modula-3<th></tr>
<tr>
<td>Pragma <tt>&lt;* EXTERNAL *&gt;</tt></td>
<td>Precedes a declaration of a PROCEDURE that is implemented
in an external library instead of a Modula-3 module.</td>
</tr>
<tr>
<td>Pragma <tt>&lt;* CALLBACK *&gt;</tt></td>
<td>Precedes a declaration of a PROCEDURE that should be called
by external library code.</td>
</tr>
<tr>
<td>Module <tt>Ctypes</tt></td>
<td>Contains Modula-3 types that match some basic C types.</td>
</tr>
<tr>
<td>Module <tt>M3toC</tt></td>
<td>Contains routines that convert between Modula-3's <tt>TEXT</tt> type
and C's <tt>char *</tt> type.</td>
</tr>
</table>
<p>
In each run of SWIG the Modula-3 part
generates several files:
</p>
<table border summary="Modula-3 generated files">
<tr>
<th>Module name scheme</th>
<th>Identifier for <tt>%insert</tt></th>
<th>Description</th>
</tr>
<tr>
<td>Module<tt>Raw.i3</tt></td>
<td><tt>m3rawintf</tt></td>
<td>Declaration of types that are equivalent to those of the C library,
<tt>EXTERNAL</tt> procedures as interface to the C library functions</td>
</tr>
<tr>
<td>Module<tt>Raw.m3</tt></td>
<td><tt>m3rawimpl</tt></td>
<td>Almost empty.</td>
</tr>
<tr>
<td>Module<tt>.i3</tt></td>
<td><tt>m3wrapintf</tt></td>
<td>Declaration of comfortable wrappers to the C library functions.</td>
</tr>
<tr>
<td>Module<tt>.m3</tt></td>
<td><tt>m3wrapimpl</tt></td>
<td>Implementation of the wrappers that
convert between Modula-3 and C types,
check for validity of values,
hand-over resource management to the garbage collector using <tt>WeakRef</tt>s
and raises exceptions.</td>
</tr>
<tr>
<td><tt>m3makefile</tt></td>
<td><tt>m3makefile</tt></td>
<td>Add the modules above to the Modula-3 project and
specify the name of the Modula-3 wrapper library
to be generated.
Today I'm not sure if it is a good idea
to create a <tt>m3makefile</tt> in each run,
because SWIG must be started for each Modula-3 module it creates.
Thus the m3makefile is overwritten each time. :-(
</td>
</tr>
</table>
<p>
Here's a scheme of how the function calls to Modula-3 wrappers
are redirected to C library functions:
</p>
<table summary="Modula-3 C library">
<tr>
<td align=center>
Modula-3 wrapper<br>
Module<tt>.i3</tt><br>
generated by Modula-3 part of SWIG
</td>
<td></td>
<td align=center></td>
</tr>
<tr>
<td align=center>
<!-- pre tag overrides centering -->
|<br>
v
</td>
<td></td>
<td align=center></td>
</tr>
<tr>
<td align=center>
Modula-3 interface to C<br>
Module<tt>Raw.i3</tt><br>
generated by Modula-3 part of SWIG
</td>
<td>--&gt;</td>
<td align=center>
C library
</td>
</tr>
</table>
<p>
I have still no good conception how one can split C library interfaces
into type oriented interfaces.
A Module in Modula-3 represents an Abstract DataType
(or call it a static classes, i.e. a class without virtual methods).
E.g. if you have a principal type, say <tt>Database</tt>,
it is good Modula-3 style to set up one Module with the name <tt>Database</tt>
where the database type is declared with the name <tt>T</tt>
and where all functions are declared that operates on it.
</p>
<p>
The normal operation of SWIG is to generate a fixed set of files per call.
To generate multiple modules one has to write one SWIG interface
(different SWIG interfaces can share common data) per module.
Identifiers belonging to a different module may ignored (<tt>%ignore</tt>)
and the principal type must be renamed (<tt>%typemap</tt>).
</p>
<H3><a name="Modula3_cppinterface"></a>25.2.2 Interfaces to C++ libraries</H3>
<p>
Interfaces to C++ files are much more complicated and
there are some more design decisions that are not made, yet.
Modula-3 has no support for C++ functions
but C++ compilers should support generating C++ functions
with a C interface.
</p>
<p>
Here's a scheme of how the function calls to Modula-3 wrappers
are redirected to C library functions:
</p>
<table summary="Modula-3 C++ library">
<tr>
<td align=center>
Modula-3 wrapper<br>
Module<tt>.i3</tt><br>
generated by Modula-3 part of SWIG
</td>
<td></td>
<td align=center>C++ library</td>
</tr>
<tr>
<td align=center>
<!-- pre tag overrides centering -->
|<br>
v
</td>
<td></td>
<td align=center>
^<br>
|
</td>
</tr>
<tr>
<td align=center>
Modula-3 interface to C<br>
Module<tt>Raw.i3</tt><br>
generated by Modula-3 part of SWIG
</td>
<td>--&gt;</td>
<td align=center>
C interface to C++<br>
module<tt>_wrap.cxx</tt><br>
generated by the SWIG core
</td>
</tr>
</table>
<p>
Wrapping C++ libraries arises additional problems:
</p>
<ul>
<li>
Is it sensible to wrap C++ classes with Modula-3 classes?
</li>
<li>
How to find the wrapping Modula-3 class
for a class pointer that is returned by a C++ routine?
</li>
<li>
How to deal with multiple inheritance
which was neglected for Modula-3 for good reasons?
</li>
<li>
Is it possible to sub-class C++ classes with Modula-3 code?
This issue is addressed by directors,
a feature that was experimentally added to some Language modules
like
<a href="Java.html#Java_directors">Java</a> and
<a href="Python.html#Python_directors">Python</a>.
</li>
<li>
How to manage storage with the garbage collector of Modula-3?
Support for
<a href="Customization.html#Customization_ownership">
<tt>%newobject</tt> and <tt>%typemap(newfree)</tt></a>
isn't implemented, yet.
What's about resources that are managed by the garbage collector
but shall be passed back to the storage management of the C++ library?
This is a general issue which is not solved in a satisfying fashion
as far as I know.
</li>
<li>
How to turn C++ exceptions into Modula-3 exceptions?
There's also no support for
<a href="Customization.html#Customization_exception">
<tt>%exception</tt></a>, yet.
</li>
</ul>
<p>
Be warned:
There is no C++ library I wrote a SWIG interface for,
so I'm not sure if this is possible or sensible, yet.
</p>
<H2><a name="Modula3_preliminaries"></a>25.3 Preliminaries</H2>
<H3><a name="Modula3_compilers"></a>25.3.1 Compilers</H3>
<p>
There are different Modula-3 compilers around:
cm3, pm3, ezm3, Klagenfurth Modula-3, Cambridge Modula-3.
SWIG itself does not contain compiler specific code
but the library file
<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
may do so.
For testing examples I use Critical Mass cm3.
</p>
<H3><a name="Modula3_commandline"></a>25.3.2 Additional Commandline Options</H3>
<p>
There are some experimental command line options
that prevent SWIG from generating interface files.
Instead files are emitted that may assist you
when writing SWIG interface files.
</p>
<table border summary="Modula-3 specific options">
<tr>
<th>Modula-3 specific options</th>
<th>Description</th>
</tr>
<tr>
<td valign=top>-generateconst &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead write code for computing numeric values of constants
to the specified file.
<br>
C code may contain several constant definitions
written as preprocessor macros.
Other language modules of SWIG use
compute-once-use-readonly variables or
functions to wrap such definitions.
All of them can invoke C code dynamically
for computing the macro values.
But if one wants to turn them into Modula-3
integer constants, enumerations or set types,
the values of these expressions has to be known statically.
Although definitions like <tt>(1 &lt;&lt; FLAG_MAXIMIZEWINDOW)</tt>
must be considered as good C style
they are hard to convert to Modula-3
since the value computation can use every feature of C.
<br>
Thus I implemented these switch
to extract all constant definitions
and write a C program that output the values of them.
It works for numeric constants only
and treats all of them as <tt>double</tt>.
Future versions may generate a C++ program
that can detect the type of the macros
by overloaded output functions.
Then strings can also be processed.
</td>
</tr>
<tr>
<td valign=top>-generaterename &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead generate suggestions for <tt>%rename</tt>.
<br>
C libraries use a naming style
that is neither homogeneous nor similar to that of Modula-3.
C function names often contain a prefix denoting the library
and some name components separated by underscores
or capitalization changes.
To get library interfaces that are really Modula-3 like
you should rename the function names with the <tt>%rename</tt> directive.
This switch outputs a list of such directives
with a name suggestion generated by a simple heuristic.
</td>
</tr>
<tr>
<td valign=top>-generatetypemap &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead generate templates for some basic typemaps.
</td>
</tr>
</table>
<H2><a name="Modula3_typemaps"></a>25.4 Modula-3 typemaps</H2>
<H3><a name="Modula3_inoutparam"></a>25.4.1 Inputs and outputs</H3>
<p>
Each C procedure has a bunch of inputs and outputs.
Inputs are passed as function arguments,
outputs are updated referential arguments and
the function value.
</p>
<p>
Each C type can have several typemaps
that apply only in case if a type is used
for an input argument, for an output argument,
or for a return value.
A further typemap may specify
the direction that is used for certain parameters.
I have chosen this separation
in order to be able to write general typemaps for the typemap library
<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
.
In the library code the final usage of the type is not known.
Using separate typemaps for each possible use
allows appropriate definitions for each case.
If these pre-definitions are fine
then the direction of the function parameter
is the only hint the user must give.
</p>
<p>
The typemaps specific to Modula-3 have a common name scheme:
A typemap name starts with "m3",
followed by "raw" or "wrap"
depending on whether it controls the generation
of the Module<tt>Raw.i3</tt> or the Module<tt>.i3</tt>, respectively.
It follows an "in" for typemaps applied to input argument,
"out" for output arguments, "arg" for all kind of arguments,
"ret" for returned values.
</p>
<p>
The main task of SWIG is to build wrapper function,
i.e. functions that convert values between C and Modula-3
and call the corresponding C function.
Modula-3 wrapper functions generated by SWIG
consist of the following parts:
</p>
<ul>
<li>Generate <tt>PROCEDURE</tt> signature.</li>
<li>Declare local variables.</li>
<li>Convert input values from Modula-3 to C.</li>
<li>Check for input value integrity.</li>
<li>Call the C function.</li>
<li>Check returned values, e.g. error codes.</li>
<li>Convert and write back values into Modula-3 records.</li>
<li>Free temporary storage.</li>
<li>Return values.</li>
</ul>
<table border summary="Modula-3 typemaps">
<tr>
<th>Typemap</th>
<th>Example</th>
<th>Description</th>
</tr>
<tr>
<td>m3wrapargvar</td>
<td><tt>$1: INTEGER := $1_name;</tt></td>
<td>
Declaration of some variables needed for temporary results.
</td>
</tr>
<tr>
<td>m3wrapargconst</td>
<td><tt>$1 = "$1_name";</tt></td>
<td>
Declaration of some constant, maybe for debug purposes.
</td>
</tr>
<tr>
<td>m3wrapargraw</td>
<td><tt>ORD($1_name)</tt></td>
<td>
The expression that should be passed as argument to the raw Modula-3 interface function.
</td>
</tr>
<tr>
<td>m3wrapargdir</td>
<td><tt>out</tt></td>
<td>
Referential arguments can be used for input, output, update.
???
</td>
</tr>
<tr>
<td>m3wrapinmode</td>
<td><tt>READONLY</tt></td>
<td>
One of Modula-3 parameter modes
<tt>VALUE</tt> (or empty),
<tt>VAR</tt>,
<tt>READONLY</tt>
</td>
</tr>
<tr>
<td>m3wrapinname</td>
<td></td>
<td>
New name of the input argument.
</td>
</tr>
<tr>
<td>m3wrapintype</td>
<td></td>
<td>
Modula-3 type of the input argument.
</td>
</tr>
<tr>
<td>m3wrapindefault</td>
<td></td>
<td>
Default value of the input argument
</td>
</tr>
<tr>
<td>m3wrapinconv</td>
<td><tt>$1 := M3toC.SharedTtoS($1_name);</tt></td>
<td>
Statement for converting the Modula-3 input value to C compliant value.
</td>
</tr>
<tr>
<td>m3wrapincheck</td>
<td><tt>IF Text.Length($1_name) &gt; 10 THEN RAISE E("str too long"); END;</tt></td>
<td>
Check the integrity of the input value.
</td>
</tr>
<tr>
<td>m3wrapoutname</td>
<td></td>
<td>
Name of the <tt>RECORD</tt> field to be used for returning multiple values.
This applies to referential output arguments that shall be turned
into return values.
</td>
</tr>
<tr>
<td>m3wrapouttype</td>
<td></td>
<td>
Type of the value that is returned instead of a referential output argument.
</td>
</tr>
<tr>
<td>m3wrapoutconv</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapoutcheck</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretraw</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretname</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wraprettype</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretvar</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretconv</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapretcheck</td>
<td></td>
<td>
</td>
</tr>
<tr>
<td>m3wrapfreearg</td>
<td><tt>M3toC.FreeSharedS(str,arg1);</tt></td>
<td>
Free resources that were temporarily used in the wrapper.
Since this step should never be skipped,
SWIG will put it in the <tt>FINALLY</tt> branch
of a <tt>TRY .. FINALLY</tt> structure.
</td>
</tr>
</table>
<H3><a name="Modula3_ordinals"></a>25.4.2 Subranges, Enumerations, Sets</H3>
<p>
Subranges, enumerations, and sets are machine oriented types
that make Modula very strong and expressive compared
with the type systems of many other languages.
</p>
<ul>
<li>
Subranges are used for statically restricted choices of integers.
</li>
<li>
Enumerations are used for named choices.
</li>
<li>
Sets are commonly used for flag (option) sets.
</li>
</ul>
<p>
Using them extensively makes Modula code very safe and readable.
</p>
<p>
C supports enumerations, too, but they are not as safe as the ones of Modula.
Thus they are abused for many things:
For named choices, for integer constant definitions, for sets.
To make it complete every way of defining a value in C
(<tt>#define</tt>, <tt>const int</tt>, <tt>enum</tt>)
is somewhere used for defining something
that must be handled completely different in Modula-3
(<tt>INTEGER</tt>, enumeration, <tt>SET</tt>).
</p>
<p>
I played around with several <tt>%feature</tt>s and <tt>%pragma</tt>s
that split the task up into converting
the C bit patterns (integer or bit set)
into Modula-3 bit patterns (integer or bit set)
and change the type as requested.
See the corresponding example in the
Examples/modula3/enum/example.i file.
This is quite messy and not satisfying.
So the best what you can currently do is
to rewrite constant definitions manually.
Though this is a tedious work
that I'd like to automate.
</p>
<H3><a name="Modula3_class"></a>25.4.3 Objects</H3>
<p>
Declarations of C++ classes are mapped to <tt>OBJECT</tt> types
while it is tried to retain the access hierarchy
"public - protected - private" using partial revelation.
Though the example in
Examples/modula3/class/example.i
is not really useful, yet.
</p>
<H3><a name="Modula3_imports"></a>25.4.4 Imports</H3>
<p>
Pieces of Modula-3 code provided by typemaps
may contain identifiers from foreign modules.
If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
contains code using the function <tt>M3toC.SharedTtoS</tt>
you may declare <tt>%typemap("m3wrapinconv:import") blah * %{M3toC%}</tt>.
Then the module <tt>M3toC</tt> is imported
if the <tt>m3wrapinconv</tt> typemap for <tt>blah *</tt>
is used at least once.
Use <tt>%typemap("m3wrapinconv:import") blah * %{MyConversions AS M3toC%}</tt>
if you need module renaming.
Unqualified import is not supported.
</p>
<p>
It is cumbersome to add this typemap to each piece of Modula-3 code.
It is especially useful when writing general typemaps
for the typemap library
<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
.
For a monolithic module you might be better off
if you add the imports directly:
</p>
<div class="code">
<pre>
%insert(m3rawintf) %{
IMPORT M3toC;
%}
</pre></div>
<H3><a name="Modula3_exceptions"></a>25.4.5 Exceptions</H3>
<p>
Modula-3 provides another possibility
of an output of a function: exceptions.
</p>
<p>
Any piece of Modula-3 code that SWIG inserts
due to a typemap can raise an exception.
This way you can also convert an error code
from a C function into a Modula-3 exception.
</p>
<p>
The <tt>RAISES</tt> clause is controlled
by typemaps with the <tt>throws</tt> extension.
If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
contains code that may raise the exceptions <tt>OSError.E</tt>
you should declare
<tt>%typemap("m3wrapinconv:throws") blah * %{OSError.E%}</tt>.
</p>
<H3><a name="Modula3_typemap_example"></a>25.4.6 Example</H3>
<p>
The generation of wrappers in Modula-3 needs very fine control
to take advantage of the language features.
Here is an example of a generated wrapper
where almost everything is generated by a typemap:
</p>
<div class="code"><pre>
<I> (* %relabel m3wrapinmode m3wrapinname m3wrapintype m3wrapindefault *)</I>
PROCEDURE Name (READONLY str : TEXT := "" )
<I> (* m3wrapoutcheck:throws *)</I>
: NameResult RAISES {E} =
CONST
arg1name = "str"; <I>(* m3wrapargconst *)</I>
VAR
arg0 : C.char_star; <I>(* m3wrapretvar *)</I>
arg1 : C.char_star; <I>(* m3wrapargvar *)</I>
arg2 : C.int;
result : RECORD
<I> (*m3wrapretname m3wraprettype*)</I>
unixPath : TEXT;
<I> (*m3wrapoutname m3wrapouttype*)</I>
checksum : CARDINAL;
END;
BEGIN
TRY
arg1 := M3toC.SharedTtoS(str); <I>(* m3wrapinconv *)</I>
IF Text.Length(arg1) &gt; 10 THEN <I>(* m3wrapincheck *)</I>
RAISE E("str too long");
END;
<I> (* m3wrapretraw m3wrapargraw *)</I>
arg0 := MessyToUnix (arg1, arg2);
result.unixPath := M3toC.CopyStoT(arg0); <I>(* m3wrapretconv *)</I>
result.checksum := arg2; <I>(* m3wrapoutconv *)</I>
IF result.checksum = 0 THEN <I>(* m3wrapoutcheck *)</I>
RAISE E("invalid checksum");
END;
FINALLY
M3toC.FreeSharedS(str,arg1); <I>(* m3wrapfreearg *)</I>
END;
END Name;
</pre></div>
<H2><a name="Modula3_hints"></a>25.5 More hints to the generator</H2>
<H3><a name="Modula3_features"></a>25.5.1 Features</H3>
<table border summary="Modula-3 features">
<tr>
<th>Feature</th>
<th>Example</th>
<th>Description</th>
</tr>
<tr>
<td>multiretval</td>
<td><tt>%m3multiretval get_box;</tt> or
<tt>%feature("modula3:multiretval") get_box;</tt></td>
<td>Let the denoted function return a <tt>RECORD</tt>
rather than a plain value.
This <tt>RECORD</tt> contains all arguments with "out" direction
including the return value of the C function (if there is one).
If more than one argument is "out"
then the function <b>must</b> have the <tt>multiretval</tt> feature activated,
but it is explicitly requested from the user to prevent mistakes.</td>
</tr>
<tr>
<td>constnumeric</td>
<td><tt>%constnumeric(12) twelve;</tt> or
<tt>%feature("constnumeric","12") twelve;</tt></td>
<td>This feature can be used to tell Modula-3's back-end of SWIG
the value of an identifier.
This is necessary in the cases
where it was defined by a non-trivial C expression.
This feature is used by the
<tt>-generateconst</tt> <a href="#Modula3_commandline">option</a>.
In future it may be generalized to other kind of values
such as strings.
</td>
</tr>
</table>
<H3><a name="Modula3_pragmas"></a>25.5.2 Pragmas</H3>
<table border summary="Modula-3 pragmas">
<tr>
<th>Pragma</th>
<th>Example</th>
<th>Description</th>
</tr>
<tr>
<td>unsafe</td>
<td><tt>%pragma(modula3) unsafe="true";</tt></td>
<td>Mark the raw interface modules as <tt>UNSAFE</tt>.
This will be necessary in many cases.</td>
</tr>
<tr>
<td>library</td>
<td><tt>%pragma(modula3) library="m3fftw";</tt></td>
<td>Specifies the library name for the wrapper library to be created.
It should be distinct from the name of the library to be wrapped.</td>
</tr>
</table>
<H2><a name="Modula3_remarks"></a>25.6 Remarks</H2>
<ul>
<li>
The Modula-3 part of SWIG doesn't try to generate nicely formatted code.
If you need to read the generated code, use <tt>m3pp</tt> to postprocess the
Modula files.
</li>
</ul>
</body>
</html>

348
Doc/Manual/Modules.html Normal file
View file

@ -0,0 +1,348 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Working with Modules</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Modules"></a>15 Working with Modules</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Modules_introduction">Modules Introduction</a>
<li><a href="#Modules_nn1">Basics</a>
<li><a href="#Modules_nn2">The SWIG runtime code</a>
<li><a href="#Modules_external_run_time">External access to the runtime</a>
<li><a href="#Modules_nn4">A word of caution about static libraries</a>
<li><a href="#Modules_nn5">References</a>
<li><a href="#Modules_nn6">Reducing the wrapper file size</a>
</ul>
</div>
<!-- INDEX -->
<H2><a name="Modules_introduction"></a>15.1 Modules Introduction</H2>
<p>
Each invocation of SWIG requires a module name to be specified.
The module name is used to name the resulting target language extension module.
Exactly what this means and what the name is used for
depends on the target language, for example the name can define
a target language namespace or merely be a useful name for naming files or helper classes.
Essentially, a module comprises target language wrappers for a chosen collection of global variables/functions, structs/classes and other C/C++ types.
</p>
<p>
The module name can be supplied in one of two ways.
The first is to specify it with the special <tt>%module</tt>
directive. This directive must appear at the beginning of the interface file.
The general form of this directive is:
</p>
<div class="code"><pre>
<tt>%module(option1="value1",option2="value2",...) modulename</tt>
</pre></div>
<p>
where the modulename is mandatory and the options add one or more optional additional features.
Typically no options are specified, for example:
</p>
<div class="code"><pre>
<tt>%module mymodule</tt>
</pre></div>
<p>
The second way to specify the module name is with the <tt>-module</tt> command line option, for example <tt>-module mymodule</tt>.
If the module name is supplied on the command line, it overrides the name specified by the
<tt>%module</tt> directive.
</p>
<p>
When first working with SWIG, users commonly start by creating a
single module. That is, you might define a single SWIG interface that
wraps some set of C/C++ code. You then compile all of the generated
wrapper code together and use it. For large applications, however,
this approach is problematic---the size of the generated wrapper code
can be rather large. Moreover, it is probably easier to manage the
target language interface when it is broken up into smaller pieces.
</p>
<p>
This chapter describes the problem of using SWIG in programs
where you want to create a collection of modules.
Each module in the collection is created via separate invocations of SWIG.
</p>
<H2><a name="Modules_nn1"></a>15.2 Basics</H2>
<p>
The basic usage case with multiple modules is when modules do not have
cross-references (ie. when wrapping multiple independent C APIs). In that case,
swig input files should just work out of the box - you simply create multiple
wrapper .cxx files, link them into your application, and insert/load each in the
scripting language runtime as you would do for the single module case.
</p>
<p>
A bit more complex is the case in which modules need to share information.
For example, when one module extends the class of another by deriving from
it:
</p>
<div class="code"><pre>
// File: base.h
class base {
public:
int foo();
};
</pre></div>
&nbsp;
<div class="code"><pre>
// File: base_module.i
%module base_module
%{
#include "base.h"
%}
%include "base.h"
</pre></div>
&nbsp;
<div class="code"><pre>
// File: derived_module.i
%module derived_module
%import "base_module.i"
%inline %{
class derived : public base {
public:
int bar();
};
%}
</pre></div>
<p>To create the wrapper properly, module <tt>derived_module</tt> needs to know about the
<tt>base</tt> class and that its interface is covered in another module. The
line <tt>%import "base_module.i"</tt> lets SWIG know exactly that. Oftentimes
the <tt>.h</tt> file is passed to <tt>%import</tt> instead of the <tt>.i</tt>,
which unfortunately doesn't work for all language modules. For example, Python requires the
name of module that the base class exists in so that the proxy classes can fully inherit the
base class's methods. Typically you will get a warning when the module name is missing, eg:
</p>
<div class="shell"> <pre>
derived_module.i:8: Warning 401: Base class 'base' ignored - unknown module name for base. Either import
the appropriate module interface file or specify the name of the module in the %import directive.
</pre></div>
<p>
It is sometimes desirable to import the header file rather than the interface file and overcome
the above warning.
For example in the case of the imported interface being quite large, it may be desirable to
simplify matters and just import a small header file of dependent types.
This can be done by specifying the optional <tt>module</tt> attribute in the <tt>%import</tt> directive.
The <tt>derived_module.i</tt> file shown above could be replaced with the following:
<div class="code"><pre>
// File: derived_module.i
%module derived_module
%import(module="base_module") "base.h"
%inline %{
class derived : public base {
public:
int bar();
};
</pre></div>
<p>
Note that "base_module" is the module name and is the same as that specified in <tt>%module</tt>
in <tt>base_module.i</tt> as well as the <tt>%import</tt> in <tt>derived_module.i</tt>.
</p>
<p>
Another issue
to beware of is that multiple dependent wrappers should not be linked/loaded
in parallel from multiple threads as SWIG provides no locking - for more on that
issue, read on.
</p>
<H2><a name="Modules_nn2"></a>15.3 The SWIG runtime code</H2>
<p>
Many of SWIG's target languages generate a set of functions commonly known as
the "SWIG runtime." These functions are primarily related to the runtime type
system which checks pointer types and performs other tasks such as proper
casting of pointer values in C++. As a general rule, the statically typed target
languages, such as Java, use the language's built in static type checking and
have no need for a SWIG runtime. All the dynamically typed / interpreted
languages rely on the SWIG runtime.
</p>
<p>
The runtime functions are private to each SWIG-generated module. That is, the
runtime functions are declared with "static" linkage and are visible only to the
wrapper functions defined in that module. The only problem with this approach is
that when more than one SWIG module is used in the same application, those
modules often need to share type information. This is especially true for C++
programs where SWIG must collect and share information about inheritance
relationships that cross module boundaries.
</p>
<p>
To solve the problem of sharing information across modules, a pointer to the
type information is stored in a global variable in the target language
namespace. During module initialization, type information is loaded into the
global data structure of type information from all modules.
</p>
<p>
There are a few trade offs with this approach. This type information is global
across all SWIG modules loaded, and can cause type conflicts between modules
that were not designed to work together. To solve this approach, the SWIG
runtime code uses a define SWIG_TYPE_TABLE to provide a unique type table. This
behavior can be enabled when compiling the generated _wrap.cxx or _wrap.c file
by adding -DSWIG_TYPE_TABLE=myprojectname to the command line argument.
</p>
<p>
Then, only modules compiled with SWIG_TYPE_TABLE set to myprojectname will share
type information. So if your project has three modules, all three should be
compiled with -DSWIG_TYPE_TABLE=myprojectname, and then these three modules will
share type information. But any other project's types will not interfere or
clash with the types in your module.
</p>
<p>
Another issue relating to the global type table is thread safety. If two modules
try and load at the same time, the type information can become corrupt. SWIG
currently does not provide any locking, and if you use threads, you must make
sure that modules are loaded serially. Be careful if you use threads and the
automatic module loading that some scripting languages provide. One solution is
to load all modules before spawning any threads, or use SWIG_TYPE_TABLE to
separate type tables so they do not clash with each other.
</p>
<p>
Lastly, SWIG uses a #define SWIG_RUNTIME_VERSION, located in Lib/swigrun.swg and
near the top of every generated module. This number gets incremented when the
data structures change, so that SWIG modules generated with different versions
can peacefully coexist. So the type structures are separated by the
(SWIG_TYPE_TABLE, SWIG_RUNTIME_VERSION) pair, where by default SWIG_TYPE_TABLE
is empty. Only modules compiled with the same pair will share type information.
</p>
<H2><a name="Modules_external_run_time"></a>15.4 External access to the runtime</H2>
<p>As described in <a href="Typemaps.html#Typemaps_runtime_type_checker">The run-time type checker</a>,
the functions <tt>SWIG_TypeQuery</tt>, <tt>SWIG_NewPointerObj</tt>, and others sometimes need
to be called. Calling these functions from a typemap is supported, since the typemap code
is embedded into the <tt>_wrap.c</tt> file, which has those declarations available. If you need
to call the SWIG run-time functions from another C file, there is one header you need
to include. To generate the header that needs to be included, run the following command:
<div class="shell"><pre>
$ swig -python -external-runtime &lt;filename&gt;
</pre></div>
<p>The filename argument is optional and if it is not passed, then the default filename will
be something like <tt>swigpyrun.h</tt>, depending on the language. This header file should
be treated like any of the other _wrap.c output files, and should be regenerated when the
_wrap files are. After including this header, your code will be able to call <tt>SWIG_TypeQuery</tt>,
<tt>SWIG_NewPointerObj</tt>, <tt>SWIG_ConvertPtr</tt> and others. The exact argument parameters
for these functions might differ between language modules; please check the language module chapters
for more information.</p>
<p>Inside this header the functions are declared static and are included inline into the file,
and thus the file does not need to be linked against any SWIG libraries or code (you might still
need to link against the language libraries like libpython-2.3). Data is shared between this
file and the _wrap.c files through a global variable in the scripting language. It is also
possible to copy this header file along with the generated wrapper files into your own package,
so that you can distribute a package that can be compiled without SWIG installed (this works
because the header file is self-contained, and does not need to link with anything).</p>
<p>
This header will also use the -DSWIG_TYPE_TABLE described above, so when
compiling any code which includes the generated header file should define the
SWIG_TYPE_TABLE to be the same as the module whose types you are trying to
access.
</p>
<H2><a name="Modules_nn4"></a>15.5 A word of caution about static libraries</H2>
<p>
When working with multiple SWIG modules, you should take care not to use static
libraries. For example, if you have a static library <tt>libfoo.a</tt> and you link a collection
of SWIG modules with that library, each module will get its own private copy of the library code inserted
into it. This is very often <b>NOT</b> what you want and it can lead to unexpected or bizarre program
behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libraries.
</p>
<H2><a name="Modules_nn5"></a>15.6 References</H2>
<p>
Due to the complexity of working with shared libraries and multiple modules, it might be a good idea to consult
an outside reference. John Levine's "Linkers and Loaders" is highly recommended.
</p>
<H2><a name="Modules_nn6"></a>15.7 Reducing the wrapper file size</H2>
<p>
Using multiple modules with the <tt>%import</tt> directive is the most common approach to modularising large projects.
In this way a number of different wrapper files can be generated, thereby avoiding the generation of a single large wrapper file.
There are a couple of alternative solutions for reducing the size of a wrapper file through the use of command line options and features.
</p>
<p>
<b>-fcompact</b><br>
This command line option will compact the size of the wrapper file without changing the code generated into the wrapper file.
It simply removes blank lines and joins lines of code together.
This is useful for compilers that have a maximum file size that can be handled.
</p>
<p>
<b>-fvirtual</b><br>
This command line option will remove the generation of superfluous virtual method wrappers.
Consider the following inheritance hierarchy:
</p>
<div class="code">
<pre>
struct Base {
virtual void method();
...
};
struct Derived : Base {
virtual void method();
...
};
</pre>
</div>
<p>
Normally wrappers are generated for both methods, whereas this command line option will suppress the generation of a wrapper for <tt>Derived::method</tt>.
Normal polymorphic behaviour remains as <tt>Derived::method</tt> will still be called should you have
a <tt>Derived</tt> instance and call the wrapper for <tt>Base::method</tt>.
</p>
<p>
<b>%feature("compactdefaultargs")</b><br>
This feature can reduce the number of wrapper methods when wrapping methods with default arguments. The section on <a href="SWIGPlus.html#SWIGPlus_default_args">default arguments</a> discusses the feature and its limitations.
</p>
</body>
</html>

71
Doc/Manual/Mzscheme.html Normal file
View file

@ -0,0 +1,71 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Hand-written HTML -->
<html>
<head>
<title>SWIG and MzScheme</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Mzscheme"></a>26 SWIG and MzScheme</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#MzScheme_nn2">Creating native MzScheme structures</a>
</ul>
</div>
<!-- INDEX -->
<p>
This section contains information on SWIG's support of MzScheme.
<H2><a name="MzScheme_nn2"></a>26.1 Creating native MzScheme structures</H2>
<p>
Example interface file:
</p>
<div class="code">
<pre>
/* define a macro for the struct creation */
%define handle_ptr(TYPE,NAME)
%typemap(argout) TYPE *NAME{
Scheme_Object *o = SWIG_NewStructFromPtr($1, $*1_mangle);
SWIG_APPEND_VALUE(o);
}
%typemap(in,numinputs=0) TYPE *NAME (TYPE temp) {
$1 = &amp;temp;
}
%enddef
/* setup the typemaps for the pointer to an output parameter cntrs */
handle_ptr(struct diag_cntrs, cntrs);
</pre>
</div>
<p>
Then in scheme, you can use regular struct access procedures like
</p>
<div class="code">
<pre>
; suppose a function created a struct foo as
; (define foo (make-diag-cntrs (#x1 #x2 #x3) (make-inspector))
; Then you can do
(format "0x~x" (diag-cntrs-field1 foo))
(format "0x~x" (diag-cntrs-field2 foo))
;etc...
</pre>
</div>
<p>
That's pretty much it. It works with nested structs as well.
</p>
</body>
</html>

991
Doc/Manual/Ocaml.html Normal file
View file

@ -0,0 +1,991 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Ocaml</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<a name="n1"></a>
<H1><a name="Ocaml"></a>27 SWIG and Ocaml</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Ocaml_nn2">Preliminaries</a>
<ul>
<li><a href="#Ocaml_nn3">Running SWIG</a>
<li><a href="#Ocaml_nn4">Compiling the code</a>
<li><a href="#Ocaml_nn5">The camlp4 module</a>
<li><a href="#Ocaml_nn6">Using your module</a>
<li><a href="#Ocaml_nn7">Compilation problems and compiling with C++</a>
</ul>
<li><a href="#Ocaml_nn8">The low-level Ocaml/C interface</a>
<ul>
<li><a href="#Ocaml_nn9">The generated module</a>
<li><a href="#Ocaml_nn10">Enums</a>
<ul>
<li><a href="#Ocaml_nn11">Enum typing in Ocaml</a>
</ul>
<li><a href="#Ocaml_nn12">Arrays</a>
<ul>
<li><a href="#Ocaml_nn13">Simple types of bounded arrays</a>
<li><a href="#Ocaml_nn14">Complex and unbounded arrays</a>
<li><a href="#Ocaml_nn15">Using an object</a>
<li><a href="#Ocaml_nn16">Example typemap for a function taking float * and int</a>
</ul>
<li><a href="#Ocaml_nn17">C++ Classes</a>
<ul>
<li><a href="#Ocaml_nn18">STL vector and string Example</a>
<li><a href="#Ocaml_nn19">C++ Class Example</a>
<li><a href="#Ocaml_nn20">Compiling the example</a>
<li><a href="#Ocaml_nn21">Sample Session</a>
</ul>
<li><a href="#Ocaml_nn22">Director Classes</a>
<ul>
<li><a href="#Ocaml_nn23">Director Introduction</a>
<li><a href="#Ocaml_nn24">Overriding Methods in Ocaml</a>
<li><a href="#Ocaml_nn25">Director Usage Example</a>
<li><a href="#Ocaml_nn26">Creating director objects</a>
<li><a href="#Ocaml_nn27">Typemaps for directors, <tt>directorin, directorout, directorargout</tt></a>
<li><a href="#Ocaml_nn28"><tt>directorin</tt> typemap</a>
<li><a href="#Ocaml_nn29"><tt>directorout</tt> typemap</a>
<li><a href="#Ocaml_nn30"><tt>directorargout</tt> typemap</a>
</ul>
<li><a href="#Ocaml_nn31">Exceptions</a>
</ul>
</ul>
</div>
<!-- INDEX -->
<p>
This chapter describes SWIG's
support of Ocaml. Ocaml is a relatively recent addition to the ML family,
and is a recent addition to SWIG. It's the second compiled, typed
language to be added. Ocaml has widely acknowledged benefits for engineers,
mostly derived from a sophisticated type system, compile-time checking
which eliminates several classes of common programming errors, and good
native performance. While all of this is wonderful, there are well-written
C and C++ libraries that Ocaml users will want to take advantage of as
part of their arsenal (such as SSL and gdbm), as well as their own mature
C and C++ code. SWIG allows this code to be used in a natural, type-safe
way with Ocaml, by providing the necessary, but repetitive glue code
which creates and uses Ocaml values to communicate with C and C++ code.
In addition, SWIG also produces the needed Ocaml source that binds
variants, functions, classes, etc.
</p>
<p>
If you're not familiar with the Objective Caml language, you can visit
<a href="http://www.ocaml.org/">The Ocaml Website</a>.
</p>
<H2><a name="Ocaml_nn2"></a>27.1 Preliminaries</H2>
<p>
SWIG 1.3 works with Ocaml 3.04 and above. Given the choice,
you should use the latest stable release. The SWIG Ocaml module has
been tested on Linux (x86,PPC,Sparc) and Cygwin on Windows. The
best way to determine whether your system will work is to compile the
examples and test-suite which come with SWIG. You can do this by running
<tt>make check</tt> from the SWIG root directory after installing SWIG.
The Ocaml module has been tested using the system's dynamic linking (the
usual -lxxx against libxxx.so, as well as with Gerd Stolpmann's
<a
href="http://www.ocaml-programming.de/packages/documentation/dl/">Dl package
</a>. The ocaml_dynamic and ocaml_dynamic_cpp targets in the
file Examples/Makefile illustrate how to compile and link SWIG modules that
will be loaded dynamically. This has only been tested on Linux so far.
</p>
<H3><a name="Ocaml_nn3"></a>27.1.1 Running SWIG</H3>
<p>
The basics of getting a SWIG Ocaml module up and running
can be seen from one of SWIG's example Makefiles, but is also described
here. To build an Ocaml module, run SWIG using the <tt>-ocaml</tt>
option.
</p>
<div class="code">
<pre>
%swig -ocaml example.i
</pre>
</div>
<p> This will produce 3 files. The file <tt>example_wrap.c</tt> contains
all of the C code needed to build an Ocaml module. To build the module,
you will compile the file <tt>example_wrap.c</tt> with <tt>ocamlc</tt> or
<tt>ocamlopt</tt> to create the needed .o file. You will need to compile
the resulting .ml and .mli files as well, and do the final link with -custom
(not needed for native link). </p>
<H3><a name="Ocaml_nn4"></a>27.1.2 Compiling the code</H3>
<p>
The O'Caml SWIG module now requires you to compile a module (<tt>Swig</tt>)
separately. In addition to aggregating common SWIG functionality, the Swig
module contains the data structure that represents C/C++ values. This allows
easier data sharing between modules if two or more are combined, because
the type of each SWIG'ed module's c_obj is derived from Swig.c_obj_t. This
also allows SWIG to acquire new conversions painlessly, as well as giving
the user more freedom with respect to custom typing.
Use <tt>ocamlc</tt> or <tt>ocamlopt</tt> to compile your
SWIG interface like:
</p>
<div class="code">
<pre>
% swig -ocaml -co swig.mli ; swig -ocaml co swig.ml
% ocamlc -c swig.mli ; ocamlc -c swig.ml
% ocamlc -c -ccopt "-I/usr/include/foo" example_wrap.c
% ocamlc -c example.mli
% ocamlc -c example.ml
</pre>
</div>
<p> <tt>ocamlc</tt> is aware of .c files and knows how to handle them. Unfortunately,
it does not know about .cxx, .cc, or .cpp files, so when SWIG is invoked
in C++ mode, you must: </p>
<div class="code">
<pre>
% cp example_wrap.cxx example_wrap.cxx.c<br>% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c<br>% ...<br>
</pre>
</div>
<H3><a name="Ocaml_nn5"></a>27.1.3 The camlp4 module</H3>
<p>
The camlp4 module (swigp4.ml -&gt; swigp4.cmo) contains a simple rewriter which
makes C++ code blend more seamlessly with objective caml code. It's use is
optional, but encouraged. The source file is included in the Lib/ocaml
directory of the SWIG source distribution. You can checkout this file with
<tt>"swig -ocaml -co swigp4.ml"</tt>. You should compile the file with
<tt>"ocamlc -I `camlp4 -where` -pp 'camlp4o pa_extend.cmo q_MLast.cmo' -c swigp4.ml"</tt>
</p>
<p>
The basic principle of the module is to recognize certain non-caml expressions
and convert them for use with C++ code as interfaced by SWIG. The camlp4
module is written to work with generated SWIG interfaces, and probably isn't
great to use with anything else.
</p>
<p>
Here are the main rewriting rules:
</p>
<table border="1" summary="Rewriting rules">
<tr><th>Input</th><th>Rewritten to</th></tr>
<tr><td>f'( ... ) as in<br> atoi'("0") or<br> _exit'(0)</td>
<td>f(C_list [ ... ]) as in<br> atoi (C_list [ C_string "0" ]) or<br> _exit (C_list [ C_int 0 ])</td></tr>
<tr><td>object -&gt; method ( ... )</td><td>(invoke object) "method" (C_list [ ... ])</td></tr>
<tr><td>
object <i>'binop</i> argument as in<br>
a '+= b</td>
<td>
(invoke object) "+=" argument as in<br>
(invoke a) "+=" b<td></tr>
<tr><th colspan=2>Note that because camlp4 always recognizes &lt;&lt;
and &gt;&gt;, they are replaced by lsl and lsr in operator names.
<tr><td>
<i>'unop</i> object as in<br>
'! a
</td><td>
(invoke a) "!" C_void</td></tr>
<tr><td>
<b>Smart pointer access like this</b><br>
object '-&gt; method ( args )<br>
</td><td>
(invoke (invoke object "-&gt;" C_void))
</td></tr>
<tr><td>
<b>Invoke syntax</b><br>
object . '( ... )
</td><td>
(invoke object) "()" (C_list [ ... ])
</td></tr>
<tr><td>
<b>Array syntax</b><br>
object '[ 10 ]
</td><td>
(invoke object) "[]" (C_int 10)
</td></tr>
<tr><td>
<b>Assignment syntax</b><br>
let a = '10 and b = '"foo" and c = '1.0 and d = 'true
</td><td>
let a = C_int 10 and b = C_string "foo" and c = C_double 1.0 and d = C_bool true
</td></tr>
<tr><td>
<b>Cast syntax</b><br>
let a = _atoi '("2") as int<br>
let b = (getenv "PATH") to string<br>
This works for int, string, float, bool
</td><td>
let a = get_int (_atoi (C_string "2"))<br>
let b = C_string (getenv "PATH")
</td></tr>
</table>
<H3><a name="Ocaml_nn6"></a>27.1.4 Using your module</H3>
<p>
You can test-drive your module by building a
toplevel ocaml interpreter. Consult the ocaml manual for details.
</p>
<p>
When linking any ocaml bytecode with your module, use the -custom
option to build your functions into the primitive list. This
option is not needed when you build native code.
</p>
<H3><a name="Ocaml_nn7"></a>27.1.5 Compilation problems and compiling with C++</H3>
<p>
As mentioned above, .cxx files need special
handling to be compiled with <tt>ocamlc</tt>. Other than that, C code
that uses <tt>class</tt> as a non-keyword, and C code that is too
liberal with pointer types may not compile under the C++ compiler.
Most code meant to be compiled as C++ will not have problems.
</p>
<H2><a name="Ocaml_nn8"></a>27.2 The low-level Ocaml/C interface</H2>
<p>
In order to provide access to overloaded functions, and
provide sensible outputs from them, all C entities are represented as
members of the c_obj type:
</p>
<p>
In the code as seen by the typemap
writer, there is a value, swig_result, that always contains the
current return data. It is a list, and must be appended with the
caml_list_append function, or with functions and macros provided by
objective caml.<br>
</p>
<div class="code"><pre>
type c_obj =
C_void
| C_bool of bool
| C_char of char
| C_uchar of char
| C_short of int
| C_ushort of int
| C_int of int
| C_uint of int32
| C_int32 of int32
| C_int64 of int64
| C_float of float
| C_double of float
| C_ptr of int64 * int64
| C_array of c_obj array
| C_list of c_obj list
| C_obj of (string -&gt; c_obj -&gt; c_obj)
| C_string of string
| C_enum of c_enum_t
</pre></div>
<p>
A few functions exist which generate and return these:
</p>
<ul>
<li>caml_ptr_val receives a c_obj and returns a void *. &nbsp;This
should be used for all pointer purposes.</li>
<li>caml_long_val receives a c_obj and returns a long. &nbsp;This
should be used for most integral purposes.<br>
</li>
<li>caml_val_ptr receives a void * and returns a c_obj.</li>
<li>caml_val_bool receives a C int and returns a c_obj representing
it's bool value.</li>
<li>caml_val_(u)?(char|short|int|long|float|double) receives an
appropriate C value and returns a c_obj representing it.</li>
<li>caml_val_string receives a char * and returns a string value.</li>
<li>caml_val_string_len receives a char * and a length and returns
a string value.</li>
<li>caml_val_obj receives a void * and an object type and returns
a C_obj, which contains a closure giving method access.</li>
</ul>
<p>
Because of this style, a typemap can return any kind of value it
wants from a function. &nbsp;This enables out typemaps and inout typemaps
to work well. &nbsp;The one thing to remember about outputting values
is that you must append them to the return list with swig_result = caml_list_append(swig_result,v).
</p>
<p>
&nbsp;This function will return a new list that has your element
appended. Upon return to caml space, the fnhelper function
beautifies the result. A list containing a single item degrades to
only that item (i.e. [ C_int 3 ] -&gt; C_int 3), and a list
containing more than one item is wrapped in C_list (i.e. [ C_char
'a' ; C_char 'b' -&gt; C_list [ C_char 'a' ; C_char b
]). &nbsp;This is in order to make return values easier to handle
when functions have only one return value, such as constructors,
and operators. &nbsp;In addition, string, pointer, and object
values are interchangeable with respect to caml_ptr_val, so you can
allocate memory as caml strings and still use the resulting
pointers for C purposes, even using them to construct simple objects
on. Note, though, that foreign C++ code does not respect the garbage
collector, although the SWIG interface does.</p>
<p>
The wild card type that you can use in lots of different ways is
C_obj. It allows you to wrap any type of thing you like as an
object using the same mechanism that the ocaml module
does. &nbsp;When evaluated in caml_ptr_val, the returned value is
the result of a call to the object's "&amp;" operator, taken as a pointer.
</p>
<p>
You should only construct values using objective caml, or using the
functions caml_val_* functions provided as static functions to a SWIG
ocaml module, as well as the caml_list_* functions. These functions
provide everything a typemap needs to produce values. In addition,
value items pass through directly, but you must make your own type
signature for a function that uses value in this way.
</p>
<H3><a name="Ocaml_nn9"></a>27.2.1 The generated module</H3>
<p>
The SWIG <tt>%module</tt> directive specifies the name of the Ocaml
module to be generated. If you specified `<tt>%module example</tt>',
then your Ocaml code will be accessible in the module Example. The
module name is always capitalized as is the ocaml convention. Note
that you must not use any Ocaml keyword to name your module. Remember
that the keywords are not the same as the C++ ones.
</p>
<p>
You can introduce extra code into the output wherever you like with SWIG.
These are the places you can introduce code:
<table border="1" summary="Extra code sections">
<tr><td>"header"</td><td>This code is inserted near the beginning of the
C wrapper file, before any function definitions.</td></tr>
<tr><td>"wrapper"</td><td>This code is inserted in the function definition
section.</td></tr>
<tr><td>"runtime"</td><td>This code is inserted near the end of the C wrapper
file.</td></tr>
<tr><td>"mli"</td><td>This code is inserted into the caml interface file.
Special signatures should be inserted here.
</td></tr>
<tr><td>"ml"</td><td>This code is inserted in the caml code defining the
interface to your C code. Special caml code, as well as any initialization
which should run when the module is loaded may be inserted here.
</td></tr>
<tr><td>"classtemplate"</td><td>The "classtemplate" place is special because
it describes the output SWIG will generate for class definitions.
</td></tr>
</table>
<H3><a name="Ocaml_nn10"></a>27.2.2 Enums</H3>
<p>
SWIG will wrap enumerations as polymorphic variants in the output
Ocaml code, as above in C_enum.&nbsp; In order to support all
C++-style uses of enums, the function int_to_enum and enum_to_int are
provided for ocaml code to produce and consume these values as
integers. &nbsp;Other than that, correct uses of enums will not have
a problem. &nbsp;Since enum labels may overlap between enums, the
enum_to_int and int_to_enum functions take an enum type label as an
argument. Example:
</p>
<div class="code"><pre>
%module enum_test
%{
enum c_enum_type { a = 1, b, c = 4, d = 8 };
%}
enum c_enum_type { a = 1, b, c = 4, d = 8 };
</pre></div>
<p>
The output mli contains:
</p>
<div class="code"><pre>
type c_enum_type = [
`unknown
| `c_enum_type
]
type c_enum_tag = [
`int of int
| `a
| `b
| `c
| `d
]
val int_to_enum c_enum_type -&gt; int -&gt; c_obj
val enum_to_int c_enum_type -&gt; c_obj -&gt; c_obj
</pre>
</div>
<p>
So it's possible to do this:
</p>
<div class="code">
<pre>
bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top
bash-2.05a$ ./enum_test_top
Objective Caml version 3.04
# open Enum_test ;;
# let x = C_enum `a ;;
val x : Enum_test.c_obj = C_enum `a
# enum_to_int `c_enum_type x ;;
- : Enum_test.c_obj = C_int 1
# int_to_enum `c_enum_type 4 ;;
- : Enum_test.c_obj = C_enum `c
</pre>
</div>
<H4><a name="Ocaml_nn11"></a>27.2.2.1 Enum typing in Ocaml</H4>
<p>
The ocaml SWIG module now has support for loading and using multiple SWIG
modules at the same time. This enhances modularity, but presents problems
when used with a language which assumes that each module's types are complete
at compile time. In order to achieve total soundness enum types are now
isolated per-module. The type issue matters when values are shared between
functions imported from different modules. You must convert values to master
values using the swig_val function before sharing them with another module.
</p>
<H3><a name="Ocaml_nn12"></a>27.2.3 Arrays</H3>
<H4><a name="Ocaml_nn13"></a>27.2.3.1 Simple types of bounded arrays</H4>
<p>
SWIG has support for array types, but you generally will need to provide
a typemap to handle them. You can currently roll your own, or expand
some of the macros provided (but not included by default) with the SWIG
distribution.
</p>
<p>
By including "carray.i", you will get access to some macros that help you
create typemaps for array types fairly easily.
</p>
<p>
<tt>%make_simple_array_typemap</tt> is the easiest way to get access to
arrays of simple types with known bounds in your code, but this only works
for arrays whose bounds are completely specified.
</p>
<H4><a name="Ocaml_nn14"></a>27.2.3.2 Complex and unbounded arrays</H4>
<p>
Unfortunately, unbounded arrays and pointers can't be handled in a
completely general way by SWIG, because the end-condition of such an
array can't be predicted. In some cases, it will be by consent
(e.g. an array of four or more chars), sometimes by explicit length
(char *buffer, int len), and sometimes by sentinel value (0,-1,etc.).
SWIG can't predict which of these methods will be used in the array,
so you have to specify it for yourself in the form of a typemap.
</p>
<H4><a name="Ocaml_nn15"></a>27.2.3.3 Using an object</H4>
<p>
It's possible to use C++ to your advantage by creating a simple object that
provides access to your array. This may be more desirable in some cases,
since the object can provide bounds checking, etc., that prevents crashes.
</p>
<p>
Consider writing an object when the ending condition of your array is complex,
such as using a required sentinel, etc.
</p>
<H4><a name="Ocaml_nn16"></a>27.2.3.4 Example typemap for a function taking float * and int</H4>
<p>
This is a simple example <tt>in</tt> typemap for an array of float, where the
length of the array is specified as an extra parameter. Other such typemaps
will work similarly. In the example, the function printfloats is called with
a float array, and specified length. The actual length reported in the len
argument is the length of the array passed from ocaml, making passing an array
into this type of function convenient.
</p>
<table border="1" bgcolor="#dddddd" summary="float * and int typemap example">
<tr><th><center>tarray.i</center></th></tr>
<tr><td><pre>
%module tarray
%{
#include &lt;stdio.h&gt;
void printfloats( float *tab, int len ) {
int i;
for( i = 0; i &lt; len; i++ ) {
printf( "%f ", tab[i] );
}
printf( "\n" );
}
%}
%typemap(in) (float *tab, int len) {
int i;
/* $*1_type */
$2 = caml_array_len($input);
$1 = ($*1_type *)malloc( $2 * sizeof( float ) );
for( i = 0; i &lt; $2; i++ ) {
$1[i] = caml_double_val(caml_array_nth($input,i));
}
}
void printfloats( float *tab, int len );
</pre></td></tr>
<tr><th>Sample Run</th></tr>
<tr><td><pre>
# open Tarray ;;
# _printfloats (C_array [| C_double 1.0 ; C_double 3.0 ; C_double 5.6666 |]) ;;
1.000000 3.000000 5.666600
- : Tarray.c_obj = C_void
</pre></td></tr></table>
<H3><a name="Ocaml_nn17"></a>27.2.4 C++ Classes</H3>
<p>
C++ classes, along with structs and unions are represented by C_obj
(string -&gt; c_obj -&gt; c_obj) wrapped closures. &nbsp;These objects
contain a method list, and a type, which allow them to be used like
C++ objects. When passed into typemaps that use pointers, they
degrade to pointers through their "&amp;" method. &nbsp;Every method
an object has is represented as a string in the object's method table,
and each method table exists in memory only once. &nbsp;In addition
to any other operators an object might have, certain builtin ones are
provided by SWIG: (all of these take no arguments (C_void))
</p>
<table summary="SWIG provided operators">
<tr><td>"~"</td><td>Delete this object</td></tr>
<tr><td>"&amp;"</td><td>Return an ordinary C_ptr value representing this
object's address</td></tr>
<tr><td>"sizeof"</td><td>If enabled with ("sizeof"="1") on the module node,
return the object's size in char.</td></tr>
<tr><td>":methods"</td><td>Returns a list of strings containing the names of
the methods this object contains</td></tr>
<tr><td>":classof"</td><td>Returns the name of the class this object belongs
to.</td></tr>
<tr><td>":parents"</td><td>Returns a list of all direct parent classes which
have been wrapped by SWIG.</td></tr>
<tr><td>"::[parent-class]"</td><td>Returns a view of the object as the
indicated parent class. This is mainly used internally by the SWIG module,
but may be useful to client programs.</td></tr>
<tr><td>"[member-variable]"</td><td>Each member variable is wrapped as a
method with an optional parameter.
Called with one argument, the member variable is set to the value of the
argument. With zero arguments, the value is returned.
</td></tr>
</table>
<p>
Note that this string belongs to the wrapper object, and not
the underlying pointer, so using create_[x]_from_ptr alters the
returned value for the same object.
</p>
<H4><a name="Ocaml_nn18"></a>27.2.4.1 STL vector and string Example</H4>
<p>
Standard typemaps are now provided for STL vector and string. More are in
the works. STL strings are passed just like normal strings, and returned
as strings. STL string references don't mutate the original string, (which
might be surprising), because Ocaml strings are mutable but have fixed
length. Instead, use multiple returns, as in the argout_ref example.
</p>
<table border="1" bgcolor="#dddddd" summary="STL vector and string example">
<tr><th><center>example.i</center></th></tr>
<tr><td><pre>
%module example
%{
#include "example.h"
%}
%include &lt;stl.i&gt;
namespace std {
%template(StringVector) std::vector &lt; string &gt;;
};
%include "example.h"
</pre></td></tr>
<tr><td><font size="-1"><i>This example is in Examples/ocaml/stl
</i></font></td></tr>
</table>
<p>
Since there's a makefile in that directory, the example is easy to build.
</p>
<p>
Here's a sample transcript of an interactive session using a string vector
after making a toplevel (make toplevel). This example uses the camlp4
module.
</p>
<div class="code"><pre>
bash-2.05a$ ./example_top
Objective Caml version 3.06
Camlp4 Parsing version 3.06
# open Swig ;;
# open Example ;;
# let x = new_StringVector '() ;;
val x : Example.c_obj = C_obj &lt;fun&gt;
# x -&gt; ":methods" () ;;
- : Example.c_obj =
C_list
[C_string "nop"; C_string "size"; C_string "empty"; C_string "clear";
C_string "push_back"; C_string "[]"; C_string "="; C_string "set";
C_string "~"; C_string "&amp;"; C_string ":parents"; C_string ":classof";
C_string ":methods"]
# x -&gt; push_back ("foo") ;;
- : Example.c_obj = C_void
# x -&gt; push_back ("bar") ;;
- : Example.c_obj = C_void
# x -&gt; push_back ("baz") ;;
- : Example.c_obj = C_void
# x '[1] ;;
- : Example.c_obj = C_string "bar"
# x -&gt; set (1,"spam") ;;
- : Example.c_obj = C_void
# x '[1] ;;
- : Example.c_obj = C_string "spam"
# for i = 0 to (x -&gt; size() as int) - 1 do
print_endline ((x '[i to int]) as string)
done ;;
foo
bar
baz
- : unit = ()
#
</pre></div>
<H4><a name="Ocaml_nn19"></a>27.2.4.2 C++ Class Example</H4>
<p>
Here's a simple example using Trolltech's Qt Library:
</p>
<table border="1" bgcolor="#dddddd" summary="Qt Library example">
<tr><th><center>qt.i</center></th></tr>
<tr><td><pre>
%module qt
%{
#include &lt;qapplication.h&gt;
#include &lt;qpushbutton.h&gt;
%}
class QApplication {
public:
QApplication( int argc, char **argv );
void setMainWidget( QWidget *widget );
void exec();
};
class QPushButton {
public:
QPushButton( char *str, QWidget *w );
void resize( int x, int y );
void show();
};
</pre></td></tr></table>
<H4><a name="Ocaml_nn20"></a>27.2.4.3 Compiling the example</H4>
<div class="code"><pre>
bash-2.05a$ QTPATH=/your/qt/path
bash-2.05a$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done
bash-2.05a$ ocamlc -c swig.mli ; ocamlc -c swig.ml
bash-2.05a$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
bash-2.05a$ swig -ocaml -c++ -I$QTPATH/include qt.i
bash-2.05a$ mv qt_wrap.cxx qt_wrap.c
bash-2.05a$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c
bash-2.05a$ ocamlc -c qt.mli
bash-2.05a$ ocamlc -c qt.ml
bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
camlp4o.cma swigp4.cmo qt_wrap.o qt.cmo -o qt_top -cclib \
-L$QTPATH/lib -cclib -lqt
</pre></div>
<H4><a name="Ocaml_nn21"></a>27.2.4.4 Sample Session</H4>
<div class="code"><pre>
bash-2.05a$ ./qt_top
Objective Caml version 3.06
Camlp4 Parsing version 3.06
# open Swig ;;
# open Qt ;;
# let a = new_QApplication '(0,0) ;;
val a : Qt.c_obj = C_obj &lt;fun&gt;
# let hello = new_QPushButton '("hi",0) ;;
val hello : Qt.c_obj = C_obj &lt;fun&gt;
# hello -&gt; resize (100,30) ;;
- : Qt.c_obj = C_void
# hello -&gt; show () ;;
- : Qt.c_obj = C_void
# a -&gt; exec () ;;
</pre></div>
<p>
Assuming you have a working installation of QT, you will see a window
containing the string "hi" in a button.
</p>
<H3><a name="Ocaml_nn22"></a>27.2.5 Director Classes</H3>
<H4><a name="Ocaml_nn23"></a>27.2.5.1 Director Introduction</H4>
<p>
Director classes are classes which allow Ocaml code to override the public
methods of a C++ object. This facility allows the user to use C++ libraries
that require a derived class to provide application specific functionality in
the context of an application or utility framework.
</p>
<p>
You can turn on director classes by using an optional module argument like
this:
</p>
<div class="code"><pre>
%module(directors="1")
...
// Turn on the director class for a specific class like this:
%feature("director")
class foo {
...
};
</pre></div>
<H4><a name="Ocaml_nn24"></a>27.2.5.2 Overriding Methods in Ocaml</H4>
<p>
Because the Ocaml language module treats C++ method calls as calls to a
certain function, all you need to do is to define the function that will
handle the method calls in terms of the public methods of the object, and
any other relevant information. The function <tt>new_derived_object</tt>
uses a stub class to call your methods in place of the ones provided by the
underlying implementation. The object you receive is the underlying object,
so you are free to call any methods you want from within your derived method.
Note that calls to the underlying object do not invoke Ocaml code. You need
to handle that yourself.
</p>
<p>
<tt>new_derived_object</tt> receives your function, the function that creates
the underlying object, and any constructor arguments, and provides an
object that you can use in any usual way. When C++ code calls one of the
object's methods, the object invokes the Ocaml function as if it had been
invoked from Ocaml, allowing any method definitions to override the C++ ones.
</p>
<p>
In this example, I'll examine the objective caml code involved in providing
an overloaded class. This example is contained in Examples/ocaml/shapes.
</p>
<H4><a name="Ocaml_nn25"></a>27.2.5.3 Director Usage Example</H4>
<table border="1" bgcolor="#dddddd" summary="Director usage example">
<tr><th><center>example_prog.ml</center>
</th></tr>
<tr><td><pre>
open Swig
open Example
...
let triangle_class pts ob meth args =
match meth with
"cover" -&gt;
(match args with
C_list [ x_arg ; y_arg ] -&gt;
let xa = x_arg as float
and ya = y_arg as float in
(point_in_triangle pts xa ya) to bool
| _ -&gt; raise (Failure "cover needs two double arguments."))
| _ -&gt; (invoke ob) meth args ;;
let triangle =
new_derived_object
new_shape
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
'() ;;
let _ = _draw_shape_coverage '(triangle, C_int 60, C_int 20) ;;
</pre></td></tr>
</table>
<p>
This is the meat of what you need to do. The actual "class" definition
containing the overloaded method is defined in the function triangle_class.
This is a lot like the class definitions emitted by SWIG, if you look at
example.ml, which is generated when SWIG consumes example.i. Basically,
you are given the arguments as a c_obj and the method name as a string, and
you must intercept the method you are interested in and provide whatever
return value you need. Bear in mind that the underlying C++ code needs the
right return type, or an exception will be thrown. This exception will
generally be Failure, or NotObject. You must call other ocaml methods that
you rely on yourself. Due to the way directors are implemented, method
calls on your object from with ocaml code will always invoke C++ methods
even if they are overridden in ocaml.
</p>
<p>
In the example, the draw_shape_coverage function plots the indicated number
of points as either covered (<tt>x</tt>) or uncovered ( ) between
0 and 1 on the X and Y axes. Your shape implementation can provide any
coverage map it likes, as long as it responds to the "cover" method call
with a boolean return (the underlying method returns bool). This might allow
a tricky shape implementation, such as a boolean combination, to be expressed
in a more effortless style in ocaml, while leaving the "engine" part of the
program in C++.
</p>
<H4><a name="Ocaml_nn26"></a>27.2.5.4 Creating director objects</H4>
<p>
The definition of the actual object triangle can be described this way:
</p>
<div class="code"><pre>
let triangle =
new_derived_object
new_shape
(triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
'()
</pre></div>
<p>
The first argument to <tt>new_derived_object</tt>, new_shape is the method
which returns a shape instance. This function will be invoked with the
third argument will be appended to the argument list [ C_void ]. In the
example, the actual argument list is sent as (C_list [ C_void ; C_void ]).
The augmented constructor for a director class needs the first argument
to determine whether it is being constructed as a derived object, or as
an object of the indicated type only (in this case <tt>shape</tt>). The
Second argument is a closure that will be added to the final C_obj.
</p>
<p>
The actual object passed to the self parameter of the director object will
be a C_director_core, containing a c_obj option ref and a c_obj. The
c_obj provided is the same object that will be returned from new_derived
object, that is, the object exposing the overridden methods. The other part
is an option ref that will have its value extracted before becoming the
<tt>ob</tt> parameter of your class closure. This ref will contain
<tt>None</tt> if the C++ object underlying is ever destroyed, and will
consequently trigger an exception when any method is called on the object
after that point (the actual raise is from an inner function used by
new_derived_object, and throws NotObject). This prevents a deleted C++
object from causing a core dump, as long as the object is destroyed
properly.
</p>
<H4><a name="Ocaml_nn27"></a>27.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4>
<p>
Special typemaps exist for use with directors, the <tt>directorin, directorout, directorargout</tt>
are used in place of <tt>in, out, argout</tt> typemaps, except that their
direction is reversed. They provide for you to provide argout values, as
well as a function return value in the same way you provide function arguments,
and to receive arguments the same way you normally receive function returns.
</p>
<H4><a name="Ocaml_nn28"></a>27.2.5.6 <tt>directorin</tt> typemap</H4>
<p>
The <tt>directorin</tt> typemap is used when you will receive arguments from a call
made by C++ code to you, therefore, values will be translated from C++ to
ocaml. You must provide some valid C_obj value. This is the value your ocaml
code receives when you are called. In general, a simple <tt>directorin</tt> typemap
can use the same body as a simple <tt>out</tt> typemap.
</p>
<H4><a name="Ocaml_nn29"></a>27.2.5.7 <tt>directorout</tt> typemap</H4>
<p>
The <tt>directorout</tt> typemap is used when you will send an argument from your
code back to the C++ caller. That is; directorout specifies a function return
conversion. You can usually use the same body as an <tt>in</tt> typemap
for the same type, except when there are special requirements for object
ownership, etc.
</p>
<H4><a name="Ocaml_nn30"></a>27.2.5.8 <tt>directorargout</tt> typemap</H4>
<p>
C++ allows function arguments which are by pointer (*) and by reference (&amp;)
to receive a value from the called function, as well as sending one there.
Sometimes, this is the main purpose of the argument given. <tt>directorargout</tt>
typemaps allow your caml code to emulate this by specifying additional return
values to be put into the output parameters. The SWIG ocaml module is a bit
loose in order to make code easier to write. In this case, your return to
the caller must be a list containing the normal function return first, followed
by any argout values in order. These argout values will be taken from the
list and assigned to the values to be returned to C++ through directorargout typemaps.
In the event that you don't specify all of the necessary values, integral
values will read zero, and struct or object returns have undefined results.
</p>
<H3><a name="Ocaml_nn31"></a>27.2.6 Exceptions</H3>
<p>
Catching exceptions is now supported using SWIG's %exception feature. A simple
but not too useful example is provided by the throw_exception testcase in
Examples/test-suite. You can provide your own exceptions, too.
</p>
</body>
</html>

844
Doc/Manual/Octave.html Normal file
View file

@ -0,0 +1,844 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Octave</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Octave"></a>28 SWIG and Octave</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Octave_nn2">Preliminaries</a>
<li><a href="#Octave_nn3">Running SWIG</a>
<ul>
<li><a href="#Octave_nn5">Compiling a dynamic module</a>
<li><a href="#Octave_nn6">Using your module</a>
</ul>
<li><a href="#Octave_nn7">A tour of basic C/C++ wrapping</a>
<ul>
<li><a href="#Octave_nn8">Modules</a>
<li><a href="#Octave_nn9">Functions</a>
<li><a href="#Octave_nn10">Global variables</a>
<li><a href="#Octave_nn11">Constants and enums</a>
<li><a href="#Octave_nn12">Pointers</a>
<li><a href="#Octave_nn13">Structures and C++ classes</a>
<li><a href="#Octave_nn15">C++ inheritance</a>
<li><a href="#Octave_nn17">C++ overloaded functions</a>
<li><a href="#Octave_nn18">C++ operators</a>
<li><a href="#Octave_nn19">Class extension with %extend</a>
<li><a href="#Octave_nn20">C++ templates</a>
<li><a href="#Octave_nn21">C++ Smart Pointers</a>
<li><a href="#Octave_nn22">Directors (calling Octave from C++ code)</a>
<li><a href="#Octave_nn23">Threads</a>
<li><a href="#Octave_nn24">Memory management</a>
<li><a href="#Octave_nn25">STL support</a>
<li><a href="#Octave_nn26">Matrix typemaps</a>
</ul>
</ul>
</div>
<!-- INDEX -->
<p>
Octave is a high-level language intended for numerical programming that is mostly compatible with MATLAB.
More information can be found at <a href="http://www.octave.org">www.octave.org</a>.
</p>
<p>
This chapter is intended to give an introduction to using the module. You should also read the SWIG documentation that is not specific to Octave.
Also, there are a dozen or so examples in the Examples/octave directory, and hundreds in the test suite (Examples/test-suite and Examples/test-suite/octave).
</p>
<H2><a name="Octave_nn2"></a>28.1 Preliminaries</H2>
<p>
The SWIG implemention was first based on Octave 2.9.12, so this is the minimum version required. Testing has only been done on Linux.
</p>
<H2><a name="Octave_nn3"></a>28.2 Running SWIG</H2>
<p>
Let's start with a very simple SWIG interface file, example.i:
</p>
<div class="code"><pre>
%module example
%{
#include "example.h"
%}
int gcd(int x, int y);
extern double Foo; </pre></div>
<p>
To build an Octave module when wrapping C code, run SWIG using the <tt>-octave</tt> option:
</p>
<div class="shell"><pre>$ swig -octave example.i </pre></div>
<p>
The <tt>-c++</tt> option is also required when wrapping C++ code:
</p>
<div class="shell"><pre>$ swig -octave -c++ example.i </pre></div>
<p>
This creates a C++ source file <tt>example_wrap.cxx</tt>. A C++ file is generated even when wrapping C code as Octave is itself written in C++ and requires wrapper code to be in the same language. The generated C++ source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application (in this case, the gcd implementation) to create an extension module.
</p>
<p>
The swig command line has a number of options you can use, like to redirect it's output. Use <tt>swig --help</tt> to learn about these.
</p>
<H3><a name="Octave_nn5"></a>28.2.1 Compiling a dynamic module</H3>
<p>
Octave modules are DLLs/shared objects having the ".oct" suffix.
Building an oct file is usually done with the mkoctfile command (either within Octave itself, or from the shell). For example,
</p>
<div class="shell"><pre>
$ swig -octave -c++ example.i -o example_wrap.cxx
$ mkoctfile example_wrap.cxx example.c
</pre></div>
<p>
where example.c is the file containing the gcd() implementation.
</p>
<p>
mkoctfile can also be used to extract the build parameters required to invoke the compiler and linker yourself. See the Octave manual and mkoctfile man page.
</p>
<p>
mkoctfile will produce example.oct, which contains the compiled extension module. Loading it into Octave is then a matter of invoking
</p>
<div class="targetlang"><pre>octave:1&gt; example</pre></div>
<H3><a name="Octave_nn6"></a>28.2.2 Using your module</H3>
<p>
Assuming all goes well, you will be able to do this:
<br>
</p>
<div class="targetlang"><pre>$ octave -q
octave:1&gt; example
octave:2&gt; example.gcd(4,6)
ans = 2
octave:3&gt; example.cvar.Foo
ans = 3
octave:4&gt; example.cvar.Foo=4;
octave:5&gt; example.cvar.Foo
ans = 4 </pre></div>
<H2><a name="Octave_nn7"></a>28.3 A tour of basic C/C++ wrapping</H2>
<H3><a name="Octave_nn8"></a>28.3.1 Modules</H3>
<p>
The SWIG module directive specifies the name of the Octave module. If you specify `module example', then in Octave everything in the module will be accessible under "example", as in the above example. When choosing a module name, make sure you don't use the same name as a built-in Octave command or standard module name.
</p>
<p>
When Octave is asked to invoke <tt>example</tt>, it will try to find the .m or .oct file that defines the function "example". It will thusly find example.oct, that upon loading will register all of the module's symbols.
</p>
<p>
Giving this function a parameter "global" will cause it to load all symbols into the global namespace in addition to the <tt>example</tt> namespace. For example:
</p>
<div class="targetlang"><pre>$ octave -q
octave:1&gt; example("global")
octave:2&gt; gcd(4,6)
ans = 2
octave:3&gt; cvar.Foo
ans = 3
octave:4&gt; cvar.Foo=4;
octave:5&gt; cvar.Foo
ans = 4
</pre></div>
<p>
It is also possible to rename the module namespace with an assignment, as in: <br>
<div class="targetlang"><pre>octave:1&gt; example;
octave:2&gt; c=example;
octave:3&gt; c.gcd(10,4)
ans = 2 </pre></div>
<p>
All global variables are put into the cvar namespace object. This is accessible either as <tt>my_module.cvar</tt>, or just <tt>cvar</tt> (if the module is imported into the global namespace).
</p>
<p>
One can also rename it by simple assignment, e.g.,
</p>
<div class="targetlang"><pre>
octave:1&gt; some_vars = cvar;
</pre></div>
<H3><a name="Octave_nn9"></a>28.3.2 Functions</H3>
<p>
Global functions are wrapped as new Octave built-in functions. For example,
</p>
<div class="code"><pre>&#037;module example
int fact(int n); </pre></div>
<p>
creates a built-in function <tt>example.fact(n)</tt> that works exactly like you think it does:
</p>
<div class="targetlang"><pre>octave:1&gt; example.fact(4)
24 </pre></div>
<H3><a name="Octave_nn10"></a>28.3.3 Global variables</H3>
<p>
Global variables are a little special in Octave. Given a global variable:
</p>
<div class="code"><pre>%module example
extern double Foo;
</pre></div>
<p>
To expose variables, SWIG actually generates two functions, to get and set the value. In this case, Foo_set and Foo_set would be generated. SWIG then automatically calls these functions when you get and set the variable-- in the former case creating a local copy in the interpreter of the C variables, and in the latter case copying an interpreter variables onto the C variable.
</p>
<div class="targetlang"><pre>octave:1&gt; example;
octave:2&gt; c=example.cvar.Foo
c = 3
octave:3&gt; example.cvar.Foo=4;
octave:4&gt; c
c = 3
octave:5&gt; example.cvar.Foo
ans = 4</pre></div>
<p>
If a variable is marked with the %immutable directive then any attempts to set this variable will cause an Octave error. Given a global variable:
</p>
<div class="code"><pre>%module example
%immutable;
extern double Foo;
%mutable;
</pre></div>
<p>
SWIG will allow the reading of <tt>Foo</tt> but when a set attempt is made, an error function will be called.
</p>
<div class="targetlang"><pre>octave:1&gt; example
octave:2&gt; example.Foo=4
error: attempt to set immutable member variable
error: assignment failed, or no method for `swig_type = scalar'
error: evaluating assignment expression near line 2, column 12 </pre></div>
<p>
It is possible to add new functions or variables to the module. This also allows the user to rename/remove existing functions and constants (but not linked variables, mutable or immutable). Therefore users are recommended to be careful when doing so.
</p>
<div class="targetlang"><pre>octave:1&gt; example;
octave:2&gt; example.PI=3.142;
octave:3&gt; example.PI
ans = 3.1420 </pre></div>
<H3><a name="Octave_nn11"></a>28.3.4 Constants and enums</H3>
<p>
Because Octave doesn't really have the concept of constants, C/C++ constants are not really constant in Octave. They are actually just a copy of the value into the Octave interpreter. Therefore they can be changed just as any other value. For example given some constants:
</p>
<div class="code"><pre>%module example
%constant int ICONST=42;
#define SCONST "Hello World"
enum Days{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
</pre></div>
<p>
This is 'effectively' converted into the following Octave code:
</p>
<div class="targetlang"><pre>example.ICONST=42
example.SCONST="Hello World"
example.SUNDAY=0
.... </pre></div>
<H3><a name="Octave_nn12"></a>28.3.5 Pointers</H3>
<p>
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the &lt;file.h&gt; interface:
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the &lt;file.h&gt; interface:
</p>
<div class="code"><pre>%module example
FILE *fopen(const char *filename, const char *mode);
int fputs(const char *, FILE *);
int fclose(FILE *);
</pre></div>
<p>
When wrapped, you will be able to use the functions in a natural way from Octave. For example:
</p>
<div class="targetlang"><pre>
octave:1&gt; example;
octave:2&gt; f=example.fopen("w","junk");
octave:3&gt; example.fputs("Hello world",f);
octave:4&gt; example.fclose(f);
</pre></div>
<p>
Simply printing the value of a wrapped C++ type will print it's typename. E.g.,
</p>
<div class="targetlang"><pre>octave:1&gt; example;
octave:2&gt; f=example.fopen("junk","w");
octave:3&gt; f
f =
{
_p_FILE, ptr = 0x9b0cd00
} </pre></div>
<p>
As the user of the pointer, you are responsible for freeing it, or closing any resources associated with it (just as you would in a C program). This does not apply so strictly to classes and structs (see below).
</p>
<div class="targetlang"><pre>octave:1&gt; example;
octave:2&gt; f=example.fopen("not there","r");
error: value on right hand side of assignment is undefined
error: evaluating assignment expression near line 2, column 2 </pre></div>
<H3><a name="Octave_nn13"></a>28.3.6 Structures and C++ classes</H3>
<p>
SWIG wraps C structures and C++ classes by using a special Octave type called a <tt>swig_ref</tt>. A <tt>swig_ref</tt> contains a reference to one or more instances of C/C++ objects, or just the type information for an object.
For each wrapped structure and class, a <tt>swig_ref</tt> will be exposed that has the name of the type. When invoked as a function, it creates a new object of its type and returns a <tt>swig_ref</tt> that points to that instance. This provides a very natural interface. For example,
</p>
<div class="code"><pre>struct Point{
int x,y;
};
</pre></div>
<p>
is used as follows:
</p>
<div class="targetlang">
<pre>octave:1&gt; example;
octave:2&gt; p=example.Point();
octave:3&gt; p.x=3;
octave:4&gt; p.y=5;
octave:5&gt; p.x, p.y
ans = 3
ans = 5
</pre></div>
<p>
In C++, invoking the type object in this way calls the object's constructor.
<tt>swig_ref</tt> objects can also be acquired by having a wrapped function return a pointer, reference, or value of a non-primitive type.
</p>
<p>
The swig_ref type handles indexing operations such that usage maps closely to what you would have in C/C++.
Structure members are accessed as in the above example, by calling set and get methods for C++ variables.
Methods also work as expected. For example, code wrapped in the following way
</p>
<div class="code"><pre>class Point{
public:
int x,y;
Point(int _x,int _y) : x(_x),y(_y) {}
double distance(const Point&amp; rhs) {
return sqrt(pow(x-rhs.x,2)+pow(y-rhs.y,2));
}
void set(int _x,int _y) {
x=_x; y=_y;
}
};
</pre></div>
<p>
can be used from Octave like this
</p>
<div class="targetlang">
<pre>octave:1&gt; example;
octave:2&gt; p1=example.Point(3,5);
octave:3&gt; p2=example.Point(1,2);
octave:4&gt; p1.distance(p2)
ans = 3.6056
</pre></div>
<p>
By using the <tt>swig_this()</tt> and <tt>swig_type()</tt> functions, one can discover the pointers to and types of the underlying C/C++ object.
</p>
<div class="targetlang">
<pre>
octave:5> swig_this(p1)
ans = 162504808
octave:6> swig_type(p1)
ans = Point
</pre></div>
<p>
Note that <tt>swig_ref</tt> is a reference-counted pointer to a C/C++ object/type, and as such has pass-by-reference semantics. For example if one has a allocated a single object but has two <tt>swig_ref</tt>'s pointing to it, modifying the object through either of them will change the single allocated object.
This differs from the usual pass-by-value (copy-on-write) semantics that Octave maintains for built-in types. For example, in the following snippet, modifying <tt>b</tt> does not modify <tt>a</tt>,
</p>
<div class="targetlang">
<pre>
octave:7> a=struct('x',4)
a =
{
x = 4
}
octave:8> b=a
b =
{
x = 4
}
octave:9> b.y=4
b =
{
x = 4
y = 4
}
octave:10> a
a =
{
x = 4
}
</pre></div>
<p>
However, when dealing with wrapped objects, one gets the behavior
</p>
<div class="targetlang">
<pre>
octave:2> a=Point(3,5)
a =
{
Point, ptr = 0x9afbbb0
}
octave:3> b=a
b =
{
Point, ptr = 0x9afbbb0
}
octave:4> b.set(2,1);
octave:5> b.x, b.y
ans = 2
ans = 1
octave:6> a.x, a.y
ans = 2
ans = 1
</pre></div>
<p>
Depending on the ownership setting of a <tt>swig_ref</tt>, it may call C++ destructors when its reference count goes to zero. See the section on memory management below for details.
</p>
<H3><a name="Octave_nn15"></a>28.3.7 C++ inheritance</H3>
<p>
Single and multiple inheritance are fully supported. The <tt>swig_ref</tt> type carries type information along with any C++ object pointer it holds.
This information contains the full class hierarchy. When an indexing operation (such as a method invocation) occurs,
the tree is walked to find a match in the current class as well as any of its bases. The lookup is then cached in the <tt>swig_ref</tt>.
</p>
<H3><a name="Octave_nn17"></a>28.3.8 C++ overloaded functions</H3>
<p>
Overloaded functions are supported, and handled as in other modules. That is,
each overload is wrapped separately (under internal names), and a dispatch function is also emitted under the external/visible name.
The dispatch function selects which overload to call (if any) based on the passed arguments.
<tt>typecheck</tt> typemaps are used to analyze each argument, as well as assign precedence. See the chapter on typemaps for details.
</p>
<H3><a name="Octave_nn18"></a>28.3.9 C++ operators</H3>
<p>
C++ operator overloading is supported, in a way similar to other modules.
The <tt>swig_ref</tt> type supports all unary and binary operators between itself and all other types that exist in the system at module load time. When an operator is used (where one of the operands is a <tt>swig_ref</tt>), the runtime routes the call to either a member function of the given object, or to a global function whose named is derived from the types of the operands (either both or just the lhs or rhs).
</p>
<p>
For example, if <tt>a</tt> and <tt>b</tt> are SWIG variables in Octave, <tt>a+b</tt> becomes <tt>a.__add(b)</tt>. The wrapper is then free to implement __add to do whatever it wants. A wrapper may define the <tt>__add</tt> function manually, %rename some other function to it, or %rename a C++ operator to it.
</p>
<p>
By default the C++ operators are renamed to their corresponding Octave operators. So without doing any work, the following interface
</p>
<div class="code"><pre>
%inline {
struct A {
int value;
A(int _value) : value(_value) {}
A operator+ (const A&amp; x) {
return A(value+x.value);
}
};
}
</pre></div>
<p>
is usable from Octave like this:
</p>
<div class="targetlang"><pre>
a=A(2), b=A(3), c=a+b
assert(c.value==5);
</pre></div>
<p>
Octave operators are mapped in the following way:
</p>
<div class="code"><pre>
__brace a{args}
__brace_asgn a{args} = rhs
__paren a(args)
__paren_asgn a(args) = rhs
__str generates string rep
__not !a
__uplus +a
__uminus -a
__transpose a.'
__hermitian a'
__incr a++
__decr a--
__add a + b
__sub a - b
__mul a * b
__div a / b
__pow a ^ b
__ldiv a \ b
__lshift a << b
__rshift a >> b
__lt a < b
__le a <= b
__eq a == b
__ge a >= b
__gt a > b
__ne a != b
__el_mul a .* b
__el_div a ./ b
__el_pow a .^ b
__el_ldiv a .\ b
__el_and a &amp; b
__el_or a | b
</pre></div>
<p>
On the C++ side, the default mappings are as follows:
</p>
<div class="code"><pre>
%rename(__add) *::operator+;
%rename(__add) *::operator+();
%rename(__add) *::operator+() const;
%rename(__sub) *::operator-;
%rename(__uminus) *::operator-();
%rename(__uminus) *::operator-() const;
%rename(__mul) *::operator*;
%rename(__div) *::operator/;
%rename(__mod) *::operator%;
%rename(__lshift) *::operator<<;
%rename(__rshift) *::operator>>;
%rename(__el_and) *::operator&amp;&amp;;
%rename(__el_or) *::operator||;
%rename(__xor) *::operator^;
%rename(__invert) *::operator~;
%rename(__lt) *::operator<;
%rename(__le) *::operator<=;
%rename(__gt) *::operator>;
%rename(__ge) *::operator>=;
%rename(__eq) *::operator==;
%rename(__ne) *::operator!=;
%rename(__not) *::operator!;
%rename(__incr) *::operator++;
%rename(__decr) *::operator--;
%rename(__paren) *::operator();
%rename(__brace) *::operator[];
</pre></div>
<H3><a name="Octave_nn19"></a>28.3.10 Class extension with %extend</H3>
<p>
The %extend directive works the same as in other modules.
</p>
<p>
You can use it to define special behavior, like for example defining Octave operators not mapped to C++ operators, or defining certain Octave mechanisms such as how an object prints. For example, the <tt>octave_value::{is_string,string_value,print}</tt> functions are routed to a special method <tt>__str</tt> that can be defined inside an %extend.
</p>
<div class="code"><pre>
%extend A {
string __str() {
stringstream sout;
sout&lt;&lt;$self->value;
return sout.str();
}
}
</pre></div>
<p>
Then in Octave one gets,
</p>
<div class="targetlang"><pre>
octave:1&gt; a=A(4);
octave:2&gt; a
a = 4
octave:3&gt; printf("%s\n",a);
4
octave:4&gt; a.__str()
4
</pre></div>
<H3><a name="Octave_nn20"></a>28.3.11 C++ templates</H3>
<p>
C++ class and function templates are fully supported as in other modules, in that the %template directive may used to create explicit instantiations of templated types.
For example, function templates can be instantiated as follows:
</p>
<div class="code"><pre>%module example
%inline {
template&lt;class __scalar&gt;
__scalar mul(__scalar a,__scalar b) {
return a*b;
}
}
%include &lt;std_complex.i&gt;
%template(mul) mul&lt;std::complex&lt;double&gt; &gt;
%template(mul) mul&lt;double&gt;
</pre></div>
<p>
and then used from Octave
</p>
<div class="targetlang"><pre>
octave:1> mul(4,3)
ans = 12
octave:2> mul(4.2,3.6)
ans = 15.120
octave:3> mul(3+4i,10+2i)
ans = 22 + 46i
</pre></div>
<p>
Similarly, class templates can be instantiated as in the following example,
</p>
<div class="code"><pre>%module example
%include &lt;std_complex.i&gt;
%include &lt;std_string.i&gt;
%inline {
#include &lt;sstream&gt;
template&lt;class __scalar&gt; class sum {
__scalar s;
public:
sum(__scalar _s=0) : s(_s) {}
sum&amp; add(__scalar _s) {
s+=_s;
return *this;
}
std::string __str() const {
std::stringstream sout;
sout&lt;&lt;s;
return sout.str();
}
};
}
%template(sum_complex) sum&lt;std::complex&lt;double&gt; &gt;;
%template(sum_double) sum&lt;double&gt;;
</pre></div>
<p>
and then used from Octave
</p>
<div class="targetlang"><pre>
octave:2> a=sum_complex(2+3i);
octave:3> a.add(2)
ans =
(4,3)
octave:4> a.add(3+i)
ans =
(7,4)
</pre></div>
<H3><a name="Octave_nn21"></a>28.3.12 C++ Smart Pointers</H3>
<p>
C++ smart pointers are fully supported as in other modules.
</p>
<H3><a name="Octave_nn22"></a>28.3.13 Directors (calling Octave from C++ code)</H3>
<p>
There is full support for SWIG Directors, which permits Octave code to subclass C++ classes, and implement their virtual methods.
</p>
<p>
Octave has no direct support for object oriented programming, however the <tt>swig_ref</tt> type provides some of this support. You can manufacture a <tt>swig_ref</tt> using the <tt>subclass</tt> function (provided by the SWIG/Octave runtime).
</p>
<p>
For example,
</p>
<div class="targetlang"><pre>
octave:1&gt; a=subclass();
octave:2&gt; a.my_var = 4;
octave:3&gt; a.my_method = @(self) printf("my_var = ",self.my_var);
octave:4&gt; a.my_method();
my_var = 4
</pre></div>
<p>
<tt>subclass()</tt> can also be used to subclass one or more C++ types. Suppose you have an interface defined by
</p>
<div class="code"><pre>
%inline {
class A {
public:
virtual my_method() {
printf("c-side routine called\n");
}
};
void call_your_method(A&amp; a) {
a.my_method();
}
}
</pre></div>
<p>
Then from Octave you can say:
</p>
<div class="targetlang"><pre>
octave:1&gt; B=@() subclass(A(),@my_method);
octave:2&gt; function my_method(self)
octave:3&gt; printf("octave-side routine called\n");
octave:4&gt; end
octave:5&gt; call_your_method(B());
octave-side routine called
</pre></div>
<p>
or more concisely,
</p>
<div class="targetlang"><pre>
octave:1&gt; B=@() subclass(A(),'my_method',@(self) printf("octave-side routine called\n"));
octave:2&gt; call_your_method(B());
octave-side routine called
</pre></div>
<p>
Note that you have to enable directors via the %feature directive (see other modules for this).
</p>
<p>
<tt>subclass()</tt> will accept any number of C++ bases or other <tt>subclass()</tt>'ed objects, <tt>(string,octave_value)</tt> pairs, and <tt>function_handles</tt>. In the first case, these are taken as base classes; in the second case, as named members (either variables or functions, depending on whether the given value is a function handle); in the third case, as member functions whose name is taken from the given function handle. E.g.,
</p>
<div class="targetlang"><pre>
octave:1&gt; B=@(some_var=2) subclass(A(),'some_var',some_var,@some_func,'another_func',@(self) do_stuff())
</pre></div>
<p>
You can also assign non-C++ member variables and functions after construct time. There is no support for non-C++ static members.
</p>
<p>
There is limited support for explicitly referencing C++ bases. So, in the example above, we could have
</p>
<div class="targetlang"><pre>
octave:1&gt; B=@() subclass(A(),@my_method);
octave:2&gt; function my_method(self)
octave:3&gt; self.A.my_method();
octave:4&gt; printf("octave-side routine called\n");
octave:5&gt; end
octave:6&gt; call_your_method(B());
c-side routine called
octave-side routine called
</pre></div>
<H3><a name="Octave_nn23"></a>28.3.14 Threads</H3>
<p>
The use of threads in wrapped Director code is not supported; i.e., an Octave-side implementation of a C++ class must be called from the Octave interpreter's thread. Anything fancier (apartment/queue model, whatever) is left to the user. Without anything fancier, this amounts to the limitation that Octave must drive the module... like, for example, an optimization package that calls Octave to evaluate an objective function.
</p>
<H3><a name="Octave_nn24"></a>28.3.15 Memory management</H3>
<p>
As noted above, <tt>swig_ref</tt> represents a reference counted pointer to a C/C++-side object. It also contains a flag indicating whether Octave or the C/C++ code owns the object. If Octave owns it, any destructors will be called when the reference count reaches zero. If the C/C++ side owns the object, then destructors will not be called when the reference count goes to zero.
</p>
<p>
For example,
<div class="code"><pre>
%inline {
class A {
public:
A() { printf("A constructing\n"); }
~A() { printf("A destructing\n"); }
};
}
</pre></div>
<p>
Would produce this behavior in Octave:
</p>
<div class="targetlang"><pre>
octave:1&gt; a=A();
A constructing
octave:2&gt; b=a;
octave:3&gt; clear a;
octave:4&gt; b=4;
A destructing
</pre></div>
<p>
The %newobject directive may be used to control this behavior for pointers returned from functions.
<p>
In the case where one wishes for the C++ side to own an object that was created in Octave (especially a Director object), one can use the __disown() method to invert this logic. Then letting the Octave reference count go to zero will not destroy the object, but destroying the object will invalidate the Octave-side object if it still exists (and call destructors of other C++ bases in the case of multiple inheritance/<tt>subclass()</tt>'ing).
</p>
<H3><a name="Octave_nn25"></a>28.3.16 STL support</H3>
<p>
Various STL library files are provided for wrapping STL containers.
</p>
<H3><a name="Octave_nn26"></a>28.3.17 Matrix typemaps</H3>
<p>
Octave provides a rich set of classes for dealing with matrices. Currently there are no built-in typemaps to deal with those. However, these are relatively straight forward for users to add themselves (see the docs on typemaps). Without much work (a single typemap decl-- say, 5 lines of code in the interface file), it would be possible to have a function
</p>
<div class="code"><pre>
double my_det(const double* mat,int m,int n);
</pre></div>
<p>
that is accessed from Octave as,
</p>
<div class="targetlang"><pre>
octave:1&gt; my_det(rand(4));
ans = -0.18388
</pre></div>
<tt><br></tt>
</body>
</html>

3001
Doc/Manual/Perl5.html Normal file

File diff suppressed because it is too large Load diff

1252
Doc/Manual/Php.html Normal file

File diff suppressed because it is too large Load diff

245
Doc/Manual/Pike.html Normal file
View file

@ -0,0 +1,245 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Pike</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Pike"></a>31 SWIG and Pike</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Pike_nn2">Preliminaries</a>
<ul>
<li><a href="#Pike_nn3">Running SWIG</a>
<li><a href="#Pike_nn4">Getting the right header files</a>
<li><a href="#Pike_nn5">Using your module</a>
</ul>
<li><a href="#Pike_nn6">Basic C/C++ Mapping</a>
<ul>
<li><a href="#Pike_nn7">Modules</a>
<li><a href="#Pike_nn8">Functions</a>
<li><a href="#Pike_nn9">Global variables</a>
<li><a href="#Pike_nn10">Constants and enumerated types</a>
<li><a href="#Pike_nn11">Constructors and Destructors</a>
<li><a href="#Pike_nn12">Static Members</a>
</ul>
</ul>
</div>
<!-- INDEX -->
<p>
This chapter describes SWIG support for Pike. As of this writing, the
SWIG Pike module is still under development and is not considered
ready for prime time. The Pike module is being developed against the
Pike 7.4.10 release and may not be compatible with previous versions
of Pike.
</p>
<p>
This chapter covers most SWIG features, but certain low-level details
are covered in less depth than in earlier chapters. At the very
least, make sure you read the "<a href="SWIG.html#SWIG">SWIG Basics</a>"
chapter.<br>
</p>
<H2><a name="Pike_nn2"></a>31.1 Preliminaries</H2>
<H3><a name="Pike_nn3"></a>31.1.1 Running SWIG</H3>
<p>
Suppose that you defined a SWIG module such as the following:
</p>
<div class="code">
<pre>%module example<br><br>%{<br>#include "example.h"<br>%}<br><br>int fact(int n);<br></pre>
</div>
<p>
To build a C extension module for Pike, run SWIG using the <tt>-pike</tt> option :
</p>
<div class="code">
<pre>$ <b>swig -pike example.i</b><br></pre>
</div>
<p>
If you're building a C++ extension, be sure to add the <tt>-c++</tt> option:
</p>
<div class="code">
<pre>$ <b>swig -c++ -pike example.i</b><br></pre>
</div>
<p>
This creates a single source file named <tt>example_wrap.c</tt> (or <tt>example_wrap.cxx</tt>, if you
ran SWIG with the <tt>-c++</tt> option).
The SWIG-generated source file contains the low-level wrappers that need
to be compiled and linked with the rest of your C/C++ application to
create an extension module.
</p>
<p>
The name of the wrapper file is derived from the name of the input
file. For example, if the input file is <tt>example.i</tt>, the name
of the wrapper file is <tt>example_wrap.c</tt>. To change this, you
can use the <tt>-o</tt> option:
</p>
<div class="code">
<pre>$ <b>swig -pike -o pseudonym.c example.i</b><br></pre>
</div>
<H3><a name="Pike_nn4"></a>31.1.2 Getting the right header files</H3>
<p>
In order to compile the C/C++ wrappers, the compiler needs to know the
path to the Pike header files. These files are usually contained in a
directory such as
</p>
<div class="code">
<pre>/usr/local/pike/7.4.10/include/pike<br></pre>
</div>
<p>
There doesn't seem to be any way to get Pike itself to reveal the
location of these files, so you may need to hunt around for them.
You're looking for files with the names <tt>global.h</tt>, <tt>program.h</tt>
and so on.
</p>
<H3><a name="Pike_nn5"></a>31.1.3 Using your module</H3>
<p>
To use your module, simply use Pike's <tt>import</tt> statement:
</p>
<div class="code"><pre>
$ <b>pike</b>
Pike v7.4 release 10 running Hilfe v3.5 (Incremental Pike Frontend)
&gt; <b>import example;</b>
&gt; <b>fact(4);</b>
(1) Result: 24
</pre></div>
<H2><a name="Pike_nn6"></a>31.2 Basic C/C++ Mapping</H2>
<H3><a name="Pike_nn7"></a>31.2.1 Modules</H3>
<p>
All of the code for a given SWIG module is wrapped into a single Pike
module. Since the name of the shared library that implements your
module ultimately determines the module's name (as far as Pike is
concerned), SWIG's <tt>%module</tt> directive doesn't really have any
significance.
</p>
<H3><a name="Pike_nn8"></a>31.2.2 Functions</H3>
<p>
Global functions are wrapped as new Pike built-in functions. For
example,
</p>
<div class="code"><pre>
%module example
int fact(int n);
</pre></div>
<p>
creates a new built-in function <tt>example.fact(n)</tt> that works
exactly as you'd expect it to:
</p>
<div class="code"><pre>
&gt; <b>import example;</b>
&gt; <b>fact(4);</b>
(1) Result: 24
</pre></div>
<H3><a name="Pike_nn9"></a>31.2.3 Global variables</H3>
<p>
Global variables are currently wrapped as a pair of functions, one to get
the current value of the variable and another to set it. For example, the
declaration
</p>
<div class="code"><pre>
%module example
double Foo;
</pre></div>
<p>
will result in two functions, <tt>Foo_get()</tt> and <tt>Foo_set()</tt>:
</p>
<div class="code"><pre>
&gt; <b>import example;</b>
&gt; <b>Foo_get();</b>
(1) Result: 3.000000
&gt; <b>Foo_set(3.14159);</b>
(2) Result: 0
&gt; <b>Foo_get();</b>
(3) Result: 3.141590
</pre></div>
<H3><a name="Pike_nn10"></a>31.2.4 Constants and enumerated types</H3>
<p>
Enumerated types in C/C++ declarations are wrapped as Pike constants,
not as Pike enums.
</p>
<H3><a name="Pike_nn11"></a>31.2.5 Constructors and Destructors</H3>
<p>
Constructors are wrapped as <tt>create()</tt> methods, and destructors are
wrapped as <tt>destroy()</tt> methods, for Pike classes.
</p>
<H3><a name="Pike_nn12"></a>31.2.6 Static Members</H3>
<p>
Since Pike doesn't support static methods or data for Pike classes, static
member functions in your C++ classes are wrapped as regular functions and
static member variables are wrapped as pairs of functions (one to get the
value of the static member variable, and another to set it). The names of
these functions are prepended with the name of the class.
For example, given this C++ class declaration:
</p>
<div class="code"><pre>
class Shape
{
public:
static void print();
static int nshapes;
};
</pre></div>
<p>
SWIG will generate a <tt>Shape_print()</tt> method that invokes the static
<tt>Shape::print()</tt> member function, as well as a pair of methods,
<tt>Shape_nshapes_get()</tt> and <tt>Shape_nshapes_set()</tt>, to get and set
the value of <tt>Shape::nshapes</tt>.
</p>
</body>
</html>

219
Doc/Manual/Preface.html Normal file
View file

@ -0,0 +1,219 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Preface</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Preface"></a>1 Preface</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Preface_nn2">Introduction</a>
<li><a href="#Preface_nn4">SWIG Versions</a>
<li><a href="#Preface_nn5">SWIG resources</a>
<li><a href="#Preface_nn6">Prerequisites</a>
<li><a href="#Preface_nn7">Organization of this manual</a>
<li><a href="#Preface_nn8">How to avoid reading the manual</a>
<li><a href="#Preface_nn9">Backwards compatibility</a>
<li><a href="#Preface_nn10">Credits</a>
<li><a href="#Preface_nn11">Bug reports</a>
</ul>
</div>
<!-- INDEX -->
<H2><a name="Preface_nn2"></a>1.1 Introduction</H2>
<p>
SWIG (Simplified Wrapper and Interface Generator) is a software development tool for building scripting language
interfaces to C and C++ programs. Originally developed in 1995, SWIG was
first used by scientists in the Theoretical Physics Division at Los Alamos National Laboratory for
building user interfaces to simulation codes running on the Connection
Machine 5 supercomputer. In this environment, scientists needed to
work with huge amounts of simulation data, complex hardware, and a
constantly changing code base. The use of a scripting language
interface provided a simple yet highly flexible foundation for solving these
types of problems. SWIG simplifies development by largely automating
the task of scripting language integration--allowing developers and users
to focus on more important problems.
</p>
<p>
Although SWIG was originally developed for scientific applications, it
has since evolved into a general purpose tool that is used in a wide
variety of applications--in fact almost anything where C/C++ programming
is involved.
<H2><a name="Preface_nn4"></a>1.2 SWIG Versions</H2>
<p>
In the late 1990's, the most stable version of SWIG was release
1.1p5. Versions 1.3.x were officially development versions and these were released
over a period of 10 years starting from the year 2000. The final version in the 1.3.x
series was 1.3.40, but in truth the 1.3.x series had been stable for many years.
An official stable version was released along with the decision to make SWIG
license changes and this gave rise to version 2.0.0 in 2010. The license was clarified
so that the code that SWIG generated could be distributed
under license terms of the user's choice/requirements and at the same time the SWIG
source was placed under the GNU General Public License version 3.
</p>
<H2><a name="Preface_nn5"></a>1.3 SWIG resources</H2>
<p>
The official location of SWIG related material is
</p>
<div class="shell"><pre>
<a href="http://www.swig.org">http://www.swig.org</a>
</pre></div>
<p>
This site contains the latest version of the software, users guide,
and information regarding bugs, installation problems, and
implementation tricks.
<p>
You can also subscribe to the swig-user mailing list by visiting the page
</p>
<div class="shell"><pre>
<a href="http://www.swig.org/mail.html">http://www.swig.org/mail.html</a>
</pre></div>
<p>
The mailing list often discusses some of the more technical aspects of
SWIG along with information about beta releases and future work.
</p>
<p>
Subversion access to the latest version of SWIG is also available. More information
about this can be obtained at:
</p>
<div class="shell"><pre>
<a href="http://www.swig.org/svn.html">http://www.swig.org/svn.html</a>
</pre></div>
<H2><a name="Preface_nn6"></a>1.4 Prerequisites</H2>
<p>
This manual assumes that you know how to write C/C++ programs and that you
have at least heard of scripting languages such as
Tcl, Python, and Perl. A detailed knowledge of these scripting
languages is not required although some familiarity won't
hurt. No prior experience with building C extensions to these
languages is required---after all, this is what SWIG does automatically.
However, you should be reasonably familiar with the use of
compilers, linkers, and makefiles since making
scripting language extensions is somewhat more complicated than
writing a normal C program.
</p>
<p>
Over time SWIG releases have become significantly more capable in
their C++ handling--especially support for advanced features like
namespaces, overloaded operators, and templates. Whenever possible,
this manual tries to cover the technicalities of this interface.
However, this isn't meant to be a tutorial on C++ programming. For many
of the gory details, you will almost certainly want to consult a good C++ reference. If you don't program
in C++, you may just want to skip those parts of the manual.
<H2><a name="Preface_nn7"></a>1.5 Organization of this manual</H2>
<p>
The first few chapters of this manual describe SWIG in general and
provide an overview of its capabilities. The remaining chapters are
devoted to specific SWIG language modules and are self
contained. Thus, if you are using SWIG to build Python interfaces, you
can probably skip to that chapter and find almost everything you need
to know.
</p>
<H2><a name="Preface_nn8"></a>1.6 How to avoid reading the manual</H2>
<p>
If you hate reading manuals, glance at the "Introduction" which
contains a few simple examples. These
examples contain about 95% of everything you need to know to use
SWIG. After that, simply use the language-specific chapters as a reference.
The SWIG distribution also comes with a large directory of
examples that illustrate different topics.
</p>
<H2><a name="Preface_nn9"></a>1.7 Backwards compatibility</H2>
<p>
If you are a previous user of SWIG, don't expect
SWIG to provide complete backwards compatibility.
Although the developers strive to the utmost to keep backwards compatibility,
this isn't always possible as the
primary goal over time is to make SWIG
better---a process that would simply be impossible if the developers
are constantly bogged down with backwards compatibility issues.
Potential incompatibilities are clearly marked in the detailed release notes
(CHANGES files).
</p>
<p>
If you need to work with different versions of SWIG and backwards
compatibility is an issue, you can use the SWIG_VERSION preprocessor
symbol which holds the version of SWIG being executed.
SWIG_VERSION is a hexadecimal integer such as 0x010311 (corresponding to SWIG-1.3.11).
This can be used in an interface file to define different typemaps, take
advantage of different features etc:
</p>
<div class="code"><pre>
#if SWIG_VERSION &gt;= 0x010311
/* Use some fancy new feature */
#endif
</pre></div>
<p>
Note: The version symbol is not defined in the generated SWIG
wrapper file. The SWIG preprocessor has defined SWIG_VERSION since SWIG-1.3.11.
</p>
<H2><a name="Preface_nn10"></a>1.8 Credits</H2>
<p>
SWIG is an unfunded project that would not be possible without the
contributions of many people working in their spare time.
If you have benefitted from using SWIG, please consider
<a href="http://www.swig.org/donate.html">Donating to SWIG</a> to keep development going.
There have been a large varied number of people
who have made contributions at all levels over time. Contributors
are mentioned either in the COPYRIGHT file or CHANGES files shipped with SWIG or in submitted bugs.
</p>
<H2><a name="Preface_nn11"></a>1.9 Bug reports</H2>
<p>
Although every attempt has been made to make SWIG bug-free, we are also trying
to make feature improvements that may introduce bugs.
To report a bug, either send mail to the SWIG developer
list at the <a href="http://www.swig.org/mail.html">swig-devel mailing list</a> or report a bug
at the <a href="http://www.swig.org/bugs.html">SWIG bug tracker</a>. In your report, be as specific as
possible, including (if applicable), error messages, tracebacks (if a
core dump occurred), corresponding portions of the SWIG interface file
used, and any important pieces of the SWIG generated wrapper code. We
can only fix bugs if we know about them.
</p>
</body>
</html>

View file

@ -0,0 +1,489 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG Preprocessor</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="Preprocessor"></a>7 Preprocessing</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Preprocessor_nn2">File inclusion</a>
<li><a href="#Preprocessor_nn3">File imports</a>
<li><a href="#Preprocessor_condition_compilation">Conditional Compilation</a>
<li><a href="#Preprocessor_nn5">Macro Expansion</a>
<li><a href="#Preprocessor_nn6">SWIG Macros</a>
<li><a href="#Preprocessor_nn7">C99 and GNU Extensions</a>
<li><a href="#Preprocessor_nn8">Preprocessing and %{ ... %} &amp; " ... " delimiters</a>
<li><a href="#Preprocessor_nn9">Preprocessing and { ... } delimiters</a>
<li><a href="#Preprocessor_typemap_delimiters">Preprocessor and Typemaps</a>
<li><a href="#Preprocessor_nn10">Viewing preprocessor output</a>
<li><a href="#Preprocessor_warning_error">The #error and #warning directives</a>
</ul>
</div>
<!-- INDEX -->
<p>
SWIG includes its own enhanced version of the C preprocessor. The preprocessor
supports the standard preprocessor directives and macro expansion rules.
However, a number of modifications and enhancements have been made. This
chapter describes some of these modifications.
</p>
<H2><a name="Preprocessor_nn2"></a>7.1 File inclusion</H2>
<p>
To include another file into a SWIG interface, use the <tt>%include</tt> directive
like this:
</p>
<div class="code">
<pre>
%include "pointer.i"
</pre>
</div>
<p>
Unlike, <tt>#include</tt>, <tt>%include</tt> includes each file once (and will not
reload the file on subsequent <tt>%include</tt> declarations). Therefore, it
is not necessary to use include-guards in SWIG interfaces.
</p>
<p>
By default, the <tt>#include</tt> is ignored unless you run SWIG with the
<tt>-includeall</tt> option. The reason for ignoring traditional includes
is that you often don't want SWIG to try and wrap everything included
in standard header system headers and auxiliary files.
<H2><a name="Preprocessor_nn3"></a>7.2 File imports</H2>
<p>
SWIG provides another file inclusion directive with the <tt>%import</tt> directive.
For example:
</p>
<div class="code">
<pre>
%import "foo.i"
</pre>
</div>
<p>
The purpose of <tt>%import</tt> is to collect certain information from another
SWIG interface file or a header file without actually generating any wrapper code.
Such information generally includes type declarations (e.g., <tt>typedef</tt>) as well as
C++ classes that might be used as base-classes for class declarations in the interface.
The use of <tt>%import</tt> is also important when SWIG is used to generate
extensions as a collection of related modules. This is an advanced topic and is described
in later in the <a href="Modules.html#Modules">Working with Modules</a> chapter.
</p>
<P>
The <tt>-importall</tt> directive tells SWIG to follow all <tt>#include</tt> statements
as imports. This might be useful if you want to extract type definitions from system
header files without generating any wrappers.
<H2><a name="Preprocessor_condition_compilation"></a>7.3 Conditional Compilation</H2>
<p>
SWIG fully supports the use of <tt>#if</tt>, <tt>#ifdef</tt>,
<tt>#ifndef</tt>, <tt>#else</tt>, <tt>#endif</tt> to conditionally
include parts of an interface. The following symbols are predefined
by SWIG when it is parsing the interface:
</p>
<div class="code"><pre>
SWIG Always defined when SWIG is processing a file
SWIGIMPORTED Defined when SWIG is importing a file with <tt>%import</tt>
SWIG_VERSION Hexadecimal (binary-coded decimal) number containing SWIG version,
such as 0x010311 (corresponding to SWIG-1.3.11).
SWIGALLEGROCL Defined when using Allegro CL
SWIGCFFI Defined when using CFFI
SWIGCHICKEN Defined when using CHICKEN
SWIGCLISP Defined when using CLISP
SWIGCSHARP Defined when using C#
SWIGGUILE Defined when using Guile
SWIGJAVA Defined when using Java
SWIGLUA Defined when using Lua
SWIGMODULA3 Defined when using Modula-3
SWIGMZSCHEME Defined when using Mzscheme
SWIGOCAML Defined when using Ocaml
SWIGOCTAVE Defined when using Octave
SWIGPERL Defined when using Perl
SWIGPHP Defined when using PHP
SWIGPIKE Defined when using Pike
SWIGPYTHON Defined when using Python
SWIGR Defined when using R
SWIGRUBY Defined when using Ruby
SWIGSEXP Defined when using S-expressions
SWIGTCL Defined when using Tcl
SWIGXML Defined when using XML
</pre></div>
<p>
In addition, SWIG defines the following set of standard C/C++ macros:
</p>
<div class="code">
<pre>
__LINE__ Current line number
__FILE__ Current file name
__STDC__ Defined to indicate ANSI C
__cplusplus Defined when -c++ option used
</pre>
</div>
<p>
Interface files can look at these symbols as necessary to change the
way in which an interface is generated or to mix SWIG directives with
C code. These symbols are also defined within the C code generated by
SWIG (except for the symbol `<tt>SWIG</tt>' which is only defined
within the SWIG compiler).
</p>
<H2><a name="Preprocessor_nn5"></a>7.4 Macro Expansion</H2>
<p>
Traditional preprocessor macros can be used in SWIG interfaces. Be aware that the <tt>#define</tt> statement
is also used to try and detect constants. Therefore, if you have something like this in your file,
</p>
<div class="code">
<pre>
#ifndef _FOO_H 1
#define _FOO_H 1
...
#endif
</pre>
</div>
<p>
you may get some extra constants such as <tt>_FOO_H</tt> showing up in the scripting interface.
</p>
<p>
More complex macros can be defined in the standard way. For example:
</p>
<div class="code">
<pre>
#define EXTERN extern
#ifdef __STDC__
#define _ANSI(args) (args)
#else
#define _ANSI(args) ()
#endif
</pre>
</div>
<p>
The following operators can appear in macro definitions:
</p>
<ul>
<li><tt>#x</tt><br>
Converts macro argument <tt>x</tt> to a string surrounded by double quotes ("x").
</li>
<li><tt>x ## y</tt><br>
Concatenates x and y together to form <tt>xy</tt>.
</li>
<li><tt>`x`</tt><br>
If <tt>x</tt> is a string surrounded by double quotes, do nothing. Otherwise, turn into a string
like <tt>#x</tt>. This is a non-standard SWIG extension.
</li>
</ul>
<H2><a name="Preprocessor_nn6"></a>7.5 SWIG Macros</H2>
<p>
SWIG provides an enhanced macro capability with the <tt>%define</tt> and <tt>%enddef</tt> directives.
For example:
</p>
<div class="code">
<pre>
%define ARRAYHELPER(type,name)
%inline %{
type *new_ ## name (int nitems) {
return (type *) malloc(sizeof(type)*nitems);
}
void delete_ ## name(type *t) {
free(t);
}
type name ## _get(type *t, int index) {
return t[index];
}
void name ## _set(type *t, int index, type val) {
t[index] = val;
}
%}
%enddef
ARRAYHELPER(int, IntArray)
ARRAYHELPER(double, DoubleArray)
</pre>
</div>
<p>
The primary purpose of <tt>%define</tt> is to define large macros of code. Unlike normal C preprocessor
macros, it is not necessary to terminate each line with a continuation character (\)--the macro definition
extends to the first occurrence of <tt>%enddef</tt>. Furthermore, when such macros are expanded,
they are reparsed through the C preprocessor. Thus, SWIG macros can contain all other preprocessor
directives except for nested <tt>%define</tt> statements.
</p>
<p>
The SWIG macro capability is a very quick and easy way to generate large amounts of code. In fact,
many of SWIG's advanced features and libraries are built using this mechanism (such as C++ template
support).
</p>
<H2><a name="Preprocessor_nn7"></a>7.6 C99 and GNU Extensions</H2>
<p>
SWIG-1.3.12 and newer releases support variadic preprocessor macros. For example:
</p>
<div class="code">
<pre>
#define DEBUGF(fmt,...) fprintf(stderr,fmt,__VA_ARGS__)
</pre>
</div>
<p>
When used, any extra arguments to <tt>...</tt> are placed into the
special variable <tt>__VA_ARGS__</tt>. This also works with special SWIG
macros defined using <tt>%define</tt>.
</p>
<p>
SWIG allows a variable number of arguments to be empty. However, this often results
in an extra comma (,) and syntax error in the resulting expansion. For example:
</p>
<div class="code">
<pre>
DEBUGF("hello"); --&gt; fprintf(stderr,"hello",);
</pre>
</div>
<p>
To get rid of the extra comma, use <tt>##</tt> like this:
</p>
<div class="code">
<pre>
#define DEBUGF(fmt,...) fprintf(stderr,fmt, ##__VA_ARGS__)
</pre>
</div>
<p>
SWIG also supports GNU-style variadic macros. For example:
</p>
<div class="code">
<pre>
#define DEBUGF(fmt, args...) fprintf(stdout,fmt,args)
</pre>
</div>
<p>
<b>Comment:</b> It's not entirely clear how variadic macros might be useful to
interface building. However, they are used internally to implement a number of
SWIG directives and are provided to make SWIG more compatible with C99 code.
</p>
<H2><a name="Preprocessor_nn8"></a>7.7 Preprocessing and %{ ... %} &amp; " ... " delimiters</H2>
<p>
The SWIG preprocessor does not process any text enclosed in a code block %{ ... %}. Therefore,
if you write code like this,
</p>
<div class="code">
<pre>
%{
#ifdef NEED_BLAH
int blah() {
...
}
#endif
%}
</pre>
</div>
<p>
the contents of the <tt>%{ ... %}</tt> block are copied without
modification to the output (including all preprocessor directives).
</p>
<H2><a name="Preprocessor_nn9"></a>7.8 Preprocessing and { ... } delimiters</H2>
<p>
SWIG always runs the preprocessor on text appearing inside <tt>{ ... }</tt>. However,
sometimes it is desirable to make a preprocessor directive pass through to the output
file. For example:
</p>
<div class="code">
<pre>
%extend Foo {
void bar() {
#ifdef DEBUG
printf("I'm in bar\n");
#endif
}
}
</pre>
</div>
<p>
By default, SWIG will interpret the <tt>#ifdef DEBUG</tt> statement. However, if you really wanted that code
to actually go into the wrapper file, prefix the preprocessor directives with <tt>%</tt> like this:
</p>
<div class="code">
<pre>
%extend Foo {
void bar() {
%#ifdef DEBUG
printf("I'm in bar\n");
%#endif
}
}
</pre>
</div>
<p>
SWIG will strip the extra <tt>%</tt> and leave the preprocessor directive in the code.
</p>
<H2><a name="Preprocessor_typemap_delimiters"></a>7.9 Preprocessor and Typemaps</H2>
<p>
<a href="Typemaps.html#Typemaps">Typemaps</a> support a special attribute called <tt>noblock</tt> where the { ... } delimiters can be used,
but the delimiters are not actually generated into the code.
The effect is then similar to using "" or %{ %} delimiters but the code <b>is</b> run through the preprocessor. For example:
</p>
<div class="code">
<pre>
#define SWIG_macro(CAST) (CAST)$input
%typemap(in) Int {$1= SWIG_macro(int);}
</pre>
</div>
<p>
might generate
</p>
<div class="code">
<pre>
{
arg1=(int)jarg1;
}
</pre>
</div>
<p>
whereas
</p>
<div class="code">
<pre>
#define SWIG_macro(CAST) (CAST)$input
%typemap(in,noblock=1) Int {$1= SWIG_macro(int);}
</pre>
</div>
<p>
might generate
</p>
<div class="code">
<pre>
arg1=(int)jarg1;
</pre>
</div>
<p>
and
</p>
<div class="code">
<pre>
#define SWIG_macro(CAST) (CAST)$input
%typemap(in) Int %{$1=SWIG_macro(int);%}
</pre>
</div>
<p>
would generate
</p>
<div class="code">
<pre>
arg1=SWIG_macro(int);
</pre>
</div>
<H2><a name="Preprocessor_nn10"></a>7.10 Viewing preprocessor output</H2>
<p>
Like many compilers, SWIG supports a <tt>-E</tt> command line option to display the output from the preprocessor.
When the <tt>-E</tt> switch is used, SWIG will not generate any wrappers.
Instead the results after the preprocessor has run are displayed.
This might be useful as an aid to debugging and viewing the results of macro expansions.
</p>
<H2><a name="Preprocessor_warning_error"></a>7.11 The #error and #warning directives</H2>
<p>
SWIG supports the commonly used <tt>#warning</tt> and <tt>#error</tt> preprocessor directives.
The <tt>#warning</tt> directive will cause SWIG to issue a warning then continue processing.
The <tt>#error</tt> directive will cause SWIG to exit with a fatal error.
Example usage:
</p>
<div class="code">
<pre>
#error "This is a fatal error message"
#warning "This is a warning message"
</pre>
</div>
<p>
The <tt>#error</tt> behaviour can be made to work like <tt>#warning</tt> if the <tt>-cpperraswarn</tt>
commandline option is used. Alternatively, the <tt>#pragma</tt> directive can be used to the same effect, for example:
</p>
<div class="code">
<pre>
/* Modified behaviour: #error does not cause SWIG to exit with error */
#pragma SWIG cpperraswarn=1
/* Normal behaviour: #error does cause SWIG to exit with error */
#pragma SWIG cpperraswarn=0
</pre>
</div>
</body>
</html>

5182
Doc/Manual/Python.html Normal file

File diff suppressed because it is too large Load diff

180
Doc/Manual/R.html Normal file
View file

@ -0,0 +1,180 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and R</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="R"></a>33 SWIG and R</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#R_nn2">Bugs</a>
<li><a href="#R_nn3">Using R and SWIG</a>
<li><a href="#R_nn4">Precompiling large R files</a>
<li><a href="#R_nn5">General policy</a>
<li><a href="#R_language_conventions">Language conventions</a>
<li><a href="#R_nn6">C++ classes</a>
<li><a href="#R_nn7">Enumerations</a>
</ul>
</div>
<!-- INDEX -->
<p>
R is a GPL'ed open source statistical and plotting environment.
Information about R can be found at <a
href="http://www.r-project.org/">www.r-project.org</a>.
The R bindings are under active development. They have been used to
compile and run an R interface to QuantLib running on Mandriva Linux
with gcc. The R bindings also work on Microsoft Windows using Visual C++.
</p>
<H2><a name="R_nn2"></a>33.1 Bugs</H2>
<p>
Currently the following features are not implemented or broken:
</p>
<ul>
<li>Garbage collection of created objects
<li>C Array wrappings
</ul>
<H2><a name="R_nn3"></a>33.2 Using R and SWIG</H2>
<p>
To use R and SWIG in C mode, execute the following commands where
example.c is the name of the file with the functions in them
</p>
<div class="shell">
<pre>
swig -r example.i
R CMD SHLIB example_wrap.c example.c
</pre>
</div>
<p>
The corresponding options for C++ mode are
</p>
<div class="shell">
<pre>
swig -c++ -r -o example_wrap.cpp example.i
R CMD SHLIB example_wrap.cpp example.cpp
</pre>
</div>
<p>
Note that R is sensitive to the names of the files.
The name of the wrapper file must be the
name of the library unless you use the -o option to R when building the library, for example:
</p>
<div class="shell">
<pre>
swig -c++ -r -o example_wrap.cpp example.i
R CMD SHLIB -o example.so example_wrap.cpp example.cpp
</pre>
</div>
<p>
R is also sensitive to the name of the file
extension in C and C++ mode. In C++ mode, the file extension must be .cpp
rather than .cxx for the R compile command to recognize it. If your C++ code is
in a file using something other than a .cpp extension, then it may still work using PKG_LIBS:
</p>
<div class="shell">
<pre>
swig -c++ -r -o example_wrap.cpp example.i
PKG_LIBS="example.cxx" R CMD SHLIB -o example example_wrap.cpp
</pre>
</div>
<p>
The commands produces two files. A dynamic shared object file called
example.so, or example.dll, and an R wrapper file called example.R. To load these
files, start up R and type in the following commands
</p>
<div class="shell">
<pre>
dyn.load(paste("example", .Platform$dynlib.ext, sep=""))
source("example.R")
cacheMetaData(1)
</pre>
</div>
The cacheMetaData(1) will cause R to refresh its object tables.
Without it, inheritance of wrapped objects may fail.
<p>
These two files can be loaded in any order
</p>
<H2><a name="R_nn4"></a>33.3 Precompiling large R files</H2>
In cases where the R file is large, one make save a lot of loading
time by precompiling the R wrapper. This can be done by creating the
file makeRData.R which contains the following
<pre>
source('BigFile.R')
save(list=ls(all=TRUE),file="BigFile.RData", compress=TRUE)
q(save="no")
</pre>
This will generate a compiled R file called BigFile.RData that
will save a large amount of loading time.
<H2><a name="R_nn5"></a>33.4 General policy</H2>
<p>
The general policy of the module is to treat the C/C++ as a basic
wrapping over the underlying functions and rely on the R type system
to provide R syntax.
</p>
<H2><a name="R_language_conventions"></a>33.5 Language conventions</H2>
<p>
getitem and setitem use C++ conventions (i.e. zero based indices). [<-
and [ are overloaded to allow for R syntax (one based indices and
slices)
</p>
<H2><a name="R_nn6"></a>33.6 C++ classes</H2>
<p>
C++ objects are implemented as external pointer objects with the class
being the mangled name of the class. The C++ classes are encapsulated
as an SEXP with an external pointer type. The class is the mangled
name of the class. The nice thing about R is that is allows you to
keep track of the pointer object which removes the necessity for a lot
of the proxy class baggage you see in other languages.
</p>
<H2><a name="R_nn7"></a>33.7 Enumerations</H2>
<p>
enumerations are characters which are then converted back and forth to
ints before calling the C routines. All of the enumeration code is
done in R.
</p>
</body>
</html>

21
Doc/Manual/README Normal file
View file

@ -0,0 +1,21 @@
This directory contains the HTML for the SWIG users manual.
All of this HTML is hand-written. However, section numbering, indices,
and the table of contents is generated automatically by the 'maketoc.py'
script. The Makefile has further information on how the various alternative
forms of the documentation is generated from the hand-written HTML.
There are 4 types of boxes that code or whatever can be inside:
- <div class="shell">...</div>
This is for text that shows the output of running commands on the shell.
- <div class="code">...</div>
This is for either C, C++, or SWIG code
- <div class="targetlang">...</div>
This is for code in a target scripting language
- <div class="diagram">...</div>
This is for text that is not code or a shell
The general format is
<div class="foo"><pre>
whatever here
</pre></div>

10902
Doc/Manual/Ruby.html Normal file

File diff suppressed because it is too large Load diff

3400
Doc/Manual/SWIG.html Normal file

File diff suppressed because it is too large Load diff

5003
Doc/Manual/SWIGPlus.html Normal file

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more