Merge trunk (up to just after swig 2.0.5 release - rev 13009) to gsoc2008-cherylfoil

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-cherylfoil@13017 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2012-04-27 18:55:37 +00:00
commit af1c6ac3c3
1811 changed files with 94580 additions and 35569 deletions

View file

@ -1,46 +1,33 @@
*** ANNOUNCE: SWIG 2.0.0 (in progress) ***
*** ANNOUNCE: SWIG 2.0.6 (in progress) ***
http://www.swig.org
We're pleased to announce SWIG-2.0.0, the latest installment in the
SWIG development effort. SWIG-2.0.0 includes a number of bug fixes
and enhancements.
We're pleased to announce SWIG-2.0.6, 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.
Scheme (Guile, MzScheme, CHICKEN), D, 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:
-------------
Availability
============
The release is available for download on Sourceforge at
http://prdownloads.sourceforge.net/swig/swig-2.0.0.tar.gz
http://prdownloads.sourceforge.net/swig/swig-2.0.6.tar.gz
A Windows version is also available at
http://prdownloads.sourceforge.net/swig/swigwin-2.0.0.zip
http://prdownloads.sourceforge.net/swig/swigwin-2.0.6.zip
Release numbers
---------------
With SWIG-1.3, we are adopting an odd/even version numbering scheme for
SWIG. Odd version numbers (1.3, 1.5, 1.7, etc...) are considered to
be development releases. Even numbers (1.4,1.6,1.8) are stable
releases. The current 1.3 effort is working to produce a stable 2.0
release. A stable 2.0 release will not be made until it can
accompanied by fully updated documentation. In the meantime, we will
continue to make periodic 1.3.x releases.
Please report problems with this release to the swig-dev mailing list,
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>

2415
CHANGES

File diff suppressed because it is too large Load diff

View file

@ -1,80 +1,7 @@
Version 1.3.37 (in progress)
=============================
Below are 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.
2008-09-02: wsfulton
[Python] Commit patch #2089149: Director exception handling mangles
returned exception. Exceptions raised by Python code in directors
are now passed through to the caller without change. Also, remove
the ": " prefix which used to be added to other director exceptions
(eg, those due to incorrect return types).
2008-09-02: wsfulton
[Python] Commit patch #1988296 GCItem multiple module linking issue when using
directors.
2008-09-02: wsfulton
[C#] Support for 'using' and 'fixed' blocks in the 'csin' typemap is now
possible through the use of the pre attribute and the new terminator attribute, eg
%typemap(csin,
pre=" using (CDate temp$csinput = new CDate($csinput)) {",
terminator=" } // terminate temp$csinput using block",
) const CDate &
"$csclassname.getCPtr(temp$csinput)"
See CSharp.html for more info.
2008-09-01: wsfulton
[CFFI] Commit patch #2079381 submitted by Boris Smilga - constant exprs put into
no-eval context in DEFCENUM
2008-09-01: wsfulton
[C#] Correct array bounds checking in std::vector typemaps - Insert and InsertRange
methods.
2008-08-02: wuzzeb
[Chicken,Allegro] Commit Patch 2019314
Fixes a build error in chicken, and several build errors and other errors
in Allegro CL
2008-07-19: wsfulton
Fix building of Tcl examples/test-suite on Mac OSX reported by Gideon Simpson.
2008-07-17: wsfulton
Fix SF #2019156 Configuring with --without-octave or --without-alllang
did not disable octave.
2008-07-14: wsfultonn
[Java, C#] Fix director typemaps for pointers so that NULL pointers are correctly
marshalled to C#/Java null in director methods.
2008-07-04: olly
[PHP] For std_vector.i and std_map.i, rename empty() to is_empty()
since "empty" is a PHP reserved word. Based on patch from Mark Klein
in SF#1943417.
2008-07-04: olly
[PHP] The deprecated command line option "-make" has been removed.
Searches on Google codesearch suggest that nobody is using it now
anyway.
2008-07-04: olly
[PHP] The SWIG cdata.i library module is now supported.
2008-07-03: olly
[PHP] The deprecated command line option "-phpfull" has been
removed. We recommend building your extension as a dynamically
loadable module.
2008-07-02: olly
[PHP4] Support for PHP4 has been removed. The PHP developers are
no longer making new PHP4 releases, and won't even be providing
patches for critical security issues after 2008-08-08.
2008-07-02: olly
[Python] Import the C extension differently for Python 2.6 and
later so that an implicit relative import doesn't produce a
deprecation warning for 2.6 and a failure for 2.7 and later.
Patch from Richard Boulton in SF#2008229, plus follow-up patches
from Richard and Haoyu Bai.
Version 2.0.6 (in progress)
===========================

View file

@ -1,7 +1,7 @@
SWIG Copyright and Authors
--------------------------
Copyright (c) 1995-2010 The SWIG Developers
Copyright (c) 1995-2011 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
@ -15,6 +15,7 @@ Active SWIG Developers:
Olly Betts (olly@survex.com) (PHP)
Joseph Wang (joequant@gmail.com) (R)
Xavier Delacour (xavier.delacour@gmail.com) (Octave)
David Nadlinger (code@klickverbot.at) (D)
Past SWIG developers and major contributors include:
Dave Beazley (dave-swig@dabeaz.com) (SWIG core, Python, Tcl, Perl)
@ -29,7 +30,7 @@ Past SWIG developers and major contributors include:
Charlie Savage (cfis@interserv.com) (Ruby)
Thien-Thi Nguyen (ttn@glug.org) (build/test/misc)
Richard Palmer (richard@magicality.org) (PHP)
Sam Liddicott - Anonova Ltd (saml@liddicott.com) (PHP)
Sam Liddicott - Ananova Ltd (saml@liddicott.com) (PHP)
Tim Hockin - Sun Microsystems (thockin@sun.com) (PHP)
Kevin Ruland (PHP)
Shibukawa Yoshiki (Japanese Translation)
@ -42,7 +43,7 @@ Past SWIG developers and major contributors include:
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)
Ahmon Dancy (dancy@franz.com) (Allegro CL)
Dirk Gerrits (Allegro CL)
Neil Cawse (C#)
Harco de Hilster (Java)
@ -53,11 +54,51 @@ Past SWIG developers and major contributors include:
Duncan Temple Lang (R)
Miklos Vajna <vmiklos@frugalware.org> (PHP directors)
Mark Gossage (mark@gossage.cjb.net) (Lua)
Raman Gopalan (ramangopalan@gmail.com) (eLua)
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)
Stefan Zager (szager@gmail.com) (Python)
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
(See CHANGES and CHANGES.current for a more complete list).
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.

View file

@ -36,7 +36,7 @@ functions to mark whether or not a particular command line option was used. Thi
<h2>Argument Marking</h2>
As command line options are are processed by language modules, the following functions are used
As command line options are processed by language modules, the following functions are used
to mark the arguments as used:
<p>

View file

@ -119,22 +119,25 @@ are case-insensitive on Windows so this convention will prevent you from inadver
creating two files that differ in case-only.
<p>
Each file should include a short abstract, author information, copyright information, and
Each file should include a short abstract, license information and
a SVN revision tag like this:
<blockquote>
<pre>
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
* 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.
*
* cwrap.c
* xxx.c
*
* This file defines a variety of wrapping rules for C/C++ handling including
* the naming of local variables, calling conventions, and so forth.
* This file defines ...
* ----------------------------------------------------------------------------- */
char cvsroot_cwrap_c[] = "$Id$";
static char cvs[] = "&#36Id&#36";
#include "swig.h"

View file

@ -21,6 +21,7 @@ The following documentation describe the internal APIs used by SWIG. These may
<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>.
<li><a href="runtime.txt">SWIG Runtime</a>.
</ul>
<hr>

View file

@ -7,11 +7,6 @@
<center>
<h1>SWIG Internals Manual</h1>
<b>Thien-Thi Nguyen <br>
<p>
David M. Beazley <br>
</b>
</center>
@ -42,11 +37,12 @@ David M. Beazley <br>
</ul>
<li><a name="i3" href="#3">3. Types and Typemaps</a>
<li><a name="i4" href="#4">4. Parsing</a>
<li><a name="i5" href="#5">5. Difference Between SWIG 1.1 and SWIG 1.3</a>
<li><a name="i6" href="#6">6. Plans for SWIG 2.0</a>
<li><a name="i7" href="#7">7. C/C++ Wrapper Support Functions</a>
<li><a name="i8" href="#8">8. Symbol Naming Guidelines for Generated C/C++ Code</a>
<li><a name="i9" href="#9">9. Debugging SWIG</a>
<li><a name="i5" href="#5">5. C/C++ Wrapper Support Functions</a>
<li><a name="i6" href="#6">6. Symbol Naming Guidelines for Generated C/C++ Code</a>
<li><a name="i7" href="#7">7. Debugging SWIG</a>
<ul>
<li><a name="i7.1" href="#7.1">7.1 Debugging DOH Types The Hard Way</a>
</ul>
</ul>
<a name="1" href="#i1">
@ -76,9 +72,8 @@ to code).
<tr><td>Examples</td>
<td>This subdir tree contains examples of using SWIG w/ different
scripting languages, including makefiles. Typically, there are the
"simple" and "matrix" examples, w/ some languages offering additional
examples. The GIFPlot example has its own set of per-language
subdirectories. See the README more index.html file in each directory
"simple" and "class" examples, w/ some languages offering additional
examples. See the README more index.html file in each directory
for more info. [FIXME: Ref SWIG user manual.]</td>
</tr>
@ -97,55 +92,35 @@ info.</td>
</tr>
<tr><td>Source</td>
<td>SWIG source code is in this subdir tree. Directories marked w/ "(*)"
are used in building the <tt>swig</tt> executable.
<td>The C and C++ source code for the <tt>swig</tt> executable is in this
subdir tree.</td>
<table border=1>
<tr><td>DOH (*)</td>
<tr><td>DOH</td>
<td>C library providing memory allocation, file access and generic
containers. Result: libdoh.a</td>
containers.</td>
</tr>
<tr><td>Experiment</td>
<td>[TODO]</td>
</tr>
<tr><td>Include (*)</td>
<tr><td>Include</td>
<td>Configuration .h files</td>
</tr>
<tr><td>LParse</td>
<td>Parser (lex / yacc) files and support [why not (*)?!]</td>
<tr><td>CParse</td>
<td>Parser (lex / yacc) files and support</td>
</tr>
<tr><td>Modules</td>
<td>[TODO]</td>
</tr>
<tr><td>Modules1.1 (*)</td>
<td>Language-specific callbacks that does actual code generation (each
language has a .cxx and a .h file). Result: libmodules11.a</td>
language has a .cxx and a .h file).</td>
</tr>
<tr><td>Preprocessor (*)</td>
<td>SWIG-specialized C/C++ preprocessor. Result: libcpp.a</td>
<tr><td>Preprocessor</td>
<td>SWIG-specialized C/C++ preprocessor.</td>
</tr>
<tr><td>SWIG1.1 (*)</td>
<td>Parts of SWIG that are not language-specific, including option
processing and the type-mapping system. Result: libswig11.a.
Note: This directory is currently being phased out. </td>
</tr>
<tr><td>SWIG1.3</td>
<td>[TODO] [funny, nothing here is presently used for swig-1.3].
This directory might turn into a compatibility interface between
SWIG1.3 and the SWIG1.1 modules.</td>
</tr>
<tr><td>Swig (*)</td>
<td>This directory contains the new ANSI C core of the system
<tr><td>Swig</td>
<td>This directory contains the ANSI C core of the system
and contains generic functions related to types, file handling,
scanning, and so forth.</td>
</tr>
@ -154,7 +129,7 @@ are used in building the <tt>swig</tt> executable.
</tr>
<tr><td>Tools</td>
<td>Libtool support and the mkdist.py script.</td>
<td>The mkdist.py script and other tools.</td>
</tr>
<tr><td>Win</td>
@ -173,14 +148,14 @@ to look for code:
<ul>
<li> <tt>Modules1.1/swigmain.cxx:main()</tt> is the program entry
<li> <tt>Modules/swigmain.cxx:main()</tt> is the program entry
point. It parses the language-specifying command-line option (for
example, <tt>-java</tt>), creating a new language-specific wrapping
object (each language is a C++ class derived from base class
<tt>Language</tt>). This object and the command-line is passed to
<tt>SWIG_main()</tt>, whose return value is the program exit value.
<li> <tt>SWIG1.1/main.cxx:SWIG_main()</tt> is the "real" main. It
<li> <tt>Modules/main.cxx:SWIG_main()</tt> is the "real" main. It
initializes the preprocessor and typemap machinery, defines some
preprocessor symbols, locates the SWIG library, processes common
command-line options, and then calls the language-specific command-line
@ -203,7 +178,7 @@ included <tt>-freeze</tt>, go into an infinite loop; otherwise return the
error count.
<li> The language-specific <tt>parse()</tt> (and all other
language-specific code) lives in <tt>Modules1.1/foo.{h,cxx}</tt> for
language-specific code) lives in <tt>Modules/foo.{h,cxx}</tt> for
language Foo. Typically, <tt>FOO::parse()</tt> calls
<tt>FOO::headers()</tt> and then the global function <tt>yyparse()</tt>,
which uses the callbacks registered by <tt>SWIG_main()</tt> above.
@ -553,8 +528,7 @@ list item: listval5
The representation and manipulation of types is currently in the
process of being reorganized and (hopefully) simplified. The
following list describes the current set of functions that are used to
manipulate datatypes. These functions are different than in
SWIG1.1 and may change names in the final SWIG1.3 release.
manipulate datatypes.
<ul>
<li><tt>SwigType_str(SwigType *t, char *name)</tt>.<br>
@ -710,19 +684,7 @@ repeated calls without making any copies.
[TODO]
<a name="5" href="#i5">
<h2>5. Difference Between SWIG 1.1 and SWIG 1.3</h2>
</a>
[TODO]
<a name="6" href="#i6">
<h2>6. Plans for SWIG 2.0</h2>
</a>
[TODO]
<a name="7" href="#i7">
<h2>7. The C/C++ Wrapping Layer</h2>
<h2>5. The C/C++ Wrapping Layer</h2>
</a>
Added: Dave Beazley (July 22, 2000)
@ -1001,8 +963,8 @@ for specifying local variable declarations and argument conversions.
<a name="8" href="#i8">
<h2>8. Symbol Naming Guidelines for Generated C/C++ Code</h2>
<a name="6" href="#i6">
<h2>6. Symbol Naming Guidelines for Generated C/C++ Code</h2>
</a>
The C++ standard (ISO/IEC 14882:1998(E)) states:
<blockquote>
@ -1048,18 +1010,142 @@ For code compiled as C or C++ that attempts to mangle a wrapped symbol:
In the past SWIG has generated many symbols which flout the standard especially double underscores. In fact they may not all be rooted out yet, so please fix them when you see them.
<a name="9" href="#i9">
<h2>9. Debugging SWIG</h2>
<a name="7" href="#i7">
<h2>7. Debugging SWIG</h2>
</a>
Warning. Debugging SWIG is for the very patient.
<p>
The DOH types used in the SWIG source code are all typedefined to void.
Consequently, it is impossible for debuggers to automatically extract any information about DOH objects.
The easiest approach to debugging and viewing the contents of DOH objects is to make a call into one of the family of SWIG print functions from the debugger.
The "Debugging Functions" section in <a href="tree.html">SWIG Parse Tree Handling</a> lists them.
It is sometimes easier to debug by placing a few calls to these functions in code of interest and recompile, especially if your debugger cannot easily make calls into functions within a debugged binary.
</p>
<p>
The SWIG distribution comes with some additional support for the gdb debugger in the <tt>Tools/swig.gdb</tt> file.
Follow the instructions in this file for 'installing'.
This support file provides an easy way to call into some of the family of SWIG print functions via additional user-defined gdb commands.
Some usage of the <tt>swigprint</tt> and <tt>locswigprint</tt> user-defined commands are demonstrated below.
</p>
<p>
More often than not, a parse tree node needs to be examined.
The session below displays the node <tt>n</tt> in one of the Java language module wrapper functions.
The <tt>swigprint</tt> method is used to show the symbol name (<tt>symname</tt> - a DOH String type) and the node (<tt>n</tt> - a DOH Hash type).
</p>
<blockquote>
<pre>
Breakpoint 1, JAVA::functionWrapper (this=0x97ea5f0, n=0xb7d2afc8) at Modules/java.cxx:799
799 String *symname = Getattr(n, "sym:name");
(gdb) next
800 SwigType *t = Getattr(n, "type");
(gdb) swigprint symname
Shape_x_set
(gdb) swigprint n
Hash(0xb7d2afc8) {
'membervariableHandler:view' : variableHandler,
'feature:except' : 0,
'name' : x,
'ismember' : 1,
'sym:symtab' : Hash(0xb7d2aca8) {......},
'nodeType' : cdecl,
'nextSibling' : Hash(0xb7d2af98) {.............},
'kind' : variable,
'variableHandler:feature:immutable' : &lt;Object 'VoidObj' at 0xb7cfa008&gt;,
'sym:name' : Shape_x_set,
'view' : membervariableHandler,
'membervariableHandler:sym:name' : x,
'membervariableHandler:type' : double,
'membervariableHandler:parms' : &lt;Object 'VoidObj' at 0xb7cfa008&gt;,
'parentNode' : Hash(0xb7d2abc8) {..............................},
'feature:java:enum' : typesafe,
'access' : public,
'parms' : Hash(0xb7cb9408) {......},
'wrap:action' : if (arg1) (arg1)-&gt;x = arg2;,
'type' : void,
'memberset' : 1,
'sym:overname' : __SWIG_0,
'membervariableHandler:name' : x,
}
</pre>
</blockquote>
<p>
Note that all the attributes in the Hash are shown, including the 'sym:name' attribute which was assigned to the <tt>symname</tt> variable.
</p>
<p>
Hash types can be shown either expanded or collapsed.
When a Hash is shown expanded, all the attributes are displayed along with their values, otherwise a '.' replaces each attribute when collapsed.
Therefore a count of the dots provides the number of attributes within an unexpanded Hash.
Below shows the 'parms' Hash being displayed with the default Hash expansion of 1, then with 2 provided as the second argument to <tt>swigprint</tt> to expand to two Hash levels in order to view the contents of the collapsed 'nextSibling' Hash.
</p>
<blockquote>
<pre>
(gdb) swigprint 0xb7cb9408
Hash(0xb7cb9408) {
'name' : self,
'type' : p.Shape,
'self' : 1,
'nextSibling' : Hash(0xb7cb9498) {...},
'hidden' : 1,
'nodeType' : parm,
}
(gdb) swigprint 0xb7cb9408 2
Hash(0xb7cb9408) {
'name' : self,
'type' : p.Shape,
'self' : 1,
'nextSibling' : Hash(0xb7cb9498) {
'name' : x,
'type' : double,
'nodeType' : parm,
},
'hidden' : 1,
'nodeType' : parm,
}
</pre>
</blockquote>
<p>
The same Hash can also be displayed with file and line location information via the <tt>locswigprint</tt> command.
</p>
<blockquote>
<pre>
(gdb) locswigprint 0xb7cb9408
example.h:11: [Hash(0xb7cb9408) {
Hash(0xb7cb9408) {
'name' : self,
'type' : p.Shape,
'self' : 1,
'nextSibling' : Hash(0xb7cb9498) {...},
'hidden' : 1,
'nodeType' : parm,
}]
</pre>
</blockquote>
<p>
<b>Tip</b>: Commands in gdb can be shortened with whatever makes them unique and can be command completed with the tab key.
Thus <tt>swigprint</tt> can usually be shortened to <tt>sw</tt> and <tt>locswigprint</tt> to <tt>loc</tt>.
The help for each command can also be obtained within the debugging session, for example, 'help swigprint'.
</p>
<p>
The sub-section below gives pointers for debugging DOH objects using casts and provides an insight into why it can be hard to debug SWIG without the family of print functions.
<p>
The DOH types are all typedefined to void.
Consequently, it is impossible for debuggers to extract any information about DOH objects.
Most debuggers will be able to display useful variable information when an object is cast to the appropriate type.
Below are some tips for displaying some of the DOH objects.
Be sure to compile with compiler optimisations turned off before attempting the casts shown in a debugger window else they are unlikely to work.
Even displaying the underlying string in a String* doesn't work straight off in all debuggers due to the multiple definition of String as a struct and a void.
<a name="7.1" href="#i7.1">
<h3>7.1 Debugging DOH Types The Hard Way</h3>
</a>
The DOH types used in SWIG are all typedefined to void and hence the lack of type information for inspecting types within a debugger.
Most debuggers will however be able to display useful variable information when an object is cast to the appropriate type.
Getting at the underlying C string within DOH types is cumbersome, but possible with appropriate casts.
The casts below can be used in a debugger windows, but be sure to compile with compiler optimisations turned off before attempting the casts else they are unlikely to work.
Even displaying the underlying string in a String * doesn't work straight off in all debuggers due to the multiple definitions of String as a struct and a void.
<p>
Below are a list of common SWIG types.
@ -1069,34 +1155,32 @@ With each is the cast that can be used in the debugger to extract the underlying
<p>
<li>String *s;</li>
<br>
(String *)((DohBase *)s)-&gt;data
<tt>(struct String *)((DohBase *)s)-&gt;data</tt>
<br>
The underlying char * string can be displayed with
<br>
((String *)((DohBase *)s)-&gt;data)-&gt;str
<tt>(*(struct String *)(((DohBase *)s)-&gt;data)).str</tt>
<p>
<li>SwigType *t;</li>
<br>
(String *)((DohBase *)t)-&gt;data
<tt>(struct String *)((DohBase *)t)-&gt;data</tt>
<br>
The underlying char * string can be displayed with
<br>
((String *)((DohBase *)t)-&gt;data)-&gt;str
<tt>(*(struct String *)(((DohBase *)t)-&gt;data)).str</tt>
<p>
<li>String_or_char *sc;</li>
<li>const_String_or_char_ptr sc;</li>
Either <br>
((String *)((DohBase *)sc)-&gt;data)-&gt;str
<tt>(*(struct String *)(((DohBase *)sc)-&gt;data)).str</tt>
<br> or <br>
(char *)sc
<tt>(char *)sc</tt>
<br> will work depending on whether the underlying type is really a String * or char *.
</ul>
<hr>
Copyright (C) 1999-2004 SWIG Development Team.
Copyright (C) 1999-2010 SWIG Development Team.
</body>
</html>

View file

@ -77,7 +77,7 @@ string prior to using this function.
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 ficticious token into order to enter a special parsing case.
return a fictitious token into order to enter a special parsing case.
</blockquote>
<p>
@ -238,7 +238,7 @@ SWIG_TOKEN_PERIOD .
SWIG_TOKEN_AT @
SWIG_TOKEN_DOLLAR $
SWIG_TOKEN_ENDLINE Literal newline
SWIG_TOKEN_ID identifer
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)
@ -281,8 +281,3 @@ using these functions to write a yacc-compatible lexer.
</body>
</html>

View file

@ -6,13 +6,6 @@
<body>
<center>
<h1>SWIG Parse Tree Handling</h1>
<p>
David M. Beazley <br>
dave-swig@dabeaz.com<br>
December, 2006<br>
</b>
</center>
<h2>Introduction</h2>
@ -210,7 +203,33 @@ This function restores a node to the state it was in prior to the last <tt>Swig_
<h2>Debugging Functions</h2>
The following functions are used to help debug SWIG parse trees.
<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>
@ -218,10 +237,10 @@ The following functions are used to help debug SWIG parse trees.
<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>-dump_tags</tt> option to SWIG.
This function is called by the <tt>-debug-tags</tt> option to SWIG.
<pre>
% swig -dump_tags -python example.i
% 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)
@ -243,7 +262,7 @@ Since many language modules include hundreds of typemaps and other information,
<blockquote>
Prints the contents of a parse tree node, including all children, to standard output. The output includes all attributes
and other details. The command line option <tt>-dump_tree</tt> produces output generated by this function.
and other details.
</blockquote>
<p>
@ -251,8 +270,8 @@ and other details. The command line option <tt>-dump_tree</tt> produces output
<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. Use the command line option <tt>-dump_tree</tt> to get
the output of this function for a SWIG input file.
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>

116
Doc/Manual/Allegrocl.html Executable file → Normal file
View file

@ -8,13 +8,13 @@
<body bgcolor="#ffffff">
<H1><a name="Allegrocl_nn1"></a>16 SWIG and Allegro Common Lisp</H1>
<H1><a name="Allegrocl"></a>17 SWIG and Allegro Common Lisp</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Allegrocl_nn2">Basics</a>
<ul>
<li><a href="#Allegrocl_nn3">Running Swig</a>
<li><a href="#Allegrocl_nn3">Running SWIG</a>
<li><a href="#Allegrocl_nn4">Command Line Options</a>
<li><a href="#Allegrocl_nn5">Inserting user code into generated files</a>
</ul>
@ -135,10 +135,10 @@ be unhappy to see some enterprising folk use this work to add
to it.
</p>
<H2><a name="Allegrocl_nn2"></a>16.1 Basics</H2>
<H2><a name="Allegrocl_nn2"></a>17.1 Basics</H2>
<H3><a name="Allegrocl_nn3"></a>16.1.1 Running Swig</H3>
<H3><a name="Allegrocl_nn3"></a>17.1.1 Running SWIG</H3>
<p>
@ -360,7 +360,7 @@ need to link in the Allegro shared library. The library you create from
the C++ wrapper will be what you then load into Allegro CL.
</p>
<H3><a name="Allegrocl_nn4"></a>16.1.2 Command Line Options</H3>
<H3><a name="Allegrocl_nn4"></a>17.1.2 Command Line Options</H3>
<p>
@ -396,7 +396,7 @@ See <a href="#Allegrocl_nn47">Section 17.5 Identifier converter
functions</a> for more details.
</p>
<H3><a name="Allegrocl_nn5"></a>16.1.3 Inserting user code into generated files</H3>
<H3><a name="Allegrocl_nn5"></a>17.1.3 Inserting user code into generated files</H3>
<p>
@ -411,7 +411,7 @@ using the SWIG <tt>%insert(section) %{ ...code... %}</tt> directive:
<pre>
%module example
%insert("runtime") %{
%{
#include "header.h"
%}
@ -432,11 +432,11 @@ generated lisp interface file
</ul>
<p>
Note that the block <tt>%{ ... %}</tt> is effectively a shortcut for
<tt>%insert("runtime") %{ ... %}</tt>.
<tt>%insert("header") %{ ... %}</tt>.
</p>
<H2><a name="Allegrocl_nn6"></a>16.2 Wrapping Overview</H2>
<H2><a name="Allegrocl_nn6"></a>17.2 Wrapping Overview</H2>
<p>
@ -446,7 +446,7 @@ New users to SWIG are encouraged to read
interested in generating an interface to C++.
</p>
<H3><a name="Allegrocl_nn7"></a>16.2.1 Function Wrapping</H3>
<H3><a name="Allegrocl_nn7"></a>17.2.1 Function Wrapping</H3>
<p>
@ -499,7 +499,7 @@ interested in generating an interface to C++.
</pre>
</div>
<H3><a name="Allegrocl_nn8"></a>16.2.2 Foreign Wrappers</H3>
<H3><a name="Allegrocl_nn8"></a>17.2.2 Foreign Wrappers</H3>
<p>
@ -512,7 +512,7 @@ interested in generating an interface to C++.
typemap.
</p>
<H3><a name="Allegrocl_nn9"></a>16.2.3 FFI Wrappers</H3>
<H3><a name="Allegrocl_nn9"></a>17.2.3 FFI Wrappers</H3>
<p>
@ -593,7 +593,7 @@ char *xxx();
ff:def-foreign-call's.
</p>
<H3><a name="Allegrocl_nn10"></a>16.2.4 Non-overloaded Defuns</H3>
<H3><a name="Allegrocl_nn10"></a>17.2.4 Non-overloaded Defuns</H3>
<p>
@ -606,7 +606,7 @@ char *xxx();
this function can be manipulated via the <tt>lout</tt> typemap.
</p>
<H3><a name="Allegrocl_nn11"></a>16.2.5 Overloaded Defuns</H3>
<H3><a name="Allegrocl_nn11"></a>17.2.5 Overloaded Defuns</H3>
<p>
@ -622,7 +622,7 @@ char *xxx();
can be manipulated via the <tt>lout</tt> typemap.
</p>
<H3><a name="Allegrocl_nn12"></a>16.2.6 What about constant and variable access?</H3>
<H3><a name="Allegrocl_nn12"></a>17.2.6 What about constant and variable access?</H3>
<p>
@ -635,7 +635,7 @@ char *xxx();
into the foreign module.
</p>
<H3><a name="Allegrocl_nn13"></a>16.2.7 Object Wrapping</H3>
<H3><a name="Allegrocl_nn13"></a>17.2.7 Object Wrapping</H3>
<p>
@ -657,7 +657,7 @@ char *xxx();
foreign function interface.
</p>
<H2><a name="Allegrocl_nn14"></a>16.3 Wrapping Details</H2>
<H2><a name="Allegrocl_nn14"></a>17.3 Wrapping Details</H2>
<p>
@ -665,7 +665,7 @@ char *xxx();
translated into lisp.
</p>
<H3><a name="Allegrocl_nn15"></a>16.3.1 Namespaces</H3>
<H3><a name="Allegrocl_nn15"></a>17.3.1 Namespaces</H3>
<p>
@ -742,7 +742,7 @@ namespace car {
function such as <tt>(car '(1 2 3)</tt>.
</p>
<H3><a name="Allegrocl_nn16"></a>16.3.2 Constants</H3>
<H3><a name="Allegrocl_nn16"></a>17.3.2 Constants</H3>
@ -803,7 +803,7 @@ namespace car {
not use the <tt>-nocwrap</tt> command-line option.
</p>
<H3><a name="Allegrocl_nn17"></a>16.3.3 Variables</H3>
<H3><a name="Allegrocl_nn17"></a>17.3.3 Variables</H3>
<p>
@ -881,7 +881,7 @@ globalvar&gt; (globalvar.nnn::glob_float)
</pre>
</div>
<H3><a name="Allegrocl_nn18"></a>16.3.4 Enumerations</H3>
<H3><a name="Allegrocl_nn18"></a>17.3.4 Enumerations</H3>
<p>
@ -957,7 +957,7 @@ EXPORT const int ACL_ENUM___FOO3__SWIG_0 = FOO3;
</pre>
</div>
<H3><a name="Allegrocl_nn19"></a>16.3.5 Arrays</H3>
<H3><a name="Allegrocl_nn19"></a>17.3.5 Arrays</H3>
<p>
@ -1105,10 +1105,10 @@ namespace BAR {
</pre>
</div>
<H3><a name="Allegrocl_nn20"></a>16.3.6 Classes and Structs and Unions (oh my!)</H3>
<H3><a name="Allegrocl_nn20"></a>17.3.6 Classes and Structs and Unions (oh my!)</H3>
<H4><a name="Allegrocl_nn21"></a>16.3.6.1 CLOS wrapping of</H4>
<H4><a name="Allegrocl_nn21"></a>17.3.6.1 CLOS wrapping of</H4>
<p>
@ -1123,7 +1123,7 @@ namespace BAR {
integer values.
</p>
<H4><a name="Allegrocl_nn22"></a>16.3.6.2 CLOS Inheritance</H4>
<H4><a name="Allegrocl_nn22"></a>17.3.6.2 CLOS Inheritance</H4>
<p>
@ -1136,7 +1136,7 @@ namespace BAR {
parameter.
</p>
<H4><a name="Allegrocl_nn23"></a>16.3.6.3 Member fields and functions</H4>
<H4><a name="Allegrocl_nn23"></a>17.3.6.3 Member fields and functions</H4>
<p>
@ -1152,7 +1152,7 @@ namespace BAR {
the interface does nothing for <tt>friend</tt> directives,
</p>
<H4><a name="Allegrocl_nn24"></a>16.3.6.4 Why not directly access C++ classes using foreign types?</H4>
<H4><a name="Allegrocl_nn24"></a>17.3.6.4 Why not directly access C++ classes using foreign types?</H4>
<p>
@ -1170,11 +1170,11 @@ namespace BAR {
use the more robust wrapper functions.
</p>
<H3><a name="Allegrocl_nn25"></a>16.3.7 Templates</H3>
<H3><a name="Allegrocl_nn25"></a>17.3.7 Templates</H3>
<H4><a name="Allegrocl_nn26"></a>16.3.7.1 Generating wrapper code for templates</H4>
<H4><a name="Allegrocl_nn26"></a>17.3.7.1 Generating wrapper code for templates</H4>
<p>
@ -1187,7 +1187,7 @@ namespace BAR {
directive.
</p>
<H4><a name="Allegrocl_nn27"></a>16.3.7.2 Implicit Template instantiation</H4>
<H4><a name="Allegrocl_nn27"></a>17.3.7.2 Implicit Template instantiation</H4>
<p>
@ -1197,7 +1197,7 @@ namespace BAR {
class schema.
</p>
<H3><a name="Allegrocl_nn28"></a>16.3.8 Typedef, Templates, and Synonym Types</H3>
<H3><a name="Allegrocl_nn28"></a>17.3.8 Typedef, Templates, and Synonym Types</H3>
<p>
@ -1277,7 +1277,7 @@ synonym&gt;
</pre>
</div>
<H4><a name="Allegrocl_nn29"></a>16.3.8.1 Choosing a primary type</H4>
<H4><a name="Allegrocl_nn29"></a>17.3.8.1 Choosing a primary type</H4>
<p>
@ -1298,7 +1298,7 @@ synonym&gt;
</li>
</ul>
<H3><a name="Allegrocl_nn30"></a>16.3.9 Function overloading/Parameter defaulting</H3>
<H3><a name="Allegrocl_nn30"></a>17.3.9 Function overloading/Parameter defaulting</H3>
<p>
@ -1461,7 +1461,7 @@ overload&gt;
</pre>
</div>
<H3><a name="Allegrocl_nn31"></a>16.3.10 Operator wrapping and Operator overloading</H3>
<H3><a name="Allegrocl_nn31"></a>17.3.10 Operator wrapping and Operator overloading</H3>
<p>
@ -1607,7 +1607,7 @@ opoverload&gt;
</pre>
</div>
<H3><a name="Allegrocl_nn32"></a>16.3.11 Varargs</H3>
<H3><a name="Allegrocl_nn32"></a>17.3.11 Varargs</H3>
<p>
@ -1628,7 +1628,7 @@ opoverload&gt;
with other ways such functions can be wrapped.
</p>
<H3><a name="Allegrocl_nn33"></a>16.3.12 C++ Exceptions</H3>
<H3><a name="Allegrocl_nn33"></a>17.3.12 C++ Exceptions</H3>
<p>
@ -1640,7 +1640,7 @@ opoverload&gt;
implemented.
</p>
<H3><a name="Allegrocl_nn34"></a>16.3.13 Pass by value, pass by reference</H3>
<H3><a name="Allegrocl_nn34"></a>17.3.13 Pass by value, pass by reference</H3>
<p>
@ -1652,7 +1652,7 @@ opoverload&gt;
newly defined types.
</p>
<H2><a name="Allegrocl_nn35"></a>16.4 Typemaps</H2>
<H2><a name="Allegrocl_nn35"></a>17.4 Typemaps</H2>
<p>
@ -1663,7 +1663,7 @@ opoverload&gt;
on <a href="Typemaps.html#Typemaps">Typemaps</a> for more information.
</p>
<H3><a name="Allegrocl_nn36"></a>16.4.1 Code Generation in the C++ Wrapper</H3>
<H3><a name="Allegrocl_nn36"></a>17.4.1 Code Generation in the C++ Wrapper</H3>
@ -1693,7 +1693,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
</pre>
</div>
<H4><a name="Allegrocl_nn37"></a>16.4.1.1 IN Typemap</H4>
<H4><a name="Allegrocl_nn37"></a>17.4.1.1 IN Typemap</H4>
<p>
@ -1728,7 +1728,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
</pre>
</div>
<H4><a name="Allegrocl_nn38"></a>16.4.1.2 OUT Typemap</H4>
<H4><a name="Allegrocl_nn38"></a>17.4.1.2 OUT Typemap</H4>
<p>
@ -1752,7 +1752,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
</pre>
</div>
<H4><a name="Allegrocl_nn39"></a>16.4.1.3 CTYPE Typemap</H4>
<H4><a name="Allegrocl_nn39"></a>17.4.1.3 CTYPE Typemap</H4>
<p>
@ -1777,14 +1777,14 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
</div>
<p>
These three typemaps are specifically employed by the the
These three typemaps are specifically employed by the
Allegro CL interface generator. SWIG also implements a number of
other typemaps that can be used for generating code in the C/C++
wrappers. You can read about
these <a href="Typemaps.html#Typemaps_nn25">common typemaps</a> here.
</p>
<H3><a name="Allegrocl_nn40"></a>16.4.2 Code generation in Lisp wrappers</H3>
<H3><a name="Allegrocl_nn40"></a>17.4.2 Code generation in Lisp wrappers</H3>
<p>
@ -1803,7 +1803,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
<a href="#Allegrocl_nn15">16.3.1 Namespaces</a> for details.
</p>
<H4><a name="Allegrocl_nn41"></a>16.4.2.1 LIN Typemap</H4>
<H4><a name="Allegrocl_nn41"></a>17.4.2.1 LIN Typemap</H4>
<p>
@ -1846,7 +1846,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
</pre>
</div>
<H4><a name="Allegrocl_nn42"></a>16.4.2.2 LOUT Typemap</H4>
<H4><a name="Allegrocl_nn42"></a>17.4.2.2 LOUT Typemap</H4>
<p>
@ -1889,7 +1889,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
</pre>
</div>
<H4><a name="Allegrocl_nn43"></a>16.4.2.3 FFITYPE Typemap</H4>
<H4><a name="Allegrocl_nn43"></a>17.4.2.3 FFITYPE Typemap</H4>
@ -1939,7 +1939,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
</pre>
</div>
<H4><a name="Allegrocl_nn44"></a>16.4.2.4 LISPTYPE Typemap</H4>
<H4><a name="Allegrocl_nn44"></a>17.4.2.4 LISPTYPE Typemap</H4>
<p>
@ -1959,7 +1959,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
</pre>
</div>
<H4><a name="Allegrocl_nn45"></a>16.4.2.5 LISPCLASS Typemap</H4>
<H4><a name="Allegrocl_nn45"></a>17.4.2.5 LISPCLASS Typemap</H4>
<p>
@ -1983,7 +1983,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
</pre>
</div>
<H3><a name="Allegrocl_nn46"></a>16.4.3 Modifying SWIG behavior using typemaps</H3>
<H3><a name="Allegrocl_nn46"></a>17.4.3 Modifying SWIG behavior using typemaps</H3>
<p>
@ -2017,10 +2017,10 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
</pre>
</div>
<H2><a name="Allegrocl_nn47"></a>16.5 Identifier Converter functions</H2>
<H2><a name="Allegrocl_nn47"></a>17.5 Identifier Converter functions</H2>
<H3><a name="Allegrocl_nn48"></a>16.5.1 Creating symbols in the lisp environment</H3>
<H3><a name="Allegrocl_nn48"></a>17.5.1 Creating symbols in the lisp environment</H3>
<p>
@ -2041,11 +2041,11 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
of arguments.
</p>
<H3><a name="Allegrocl_nn49"></a>16.5.2 Existing identifier-converter functions</H3>
<H3><a name="Allegrocl_nn49"></a>17.5.2 Existing identifier-converter functions</H3>
<p>Two basic identifier routines have been defined.
<H4><a name="Allegrocl_nn50"></a>16.5.2.1 identifier-convert-null</H4>
<H4><a name="Allegrocl_nn50"></a>17.5.2.1 identifier-convert-null</H4>
<p>
@ -2054,7 +2054,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
strings, from which a symbol will be created.
</p>
<H4><a name="Allegrocl_nn51"></a>16.5.2.2 identifier-convert-lispify</H4>
<H4><a name="Allegrocl_nn51"></a>17.5.2.2 identifier-convert-lispify</H4>
<p>
@ -2063,7 +2063,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
same symbol transformations.
</p>
<H4><a name="Allegrocl_nn52"></a>16.5.2.3 Default identifier to symbol conversions</H4>
<H4><a name="Allegrocl_nn52"></a>17.5.2.3 Default identifier to symbol conversions</H4>
<p>
@ -2072,7 +2072,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
default naming conventions.
</p>
<H3><a name="Allegrocl_nn53"></a>16.5.3 Defining your own identifier-converter</H3>
<H3><a name="Allegrocl_nn53"></a>17.5.3 Defining your own identifier-converter</H3>
<p>
@ -2128,7 +2128,7 @@ indicating the number of arguments passed to the routine indicated by
this identifier.
</p>
<H3><a name="Allegrocl_nn54"></a>16.5.4 Instructing SWIG to use a particular identifier-converter</H3>
<H3><a name="Allegrocl_nn54"></a>17.5.4 Instructing SWIG to use a particular identifier-converter</H3>
<p>

749
Doc/Manual/Android.html Normal file
View file

@ -0,0 +1,749 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Android</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="Android"></a>18 SWIG and Android</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Android_overview">Overview</a>
<li><a href="#Android_examples">Android examples</a>
<ul>
<li><a href="#Android_examples_intro">Examples introduction</a>
<li><a href="#Android_example_simple">Simple C example</a>
<li><a href="#Android_example_class">C++ class example</a>
</ul>
</ul>
</div>
<!-- INDEX -->
<p>
This chapter describes SWIG's support of Android.
</p>
<H2><a name="Android_overview"></a>18.1 Overview</H2>
<p>
The Android chapter is fairly short as support for Android is the same as for Java, where the Java Native Interface (JNI) is
used to call from Android Java into C or C++ compiled code.
Everything in the <a href="Java.html">Java chapter</a> applies to generating code for access from Android Java code.
This chapter contains a few Android specific notes and examples.
</p>
<H2><a name="Android_examples"></a>18.2 Android examples</H2>
<H3><a name="Android_examples_intro"></a>18.2.1 Examples introduction</H3>
<p>
The examples require the the <a href="http://developer.android.com/sdk/index.html">Android SDK</a> and <a href="http://developer.android.com/sdk/ndk/index.html">Android NDK</a> which can be installed as per instructions in the links.
The Eclipse version is not required for these examples as just the command line tools are used (shown for Linux as the host, but Windows will be very similar, if not identical in most places).
Add the SDK tools and NDK tools to your path and create a directory somewhere for your Android projects (adjust PATH as necessary to where you installed the tools):
</p>
<div class="shell">
<pre>
$ export PATH=$HOME/android/android-sdk-linux_x86/tools:$HOME/android/android-sdk-linux_x86/platform-tools:$HOME/android/android-ndk-r6b:$PATH
$ mkdir AndroidApps
$ cd AnrdoidApps
</pre>
</div>
<p>
The examples use a target id of 1. This might need changing depending on your setup.
After installation of the Android SDK, the available target ids can be viewed by running the command below.
Please adjust the id to suit your target device.
</p>
<div class="shell">
<pre>
$ android list targets
</pre>
</div>
<p>
The following examples are shipped with SWIG under the Examples/android directory and include a Makefile to build and install each example.
</p>
<H3><a name="Android_example_simple"></a>18.2.2 Simple C example</H3>
<p>
This simple C example shows how to call a C function as well as read and modify a global variable.
First we'll create and build a pure Java Android app. Afterwards the JNI code will be generated by SWIG and built into the app.
First create and build an app called <tt>SwigSimple</tt> in a subdirectory called <tt>simple</tt> using the commands below.
Adjust the <tt>--target</tt> id as mentioned earlier in the <a href="Android.html#Android_examples_intro">Examples introduction</a>.
<a href="http://developer.android.com/guide/developing/projects/projects-cmdline.html">Managing Projects from the Command Line</a> on the Android developer's site is a useful reference for these steps.
</p>
<div class="shell">
<pre>
$ android create project --target 1 --name SwigSimple --path ./simple --activity SwigSimple --package org.swig.simple
$ cd simple
$ ant debug
</pre>
</div>
<p>
Modify <tt>src/org/swig/simple/SwigSimple.java</tt> from the default to:
</p>
<div class="code">
<pre>
package org.swig.simple;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ScrollView;
import android.text.method.ScrollingMovementMethod;
public class SwigSimple extends Activity
{
TextView outputText = null;
ScrollView scroller = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
outputText = (TextView)findViewById(R.id.OutputText);
outputText.setText("Press 'Run' to start...\n");
outputText.setMovementMethod(new ScrollingMovementMethod());
scroller = (ScrollView)findViewById(R.id.Scroller);
}
public void onRunButtonClick(View view)
{
outputText.append("Started...\n");
nativeCall();
outputText.append("Finished!\n");
// Ensure scroll to end of text
scroller.post(new Runnable() {
public void run() {
scroller.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
/** Calls into C/C++ code */
public void nativeCall()
{
// TODO
}
}
</pre>
</div>
<p>
The above simply adds a <i>Run</i> button and scrollable text view as the GUI aspects of the program.
The associated resources need to be created, modify <tt>res/layout/main.xml</tt> as follows:
</p>
<div class="code">
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
&gt;
&lt;Button
android:id="@+id/RunButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Run..."
android:onClick="onRunButtonClick"
/&gt;
&lt;ScrollView
android:id="@+id/Scroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
&gt;
&lt;TextView
android:id="@+id/OutputText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/&gt;
&lt;/ScrollView&gt;
&lt;/LinearLayout&gt;
</pre>
</div>
<p>
Rebuild the project with your changes:
</p>
<div class="shell">
<pre>
$ ant debug
</pre>
</div>
<p>
Although there are no native function calls in the code, yet, you may want to check that this simple pure
Java app runs before adding in the native calls.
First, set up your Android device for hardware debugging, see <a href="http://developer.android.com/guide/developing/device.html">Using hardware devices</a> on the Android developer's site.
When complete your device should be listed in those attached, something like:
</p>
<div class="shell">
<pre>
$ adb devices
List of devices attached
A32-6DBE0001-9FF80000-015D62C3-02018028 device
</pre>
</div>
<p>
This means you are now ready to install the application...
</p>
<div class="shell">
<pre>
$ adb install bin/SwigSimple-debug.apk
95 KB/s (4834 bytes in 0.049s)
pkg: /data/local/tmp/SwigSimple-debug.apk
Success
</pre>
</div>
<p>
The newly installed 'SwigSimple' app will be amongst all your other applications on the home screen. Run the app and it will show a <i>Run</i> button text box below it.
Press the <i>Run</i> button to see the simple text output.
</p>
<p>
The application can be uninstalled like any other application and in fact must be uninstalled before installing an updated version. Uninstalling is quite easy too from your host computer:
</p>
<div class="shell">
<pre>
$ adb uninstall org.swig.simple
Success
</pre>
</div>
<p>
Now that you have a pure Java Android app working, let's add some JNI code generated from SWIG.
</p>
<p>
First create a <tt>jni</tt> subdirectory and then create some C source code in <tt>jni/example.c</tt>:
</p>
<div class="code">
<pre>
/* File : example.c */
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x &gt; 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
</pre>
</div>
<p>
Create a SWIG interface file for this C code, <tt>jni/example.i</tt>:
</p>
<div class="code">
<pre>
/* File : example.i */
%module example
%inline %{
extern int gcd(int x, int y);
extern double Foo;
%}
</pre>
</div>
<p>
Invoke SWIG as follows:
</p>
<div class="shell">
<pre>
$ swig -java -package org.swig.simple -outdir src/org/swig/simple -o jni/example_wrap.c jni/example.i
</pre>
</div>
<p>
SWIG generates the following files:
</p>
<ul>
<li><tt>src/org/swig/simple/exampleJNI.java</tt></li>
<li><tt>src/org/swig/simple/example.java</tt></li>
<li><tt>jni/example_wrap.c</tt></li>
</ul>
<p>
Next we need to create a standard Android NDK build system file <tt>jni/Android.mk</tt>:
</p>
<div class="code">
<pre>
# File: Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := example
LOCAL_SRC_FILES := example_wrap.c example.c
include $(BUILD_SHARED_LIBRARY)
</pre>
</div>
<p>
See the <a href="http://developer.android.com/sdk/ndk/index.html">Android NDK documentation</a> for more on the NDK build system and getting started with the NDK.
A simple invocation of ndk-build will compile the .c files and generate a shared object/system library. Output will be similar to:
</p>
<div class="shell">
<pre>
$ ndk-build
Compile thumb : example &lt;= example_wrap.c
Compile thumb : example &lt;= example.c
SharedLibrary : libexample.so
Install : libexample.so =&gt; libs/armeabi/libexample.so
</pre>
</div>
<p>
Now that the C JNI layer has been built, we can write Java code to call into the this layer.
Modify the <tt>nativeCall</tt> method in <tt>src/org/swig/simple/SwigSimple.java</tt> to call the JNI code as follows and add the static constructor to load the system library containing the compiled JNI C code:
</p>
<div class="code">
<pre>
/** Calls into C/C++ code */
public void nativeCall()
{
// Call our gcd() function
int x = 42;
int y = 105;
int g = example.gcd(x,y);
outputText.append("The greatest common divisor of " + x + " and " + y + " is " + g + "\n");
// Manipulate the Foo global variable
// Output its current value
double foo = example.getFoo();
outputText.append("Foo = " + foo + "\n");
// Change its value
example.setFoo(3.1415926);
// See if the change took effect
outputText.append("Foo = " + example.getFoo() + "\n");
// Restore value
example.setFoo(foo);
}
/** static constructor */
static {
System.loadLibrary("example");
}
</pre>
</div>
<p>
Compile the Java code as usual, uninstall the old version of the app if still installed and re-install the new app:
</p>
<div class="shell">
<pre>
$ ant debug
$ adb uninstall org.swig.simple
$ adb install bin/SwigSimple-debug.apk
</pre>
</div>
<p>
Run the app again and this time you will see the output pictured below, showing the result of calls into the C code:
</p>
<center><img src="android-simple.png" alt="Android screenshot of SwigSimple example"></center>
<H3><a name="Android_example_class"></a>18.2.3 C++ class example</H3>
<p>
The steps for calling C++ code are almost identical to those in the previous C code example.
All the steps required to compile and use a simple hierarchy of classes for shapes are shown in this example.
</p>
<p>
First create an Android project called <tt>SwigClass</tt> in a subdirectory called <tt>class</tt>.
The steps below create and build a the JNI C++ app.
Adjust the <tt>--target</tt> id as mentioned earlier in the <a href="Android.html#Android_examples_intro">Examples introduction</a>.
</p>
<div class="shell">
<pre>
$ android create project --target 1 --name SwigClass --path ./class --activity SwigClass --package org.swig.classexample
$ cd class
</pre>
</div>
<p>
Now create a <tt>jni</tt> subdirectory and then create a C++ header file <tt>jni/example.h</tt> which defines our
hierarchy of shape classes:
</p>
<div class="code">
<pre>
/* File : example.h */
class Shape {
public:
Shape() {
nshapes++;
}
virtual ~Shape() {
nshapes--;
};
double x, y;
void move(double dx, double dy);
virtual double area(void) = 0;
virtual double perimeter(void) = 0;
static int nshapes;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { };
virtual double area(void);
virtual double perimeter(void);
};
class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { };
virtual double area(void);
virtual double perimeter(void);
};
</pre>
</div>
<p>
and create the implementation in the <tt>jni/example.cpp</tt> file:
</p>
<div class="code">
<pre>
/* File : example.cpp */
#include "example.h"
#define M_PI 3.14159265358979323846
/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
x += dx;
y += dy;
}
int Shape::nshapes = 0;
double Circle::area(void) {
return M_PI*radius*radius;
}
double Circle::perimeter(void) {
return 2*M_PI*radius;
}
double Square::area(void) {
return width*width;
}
double Square::perimeter(void) {
return 4*width;
}
</pre>
</div>
<p>
Create a SWIG interface file for this C++ code in <tt>jni/example.i</tt>:
</p>
<div class="code">
<pre>
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Let's just grab the original header file here */
%include "example.h"
</pre>
</div>
<p>
Invoke SWIG as follows, note that the -c++ option is required for C++ code:
</p>
<div class="shell">
<pre>
$ swig -c++ -java -package org.swig.classexample -outdir src/org/swig/classexample -o jni/example_wrap.cpp jni/example.i
</pre>
</div>
<p>
SWIG generates the following files:
</p>
<ul>
<li><tt>src/org/swig/classexample/Square.java</tt></li>
<li><tt>src/org/swig/classexample/exampleJNI.java</tt></li>
<li><tt>src/org/swig/classexample/example.java</tt></li>
<li><tt>src/org/swig/classexample/Circle.java</tt></li>
<li><tt>src/org/swig/classexample/Shape.java</tt></li>
<li><tt>jni/example_wrap.cpp</tt></li>
</ul>
<p>
Next we need to create an Android NDK build system file for compiling the C++ code <tt>jni/Android.mk</tt>.
The <tt>-frtti</tt> compiler flag isn't strictly needed for this example, but is needed for any code that uses C++ RTTI:
</p>
<div class="code">
<pre>
# File: Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := example
LOCAL_SRC_FILES := example_wrap.cpp example.cpp
LOCAL_CFLAGS := -frtti
include $(BUILD_SHARED_LIBRARY)
</pre>
</div>
<p>
A simple invocation of ndk-build will compile the .cpp files and generate a shared object/system library. Output will be similar to:
</p>
<div class="shell">
<pre>
$ ndk-build
Compile++ thumb : example &lt;= example_wrap.cpp
Compile++ thumb : example &lt;= example.cpp
StaticLibrary : libstdc++.a
SharedLibrary : libexample.so
Install : libexample.so =&gt; libs/armeabi/libexample.so
</pre>
</div>
<p>
Now that the C JNI layer has been built, we can write Java code to call into this layer.
Modify <tt>src/org/swig/classexample/SwigClass.java</tt> from the default to:
</p>
<div class="code">
<pre>
package org.swig.classexample;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ScrollView;
import android.text.method.ScrollingMovementMethod;
public class SwigClass extends Activity
{
TextView outputText = null;
ScrollView scroller = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
outputText = (TextView)findViewById(R.id.OutputText);
outputText.setText("Press 'Run' to start...\n");
outputText.setMovementMethod(new ScrollingMovementMethod());
scroller = (ScrollView)findViewById(R.id.Scroller);
}
public void onRunButtonClick(View view)
{
outputText.append("Started...\n");
nativeCall();
outputText.append("Finished!\n");
// Ensure scroll to end of text
scroller.post(new Runnable() {
public void run() {
scroller.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
/** Calls into C/C++ code */
public void nativeCall()
{
// ----- Object creation -----
outputText.append( "Creating some objects:\n" );
Circle c = new Circle(10);
outputText.append( " Created circle " + c + "\n");
Square s = new Square(10);
outputText.append( " Created square " + s + "\n");
// ----- Access a static member -----
outputText.append( "\nA total of " + Shape.getNshapes() + " shapes were created\n" );
// ----- Member data access -----
// Notice how we can do this using functions specific to
// the 'Circle' class.
c.setX(20);
c.setY(30);
// Now use the same functions in the base class
Shape shape = s;
shape.setX(-10);
shape.setY(5);
outputText.append( "\nHere is their current position:\n" );
outputText.append( " Circle = (" + c.getX() + " " + c.getY() + ")\n" );
outputText.append( " Square = (" + s.getX() + " " + s.getY() + ")\n" );
// ----- Call some methods -----
outputText.append( "\nHere are some properties of the shapes:\n" );
Shape[] shapes = {c,s};
for (int i=0; i&lt;shapes.length; i++)
{
outputText.append( " " + shapes[i].toString() + "\n" );
outputText.append( " area = " + shapes[i].area() + "\n" );
outputText.append( " perimeter = " + shapes[i].perimeter() + "\n" );
}
// Notice how the area() and perimeter() functions really
// invoke the appropriate virtual method on each object.
// ----- Delete everything -----
outputText.append( "\nGuess I'll clean up now\n" );
// Note: this invokes the virtual destructor
// You could leave this to the garbage collector
c.delete();
s.delete();
outputText.append( Shape.getNshapes() + " shapes remain\n" );
outputText.append( "Goodbye\n" );
}
/** static constructor */
static {
System.loadLibrary("example");
}
}
</pre>
</div>
<p>
Note the static constructor and the interesting JNI code is in the <tt>nativeCall</tt> method.
The remaining code deals with the GUI aspects which are identical to the previous C simple example. Modify <tt>res/layout/main.xml</tt> to contain the xml for the 'Run' button and scrollable text view:
</p>
<div class="code">
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
&gt;
&lt;Button
android:id="@+id/RunButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Run..."
android:onClick="onRunButtonClick"
/&gt;
&lt;ScrollView
android:id="@+id/Scroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
&gt;
&lt;TextView
android:id="@+id/OutputText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/&gt;
&lt;/ScrollView&gt;
&lt;/LinearLayout&gt;
</pre>
</div>
<p>
Compile the Java code as usual, uninstall the old version of the app if installed and re-install the new app:
</p>
<div class="shell">
<pre>
$ ant debug
$ adb uninstall org.swig.classexample
$ adb install bin/SwigClass-debug.apk
</pre>
</div>
<p>
Run the app to see the result of calling the C++ code from Java:
</p>
<center><img src="android-class.png" alt="Android screenshot of SwigClass example"></center>
</body>
</html>

View file

@ -30,8 +30,6 @@
<b>Disclaimer: This chapter is under construction.</b>
<p>
In Chapter 3, SWIG's treatment of basic datatypes and pointers was
described. In particular, primitive types such as <tt>int</tt> and
@ -83,7 +81,7 @@ One way to deal with this is to use the
%include "typemaps.i"
%apply double *OUTPUT { double *result };
%inlne %{
%inline %{
extern void add(double a, double b, double *result);
%}
</pre></div>
@ -351,7 +349,7 @@ function like this in an interface file :</p>
<div class="code"><pre>
%module example
%include typemaps.i
%include "typemaps.i"
...
%{
extern void negate(double *);

View file

@ -5,33 +5,42 @@
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="CSharp"></a>17 SWIG and C#</H1>
<H1><a name="CSharp"></a>19 SWIG and C#</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#csharp_introduction">Introduction</a>
<li><a href="#csharp_differences_java">Differences to the Java module</a>
<li><a href="#csharp_exceptions">C# Exceptions</a>
<li><a href="#CSharp_introduction">Introduction</a>
<li><a href="#CSharp_differences_java">Differences to the Java module</a>
<li><a href="#CSharp_void_pointers">Void pointers</a>
<li><a href="#CSharp_arrays">C# Arrays</a>
<ul>
<li><a href="#csharp_exception_example_check_typemap">C# exception example using "check" typemap</a>
<li><a href="#csharp_exception_example_percent_exception">C# exception example using %exception</a>
<li><a href="#csharp_exception_example_exception_specifications">C# exception example using exception specifications</a>
<li><a href="#csharp_custom_application_exception">Custom C# ApplicationException example</a>
<li><a href="#CSharp_arrays_swig_library">The SWIG C arrays library</a>
<li><a href="#CSharp_arrays_pinvoke_default_array_marshalling">Managed arrays using P/Invoke default array marshalling</a>
<li><a href="#CSharp_arrays_pinning">Managed arrays using pinning</a>
</ul>
<li><a href="#csharp_directors">C# Directors</a>
<li><a href="#CSharp_exceptions">C# Exceptions</a>
<ul>
<li><a href="#csharp_directors_example">Directors example</a>
<li><a href="#csharp_directors_implementation">Directors implementation</a>
<li><a href="#csharp_director_caveats">Director caveats</a>
<li><a href="#CSharp_exception_example_check_typemap">C# exception example using "check" typemap</a>
<li><a href="#CSharp_exception_example_percent_exception">C# exception example using %exception</a>
<li><a href="#CSharp_exception_example_exception_specifications">C# exception example using exception specifications</a>
<li><a href="#CSharp_custom_application_exception">Custom C# ApplicationException example</a>
</ul>
<li><a href="#csharp_typemap_examples">C# Typemap examples</a>
<li><a href="#CSharp_directors">C# Directors</a>
<ul>
<li><a href="#csharp_memory_management_member_variables">Memory management when returning references to member variables</a>
<li><a href="#csharp_memory_management_objects">Memory management for objects passed to the C++ layer</a>
<li><a href="#csharp_date_marshalling">Date marshalling using the csin typemap and associated attributes</a>
<li><a href="#csharp_date_properties">A date example demonstrating marshalling of C# properties</a>
<li><a href="#csharp_partial_classes">Turning wrapped classes into partial classes</a>
<li><a href="#csharp_extending_proxy_class">Extending proxy classes with additional C# code</a>
<li><a href="#CSharp_directors_example">Directors example</a>
<li><a href="#CSharp_directors_implementation">Directors implementation</a>
<li><a href="#CSharp_director_caveats">Director caveats</a>
</ul>
<li><a href="#CSharp_multiple_modules">Multiples modules</a>
<li><a href="#CSharp_typemap_examples">C# Typemap examples</a>
<ul>
<li><a href="#CSharp_memory_management_member_variables">Memory management when returning references to member variables</a>
<li><a href="#CSharp_memory_management_objects">Memory management for objects passed to the C++ layer</a>
<li><a href="#CSharp_date_marshalling">Date marshalling using the csin typemap and associated attributes</a>
<li><a href="#CSharp_date_properties">A date example demonstrating marshalling of C# properties</a>
<li><a href="#CSharp_partial_classes">Turning wrapped classes into partial classes</a>
<li><a href="#CSharp_extending_proxy_class">Extending proxy classes with additional C# code</a>
<li><a href="#CSharp_enum_underlying_type">Underlying type for enums</a>
</ul>
</ul>
</div>
@ -39,7 +48,7 @@
<H2><a name="csharp_introduction"></a>17.1 Introduction</H2>
<H2><a name="CSharp_introduction"></a>19.1 Introduction</H2>
<p>
@ -48,9 +57,9 @@ The wrapper code implementation uses C# and the Platform Invoke (PInvoke) interf
The PInvoke interface has been chosen over Microsoft's Managed C++ interface as it is portable to both Microsoft Windows and non-Microsoft platforms.
PInvoke is part of the ECMA/ISO C# specification.
It is also better suited for robust production environments due to the Managed C++ flaw called the
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vcconMixedDLLLoadingProblem.asp">Mixed DLL Loading Problem</a>.
Swig C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using
<a href="http://www.mono-project.com/">Mono</a> and <a href="http://www.dotgnu.org/pnet.html">Portable.NET</a>.
<a href="http://msdn.microsoft.com/en-us/library/aa290048(VS.71).aspx">Mixed DLL Loading Problem</a>.
SWIG C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using
<a href="http://www.mono-project.com/Main_Page">Mono</a> and <a href="http://www.dotgnu.org/pnet.html">Portable.NET</a>.
</p>
<p>
@ -59,7 +68,7 @@ The <a href="http://msdn.microsoft.com">Microsoft Developer Network (MSDN)</a> h
Monodoc, available from the Mono project, has a very useful section titled <a href="http://www.mono-project.com/Interop_with_Native_Libraries">Interop with native libraries</a>.
</p>
<H2><a name="csharp_differences_java"></a>17.2 Differences to the Java module</H2>
<H2><a name="CSharp_differences_java"></a>19.2 Differences to the Java module</H2>
<p>
@ -93,6 +102,12 @@ namespace com.bloggs.widget {
...
}
</pre></div>
Note that by default, the generated C# classes have no namespace and the module name is unrelated to namespaces. The module name is just like in Java and is merely used to name some of the generated classes.
</li>
<li>
The <a href="SWIGPlus.html#SWIGPlus_nspace">nspace feature</a> is also supported as described in this general section with a C# example.
Unlike Java which requires the use of the -package option when using the <tt>nspace</tt> feature, the -namespace option is not mandatory for C#.
</li>
<li>
@ -125,7 +140,7 @@ If it was used, it would generate an illegal runtime initialisation via a PInvok
C# doesn't support the notion of throws clauses.
Therefore there is no 'throws' typemap attribute support for adding exception classes to a throws clause.
Likewise there is no need for an equivalent to <tt>%javaexception</tt>.
In fact, throwing C# exceptions works quite differently, see <a href="CSharp.html#csharp_exceptions">C# Exceptions></a> below.
In fact, throwing C# exceptions works quite differently, see <a href="CSharp.html#CSharp_exceptions">C# Exceptions</a> below.
</li>
<li>
@ -156,6 +171,14 @@ javadestruct_derived -&gt; csdestruct_derived
</li>
<li>
<p>Typemap macros:</p>
<div class="code"><pre>
SWIG_JAVABODY_PROXY -&gt; SWIG_CSBODY_PROXY
SWIG_JAVABODY_TYPEWRAPPER -&gt; SWIG_CSBODY_TYPEWRAPPER
</pre></div>
</li>
<li>
<p>Additional typemaps:</p>
@ -194,6 +217,7 @@ jniclassinterfaces -&gt; imclassinterfaces
$javaclassname -&gt; $csclassname
$&amp;javaclassname -&gt; $&amp;csclassname
$*javaclassname -&gt; $*csclassname
$javaclazzname -&gt; $csclazzname
$javainput -&gt; $csinput
$jnicall -&gt; $imcall
</pre></div>
@ -201,7 +225,12 @@ $jnicall -&gt; $imcall
<li>
<p>
Unlike the "javain" typemap, the "csin" typemap does not support the 'pgcpp' attribute as the C# module does not have a premature garbage collection prevention parameter. The "csin" typemap supports an additional optional attribute called 'cshin'. It should contain the parameter type and name whenever a <a href="Java.html#java_constructor_helper_function">constructor helper function</a> is generated due to the 'pre' or 'post' attributes. Note that 'pre', 'post' and 'cshin' attributes are not used for marshalling the property set. Please see the <a href="#csharp_date_marshalling">Date marshalling example</a> and <a href="#CSharp.html#csharp_date_properties">Date marshalling of properties example</a> for further understanding.
Unlike the "javain" typemap, the "csin" typemap does not support the 'pgcpp' attribute as the C# module does not have a premature garbage collection prevention parameter.
The "csin" typemap supports additional optional attributes called 'cshin' and 'terminator'.
The 'cshin' attribute should contain the parameter type and name whenever a <a href="Java.html#Java_constructor_helper_function">constructor helper function</a> is generated due to the 'pre' or 'post' attributes.
The 'terminator' attribute normally just contains a closing brace for when the 'pre' attribute contains an opening brace, such as when a C# <tt>using</tt> or <tt>fixed</tt> block is started.
Note that 'pre', 'post', 'terminator' and 'cshin' attributes are not used for marshalling the property set.
Please see the <a href="#CSharp_date_marshalling">Date marshalling example</a> and <a href="#CSharp_date_properties">Date marshalling of properties example</a> for further understanding of these "csin" applicable attributes.
</p>
</li>
@ -237,7 +266,9 @@ public static extern IntPtr function(string jarg1);
<p>
Support for type attributes.
The 'imtype' and 'cstype' typemaps can have an optional <tt>inattributes</tt> and <tt>outattributes</tt> typemap attribute.
There are C# attributes and typemap attributes, don't get confused!!
The 'imtype' typemap can also have an optional <tt>directorinattributes</tt> and <tt>directoroutattributes</tt>
typemap attribute which attaches to director delegates, an implementation detail of directors, see <a href="#CSharp_directors_implementation">directors implementation</a>.
Note that there are C# attributes and typemap attributes, don't get confused between the two!!
The C# attributes specified in these typemap attributes are generated wherever the type is used in the C# wrappers.
These can be used to specify any C# attribute associated with a C/C++ type, but are more typically used for the C# <tt>MarshalAs</tt> attribute.
For example:
@ -281,12 +312,17 @@ These attributes are associated with the C/C++ parameter type or return type, wh
the attribute features and typemaps covered next.
Note that all these different C# attributes can be combined so that a method has more than one attribute.
</p>
<p>
The <tt>directorinattributes</tt> and <tt>directoroutattributes</tt> typemap attribute are attached to the delegates in the director class, for example, the SwigDelegateBase_0
</p>
</li>
<li>
<p>
Support for attaching C# attributes to wrapped methods and variables.
This is done using the <tt>%csattributes</tt> feature, see <a href="Customization.html#features">%feature directives</a>.
Support for attaching C# attributes to wrapped methods, variables and enum values.
This is done using the <tt>%csattributes</tt> feature, see <a href="Customization.html#Customization_features">%feature directives</a>.
Note that C# attributes are attached to proxy classes and enums using the <tt>csattributes</tt> typemap.
For example, imagine we have a custom attribute class, <tt>ThreadSafeAttribute</tt>, for labelling thread safety.
The following SWIG code shows how to attach this C# attribute to some methods and the class declaration itself:
@ -332,6 +368,38 @@ they can be added using the 'csvarin' and 'csvarout' typemaps respectively.
Note that the type used for the property is specified in the 'cstype' typemap.
If the 'out' attribute exists in this typemap, then the type used is from the 'out' attribute.
</p>
<p>
An example for attaching attributes to the enum and enum values is shown below.
</p>
<div class="code">
<pre>
%typemap(csattributes) Couleur "[System.ComponentModel.Description(\"Colours\")]"
%csattributes Rouge "[System.ComponentModel.Description(\"Red\")]"
%csattributes Vert "[System.ComponentModel.Description(\"Green\")]"
%inline %{
enum Couleur { Rouge, Orange, Vert };
%}
</pre>
</div>
<p>
which will result in the following C# enum:
</p>
<div class="code">
<pre>
[System.ComponentModel.Description("Colours")]
public enum Couleur {
[System.ComponentModel.Description("Red")]
Rouge,
Orange,
[System.ComponentModel.Description("Green")]
Vert
}
</pre>
</div>
</li>
<li>
@ -350,7 +418,7 @@ This feature is useful for some obscure cases where SWIG might get the <tt>virtu
</li>
<li>
<a name="csharp_module_directive"></a>
<a name="CSharp_module_directive"></a>
<p>
The name of the intermediary class can be changed from its default, that is, the module name with PINVOKE appended after it.
The module directive attribute <tt>imclassname</tt> is used to achieve this:
@ -385,7 +453,7 @@ if specified, otherwise it is equivalent to the <b>$module</b> special variable.
<p>
<b><tt>$imclassname</tt></b><br>
This special variable expands to the intermediary class name. For C# this is usually the same as '$modulePINVOKE' ('$moduleJNI' for Java),
unless the imclassname attribute is specified in the <a href="CSharp.html#csharp_module_directive">%module directive</a>.
unless the imclassname attribute is specified in the <a href="CSharp.html#CSharp_module_directive">%module directive</a>.
</p>
<p>
@ -397,7 +465,296 @@ Windows users can also get the examples working using a
<a href="http://www.cygwin.com">Cygwin</a> or <a href="http://www.mingw.org">MinGW</a> environment for automatic configuration of the example makefiles.
Any one of the three C# compilers (Portable.NET, Mono or Microsoft) can be detected from within a Cygwin or Mingw environment if installed in your path.
<H2><a name="csharp_exceptions"></a>17.3 C# Exceptions</H2>
<H2><a name="CSharp_void_pointers"></a>19.3 Void pointers</H2>
<p>
By default SWIG treats <tt>void *</tt> as any other pointer and hence marshalls it as a type wrapper class called <tt>SWIGTYPE_p_void</tt>.
If you want to marshall with the .NET <tt>System.IntPtr</tt> type instead, there is a simple set of named typemaps called
<tt>void *VOID_INT_PTR</tt> that can be used.
They can be applied like any other named typemaps:
</p>
<div class="code">
<pre>
%apply void *VOID_INT_PTR { void * }
void * f(void *v);
</pre>
</div>
<H2><a name="CSharp_arrays"></a>19.4 C# Arrays</H2>
<p>
There are various ways to pass arrays from C# to C/C++.
The default wrapping treats arrays as pointers and as such simple type wrapper classes are generated,
eg <tt>SWIGTYPE_p_int</tt> when wrapping the C type <tt>int []</tt> or <tt>int *</tt>.
This gives a rather restricted use of the underlying unmanaged code and the most practical way to use arrays is to enhance or customise
with one of the following three approaches; namely the SWIG C arrays library, P/Invoke default array marshalling or
pinned arrays.
</p>
<H3><a name="CSharp_arrays_swig_library"></a>19.4.1 The SWIG C arrays library</H3>
<p>
The C arrays library keeps all the array memory in the unmanaged layer.
The library is available to all language modules and is documented in the <a href="Library.html#Library_carrays">carrays.i library</a> section.
Please refer to this section for details, but for convenience, the C# usage for the two examples outlined there is shown below.
</p>
<p>
For the <tt>%array_functions</tt> example, the equivalent usage would be:
</p>
<div class="code">
<pre>
SWIGTYPE_p_double a = example.new_doubleArray(10); // Create an array
for (int i=0; i&lt;10; i++)
example.doubleArray_setitem(a,i,2*i); // Set a value
example.print_array(a); // Pass to C
example.delete_doubleArray(a); // Destroy array
</pre>
</div>
<p>
and for the <tt>%array_class</tt> example, the equivalent usage would be:
</p>
<div class="code">
<pre>
doubleArray c = new doubleArray(10); // Create double[10]
for (int i=0; i&lt;10; i++)
c.setitem(i, 2*i); // Assign values
example.print_array(c.cast()); // Pass to C
</pre>
</div>
<H3><a name="CSharp_arrays_pinvoke_default_array_marshalling"></a>19.4.2 Managed arrays using P/Invoke default array marshalling</H3>
<p>
In the P/Invoke default marshalling scheme, one needs to designate whether the invoked function will treat a managed
array parameter as input, output, or both. When the function is invoked, the CLR allocates a separate chunk of memory as big as the given managed array,
which is automatically released at the end of the function call. If the array parameter is marked as being input, the content of the managed array is copied
into this buffer when the call is made. Correspondingly, if the array parameter is marked as being output, the contents of the reserved buffer are copied
back into the managed array after the call returns. A pointer to this buffer
is passed to the native function.
</p>
<p>
The reason for allocating a separate buffer is to leave the CLR free to relocate the managed array object
during garbage collection. If the overhead caused by the copying is causing a significant performance penalty, consider pinning the managed array and
passing a direct reference as described in the next section.
</p>
<p>
For more information on the subject, see the
<a href="http://msdn.microsoft.com/en-us/library/z6cfh6e6(VS.80).aspx">Default Marshaling for Arrays</a> article
on MSDN.
</p>
<p>
The P/Invoke default marshalling is supported by the <tt>arrays_csharp.i</tt> library via the INPUT, OUTPUT and INOUT typemaps.
Let's look at some example usage. Consider the following C function:
</p>
<div class="code">
<pre>
void myArrayCopy(int *sourceArray, int *targetArray, int nitems);
</pre>
</div>
<p>
We can now instruct SWIG to use the default marshalling typemaps by
</p>
<div class="code">
<pre>
%include "arrays_csharp.i"
%apply int INPUT[] {int *sourceArray}
%apply int OUTPUT[] {int *targetArray}
</pre>
</div>
<p>
As a result, we get the following method in the module class:
</p>
<div class="code">
<pre>
public static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) {
examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
}
</pre>
</div>
<p>
If we look beneath the surface at the corresponding intermediary class code, we see
that SWIG has generated code that uses attributes
(from the System.Runtime.InteropServices namespace) to tell the CLR to use default
marshalling for the arrays:
</p>
<div class="code">
<pre>
[DllImport("example", EntryPoint="CSharp_myArrayCopy")]
public static extern void myArrayCopy([In, MarshalAs(UnmanagedType.LPArray)]int[] jarg1,
[Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg2,
int jarg3);
</pre>
</div>
<p>
As an example of passing an inout array (i.e. the target function will both read from and
write to the array), consider this C function that swaps a given number of elements
in the given arrays:
</p>
<div class="code">
<pre>
void myArraySwap(int *array1, int *array2, int nitems);
</pre>
</div>
<p>
Now, we can instruct SWIG to wrap this by
</p>
<div class="code">
<pre>
%include "arrays_csharp.i"
%apply int INOUT[] {int *array1}
%apply int INOUT[] {int *array2}
</pre>
</div>
<p>
This results in the module class method
</p>
<div class="code">
<pre>
public static void myArraySwap(int[] array1, int[] array2, int nitems) {
examplePINVOKE.myArraySwap(array1, array2, nitems);
}
</pre>
</div>
<p>
and intermediary class method
</p>
<div class="code">
<pre>
[DllImport("example", EntryPoint="CSharp_myArraySwap")]
public static extern void myArraySwap([In, Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg1,
[In, Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg2,
int jarg3);
</pre>
</div>
<H3><a name="CSharp_arrays_pinning"></a>19.4.3 Managed arrays using pinning</H3>
<p>
It is also possible to pin a given array in memory (i.e. fix its location in memory), obtain a
direct pointer to it, and then pass this pointer to the wrapped C/C++ function. This approach
involves no copying, but it makes the work of the garbage collector harder as
the managed array object can not be relocated before the fix on the array is released. You should avoid
fixing arrays in memory in cases where the control may re-enter the managed side via a callback and/or
another thread may produce enough garbage to trigger garbage collection.
</p>
<p>
For more information, see the <a href="http://msdn.microsoft.com/en-us/library/f58wzh21(VS.80).aspx">fixed statement</a> in the C# language reference.
</p>
<p>
Now let's look at an example using pinning, thus avoiding the CLR making copies
of the arrays passed as parameters. The <tt>arrays_csharp.i</tt> library file again provides the required support via the <tt>FIXED</tt> typemaps.
Let's use the same function from the previous section:
</p>
<div class="code">
<pre>
void myArrayCopy(int *sourceArray, int *targetArray, int nitems);
</pre>
</div>
<p>
We now need to declare the module class method unsafe, as we are using pointers:
</p>
<div class="code">
<pre>
%csmethodmodifiers myArrayCopy "public unsafe";
</pre>
</div>
<p>
Apply the appropriate typemaps to the array parameters:
</p>
<div class="code">
<pre>
%include "arrays_csharp.i"
%apply int FIXED[] {int *sourceArray}
%apply int FIXED[] {int *targetArray}
</pre>
</div>
<p>
Notice that there is no need for separate in, out or inout typemaps as is the
case when using P/Invoke default marshalling.
</p>
<p>
As a result, we get the following method in the module class:
</p>
<div class="code">
<pre>
public unsafe static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) {
fixed ( int *swig_ptrTo_sourceArray = sourceArray ) {
fixed ( int *swig_ptrTo_targetArray = targetArray ) {
{
examplePINVOKE.myArrayCopy((IntPtr)swig_ptrTo_sourceArray, (IntPtr)swig_ptrTo_targetArray,
nitems);
}
}
}
}
</pre>
</div>
<p>
On the method signature level the only difference to the version using P/Invoke default
marshalling is the "unsafe" quantifier, which is required because we are handling pointers.
</p>
<p>
Also the intermediary class method looks a little different from the default marshalling
example - the method is expecting an IntPtr as the parameter type.
</p>
<div class="code">
<pre>
[DllImport("example", EntryPoint="CSharp_myArrayCopy")]
public static extern void myArrayCopy(IntPtr jarg1, IntPtr jarg2, int jarg3);
</pre>
</div>
<H2><a name="CSharp_exceptions"></a>19.5 C# Exceptions</H2>
<p>
@ -405,7 +762,7 @@ It is possible to throw a C# Exception from C/C++ code.
SWIG already provides the framework for throwing C# exceptions if it is able to detect that a C++ exception could be thrown.
Automatically detecting that a C++ exception could be thrown is only possible when a C++ exception specification is used,
see <a href="SWIGPlus.html#SWIGPlus_exception_specifications">Exception specifications</a>.
The <a href="Customization.html#exception">Exception handling with %exception</a> section details the <tt>%exception</tt> feature.
The <a href="Customization.html#Customization_exception">Exception handling with %exception</a> section details the <tt>%exception</tt> feature.
Customised code for handling exceptions with or without a C++ exception specification is possible and the details follow.
However anyone wishing to do this should be familiar with the contents of the sections referred to above.
</p>
@ -494,7 +851,7 @@ set so should only be used when a C# exception is not created.
</p>
<H3><a name="csharp_exception_example_check_typemap"></a>17.3.1 C# exception example using "check" typemap</H3>
<H3><a name="CSharp_exception_example_check_typemap"></a>19.5.1 C# exception example using "check" typemap</H3>
<p>
@ -668,7 +1025,7 @@ without setting the <tt>canthrow</tt> attribute you will get a warning message s
<div class="code">
<pre>
example.i:21: Warning(845): Unmanaged code contains a call to a SWIG_CSharpSetPendingException
example.i:21: Warning 845: Unmanaged code contains a call to a SWIG_CSharpSetPendingException
method and C# code does not handle pending exceptions via the canthrow attribute.
</pre>
</div>
@ -676,12 +1033,12 @@ method and C# code does not handle pending exceptions via the canthrow attribute
Actually it will issue this warning for any function beginning with <tt>SWIG_CSharpSetPendingException</tt>.
</P>
<H3><a name="csharp_exception_example_percent_exception"></a>17.3.2 C# exception example using %exception</H3>
<H3><a name="CSharp_exception_example_percent_exception"></a>19.5.2 C# exception example using %exception</H3>
<p>
Let's consider a similar, but more common example that throws a C++ exception from within a wrapped function.
We can use <tt>%exception</tt> as mentioned in <a href="Customization.html#exception">Exception handling with %exception</a>.
We can use <tt>%exception</tt> as mentioned in <a href="Customization.html#Customization_exception">Exception handling with %exception</a>.
</p>
<div class="code">
@ -741,7 +1098,7 @@ The managed code generated does check for the pending exception as mentioned ear
</pre>
</div>
<H3><a name="csharp_exception_example_exception_specifications"></a>17.3.3 C# exception example using exception specifications</H3>
<H3><a name="CSharp_exception_example_exception_specifications"></a>19.5.3 C# exception example using exception specifications</H3>
<p>
@ -798,7 +1155,7 @@ SWIGEXPORT void SWIGSTDCALL CSharp_evensonly(int jarg1) {
Multiple catch handlers are generated should there be more than one exception specifications declared.
</p>
<H3><a name="csharp_custom_application_exception"></a>17.3.4 Custom C# ApplicationException example</H3>
<H3><a name="CSharp_custom_application_exception"></a>19.5.4 Custom C# ApplicationException example</H3>
<p>
@ -932,7 +1289,7 @@ try {
</pre>
</div>
<H2><a name="csharp_directors"></a>17.4 C# Directors</H2>
<H2><a name="CSharp_directors"></a>19.6 C# Directors</H2>
<p>
@ -942,10 +1299,10 @@ Essentially, it enables unmanaged C++ code to call back into managed code for vi
<p>
The following sections provide information on the C# director implementation and contain most of the information required to use the C# directors.
However, the <a href="Java.html#java_directors">Java directors</a> section should also be read in order to gain more insight into directors.
However, the <a href="Java.html#Java_directors">Java directors</a> section should also be read in order to gain more insight into directors.
</p>
<H3><a name="csharp_directors_example"></a>17.4.1 Directors example</H3>
<H3><a name="CSharp_directors_example"></a>19.6.1 Directors example</H3>
<p>
@ -1066,7 +1423,7 @@ CSharpDerived - UIntMethod(123)
</pre>
</div>
<H3><a name="csharp_directors_implementation"></a>17.4.2 Directors implementation</H3>
<H3><a name="CSharp_directors_implementation"></a>19.6.2 Directors implementation</H3>
<p>
@ -1252,7 +1609,7 @@ void SwigDirector_Base::BaseBoolMethod(Base const &amp;b, bool flag) {
</pre>
</div>
<H3><a name="csharp_director_caveats"></a>17.4.3 Director caveats</H3>
<H3><a name="CSharp_director_caveats"></a>19.6.3 Director caveats</H3>
<p>
@ -1300,7 +1657,42 @@ However, a call from C# to <tt>CSharpDefaults.DefaultMethod()</tt> will of cours
should pass the call on to <tt>CSharpDefaults.DefaultMethod(int)</tt>using the C++ default value, as shown above.
</p>
<H2><a name="csharp_typemap_examples"></a>17.5 C# Typemap examples</H2>
<H2><a name="CSharp_multiple_modules"></a>19.7 Multiples modules</H2>
<p>
When using <a href="Modules.html">multiple modules</a> it is is possible to compile each SWIG generated wrapper
into a different assembly.
However, by default the generated code may not compile if
generated classes in one assembly use generated classes in another assembly.
The visibility of the
<tt>getCPtr()</tt> and pointer constructor generated from the <tt>csbody</tt> typemaps needs changing.
The default visibility is <tt>internal</tt> but it needs to be <tt>public</tt> for access from a different assembly.
Just changing 'internal' to 'public' in the typemap achieves this.
Two macros are available in <tt>csharp.swg</tt> to make this easier and using them is the preferred approach
over simply copying the typemaps and modifying as this is forward compatible with any changes in
the <tt>csbody</tt> typemap in future versions of SWIG.
The macros are for the proxy and typewrapper classes and can respectively be used to
to make the method and constructor public:
</p>
<div class="code">
<pre>
SWIG_CSBODY_PROXY(public, public, SWIGTYPE)
SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
</pre>
</div>
<p>
Alternatively, instead of exposing these as public, consider
using the <tt>[assembly:InternalsVisibleTo("Name")]</tt> attribute available in the .NET framework when you
know which assemblies these can be exposed to.
Another approach would be to make these public, but also to hide them from intellisense by using
the <tt>[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]</tt> attribute
if you don't want users to easily stumble upon these so called 'internal workings' of the wrappers.
</p>
<H2><a name="CSharp_typemap_examples"></a>19.8 C# Typemap examples</H2>
This section includes a few examples of typemaps. For more examples, you
@ -1308,12 +1700,12 @@ might look at the files "<tt>csharp.swg</tt>" and "<tt>typemaps.i</tt>" in
the SWIG library.
<H3><a name="csharp_memory_management_member_variables"></a>17.5.1 Memory management when returning references to member variables</H3>
<H3><a name="CSharp_memory_management_member_variables"></a>19.8.1 Memory management when returning references to member variables</H3>
<p>
This example shows how to prevent premature garbage collection of objects when the underlying C++ class returns a pointer or reference to a member variable.
The example is a direct equivalent to this <a href="Java.html#java_memory_management_objects">Java equivalent</a>.
The example is a direct equivalent to this <a href="Java.html#Java_memory_management_objects">Java equivalent</a>.
</p>
<p>
@ -1432,11 +1824,11 @@ public class Bike : IDisposable {
Note the <tt>addReference</tt> call.
</p>
<H3><a name="csharp_memory_management_objects"></a>17.5.2 Memory management for objects passed to the C++ layer</H3>
<H3><a name="CSharp_memory_management_objects"></a>19.8.2 Memory management for objects passed to the C++ layer</H3>
<p>
The example is a direct equivalent to this <a href="Java.html#java_memory_management_objects">Java equivalent</a>.
The example is a direct equivalent to this <a href="Java.html#Java_memory_management_objects">Java equivalent</a>.
Managing memory can be tricky when using C++ and C# proxy classes.
The previous example shows one such case and this example looks at memory management for a class passed to a C++ method which expects the object to remain in scope
after the function has returned. Consider the following two C++ classes:
@ -1551,14 +1943,14 @@ The 'cscode' typemap simply adds in the specified code into the C# proxy class.
</div>
<H3><a name="csharp_date_marshalling"></a>17.5.3 Date marshalling using the csin typemap and associated attributes</H3>
<H3><a name="CSharp_date_marshalling"></a>19.8.3 Date marshalling using the csin typemap and associated attributes</H3>
<p>
The <a href="Java.html#nan_exception_typemap">NaN Exception example</a> is a simple example of the "javain" typemap and its 'pre' attribute.
The <a href="Java.html#Java_nan_exception_typemap">NaN Exception example</a> is a simple example of the "javain" typemap and its 'pre' attribute.
This example demonstrates how a C++ date class, say <tt>CDate</tt>, can be mapped onto the standard .NET date class,
<tt>System.DateTime</tt> by using the 'pre', 'post' and 'pgcppname' attributes of the "csin" typemap (the C# equivalent to the "javain" typemap).
The example is an equivalent to the <a href="Java.html#java_date_marshalling">Java Date marshalling example</a>.
The example is an equivalent to the <a href="Java.html#Java_date_marshalling">Java Date marshalling example</a>.
The idea is that the <tt>System.DateTime</tt> is used wherever the C++ API uses a <tt>CDate</tt>.
Let's assume the code being wrapped is as follows:
</p>
@ -1783,7 +2175,8 @@ public class example {
try {
examplePINVOKE.addYears(CDate.getCPtr(temppDate), years);
} finally {
pDate = new System.DateTime(temppDate.getYear(), temppDate.getMonth(), temppDate.getDay(), 0, 0, 0);
pDate = new System.DateTime(temppDate.getYear(), temppDate.getMonth(), temppDate.getDay(),
0, 0, 0);
}
}
...
@ -1800,13 +2193,13 @@ The <tt>subtractYears</tt> method is nearly identical to the above <tt>addYears<
<div class="code">
<pre>
%typemap(csin,
pre=" using (CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day)) {",
post=" $csinput = new System.DateTime(temp$csinput.getYear(),"
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
terminator=" } // terminate temp$csinput using block",
cshin="ref $csinput"
) CDate *
"$csclassname.getCPtr(temp$csinput)"
pre=" using (CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day)) {",
post=" $csinput = new System.DateTime(temp$csinput.getYear(),"
" temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);",
terminator=" } // terminate temp$csinput using block",
cshin="ref $csinput"
) CDate *
"$csclassname.getCPtr(temp$csinput)"
void subtractYears(CDate *pDate, int years) {
*pDate = CDate(pDate-&gt;getYear() - years, pDate-&gt;getMonth(), pDate-&gt;getDay());
@ -1826,7 +2219,8 @@ public class example {
try {
examplePINVOKE.subtractYears(CDate.getCPtr(temppDate), years);
} finally {
pDate = new System.DateTime(temppDate.getYear(), temppDate.getMonth(), temppDate.getDay(), 0, 0, 0);
pDate = new System.DateTime(temppDate.getYear(), temppDate.getMonth(), temppDate.getDay(),
0, 0, 0);
}
} // terminate temppDate using block
}
@ -1835,7 +2229,7 @@ public class example {
</pre>
</div>
<H3><a name="csharp_date_properties"></a>17.5.4 A date example demonstrating marshalling of C# properties</H3>
<H3><a name="CSharp_date_properties"></a>19.8.4 A date example demonstrating marshalling of C# properties</H3>
<p>
@ -1936,7 +2330,7 @@ Some points to note:
</ul>
<H3><a name="csharp_partial_classes"></a>17.5.5 Turning wrapped classes into partial classes</H3>
<H3><a name="CSharp_partial_classes"></a>19.8.5 Turning wrapped classes into partial classes</H3>
<p>
@ -2036,7 +2430,7 @@ demonstrating that the class contains methods calling both unmanaged code - <tt>
The following example is an alternative approach to adding managed code to the generated proxy class.
</p>
<H3><a name="csharp_extending_proxy_class"></a>17.5.6 Extending proxy classes with additional C# code</H3>
<H3><a name="CSharp_extending_proxy_class"></a>19.8.6 Extending proxy classes with additional C# code</H3>
<p>
@ -2075,6 +2469,38 @@ public class ExtendMe : IDisposable {
</pre>
</div>
<H3><a name="CSharp_enum_underlying_type"></a>19.8.7 Underlying type for enums</H3>
<P>
C# enums use int as the underlying type for each enum item.
If you wish to change the underlying type to something else, then use the <tt>csbase</tt> typemap.
For example when your C++ code uses a value larget than int, this is necessary as the C# compiler will not compile values which are too large to fit into an int.
Here is an example:
</p>
<div class="code">
<pre>
%typemap(csbase) BigNumbers "uint"
%inline %{
enum BigNumbers { big=0x80000000, bigger };
%}
</pre>
</div>
<p>
The generated enum will then use the given underlying type and compile correctly:
</p>
<div class="code">
<pre>
public enum BigNumbers : uint {
big = 0x80000000,
bigger
}
</pre>
</div>
</body>
</html>

View file

@ -8,7 +8,7 @@
<body bgcolor="#ffffff">
<H1><a name="Chicken"></a>18 SWIG and Chicken</H1>
<H1><a name="Chicken"></a>20 SWIG and Chicken</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
@ -35,7 +35,7 @@
<li><a href="#Chicken_nn16">Typemaps</a>
<li><a href="#Chicken_nn17">Pointers</a>
<ul>
<li><a href="#collection">Garbage collection</a>
<li><a href="#Chicken_collection">Garbage collection</a>
</ul>
<li><a href="#Chicken_nn18">Unsupported features and known problems</a>
<ul>
@ -72,7 +72,7 @@
</p>
<H2><a name="Chicken_nn2"></a>18.1 Preliminaries</H2>
<H2><a name="Chicken_nn2"></a>20.1 Preliminaries</H2>
<p>
@ -80,17 +80,16 @@
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="#collection">Garbage collection</a>
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/
or Examples/GIFPlot/Chicken for the basic steps to run SWIG
CHICKEN.
directory for the basic steps to run SWIG CHICKEN.
</p>
<H3><a name="Chicken_nn3"></a>18.1.1 Running SWIG in C mode</H3>
<H3><a name="Chicken_nn3"></a>20.1.1 Running SWIG in C mode</H3>
<p>
@ -123,7 +122,7 @@
object files and linked into your project.
</p>
<H3><a name="Chicken_nn4"></a>18.1.2 Running SWIG in C++ mode</H3>
<H3><a name="Chicken_nn4"></a>20.1.2 Running SWIG in C++ mode</H3>
<p>
@ -152,10 +151,10 @@
object files and linked into your project.
</p>
<H2><a name="Chicken_nn5"></a>18.2 Code Generation</H2>
<H2><a name="Chicken_nn5"></a>20.2 Code Generation</H2>
<H3><a name="Chicken_nn6"></a>18.2.1 Naming Conventions</H3>
<H3><a name="Chicken_nn6"></a>20.2.1 Naming Conventions</H3>
<p>
@ -171,7 +170,7 @@
<tt>%rename</tt> SWIG directive in the SWIG interface file.
</p>
<H3><a name="Chicken_nn7"></a>18.2.2 Modules</H3>
<H3><a name="Chicken_nn7"></a>20.2.2 Modules</H3>
<p>
@ -193,7 +192,7 @@
(uses <i>modulename</i>))</code> CHICKEN Scheme form.
</p>
<H3><a name="Chicken_nn8"></a>18.2.3 Constants and Variables</H3>
<H3><a name="Chicken_nn8"></a>20.2.3 Constants and Variables</H3>
<p>
@ -226,11 +225,11 @@
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#features">Features and the %feature directive</a>
<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>18.2.4 Functions</H3>
<H3><a name="Chicken_nn9"></a>20.2.4 Functions</H3>
<p>
@ -249,12 +248,12 @@
parameters). The return values can then be accessed with <code>(call-with-values)</code>.
</p>
<H3><a name="Chicken_nn10"></a>18.2.5 Exceptions</H3>
<H3><a name="Chicken_nn10"></a>20.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#exception">Exception handling with %exception</a>
See <a href="Customization.html#Customization_exception">Exception handling with %exception</a>
for more information about declaring exceptions in the interface file.
</p>
@ -263,7 +262,7 @@
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
<a href="http://www.call-with-current-continuation.org/manual/Exceptions.html#Exceptions">Chicken manual on Exceptions</a>
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>
@ -291,7 +290,7 @@
</pre></div>
<H2><a name="Chicken_nn11"></a>18.3 TinyCLOS</H2>
<H2><a name="Chicken_nn11"></a>20.3 TinyCLOS</H2>
<p>
@ -334,7 +333,7 @@
</p>
<H2><a name="Chicken_nn12"></a>18.4 Linkage</H2>
<H2><a name="Chicken_nn12"></a>20.4 Linkage</H2>
<p>
@ -355,7 +354,7 @@
</p>
<H3><a name="Chicken_nn13"></a>18.4.1 Static binary or shared library linked at compile time</H3>
<H3><a name="Chicken_nn13"></a>20.4.1 Static binary or shared library linked at compile time</H3>
<p>We can easily use csc to build a static binary.</p>
@ -396,7 +395,7 @@ in which case the test script does not need to be linked with example.so. The t
be run with <tt>csi</tt>.
</p>
<H3><a name="Chicken_nn14"></a>18.4.2 Building chicken extension libraries</H3>
<H3><a name="Chicken_nn14"></a>20.4.2 Building chicken extension libraries</H3>
<p>Building a shared library like in the above section only works if the library
@ -417,8 +416,8 @@ $ csc -sv modname.scm modname_wrap.c modname_impl.c -o modname.so
</div>
<p>This library can then be loaded by scheme code with the <code>(require 'modname)</code> function.
See <a href="http://www.call-with-current-continuation.org/manual/Loading-extension-libraries.html">
Loading-extension-libraries</a> in the eval unit inside the CHICKEN manual for more information.</p>
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>
@ -454,7 +453,7 @@ 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>18.4.3 Linking multiple SWIG modules with TinyCLOS</H3>
<H3><a name="Chicken_nn15"></a>20.4.3 Linking multiple SWIG modules with TinyCLOS</H3>
<p>Linking together multiple modules that share type information using the <code>%import</code>
@ -478,7 +477,7 @@ 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>18.5 Typemaps</H2>
<H2><a name="Chicken_nn16"></a>20.5 Typemaps</H2>
<p>
@ -487,7 +486,7 @@ all the modules.</p>
<code>Lib/chicken/chicken.swg</code>.
</p>
<H2><a name="Chicken_nn17"></a>18.6 Pointers</H2>
<H2><a name="Chicken_nn17"></a>20.6 Pointers</H2>
<p>
@ -520,7 +519,7 @@ all the modules.</p>
type. flags is either zero or SWIG_POINTER_DISOWN (see below).
</p>
<H3><a name="collection"></a>18.6.1 Garbage collection</H3>
<H3><a name="Chicken_collection"></a>20.6.1 Garbage collection</H3>
<p>If the owner flag passed to <code>SWIG_NewPointerObj</code> is 1, <code>NewPointerObj</code> will add a
@ -531,12 +530,12 @@ all the modules.</p>
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#ownership">Object ownership and %newobject</a> for more information.
<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 chapter</a> for more information on how to apply typemaps),
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
@ -551,7 +550,7 @@ all the modules.</p>
must be called manually.
</p>
<H2><a name="Chicken_nn18"></a>18.7 Unsupported features and known problems</H2>
<H2><a name="Chicken_nn18"></a>20.7 Unsupported features and known problems</H2>
<ul>
@ -561,7 +560,7 @@ all the modules.</p>
<a href="SWIGPlus.html#SWIGPlus_default_args">%feature(compactdefaultargs)</a>.</li>
</ul>
<H3><a name="Chicken_nn19"></a>18.7.1 TinyCLOS problems with Chicken version &lt;= 1.92</H3>
<H3><a name="Chicken_nn19"></a>20.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

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#exception">Exception handling with %exception</a>
<li><a href="#Customization_exception">Exception handling with %exception</a>
<ul>
<li><a href="#Customization_nn3">Handling exceptions in C code</a>
<li><a href="#Customization_nn4">Exception handling with longjmp()</a>
@ -20,14 +20,14 @@
<li><a href="#Customization_exception_special_variables">Special variables for %exception</a>
<li><a href="#Customization_nn7">Using The SWIG exception library</a>
</ul>
<li><a href="#ownership">Object ownership and %newobject</a>
<li><a href="#features">Features and the %feature directive</a>
<li><a href="#Customization_ownership">Object ownership and %newobject</a>
<li><a href="#Customization_features">Features and the %feature directive</a>
<ul>
<li><a href="#Customization_feature_attributes">Feature attributes</a>
<li><a href="#Customization_feature_flags">Feature flags</a>
<li><a href="#Customization_clearing_features">Clearing features</a>
<li><a href="#Customization_features_default_args">Features and default arguments</a>
<li><a href="#features_example">Feature example</a>
<li><a href="#Customization_features_example">Feature example</a>
</ul>
</ul>
</div>
@ -45,7 +45,7 @@ of exception handling is presented. Then, a more general-purpose
customization mechanism known as "features" is described.
</p>
<H2><a name="exception"></a>11.1 Exception handling with %exception</H2>
<H2><a name="Customization_exception"></a>11.1 Exception handling with %exception</H2>
<p>
@ -53,6 +53,21 @@ The <tt>%exception</tt> directive allows you to define a general purpose excepti
handler. For example, you can specify the following:
</p>
<div class="code"><pre>
%exception {
try {
$action
}
catch (RangeError) {
... handle error ...
}
}
</pre></div>
<p>
How the exception is handled depends on the target language, for example, Python:
</p>
<div class="code"><pre>
%exception {
try {
@ -60,7 +75,7 @@ handler. For example, you can specify the following:
}
catch (RangeError) {
PyErr_SetString(PyExc_IndexError,"index out-of-bounds");
return NULL;
SWIG_fail;
}
}
</pre></div>
@ -68,7 +83,7 @@ handler. For example, you can specify the following:
<p>
When defined, the code enclosed in braces is inserted directly into the low-level wrapper
functions. The special variable <tt>$action</tt> is one of a few
<a href="Customization.html#Customization_exception_special_variables">%exception special variable</a>
<a href="Customization.html#Customization_exception_special_variables">%exception special variables</a>
supported and gets replaced with the actual operation
to be performed (a function call, method invocation, attribute access, etc.). An exception handler
remains in effect until it is explicitly deleted. This is done by using either <tt>%exception</tt>
@ -336,7 +351,7 @@ In this case, the exception handler is only attached to declarations
named "allocate". This would include both global and member
functions. The names supplied to <tt>%exception</tt> follow the same
rules as for <tt>%rename</tt> described in the section on
<a href="SWIGPlus.html#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>.
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>.
For example, if you wanted to define
an exception handler for a specific class, you might write this:
</p>
@ -567,7 +582,7 @@ it can be used elsewhere in SWIG. This includes typemaps and helper
functions.
</p>
<H2><a name="ownership"></a>11.2 Object ownership and %newobject</H2>
<H2><a name="Customization_ownership"></a>11.2 Object ownership and %newobject</H2>
<p>
@ -689,6 +704,11 @@ depends on the target language on implementing the 'disown' mechanism
properly.
</p>
<p>
The use of <tt>%newobject</tt> is also integrated with reference counting and is covered in the
<a href="SWIGPlus.html#SWIGPlus_ref_unref">C++ reference counted objects</a> section.
</p>
<p>
<b>Compatibility note:</b> Previous versions of SWIG had a special <tt>%new</tt> directive. However, unlike <tt>%newobject</tt>,
it only applied to the next declaration. For example:
@ -719,7 +739,7 @@ char *strdup(const char *s);
The results might not be what you expect.
</p>
<H2><a name="features"></a>11.3 Features and the %feature directive</H2>
<H2><a name="Customization_features"></a>11.3 Features and the %feature directive</H2>
<p>
@ -758,9 +778,9 @@ involving <tt>%feature</tt>:
</div>
<p>
The name matching rules outlined in the <a href="SWIGPlus.html#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
The name matching rules outlined in the <a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
section applies to all <tt>%feature</tt> directives.
In fact the the <tt>%rename</tt> directive is just a special form of <tt>%feature</tt>.
In fact the <tt>%rename</tt> directive is just a special form of <tt>%feature</tt>.
The matching rules mean that features are very flexible and can be applied with
pinpoint accuracy to specific declarations if needed.
Additionally, if no declaration name is given, a global feature is said to be defined.
@ -839,7 +859,7 @@ In the following example, <tt>MyExceptionClass</tt> is the name of the Java clas
</div>
<p>
Further details can be obtained from the <a href="Java.html#exception_handling">Java exception handling</a> section.
Further details can be obtained from the <a href="Java.html#Java_exception_handling">Java exception handling</a> section.
</p>
<H3><a name="Customization_feature_flags"></a>11.3.2 Feature flags</H3>
@ -1019,6 +1039,20 @@ but this will:
</pre>
</div>
<p>
SWIG provides macros for disabling and clearing features. Many of these can be found in the <tt>swig.swg</tt> library file.
The typical pattern is to define three macros; one to define the feature itself, one to disable the feature and one to clear the feature.
The three macros below show this for the "except" feature:
</p>
<div class="code">
<pre>
#define %exception %feature("except")
#define %noexception %feature("except","0")
#define %clearexception %feature("except","")
</pre>
</div>
<H3><a name="Customization_features_default_args"></a>11.3.4 Features and default arguments</H3>
@ -1094,7 +1128,7 @@ specifying or not specifying default arguments in a feature is not applicable as
in SWIG-1.3.23 when the approach to wrapping methods with default arguments was changed.
</p>
<H3><a name="features_example"></a>11.3.5 Feature example</H3>
<H3><a name="Customization_features_example"></a>11.3.5 Feature example</H3>
<p>

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

@ -0,0 +1,454 @@
<!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>21 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_nspace">Extended namespace support (<tt>nspace</tt>)</a>
<li><a href="#D_native_pointer_support">Native pointer support</a>
<li><a href="#D_operator_overloading">Operator overloading</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>21.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>21.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>21.3 Typemaps</H2>
<H3><a name="D_typemap_name_comparison"></a>21.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>21.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>21.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>21.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). To inject further parameter processing code before or after the call to the intermediary layer, the <tt>pre</tt>, <tt>post</tt> and <tt>terminator</tt> attributes can be used (please refer to the <a href="CSharp.html#CSharp_date_marshalling">C# date marshalling example</a> for more information on these).</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_imcall"><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)
&uarr; &darr;
&lt;directorout&gt; &lt;directorin&gt;
&uarr; &darr;
ctype methodCallback(ctype a) C++
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
imtype methodCallback(imtype a) D
&uarr; &darr;
&lt;ddirectorout&gt; &lt;ddirectorin&gt;
&uarr; &darr;
dtype DClass.method(dtype a)</pre></div>
<H3><a name="D_typecheck_typemaps"></a>21.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>21.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>21.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>$dclazzname</tt> (C#: <tt>$csclazzname</tt>)</dt>
<dd>
<p>This special variable expands the fully qualified C++ class into the package name, if used by the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt> feature</a>, and the proxy class name, mangled for use as a function name. For example, <tt>Namespace1::Namespace2::Klass</tt> is expanded into <tt>Namespace1_Namespace2_Klass_</tt>.</p>
<p>This special variable might be useful for calling certain functions in the wrapper layer (e.g. upcast wrappers) which are mangled like this.</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_imcall"><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>21.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>21.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> and/or the <tt>nspace</tt> feature is used, 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>21.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>21.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>21.8 Other features</H2>
<H3><a name="D_nspace"></a>21.8.1 Extended namespace support (<tt>nspace</tt>)</H3>
<p>By default, SWIG flattens all C++ namespaces into a single target language namespace, but as for Java and C#, the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature is supported for D. If it is active, C++ namespaces are mapped to D packages/modules. Note, however, that like for the other languages, <em>free</em> variables and functions are not supported yet; currently, they are all allows written to the main proxy D module.</p>
<H3><a name="D_native_pointer_support"></a>21.8.2 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 <em>primitive type</em> 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_operator_overloading"></a>21.8.3 Operator overloading</H3>
<p>The D module comes with basic operator overloading support for both D1 and D2. There are, however, a few limitations arising from conceptual differences between C++ and D:</p>
<p>The first key difference is that C++ supports free functions as operators (along with argument-dependent lookup), while D requires operators to be member functions of the class they are operating on. SWIG can only automatically generate wrapping code for member function operators; if you want to use operators defined as free functions in D, you need to handle them manually.</p>
<p>Another set of differences between C++ and D concerns individual operators. For example, there are quite a few operators which are overloadable in C++, but not in D, for example <tt>&amp;&amp;</tt> and <tt>||</tt>, but also <tt>!</tt>, and prefix increment/decrement operators in <a href="http://www.digitalmars.com/d/1.0/operatoroverloading.html">D1</a> resp. their postfix pendants in <a href="http://www.digitalmars.com/d/2.0/operatoroverloading.html">D2</a>.</p>
<p>There are also some cases where the operators can be translated to D, but the differences in the implementation details are big enough that a rather involved scheme would be required for automatic wrapping them, which has not been implemented yet. This affects, for example, the array subscript operator, <tt>[]</tt>, in combination with assignments - while <tt>operator []</tt> in C++ simply returns a reference which is then written to, D resorts to a separate <tt>opIndexAssign</tt> method -, or implicit casting (which was introduced in D2 via <tt>alias this</tt>). Despite the lack of automatic support, manually handling these cases should be perfectly possible.</p>
<H3><a name="D_test_suite"></a>21.8.4 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>21.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>21.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>
</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>

File diff suppressed because it is too large Load diff

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

@ -0,0 +1,635 @@
<!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>22 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>
<li><a href="#Go_output_arguments">Output arguments</a>
<li><a href="#Go_adding_additional_code">Adding additional go code</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>22.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>22.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>22.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/5g.</td>
</tr>
<tr>
<td>-gccgo-46</td>
<td>Generate code for gccgo 4.6. The default is set by the configure
script. This generates code that does not use some facilities
that are only available in gccgo 4.7 and later.</td>
</tr>
<tr>
<td>-no-gccgo-46</td>
<td>Turn off <code>-gccgo-46</code>, whether set by default or earlier
on the command line.
</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>-soname %lt;name%gt;</td>
<td>Set the runtime name of the shared library that the dynamic linker
should include at runtime. The default is the package name with
".so" appended. This is only used when generating code for
6g/8g/5g; when using gccgo, the equivalent name will be taken from
the <code>-soname</code> option passed to the linker.</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>22.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>22.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>22.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>22.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>22.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>22.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>22.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>ClassNameMethodName</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>
<p>Note that C++ pointers to compound objects are represented in go as objects
themselves, not as go pointers. So, for example, if you wrap the following
function:</p>
<div class="code">
<pre>
class MyClass {
int MyMethod();
static MyClass *MyFactoryFunction();
};
</pre>
</div>
<p>You will get go code that looks like this:</p>
<div class="code">
<pre>
type MyClass interface {
Swigcptr() uintptr
SwigIsMyClass()
MyMethod() int
}
MyClassMyFactoryFunction() MyClass {
// swig magic here
}
</pre>
</div>
<p>Note that the factory function does not return a go pointer; it actually
returns a go interface. If the returned pointer can be null, you can check
for this by calling the Swigcptr() method.
</p>
<H4><a name="Go_class_inheritance"></a>22.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>22.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>22.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>22.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>
<H3><a name="Go_output_arguments"></a>22.3.9 Output arguments</H3>
<p>Because of limitations in the way output arguments are processed in swig,
a function with output arguments will not have multiple return values.
Instead, you must pass a pointer into the C++ function to tell it where to
store the ouput value. In go, you supply a slice in the place of the output
argument.</p>
<p>For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
returns the integer part in one of its parameters):</p>
<div class="code">
<pre>
double modf(double x, double *ip);
</pre>
</div>
<p>You could wrap it with SWIG as follows:</p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
double modf(double x, double *OUTPUT);
</pre>
</div>
<p>or you can use the <code>%apply</code> directive:</p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
</pre>
</div>
<p>In Go you would use it like this:</p>
<div class="code">
<pre>
ptr := []float64{0.0}
fraction := modulename.Modf(5.0, ptr)
</pre>
</div>
<p>Since this is ugly, you may want to wrap the swig-generated API with
some <a href="#Embedded_go_code">additional functions written in go</a> that
hide the ugly details.</p>
<p>There are no <code>char&nbsp;*OUTPUT</code> typemaps. However you can
apply the <code>signed&nbsp;char&nbsp;*</code> typemaps instead:</p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
%apply signed char *OUTPUT {char *output};
void f(char *output);
</pre>
</div>
<H3><a name="Go_adding_additional_code"></a>22.3.10 Adding additional go code</H3>
<p>Often the APIs generated by swig are not very natural in go, especially if
there are output arguments. You can
insert additional go wrapping code to add new APIs
with <code>%insert(go_wrapper)</code>, like this:</p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
// Change name of what swig generates to Wrapped_modf. This function will
// have the following signature in go:
// func Wrapped_modf(float64, []float64) float64
%rename(wrapped_modf) modf(double x, double *ip);
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
%insert(go_wrapper) %{
// The improved go interface to this function, which has two return values,
// in the more natural go idiom:
func Modf(x float64) (fracPart float64, intPart float64) {
ip := []float64{0.0}
fracPart = Wrapped_modf(x, ip)
intPart = ip[0]
return
}
%}
</pre>
</div>
<p>For classes, since swig generates an interface, you can add additional
methods by defining another interface that includes the swig-generated
interface. For example,</p>
<div class="code">
<pre>
%rename(Wrapped_MyClass) MyClass;
%rename(Wrapped_GetAValue) MyClass::GetAValue(int *x);
%apply int *OUTPUT { int *x };
class MyClass {
public:
MyClass();
int AFineMethod(const char *arg); // Swig's wrapping is fine for this one.
bool GetAValue(int *x);
};
%insert(go_wrapper) %{
type MyClass interface {
Wrapped_MyClass
GetAValue() (int, bool)
}
func (arg SwigcptrWrapped_MyClass) GetAValue() (int, bool) {
ip := []int{0}
ok := arg.Wrapped_GetAValue(ip)
return ip[0], ok
}
%}
</pre>
</div>
<p>Of course, if you have to rewrite most of the methods, instead of just a
few, then you might as well define your own struct that includes the
swig-wrapped object, instead of adding methods to the swig-generated object.</p>
<p>This only works if your wrappers do not need to import other go modules.
There is at present no way to insert import statements in the correct place
in swig-generated go. If you need to do that, you must put your go code
in a separate file.</p>
</body>
</html>

View file

@ -8,7 +8,7 @@
<body bgcolor="#ffffff">
<H1><a name="Guile"></a>19 SWIG and Guile</H1>
<H1><a name="Guile"></a>23 SWIG and Guile</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
@ -47,7 +47,7 @@
<p>
This section details guile-specific support in SWIG.
<H2><a name="Guile_nn2"></a>19.1 Meaning of "Module"</H2>
<H2><a name="Guile_nn2"></a>23.1 Meaning of "Module"</H2>
<p>
@ -55,7 +55,7 @@ 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>19.2 Using the SCM or GH Guile API</H2>
<H2><a name="Guile_nn3"></a>23.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
@ -69,7 +69,7 @@ SCM interface is the default. The SCM and GH interface differ greatly in how th
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/guile-ref/GH-deprecation.html">Guile manual</a>.
<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
@ -103,7 +103,7 @@ for the specific API. Currently only the guile language module has created a ma
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>19.3 Linkage</H2>
<H2><a name="Guile_nn4"></a>23.3 Linkage</H2>
<p>
@ -111,7 +111,7 @@ 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>19.3.1 Simple Linkage</H3>
<H3><a name="Guile_nn5"></a>23.3.1 Simple Linkage</H3>
<p>
@ -206,7 +206,7 @@ placed between the <code>define-module</code> form and the
<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>19.3.2 Passive Linkage</H3>
<H3><a name="Guile_nn6"></a>23.3.2 Passive Linkage</H3>
<p>Passive linkage is just like simple linkage, but it generates an
@ -216,7 +216,7 @@ 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>19.3.3 Native Guile Module Linkage</H3>
<H3><a name="Guile_nn7"></a>23.3.3 Native Guile Module Linkage</H3>
<p>SWIG can also generate wrapper code that does all the Guile module
@ -257,7 +257,7 @@ Newer Guile versions have a shorthand procedure for this:
</div>
</ul>
<H3><a name="Guile_nn8"></a>19.3.4 Old Auto-Loading Guile Module Linkage</H3>
<H3><a name="Guile_nn8"></a>23.3.4 Old Auto-Loading Guile Module Linkage</H3>
<p>Guile used to support an autoloading facility for object-code
@ -283,7 +283,7 @@ option, SWIG generates an exported module initialization function with
an appropriate name.
<H3><a name="Guile_nn9"></a>19.3.5 Hobbit4D Linkage</H3>
<H3><a name="Guile_nn9"></a>23.3.5 Hobbit4D Linkage</H3>
<p>
@ -308,7 +308,7 @@ 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>19.4 Underscore Folding</H2>
<H2><a name="Guile_nn10"></a>23.4 Underscore Folding</H2>
<p>
@ -320,7 +320,7 @@ complained so far.
<code>%rename</code> to specify the Guile name of the wrapped
functions and variables (see CHANGES).
<H2><a name="Guile_nn11"></a>19.5 Typemaps</H2>
<H2><a name="Guile_nn11"></a>23.5 Typemaps</H2>
<p>
@ -409,10 +409,10 @@ See also the "multivalue" example.
%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#features">Features and the %feature directive</a>
<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>19.6 Representation of pointers as smobs</H2>
<H2><a name="Guile_nn12"></a>23.6 Representation of pointers as smobs</H2>
<p>
@ -429,11 +429,11 @@ 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>.
<a href="Typemaps.html#Typemaps_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>19.6.1 GH Smobs</H3>
<H3><a name="Guile_nn13"></a>23.6.1 GH Smobs</H3>
<p>
@ -462,7 +462,7 @@ 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>19.6.2 SCM Smobs</H3>
<H3><a name="Guile_nn14"></a>23.6.2 SCM Smobs</H3>
<p>The SCM interface (using the "-scm" argument to swig) uses swigrun.swg.
@ -477,7 +477,7 @@ in the smob tag. If a generated GOOPS module has been loaded, smobs will be wra
GOOPS class.</p>
<H3><a name="Guile_nn15"></a>19.6.3 Garbage Collection</H3>
<H3><a name="Guile_nn15"></a>23.6.3 Garbage Collection</H3>
<p>Garbage collection is a feature of the new SCM interface, and it is automatically included
@ -487,11 +487,11 @@ to the destructor for this type. The destructor is the generated wrapper around
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#ownership">
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>19.7 Exception Handling</H2>
<H2><a name="Guile_nn16"></a>23.7 Exception Handling</H2>
<p>
@ -517,7 +517,7 @@ mapping:
The default when not specified here is to use "swig-error".
See Lib/exception.i for details.
<H2><a name="Guile_nn17"></a>19.8 Procedure documentation</H2>
<H2><a name="Guile_nn17"></a>23.8 Procedure documentation</H2>
<p>If invoked with the command-line option <code>-procdoc
@ -553,7 +553,7 @@ like this:
typemap argument <code>doc</code>. See <code>Lib/guile/typemaps.i</code> for
details.
<H2><a name="Guile_nn18"></a>19.9 Procedures with setters</H2>
<H2><a name="Guile_nn18"></a>23.9 Procedures with setters</H2>
<p>For global variables, SWIG creates a single wrapper procedure
@ -581,7 +581,7 @@ 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>19.10 GOOPS Proxy Classes</H2>
<H2><a name="Guile_nn19"></a>23.10 GOOPS Proxy Classes</H2>
<p>SWIG can also generate classes and generic functions for use with
@ -730,7 +730,7 @@ Notice that &lt;Foo&gt; is used before it is defined. The fix is to just put th
<code>%import "foo.h"</code> before the <code>%inline</code> block.
</p>
<H3><a name="Guile_nn20"></a>19.10.1 Naming Issues</H3>
<H3><a name="Guile_nn20"></a>23.10.1 Naming Issues</H3>
<p>As you can see in the example above, there are potential naming conflicts. The default exported
@ -767,9 +767,7 @@ guile-modules. For example,</p>
(use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:)))
</pre></div>
<p>TODO: Renaming class name prefixes?</p>
<H3><a name="Guile_nn21"></a>19.10.2 Linking</H3>
<H3><a name="Guile_nn21"></a>23.10.2 Linking</H3>
<p>The guile-modules generated above all need to be linked together. GOOPS support requires
@ -814,7 +812,7 @@ Produces the following code at the top of the generated GOOPS guile-module
<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>
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>
@ -848,7 +846,7 @@ Produces the following code at the top of the generated GOOPS guile-module
</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
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>

View file

@ -37,7 +37,7 @@
<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 declarations and creates
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
@ -68,7 +68,8 @@ 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.
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>
@ -194,9 +195,9 @@ extern int my_mod(int n, int m);
<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.
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>
@ -334,7 +335,7 @@ major features include:
<p>
Currently, the only major C++ feature not supported is nested classes--a limitation
that will be removed in a future release.
that should be removed in a future release, but has some workarounds for the moment.
</p>
<p>
@ -365,20 +366,20 @@ possible to support different types of interfaces depending on the application.
<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 from popular IDEs such as
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>)
(<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>ac_pkg_swig</tt>, see
<a href="http://www.gnu.org/software/ac-archive/htmldoc/ac_pkg_swig.html">http://www.gnu.org/software/ac-archive/htmldoc/ac_pkg_swig.html</a>.
The <tt>ac_python_devel</tt> macro is also helpful for generating Python extensions. See the
<a href="http://www.gnu.org/software/ac-archive/htmldoc/index.html">Autoconf Macro Archive</a>
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>
@ -414,7 +415,8 @@ 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.dll (Windows).
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>

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@
<li><a href="#Library_nn3">C Arrays and Pointers</a>
<ul>
<li><a href="#Library_nn4">cpointer.i</a>
<li><a href="#Library_nn5">carrays.i</a>
<li><a href="#Library_carrays">carrays.i</a>
<li><a href="#Library_nn6">cmalloc.i</a>
<li><a href="#Library_nn7">cdata.i</a>
</ul>
@ -27,9 +27,10 @@
</ul>
<li><a href="#Library_stl_cpp_library">STL/C++ Library</a>
<ul>
<li><a href="#Library_nn14">std_string.i</a>
<li><a href="#Library_nn15">std_vector.i</a>
<li><a href="#Library_std_string">std::string</a>
<li><a href="#Library_std_vector">std::vector</a>
<li><a href="#Library_stl_exceptions">STL exceptions</a>
<li><a href="#Library_std_shared_ptr">shared_ptr smart pointer</a>
</ul>
<li><a href="#Library_nn16">Utility Libraries</a>
<ul>
@ -316,7 +317,7 @@ In this example, the function <tt>int_to_uint()</tt> would be used to cast type
<b>Note:</b> When working with simple pointers, typemaps can often be used to provide more seamless operation.
</p>
<H3><a name="Library_nn5"></a>8.2.2 carrays.i</H3>
<H3><a name="Library_carrays"></a>8.2.2 carrays.i</H3>
<p>
@ -419,7 +420,9 @@ delete_doubleArray(a) # Destroy array
</div>
<p>
<b><tt>%array_class(type,name)</tt></b>
</p>
<div class="indent">
<p>
@ -665,7 +668,7 @@ in order for this to work.
</p>
<p>
<b><tt>char *cdata(void *ptr, int nbytes)</tt></b>
<b><tt>const char *cdata(void *ptr, size_t nbytes)</tt></b>
</p>
<div class="indent"><p>
@ -674,13 +677,17 @@ pointer.
</p></div>
<p>
<b><tt>void memmove(void *ptr, char *s)</tt></b>
<b><tt>void memmove(void *ptr, const char *s)</tt></b>
</p>
<div class="indent"><p>
Copies all of the string data in <tt>s</tt> into the memory pointed to by
<tt>ptr</tt>. The string may contain embedded NULL bytes. The length of
the string is implicitly determined in the underlying wrapper code.
<tt>ptr</tt>. The string may contain embedded NULL bytes.
This is actually a wrapper to the standard C library <tt>memmove</tt> function, which is
declared as
<b><tt>void memmove(void *ptr, const void *src, size_t n)</tt></b>.
The <tt>src</tt> and length <tt>n</tt> parameters are
extracted from the language specific string <tt>s</tt> in the underlying wrapper code.
</p></div>
<p>
@ -821,20 +828,20 @@ If you have a function that expects binary data,
<div class="code">
<pre>
int parity(char *str, int len, int initial);
size_t parity(char *str, size_t len, size_t initial);
</pre>
</div>
<p>
you can wrap the parameters <tt>(char *str, int len)</tt> as a single
you can wrap the parameters <tt>(char *str, size_t len)</tt> as a single
argument using a typemap. Just do this:
</p>
<div class="code">
<pre>
%apply (char *STRING, int LENGTH) { (char *str, int len) };
%apply (char *STRING, size_t LENGTH) { (char *str, size_t len) };
...
int parity(char *str, int len, int initial);
size_t parity(char *str, size_t len, size_t initial);
</pre>
</div>
@ -851,6 +858,7 @@ Now, in the target language, you can use binary string data like this:
<p>
In the wrapper function, the passed string will be expanded to a pointer and length parameter.
The <tt>(char *STRING, int LENGTH)</tt> multi-argument typemap is also available in addition to <tt>(char *STRING, size_t LENGTH)</tt>.
</p>
<H3><a name="Library_nn11"></a>8.3.3 Using %newobject to release memory</H3>
@ -888,7 +896,10 @@ char *foo();
</div>
<p>
This will release the result.
This will release the result if the appropriate target language support is available.
SWIG provides the appropriate "newfree" typemap for <tt>char *</tt> so that the memory is released,
however, you may need to provide your own "newfree" typemap for other types.
See <a href="Customization.html#Customization_ownership">Object ownership and %newobject</a> for more details.
</p>
<H3><a name="Library_nn12"></a>8.3.4 cstring.i</H3>
@ -1378,6 +1389,7 @@ The following table shows which C++ classes are supported and the equivalent SWI
<tr> <td>std::set</td> <td>set</td> <td>std_set.i</td> </tr>
<tr> <td>std::string</td> <td>string</td> <td>std_string.i</td> </tr>
<tr> <td>std::vector</td> <td>vector</td> <td>std_vector.i</td> </tr>
<tr> <td>std::shared_ptr</td> <td>shared_ptr</td> <td>std_shared_ptr.i</td> </tr>
</table>
@ -1387,7 +1399,7 @@ Please look for the library files in the appropriate language library directory.
</p>
<H3><a name="Library_nn14"></a>8.4.1 std_string.i</H3>
<H3><a name="Library_std_string"></a>8.4.1 std::string</H3>
<p>
@ -1471,16 +1483,11 @@ void foo(string s, const String &amp;t); // std_string typemaps still applie
</pre>
</div>
<p>
<b>Note:</b> The <tt>std_string</tt> library is incompatible with Perl on some platforms.
We're looking into it.
</p>
<H3><a name="Library_nn15"></a>8.4.2 std_vector.i</H3>
<H3><a name="Library_std_vector"></a>8.4.2 std::vector</H3>
<p>
The <tt>std_vector.i</tt> library provides support for the C++ <tt>vector</tt> class in the STL.
The <tt>std_vector.i</tt> library provides support for the C++ <tt>std::vector</tt> class in the STL.
Using this library involves the use of the <tt>%template</tt> directive. All you need to do is to
instantiate different versions of <tt>vector</tt> for the types that you want to use. For example:
</p>
@ -1655,11 +1662,6 @@ if you want to make their head explode.
details and the public API exposed to the interpreter vary.
</p>
<p>
<b>Note:</b> <tt>std_vector.i</tt> was written by Luigi "The Amazing" Ballabio.
</p>
<H3><a name="Library_stl_exceptions"></a>8.4.3 STL exceptions</H3>
@ -1710,6 +1712,164 @@ The <tt>%exception</tt> directive can be used by placing the following code befo
Any thrown STL exceptions will then be gracefully handled instead of causing a crash.
</p>
<H3><a name="Library_std_shared_ptr"></a>8.4.4 shared_ptr smart pointer</H3>
<p>
Some target languages have support for handling the widely used <tt>boost::shared_ptr</tt> smart pointer.
This smart pointer is also available as <tt>std::tr1::shared_ptr</tt> before it becomes fully standardized as <tt>std::shared_ptr</tt>.
The <tt>boost_shared_ptr.i</tt> library provides support for <tt>boost::shared_ptr</tt> and <tt>std_shared_ptr.i</tt> provides support for <tt>std::shared_ptr</tt>, but if the following macro is defined as shown, it can be used for <tt>std::tr1::shared_ptr</tt>:
</p>
<div class="code">
<pre>
#define SWIG_SHARED_PTR_SUBNAMESPACE tr1
%include &lt;std_shared_ptr.i&gt;
</pre>
</div>
<p>
You can only use one of these variants of shared_ptr in your interface file at a time.
and all three variants must be used in conjunction with the <tt>%shared_ptr(T)</tt> macro,
where <tt>T</tt> is the underlying pointer type equating to usage <tt>shared_ptr&lt;T&gt;</tt>.
The type <tt>T</tt> must be non-primitive.
A simple example demonstrates usage:
</p>
<div class="code">
<pre>
%module example
%include &lt;boost_shared_ptr.i&gt;
%shared_ptr(IntValue)
%inline %{
#include &lt;boost/shared_ptr.hpp&gt;
struct IntValue {
int value;
IntValue(int v) : value(v) {}
};
static int extractValue(const IntValue &amp;t) {
return t.value;
}
static int extractValueSmart(boost::shared_ptr&lt;IntValue&gt; t) {
return t-&gt;value;
}
%}
</pre>
</div>
<p>
Note that the <tt>%shared_ptr(IntValue)</tt> declaration occurs after the inclusion of the <tt>boost_shared_ptr.i</tt>
library which provides the macro and, very importantly, before any usage or declaration of the type, <tt>IntValue</tt>.
The <tt>%shared_ptr</tt> macro provides, a few things for handling this smart pointer, but mostly a number of
typemaps. These typemaps override the default typemaps so that the underlying proxy class is stored and passed around
as a pointer to a <tt>shared_ptr</tt> instead of a plain pointer to the underlying type.
This approach means that any instantiation of the type can be passed to methods taking the type by value, reference, pointer
or as a smart pointer.
The interested reader might want to look at the generated code, however, usage is simple and no different
handling is required from the target language.
For example, a simple use case of the above code from Java would be:
</p>
<div class="targetlang">
<pre>
IntValue iv = new IntValue(1234);
int val1 = example.extractValue(iv);
int val2 = example.extractValueSmart(iv);
System.out.println(val1 + " " + val2);
</pre>
</div>
<p>
This shared_ptr library works quite differently to SWIG's normal, but somewhat limited,
<a href="SWIGPlus.html#SWIGPlus_smart_pointers">smart pointer handling</a>.
The shared_ptr library does not generate extra wrappers, just for smart pointer handling, in addition to the proxy class.
The normal proxy class including inheritance relationships is generated as usual.
The only real change introduced by the <tt>%shared_ptr</tt> macro is that the proxy class stores a pointer to the shared_ptr instance instead of a raw pointer to the instance.
A proxy class derived from a base which is being wrapped with shared_ptr can and <b>must</b> be wrapped as a shared_ptr too.
In other words all classes in an inheritance hierarchy must all be used with the <tt>%shared_ptr</tt> macro.
For example the following code can be used with the base class shown earlier:
</p>
<div class="code">
<pre>
%shared_ptr(DerivedIntValue)
%inline %{
struct DerivedIntValue : IntValue {
DerivedIntValue(int value) : IntValue(value) {}
...
};
%}
</pre>
</div>
<p>
A shared_ptr of the derived class can now be passed to a method where the base is expected in the target language, just as it can in C++:
</p>
<div class="targetlang">
<pre>
DerivedIntValue div = new DerivedIntValue(5678);
int val3 = example.extractValue(div);
int val4 = example.extractValueSmart(div);
</pre>
</div>
<p>
If the <tt>%shared_ptr</tt> macro is omitted for any class in the inheritance hierarchy, SWIG will warn about this and the generated code may or may not result in a C++ compilation error.
For example, the following input:
</p>
<div class="code">
<pre>
%include "boost_shared_ptr.i"
%shared_ptr(Parent);
%inline %{
#include &lt;boost/shared_ptr.hpp&gt;
struct GrandParent {
virtual ~GrandParent() {}
};
struct Parent : GrandParent {
virtual ~Parent() {}
};
struct Child : Parent {
virtual ~Child() {}
};
%}
</pre>
</div>
<p>
warns about the missing smart pointer information:
</p>
<div class="shell">
<pre>
example.i:12: Warning 520: Base class 'GrandParent' of 'Parent' is not similarly marked as a smart pointer.
example.i:16: Warning 520: Derived class 'Child' of 'Parent' is not similarly marked as a smart pointer.
</pre>
</div>
<p>
Adding the missing <tt>%shared_ptr</tt> macros will fix this:
</p>
<div class="code">
<pre>
%include "boost_shared_ptr.i"
%shared_ptr(GrandParent);
%shared_ptr(Parent);
%shared_ptr(Child);
... as before ...
</pre>
</div>
<H2><a name="Library_nn16"></a>8.5 Utility Libraries</H2>

View file

@ -6,7 +6,7 @@
</head>
<body bgcolor="#ffffff">
<H1><a name="Lisp_nn1"></a>21 SWIG and Common Lisp</H1>
<H1><a name="Lisp"></a>25 SWIG and Common Lisp</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
@ -41,16 +41,16 @@
Lisp, Common Foreign Function Interface(CFFI), CLisp and UFFI
foreign function interfaces.
</p>
<H2><a name="Lisp_nn2"></a>21.1 Allegro Common Lisp</H2>
<H2><a name="Lisp_nn2"></a>25.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_nn1">here</a>
<a href="Allegrocl.html#Allegrocl">here</a>
</p>
<H2><a name="Lisp_nn3"></a>21.2 Common Foreign Function Interface(CFFI)</H2>
<H2><a name="Lisp_nn3"></a>25.2 Common Foreign Function Interface(CFFI)</H2>
<p>
@ -77,7 +77,7 @@ swig -cffi -module <i>module-name</i> <i>file-name</i>
files and the various things which you can do with them.
</p>
<H3><a name="Lisp_nn4"></a>21.2.1 Additional Commandline Options </H3>
<H3><a name="Lisp_nn4"></a>25.2.1 Additional Commandline Options </H3>
<p>
@ -96,14 +96,14 @@ swig -cffi -help
<tr>
<td>-generate-typedef</td>
<td>If this option is given then defctype will be used to generate<br\>
<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\>
<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>
@ -118,7 +118,7 @@ swig -cffi -help
</table>
<H3><a name="Lisp_nn5"></a>21.2.2 Generating CFFI bindings</H3>
<H3><a name="Lisp_nn5"></a>25.2.2 Generating CFFI bindings</H3>
As we mentioned earlier the ideal way to use SWIG is to use interface
@ -269,7 +269,7 @@ The generated SWIG Code will be:
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#features">feature directive</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.
@ -392,7 +392,7 @@ The feature <i>intern_function</i> ensures that all C names are
</pre></div>
<H3><a name="Lisp_nn6"></a>21.2.3 Generating CFFI bindings for C++ code</H3>
<H3><a name="Lisp_nn6"></a>25.2.3 Generating CFFI bindings for C++ code</H3>
<p>This feature to SWIG (for CFFI) is very new and still far from
@ -568,7 +568,7 @@ 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>21.2.4 Inserting user code into generated files</H3>
<H3><a name="Lisp_nn7"></a>25.2.4 Inserting user code into generated files</H3>
<p>
@ -583,7 +583,7 @@ using the SWIG <tt>%insert(section) %{ ...code... %}</tt> directive:
<pre>
%module example
%insert("runtime") %{
%{
#include "header.h"
%}
@ -604,11 +604,11 @@ generated lisp interface file:
</ul>
<p>
Note that the block <tt>%{ ... %}</tt> is effectively a shortcut for
<tt>%insert("runtime") %{ ... %}</tt>.
<tt>%insert("header") %{ ... %}</tt>.
</p>
<H2><a name="Lisp_nn8"></a>21.3 CLISP</H2>
<H2><a name="Lisp_nn8"></a>25.3 CLISP</H2>
<p>
@ -638,7 +638,7 @@ swig -clisp -module <i>module-name</i> <i>file-name</i>
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>21.3.1 Additional Commandline Options </H3>
<H3><a name="Lisp_nn9"></a>25.3.1 Additional Commandline Options </H3>
<p>
@ -671,7 +671,7 @@ and global variables will be created otherwise only definitions for<br/>
</table>
<H3><a name="Lisp_nn10"></a>21.3.2 Details on CLISP bindings</H3>
<H3><a name="Lisp_nn10"></a>25.3.2 Details on CLISP bindings</H3>
<p>
@ -795,7 +795,7 @@ struct bar {
</pre></div>
<H2><a name="Lisp_nn11"></a>21.4 UFFI </H2>
<H2><a name="Lisp_nn11"></a>25.4 UFFI </H2>
</body>

View file

@ -6,13 +6,14 @@
</head>
<body bgcolor="#ffffff">
<H1><a name="Lua_nn1"></a>22 SWIG and Lua</H1>
<H1><a name="Lua"></a>26 SWIG and Lua</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Lua_nn2">Preliminaries</a>
<li><a href="#Lua_nn3">Running SWIG</a>
<ul>
<li><a href="#Lua_commandline">Additional command line options</a>
<li><a href="#Lua_nn4">Compiling and Linking and Interpreter</a>
<li><a href="#Lua_nn5">Compiling a dynamic module</a>
<li><a href="#Lua_nn6">Using your module</a>
@ -31,17 +32,33 @@
<li><a href="#Lua_nn17">C++ overloaded functions</a>
<li><a href="#Lua_nn18">C++ operators</a>
<li><a href="#Lua_nn19">Class extension with %extend</a>
<li><a href="#Lua_nn20">C++ templates</a>
<li><a href="#Lua_nn21">C++ Smart Pointers</a>
<li><a href="#Lua_nn22">C++ Exceptions</a>
<li><a href="#Lua_nn23">Writing your own custom wrappers</a>
<li><a href="#Lua_nn24">Adding additional Lua code</a>
<li><a href="#Lua_nn20">Using %newobject to release memory</a>
<li><a href="#Lua_nn21">C++ templates</a>
<li><a href="#Lua_nn22">C++ Smart Pointers</a>
<li><a href="#Lua_nn23">C++ Exceptions</a>
</ul>
<li><a href="#Lua_nn25">Details on the Lua binding</a>
<li><a href="#Lua_nn24">Typemaps</a>
<ul>
<li><a href="#Lua_nn26">Binding global data into the module.</a>
<li><a href="#Lua_nn27">Userdata and Metatables</a>
<li><a href="#Lua_nn28">Memory management</a>
<li><a href="#Lua_nn25">What is a typemap?</a>
<li><a href="#Lua_nn26">Using typemaps</a>
<li><a href="#Lua_nn27">Typemaps and arrays</a>
<li><a href="#Lua_nn28">Typemaps and pointer-pointer functions</a>
</ul>
<li><a href="#Lua_nn29">Writing typemaps</a>
<ul>
<li><a href="#Lua_nn30">Typemaps you can write</a>
<li><a href="#Lua_nn31">SWIG's Lua-C API</a>
</ul>
<li><a href="#Lua_nn32">Customization of your Bindings</a>
<ul>
<li><a href="#Lua_nn33">Writing your own custom wrappers</a>
<li><a href="#Lua_nn34">Adding additional Lua code</a>
</ul>
<li><a href="#Lua_nn35">Details on the Lua binding</a>
<ul>
<li><a href="#Lua_nn36">Binding global data into the module.</a>
<li><a href="#Lua_nn37">Userdata and Metatables</a>
<li><a href="#Lua_nn38">Memory management</a>
</ul>
</ul>
</div>
@ -52,13 +69,18 @@
<p>
Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, light-weight configuration language for any program that needs one. Lua is implemented as a library, written in clean C (that is, in the common subset of ANSI C and C++). Its also a <em>really</em> tiny language, less than 6000 lines of code, which compiles to &lt;100 kilobytes of binary code. It can be found at <a href="http://www.lua.org">http://www.lua.org</a>
</p>
<H2><a name="Lua_nn2"></a>22.1 Preliminaries</H2>
<p>
eLua stands for Embedded Lua (can be thought of as a flavor of Lua) and offers the full implementation of the Lua programming language to the embedded world, extending it with specific features for efficient and portable software embedded development. eLua runs on smaller devices like microcontrollers and provides the full features of the regular Lua desktop version. More information on eLua can be found here: <a href="http://www.eluaproject.net">http://www.eluaproject.net</a>
</p>
<H2><a name="Lua_nn2"></a>26.1 Preliminaries</H2>
<p>
The current SWIG implementation is designed to work with Lua 5.0.x and Lua 5.1.x. It should work with later versions of Lua, but certainly not with Lua 4.0 due to substantial API changes. ((Currently SWIG generated code has only been tested on Windows with MingW, though given the nature of Lua, is should not have problems on other OS's)). It is possible to either static link or dynamic link a Lua module into the interpreter (normally Lua static links its libraries, as dynamic linking is not available on all platforms).
The current SWIG implementation is designed to work with Lua 5.0.x, 5.1.x and 5.2.x. It should work with later versions of Lua, but certainly not with Lua 4.0 due to substantial API changes. It is possible to either static link or dynamic link a Lua module into the interpreter (normally Lua static links its libraries, as dynamic linking is not available on all platforms). SWIG also supports eLua and works with eLua 0.8. SWIG generated code for eLua has been tested on Stellaris ARM Cortex-M3 LM3S and Infineon TriCore.
</p>
<H2><a name="Lua_nn3"></a>22.2 Running SWIG</H2>
<H2><a name="Lua_nn3"></a>26.2 Running SWIG</H2>
<p>
@ -90,7 +112,56 @@ This creates a C/C++ source file <tt>example_wrap.c</tt> or <tt>example_wrap.cxx
<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 -o option. The wrappered module will export one function <tt>"int luaopen_example(lua_State* L)"</tt> which must be called to register the module with the Lua interpreter. The name "luaopen_example" depends upon the name of the module.
</p>
<H3><a name="Lua_nn4"></a>22.2.1 Compiling and Linking and Interpreter</H3>
<p>
To build an eLua module, run SWIG using <tt>-lua</tt> and add either <tt>-elua</tt> or <tt>-eluac</tt>.
</p>
<div class="shell"><pre>
$ swig -lua -elua example.i
</pre></div>
<p>
or
</p>
<div class="shell"><pre>
$ swig -lua -eluac example.i
</pre></div>
<p>
The <tt>-elua</tt> option puts all the C function wrappers and variable get/set wrappers in rotables. It also generates a metatable which will control the access to these variables from eLua. It also offers a significant amount of module size compression. On the other hand, the <tt>-eluac</tt> option puts all the wrappers in a single rotable. With this option, no matter how huge the module, it will consume no additional microcontroller SRAM (crass compression). There is a catch though: Metatables are not generated with <tt>-eluac</tt>. To access any value from eLua, one must directly call the wrapper function associated with that value.
</p>
<H3><a name="Lua_commandline"></a>26.2.1 Additional command line options</H3>
<p>
The following table list the additional commandline options available for the Lua module. They can also be seen by using:
</p>
<div class="code"><pre>
swig -lua -help
</pre></div>
<table summary="Lua specific options">
<tr>
<th>Lua specific options</th>
</tr>
<tr>
<td>-elua</td>
<td>Generates LTR compatible wrappers for smaller devices running elua.</td>
</tr>
<tr>
<td>-eluac</td>
<td>LTR compatible wrappers in "crass compress" mode for elua.</td>
</tr>
<tr>
<td>-nomoduleglobal</td>
<td>Do not register the module name as a global variable but return the module table from calls to require.</td>
</tr>
</table>
<H3><a name="Lua_nn4"></a>26.2.2 Compiling and Linking and Interpreter</H3>
<p>
@ -136,8 +207,33 @@ $ gcc -I/usr/include/lua -c example_wrap.c -o example_wrap.o
$ gcc -c example.c -o example.o
$ gcc -I/usr/include/lua -L/usr/lib/lua min.o example_wrap.o example.o -o my_lua
</pre></div>
<p>
For eLua, the source must be built along with the wrappers generated by SWIG. Make sure the eLua source files <tt>platform_conf.h</tt> and <tt>auxmods.h</tt> are updated with the entries of your new module. Please note: <tt>"mod"</tt> is the module name.
</p>
<div class="code"><pre>
/* Sample platform_conf.h */
#define LUA_PLATFORM_LIBS_ROM\
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
_ROM( AUXLIB_MOD, luaopen_mod, mod_map )\
....
</pre></div>
<p>
</p>
<div class="code"><pre>
/* Sample auxmods.h */
#define AUXLIB_PIO "pio"
LUALIB_API int ( luaopen_pio )(lua_State *L );
<H3><a name="Lua_nn5"></a>22.2.2 Compiling a dynamic module</H3>
#define AUXLIB_MOD "mod"
LUALIB_API int ( luaopen_mod )(lua_State *L );
....
</pre></div>
<p>
More information on building and configuring eLua can be found here: <a href="http://www.eluaproject.net/doc/v0.8/en_building.html">http://www.eluaproject.net/doc/v0.8/en_building.html</a>
</p>
<H3><a name="Lua_nn5"></a>26.2.3 Compiling a dynamic module</H3>
<p>
@ -150,7 +246,7 @@ $ gcc -c example.c -o example.o
$ gcc -shared -I/usr/include/lua -L/usr/lib/lua example_wrap.o example.o -o example.so
</pre></div>
<p>
The wrappers produced by SWIG can be compiled and linked with Lua 5.1.x. The loading is extremely simple.
The wrappers produced by SWIG can be compiled and linked with Lua 5.1.x and later. The loading is extremely simple.
</p>
<div class="targetlang"><pre>
require("example")
@ -161,7 +257,7 @@ For those using Lua 5.0.x, you will also need an interpreter with the loadlib fu
<div class="targetlang"><pre>
my_init=loadlib("example.so","luaopen_example") -- for Unix/Linux
--my_init=loadlib("example.dll","luaopen_example") -- for Windows
assert(my_init) -- name sure its not nil
assert(my_init) -- make sure it's not nil
my_init() -- call the init fn of the lib
</pre></div>
<p>
@ -205,7 +301,7 @@ Is quite obvious (Go back and consult the Lua documents on how to enable loadlib
<H3><a name="Lua_nn6"></a>22.2.3 Using your module</H3>
<H3><a name="Lua_nn6"></a>26.2.4 Using your module</H3>
<p>
@ -223,19 +319,19 @@ $ ./my_lua
&gt;
</pre></div>
<H2><a name="Lua_nn7"></a>22.3 A tour of basic C/C++ wrapping</H2>
<H2><a name="Lua_nn7"></a>26.3 A tour of basic C/C++ wrapping</H2>
<p>
By default, SWIG tries to build a very natural Lua interface to your C/C++ code. This section briefly covers the essential aspects of this wrapping.
</p>
<H3><a name="Lua_nn8"></a>22.3.1 Modules</H3>
<H3><a name="Lua_nn8"></a>26.3.1 Modules</H3>
<p>
The SWIG module directive specifies the name of the Lua module. If you specify `module example', then everything is wrapped into a Lua table 'example' containing all the functions and variables. When choosing a module name, make sure you don't use the same name as a built-in Lua command or standard module name.
</p>
<H3><a name="Lua_nn9"></a>22.3.2 Functions</H3>
<H3><a name="Lua_nn9"></a>26.3.2 Functions</H3>
<p>
@ -273,7 +369,7 @@ It is also possible to rename the module with an assignment.
24
</pre></div>
<H3><a name="Lua_nn10"></a>22.3.3 Global variables</H3>
<H3><a name="Lua_nn10"></a>26.3.3 Global variables</H3>
<p>
@ -319,7 +415,7 @@ extern double Foo;
%mutable;
</pre></div>
<p>
SWIG will allow the the reading of <tt>Foo</tt> but when a set attempt is made, an error function will be called.
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>
&gt; print(e.Foo) -- reading works ok
@ -346,8 +442,22 @@ nil
&gt; print(example.PI)
3.142
</pre></div>
<p>
If you have used the <tt>-eluac</tt> option for your eLua module, you will have to follow a different approach while manipulating global variables. (This is not applicable for wrappers generated with <tt>-elua</tt>)
</p>
<div class="targetlang"><pre>
&gt; -- Applicable only with -eluac. (num is defined)
&gt; print(example.num_get())
20
&gt; example.num_set(50) -- new value added
&gt; print(example.num_get())
50
</pre></div>
<p>
In general, functions of the form <tt>"variable_get()"</tt> and <tt>"variable_set()"</tt> are automatically generated by SWIG for use with <tt>-eluac</tt>.
</p>
<H3><a name="Lua_nn11"></a>22.3.4 Constants and enums</H3>
<H3><a name="Lua_nn11"></a>26.3.4 Constants and enums</H3>
<p>
@ -370,7 +480,18 @@ example.SUNDAY=0
<p>
Constants are not guaranteed to remain constant in Lua. The name of the constant could be accidentally reassigned to refer to some other object. Unfortunately, there is no easy way for SWIG to generate code that prevents this. You will just have to be careful.
</p>
<H3><a name="Lua_nn12"></a>22.3.5 Pointers</H3>
<p>
If you're using eLua and have used <tt>-elua</tt> or <tt>-eluac</tt> to generate your wrapper, macro constants and enums should be accessed through a rotable called <tt>"const"</tt>. In eLua, macro constants and enums are guaranteed to remain constants since they are all contained within a rotable. A regular C constant is accessed from eLua just as if it were a regular global variable, just that the property of value immutability is demonstrated if an attempt at modifying a C constant is made.
</p>
<div class="targetlang"><pre>
&gt; print(example.ICONST)
10
&gt; print(example.const.SUNDAY)
0
&gt; print(example.const.SCONST)
Hello World
</pre></div>
<H3><a name="Lua_nn12"></a>26.3.5 Pointers</H3>
<p>
@ -408,7 +529,7 @@ Lua enforces the integrity of its userdata, so it is virtually impossible to cor
nil
</pre></div>
<H3><a name="Lua_nn13"></a>22.3.6 Structures</H3>
<H3><a name="Lua_nn13"></a>26.3.6 Structures</H3>
<p>
@ -493,8 +614,26 @@ Because the pointer points inside the structure, you can modify the contents and
&gt; x = b.f
&gt; x.a = 3 -- Modifies the same structure
</pre></div>
<p>
For eLua with the <tt>-eluac</tt> option, structure manipulation has to be performed with specific structure functions generated by SWIG. Let's say you have the following structure definition:
</p>
<div class="code"><pre>struct data {
int x, y;
double z;
};
<H3><a name="Lua_nn14"></a>22.3.7 C++ classes</H3>
&gt; --From eLua
&gt; a = example.new_data()
&gt; example.data_x_set(a, 10)
&gt; example.data_y_set(a, 20)
&gt; print(example.data_x_get(a), example.data_y_get(a))
10 20
</pre></div>
<p>
In general, functions of the form <tt>"new_struct()"</tt>, <tt>"struct_member_get()"</tt>, <tt>"struct_member_set()"</tt> and <tt>"free_struct()"</tt> are automatically generated by SWIG for each structure defined in C. (Please note: This doesn't apply for modules generated with the <tt>-elua</tt> option)
</p>
<H3><a name="Lua_nn14"></a>26.3.7 C++ classes</H3>
<p>
@ -526,7 +665,7 @@ Stout
&gt;
</pre></div>
<p>
(Note: for calling methods of a class, you use <tt>class:method(args)</tt>, not <tt>class.method(args)</tt>, its an easy mistake to make. However for data attributes it is <tt>class.attribute</tt>)
(Note: for calling methods of a class, you use <tt>class:method(args)</tt>, not <tt>class.method(args)</tt>, it's an easy mistake to make. However for data attributes it is <tt>class.attribute</tt>)
</p>
<p>
Class data members are accessed in the same manner as C structures. Static class members present a special problem for Lua, as Lua doesn't have support for such features. Therefore, SWIG generates wrappers that try to work around some of these issues. To illustrate, suppose you have a class like this:
@ -535,7 +674,6 @@ Class data members are accessed in the same manner as C structures. Static class
public:
static void foo();
static int bar;
};
</pre></div>
<p>
@ -555,7 +693,7 @@ It is not (currently) possible to access static members of an instance:
-- does NOT work
</pre></div>
<H3><a name="Lua_nn15"></a>22.3.8 C++ inheritance</H3>
<H3><a name="Lua_nn15"></a>26.3.8 C++ inheritance</H3>
<p>
@ -580,7 +718,7 @@ then the function <tt>spam()</tt> accepts a Foo pointer or a pointer to any clas
<p>
It is safe to use multiple inheritance with SWIG.
</p>
<H3><a name="Lua_nn16"></a>22.3.9 Pointers, references, values, and arrays</H3>
<H3><a name="Lua_nn16"></a>26.3.9 Pointers, references, values, and arrays</H3>
<p>
@ -611,7 +749,7 @@ Foo spam7();
<p>
then all three functions will return a pointer to some Foo object. Since the third function (spam7) returns a value, newly allocated memory is used to hold the result and a pointer is returned (Lua will release this memory when the return value is garbage collected). The other two are pointers which are assumed to be managed by the C code and so will not be garbage collected.
</p>
<H3><a name="Lua_nn17"></a>22.3.10 C++ overloaded functions</H3>
<H3><a name="Lua_nn17"></a>26.3.10 C++ overloaded functions</H3>
<p>
@ -669,8 +807,8 @@ void foo(Bar &amp;b);
If declarations such as these appear, you will get a warning message like this:
</p>
<div class="shell"><pre>
example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int)
at example.i:11.
example.i:12: Warning 509: Overloaded method spam(short) effectively ignored,
example.i:11: Warning 509: as it is shadowed by spam(int).
</pre></div>
<p>
To fix this, you either need to ignore or rename one of the methods. For example:
@ -697,7 +835,7 @@ Please refer to the "SWIG and C++" chapter for more information about overloadin
<p>
Dealing with the Lua coercion mechanism, the priority is roughly (integers, floats, strings, userdata). But it is better to rename the functions rather than rely upon the ordering.
</p>
<H3><a name="Lua_nn18"></a>22.3.11 C++ operators</H3>
<H3><a name="Lua_nn18"></a>26.3.11 C++ operators</H3>
<p>
@ -809,7 +947,7 @@ It is also possible to overload the operator<tt>[]</tt>, but currently this cann
};
</pre></div>
<H3><a name="Lua_nn19"></a>22.3.12 Class extension with %extend</H3>
<H3><a name="Lua_nn19"></a>26.3.12 Class extension with %extend</H3>
<p>
@ -864,7 +1002,32 @@ true
<p>
Extend works with both C and C++ code, on classes and structs. It does not modify the underlying object in any way---the extensions only show up in the Lua interface. The only item to take note of is the code has to use the '$self' instead of 'this', and that you cannot access protected/private members of the code (as you are not officially part of the class).
</p>
<H3><a name="Lua_nn20"></a>22.3.13 C++ templates</H3>
<H3><a name="Lua_nn20"></a>26.3.13 Using %newobject to release memory</H3>
<p> If you have a function that allocates memory like this,</p>
<div class="code">
<pre>char *foo() {
char *result = (char *) malloc(...);
...
return result;
}
</pre>
</div>
<p> then the SWIG generated wrappers will have a memory leak--the
returned data will be copied into a string object and the old contents
ignored.</p>
<p> To fix the memory leak, use the <a href="Customization.html#Customization_ownership">%newobject directive</a>.</p>
<div class="code">
<pre>%newobject foo;
...
char *foo();
</pre>
</div>
<p> This will release the allocated memory.</p>
<H3><a name="Lua_nn21"></a>26.3.14 C++ templates</H3>
<p>
@ -899,7 +1062,7 @@ In Lua:
<p>
Obviously, there is more to template wrapping than shown in this example. More details can be found in the SWIG and C++ chapter. Some more complicated examples will appear later.
</p>
<H3><a name="Lua_nn21"></a>22.3.14 C++ Smart Pointers</H3>
<H3><a name="Lua_nn22"></a>26.3.15 C++ Smart Pointers</H3>
<p>
@ -951,7 +1114,7 @@ If you ever need to access the underlying pointer returned by <tt>operator-&gt;(
&gt; f = p:__deref__() -- Returns underlying Foo *
</pre></div>
<H3><a name="Lua_nn22"></a>22.3.15 C++ Exceptions</H3>
<H3><a name="Lua_nn23"></a>26.3.16 C++ Exceptions</H3>
<p>
@ -970,13 +1133,13 @@ SWIG will automatically convert this to a Lua error.
</p>
<div class="targetlang"><pre>
> message()
&gt; message()
I died.
stack traceback:
[C]: in function 'message'
stdin:1: in main chunk
[C]: ?
>
&gt;
</pre></div>
<p>
@ -985,13 +1148,13 @@ Using xpcall will allow you to obtain additional debug information (such as a st
</p>
<div class="targetlang"><pre>
> function a() b() end -- function a() calls function b()
> function b() message() end -- function b() calls C++ function message(), which throws
> ok,res=pcall(a) -- call the function
> print(ok,res)
&gt; function a() b() end -- function a() calls function b()
&gt; function b() message() end -- function b() calls C++ function message(), which throws
&gt; ok,res=pcall(a) -- call the function
&gt; print(ok,res)
false I died.
> ok,res=xpcall(a,debug.traceback) -- call the function
> print(ok,res)
&gt; ok,res=xpcall(a,debug.traceback) -- call the function
&gt; print(ok,res)
false I died.
stack traceback:
[C]: in function 'message'
@ -1003,11 +1166,12 @@ stack traceback:
</pre></div>
<p>
SWIG is able to throw numeric types, enums, chars, char*'s and std::string's without problem.
However its not so simple for to throw objects.
SWIG is able to throw numeric types, enums, chars, char*'s and std::string's without problem. It has also written typemaps for std::exception and its derived classes, which convert the exception into an error string. </p>
<p>
However it's not so simple to throw other types of objects.
Thrown objects are not valid outside the 'catch' block. Therefore they cannot be
returned to the interpreter.
The obvious ways to overcome this would be to either return a copy of the object, or so convert the object to a string and
The obvious ways to overcome this would be to either return a copy of the object, or to convert the object to a string and
return that. Though it seems obvious to perform the former, in some cases this is not possible, most notably when
SWIG has no information about the object, or the object is not copyable/creatable.
</p>
@ -1021,27 +1185,23 @@ void throw_A() throw(A*) {
}
</pre></div>
<p>
SWIG will just convert it (poorly) to a string and use that as its error. (Yes its not that useful, but it always works).
SWIG will just convert it (poorly) to a string and use that as its error. (This is not that useful, but it always works).
</p>
<div class="targetlang"><pre>
> throw_A()
&gt; throw_A()
object exception:A *
stack traceback:
[C]: in function 'unknown'
stdin:1: in main chunk
[C]: ?
>
&gt;
</pre></div>
<p>
To get a more useful behaviour out of SWIG you must either: provide a way to convert your exceptions into strings, or
throw objects which can be copied.
</p>
<p>
SWIG has typemaps for std::exception and its children already written, so a function which throws any of these will
automatically have its exception converted into an error string.
</p>
<p>
If you have your own class which you want output as a string you will need to add a typemap something like this:
</p>
<div class="code"><pre>
@ -1052,8 +1212,8 @@ If you have your own class which you want output as a string you will need to ad
%}
</pre></div>
<p>
If you wish your exception to be returned to the interpreter, it must firstly be copyable. Then you must have and additional
<tt>%apply</tt> statement, to inform SWIG to return a copy of this object to the interpreter. For example:
If you wish your exception to be returned to the interpreter, it must firstly be copyable. Then you must have an additional
<tt>%apply</tt> statement, to tell SWIG to return a copy of this object to the interpreter. For example:
</p>
<div class="code"><pre>
%apply SWIGTYPE EXCEPTION_BY_VAL {Exc}; // tell SWIG to return Exc by value to interpreter
@ -1076,33 +1236,297 @@ void throw_exc() throw(Exc) {
Then the following code can be used (note: we use pcall to catch the error so we can process the exception).
</p>
<div class="targetlang"><pre>
> ok,res=pcall(throw_exc)
> print(ok)
&gt; ok,res=pcall(throw_exc)
&gt; print(ok)
false
> print(res)
&gt; print(res)
userdata: 0003D880
> print(res.code,res.msg)
&gt; print(res.code,res.msg)
42 Hosed
>
&gt;
</pre></div>
<p>
Note: is is also possible (though tedious) to have a function throw several different kinds of exceptions. To process this
Note: it is also possible (though tedious) to have a function throw several different kinds of exceptions. To process this
will require a pcall, followed by a set of if statements checking the type of the error.
</p>
<p>
All of this code assumes that your C++ code uses exception specification (which a lot doesn't).
If it doesn't consult the "<a href="SWIGPlus.html#SWIGPlus_catches">Exception handling with %catches</a>" section
and the "<a href="Customization.html#exception">Exception handling with %exception</a>" section, for more details on how to
and the "<a href="Customization.html#Customization_exception">Exception handling with %exception</a>" section, for more details on how to
add exception specification to functions or globally (respectively).
</p>
<H3><a name="Lua_nn23"></a>22.3.16 Writing your own custom wrappers</H3>
<H2><a name="Lua_nn24"></a>26.4 Typemaps</H2>
<p>This section explains what typemaps are and the usage of them. The default wrapping behaviour of SWIG is enough in most cases. However sometimes SWIG may need a little additional assistance to know which typemap to apply to provide the best wrapping. This section will be explaining how to use typemaps to best effect</p>
<H3><a name="Lua_nn25"></a>26.4.1 What is a typemap?</H3>
<p>A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from Lua to C, you might define a typemap like this:</p>
<div class="code"><pre>%module example
%typemap(in) int {
$1 = (int) lua_tonumber(L,$input);
printf("Received an integer : %d\n",$1);
}
%inline %{
extern int fact(int n);
%}
</pre></div>
<p><i>Note: you shouldn't use this typemap, as SWIG already has a typemap for this task. This is purely for example.</i></p>
<p>Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int. The $input is the index on the Lua stack for the value to be used.</p>
<p>When this example is compiled into a Lua module, it operates as follows:</p>
<div class="targetlang"><pre>&gt; require "example"
&gt; print(example.fact(6))
Received an integer : 6
720
</pre></div>
<H3><a name="Lua_nn26"></a>26.4.2 Using typemaps</H3>
<p>There are many ready written typemaps built into SWIG for all common types (int, float, short, long, char*, enum and more), which SWIG uses automatically, with no effort required on your part.</p>
<p>However for more complex functions which use input/output parameters or arrays, you will need to make use of &lt;typemaps.i&gt;, which contains typemaps for these situations. For example, consider these functions:</p>
<div class="code"><pre>void add(int x, int y, int *result) {
*result = x + y;
}
int sub(int *x1, int *y1) {
return *x1-*y1;
}
void swap(int *sx, int *sy) {
int t=*sx;
*sx=*sy;
*sy=t;
}
</pre></div>
<p>It is clear to the programmer, that 'result' is an output parameter, 'x1' and 'y1' are input parameters and 'sx' and 'sy' are input/output parameters. However is not apparent to SWIG, so SWIG must to informed about which kind they are, so it can wrapper accordingly.</p>
<p>One means would be to rename the argument name to help SWIG, eg <tt>void add(int x, int y, int *OUTPUT)</tt>, however it is easier to use the <tt>%apply</tt> to achieve the same result, as shown below.</p>
<div class="code"><pre>%include &lt;typemaps.i&gt;
%apply int* OUTPUT {int *result}; // int *result is output
%apply int* INPUT {int *x1, int *y1}; // int *x1 and int *y1 are input
%apply int* INOUT {int *sx, int *sy}; // int *sx and int *sy are input and output
void add(int x, int y, int *result);
int sub(int *x1, int *y1);
void swap(int *sx, int *sy);
</pre></div>
<p>When wrapped, it gives the following results:</p>
<div class="targetlang"><pre>&gt; require "example"
&gt; print(example.add(1,2))
3
&gt; print(demo.sub(1,2))
-1
&gt; a,b=1,2
&gt; c,d=demo.swap(a,b)
&gt; print(a,b,c,d)
1 2 2 1
</pre></div>
<p>Notice, that 'result' is not required in the arguments to call the function, as it an output parameter only. For 'sx' and 'sy' they must be passed in (as they are input), but the original value is not modified (Lua does not have a pass by reference feature). The modified results are then returned as two return values. All INPUT/OUTPUT/INOUT arguments will behave in a similar manner.</p>
<p>Note: C++ references must be handled exactly the same way. However SWIG will automatically wrap a <tt>const int&amp;</tt> as an input parameter (since that it obviously input).</p>
<H3><a name="Lua_nn27"></a>26.4.3 Typemaps and arrays</H3>
<p>Arrays present a challenge for SWIG, because like pointers SWIG does not know whether these are input or output values, nor
does SWIG have any indication of how large an array should be. However with the proper guidance SWIG can easily wrapper
arrays for convenient usage.</p>
<p>Given the functions:</p>
<div class="code"><pre>extern void sort_int(int* arr, int len);
extern void sort_double(double* arr, int len);
</pre></div>
<p>There are basically two ways that SWIG can deal with this. The first way, uses the <tt>&lt;carrays.i&gt;</tt> library
to create an array in C/C++ then this can be filled within Lua and passed into the function. It works, but its a bit tedious.
More details can be found in the <a href="Library.html#Library_carrays">carrays.i</a> documention.</p>
<p>The second and more intuitive way, would be to pass a Lua table directly into the function, and have SWIG automatically convert between Lua-table and C-array. Within the <tt>&lt;typemaps.i&gt;</tt> file there are typemaps ready written to perform this task. To use them is again a matter of using %appy in the correct manner.</p>
<p>The wrapper file below, shows both the use of carrays as well as the use of the typemap to wrap arrays. </p>
<div class="code"><pre>// using the C-array
%include &lt;carrays.i&gt;
// this declares a batch of function for manipulating C integer arrays
%array_functions(int,int)
extern void sort_int(int* arr, int len); // the function to wrap
// using typemaps
%include &lt;typemaps.i&gt;
%apply (double *INOUT,int) {(double* arr,int len)};
extern void sort_double(double* arr, int len); // the function to wrap
</pre></div>
<p>Once wrappered, the functions can both be called, though with different ease of use:</p>
<div class="targetlang"><pre>require "example"
ARRAY_SIZE=10
-- passing a C array to the sort_int()
arr=example.new_int(ARRAY_SIZE) -- create the array
for i=0,ARRAY_SIZE-1 do -- index 0..9 (just like C)
example.int_setitem(arr,i,math.random(1000))
end
example.sort_int(arr,ARRAY_SIZE) -- call the function
example.delete_int(arr) -- must delete the allocated memory
-- use a typemap to call with a Lua-table
-- one item of note: the typemap creates a copy, rather than edit-in-place
t={} -- a Lua table
for i=1,ARRAY_SIZE do -- index 1..10 (Lua style)
t[i]=math.random(1000)/10
end
t=example.sort_double(t) -- replace t with the result
</pre></div>
<p>Obviously the first version could be made less tedious by writing a Lua function to perform the conversion from a table
to a C-array. The <tt>%luacode</tt> directive is good for this. See SWIG\Examples\lua\arrays for an example of this.</p>
<p><b>Warning:</b> in C indexes start at ZERO, in Lua indexes start at ONE. SWIG expects C-arrays to be filled for 0..N-1
and Lua tables to be 1..N, (the indexing follows the norm for the language). In the typemap when it converts the table to an array it quietly changes the indexing accordingly. Take note of this behaviour if you have a C function which returns indexes.</p>
<p>Note: SWIG also can support arrays of pointers in a similar manner.</p>
<H3><a name="Lua_nn28"></a>26.4.4 Typemaps and pointer-pointer functions</H3>
<p>Several C++ libraries use a pointer-pointer functions to create its objects. These functions require a pointer to a pointer which is then filled with the pointer to the new object. Microsoft's COM and DirectX as well as many other libraries have this kind of function. An example is given below:</p>
<div class="code"><pre>struct iMath; // some structure
int Create_Math(iMath** pptr); // its creator (assume it mallocs)
</pre></div>
<p>Which would be used with the following C code:</p>
<div class="code"><pre>iMath* ptr;
int ok;
ok=Create_Math(&amp;ptr);
// do things with ptr
//...
free(ptr); // dispose of iMath
</pre></div>
<p>SWIG has a ready written typemap to deal with such a kind of function in &lt;typemaps.i&gt;. It provides the correct wrapping as well as setting the flag to inform Lua that the object in question should be garbage collected. Therefore the code is simply:</p>
<div class="code"><pre>%include &lt;typemaps.i&gt;
%apply SWIGTYPE** OUTPUT{iMath **pptr }; // tell SWIG its an output
struct iMath; // some structure
int Create_Math(iMath** pptr); // its creator (assume it mallocs)
</pre></div>
<p>The usage is as follows:</p>
<div class="targetlang"><pre>ok,ptr=Create_Math() -- ptr is a iMath* which is returned with the int (ok)
ptr=nil -- the iMath* will be GC'ed as normal
</pre></div>
<H2><a name="Lua_nn29"></a>26.5 Writing typemaps</H2>
<p>This section describes how you can modify SWIG's default wrapping behavior for various C/C++ datatypes using the <tt>%typemap</tt> directive. This is an advanced topic that assumes familiarity with the Lua C API as well as the material in the "<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter.</p>
<p>Before proceeding, it should be stressed that writing typemaps is rarely needed unless you want to change some aspect of the wrapping, or to achieve an effect which in not available with the default bindings.</p>
<p>Before proceeding, you should read the previous section on using typemaps, as well as read the ready written typemaps found in luatypemaps.swg and typemaps.i. These are both well documented and fairly easy to read. You should not attempt to write your own typemaps until you have read and can understand both of these files (they may well also give you a idea to base your worn on).</p>
<H3><a name="Lua_nn30"></a>26.5.1 Typemaps you can write</H3>
<p>There are many different types of typemap that can be written, the full list can be found in the "<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter. However the following are the most commonly used ones.</p>
<ul>
<li><tt>in</tt> this is for input arguments to functions</li>
<li><tt>out</tt> this is for return types from functions</li>
<li><tt>argout</tt> this is for a function argument which is actually returning something</li>
<li><tt>typecheck</tt> this is used to determine which overloaded function should be called
(the syntax for the typecheck is different from the typemap, see typemaps for details).</li>
</ul>
<H3><a name="Lua_nn31"></a>26.5.2 SWIG's Lua-C API</H3>
<p>This section explains the SWIG specific Lua-C API. It does not cover the main Lua-C api, as this is well documented and not worth covering.</p>
<p><tt>int SWIG_ConvertPtr(lua_State* L,int index,void** ptr,swig_type_info *type,int flags);</tt></p>
<div class="indent">
This is the standard function used for converting a Lua userdata to a void*. It takes the value at the given index in the Lua state and converts it to a userdata. It will then provide the necessary type checks, confirming that the pointer is compatible with the type given in 'type'. Then finally setting '*ptr' to the pointer.
If flags is set to SWIG_POINTER_DISOWN, this is will clear any ownership flag set on the object.<br>
The returns a value which can be checked with the macro SWIG_IsOK()
</div>
<p><tt>void SWIG_NewPointerObj(lua_State* L,void* ptr,swig_type_info *type,int own);</tt></p>
<div class="indent">
This is the opposite of SWIG_ConvertPtr, as it pushes a new userdata which wrappers the pointer 'ptr' of type 'type'.
The parameter 'own' specifies if the object is owned be Lua and if it is 1 then Lua will GC the object when the userdata is disposed of.
</div>
<p><tt>void* SWIG_MustGetPtr(lua_State* L,int index,swig_type_info *type,int flags,int argnum,const char* func_name);</tt></p>
<div class="indent">
This function is a version of SWIG_ConvertPtr(), except that it will either work, or it will trigger a lua_error() with a text error message. This function is rarely used, and may be deprecated in the future.
</div>
<p><tt>SWIG_fail</tt></p>
<div class="indent">
This macro, when called within the context of a SWIG wrapped function, will jump to the error handler code. This will call any cleanup code (freeing any temp variables) and then triggers a lua_error.<br>
A common use for this code is:<br><pre>
if (!SWIG_IsOK(SWIG_ConvertPtr( .....)){
lua_pushstring(L,"something bad happened");
SWIG_fail;
}</pre></div>
<p><tt>SWIG_fail_arg(char* func_name,int argnum,char* type)</tt></p>
<div class="indent">
This macro, when called within the context of a SWIG wrapped function, will display the error message and jump to the error handler code. The error message is of the form
<pre>
"Error in <i>func_name</i> (arg <i>argnum</i>), expected '<i>type</i>' got '<i>whatever the type was</i>'"
</pre></div>
<p><tt>SWIG_fail_ptr(const char* fn_name,int argnum,swig_type_info* type);</tt></p>
<div class="indent">
Similar to SWIG_fail_arg, except that it will display the swig_type_info information instead.</div>
<H2><a name="Lua_nn32"></a>26.6 Customization of your Bindings</H2>
<p>
Sometimes, it may be neccesary to add your own special functions, which bypass the normal SWIG wrappering method, and just use the native Lua API calls. These 'native' functions allow direct adding of your own code into the module. This is performed with the <tt>%native</tt> directive as follows:
This section covers adding of some small extra bits to your module to add the last finishing touches.
</p>
<H3><a name="Lua_nn33"></a>26.6.1 Writing your own custom wrappers</H3>
<p>
Sometimes, it may be necessary to add your own special functions, which bypass the normal SWIG wrapper method, and just use the native Lua API calls. These 'native' functions allow direct adding of your own code into the module. This is performed with the <tt>%native</tt> directive as follows:
</p>
<div class="code"><pre>%native(my_func) int native_function(lua_State*L); // registers native_function() with SWIG
...
@ -1114,10 +1538,10 @@ int native_function(lua_State*L) // my native code
%}
</pre></div>
<p>
The <tt>%native</tt> directive in the above example, tells SWIG that there is a function <tt>int native_function(lua_State*L);</tt> which is to be added into the module under the name '<tt>my_func</tt>'. SWIG will not add any wrappering for this function, beyond adding it into the function table. How you write your code is entirely up to you.
The <tt>%native</tt> directive in the above example, tells SWIG that there is a function <tt>int native_function(lua_State*L);</tt> which is to be added into the module under the name '<tt>my_func</tt>'. SWIG will not add any wrapper for this function, beyond adding it into the function table. How you write your code is entirely up to you.
</p>
<H3><a name="Lua_nn24"></a>22.3.17 Adding additional Lua code</H3>
<H3><a name="Lua_nn34"></a>26.6.2 Adding additional Lua code</H3>
<p>
@ -1155,18 +1579,18 @@ Good uses for this feature is adding of new code, or writing helper functions to
See Examples/lua/arrays for an example of this code.
</p>
<H2><a name="Lua_nn25"></a>22.4 Details on the Lua binding</H2>
<H2><a name="Lua_nn35"></a>26.7 Details on the Lua binding</H2>
<p>
In the previous section, a high-level view of Lua wrapping was presented. Obviously a lot of stuff happens behind the scenes to make this happen. This section will explain some of the low-level details on how this is achieved.
</p>
<p>
<i>If you just want to use SWIG and don't care how it works, then stop reading here. This is going into the guts of the code and how it works. Its mainly for people who need to know whats going on within the code.
<i>If you just want to use SWIG and don't care how it works, then stop reading here. This is going into the guts of the code and how it works. It's mainly for people who need to know what's going on within the code.
</i>
</p>
<H3><a name="Lua_nn26"></a>22.4.1 Binding global data into the module.</H3>
<H3><a name="Lua_nn36"></a>26.7.1 Binding global data into the module.</H3>
<p>
@ -1226,7 +1650,7 @@ end
<p>
That way when you call '<tt>a=example.Foo</tt>', the interpreter looks at the table 'example' sees that there is no field 'Foo' and calls __index. This will in turn check in '.get' table and find the existence of 'Foo' and then return the value of the C function call 'Foo_get()'. Similarly for the code '<tt>example.Foo=10</tt>', the interpreter will check the table, then call the __newindex which will then check the '.set' table and call the C function 'Foo_set(10)'.
</p>
<H3><a name="Lua_nn27"></a>22.4.2 Userdata and Metatables</H3>
<H3><a name="Lua_nn37"></a>26.7.2 Userdata and Metatables</H3>
<p>
@ -1301,16 +1725,16 @@ So when 'p:Print()' is called, the __index looks on the object metatable for a '
In theory, you can play with this usertable &amp; add new features, but remember that it is a shared table between all instances of one class, and you could very easily corrupt the functions in all the instances.
</p>
<p>
Note: Both the opaque structures (like the FILE*) and normal wrappered classes/structs use the same 'swig_lua_userdata' structure. Though the opaque structures has do not have a metatable attached, or any information on how to dispose of them when the interpreter has finished with them.
Note: Both the opaque structures (like the FILE*) and normal wrapped classes/structs use the same 'swig_lua_userdata' structure. Though the opaque structures has do not have a metatable attached, or any information on how to dispose of them when the interpreter has finished with them.
</p>
<p>
Note: Operator overloads are basically done in the same way, by adding functions such as '__add' &amp; '__call' to the classes metatable. The current implementation is a bit rough as it will add any member function beginning with '__' into the metatable too, assuming its an operator overload.
</p>
<H3><a name="Lua_nn28"></a>22.4.3 Memory management</H3>
<H3><a name="Lua_nn38"></a>26.7.3 Memory management</H3>
<p>
Lua is very helpful with the memory management. The 'swig_lua_userdata' is fully managed by the interpreter itself. This means that neither the C code nor the Lua code can damage it. Once a piece of userdata has no references to it, it is not instantly collected, but will be collected when Lua deems is necessary. (You can force collection by calling the Lua function <tt>collectgarbage()</tt>). Once the userdata is about to be free'ed, the interpreter will check the userdata for a metatable and for a function '__gc'. If this exists this is called. For all complete types (ie normal wrappered classes &amp; structs) this should exist. The '__gc' function will check the 'swig_lua_userdata' to check for the 'own' field and if this is true (which is will be for all owned data's) it will then call the destructor on the pointer.
Lua is very helpful with the memory management. The 'swig_lua_userdata' is fully managed by the interpreter itself. This means that neither the C code nor the Lua code can damage it. Once a piece of userdata has no references to it, it is not instantly collected, but will be collected when Lua deems is necessary. (You can force collection by calling the Lua function <tt>collectgarbage()</tt>). Once the userdata is about to be free'ed, the interpreter will check the userdata for a metatable and for a function '__gc'. If this exists this is called. For all complete types (ie normal wrapped classes &amp; structs) this should exist. The '__gc' function will check the 'swig_lua_userdata' to check for the 'own' field and if this is true (which is will be for all owned data) it will then call the destructor on the pointer.
</p>
<p>
It is currently not recommended to edit this field or add some user code, to change the behaviour. Though for those who wish to try, here is where to look.

View file

@ -9,55 +9,70 @@
# 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 clean validate test
.PHONY: maketoc check generate all maintainer-clean validate test
all: maketoc check generate
maketoc:
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`; for a in $$all; do tidy -errors --gnu-emacs yes -quiet $$a; done;
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:
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:
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
clean:
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;
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;
all=`sed '/^#/d' chapters`; for a in $$all; do validate --emacs $$a; done;
# Link checking using linkchecker
linkchecker:
@echo -----------------------------------------------------------------------
@echo Note linkchecker versions prior to 6.1 do not work properly wrt anchors
@echo -----------------------------------------------------------------------
linkchecker --config=./linkchecker.config index.html

View file

@ -5,42 +5,39 @@
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="Modula3"></a>23 SWIG and Modula-3</H1>
<H1><a name="Modula3"></a>27 SWIG and Modula-3</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#modula3_overview">Overview</a>
<li><a href="#Modula3_modula3_overview">Overview</a>
<ul>
<li><a href="#whyscripting">Why not scripting ?</a>
<li><a href="#whymodula3">Why Modula-3 ?</a>
<li><a href="#whycpp">Why C / C++ ?</a>
<li><a href="#whyswig">Why SWIG ?</a>
<li><a href="#Modula3_motivation">Motivation</a>
</ul>
<li><a href="#conception">Conception</a>
<li><a href="#Modula3_conception">Conception</a>
<ul>
<li><a href="#cinterface">Interfaces to C libraries</a>
<li><a href="#cppinterface">Interfaces to C++ libraries</a>
<li><a href="#Modula3_cinterface">Interfaces to C libraries</a>
<li><a href="#Modula3_cppinterface">Interfaces to C++ libraries</a>
</ul>
<li><a href="#preliminaries">Preliminaries</a>
<li><a href="#Modula3_preliminaries">Preliminaries</a>
<ul>
<li><a href="#compilers">Compilers</a>
<li><a href="#commandline">Additional Commandline Options</a>
<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>
<li><a href="#Modula3_typemaps">Modula-3 typemaps</a>
<ul>
<li><a href="#inoutparam">Inputs and outputs</a>
<li><a href="#ordinals">Subranges, Enumerations, Sets</a>
<li><a href="#class">Objects</a>
<li><a href="#imports">Imports</a>
<li><a href="#exceptions">Exceptions</a>
<li><a href="#typemap_example">Example</a>
<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="#hints">More hints to the generator</a>
<li><a href="#Modula3_hints">More hints to the generator</a>
<ul>
<li><a href="#features">Features</a>
<li><a href="#pragmas">Pragmas</a>
<li><a href="#Modula3_features">Features</a>
<li><a href="#Modula3_pragmas">Pragmas</a>
</ul>
<li><a href="#remarks">Remarks</a>
<li><a href="#Modula3_remarks">Remarks</a>
</ul>
</div>
<!-- INDEX -->
@ -49,24 +46,29 @@
<p>
This chapter describes SWIG's support of
<a href="http://www.m3.org/">Modula-3</a>.
<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</a>.
<a href="Typemaps.html#Typemaps">typemaps</a>.
</p>
<H2><a name="modula3_overview"></a>23.1 Overview</H2>
<H2><a name="Modula3_modula3_overview"></a>27.1 Overview</H2>
<p>
The Modula-3 support is very basic and highly experimental!
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!
The Modula-3 generator was already useful for interfacing
to the libraries
However, the Modula-3 generator was already useful for interfacing
to the libraries:
</p>
<ol>
@ -78,130 +80,34 @@ PLPlot
<li>
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/fftw/">
FFTW
</a> .
</a>
</li>
</ol>
<p>
I took some more time to explain
why I think it's right what I'm doing.
So the introduction got a bit longer than it should ... ;-)
</p>
<H3><a name="whyscripting"></a>23.1.1 Why not scripting ?</H3>
<H3><a name="Modula3_motivation"></a>27.1.1 Motivation</H3>
<p>
SWIG started as wrapper from the fast compiled languages C and C++
to high level scripting languages like Python.
Although scripting languages are designed
to make programming life easier
by hiding machine internals from the programmer
there are several aspects of today's scripting languages
that are unfavourable in my opinion.
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>
Besides C, C++, Cluster (a Modula derivate for Amiga computers)
I evaluated several scripting like languages in the past:
Different dialects of BASIC,
Perl, ARexx (a variant of Rexx for Amiga computers),
shell scripts.
I found them too inconsistent,
too weak in distinguishing types,
too weak in encapsulating pieces of code.
Eventually I have started several projects in Python
because of the fine syntax.
But when projects became larger
I lost the track.
I got convinced that one can not have
maintainable code in a language
that is not statically typed.
In fact the main advantages of scripting languages
e.g. matching regular expressions,
complex built-in datatypes like lists, dictionaries,
are not advantages of the language itself
but can be provided by function libraries.
</p>
<H3><a name="whymodula3"></a>23.1.2 Why Modula-3 ?</H3>
<p>
Modula-3 is a compiler language
in the tradition of Niklaus Wirth's Modula 2,
which is in turn a successor of the popular Pascal.
I have chosen Modula-3
because of its
logical syntax,
strong modularization,
the type system which is very detailed
for machine types compared to other languages.
Of course it supports all of the modern games
like exceptions, objects, garbage collection, threads.
While C++ programmers must
control three languages,
namely the preprocessor, C and ++,
Modula-3 is made in one go
and the language definition is really compact.
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>
On the one hand Modula-3 can be safe
(but probably less efficient) in normal modules
while providing much static and dynamic safety.
On the other hand you can write efficient
but less safe code in the style of C
within <tt>UNSAFE</tt> modules.
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>
Unfortunately Modula's safety and strength
requires more writing than scripting languages do.
Today if I want to safe characters
I prefer Haskell (similar to OCAML) -
it's statically typed, too.
</p>
<H3><a name="whycpp"></a>23.1.3 Why C / C++ ?</H3>
<p>
Although it is no problem to write Modula-3 programs
that performs as fast as C
most libraries are not written in Modula-3 but in C.
Fortunately the binary interface of most function libraries
can be addressed by Modula-3.
Even more fortunately even non-C libraries may provide C header files.
This is where SWIG becomes helpful.
</p>
<H3><a name="whyswig"></a>23.1.4 Why SWIG ?</H3>
<p>
The C headers and the possibility to interface to C libraries
still leaves the work for you
to write Modula-3 interfaces to them.
To make things comfortable you will also need
wrappers that convert between high-level features of Modula-3
(garbage collecting, exceptions)
and the low level of the C libraries.
</p>
<p>
SWIG converts C headers to Modula-3 interfaces for you.
You could call the C functions without loss
of efficiency but it won't be joy
because you could not pass <tt>TEXT</tt>s
or open arrays and
you would have to process error return codes
rather then exceptions.
But using some typemaps SWIG will also generate
wrappers that bring the whole Modula-3 comfort to you.
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
@ -211,59 +117,32 @@ otherwise you lose static safety and consistency.
</p>
<p>
But you have still a problem:
C library interfaces are often ill.
They lack for certain information
because C compilers wouldn't care about.
You should integrate detailed type information
by adding <tt>typedef</tt>s and <tt>const</tt>s
and you should persuade the C library programmer
to add this information to his interface.
Only this way other language users can benefit from your work
and only this way you can easily update your interfaces
when a new library version is released.
You will realise that writing <b>good</b> SWIG interfaces
is very costly and it will only amortise
when considering evolving libraries.
</p>
<p>
Without SWIG you would probably never consider
to call C++ libraries from Modula-3.
But with SWIG this is worth a consideration.
SWIG can write C wrappers to C++ functions and object methods
that may throw exceptions.
In fact it breaks down C++ libraries to C interfaces
which can be in turn called from Modula-3.
To make it complete you can hide the C interface
with Modula-3 classes and exceptions.
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>
Although SWIG does the best it can do
it can only serve as a one-way strategy.
That means you can use C++ libraries
with Modula-3 (even with call back functions),
but it's certainly not possible to smoothly
integrate Modula-3 code into a C / C++ project.
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="conception"></a>23.2 Conception</H2>
<H2><a name="Modula3_conception"></a>27.2 Conception</H2>
<H3><a name="cinterface"></a>23.2.1 Interfaces to C libraries</H3>
<H3><a name="Modula3_cinterface"></a>27.2.1 Interfaces to C libraries</H3>
<p>
Modula-3 has an integrated support for calling C functions.
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>
modula3.swg
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.
@ -404,7 +283,7 @@ and the principal type must be renamed (<tt>%typemap</tt>).
</p>
<H3><a name="cppinterface"></a>23.2.2 Interfaces to C++ libraries</H3>
<H3><a name="Modula3_cppinterface"></a>27.2.2 Interfaces to C++ libraries</H3>
<p>
@ -417,7 +296,7 @@ with a C interface.
<p>
Here's a scheme of how the function calls to Modula-3 wrappers
a redirected to C library functions:
are redirected to C library functions:
</p>
<table summary="Modula-3 C++ library">
@ -477,13 +356,13 @@ 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#directors">Python</a>.
<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#ownership">
<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
@ -494,7 +373,7 @@ as far as I know.
<li>
How to turn C++ exceptions into Modula-3 exceptions?
There's also no support for
<a href="Customization.html#exception">
<a href="Customization.html#Customization_exception">
<tt>%exception</tt></a>, yet.
</li>
</ul>
@ -505,24 +384,23 @@ 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="preliminaries"></a>23.3 Preliminaries</H2>
<H2><a name="Modula3_preliminaries"></a>27.3 Preliminaries</H2>
<H3><a name="compilers"></a>23.3.1 Compilers</H3>
<H3><a name="Modula3_compilers"></a>27.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>
but the modula3.swg library file
may do so.
For testing examples I use Critical Mass cm3.
</p>
<H3><a name="commandline"></a>23.3.2 Additional Commandline Options</H3>
<H3><a name="Modula3_commandline"></a>27.3.2 Additional Commandline Options</H3>
<p>
@ -599,10 +477,10 @@ Instead generate templates for some basic typemaps.
</tr>
</table>
<H2><a name="modula3_typemaps"></a>23.4 Modula-3 typemaps</H2>
<H2><a name="Modula3_typemaps"></a>27.4 Modula-3 typemaps</H2>
<H3><a name="inoutparam"></a>23.4.1 Inputs and outputs</H3>
<H3><a name="Modula3_inoutparam"></a>27.4.1 Inputs and outputs</H3>
<p>
@ -620,9 +498,7 @@ 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 order to be able to write general typemaps for the modula3.swg typemap library.
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.
@ -818,7 +694,7 @@ consist of the following parts:
</table>
<H3><a name="ordinals"></a>23.4.2 Subranges, Enumerations, Sets</H3>
<H3><a name="Modula3_ordinals"></a>27.4.2 Subranges, Enumerations, Sets</H3>
<p>
@ -860,8 +736,8 @@ 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
<a href="../../Examples/modula3/enum/example.i">example</a>.
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.
@ -870,20 +746,20 @@ that I'd like to automate.
</p>
<H3><a name="class"></a>23.4.3 Objects</H3>
<H3><a name="Modula3_class"></a>27.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
<a href="../../Examples/modula3/class/example.i">implementation</a>
Though the example in
Examples/modula3/class/example.i
is not really useful, yet.
</p>
<H3><a name="imports"></a>23.4.4 Imports</H3>
<H3><a name="Modula3_imports"></a>27.4.4 Imports</H3>
<p>
@ -903,9 +779,7 @@ Unqualified import is not supported.
<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 the modula3.swg typemap library.
For a monolithic module you might be better off
if you add the imports directly:
</p>
@ -918,7 +792,7 @@ IMPORT M3toC;
</pre></div>
<H3><a name="exceptions"></a>23.4.5 Exceptions</H3>
<H3><a name="Modula3_exceptions"></a>27.4.5 Exceptions</H3>
<p>
@ -942,7 +816,7 @@ you should declare
<tt>%typemap("m3wrapinconv:throws") blah * %{OSError.E%}</tt>.
</p>
<H3><a name="typemap_example"></a>23.4.6 Example</H3>
<H3><a name="Modula3_typemap_example"></a>27.4.6 Example</H3>
<p>
@ -989,10 +863,10 @@ where almost everything is generated by a typemap:
</pre></div>
<H2><a name="hints"></a>23.5 More hints to the generator</H2>
<H2><a name="Modula3_hints"></a>27.5 More hints to the generator</H2>
<H3><a name="features"></a>23.5.1 Features</H3>
<H3><a name="Modula3_features"></a>27.5.1 Features</H3>
<table border summary="Modula-3 features">
@ -1022,14 +896,14 @@ where almost everything is generated by a typemap:
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="#options">option</a>.
<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="pragmas"></a>23.5.2 Pragmas</H3>
<H3><a name="Modula3_pragmas"></a>27.5.2 Pragmas</H3>
<table border summary="Modula-3 pragmas">
@ -1052,14 +926,14 @@ where almost everything is generated by a typemap:
</tr>
</table>
<H2><a name="remarks"></a>23.6 Remarks</H2>
<H2><a name="Modula3_remarks"></a>27.6 Remarks</H2>
<ul>
<li>
The Modula-3 part of SWIG doesn't try to generate nicely formatted code.
Use <tt>m3pp</tt> to postprocess the Modula files,
it does a very good job here.
If you need to read the generated code, use <tt>m3pp</tt> to postprocess the
Modula files.
</li>
</ul>

View file

@ -10,9 +10,10 @@
<!-- 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="#external_run_time">External access to the runtime</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>
@ -22,11 +23,49 @@
<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 into a module and use it. For large applications, however,
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.
@ -34,10 +73,11 @@ target language interface when it is broken up into smaller pieces.
<p>
This chapter describes the problem of using SWIG in programs
where you want to create a collection of modules.
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.1 Basics</H2>
<H2><a name="Modules_nn1"></a>15.2 Basics</H2>
<p>
@ -50,43 +90,93 @@ scripting language runtime as you would do for the single module case.
<p>
A bit more complex is the case in which modules need to share information.
For example, when one module extends the class of the another by deriving from
For example, when one module extends the class of another by deriving from
it:
</p>
<div class="code"><pre>
%module base
%inline %{
// File: base.h
class base {
public:
int foo(void);
int foo();
};
%}
</pre></div>
&nbsp;
<div class="code"><pre>
%module derived
%import "base.i"
<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(void);
int bar();
};
%}
</pre></div>
<p>To create the wrapper properly, module <tt>derived</tt> needs to know the
<tt>base</tt> class and that it's interface is covered in another module. The
line <tt>%import "base.i"</tt> lets SWIG know exactly that. The common mistake here is
to <tt>%import</tt> the <tt>.h</tt> file instead of the <tt>.i</tt>, which sadly won't do the trick. Another issue
to take care 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>
<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>
<H2><a name="Modules_nn2"></a>15.2 The SWIG runtime code</H2>
<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>
@ -152,10 +242,10 @@ can peacefully coexist. So the type structures are separated by the
is empty. Only modules compiled with the same pair will share type information.
</p>
<H2><a name="external_run_time"></a>15.3 External access to the runtime</H2>
<H2><a name="Modules_external_run_time"></a>15.4 External access to the runtime</H2>
<p>As described in <a href="Typemaps.html#runtime_type_checker">The run-time type checker</a>,
<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
@ -189,7 +279,7 @@ 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.4 A word of caution about static libraries</H2>
<H2><a name="Modules_nn4"></a>15.5 A word of caution about static libraries</H2>
<p>
@ -200,7 +290,7 @@ into it. This is very often <b>NOT</b> what you want and it can lead to unexpect
behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libraries.
</p>
<H2><a name="Modules_nn5"></a>15.5 References</H2>
<H2><a name="Modules_nn5"></a>15.6 References</H2>
<p>
@ -208,7 +298,7 @@ Due to the complexity of working with shared libraries and multiple modules, it
an outside reference. John Levine's "Linkers and Loaders" is highly recommended.
</p>
<H2><a name="Modules_nn6"></a>15.6 Reducing the wrapper file size</H2>
<H2><a name="Modules_nn6"></a>15.7 Reducing the wrapper file size</H2>
<p>

View file

@ -2,17 +2,19 @@
<!-- Hand-written HTML -->
<html>
<head>
<title>SWIG and MzScheme</title>
<title>SWIG and MzScheme/Racket</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#ffffff">
<H1><a name="MzScheme"></a>24 SWIG and MzScheme</H1>
<H1><a name="Mzscheme"></a>28 SWIG and MzScheme/Racket</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#MzScheme_nn2">Creating native MzScheme structures</a>
<li><a href="#MzScheme_nn2">Creating native structures</a>
<li><a href="#MzScheme_simple">Simple example</a>
<li><a href="#MzScheme_external_docs">External documentation</a>
</ul>
</div>
<!-- INDEX -->
@ -20,9 +22,9 @@
<p>
This section contains information on SWIG's support of MzScheme.
This section contains information on SWIG's support of Racket, formally known as MzScheme.
<H2><a name="MzScheme_nn2"></a>24.1 Creating native MzScheme structures</H2>
<H2><a name="MzScheme_nn2"></a>28.1 Creating native structures</H2>
<p>
@ -63,8 +65,116 @@ Then in scheme, you can use regular struct access procedures like
</pre>
</div>
<H2><a name="MzScheme_simple"></a>28.2 Simple example</H2>
<p>
That's pretty much it. It works with nested structs as well.
A few examples are available in the Examples/mzscheme directory.
The code and log of a session using SWIG below should help getting started.
</p>
<p>
C header file:
</p>
<div class="code">
<pre>
// example.h
int fact(int n);
</pre>
</div>
<p>
C source code:
</p>
<div class="code">
<pre>
// File: example.c
#include "example.h"
int fact(int n) {
if (n &lt; 0) { /* This should probably return an error, but this is simpler */
return 0;
}
if (n == 0) {
return 1;
}
else {
/* testing for overflow would be a good idea here */
return n * fact(n-1);
}
}
</pre>
</div>
<p>
SWIG interface file:
</p>
<div class="code">
<pre>
/* File: example.i */
%module example
%{
#include "example.h"
%}
int fact(int n);
</pre>
</div>
<p>
The session below using the above files is on an OS X machine, but the points to be made are more general. On OS X, libtool is the tool which creates libraries, which are named .dylib, rather than .so on other unixes, or .dll on Windows.
</p>
<div class="shell">
<pre>
% swig -mzscheme -declaremodule example.i
% gcc -c -m32 -o example.o example.c # force 32-bit object file (mzscheme is 32-bit only)
% libtool -dynamic -o libexample.dylib example.o # make it into a library
% ls # what've we got so far?
example.c example.o
example.h example_wrap.c
example.i libexample.dylib*
% mzc --cgc --cc example_wrap.c # compile the wrapping code
% LDFLAGS="-L. -lexample" mzc --ld example_wrap.dylib example_wrap.o # ...and link it
% mzscheme -e '(path-&gt;string (build-path "compiled" "native" (system-library-subpath)))'
"compiled/native/i386-macosx/3m"
% mkdir -p compiled/native/i386-macosx/3m # move the extension library to a magic place
% mv example_wrap.dylib compiled/native/i386-macosx/3m/example_ss.dylib
% mzscheme
Welcome to MzScheme v4.2.4 [3m], Copyright (c) 2004-2010 PLT Scheme Inc.
&gt; (require "example.ss")
&gt; (fact 5)
120
&gt; ^D
% echo 'It works!'
</pre>
</div>
<p>
Some points of interest:
</p>
<ul>
<li> This is on a 64-bit machine, so we have to include the -m32 option when building the object file
<li> If you want to declare a scheme module (and you probably do), it's important that you include the -declaremodule option to swig (if you miss this out, it'll appear to work, but fail later).
<li> Use mzc to compile and then link the wrapped code. You'll probably need to adjust the link flags to refer to the library you're wrapping (you can either do this with an LDFLAGS declaration, as here, or with multiple ++ldf options to mzc).
<li> Create the directory with path (build-path "compiled" "native" (system-library-subpath)) and move the freshly-generated .dylib to there, changing its name to module-name_ss.dylib. After that, you can REQUIRE the new module with (require "module-name.ss").
<li> The above requests mzc to create an extension using the CGC garbage-collector. The alternative -- the 3m collector -- has generally better performance, but work is still required for SWIG to emit code which is compatible with it.
</ul>
<H2><a name="MzScheme_external_docs"></a>28.3 External documentation</H2>
<p>
See the <a href="http://docs.racket-lang.org/inside/index.html">C API</a> for more description of using the mechanism for adding extensions. The main documentation is <a href="http://docs.racket-lang.org/">here</a>.
</p>
<p>
Tip: mzc's --vv option is very useful for debugging the inevitable library problems you'll encounter.
</p>
</body>

View file

@ -6,7 +6,7 @@
</head>
<body bgcolor="#ffffff">
<a name="n1"></a>
<H1><a name="Ocaml"></a>25 SWIG and Ocaml</H1>
<H1><a name="Ocaml"></a>29 SWIG and Ocaml</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
@ -80,7 +80,7 @@ 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>25.1 Preliminaries</H2>
<H2><a name="Ocaml_nn2"></a>29.1 Preliminaries</H2>
<p>
@ -93,13 +93,13 @@ examples and test-suite which come with SWIG. You can do this by running
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
href="http://download.camlcity.org/download/">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>25.1.1 Running SWIG</H3>
<H3><a name="Ocaml_nn3"></a>29.1.1 Running SWIG</H3>
<p>
@ -122,7 +122,7 @@ you will compile the file <tt>example_wrap.c</tt> with <tt>ocamlc</tt> or
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>25.1.2 Compiling the code</H3>
<H3><a name="Ocaml_nn4"></a>29.1.2 Compiling the code</H3>
<p>
@ -158,7 +158,7 @@ the user more freedom with respect to custom typing.
</pre>
</div>
<H3><a name="Ocaml_nn5"></a>25.1.3 The camlp4 module</H3>
<H3><a name="Ocaml_nn5"></a>29.1.3 The camlp4 module</H3>
<p>
@ -234,7 +234,7 @@ let b = C_string (getenv "PATH")
</td></tr>
</table>
<H3><a name="Ocaml_nn6"></a>25.1.4 Using your module</H3>
<H3><a name="Ocaml_nn6"></a>29.1.4 Using your module</H3>
<p>
@ -248,7 +248,7 @@ When linking any ocaml bytecode with your module, use the -custom
option is not needed when you build native code.
</p>
<H3><a name="Ocaml_nn7"></a>25.1.5 Compilation problems and compiling with C++</H3>
<H3><a name="Ocaml_nn7"></a>29.1.5 Compilation problems and compiling with C++</H3>
<p>
@ -259,7 +259,7 @@ 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>25.2 The low-level Ocaml/C interface</H2>
<H2><a name="Ocaml_nn8"></a>29.2 The low-level Ocaml/C interface</H2>
<p>
@ -360,7 +360,7 @@ is that you must append them to the return list with swig_result = caml_list_a
signature for a function that uses value in this way.
</p>
<H3><a name="Ocaml_nn9"></a>25.2.1 The generated module</H3>
<H3><a name="Ocaml_nn9"></a>29.2.1 The generated module</H3>
<p>
@ -394,7 +394,7 @@ it describes the output SWIG will generate for class definitions.
</td></tr>
</table>
<H3><a name="Ocaml_nn10"></a>25.2.2 Enums</H3>
<H3><a name="Ocaml_nn10"></a>29.2.2 Enums</H3>
<p>
@ -457,7 +457,7 @@ val x : Enum_test.c_obj = C_enum `a
</pre>
</div>
<H4><a name="Ocaml_nn11"></a>25.2.2.1 Enum typing in Ocaml</H4>
<H4><a name="Ocaml_nn11"></a>29.2.2.1 Enum typing in Ocaml</H4>
<p>
@ -470,10 +470,10 @@ 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>25.2.3 Arrays</H3>
<H3><a name="Ocaml_nn12"></a>29.2.3 Arrays</H3>
<H4><a name="Ocaml_nn13"></a>25.2.3.1 Simple types of bounded arrays</H4>
<H4><a name="Ocaml_nn13"></a>29.2.3.1 Simple types of bounded arrays</H4>
<p>
@ -494,7 +494,7 @@ 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>25.2.3.2 Complex and unbounded arrays</H4>
<H4><a name="Ocaml_nn14"></a>29.2.3.2 Complex and unbounded arrays</H4>
<p>
@ -507,7 +507,7 @@ 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>25.2.3.3 Using an object</H4>
<H4><a name="Ocaml_nn15"></a>29.2.3.3 Using an object</H4>
<p>
@ -521,7 +521,7 @@ 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>25.2.3.4 Example typemap for a function taking float * and int</H4>
<H4><a name="Ocaml_nn16"></a>29.2.3.4 Example typemap for a function taking float * and int</H4>
<p>
@ -572,7 +572,7 @@ void printfloats( float *tab, int len );
</pre></td></tr></table>
<H3><a name="Ocaml_nn17"></a>25.2.4 C++ Classes</H3>
<H3><a name="Ocaml_nn17"></a>29.2.4 C++ Classes</H3>
<p>
@ -615,7 +615,7 @@ the underlying pointer, so using create_[x]_from_ptr alters the
returned value for the same object.
</p>
<H4><a name="Ocaml_nn18"></a>25.2.4.1 STL vector and string Example</H4>
<H4><a name="Ocaml_nn18"></a>29.2.4.1 STL vector and string Example</H4>
<p>
@ -634,13 +634,13 @@ length. Instead, use multiple returns, as in the argout_ref example.
#include "example.h"
%}
%include stl.i
%include &lt;stl.i&gt;
namespace std {
%template(StringVector) std::vector &lt; string &gt;;
};
%include example.h
%include "example.h"
</pre></td></tr>
<tr><td><font size="-1"><i>This example is in Examples/ocaml/stl
</i></font></td></tr>
@ -695,7 +695,7 @@ baz
#
</pre></div>
<H4><a name="Ocaml_nn19"></a>25.2.4.2 C++ Class Example</H4>
<H4><a name="Ocaml_nn19"></a>29.2.4.2 C++ Class Example</H4>
<p>
@ -725,7 +725,7 @@ public:
};
</pre></td></tr></table>
<H4><a name="Ocaml_nn20"></a>25.2.4.3 Compiling the example</H4>
<H4><a name="Ocaml_nn20"></a>29.2.4.3 Compiling the example</H4>
<div class="code"><pre>
@ -743,7 +743,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
-L$QTPATH/lib -cclib -lqt
</pre></div>
<H4><a name="Ocaml_nn21"></a>25.2.4.4 Sample Session</H4>
<H4><a name="Ocaml_nn21"></a>29.2.4.4 Sample Session</H4>
<div class="code"><pre>
@ -770,10 +770,10 @@ 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>25.2.5 Director Classes</H3>
<H3><a name="Ocaml_nn22"></a>29.2.5 Director Classes</H3>
<H4><a name="Ocaml_nn23"></a>25.2.5.1 Director Introduction</H4>
<H4><a name="Ocaml_nn23"></a>29.2.5.1 Director Introduction</H4>
<p>
@ -800,7 +800,7 @@ class foo {
};
</pre></div>
<H4><a name="Ocaml_nn24"></a>25.2.5.2 Overriding Methods in Ocaml</H4>
<H4><a name="Ocaml_nn24"></a>29.2.5.2 Overriding Methods in Ocaml</H4>
<p>
@ -828,7 +828,7 @@ 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>25.2.5.3 Director Usage Example</H4>
<H4><a name="Ocaml_nn25"></a>29.2.5.3 Director Usage Example</H4>
<table border="1" bgcolor="#dddddd" summary="Director usage example">
@ -887,7 +887,7 @@ in a more effortless style in ocaml, while leaving the "engine" part of the
program in C++.
</p>
<H4><a name="Ocaml_nn26"></a>25.2.5.4 Creating director objects</H4>
<H4><a name="Ocaml_nn26"></a>29.2.5.4 Creating director objects</H4>
<p>
@ -928,7 +928,7 @@ object from causing a core dump, as long as the object is destroyed
properly.
</p>
<H4><a name="Ocaml_nn27"></a>25.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4>
<H4><a name="Ocaml_nn27"></a>29.2.5.5 Typemaps for directors, <tt>directorin, directorout, directorargout</tt></H4>
<p>
@ -939,7 +939,7 @@ 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>25.2.5.6 <tt>directorin</tt> typemap</H4>
<H4><a name="Ocaml_nn28"></a>29.2.5.6 <tt>directorin</tt> typemap</H4>
<p>
@ -950,7 +950,7 @@ code receives when you are called. In general, a simple <tt>directorin</tt> typ
can use the same body as a simple <tt>out</tt> typemap.
</p>
<H4><a name="Ocaml_nn29"></a>25.2.5.7 <tt>directorout</tt> typemap</H4>
<H4><a name="Ocaml_nn29"></a>29.2.5.7 <tt>directorout</tt> typemap</H4>
<p>
@ -961,7 +961,7 @@ for the same type, except when there are special requirements for object
ownership, etc.
</p>
<H4><a name="Ocaml_nn30"></a>25.2.5.8 <tt>directorargout</tt> typemap</H4>
<H4><a name="Ocaml_nn30"></a>29.2.5.8 <tt>directorargout</tt> typemap</H4>
<p>
@ -978,7 +978,7 @@ 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>25.2.6 Exceptions</H3>
<H3><a name="Ocaml_nn31"></a>29.2.6 Exceptions</H3>
<p>

View file

@ -8,13 +8,14 @@
<body bgcolor="#ffffff">
<H1><a name="Octave"></a>26 SWIG and Octave</H1>
<H1><a name="Octave"></a>30 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_nn4">Command-line options</a>
<li><a href="#Octave_nn5">Compiling a dynamic module</a>
<li><a href="#Octave_nn6">Using your module</a>
</ul>
@ -46,7 +47,7 @@
<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>.
More information can be found at <a href="http://www.gnu.org/software/octave/">Octave web site</a>.
</p>
<p>
@ -54,21 +55,26 @@ More information can be found at <a href="http://www.octave.org">www.octave.org<
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>26.1 Preliminaries</H2>
<H2><a name="Octave_nn2"></a>30.1 Preliminaries</H2>
<p>
The current SWIG implemention is based on Octave 2.9.12. Support for other versions (in particular the recent 3.0) has not been tested, nor has support for any OS other than Linux.
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>26.2 Running SWIG</H2>
<p>
As of SWIG 2.0.5, the Octave module should work with Octave versions 3.0.5, 3.2.4, and 3.4.0.
</p>
<H2><a name="Octave_nn3"></a>30.2 Running SWIG</H2>
<p>
Let's start with a very simple SWIG interface file:
Let's start with a very simple SWIG interface file, example.i:
</p>
<div class="code"><pre>%module example
<div class="code"><pre>
%module example
%{
#include "example.h"
%}
@ -76,20 +82,49 @@ int gcd(int x, int y);
extern double Foo; </pre></div>
<p>
To build an Octave module, run SWIG using the <tt>-octave</tt> option. The <tt>-c++</tt> option is required (for now) as Octave itself is written in C++ and thus the wrapper code must also be.
To build an Octave module when wrapping C code, run SWIG using the <tt>-octave</tt> option:
</p>
<div class="shell"><pre>$ swig -octave -c++ example.i </pre></div>
<div class="shell"><pre>$ swig -octave -o example_wrap.cpp example.i </pre></div>
<p>
This creates a C/C++ source file <tt>example_wrap.cxx</tt>. 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.
The <tt>-c++</tt> option is also required when wrapping C++ code:
</p>
<div class="shell"><pre>$ swig -octave -c++ -o example_wrap.cpp example.i </pre></div>
<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.
This creates a C++ source file <tt>example_wrap.cpp</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>
<H3><a name="Octave_nn5"></a>26.2.1 Compiling a dynamic module</H3>
<H3><a name="Octave_nn4"></a>30.2.1 Command-line options</H3>
<p>
The swig command line has a number of options you can use, like to redirect its output. Use <tt>swig -help</tt> to learn about these.
Options specific to the Octave module are:
</p>
<div class="shell">
<pre>$ swig -octave -help
...
Octave Options (available with -octave)
-global - Load all symbols into the global namespace [default]
-globals <em>name</em> - Set <em>name</em> used to access C global variables [default: 'cvar']
- Use '.' to load C global variables into module namespace
-noglobal - Do not load all symbols into the global namespace
-opprefix <em>str</em> - Prefix <em>str</em> for global operator functions [default: 'op_']
</pre></div>
<p>
The <em>-global</em> and <em>-noglobal</em> options determine whether the Octave module will load all symbols into the global namespace in addition to the global namespace.
The <em>-globals</em> option sets the name of the variable which is the namespace for C global variables exported by the module.
The special name "." loads C global variables into the module namespace, i.e. alongside C functions and structs exported by the module.
The <em>-opprefix</em> options sets the prefix of the names of global/friend <a href="#Octave_nn18">operator</a> functions.
</p>
<H3><a name="Octave_nn5"></a>30.2.2 Compiling a dynamic module</H3>
<p>
@ -98,8 +133,8 @@ Building an oct file is usually done with the mkoctfile command (either within O
</p>
<div class="shell"><pre>
$ swig -octave -c++ example.i -o example_wrap.cxx
$ mkoctfile example_wrap.cxx example.c
$ swig -octave -c++ -o example_wrap.cpp example.i
$ mkoctfile example_wrap.cpp example.c
</pre></div>
<p>
@ -116,7 +151,7 @@ $ mkoctfile example_wrap.cxx example.c
<div class="targetlang"><pre>octave:1&gt; example</pre></div>
<H3><a name="Octave_nn6"></a>26.2.2 Using your module</H3>
<H3><a name="Octave_nn6"></a>30.2.3 Using your module</H3>
<p>
@ -134,10 +169,10 @@ octave:4&gt; example.cvar.Foo=4;
octave:5&gt; example.cvar.Foo
ans = 4 </pre></div>
<H2><a name="Octave_nn7"></a>26.3 A tour of basic C/C++ wrapping</H2>
<H2><a name="Octave_nn7"></a>30.3 A tour of basic C/C++ wrapping</H2>
<H3><a name="Octave_nn8"></a>26.3.1 Modules</H3>
<H3><a name="Octave_nn8"></a>30.3.1 Modules</H3>
<p>
@ -149,37 +184,73 @@ When Octave is asked to invoke <tt>example</tt>, it will try to find the .m or .
</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:
An Octave module takes three options, <em>-global</em>, <em>-noglobal</em>, and <em>-globals</em>, which behave the same as the corresponding swig <a href="#Octave_nn4">command-line options</a>.
Here are some example usages:
</p>
<div class="targetlang"><pre>$ octave -q
octave:1&gt; example("global")
octave:2&gt; gcd(4,6)
<div class="targetlang"><pre>
octave:1&gt; example -help
usage: example [-global|-noglobal] [-globals &lt;name&gt;]
octave:2&gt; example -global
octave:3&gt; gcd(4,6)
ans = 2
octave:3&gt; cvar.Foo
octave:4&gt; cvar.Foo
ans = 3
octave:4&gt; cvar.Foo=4;
octave:5&gt; cvar.Foo
ans = 4
octave:5&gt; cvar.Foo=4;
octave:6&gt; cvar.Foo
ans = 4
</pre></div>
<br>
<div class="targetlang"><pre>
octave:1&gt; example -noglobal
octave:2&gt; gcd(6,9)
ans = 3
octave:3&gt; cvar.Foo
error: `cvar' undefined near line 3 column 1
octave:3&gt; example.cvar.Foo
ans = 3
</pre></div>
<br>
<div class="targetlang"><pre>
octave:1&gt; example -globals mycvar
octave:2&gt; cvar.Foo
error: `cvar' undefined near line 2 column 1
octave:2&gt; mycvar.Foo
ans = 3
</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;
It is also possible to rename the module / global variables namespaces 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;
ans = 2
octave:4&gt; some_vars = cvar;
octave:5&gt; some_vars.Foo
ans = 3
</pre></div>
<H3><a name="Octave_nn9"></a>26.3.2 Functions</H3>
<p>
Modules can also be loaded from within functions, even before being loaded in the base context.
If the module is also used in the base context, however, it must first be loaded again:
</p>
<div class="targetlang"><pre>
octave:1&gt; function l = my_lcm(a,b)
&gt; example
&gt; l = abs(a*b)/example.gcd(a,b);
&gt; endfunction
octave:2&gt; my_lcm(4,6)
ans = 12
octave:3&gt; example.gcd(4,6)
error: can't perform indexing operations for &lt;unknown type&gt; type
octave:3&gt; example;
octave:4&gt; example.gcd(4,6)
ans = 2
</pre></div>
<H3><a name="Octave_nn9"></a>30.3.2 Functions</H3>
<p>
@ -196,7 +267,7 @@ int fact(int n); </pre></div>
<div class="targetlang"><pre>octave:1&gt; example.fact(4)
24 </pre></div>
<H3><a name="Octave_nn10"></a>26.3.3 Global variables</H3>
<H3><a name="Octave_nn10"></a>30.3.3 Global variables</H3>
<p>
@ -231,7 +302,7 @@ extern double Foo;
</pre></div>
<p>
SWIG will allow the the reading of <tt>Foo</tt> but when a set attempt is made, an error function will be called.
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
@ -249,7 +320,7 @@ octave:2&gt; example.PI=3.142;
octave:3&gt; example.PI
ans = 3.1420 </pre></div>
<H3><a name="Octave_nn11"></a>26.3.4 Constants and enums</H3>
<H3><a name="Octave_nn11"></a>30.3.4 Constants and enums</H3>
<p>
@ -271,7 +342,7 @@ example.SCONST="Hello World"
example.SUNDAY=0
.... </pre></div>
<H3><a name="Octave_nn12"></a>26.3.5 Pointers</H3>
<H3><a name="Octave_nn12"></a>30.3.5 Pointers</H3>
<p>
@ -318,7 +389,7 @@ 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>26.3.6 Structures and C++ classes</H3>
<H3><a name="Octave_nn13"></a>30.3.6 Structures and C++ classes</H3>
<p>
@ -453,7 +524,7 @@ ans = 1
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>26.3.7 C++ inheritance</H3>
<H3><a name="Octave_nn15"></a>30.3.7 C++ inheritance</H3>
<p>
@ -462,7 +533,7 @@ This information contains the full class hierarchy. When an indexing operation (
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>26.3.8 C++ overloaded functions</H3>
<H3><a name="Octave_nn17"></a>30.3.8 C++ overloaded functions</H3>
<p>
@ -472,7 +543,7 @@ The dispatch function selects which overload to call (if any) based on the passe
<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>26.3.9 C++ operators</H3>
<H3><a name="Octave_nn18"></a>30.3.9 C++ operators</H3>
<p>
@ -572,7 +643,11 @@ On the C++ side, the default mappings are as follows:
%rename(__brace) *::operator[];
</pre></div>
<H3><a name="Octave_nn19"></a>26.3.10 Class extension with %extend</H3>
<p>
Octave can also utilise friend (i.e. non-member) operators with a simple %rename: see the example in the Examples/octave/operator directory.
</p>
<H3><a name="Octave_nn19"></a>30.3.10 Class extension with %extend</H3>
<p>
@ -602,7 +677,7 @@ octave:3&gt; printf("%s\n",a);
octave:4&gt; a.__str()
4
</pre></div>
<H3><a name="Octave_nn20"></a>26.3.11 C++ templates</H3>
<H3><a name="Octave_nn20"></a>30.3.11 C++ templates</H3>
<p>
@ -679,14 +754,14 @@ ans =
</pre></div>
<H3><a name="Octave_nn21"></a>26.3.12 C++ Smart Pointers</H3>
<H3><a name="Octave_nn21"></a>30.3.12 C++ Smart Pointers</H3>
<p>
C++ smart pointers are fully supported as in other modules.
</p>
<H3><a name="Octave_nn22"></a>26.3.13 Directors (calling Octave from C++ code)</H3>
<H3><a name="Octave_nn22"></a>30.3.13 Directors (calling Octave from C++ code)</H3>
<p>
@ -747,7 +822,8 @@ Note that you have to enable directors via the %feature directive (see other mod
<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())
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.
@ -766,14 +842,14 @@ c-side routine called
octave-side routine called
</pre></div>
<H3><a name="Octave_nn23"></a>26.3.14 Threads</H3>
<H3><a name="Octave_nn23"></a>30.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>26.3.15 Memory management</H3>
<H3><a name="Octave_nn24"></a>30.3.15 Memory management</H3>
<p>
@ -807,14 +883,14 @@ The %newobject directive may be used to control this behavior for pointers retur
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>26.3.16 STL support</H3>
<H3><a name="Octave_nn25"></a>30.3.16 STL support</H3>
<p>
This is some skeleton support for various STL containers.
Various STL library files are provided for wrapping STL containers.
</p>
<H3><a name="Octave_nn26"></a>26.3.17 Matrix typemaps</H3>
<H3><a name="Octave_nn26"></a>30.3.17 Matrix typemaps</H3>
<p>

View file

@ -6,7 +6,7 @@
</head>
<body bgcolor="#ffffff">
<H1><a name="Perl5"></a>27 SWIG and Perl5</H1>
<H1><a name="Perl5"></a>31 SWIG and Perl5</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
@ -40,7 +40,7 @@
<li><a href="#Perl5_nn24">Modules and packages</a>
</ul>
<li><a href="#Perl5_nn25">Input and output parameters</a>
<li><a href="#Perl5_nn26">Exception handling </a>
<li><a href="#Perl5_nn26">Exception handling</a>
<li><a href="#Perl5_nn27">Remapping datatypes with typemaps</a>
<ul>
<li><a href="#Perl5_nn28">A simple typemap example</a>
@ -50,8 +50,8 @@
</ul>
<li><a href="#Perl5_nn32">Typemap Examples</a>
<ul>
<li><a href="#Perl5_nn33">Converting a Perl5 array to a char ** </a>
<li><a href="#Perl5_nn34">Return values </a>
<li><a href="#Perl5_nn33">Converting a Perl5 array to a char **</a>
<li><a href="#Perl5_nn34">Return values</a>
<li><a href="#Perl5_nn35">Returning values from arguments</a>
<li><a href="#Perl5_nn36">Accessing array structure members</a>
<li><a href="#Perl5_nn37">Turning Perl references into C pointers</a>
@ -82,12 +82,12 @@
This chapter describes SWIG's support of Perl5. Although the Perl5
module is one of the earliest SWIG modules, it has continued to evolve
and has been improved greatly with the help of SWIG users. For the
best results, it is recommended that SWIG be used with Perl5.003 or
later. Earlier versions are problematic and SWIG generated extensions
may not compile or run correctly.
best results, it is recommended that SWIG be used with Perl 5.8 or
later. We're no longer testing regularly with older versions, but
Perl 5.6 seems to mostly work, while older versions don't.
</p>
<H2><a name="Perl5_nn2"></a>27.1 Overview</H2>
<H2><a name="Perl5_nn2"></a>31.1 Overview</H2>
<p>
@ -108,12 +108,12 @@ described. Advanced customization features, typemaps, and other
options are found near the end of the chapter.
</p>
<H2><a name="Perl5_nn3"></a>27.2 Preliminaries</H2>
<H2><a name="Perl5_nn3"></a>31.2 Preliminaries</H2>
<p>
To build a Perl5 module, run Swig using the <tt>-perl</tt> option as
follows :
To build a Perl5 module, run SWIG using the <tt>-perl</tt> option as
follows:
</p>
<div class="code"><pre>
@ -133,11 +133,11 @@ To build the module, you will need to compile the file
<tt>example_wrap.c</tt> and link it with the rest of your program.
</p>
<H3><a name="Perl5_nn4"></a>27.2.1 Getting the right header files</H3>
<H3><a name="Perl5_nn4"></a>31.2.1 Getting the right header files</H3>
<p>
In order to compile, SWIG extensions need the following Perl5 header files :</p>
In order to compile, SWIG extensions need the following Perl5 header files:</p>
<div class="code"><pre>
#include "Extern.h"
@ -149,23 +149,23 @@ In order to compile, SWIG extensions need the following Perl5 header files :</p>
These are typically located in a directory like this</p>
<div class="code"><pre>
/usr/lib/perl5/5.00503/i386-linux/CORE
/usr/lib/perl/5.14/CORE
</pre></div>
<p>
The SWIG configuration script automatically tries to locate this directory so
that it can compile examples. However, if you need to find out where the directory is
loaded, an easy way to find out is to run Perl itself.
located, an easy way to find out is to ask Perl itself:
</p>
<div class="code">
<pre>
% perl -e 'use Config; print $Config{archlib};'
/usr/lib/perl5/5.00503/i386-linux
$ perl -e 'use Config; print "$Config{archlib}\n";'
/usr/lib/perl/5.14
</pre>
</div>
<H3><a name="Perl5_nn5"></a>27.2.2 Compiling a dynamic module</H3>
<H3><a name="Perl5_nn5"></a>31.2.2 Compiling a dynamic module</H3>
<p>
@ -176,9 +176,9 @@ using commands like this (shown for Linux):
<div class="code"><pre>
$ swig -perl example.i
% gcc example.c
% gcc -c example_wrap.c -I/usr/lib/perl5/5.00503/i386-linux/CORE -Dbool=char
% gcc -shared example.o example_wrap.o -o example.so
$ gcc -fPIC example.c
$ gcc -fPIC -c example_wrap.c -I/usr/lib/perl/5.14/CORE -Dbool=char
$ gcc -shared example.o example_wrap.o -o example.so
</pre></div>
<p>
@ -198,13 +198,13 @@ the target should be named `<tt>example.so</tt>',
`<tt>example.sl</tt>', or the appropriate dynamic module name on your system.
</p>
<H3><a name="Perl5_nn6"></a>27.2.3 Building a dynamic module with MakeMaker</H3>
<H3><a name="Perl5_nn6"></a>31.2.3 Building a dynamic module with MakeMaker</H3>
<p>
It is also possible to use Perl to build dynamically loadable modules
for you using the MakeMaker utility. To do this, write a Perl
script such as the following :</p>
script such as the following:</p>
<div class="targetlang"><pre>
# File : Makefile.PL
@ -218,12 +218,12 @@ WriteMakefile(
</pre></div>
<p>
Now, to build a module, simply follow these steps :</p>
Now, to build a module, simply follow these steps:</p>
<div class="code"><pre>
% perl Makefile.PL
% make
% make install
$ perl Makefile.PL
$ make
$ make install
</pre></div>
<p>
@ -232,17 +232,17 @@ the preferred approach to compilation. More information about MakeMaker can be
found in "Programming Perl, 2nd ed." by Larry Wall, Tom Christiansen,
and Randal Schwartz.</p>
<H3><a name="Perl5_nn7"></a>27.2.4 Building a static version of Perl</H3>
<H3><a name="Perl5_nn7"></a>31.2.4 Building a static version of Perl</H3>
<p>
If you machine does not support dynamic loading or if you've tried to
use it without success, you can build a new version of the Perl
interpreter with your SWIG extensions added to it. To build a static
extension, you first need to invoke SWIG as follows :</p>
extension, you first need to invoke SWIG as follows:</p>
<div class="code"><pre>
% swig -perl -static example.i
$ swig -perl -static example.i
</pre></div>
<p>
@ -253,7 +253,7 @@ By default SWIG includes code for dynamic loading, but the
Next, you will need to supply a <tt>main()</tt> function that
initializes your extension and starts the Perl interpreter. While,
this may sound daunting, SWIG can do this for you automatically as
follows :</p>
follows:</p>
<div class="targetlang"><pre>
%module example
@ -264,14 +264,14 @@ extern int fact(int);
%}
// Include code for rebuilding Perl
%include perlmain.i
%include &lt;perlmain.i&gt;
</pre></div>
<p>
The same thing can be accomplished by running SWIG as follows :</p>
The same thing can be accomplished by running SWIG as follows:</p>
<div class="code"><pre>
% swig -perl -static -lperlmain.i example.i
$ swig -perl -static -lperlmain.i example.i
</pre></div>
<p>
@ -290,7 +290,7 @@ for a dynamic module, but change the link line to something like this:
</p>
<div class="code"><pre>
% gcc example.o example_wrap.o -L/usr/lib/perl5/5.00503/i386-linux/CORE \
$ gcc example.o example_wrap.o -L/usr/lib/perl/5.14/CORE \
-lperl -lsocket -lnsl -lm -o myperl
</pre></div>
@ -301,7 +301,7 @@ added to it. Depending on your machine, you may need to link with
additional libraries such as <tt>-lsocket, -lnsl, -ldl</tt>, etc.
</p>
<H3><a name="Perl5_nn8"></a>27.2.5 Using the module</H3>
<H3><a name="Perl5_nn8"></a>31.2.5 Using the module</H3>
<p>
@ -323,9 +323,7 @@ A common error received by first-time users is the following:
<div class="targetlang">
<pre>
use example;
Can't locate example.pm in @INC (@INC contains: /usr/lib/perl5/5.00503/i386-lin
ux /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/pe
rl5/site_perl/5.005 .) at - line 1.
Can't locate example.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl .) at - line 1.
BEGIN failed--compilation aborted at - line 1.
</pre>
</div>
@ -363,7 +361,7 @@ Another common error is the following:
<pre>
use example;
Can't load './example.so' for module example: ./example.so:
undefined symbol: Foo at /usr/lib/perl5/5.00503/i386-linux/DynaLoader.pm line 169.
undefined symbol: Foo at /usr/lib/perl/5.14/i386-linux/DynaLoader.pm line 169.
at - line 1
BEGIN failed--compilation aborted at - line 1.
@ -409,7 +407,7 @@ error when you try to use your module:
<pre>
use example;
Can't load './example.so' for module example: libfoo.so: cannot open shared object file:
No such file or directory at /usr/lib/perl5/5.00503/i386-linux/DynaLoader.pm line 169.
No such file or directory at /usr/lib/perl/5.14/i386-linux/DynaLoader.pm line 169.
at - line 1
BEGIN failed--compilation aborted at - line 1.
@ -456,7 +454,7 @@ system configuration (this requires root access and you will need to
read the man pages).
</p>
<H3><a name="Perl5_nn9"></a>27.2.6 Compilation problems and compiling with C++</H3>
<H3><a name="Perl5_nn9"></a>31.2.6 Compilation problems and compiling with C++</H3>
<p>
@ -472,10 +470,10 @@ compiler. For example:
</p>
<div class="code"><pre>
% swig -c++ -perl example.i
% g++ -c example.cxx
% g++ -c example_wrap.cxx -I/usr/lib/perl5/5.00503/i386-linux/CORE
% <b>g++ -shared example.o example_wrap.o -o example.so</b>
$ swig -c++ -perl example.i
$ g++ -fPIC -c example.cxx
$ g++ -fPIC -c example_wrap.cxx -I/usr/lib/perl/5.14/i386-linux/CORE
$ <b>g++ -shared example.o example_wrap.o -o example.so</b>
</pre></div>
<p>
@ -485,10 +483,10 @@ Solaris, you often need to add an extra library <tt>-lCrun</tt> like this:
</p>
<div class="code"><pre>
% swig -c++ -perl example.i
% g++ -c example.cxx
% g++ -c example_wrap.cxx -I/usr/lib/perl5/5.00503/i386-linux/CORE
% g++ -shared example.o example_wrap.o -o example.so <b>-lCrun</b>
$ swig -c++ -perl example.i
$ CC -c example.cxx
$ CC -c example_wrap.cxx -I/usr/lib/perl/5.14/i386-linux/CORE
$ CC -shared example.o example_wrap.o -o example.so <b>-lCrun</b>
</pre></div>
<p>
@ -503,7 +501,7 @@ it needs to be. So you should compile the wrapper like:
</p>
<div class="code"><pre>
% g++ -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE -D_GNU_SOURCE
$ g++ -fPIC -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE -D_GNU_SOURCE
</pre></div>
<p>
@ -511,7 +509,7 @@ it needs to be. So you should compile the wrapper like:
</p>
<div class="code"><pre>
% perl -e 'use Config; print $Config{ccflags};'
$ perl -e 'use Config; print "$Config{ccflags}\n";'
</pre></div>
<p>
@ -519,8 +517,8 @@ So you could also compile the wrapper like
</p>
<div class="code"><pre>
% g++ -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE \
`perl -e 'use Config; print $Config{ccflags}'`
$ g++ -fPIC -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE \
`perl -MConfig -e 'print $Config{ccflags}'`
</pre></div>
<p>
@ -568,8 +566,8 @@ can behave strangely when working with multiple modules.
<p>
It should be noted that you may get a lot of error messages
about the `<tt>bool</tt>' datatype when compiling a C++ Perl module. If
you experience this problem, you can try the following :</p>
about the '<tt>bool</tt>' datatype when compiling a C++ Perl module. If
you experience this problem, you can try the following:</p>
<ul>
<li>Use <tt>-DHAS_BOOL</tt> when compiling the SWIG wrapper code
@ -599,7 +597,7 @@ have to find the macro that conflicts and add an #undef into the .i file. Pleas
any conflicting macros you find to <a href="http://www.swig.org/mail.html">swig-user mailing list</a>.
</p>
<H3><a name="Perl5_nn10"></a>27.2.7 Compiling for 64-bit platforms</H3>
<H3><a name="Perl5_nn10"></a>31.2.7 Compiling for 64-bit platforms</H3>
<p>
@ -626,7 +624,7 @@ also introduce problems on platforms that support more than one
linking standard (e.g., -o32 and -n32 on Irix).
</p>
<H2><a name="Perl5_nn11"></a>27.3 Building Perl Extensions under Windows</H2>
<H2><a name="Perl5_nn11"></a>31.3 Building Perl Extensions under Windows</H2>
<p>
@ -637,13 +635,13 @@ section assumes you are using SWIG with Microsoft Visual C++
although the procedure may be similar with other compilers.
</p>
<H3><a name="Perl5_nn12"></a>27.3.1 Running SWIG from Developer Studio</H3>
<H3><a name="Perl5_nn12"></a>31.3.1 Running SWIG from Developer Studio</H3>
<p>
If you are developing your application within Microsoft developer
studio, SWIG can be invoked as a custom build option. The process
roughly requires these steps :</p>
roughly requires these steps:</p>
<ul>
<li>Open up a new workspace and use the AppWizard to select a DLL
@ -651,7 +649,7 @@ project.
<li>Add both the SWIG interface file (the .i file), any supporting C
files, and the name of the wrapper file that will be created by SWIG
(ie. <tt>example_wrap.c</tt>). Note : If using C++, choose a
(ie. <tt>example_wrap.c</tt>). Note: If using C++, choose a
different suffix for the wrapper file such as
<tt>example_wrap.cxx</tt>. Don't worry if the wrapper file doesn't
exist yet--Developer studio will keep a reference to it around.
@ -689,7 +687,7 @@ Now, assuming you made it this far, SWIG will be automatically invoked when
you build your project. Any changes made to the interface file will
result in SWIG being automatically invoked to produce a new version of
the wrapper file. To run your new Perl extension, simply run Perl and
use the use command as normal. For example :
use the use command as normal. For example:
</p>
<div class="targetlang"><pre>
@ -700,7 +698,7 @@ print "$a\n";
</pre></div>
<H3><a name="Perl5_nn13"></a>27.3.2 Using other compilers</H3>
<H3><a name="Perl5_nn13"></a>31.3.2 Using other compilers</H3>
<p>
@ -708,7 +706,7 @@ SWIG is known to work with Cygwin and may work with other compilers on Windows.
For general hints and suggestions refer to the <a href="Windows.html#Windows">Windows</a> chapter.
</p>
<H2><a name="Perl5_nn14"></a>27.4 The low-level interface</H2>
<H2><a name="Perl5_nn14"></a>31.4 The low-level interface</H2>
<p>
@ -718,7 +716,7 @@ can be used to control your application. However, it is also used to
construct more user-friendly proxy classes as described in the next section.
</p>
<H3><a name="Perl5_nn15"></a>27.4.1 Functions</H3>
<H3><a name="Perl5_nn15"></a>31.4.1 Functions</H3>
<p>
@ -741,7 +739,7 @@ use example;
$a = &amp;example::fact(2);
</pre></div>
<H3><a name="Perl5_nn16"></a>27.4.2 Global variables</H3>
<H3><a name="Perl5_nn16"></a>31.4.2 Global variables</H3>
<p>
@ -758,7 +756,7 @@ double Spam;
</pre></div>
<p>
is accessed as follows :</p>
is accessed as follows:</p>
<div class="targetlang"><pre>
use example;
@ -811,11 +809,11 @@ extern char *path; // Declared later in the input
</pre>
</div>
<H3><a name="Perl5_nn17"></a>27.4.3 Constants</H3>
<H3><a name="Perl5_nn17"></a>31.4.3 Constants</H3>
<p>
Constants are wrapped as read-only Perl variables. For example:
By default, constants are wrapped as read-only Perl variables. For example:
</p>
<div class="code">
@ -838,14 +836,27 @@ $example::FOO = 2; # Error
</pre>
</div>
<H3><a name="Perl5_nn18"></a>27.4.4 Pointers</H3>
<p>
Alternatively, if you use swig's <tt>-const</tt> option, constants are wrapped
such that the leading $ isn't required (by using a constant subroutine), which
usually gives a more natural Perl interface, for example:
</p>
<div class="targetlang">
<pre>
use example;
print example::FOO,"\n";
</pre>
</div>
<H3><a name="Perl5_nn18"></a>31.4.4 Pointers</H3>
<p>
SWIG represents pointers as blessed references. A blessed reference
is the same as a Perl reference except that it has additional
information attached to it indicating what kind of reference it
is. That is, if you have a C declaration like this :</p>
is. That is, if you have a C declaration like this:</p>
<div class="code"><pre>
Matrix *new_Matrix(int n, int m);
@ -867,7 +878,7 @@ generated.</p>
<p>
To check to see if a value is the NULL pointer, use the
<tt>defined()</tt> command :</p>
<tt>defined()</tt> command:</p>
<div class="targetlang"><pre>
if (defined($ptr)) {
@ -879,7 +890,7 @@ if (defined($ptr)) {
</pre></div>
<p>
To create a NULL pointer, you should pass the <tt>undef </tt>value to
To create a NULL pointer, you should pass the <tt>undef</tt> value to
a function.
</p>
@ -889,9 +900,9 @@ pointer that SWIG wrapper functions return. Suppose that <tt>$a</tt>
and <tt>$b</tt> are two references that point to the same C object.
In general, <tt>$a</tt> and <tt>$b</tt> will be different--since they
are different references. Thus, it is a mistake to check the equality
of <tt>$a </tt>and <tt>$b</tt> to check the equality of two C
of <tt>$a</tt> and <tt>$b</tt> to check the equality of two C
pointers. The correct method to check equality of C pointers is to
dereference them as follows :
dereference them as follows:
</p>
<div class="targetlang"><pre>
@ -947,7 +958,7 @@ as XS and <tt>xsubpp</tt>. Given the advancement of the SWIG typesystem and the
SWIG and XS, this is no longer supported.
</p>
<H3><a name="Perl5_nn19"></a>27.4.5 Structures</H3>
<H3><a name="Perl5_nn19"></a>31.4.5 Structures</H3>
<p>
@ -1081,12 +1092,12 @@ void Bar_f_set(Bar *b, Foo *val) {
</div>
<H3><a name="Perl5_nn20"></a>27.4.6 C++ classes</H3>
<H3><a name="Perl5_nn20"></a>31.4.6 C++ classes</H3>
<p>
C++ classes are wrapped by building a set of low level accessor functions.
Consider the following class :
Consider the following class:
</p>
<div class="code"><pre>
@ -1104,7 +1115,7 @@ static void print(List *l);
</pre></div>
<p>
When wrapped by SWIG, the following functions are created :
When wrapped by SWIG, the following functions are created:
</p>
<div class="code"><pre>
@ -1146,7 +1157,7 @@ provides direct access to C++ objects. A higher level interface using Perl prox
can be built using these low-level accessors. This is described shortly.
</p>
<H3><a name="Perl5_nn21"></a>27.4.7 C++ classes and type-checking</H3>
<H3><a name="Perl5_nn21"></a>31.4.7 C++ classes and type-checking</H3>
<p>
@ -1182,7 +1193,7 @@ If necessary, the type-checker also adjusts the value of the pointer (as is nece
multiple inheritance is used).
</p>
<H3><a name="Perl5_nn22"></a>27.4.8 C++ overloaded functions</H3>
<H3><a name="Perl5_nn22"></a>31.4.8 C++ overloaded functions</H3>
<p>
@ -1226,7 +1237,7 @@ example::Spam_foo_d($s,3.14);
Please refer to the "SWIG Basics" chapter for more information.
</p>
<H3><a name="Perl5_nn23"></a>27.4.9 Operators</H3>
<H3><a name="Perl5_nn23"></a>31.4.9 Operators</H3>
<p>
@ -1253,17 +1264,17 @@ The following C++ operators are currently supported by the Perl module:
<li>operator or </li>
</ul>
<H3><a name="Perl5_nn24"></a>27.4.10 Modules and packages</H3>
<H3><a name="Perl5_nn24"></a>31.4.10 Modules and packages</H3>
<p>
When you create a SWIG extension, everything gets placed into
a single Perl module. The name of the module is determined by the
<tt>%module</tt> directive. To use the module, do the following :
<tt>%module</tt> directive. To use the module, do the following:
</p>
<div class="targetlang"><pre>
% perl5
$ perl5
use example; # load the example module
print example::fact(4),"\n" # Call a function in it
24
@ -1329,17 +1340,17 @@ nested namespace simply provide the fully qualified name in your
<!--
<p>
This can be changed by giving SWIG the -package
option :
option:
</p>
<div class="code"><pre>
% swig -perl -package Foo example.i
$ swig -perl -package Foo example.i
</pre></div>
<p>
In this case, you still create a module called `<tt>example</tt>' exactly as before, but
all of the functions in that module will be installed into the package
`<tt>Foo</tt>.' For example :
`<tt>Foo</tt>.' For example:
</p>
<div class="targetlang"><pre>
@ -1348,7 +1359,7 @@ print Foo::fact(4),"\n"; # Call a function in package FooBar
</pre></div>
-->
<H2><a name="Perl5_nn25"></a>27.5 Input and output parameters</H2>
<H2><a name="Perl5_nn25"></a>31.5 Input and output parameters</H2>
<p>
@ -1543,7 +1554,7 @@ example:
<div class="code">
<pre>
%module example
%include typemaps.i
%include "typemaps.i"
void add(int x, int y, int *REFERENCE);
</pre>
@ -1567,7 +1578,7 @@ print "$c\n";
<b>Note:</b> The <tt>REFERENCE</tt> feature is only currently supported for numeric types (integers and floating point).
</p>
<H2><a name="Perl5_nn26"></a>27.6 Exception handling </H2>
<H2><a name="Perl5_nn26"></a>31.6 Exception handling</H2>
<p>
@ -1575,7 +1586,7 @@ The SWIG <tt>%exception</tt> directive can be used to create a
user-definable exception handler for converting exceptions in your
C/C++ program into Perl exceptions. The chapter on customization features
contains more details, but suppose you have a C++ class like the
following :
following:
</p>
<div class="code"><pre>
@ -1732,7 +1743,7 @@ This is still supported, but it is deprecated. The newer <tt>%exception</tt> di
functionality, but it has additional capabilities that make it more powerful.
</p>
<H2><a name="Perl5_nn27"></a>27.7 Remapping datatypes with typemaps</H2>
<H2><a name="Perl5_nn27"></a>31.7 Remapping datatypes with typemaps</H2>
<p>
@ -1749,7 +1760,7 @@ Typemaps are only used if you want to change some aspect of the primitive
C-Perl interface.
</p>
<H3><a name="Perl5_nn28"></a>27.7.1 A simple typemap example</H3>
<H3><a name="Perl5_nn28"></a>31.7.1 A simple typemap example</H3>
<p>
@ -1783,7 +1794,7 @@ The <tt>$input</tt> variable is the input object (usually a <tt>SV *</tt>).
</p>
<p>
When this example is used in Perl5, it will operate as follows :
When this example is used in Perl5, it will operate as follows:
</p>
<div class="targetlang"><pre>
@ -1792,7 +1803,7 @@ $n = example::fact(6);
print "$n\n";
...
Output :
Output:
Received an integer : 6
720
</pre></div>
@ -1853,7 +1864,7 @@ example::count("e","Hello World");
</div>
<H3><a name="Perl5_nn29"></a>27.7.2 Perl5 typemaps</H3>
<H3><a name="Perl5_nn29"></a>31.7.2 Perl5 typemaps</H3>
<p>
@ -1958,7 +1969,7 @@ Return of C++ member data (all languages).
Check value of input parameter.
</div>
<H3><a name="Perl5_nn30"></a>27.7.3 Typemap variables</H3>
<H3><a name="Perl5_nn30"></a>31.7.3 Typemap variables</H3>
<p>
@ -2029,7 +2040,7 @@ properly assigned.
The Perl name of the wrapper function being created.
</div>
<H3><a name="Perl5_nn31"></a>27.7.4 Useful functions</H3>
<H3><a name="Perl5_nn31"></a>31.7.4 Useful functions</H3>
<p>
@ -2098,7 +2109,7 @@ int sv_isa(SV *, char *0;
</div>
<H2><a name="Perl5_nn32"></a>27.8 Typemap Examples</H2>
<H2><a name="Perl5_nn32"></a>31.8 Typemap Examples</H2>
<p>
@ -2107,7 +2118,7 @@ might look at the files "<tt>perl5.swg</tt>" and "<tt>typemaps.i</tt>" in
the SWIG library.
</p>
<H3><a name="Perl5_nn33"></a>27.8.1 Converting a Perl5 array to a char ** </H3>
<H3><a name="Perl5_nn33"></a>31.8.1 Converting a Perl5 array to a char **</H3>
<p>
@ -2160,7 +2171,7 @@ reference to be used as a char ** datatype.
};
myav = av_make(len,svs);
free(svs);
$result = newRV((SV*)myav);
$result = newRV_noinc((SV*)myav);
sv_2mortal($result);
argvi++;
}
@ -2187,7 +2198,7 @@ char **get_args() {
<p>
When this module is compiled, the wrapped C functions can be used in a
Perl script as follows :
Perl script as follows:
</p>
<div class="targetlang"><pre>
@ -2199,7 +2210,7 @@ print @$b,"\n"; # Print it out
</pre></div>
<H3><a name="Perl5_nn34"></a>27.8.2 Return values </H3>
<H3><a name="Perl5_nn34"></a>31.8.2 Return values</H3>
<p>
@ -2214,7 +2225,7 @@ number of output values.
<p>
The total number of return values should not exceed the number of
input values unless you explicitly extend the argument stack. This
can be done using the <tt>EXTEND()</tt> macro as in :
can be done using the <tt>EXTEND()</tt> macro as in:
</p>
<div class="code"><pre>
@ -2228,7 +2239,7 @@ can be done using the <tt>EXTEND()</tt> macro as in :
}
</pre></div>
<H3><a name="Perl5_nn35"></a>27.8.3 Returning values from arguments</H3>
<H3><a name="Perl5_nn35"></a>31.8.3 Returning values from arguments</H3>
<p>
@ -2273,7 +2284,7 @@ int multout(double a, double b, double *OUTPUT, double *OUTPUT);
<p>
When this function is called, the output arguments are appended to the stack used
to return results. This shows up an array in Perl.
For example :
For example:
</p>
<div class="targetlang"><pre>
@ -2282,11 +2293,11 @@ print "multout(7,13) = @r\n";
($x,$y) = multout(7,13);
</pre></div>
<H3><a name="Perl5_nn36"></a>27.8.4 Accessing array structure members</H3>
<H3><a name="Perl5_nn36"></a>31.8.4 Accessing array structure members</H3>
<p>
Consider the following data structure :
Consider the following data structure:
</p>
<div class="code"><pre>
@ -2345,13 +2356,13 @@ the "in" typemap in the previous section would be used to convert an
to copy the converted array into a C data structure.
</p>
<H3><a name="Perl5_nn37"></a>27.8.5 Turning Perl references into C pointers</H3>
<H3><a name="Perl5_nn37"></a>31.8.5 Turning Perl references into C pointers</H3>
<p>
A frequent confusion on the SWIG mailing list is errors caused by the
mixing of Perl references and C pointers. For example, suppose you
have a C function that modifies its arguments like this :
have a C function that modifies its arguments like this:
</p>
<div class="code"><pre>
@ -2361,7 +2372,7 @@ void add(double a, double b, double *c) {
</pre></div>
<p>
A common misinterpretation of this function is the following Perl script :
A common misinterpretation of this function is the following Perl script:
</p>
<div class="targetlang"><pre>
@ -2398,7 +2409,7 @@ To make this work with a reference, you can use a typemap such as this:
</pre></div>
<p>
Now, if you place this before the add function, you can do this :
Now, if you place this before the add function, you can do this:
</p>
<div class="targetlang"><pre>
@ -2410,7 +2421,7 @@ print "$c\n";
</pre></div>
<H3><a name="Perl5_nn38"></a>27.8.6 Pointer handling</H3>
<H3><a name="Perl5_nn38"></a>31.8.6 Pointer handling</H3>
<p>
@ -2489,7 +2500,7 @@ For example:
</pre>
</div>
<H2><a name="Perl5_nn39"></a>27.9 Proxy classes</H2>
<H2><a name="Perl5_nn39"></a>31.9 Proxy classes</H2>
<p>
@ -2505,7 +2516,7 @@ to the underlying code. This section describes the implementation
details of the proxy interface.
</p>
<H3><a name="Perl5_nn40"></a>27.9.1 Preliminaries</H3>
<H3><a name="Perl5_nn40"></a>31.9.1 Preliminaries</H3>
<p>
@ -2527,11 +2538,11 @@ SWIG creates a collection of high-level Perl wrappers. In your scripts, you wil
high level wrappers. The wrappers, in turn, interact with the low-level procedural module.
</p>
<H3><a name="Perl5_nn41"></a>27.9.2 Structure and class wrappers</H3>
<H3><a name="Perl5_nn41"></a>31.9.2 Structure and class wrappers</H3>
<p>
Suppose you have the following SWIG interface file :
Suppose you have the following SWIG interface file:
</p>
<div class="code"><pre>
@ -2653,13 +2664,13 @@ $v-&gt;DESTROY();
</pre></div>
<H3><a name="Perl5_nn42"></a>27.9.3 Object Ownership</H3>
<H3><a name="Perl5_nn42"></a>31.9.3 Object Ownership</H3>
<p>
In order for proxy classes to work properly, it is necessary for Perl
to manage some mechanism of object ownership. Here's the crux of the
problem---suppose you had a function like this :
problem---suppose you had a function like this:
</p>
<div class="code"><pre>
@ -2672,7 +2683,7 @@ Vector *Vector_get(Vector *v, int index) {
This function takes a Vector pointer and returns a pointer to another
Vector. Such a function might be used to manage arrays or lists of
vectors (in C). Now contrast this function with the constructor for a
Vector object :
Vector object:
</p>
<div class="code"><pre>
@ -2714,7 +2725,7 @@ corresponding Perl object (this situation turns out to come up
frequently when constructing objects like linked lists and trees).
When C takes possession of an object, you can change Perl's ownership
by simply deleting the object from the <tt>%OWNER</tt> hash. This is
done using the <tt>DISOWN </tt>method.
done using the <tt>DISOWN</tt> method.
</p>
<div class="targetlang"><pre>
@ -2740,11 +2751,11 @@ counting, garbage collection, or advanced features one might find in
sophisticated languages.
</p>
<H3><a name="Perl5_nn43"></a>27.9.4 Nested Objects</H3>
<H3><a name="Perl5_nn43"></a>31.9.4 Nested Objects</H3>
<p>
Suppose that we have a new object that looks like this :
Suppose that we have a new object that looks like this:
</p>
<div class="code"><pre>
@ -2761,7 +2772,7 @@ struct Particle {
In this case, the members of the structure are complex objects that
have already been encapsulated in a Perl proxy class. To handle
these correctly, we use the <tt>%BLESSEDMEMBERS</tt> hash which would
look like this (along with some supporting code) :
look like this (along with some supporting code):
</p>
<div class="targetlang"><pre>
@ -2783,7 +2794,7 @@ unmodified.
</p>
<p>
This implementation allows us to operate on nested structures as follows :
This implementation allows us to operate on nested structures as follows:
</p>
<div class="targetlang"><pre>
@ -2793,12 +2804,12 @@ $p-&gt;{f}-&gt;{x} = 0.0;
%${$p-&gt;{v}} = ( x=&gt;0, y=&gt;0, z=&gt;0);
</pre></div>
<H3><a name="Perl5_nn44"></a>27.9.5 Proxy Functions</H3>
<H3><a name="Perl5_nn44"></a>31.9.5 Proxy Functions</H3>
<p>
When functions take arguments involving a complex object, it is
sometimes necessary to write a proxy function. For example :
sometimes necessary to write a proxy function. For example:
</p>
<div class="code"><pre>
@ -2809,7 +2820,7 @@ double dot_product(Vector *v1, Vector *v2);
Since Vector is an object already wrapped into a proxy class, we need
to modify this function to accept arguments that are given in the form
of tied hash tables. This is done by creating a Perl function like
this :
this:
</p>
<div class="targetlang"><pre>
@ -2827,13 +2838,13 @@ This function replaces the original function, but operates in an
identical manner.
</p>
<H3><a name="Perl5_nn45"></a>27.9.6 Inheritance</H3>
<H3><a name="Perl5_nn45"></a>31.9.6 Inheritance</H3>
<p>
Simple C++ inheritance is handled using the Perl <tt>@ISA</tt> array
in each class package. For example, if you have the following
interface file :
interface file:
</p>
<div class="code"><pre>
@ -2868,7 +2879,7 @@ public:
</pre></div>
<p>
The resulting, Perl wrapper class will create the following code :
The resulting, Perl wrapper class will create the following code:
</p>
<div class="targetlang"><pre>
@ -2903,12 +2914,12 @@ particular, inheritance of data members is extremely tricky (and I'm
not even sure if it really works).
</p>
<H3><a name="Perl5_nn46"></a>27.9.7 Modifying the proxy methods</H3>
<H3><a name="Perl5_nn46"></a>31.9.7 Modifying the proxy methods</H3>
<p>
It is possible to override the SWIG generated proxy/shadow methods, using <tt>%feature("shadow")</tt>.
It works like all the other <a href="Customization.html#features">%feature directives</a>.
It works like all the other <a href="Customization.html#Customization_features">%feature directives</a>.
Here is a simple example showing how to add some Perl debug code to the constructor:
</p>
@ -2931,7 +2942,7 @@ public:
};
</pre></div>
<H2><a name="Perl5_nn47"></a>27.10 Adding additional Perl code</H2>
<H2><a name="Perl5_nn47"></a>31.10 Adding additional Perl code</H2>
<p>

View file

@ -7,14 +7,13 @@
</head>
<body bgcolor="#ffffff">
<H1><a name="Php"></a>28 SWIG and PHP</H1>
<H1><a name="Php"></a>32 SWIG and PHP</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Php_nn1">Generating PHP Extensions</a>
<ul>
<li><a href="#Php_nn1_1">Building a loadable extension</a>
<li><a href="#Php_nn1_2">Building extensions into PHP</a>
<li><a href="#Php_nn1_3">Using PHP Extensions</a>
</ul>
<li><a href="#Php_nn2">Basic PHP interface</a>
@ -33,6 +32,16 @@
</ul>
<li><a href="#Php_nn2_7">PHP Pragmas, Startup and Shutdown code</a>
</ul>
<li><a href="#Php_nn3">Cross language polymorphism</a>
<ul>
<li><a href="#Php_nn3_1">Enabling directors</a>
<li><a href="#Php_nn3_2">Director classes</a>
<li><a href="#Php_nn3_3">Ownership and object destruction</a>
<li><a href="#Php_nn3_4">Exception unrolling</a>
<li><a href="#Php_nn3_5">Overhead and code bloat</a>
<li><a href="#Php_nn3_6">Typemaps</a>
<li><a href="#Php_nn3_7">Miscellaneous</a>
</ul>
</ul>
</div>
<!-- INDEX -->
@ -40,23 +49,23 @@
<p>
<b>Caution: This chapter (and module!) is still under construction</b>
SWIG supports generating wrappers for PHP5. Support for PHP4 was removed
in SWIG 1.3.37. The PHP developers are no longer making new PHP4 releases,
and won't even be patching critical security issues after 2008-08-08, so it
doesn't make much sense for SWIG to continue to support PHP4 now. If you
really need to continue to use PHP4, just stick with SWIG 1.3.36.
</p>
<p>
SWIG supports generating wrappers for PHP5. Support for PHP4 has been removed
as of SWIG 1.3.37. The PHP developers are no longer making new PHP4 releases,
and won't even be patching critical security issues after 2008-08-08, so it
doesn't make much sense for SWIG to continue to support PHP4 at this point.
If you need to continue to use PHP4, stick with SWIG 1.3.36.
Currently any PHP5 release should work, but we don't regularly test with
PHP &lt; 5.3.
</p>
<p>
In this chapter, we discuss SWIG's support of PHP. The PHP module
was extensively rewritten in release 1.3.26, and support for generating
OO wrappers for PHP5 was added in 1.3.30. The PHP module works fairly
well, but currently does not implement all the
features available in some of the other languages.
OO wrappers for PHP5 was added in 1.3.30. The PHP module now supports most
of the features available in some of the other languages.
</p>
<p>
@ -70,7 +79,7 @@ your extension into php directly, you will need the complete PHP source tree
available.
</p>
<H2><a name="Php_nn1"></a>28.1 Generating PHP Extensions</H2>
<H2><a name="Php_nn1"></a>32.1 Generating PHP Extensions</H2>
<p>
@ -96,7 +105,7 @@ also contain PHP5 class wrappers.
</p>
<p>
Swig can generate PHP extensions from C++ libraries as well when
SWIG can generate PHP extensions from C++ libraries as well when
given the <tt>-c++</tt> option. The support for C++ is discussed in
more detail in <a href="#Php_nn2_6">section 27.2.6</a>.
</p>
@ -117,7 +126,8 @@ and it doesn't play nicely with package system. We don't recommend
this approach, or provide explicit support for it.
</p>
<H3><a name="Php_nn1_1"></a>28.1.1 Building a loadable extension</H3>
<H3><a name="Php_nn1_1"></a>32.1.1 Building a loadable extension</H3>
<p>
To build your module as a dynamically loadable extension, use compilation
@ -131,7 +141,8 @@ least work for Linux though):
gcc -shared example_wrap.o -o example.so
</pre></div>
<H3><a name="Php_nn1_3"></a>28.1.3 Using PHP Extensions</H3>
<H3><a name="Php_nn1_3"></a>32.1.2 Using PHP Extensions</H3>
<p>
To test the extension from a PHP script, you need to load it first. You
@ -161,21 +172,22 @@ attempts to do the <tt>dl()</tt> call for you:
include("example.php");
</pre></div>
<H2><a name="Php_nn2"></a>28.2 Basic PHP interface</H2>
<H2><a name="Php_nn2"></a>32.2 Basic PHP interface</H2>
<p>
It is important to understand that PHP uses a single global namespace
into which all symbols from extension modules are loaded. It is quite
possible for names of symbols in one extension module to clash with
other symbols unless care is taken to <tt>%rename</tt> them.
other symbols unless care is taken to <tt>%rename</tt> them. At present
SWIG doesn't have support for the namespace feature added in PHP 5.3.
</p>
<H3><a name="Php_nn2_1"></a>28.2.1 Constants</H3>
<H3><a name="Php_nn2_1"></a>32.2.1 Constants</H3>
<p>
These work in much the same way as in C/C++, constants can be defined
These work in much the same way as in C/C++. Constants can be defined
by using either the normal C pre-processor declarations, or the
<tt>%constant</tt> SWIG directive. These will then be available from
your PHP script as a PHP constant, (i.e. no dollar sign is needed to
@ -192,7 +204,7 @@ access them.) For example, with a swig interface file like this,
</div>
<p>
you can access the constants in your php script like this,
you can access the constants in your PHP script like this,
</p>
<div class="code"><pre>
@ -206,9 +218,16 @@ echo "E = " . E . "\n";
</div>
<p>
There are two peculiarities with using constants in PHP. The first is that
if you try to use an undeclared constant, it will evaluate to a string
set to the constant's name. For example,
There's one peculiarity of how constants work in PHP which it is useful
to note (this is not specific to SWIG though) - if you try to use an undeclared
constant, PHP will issue a warning and then expand the constant to a string
version of the constant's name. The warning will often be missed though as
if you're using PHP in a webserver, it will probably end up in error.log or
similar.
</p>
<p>
For example,
</p>
<div class="code"><pre>
@ -236,67 +255,12 @@ if(EASY_TO_MISPEL) {
</div>
<p>
will issue a warning about the undeclared constant, but will then
evaluate it and turn it into a string ('EASY_TO_MISPEL'), which
evaluates to true, rather than the value of the constant which would
be false. This is a feature!
The mis-spelled constant will become the string 'EASY_TO_MISPEL', which
is treated as true by the if test, when the value of the intended constant
would be treated as false!
</p>
<p>
The second 'feature' is that although constants are case sensitive (by
default), you cannot declare a constant twice with alternative
cases. E.g.,
</p>
<div class="code">
<pre>
%module example
#define TEST Hello
#define Test World
</pre>
</div>
<p>
accessed from PHP,
</p>
<div class="code">
<pre>
include("example.php");
echo TEST, Test;
</pre>
</div>
<p>
will output "Hello Test" rather than "Hello World". This is because
internally, all constants are stored in a hash table by their lower
case name, so 'TEST' and 'Test' will map to the same hash element
('Test'). But, because we declared them case sensitive, the Zend
engine will test if the case matches with the case the constant was
declared with first.
</p>
<p>
So, in the example above, the TEST constant was declared first, and
will be stored under the hash element 'test'. The 'Test' constant will
also map to the same hash element 'test', but will not overwrite
it. When called from the script, the TEST constant will again be
mapped to the hash element 'test' so the constant will be
retrieved. The case will then be checked, and will match up, so the
value ('Hello') will be returned. When 'Test' is evaluated, it will
also map to the same hash element 'test'. The same constant will be
retrieved, this time though the case check will fail as 'Test' !=
'TEST'. So PHP will assume that Test is a undeclared constant, and as
explained above, will return it as a string set to the constant name
('Test'). Hence the script above will print 'Hello Test'. If they were
declared non-case sensitive, the output would be 'Hello Hello', as
both point to the same value, without the case test taking place. (
Apologies, this paragraph needs rewriting to make some sense. )
</p>
<H3><a name="Php_nn2_2"></a>28.2.2 Global Variables</H3>
<H3><a name="Php_nn2_2"></a>32.2.2 Global Variables</H3>
<p>
@ -345,7 +309,7 @@ undefined.
At this time SWIG does not support custom accessor methods.
</p>
<H3><a name="Php_nn2_3"></a>28.2.3 Functions</H3>
<H3><a name="Php_nn2_3"></a>32.2.3 Functions</H3>
<p>
@ -398,7 +362,7 @@ print $s; # The value of $s was not changed.
-->
<H3><a name="Php_nn2_4"></a>28.2.4 Overloading</H3>
<H3><a name="Php_nn2_4"></a>32.2.4 Overloading</H3>
<p>
@ -406,13 +370,13 @@ Although PHP does not support overloading functions natively, swig
will generate dispatch functions which will use <tt>%typecheck</tt>
typemaps to allow overloading. This dispatch function's operation and
precedence is described in <a
href="TypemapsSWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping
href="SWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping
Overloaded Functions and Methods</a>.
</p>
<!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality
<p>
Because PHP4 is a dynamically typed language, simple values can be
Because PHP is a dynamically typed language, simple values can be
silently converted from one type to another. For example, integers,
doubles and strings silently convert to each other depending on
context. This situation make overloading slightly problematic because
@ -432,7 +396,7 @@ PHP. The string <tt>"2"</tt> simultaneously represents the integer
<p>
In order to provide the most natural experience to PHP programmers,
the default <tt>%typecheck</tt> implemented in <tt>php4.swg</tt>
the default <tt>%typecheck</tt> implemented in <tt>php.swg</tt>
allows any simple type (integer, double, string) in PHP to be used for
any simple C type (int, double, char *). The function selected then
depends only on the argument type precedence defined by SWIG.
@ -454,7 +418,7 @@ taking the integer argument.
</p>
-->
<H3><a name="Php_nn2_5"></a>28.2.5 Pointers and References</H3>
<H3><a name="Php_nn2_5"></a>32.2.5 Pointers and References</H3>
<p>
@ -478,7 +442,7 @@ One can include <b>cpointer.i</b> to generate PHP wrappers to <tt>int
<div class="code"><pre>
%module example
%include cpointer.i
%include "cpointer.i"
%pointer_functions(int,intp)
void add( int *in1, int *in2, int *result);
@ -512,7 +476,7 @@ parameter names as appropriate.
<div class="code"><pre>
%module example
%include typemaps.i
%include "typemaps.i"
void add( int *INPUT, int *INPUT, int *OUTPUT);
@ -544,7 +508,7 @@ named typemap REFERENCE.
<div class="code"><pre>
%module example
%include phppointers.i
%include "phppointers.i"
void add( int *REF, int *REF, int *REF);
@ -586,13 +550,15 @@ PHP in a number of ways: by using <tt>unset</tt> on an existing
variable, or assigning <tt>NULL</tt> to a variable.
</p>
<H3><a name="Php_nn2_6"></a>28.2.6 Structures and C++ classes</H3>
<H3><a name="Php_nn2_6"></a>32.2.6 Structures and C++ classes</H3>
<p>
SWIG defaults to wrapping C++ structs and classes with PHP classes
unless "-noproxy" is specified. For PHP5, a PHP wrapper
class is generated which calls a set of flat functions wrapping the C++ class.
SWIG defaults to wrapping C++ structs and classes with PHP classes - this
is done by generating a PHP wrapper script which defines proxy classes
which calls a set of flat functions which actually wrap the C++ class.
You can disable this wrapper layer by passing the command-line option
"-noproxy" in which case you'll just get the flat functions.
</p>
<p>
@ -645,7 +611,7 @@ Would be used in the following way from PHP5:
Member variables and methods are accessed using the <tt>-&gt;</tt> operator.
</p>
<H4><a name="Php_nn2_6_1"></a>28.2.6.1 Using <tt>-noproxy</tt></H4>
<H4><a name="Php_nn2_6_1"></a>32.2.6.1 Using <tt>-noproxy</tt></H4>
<p>
@ -671,7 +637,7 @@ Complex_im_set($obj,$d);
Complex_im_get($obj);
</pre></div>
<H4><a name="Php_nn2_6_2"></a>28.2.6.2 Constructors and Destructors</H4>
<H4><a name="Php_nn2_6_2"></a>32.2.6.2 Constructors and Destructors</H4>
<p>
@ -712,7 +678,7 @@ the programmer can either reassign the variable or call
<tt>unset($v)</tt>
</p>
<H4><a name="Php_nn2_6_3"></a>28.2.6.3 Static Member Variables</H4>
<H4><a name="Php_nn2_6_3"></a>32.2.6.3 Static Member Variables</H4>
<p>
@ -755,7 +721,7 @@ Ko::threats(10);
echo "There has now been " . Ko::threats() . " threats\n";
</pre></div>
<H4><a name="Php_nn2_6_4"></a>28.2.6.4 Static Member Functions</H4>
<H4><a name="Php_nn2_6_4"></a>32.2.6.4 Static Member Functions</H4>
<p>
@ -777,15 +743,9 @@ Ko::threats();
</pre></div>
<H3><a name="Php_nn2_7"></a>28.2.7 PHP Pragmas, Startup and Shutdown code</H3>
<H3><a name="Php_nn2_7"></a>32.2.7 PHP Pragmas, Startup and Shutdown code</H3>
<p>
Note: Currently pragmas for PHP need to be specified using
<tt>%pragma(php4)</tt> but also apply for PHP5! This is just a historical
oddity because SWIG's PHP support predates PHP5.
</p>
<p>
To place PHP code in the generated "example.php" file one can use the
<b>code</b> pragma. The code is inserted after loading the shared
@ -794,7 +754,7 @@ object.
<div class="code"><pre>
%module example
%pragma(php4) code="
%pragma(php) code="
# This code is inserted into example.php
echo \"example.php execution\\n\";
"
@ -816,7 +776,7 @@ the example.php file.
<div class="code"><pre>
%module example
%pragma(php4) code="
%pragma(php) code="
include \"include.php\";
"
%pragma(php) include="include.php" // equivalent.
@ -830,7 +790,7 @@ phpinfo() function.
<div class="code"><pre>
%module example;
%pragma(php4) phpinfo="
%pragma(php) phpinfo="
zend_printf("An example of PHP support through SWIG\n");
php_info_print_table_start();
php_info_print_table_header(2, \"Directive\", \"Value\");
@ -856,7 +816,7 @@ either <tt>%init</tt> or <tt>%minit</tt>.
<p>
To insert code into the <tt>PHP_MSHUTDOWN_FUNCTION</tt>, one can use
either <tt>%init</tt> or <tt>%minit</tt>.
either <tt>%shutdown</tt> or <tt>%mshutdown</tt>.
</p>
<div class="code"><pre>
@ -867,8 +827,384 @@ either <tt>%init</tt> or <tt>%minit</tt>.
</pre></div>
<p>
The <tt>%rinit</tt> and <tt>%rshutdown</tt> statements insert code
into the request init and shutdown code respectively.
The <tt>%rinit</tt> and <tt>%rshutdown</tt> statements are very similar but insert code
into the request init (PHP_RINIT_FUNCTION) and request shutdown (PHP_RSHUTDOWN_FUNCTION) code respectively.
</p>
<H2><a name="Php_nn3"></a>32.3 Cross language polymorphism</H2>
<p>
Proxy classes provide a more natural, object-oriented way to access
extension classes. As described above, each proxy instance has an
associated C++ instance, and method calls to the proxy are passed to the
C++ instance transparently via C wrapper functions.
</p>
<p>
This arrangement is asymmetric in the sense that no corresponding
mechanism exists to pass method calls down the inheritance chain from
C++ to PHP. In particular, if a C++ class has been extended in PHP
(by extending the proxy class), these extensions will not be visible
from C++ code. Virtual method calls from C++ are thus not able access
the lowest implementation in the inheritance chain.
</p>
<p>
Changes have been made to SWIG 1.3.18 to address this problem and make
the relationship between C++ classes and proxy classes more symmetric.
To achieve this goal, new classes called directors are introduced at the
bottom of the C++ inheritance chain. Support for generating PHP classes
has been added in SWIG 1.3.40. The job of the directors is to route
method calls correctly, either to C++ implementations higher in the
inheritance chain or to PHP implementations lower in the inheritance
chain. The upshot is that C++ classes can be extended in PHP and from
C++ these extensions look exactly like native C++ classes. Neither C++
code nor PHP code needs to know where a particular method is
implemented: the combination of proxy classes, director classes, and C
wrapper functions takes care of all the cross-language method routing
transparently.
</p>
<H3><a name="Php_nn3_1"></a>32.3.1 Enabling directors</H3>
<p>
The director feature is disabled by default. To use directors you
must make two changes to the interface file. First, add the "directors"
option to the %module directive, like this:
</p>
<div class="code">
<pre>
%module(directors="1") modulename
</pre>
</div>
<p>
Without this option no director code will be generated. Second, you
must use the %feature("director") directive to tell SWIG which classes
and methods should get directors. The %feature directive can be applied
globally, to specific classes, and to specific methods, like this:
</p>
<div class="code">
<pre>
// generate directors for all classes that have virtual methods
%feature("director");
// generate directors for all virtual methods in class Foo
%feature("director") Foo;
// generate a director for just Foo::bar()
%feature("director") Foo::bar;
</pre>
</div>
<p>
You can use the %feature("nodirector") directive to turn off
directors for specific classes or methods. So for example,
</p>
<div class="code">
<pre>
%feature("director") Foo;
%feature("nodirector") Foo::bar;
</pre>
</div>
<p>
will generate directors for all virtual methods of class Foo except
bar().
</p>
<p>
Directors can also be generated implicitly through inheritance.
In the following, class Bar will get a director class that handles
the methods one() and two() (but not three()):
</p>
<div class="code">
<pre>
%feature("director") Foo;
class Foo {
public:
Foo(int foo);
virtual void one();
virtual void two();
};
class Bar: public Foo {
public:
virtual void three();
};
</pre>
</div>
<p>
then at the PHP side you can define
</p>
<div class="targetlang">
<pre>
require("mymodule.php");
class MyFoo extends Foo {
function one() {
print "one from php\n";
}
}
</pre>
</div>
<H3><a name="Php_nn3_2"></a>32.3.2 Director classes</H3>
<p>
For each class that has directors enabled, SWIG generates a new class
that derives from both the class in question and a special
<tt>Swig::Director</tt> class. These new classes, referred to as director
classes, can be loosely thought of as the C++ equivalent of the PHP
proxy classes. The director classes store a pointer to their underlying
PHP object. Indeed, this is quite similar to the "_cPtr" and "thisown"
members of the PHP proxy classes.
</p>
<p>
For simplicity let's ignore the <tt>Swig::Director</tt> class and refer to the
original C++ class as the director's base class. By default, a director
class extends all virtual methods in the inheritance chain of its base
class (see the preceding section for how to modify this behavior).
Thus all virtual method calls, whether they originate in C++ or in
PHP via proxy classes, eventually end up in at the implementation in the
director class. The job of the director methods is to route these method
calls to the appropriate place in the inheritance chain. By "appropriate
place" we mean the method that would have been called if the C++ base
class and its extensions in PHP were seamlessly integrated. That
seamless integration is exactly what the director classes provide,
transparently skipping over all the messy extension API glue that binds
the two languages together.
</p>
<p>
In reality, the "appropriate place" is one of only two possibilities:
C++ or PHP. Once this decision is made, the rest is fairly easy. If the
correct implementation is in C++, then the lowest implementation of the
method in the C++ inheritance chain is called explicitly. If the correct
implementation is in PHP, the Zend API is used to call the method of the
underlying PHP object (after which the usual virtual method resolution
in PHP automatically finds the right implementation).
</p>
<p>
Now how does the director decide which language should handle the method call?
The basic rule is to handle the method in PHP, unless there's a good
reason not to. The reason for this is simple: PHP has the most
"extended" implementation of the method. This assertion is guaranteed,
since at a minimum the PHP proxy class implements the method. If the
method in question has been extended by a class derived from the proxy
class, that extended implementation will execute exactly as it should.
If not, the proxy class will route the method call into a C wrapper
function, expecting that the method will be resolved in C++. The wrapper
will call the virtual method of the C++ instance, and since the director
extends this the call will end up right back in the director method. Now
comes the "good reason not to" part. If the director method were to blindly
call the PHP method again, it would get stuck in an infinite loop. We avoid this
situation by adding special code to the C wrapper function that tells
the director method to not do this. The C wrapper function compares the
called and the declaring class name of the given method. If these are
not the same, then the C wrapper function tells the director to resolve
the method by calling up the C++ inheritance chain, preventing an
infinite loop.
</p>
<p>
One more point needs to be made about the relationship between director
classes and proxy classes. When a proxy class instance is created in
PHP, SWIG creates an instance of the original C++ class and assigns it
to <tt>-&gt;_cPtr</tt>. This is exactly what happens without directors
and is true even if directors are enabled for the particular class in
question. When a class <i>derived</i> from a proxy class is created,
however, SWIG then creates an instance of the corresponding C++ director
class. The reason for this difference is that user-defined subclasses
may override or extend methods of the original class, so the director
class is needed to route calls to these methods correctly. For
unmodified proxy classes, all methods are ultimately implemented in C++
so there is no need for the extra overhead involved with routing the
calls through PHP.
</p>
<H3><a name="Php_nn3_3"></a>32.3.3 Ownership and object destruction</H3>
<p>
Memory management issues are slightly more complicated with directors
than for proxy classes alone. PHP instances hold a pointer to the
associated C++ director object, and the director in turn holds a pointer
back to the PHP object. By default, proxy classes own their C++ director
object and take care of deleting it when they are garbage collected.
</p>
<p>
This relationship can be reversed by calling the special
<tt>-&gt;thisown</tt> property of the proxy class. After setting this
property to <tt>0</tt>, the director class no longer destroys the PHP
object. Assuming no outstanding references to the PHP object remain,
the PHP object will be destroyed at the same time. This is a good thing,
since directors and proxies refer to each other and so must be created
and destroyed together. Destroying one without destroying the other will
likely cause your program to segfault.
</p>
<p>
Here is an example:
</p>
<div class="code">
<pre>
class Foo {
public:
...
};
class FooContainer {
public:
void addFoo(Foo *);
...
};
</pre>
</div>
<br>
<div class="targetlang">
<pre>
$c = new FooContainer();
$a = new Foo();
$a-&gt;thisown = 0;
$c-&gt;addFoo($a);
</pre>
</div>
<p>
In this example, we are assuming that FooContainer will take care of
deleting all the Foo pointers it contains at some point.
</p>
<H3><a name="Php_nn3_4"></a>32.3.4 Exception unrolling</H3>
<p>
With directors routing method calls to PHP, and proxies routing them
to C++, the handling of exceptions is an important concern. By default, the
directors ignore exceptions that occur during method calls that are
resolved in PHP. To handle such exceptions correctly, it is necessary
to temporarily translate them into C++ exceptions. This can be done with
the %feature("director:except") directive. The following code should
suffice in most cases:
</p>
<div class="code">
<pre>
%feature("director:except") {
if ($error == FAILURE) {
throw Swig::DirectorMethodException();
}
}
</pre>
</div>
<p>
This code will check the PHP error state after each method call from a
director into PHP, and throw a C++ exception if an error occurred. This
exception can be caught in C++ to implement an error handler.
Currently no information about the PHP error is stored in the
Swig::DirectorMethodException object, but this will likely change in the
future.
</p>
<p>
It may be the case that a method call originates in PHP, travels up to
C++ through a proxy class, and then back into PHP via a director method.
If an exception occurs in PHP at this point, it would be nice for that
exception to find its way back to the original caller. This can be done
by combining a normal %exception directive with the
<tt>director:except</tt> handler shown above. Here is an example of a
suitable exception handler:
</p>
<div class="code">
<pre>
%exception {
try { $action }
catch (Swig::DirectorException &amp;e) { SWIG_fail; }
}
</pre>
</div>
<p>
The class Swig::DirectorException used in this example is actually a
base class of Swig::DirectorMethodException, so it will trap this
exception. Because the PHP error state is still set when
Swig::DirectorMethodException is thrown, PHP will register the exception
as soon as the C wrapper function returns.
</p>
<H3><a name="Php_nn3_5"></a>32.3.5 Overhead and code bloat</H3>
<p>
Enabling directors for a class will generate a new director method for
every virtual method in the class' inheritance chain. This alone can
generate a lot of code bloat for large hierarchies. Method arguments
that require complex conversions to and from target language types can
result in large director methods. For this reason it is recommended that
you selectively enable directors only for specific classes that are
likely to be extended in PHP and used in C++.
</p>
<p>
Compared to classes that do not use directors, the call routing in the
director methods does add some overhead. In particular, at least one
dynamic cast and one extra function call occurs per method call from
PHP. Relative to the speed of PHP execution this is probably completely
negligible. For worst case routing, a method call that ultimately
resolves in C++ may take one extra detour through PHP in order to ensure
that the method does not have an extended PHP implementation. This could
result in a noticeable overhead in some cases.
</p>
<p>
Although directors make it natural to mix native C++ objects with PHP
objects (as director objects) via a common base class pointer, one
should be aware of the obvious fact that method calls to PHP objects
will be much slower than calls to C++ objects. This situation can be
optimized by selectively enabling director methods (using the %feature
directive) for only those methods that are likely to be extended in PHP.
</p>
<H3><a name="Php_nn3_6"></a>32.3.6 Typemaps</H3>
<p>
Typemaps for input and output of most of the basic types from director
classes have been written. These are roughly the reverse of the usual
input and output typemaps used by the wrapper code. The typemap
operation names are 'directorin', 'directorout', and 'directorargout'.
The director code does not currently use any of the other kinds of
typemaps. It is not clear at this point which kinds are appropriate and
need to be supported.
</p>
<H3><a name="Php_nn3_7"></a>32.3.7 Miscellaneous</H3>
<p> Director typemaps for STL classes are mostly in place, and hence you
should be able to use std::string, etc., as you would any other type.
</p>
</body>

View file

@ -6,7 +6,7 @@
</head>
<body bgcolor="#ffffff">
<H1><a name="Pike"></a>29 SWIG and Pike</H1>
<H1><a name="Pike"></a>33 SWIG and Pike</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
@ -46,10 +46,10 @@ least, make sure you read the "<a href="SWIG.html#SWIG">SWIG Basics</a>"
chapter.<br>
</p>
<H2><a name="Pike_nn2"></a>29.1 Preliminaries</H2>
<H2><a name="Pike_nn2"></a>33.1 Preliminaries</H2>
<H3><a name="Pike_nn3"></a>29.1.1 Running SWIG</H3>
<H3><a name="Pike_nn3"></a>33.1.1 Running SWIG</H3>
<p>
@ -94,7 +94,7 @@ can use the <tt>-o</tt> option:
<div class="code">
<pre>$ <b>swig -pike -o pseudonym.c example.i</b><br></pre>
</div>
<H3><a name="Pike_nn4"></a>29.1.2 Getting the right header files</H3>
<H3><a name="Pike_nn4"></a>33.1.2 Getting the right header files</H3>
<p>
@ -114,7 +114,7 @@ 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>29.1.3 Using your module</H3>
<H3><a name="Pike_nn5"></a>33.1.3 Using your module</H3>
<p>
@ -129,10 +129,10 @@ Pike v7.4 release 10 running Hilfe v3.5 (Incremental Pike Frontend)
(1) Result: 24
</pre></div>
<H2><a name="Pike_nn6"></a>29.2 Basic C/C++ Mapping</H2>
<H2><a name="Pike_nn6"></a>33.2 Basic C/C++ Mapping</H2>
<H3><a name="Pike_nn7"></a>29.2.1 Modules</H3>
<H3><a name="Pike_nn7"></a>33.2.1 Modules</H3>
<p>
@ -143,7 +143,7 @@ concerned), SWIG's <tt>%module</tt> directive doesn't really have any
significance.
</p>
<H3><a name="Pike_nn8"></a>29.2.2 Functions</H3>
<H3><a name="Pike_nn8"></a>33.2.2 Functions</H3>
<p>
@ -168,11 +168,11 @@ exactly as you'd expect it to:
(1) Result: 24
</pre></div>
<H3><a name="Pike_nn9"></a>29.2.3 Global variables</H3>
<H3><a name="Pike_nn9"></a>33.2.3 Global variables</H3>
<p>
Global variables are currently wrapped as a pair of of functions, one to get
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>
@ -197,7 +197,7 @@ will result in two functions, <tt>Foo_get()</tt> and <tt>Foo_set()</tt>:
(3) Result: 3.141590
</pre></div>
<H3><a name="Pike_nn10"></a>29.2.4 Constants and enumerated types</H3>
<H3><a name="Pike_nn10"></a>33.2.4 Constants and enumerated types</H3>
<p>
@ -205,7 +205,7 @@ Enumerated types in C/C++ declarations are wrapped as Pike constants,
not as Pike enums.
</p>
<H3><a name="Pike_nn11"></a>29.2.5 Constructors and Destructors</H3>
<H3><a name="Pike_nn11"></a>33.2.5 Constructors and Destructors</H3>
<p>
@ -213,7 +213,7 @@ 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>29.2.6 Static Members</H3>
<H3><a name="Pike_nn12"></a>33.2.6 Static Members</H3>
<p>

View file

@ -11,13 +11,12 @@
<div class="sectiontoc">
<ul>
<li><a href="#Preface_nn2">Introduction</a>
<li><a href="#Preface_nn3">Special Introduction for Version 1.3</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_nn9">Backwards compatibility</a>
<li><a href="#Preface_nn10">Credits</a>
<li><a href="#Preface_nn11">Bug reports</a>
</ul>
@ -49,34 +48,22 @@ 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_nn3"></a>1.2 Special Introduction for Version 1.3</H2>
<H2><a name="Preface_nn4"></a>1.2 SWIG Versions</H2>
<p>
Since SWIG was released in 1996, its user base and applicability has
continued to grow. Although its rate of development has varied, an
active development effort has continued to make improvements to the
system. Today, nearly a dozen developers are working to create
SWIG-2.0---a system that aims to provide wrapping support for nearly
all of the ANSI C++ standard and approximately ten target languages
including Guile, Java, Mzscheme, Ocaml, Perl, Pike, PHP, Python, Ruby,
and Tcl.
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_nn4"></a>1.3 SWIG Versions</H2>
<p>
For several years, the most stable version of SWIG has been release
1.1p5. Starting with version 1.3, a new version numbering scheme has
been adopted. Odd version numbers (1.3, 1.5, etc.) represent
development versions of SWIG. Even version numbers (1.4, 1.6, etc.)
represent stable releases. Currently, developers are working to
create a stable SWIG-2.0 release. Don't let the development status
of SWIG-1.3 scare you---it is much more stable (and capable) than SWIG-1.1p5.
</p>
<H2><a name="Preface_nn5"></a>1.4 SWIG resources</H2>
<H2><a name="Preface_nn5"></a>1.3 SWIG resources</H2>
<p>
@ -106,7 +93,7 @@ SWIG along with information about beta releases and future work.
</p>
<p>
SVN access to the latest version of SWIG is also available. More information
Subversion access to the latest version of SWIG is also available. More information
about this can be obtained at:
</p>
@ -115,7 +102,7 @@ about this can be obtained at:
</pre></div>
<H2><a name="Preface_nn6"></a>1.5 Prerequisites</H2>
<H2><a name="Preface_nn6"></a>1.4 Prerequisites</H2>
<p>
@ -132,7 +119,7 @@ writing a normal C program.
</p>
<p>
Recent SWIG releases have become significantly more capable in
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.
@ -140,7 +127,7 @@ 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.6 Organization of this manual</H2>
<H2><a name="Preface_nn7"></a>1.5 Organization of this manual</H2>
<p>
@ -149,11 +136,10 @@ 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. Caveat: we are currently working on a documentation rewrite and many
of the older language module chapters are still somewhat out of date.
to know.
</p>
<H2><a name="Preface_nn8"></a>1.7 How to avoid reading the manual</H2>
<H2><a name="Preface_nn8"></a>1.6 How to avoid reading the manual</H2>
<p>
@ -165,24 +151,19 @@ The SWIG distribution also comes with a large directory of
examples that illustrate different topics.
</p>
<H2><a name="Preface_nn9"></a>1.8 Backwards Compatibility</H2>
<H2><a name="Preface_nn9"></a>1.7 Backwards compatibility</H2>
<p>
If you are a previous user of SWIG, don't expect recent versions of
SWIG to provide backwards compatibility. In fact, backwards
compatibility issues may arise even between successive 1.3.x releases.
Although these incompatibilities are regrettable, SWIG-1.3 is an active
development project. The primary goal of this effort is to make SWIG
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.
</p>
<p>
On a positive note, a few incompatibilities are a small price to pay
for the large number of new features that have been
added---namespaces, templates, smart pointers, overloaded methods,
operators, and more.
Potential incompatibilities are clearly marked in the detailed release notes
(CHANGES files).
</p>
@ -206,33 +187,20 @@ 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.9 Credits</H2>
<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. Most recent SWIG development has been
supported by Matthias K&ouml;ppe, William Fulton, Lyle Johnson,
Richard Palmer, Thien-Thi Nguyen, Jason Stewart, Loic Dachary, Masaki
Fukushima, Luigi Ballabio, Sam Liddicott, Art Yerkes, Marcelo Matus,
Harco de Hilster, John Lenz, and Surendra Singhi.
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>
<p>
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.
<H2><a name="Preface_nn11"></a>1.10 Bug reports</H2>
<H2><a name="Preface_nn11"></a>1.9 Bug reports</H2>
<p>

View file

@ -81,7 +81,7 @@ Such information generally includes type declarations (e.g., <tt>typedef</tt>) a
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 a later chapter.
in later in the <a href="Modules.html#Modules">Working with Modules</a> chapter.
</p>
<P>
@ -102,12 +102,13 @@ by SWIG when it is parsing the interface:
<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>
SWIGMAC Defined when running SWIG on the Macintosh
SWIGWIN Defined when running SWIG under Windows
SWIG_VERSION Hexadecimal number containing SWIG version,
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
@ -115,17 +116,15 @@ 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
SWIGPERL5 Defined when using Perl5
SWIGPHP Defined when using PHP
SWIGPHP4 Defined when using PHP4
SWIGPHP5 Defined when using PHP5
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
SWIGTCL8 Defined when using Tcl8.0
SWIGXML Defined when using XML
</pre></div>
@ -378,7 +377,7 @@ SWIG will strip the extra <tt>%</tt> and leave the preprocessor directive in the
<p>
<a href="Typemaps.html">Typemaps</a> support a special attribute called <tt>noblock</tt> where the { ... } delimiters can be used,
<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>

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,7 @@
</head>
<body bgcolor="#ffffff">
<H1><a name="R"></a>33 SWIG and R</H1>
<H1><a name="R"></a>35 SWIG and R</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
@ -33,7 +33,7 @@ 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>
<H2><a name="R_nn2"></a>35.1 Bugs</H2>
<p>
@ -45,7 +45,7 @@ Currently the following features are not implemented or broken:
<li>C Array wrappings
</ul>
<H2><a name="R_nn3"></a>33.2 Using R and SWIG</H2>
<H2><a name="R_nn3"></a>35.2 Using R and SWIG</H2>
<p>
@ -56,28 +56,48 @@ example.c is the name of the file with the functions in them
<div class="shell">
<pre>
swig -r example.i
PKG_LIBS="example.c" R CMD SHLIB example_wrap.c
R CMD SHLIB example_wrap.c example.c
</pre>
</div>
<p>
The corresponding comments for C++ mode are
The corresponding options for C++ mode are
</p>
<div class="shell">
<pre>
swig -c++ -r -o example_wrap.cpp example.i
PKG_LIBS="example.cxx" R CMD SHLIB example_wrap.cpp
R CMD SHLIB example_wrap.cpp example.cpp
</pre>
</div>
<p>
Note that R is sensitive to the name of the file and to the file
extension in C and C++ mode. The name of the wrapper file must be the
name of the library. Also in C++ mode, the file extension must be .cpp
rather than .cxx for the R compile command to recognize it.
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
@ -99,7 +119,7 @@ Without it, inheritance of wrapped objects may fail.
These two files can be loaded in any order
</p>
<H2><a name="R_nn4"></a>33.3 Precompiling large R files</H2>
<H2><a name="R_nn4"></a>35.3 Precompiling large R files</H2>
In cases where the R file is large, one make save a lot of loading
@ -117,7 +137,7 @@ will save a large amount of loading time.
<H2><a name="R_nn5"></a>33.4 General policy</H2>
<H2><a name="R_nn5"></a>35.4 General policy</H2>
<p>
@ -126,7 +146,7 @@ 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>
<H2><a name="R_language_conventions"></a>35.5 Language conventions</H2>
<p>
@ -135,7 +155,7 @@ 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>
<H2><a name="R_nn6"></a>35.6 C++ classes</H2>
<p>
@ -147,7 +167,7 @@ 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>
<H2><a name="R_nn7"></a>35.7 Enumerations</H2>
<p>

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@
<li><a href="#SWIG_nn2">Running SWIG</a>
<ul>
<li><a href="#SWIG_nn3">Input format</a>
<li><a href="#output">SWIG Output</a>
<li><a href="#SWIG_output">SWIG Output</a>
<li><a href="#SWIG_nn5">Comments</a>
<li><a href="#SWIG_nn6">C Preprocessor</a>
<li><a href="#SWIG_nn7">SWIG Directives</a>
@ -44,6 +44,12 @@
<li><a href="#SWIG_nn26">Arrays</a>
<li><a href="#SWIG_readonly_variables">Creating read-only variables</a>
<li><a href="#SWIG_rename_ignore">Renaming and ignoring declarations</a>
<ul>
<li><a href="#SWIG_nn29">Simple renaming of specific identifiers</a>
<li><a href="#SWIG_advanced_renaming">Advanced renaming support</a>
<li><a href="#SWIG_limiting_renaming">Limiting global renaming rules</a>
<li><a href="#SWIG_chosen_unignore">Ignoring everything then wrapping a few selected symbols</a>
</ul>
<li><a href="#SWIG_default_args">Default/optional arguments</a>
<li><a href="#SWIG_nn30">Pointers to functions and callbacks</a>
</ul>
@ -92,7 +98,7 @@ chapters.
<p>
To run SWIG, use the <tt>swig</tt> command with options options and a filename like this:
To run SWIG, use the <tt>swig</tt> command with options and a filename like this:
</p>
<div class="shell"><pre>
@ -113,6 +119,7 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
-clisp Generate CLISP wrappers
-cffi Generate CFFI wrappers
-csharp Generate C# wrappers
-go Generate Go wrappers
-guile Generate Guile wrappers
-java Generate Java wrappers
-lua Generate Lua wrappers
@ -120,8 +127,7 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
-mzscheme Generate Mzscheme wrappers
-ocaml Generate Ocaml wrappers
-perl Generate Perl wrappers
-php4 Generate PHP4 wrappers
-php5 Generate PHP5 wrappers
-php Generate PHP wrappers
-pike Generate Pike wrappers
-python Generate Python wrappers
-r Generate R (aka GNU S) wrappers
@ -140,7 +146,9 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
-l<em>file</em> Include a SWIG library file.
-module <em>name</em> Set the name of the SWIG module
-o <em>outfile</em> Name of output file
-outcurrentdir Set default output dir to current dir instead of input file's path
-outdir <em>dir</em> Set language specific files output directory
-pcreversion Display PCRE version information
-swiglib Show location of SWIG library
-version Show SWIG version number
@ -174,13 +182,8 @@ int bar(int x);
...
</pre></div>
<p>
The name of the module is supplied using the special <tt>%module</tt>
directive (or the <tt>-module</tt> command line option). This
directive must appear at the beginning of the file and is used to name
the resulting extension module (in addition, this name often defines
a namespace in the target language). If the module name is supplied on the
command line, it overrides the name specified with the
<tt>%module</tt> directive.
The module name is supplied using the special <tt>%module</tt>
directive. Modules are described further in the <a href="Modules.html#Modules_introduction">Modules Introduction</a> section.
</p>
<p>
@ -198,7 +201,7 @@ semantics in SWIG is analogous to that of the declarations section
used in input files to parser generation tools such as yacc or bison.
</p>
<H3><a name="output"></a>5.1.2 SWIG Output</H3>
<H3><a name="SWIG_output"></a>5.1.2 SWIG Output</H3>
<p>
@ -247,6 +250,17 @@ cppfiles/example_wrap.cpp
pyfiles/example.py
</pre></div>
<p>
If the <tt>-outcurrentdir</tt> option is used (without <tt>-o</tt>)
then SWIG behaves like a typical C/C++
compiler and the default output directory is then the current directory. Without
this option the default output directory is the path to the input file.
If <tt>-o</tt> and
<tt>-outcurrentdir</tt> are used together, <tt>-outcurrentdir</tt> is effectively ignored
as the output directory for the language files is the same directory as the
generated C/C++ file if not overidden with <tt>-outdir</tt>.
</p>
<H3><a name="SWIG_nn5"></a>5.1.3 Comments</H3>
@ -324,10 +338,13 @@ currently supported:
</p>
<ul>
<li>Non-conventional type declarations.
<li>
<p>
Non-conventional type declarations.
For example, SWIG does not support declarations such as the following
(even though this is legal C):
</p>
<div class="code">
<pre>
/* Non-conventional placement of storage specifier (extern) */
@ -349,15 +366,19 @@ if you're feeling particularly obfuscated, you can certainly break SWIG (althoug
</p>
</li>
<li>Running SWIG on C++ source files (what would appear in a .C or .cxx file)
is not recommended. Even though SWIG can parse C++ class declarations,
it ignores declarations that are decoupled from their
original class definition (the declarations are parsed, but a lot of warning
messages may be generated). For example:
<li>
<p>
Running SWIG on C++ source files (the code in a .C, .cpp or .cxx file) is not recommended.
The usual approach is to feed SWIG header files for parsing C++ definitions and declarations.
The main reason is if SWIG parses a scoped definition or declaration (as is normal for C++ source files),
it is ignored, unless a declaration for the symbol was parsed earlier.
For example
</p>
<div class="code">
<pre>
/* Not supported by SWIG */
/* bar not wrapped unless foo has been defined and
the declaration of bar within foo has already been parsed */
int foo::bar(int) {
... whatever ...
}
@ -365,9 +386,12 @@ int foo::bar(int) {
</div>
</li>
<li>Certain advanced features of C++ such as nested classes
are not yet supported. Please see the section on using SWIG
with C++ for more information.
<li>
<p>
Certain advanced features of C++ such as nested classes
are not yet fully supported. Please see the C++ <a href="SWIGPlus.html#SWIGPlus_nested_classes">Nested classes</a> section
for more information.
</p>
</ul>
<p>
@ -661,7 +685,6 @@ enum boolean {NO=0, YES=1};
enum months {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG,
SEP, OCT, NOV, DEC};
%constant double BLAH = 42.37;
#define F_CONST (double) 5 // A floating pointer constant with cast
#define PI_4 PI/4
#define FLAGS 0x04 | 0x08 | 0x40
@ -700,8 +723,15 @@ the declaration
<p>
defines a constant because <tt>PI</tt> was already defined as a
constant and the value is known.
However, for the same conservative reasons even a constant with a simple cast will be ignored, such as
</p>
<div class="code">
<pre>
#define F_CONST (double) 5 // A floating pointer constant with cast
</pre>
</div>
<p>
The use of constant expressions is allowed, but SWIG does not evaluate
them. Rather, it passes them through to the output file and lets the C
@ -775,6 +805,12 @@ In this case, the pointer <tt>e</tt> can change---it's only the value
being pointed to that is read-only.
</p>
<p>
Please note that for const parameters or return types used in a function, SWIG pretty much ignores
the fact that these are const, see the section on <a href="SWIGPlus.html#SWIGPlus_const">const-correctness</a>
for more information.
</p>
<p>
<b>Compatibility Note:</b> One reason for changing SWIG to handle
<tt>const</tt> declarations as read-only variables is that there are
@ -1590,7 +1626,7 @@ double y; // Read-write
<p>
The <tt>%mutable</tt> and <tt>%immutable</tt> directives are actually
<a href="Customization.html#features">%feature directives</a> defined like this:
<a href="Customization.html#Customization_features">%feature directives</a> defined like this:
</p>
<div class="code"><pre>
@ -1633,6 +1669,9 @@ generate a warning message. Simply change the directives to <tt>%immutable;</t
<H3><a name="SWIG_rename_ignore"></a>5.4.7 Renaming and ignoring declarations</H3>
<H4><a name="SWIG_nn29"></a>5.4.7.1 Simple renaming of specific identifiers</H4>
<p>
Normally, the name of a C declaration is used when that declaration is
wrapped into the target language. However, this may generate a
@ -1644,7 +1683,7 @@ directive as shown :</p>
// interface.i
%rename(my_print) print;
extern void print(char *);
extern void print(const char *);
%rename(foo) a_really_long_and_annoying_name;
extern int a_really_long_and_annoying_name;
@ -1697,9 +1736,10 @@ to ignore declarations that match a given identifier. For example:
<div class="code">
<pre>
%ignore print; // Ignore all declarations named print
%ignore _HAVE_FOO_H; // Ignore an include guard constant
%ignore MYMACRO; // Ignore a macro
...
%include "foo.h" // Grab a header file
#define MYMACRO 123
void print(const char *);
...
</pre>
</div>
@ -1711,12 +1751,6 @@ to add conditional compilation to the header. However, it should be stressed t
declarations. If you need to remove a whole section of problematic code, the SWIG preprocessor should be used instead.
</p>
<p>
More powerful variants of <tt>%rename</tt> and <tt>%ignore</tt> directives can be used to help
wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the
<a href="SWIGPlus.html#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section in the C++ chapter.
</p>
<p>
<b>Compatibility note: </b> Older versions of SWIG provided a special <tt>%name</tt> directive for renaming declarations.
For example:
@ -1724,7 +1758,7 @@ For example:
<div class="code">
<pre>
%name(output) extern void print(char *);
%name(output) extern void print(const char *);
</pre>
</div>
@ -1733,6 +1767,337 @@ This directive is still supported, but it is deprecated and should probably be a
directive is more powerful and better supports wrapping of raw header file information.
</p>
<H4><a name="SWIG_advanced_renaming"></a>5.4.7.2 Advanced renaming support</H4>
<p>
While writing <tt>%rename</tt> for specific declarations is simple enough,
sometimes the same renaming rule needs to be applied to many, maybe all,
identifiers in the SWIG input. For example, it may be necessary to apply some
transformation to all the names in the target language to better follow its
naming conventions, like adding a specific prefix to all wrapped functions. Doing it individually
for each function is impractical so SWIG supports applying a renaming rule to
all declarations if the name of the identifier to be renamed is not specified:
</p>
<div class="code">
<pre>
%rename("myprefix_%s") ""; // print&nbsp;-&gt;&nbsp;myprefix_print
</pre>
</div>
<p>
This also shows that the argument of <tt>%rename</tt> doesn't have to be a
literal string but can be a <tt>printf()</tt>-like format string. In the
simplest form, <tt>"%s"</tt> is replaced with the name of the original
declaration, as shown above. However this is not always enough and SWIG
provides extensions to the usual format string syntax to allow applying a
(SWIG-defined) function to the argument. For example, to wrap all C functions
<tt>do_something_long()</tt> as more Java-like <tt>doSomethingLong()</tt> you
can use the <tt>"lowercamelcase"</tt> extended format specifier like this:
</p>
<div class="code">
<pre>
%rename("%(lowercamelcase)s") ""; // foo_bar -&gt; fooBar; FooBar -&gt; fooBar
</pre>
</div>
<p>
Some functions can be parametrized, for example the <tt>"strip"</tt> one
strips the provided prefix from its argument. The prefix is specified as part
of the format string, following a colon after the function name:
</p>
<div class="code">
<pre>
%rename("%(strip:[wx])s") ""; // wxHello -&gt; Hello; FooBar -&gt; FooBar
</pre>
</div>
<p>
Below is the table summarizing all currently defined functions with an example
of applying each one. Note that some of them have two names, a shorter one
and a more descriptive one, but the two functions are otherwise equivalent:
</p>
<table summary="Format string functions" border="1" cellpadding="5">
<tr>
<th>Function</th><th>Returns</th><th colspan=2>Example (in/out)</th>
</tr>
<tr>
<td><tt>uppercase</tt> or <tt>upper</tt></td>
<td>Upper case version of the string.</td>
<td><tt>Print</tt></td><td><tt>PRINT</tt></td>
</tr>
<tr>
<td><tt>lowercase</tt> or <tt>lower</tt></td>
<td>Lower case version of the string.</td>
<td><tt>Print</tt></td><td><tt>print</tt></td>
</tr>
<tr>
<td><tt>title</tt></td>
<td>String with first letter capitalized and the rest in lower case.</td>
<td><tt>print</tt></td><td><tt>Print</tt></td>
</tr>
<tr>
<td><tt>firstuppercase</tt></td>
<td>String with the first letter capitalized and the rest unchanged.</td>
<td><tt>printIt</tt></td><td><tt>PrintIt</tt></td>
</tr>
<tr>
<td><tt>firstlowercase</tt></td>
<td>String with the first letter in lower case and the rest unchanged.</td>
<td><tt>PrintIt</tt></td><td><tt>printIt</tt></td>
</tr>
<tr>
<td><tt>camelcase</tt> or <tt>ctitle</tt></td>
<td>String with capitalized first letter and any letter following an
underscore (which are removed in the process) and rest in lower case.</td>
<td><tt>print_it</tt></td><td><tt>PrintIt</tt></td>
</tr>
<tr>
<td><tt>lowercamelcase</tt> or <tt>lctitle</tt></td>
<td>String with every letter following an underscore (which is removed in
the process) capitalized and rest, including the first letter, in lower
case.</td>
<td><tt>print_it</tt></td><td><tt>printIt</tt></td>
</tr>
<tr>
<td><tt>undercase</tt> or <tt>utitle</tt></td>
<td>Lower case string with underscores inserted before every upper case
letter in the original string and any number not at the end of string.
Logically, this is the reverse of <tt>camelcase</tt>.</td>
<td><tt>PrintIt</tt></td><td><tt>print_it</tt></td>
</tr>
<tr>
<td><tt>schemify</tt></td>
<td>String with all underscores replaced with dashes, resulting in more
Lispers/Schemers-pleasing name.</td>
<td><tt>print_it</tt></td><td><tt>print-it</tt></td>
</tr>
<tr>
<td><tt>strip:[prefix]</tt></td>
<td>String without the given prefix or the original string if it doesn't
start with this prefix. Note that square brackets should be used
literally, e.g. <tt>%rename("strip:[wx]")</tt></td>
<td><tt>wxPrint</tt></td><td><tt>Print</tt></td>
</tr>
<tr>
<td><span style="white-space: nowrap;"><tt>regex:/pattern/subst/</tt></span></td>
<td>String after (Perl-like) regex substitution operation. This function
allows to apply arbitrary regular expressions to the identifier names. The
<i>pattern</i> part is a regular expression in Perl syntax (as supported
by the <a href="http://www.pcre.org/">Perl Compatible Regular Expressions (PCRE)</a>)
library and the <i>subst</i> string
can contain back-references introduced by <tt>'\'</tt> or, as backslashes need
to be escaped in C strings, rather by <tt>"\\"</tt>. For example, to remove
any alphabetic prefix before an underscore you could use the following directive:
<tt>%rename("regex:/(\\w+)_(.*)/\\2/")</tt></td>
<td><tt>Prefix_Print</tt></td><td><tt>Print</tt></td>
</tr>
<tr>
<td><tt>command:cmd</tt></td>
<td>Output of an external command <tt>cmd</tt> with the string passed to
it as input. Notice that this function is extremely slow compared to all
the other ones as it involves spawning a separate process and using it for
many declarations is not recommended. The <i>cmd</i> is not enclosed in
square brackets but must be terminated with a triple <tt>'&lt;'</tt> sign,
e.g. <tt>%rename("command:tr&nbsp;-d&nbsp;aeiou &lt;&lt;&lt;")</tt>
(nonsensical example removing all vowels)</td>
<td><tt>Print</tt></td><td><tt>Prnt</tt></td>
</tr>
</table>
<p>
The most general function of all of the above ones (not counting
<tt>command</tt> which is even more powerful in principle but which should
generally be avoided because of performance considerations) is the
<tt>regex</tt> one. Here are some more examples of its use:
</p>
<div class="code">
<pre>
// Strip the wx prefix from all identifiers except those starting with wxEVT
%rename("%(regex:/wx(?!EVT)(.*)/\\1/)s") ""; // wxSomeWidget -&gt; SomeWidget
// wxEVT_PAINT -&gt; wxEVT_PAINT
// Apply a rule for renaming the enum elements to avoid the common prefixes
// which are redundant in C#/Java
%rename("%(regex:/^([A-Z][a-z]+)+_(.*)/\\2/)s", %$isenumitem) ""; // Colour_Red -&gt; Red
// Remove all "Set/Get" prefixes.
%rename("%(regex:/^(Set|Get)(.*)/\\2/)s") ""; // SetValue -&gt; Value
// GetValue -&gt; Value
</pre>
</div>
<p>
As before, everything that was said above about <tt>%rename</tt> also applies to
<tt>%ignore</tt>. In fact, the latter is just a special case of the former and
ignoring an identifier is the same as renaming it to the special
<tt>"$ignore"</tt> value. So the following snippets
</p>
<div class="code">
<pre>
%ignore print;
</pre>
</div>
<p>
and
</p>
<div class="code">
<pre>
%rename("$ignore") print;
</pre>
</div>
<p>
are exactly equivalent and <tt>%rename</tt> can be used to selectively ignore
multiple declarations using the previously described matching possibilities.
</p>
<H4><a name="SWIG_limiting_renaming"></a>5.4.7.3 Limiting global renaming rules</H4>
<p>
As explained in the previous sections, it is possible to either rename
individual declarations or apply a rename rule to all of them at once. In
practice, the latter is however rarely appropriate as there are always some
exceptions to the general rules. To deal with them, the scope of an unnamed
<tt>%rename</tt> can be limited using subsequent <tt>match</tt> parameters.
They can be applied to any of the attributes associated by SWIG with the
declarations appearing in its input. For example:
</p>
<div class="code">
<pre>
%rename("foo", match$name="bar") "";
</pre>
</div>
<p>
can be used to achieve the same effect as the simpler
</p>
<div class="code">
<pre>
%rename("foo") bar;
</pre>
</div>
<p>
and so is not very interesting on its own. However <tt>match</tt> can also be
applied to the declaration type, for example <tt>match="class"</tt> restricts
the match to class declarations only (in C++) and <tt>match="enumitem"</tt>
restricts it to the enum elements. SWIG also provides convenience macros for
such match expressions, for example
</p>
<div class="code">
<pre>
%rename("%(title)s", %$isenumitem) "";
</pre>
</div>
<p>
will capitalize the names of all the enum elements but not change the case of
the other declarations. Similarly, <tt>%$isclass</tt>, <tt>%$isfunction</tt>,
<tt>%$isconstructor</tt>, <tt>%$isunion</tt>, <tt>%$istemplate</tt>,
and <tt>%$isvariable</tt> can be used. Many other checks are possible and this
documentation is not exhaustive, see the "%rename predicates" section in
<tt>swig.swg</tt> for the full list of supported match expressions.
</p>
<p>
In addition to literally matching some string with <tt>match</tt> you can
also use <tt>regexmatch</tt> or <tt>notregexmatch</tt> to match a string
against a regular expression. For example, to ignore all functions having
"Old" as a suffix you could use
</p>
<div class="code">
<pre>
%rename("$ignore", regexmatch$name="Old$") "";
</pre>
</div>
<p>
For simple cases like this, specifying the regular expression for the
declaration name directly can be preferable and can also be done using
<tt>regextarget</tt>:
</p>
<div class="code">
<pre>
%rename("$ignore", regextarget=1) "Old$";
</pre>
</div>
<p>
Notice that the check is done only against the name of the declaration
itself, if you need to match the full name of a C++ declaration you
must use <tt>fullname</tt> attribute:
</p>
<div class="code">
<pre>
%rename("$ignore", regextarget=1, fullname=1) "NameSpace::ClassName::.*Old$";
</pre>
</div>
<p>
As for <tt>notregexmatch</tt>, it restricts the match only to the strings not
matching the specified regular expression. So to rename all declarations to lower case
except those consisting of capital letters only:
</p>
<div class="code">
<pre>
%rename("$(lower)s", notregexmatch$name="^[A-Z]+$") "";
</pre>
</div>
<p>
Finally, variants of <tt>%rename</tt> and <tt>%ignore</tt> directives can be used to help
wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the
<a href="SWIGPlus.html#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section in the C++ chapter.
</p>
<H4><a name="SWIG_chosen_unignore"></a>5.4.7.4 Ignoring everything then wrapping a few selected symbols</H4>
<p>
Using the techniques described above it is possible to ignore everything in a header and then
selectively wrap a few chosen methods or classes. For example, consider a header, <tt>myheader.h</tt>
which has many classes in it and just the one class called <tt>Star</tt> is wanted within this header,
the following approach could be taken:
</p>
<div class="code">
<pre>
%ignore ""; // Ignore everything
// Unignore chosen class 'Star'
%rename("%s") Star;
// As the ignore everything will include the constructor, destructor, methods etc
// in the class, these have to be explicitly unignored too:
%rename("%s") Star::Star;
%rename("%s") Star::~Star;
%rename("%s") Star::shine; // named method
%include "myheader.h"
</pre>
</div>
<p>
Another approach which might be more suitable as it does not require naming all the methods in the
chosen class is to begin by ignoring just the classes. This does not add an explicit ignore to any
members of the class, so when the chosen class is unignored, all of its methods will be wrapped.
</p>
<div class="code">
<pre>
%rename($ignore, %$isclass) ""; // Only ignore all classes
%rename("%s") Star; // Unignore 'Star'
%include "myheader.h"
</pre>
</div>
<H3><a name="SWIG_default_args"></a>5.4.8 Default/optional arguments</H3>
@ -1896,13 +2261,13 @@ normally, just use the original function name such as <tt>add()</tt>.
<p>
SWIG provides a number of extensions to standard C printf formatting
that may be useful in this context. For instance, the following
variation installs the callbacks as all upper-case constants such as
variation installs the callbacks as all upper case constants such as
<tt>ADD</tt>, <tt>SUB</tt>, and <tt>MUL</tt>:
</p>
<div class="code"><pre>
/* Some callback functions */
%callback("%(upper)s");
%callback("%(uppercase)s");
int add(int,int);
int sub(int,int);
int mul(int,int);
@ -1910,7 +2275,7 @@ int mul(int,int);
</pre></div>
<p>
A format string of <tt>"%(lower)s"</tt> converts all characters to lower-case.
A format string of <tt>"%(lowercase)s"</tt> converts all characters to lower case.
A string of <tt>"%(title)s"</tt> capitalizes the first character and converts the
rest to lower case.
</p>
@ -1919,7 +2284,8 @@ rest to lower case.
And now, a final note about function pointer support. Although SWIG
does not normally allow callback functions to be written in the target language, this
can be accomplished with the use of typemaps and other advanced SWIG features.
This is described in a later chapter.
See the <a href="Typemaps.html#Typemaps">Typemaps chapter</a> for more about typemaps
and individual target language chapters for more on callbacks and the 'director' feature.
</p>
<H2><a name="SWIG_nn31"></a>5.5 Structures and unions</H2>
@ -2350,7 +2716,7 @@ You can make a <tt>Vector</tt> look a lot like a class by writing a SWIG interfa
#include "vector.h"
%}
%include vector.h // Just grab original C header file
%include "vector.h" // Just grab original C header file
%extend Vector { // Attach these functions to struct Vector
Vector(double x, double y, double z) {
Vector *v;
@ -2376,6 +2742,10 @@ You can make a <tt>Vector</tt> look a lot like a class by writing a SWIG interfa
<p>
Note the usage of the <tt>$self</tt> special variable.
Its usage is identical to a C++ 'this' pointer and should be used whenever access to the struct instance is required.
Also note that C++ constructor and destructor syntax has been used to simulate a constructor and destructor, even for C code.
There is one subtle difference to a normal C++ constructor implementation though and that is although the constructor declaration
is as per a normal C++ constructor, the newly constructed object must be returned <b>as if</b> the constructor declaration
had a return value, a <tt>Vector *</tt> in this case.
</p>
<p>
@ -2473,7 +2843,7 @@ instead of a method. To do this, you might write some code like this:
// Now supply the implementation of the Vector_magnitude_get function
%{
const double Vector_magnitude_get(Vector *v) {
return (const double) return sqrt(v-&gt;x*v-&gt;x+v-&gt;y*v-&gt;y+v-&gt;z*v-&gt;z);
return (const double) sqrt(v-&gt;x*v-&gt;x+v-&gt;y*v-&gt;y+v-&gt;z*v-&gt;z);
}
%}
@ -2486,41 +2856,53 @@ of the object.
</p>
<p>
A similar technique can also be used to work with problematic data members.
A similar technique can also be used to work with data members that you want to process.
For example, consider this interface:
</p>
<div class="code">
<pre>
struct Person {
char name[50];
...
}
typedef struct {
char name[50];
...
} Person;
</pre>
</div>
<p>
By default, the <tt>name</tt> attribute is read-only because SWIG does not
normally know how to modify arrays. However, you can rewrite the interface
as follows to change this:
Say you wanted to ensure <tt>name</tt> was always upper case, you can rewrite
the interface as follows to ensure this occurs whenever a name is read or written to:
</p>
<div class="code">
<pre>
struct Person {
%extend {
char *name;
}
...
typedef struct {
%extend {
char name[50];
}
...
} Person;
%{
#include &lt;string.h&gt;
#include &lt;ctype.h&gt;
void make_upper(char *name) {
char *c;
for (c = name; *c; ++c)
*c = (char)toupper((int)*c);
}
// Specific implementation of set/get functions
%{
/* Specific implementation of set/get functions forcing capitalization */
char *Person_name_get(Person *p) {
return p-&gt;name;
make_upper(p-&gt;name);
return p-&gt;name;
}
void Person_name_set(Person *p, char *val) {
strncpy(p-&gt;name,val,50);
strncpy(p-&gt;name,val,50);
make_upper(p-&gt;name);
}
%}
</pre>
@ -2530,7 +2912,7 @@ void Person_name_set(Person *p, char *val) {
Finally, it should be stressed that even though <tt>%extend</tt>
can be used to add new data members, these new members can not require
the allocation of additional storage in the object (e.g., their values must
be entirely synthesized from existing attributes of the structure).
be entirely synthesized from existing attributes of the structure or obtained elsewhere).
</p>
<p>
@ -2613,10 +2995,16 @@ $o-&gt;{intRep}-&gt;{ivalue} = 7 # Change value of o.intRep.ivalue
</pre></div>
<p>
If you have a lot nested structure declarations, it is
If you have a lot of nested structure declarations, it is
advisable to double-check them after running SWIG. Although,
there is a good chance that they will work, you may have to
modify the interface file in certain cases.
</p>
<p>
Finally, note that nesting is handled differently in C++ mode,
see <a href="SWIGPlus.html#SWIGPlus_nested_classes">Nested classes</a>.
</p>
<H3><a name="SWIG_nn39"></a>5.5.8 Other things to note about structure wrapping</H3>
@ -2694,12 +3082,17 @@ output of SWIG is structured first.</p>
<p>
When SWIG creates its output file, it is broken up into four sections
When SWIG creates its output file, it is broken up into five sections
corresponding to runtime code, headers, wrapper functions, and module
initialization code (in that order).
</p>
<ul>
<li><b>Begin section</b>. <br>
A placeholder for users to put code at the beginning of the C/C++ wrapper file.
This is most often used to define preprocessor macros that are used in later sections.
</li>
<li><b>Runtime code</b>. <br>
This code is internal to SWIG and is used to include
type-checking and other support functions that are used by the rest of the module.
@ -2726,11 +3119,16 @@ the module upon loading.
<p>
Code is inserted into the appropriate code section by using one
of the following code insertion directives:
of the code insertion directives listed below. The order of the sections in
the wrapper file is as shown:
</p>
<div class="code">
<pre>
%begin %{
... code in begin section ...
%}
%runtime %{
... code in runtime section ...
%}
@ -2751,10 +3149,12 @@ of the following code insertion directives:
<p>
The bare <tt>%{ ... %}</tt> directive is a shortcut that is the same as
<tt>%header %{ ... %}</tt>.
<tt>%header %{ ... %}</tt>.
</p>
<p>
The <tt>%begin</tt> section is effectively empty as it just contains the SWIG banner by default.
This section is provided as a way for users to insert code at the top of the wrapper file before any other code is generated.
Everything in a code insertion block is copied verbatim into the output file and is
not parsed by SWIG. Most SWIG input files have at least one such block to include header
files and support C code. Additional code blocks may be placed anywhere in a
@ -2865,10 +3265,16 @@ interface to your program.
SWIG's <tt>%include</tt> directive to process an entire C
source/header file.
<li>Make sure everything in the interface file uses ANSI C/C++syntax.
<li>Make sure everything in the interface file uses ANSI C/C++ syntax.
<li>Make sure all necessary `<tt>typedef</tt>' declarations and
type-information is available in the interface file.
type-information is available in the interface file.
In particular, ensure that the type information is specified in the correct order as required by a C/C++ compiler.
Most importantly, define a type before it is used! A C compiler will tell you
if the full type information is not available if it is needed, whereas
SWIG will usually not warn or error out as it is designed to work without
full type information. However, if type information is not specified
correctly, the wrappers can be sub-optimal and even result in uncompileable C/C++ code.
<li>If your program has a main() function, you may need to rename it
(read on).
@ -2927,16 +3333,21 @@ extern void dump(FILE *f);
<p>
Of course, in this case, our header file is pretty simple so we could
have made an interface file like this as well:</p>
use a simpler approach and use an interface file like this:</p>
<div class="code"><pre>
/* File : interface.i */
%module mymodule
%include header.h
%{
#include "header.h"
%}
%include "header.h"
</pre></div>
<p>
Naturally, your mileage may vary.</p>
The main advantage of this approach is minimal maintenance of an interface file for when the header file changes in the future.
In more complex projects, an interface file containing numerous <tt>%include</tt> and <tt>#include</tt> statements like this is one of the most common approaches to interface file design due to lower maintenance overhead.
</p>
<H3><a name="SWIG_nn48"></a>5.7.3 Why use separate interface files?</H3>

View file

@ -42,21 +42,25 @@
<ul>
<li><a href="#SWIGPlus_nn24">Dispatch function generation</a>
<li><a href="#SWIGPlus_nn25">Ambiguity in Overloading</a>
<li><a href="#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
<li><a href="#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a>
<li><a href="#SWIGPlus_nn27">Comments on overloading</a>
</ul>
<li><a href="#SWIGPlus_nn28">Wrapping overloaded operators</a>
<li><a href="#SWIGPlus_class_extension">Class extension</a>
<li><a href="#SWIGPlus_nn30">Templates</a>
<li><a href="#SWIGPlus_nn31">Namespaces</a>
<li><a href="#SWIGPlus_namespaces">Namespaces</a>
<ul>
<li><a href="#SWIGPlus_nspace">The nspace feature for namespaces</a>
</ul>
<li><a href="#SWIGPlus_renaming_templated_types_namespaces">Renaming templated types in namespaces</a>
<li><a href="#SWIGPlus_exception_specifications">Exception specifications</a>
<li><a href="#SWIGPlus_catches">Exception handling with %catches</a>
<li><a href="#SWIGPlus_nn33">Pointers to Members</a>
<li><a href="#SWIGPlus_nn34">Smart pointers and operator-&gt;()</a>
<li><a href="#SWIGPlus_smart_pointers">Smart pointers and operator-&gt;()</a>
<li><a href="#SWIGPlus_ref_unref">C++ reference counted objects - ref/unref feature</a>
<li><a href="#SWIGPlus_nn35">Using declarations and inheritance</a>
<li><a href="#SWIGPlus_nested_classes">Nested classes</a>
<li><a href="#SWIGPlus_nn37">A brief rant about const-correctness</a>
<li><a href="#SWIGPlus_const">A brief rant about const-correctness</a>
<li><a href="#SWIGPlus_nn42">Where to go for more information</a>
</ul>
</div>
@ -1125,7 +1129,7 @@ For example if a method has ten default arguments, then eleven wrapper methods a
<p>
Please see the <a href="Customization.html#Customization_features_default_args">Features and default arguments</a>
section for more information on using <tt>%feature</tt> with functions with default arguments.
The <a href="#ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section
The <a href="#SWIGPlus_ambiguity_resolution_renaming">Ambiguity resolution and renaming</a> section
also deals with using <tt>%rename</tt> and <tt>%ignore</tt> on methods with default arguments.
If you are writing your own typemaps for types used in methods with default arguments, you may also need to write a <tt>typecheck</tt> typemap.
See the <a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a> section for details or otherwise
@ -1616,7 +1620,7 @@ warning message like this:
<div class="shell">
<pre>
example.i:18: Warning(401): Nothing known about base class 'Foo'. Ignored.
example.i:18: Warning 401: Nothing known about base class 'Foo'. Ignored.
</pre>
</div>
@ -2031,7 +2035,8 @@ Therefore, when SWIG encounters this situation, it may generate a warning messag
<div class="shell">
<pre>
example.i:4: Warning(509): Overloaded foo(long) is shadowed by foo(int) at example.i:3.
example.i:4: Warning 509: Overloaded method foo(long) effectively ignored,
example.i:3: Warning 509: as it is shadowed by foo(int).
</pre>
</div>
@ -2041,7 +2046,8 @@ or for statically typed languages like Java:
<div class="shell">
<pre>
example.i:4: Warning(516): Overloaded method foo(long) ignored. Method foo(int)
example.i:4: Warning 516: Overloaded method foo(long) ignored,
example.i:3: Warning 516: using foo(int) instead.
at example.i:3 used.
</pre>
</div>
@ -2091,7 +2097,7 @@ When wrapping an overloaded function, there is a chance that you will get an err
<div class="shell">
<pre>
example.i:3: Warning(467): Overloaded foo(int) not supported (no type checking
example.i:3: Warning 467: Overloaded foo(int) not supported (no type checking
rule for 'int').
</pre>
</div>
@ -2122,7 +2128,7 @@ it means that the target language module has not yet implemented support for ove
functions and methods. The only way to fix the problem is to read the next section.
</p>
<H3><a name="ambiguity_resolution_renaming"></a>6.15.3 Ambiguity resolution and renaming</H3>
<H3><a name="SWIGPlus_ambiguity_resolution_renaming"></a>6.15.3 Ambiguity resolution and renaming</H3>
<p>
@ -3246,22 +3252,39 @@ public:
</div>
<p>
SWIG should be able to handle most simple uses of partial specialization. However, it may fail
to match templates properly in more complicated cases. For example, if you have this code,
SWIG supports both template explicit specialization and partial specialization. Consider:
</p>
<div class="code">
<pre>
template&lt;class T1, class T2&gt; class Foo&lt;T1, T2 *&gt; { };
template&lt;class T1, class T2&gt; class Foo { }; // (1) primary template
template&lt;&gt; class Foo&lt;double *, int *&gt; { }; // (2) explicit specialization
template&lt;class T1, class T2&gt; class Foo&lt;T1, T2 *&gt; { }; // (3) partial specialization
</pre>
</div>
<p>
SWIG isn't able to match it properly for instantiations like <tt>Foo&lt;int *, int *&gt;</tt>.
This problem is not due to parsing, but due to the fact that SWIG does not currently implement all
of the C++ argument deduction rules.
SWIG is able to properly match explicit instantiations:
</p>
<div class="code">
<pre>
<tt>Foo&lt;double *, int *&gt;</tt> // explicit specialization matching (2)
</pre>
</div>
<p>
SWIG implements template argument deduction so that the following partial specialization examples work just like they would with a C++ compiler:
</p>
<div class="code">
<pre>
<tt>Foo&lt;int *, int *&gt;</tt> // partial specialization matching (3)
<tt>Foo&lt;int *, const int *&gt;</tt> // partial specialization matching (3)
<tt>Foo&lt;int *, int **&gt;</tt> // partial specialization matching (3)
</pre>
</div>
<p>
Member function templates are supported. The underlying principle is the same
as for normal templates--SWIG can't create a wrapper unless you provide
@ -3334,7 +3357,7 @@ public:
<p>
In this case, the <tt>%extend</tt> directive is not needed, and
<tt>%template</tt> does the exactly same job, i.e., it adds two new
<tt>%template</tt> does exactly the same job, i.e., it adds two new
methods to the Foo class.
</p>
@ -3471,7 +3494,7 @@ instead:
<p>
In this case, the default and conversion constructors have the same
name. Hence, Swig will overload them and define an unique visible
name. Hence, SWIG will overload them and define an unique visible
constructor, that will dispatch the proper call depending on the argument
type.
</p>
@ -3628,12 +3651,16 @@ as the class name. For example:
Similar changes apply to typemaps and other customization features.
</p>
<H2><a name="SWIGPlus_nn31"></a>6.19 Namespaces</H2>
<H2><a name="SWIGPlus_namespaces"></a>6.19 Namespaces</H2>
<p>
Support for C++ namespaces is a relatively late addition to SWIG,
first appearing in SWIG-1.3.12. Before describing the implementation,
Support for C++ namespaces is comprehensive, but by default simple, however,
some target languages can turn on more advanced namespace support via the
<a href="#SWIGPlus_nspace">nspace feature</a>, described later.
Code within unnamed namespaces is ignored as there is no external
access to symbols declared within the unnamed namespace.
Before detailing the default implementation for named namespaces,
it is worth noting that the semantics of C++ namespaces is extremely
non-trivial--especially with regard to the C++ type system and class
machinery. At a most basic level, namespaces are sometimes used to
@ -3817,7 +3844,7 @@ When this conflict occurs, you will get an error message that resembles this:
<div class="shell">
<pre>
example.i:26. Error. 'foo' is multiply defined in the generated module.
example.i:26. Error. 'foo' is multiply defined in the generated target language module.
example.i:23. Previous declaration of 'foo'
</pre>
</div>
@ -4073,6 +4100,87 @@ with any namespace awareness. In the future, language modules may or may not p
more advanced namespace support.
</p>
<H3><a name="SWIGPlus_nspace"></a>6.19.1 The nspace feature for namespaces</H3>
<p>
Some target languages provide support for the <tt>nspace</tt> <a href="Customization.html#Customization_features">feature</a>.
The feature can be applied to any class, struct, union or enum declared within a named namespace.
The feature wraps the type within the target language specific concept of a namespace,
for example, a Java package or C# namespace.
Please see the language specific sections to see if the target language you are interested in supports the nspace feature.
</p>
<p>
The feature is demonstrated below for C# using the following example:
</p>
<div class="code">
<pre>
%feature("nspace") MyWorld::Material::Color;
%nspace MyWorld::Wrapping::Color; // %nspace is a macro for %feature("nspace")
namespace MyWorld {
namespace Material {
class Color {
...
};
}
namespace Wrapping {
class Color {
...
};
}
}
</pre>
</div>
<p>
Without the <tt>nspace</tt> feature directives above or <tt>%rename</tt>, you would get the following warning resulting in just one of the <tt>Color</tt> classes being available for use from the target language:
</p>
<div class="shell">
<pre>
example.i:9: Error: 'Color' is multiply defined in the generated target language module.
example.i:5: Error: Previous declaration of 'Color'
</pre>
</div>
<p>
With the <tt>nspace</tt> feature the two <tt>Color</tt> classes are wrapped into the equivalent C# namespaces.
A fully qualified constructor call of each these two types in C# is then:
</p>
<div class="targetlang">
<pre>
MyWorld.Material.Color materialColor = new MyWorld.Material.Color();
MyWorld.Wrapping.Color wrappingColor = new MyWorld.Wrapping.Color();
</pre>
</div>
<p>
Note that the <tt>nspace</tt> feature does not apply to variables and functions simply declared in a namespace. For example, the following symbols cannot co-exist in the target language without renaming. This may change in a future version.
</p>
<div class="code">
<pre>
namespace MyWorld {
namespace Material {
int quantity;
void dispatch();
}
namespace Wrapping {
int quantity;
void dispatch();
}
}
</pre>
</div>
<p>
<b>Compatibility Note:</b> The nspace feature was first introduced in SWIG-2.0.0.
</p>
<H2><a name="SWIGPlus_renaming_templated_types_namespaces"></a>6.20 Renaming templated types in namespaces</H2>
@ -4085,8 +4193,9 @@ In the example below, the generic template type is used to rename to <tt>bbb</tt
<div class="code">
<pre>
%rename(bbb) Space::ABC::aaa(T t); // will match but with lower precedence than ccc
%rename(ccc) Space::ABC&lt;Space::XYZ&gt;::aaa(Space::XYZ t); // will match but with higher precedence than bbb
%rename(bbb) Space::ABC::aaa(T t); // will match but with lower precedence than ccc
%rename(ccc) Space::ABC&lt;Space::XYZ&gt;::aaa(Space::XYZ t);// will match but with higher precedence
// than bbb
namespace Space {
class XYZ {};
@ -4107,9 +4216,9 @@ Below shows how %rename can be placed inside a namespace.
<div class="code">
<pre>
namespace Space {
%rename(bbb) ABC::aaa(T t); // will match but with lower precedence than ccc
%rename(ccc) ABC&lt;Space::XYZ&gt;::aaa(Space::XYZ t); // will match but with higher precedence than bbb
%rename(ddd) ABC&lt;Space::XYZ&gt;::aaa(XYZ t); // will not match
%rename(bbb) ABC::aaa(T t); // will match but with lower precedence than ccc
%rename(ccc) ABC&lt;Space::XYZ&gt;::aaa(Space::XYZ t);// will match but with higher precedence than bbb
%rename(ddd) ABC&lt;Space::XYZ&gt;::aaa(XYZ t); // will not match
}
namespace Space {
@ -4131,11 +4240,11 @@ The following example shows how %rename can be placed within %extend.
<pre>
namespace Space {
%extend ABC {
%rename(bbb) aaa(T t); // will match but with lower precedence than ccc
%rename(bbb) aaa(T t); // will match but with lower precedence than ccc
}
%extend ABC&lt;Space::XYZ&gt; {
%rename(ccc) aaa(Space::XYZ t); // will match but with higher precedence than bbb
%rename(ddd) aaa(XYZ t); // will not match
%rename(ccc) aaa(Space::XYZ t);// will match but with higher precedence than bbb
%rename(ddd) aaa(XYZ t); // will not match
}
}
@ -4197,7 +4306,7 @@ is outlined in the <a href="Typemaps.html#throws_typemap">"throws" typemap</a> s
<p>
Since exception specifications are sometimes only used sparingly, this alone may not be enough to
properly handle C++ exceptions. To do that, a different set of special SWIG directives are used.
Consult the "<a href="Customization.html#exception">Exception handling with %exception</a>" section for details.
Consult the "<a href="Customization.html#Customization_exception">Exception handling with %exception</a>" section for details.
The next section details a way of simulating an exception specification or replacing an existing one.
</p>
@ -4301,7 +4410,7 @@ when checking types. However, no such support is currently provided
for member pointers.
</p>
<H2><a name="SWIGPlus_nn34"></a>6.24 Smart pointers and operator-&gt;()</H2>
<H2><a name="SWIGPlus_smart_pointers"></a>6.24 Smart pointers and operator-&gt;()</H2>
<p>
@ -4510,8 +4619,179 @@ p = f.__deref__() # Raw pointer from operator-&gt;
<b>Note:</b> Smart pointer support was first added in SWIG-1.3.14.
</p>
<H2><a name="SWIGPlus_ref_unref"></a>6.25 C++ reference counted objects - ref/unref feature</H2>
<H2><a name="SWIGPlus_nn35"></a>6.25 Using declarations and inheritance</H2>
<p>
Another similar idiom in C++ is the use of reference counted objects. Consider for example:
<div class="code">
<pre>
class RCObj {
// implement the ref counting mechanism
int add_ref();
int del_ref();
int ref_count();
public:
virtual ~RCObj() = 0;
int ref() const {
return add_ref();
}
int unref() const {
if (ref_count() == 0 || del_ref() == 0 ) {
delete this;
return 0;
}
return ref_count();
}
};
class A : RCObj {
public:
A();
int foo();
};
class B {
A *_a;
public:
B(A *a) : _a(a) {
a-&gt;ref();
}
~B() {
a-&gt;unref();
}
};
int main() {
A *a = new A(); // (count: 0)
a-&gt;ref(); // 'a' ref here (count: 1)
B *b1 = new B(a); // 'a' ref here (count: 2)
if (1 + 1 == 2) {
B *b2 = new B(a); // 'a' ref here (count: 3)
delete b2; // 'a' unref, but not deleted (count: 2)
}
delete b1; // 'a' unref, but not deleted (count: 1)
a-&gt;unref(); // 'a' unref and deleted (count: 0)
}
</pre>
</div>
<p>
In the example above, the 'A' class instance 'a' is a reference counted
object, which can't be deleted arbitrarily since it is shared between
the objects 'b1' and 'b2'. 'A' is derived from a <i>Reference Counted
Object</i> 'RCObj', which implements the ref/unref idiom.
</p>
<p>
To tell SWIG that 'RCObj' and all its derived classes are reference
counted objects, use the "ref" and "unref" <a href="Customization.html#Customization_features">features</a>.
These are also available as <tt>%refobject</tt> and <tt>%unrefobject</tt>, respectively.
For example:
</p>
<div class="code">
<pre>
%module example
...
%feature("ref") RCObj "$this-&gt;ref();"
%feature("unref") RCObj "$this-&gt;unref();"
%include "rcobj.h"
%include "A.h"
...
</pre>
</div>
<p>
where the code passed to the "ref" and "unref" features will be
executed as needed whenever a new object is passed to python, or when
python tries to release the proxy object instance, respectively.
</p>
<p>
On the python side, the use of a reference counted object is no
different to any other regular instance:
</p>
<div class="targetlang">
<pre>
def create_A():
a = A() # SWIG ref 'a' - new object is passed to python (count: 1)
b1 = B(a) # C++ ref 'a (count: 2)
if 1 + 1 == 2:
b2 = B(a) # C++ ref 'a' (count: 3)
return a # 'b1' and 'b2' are released and deleted, C++ unref 'a' twice (count: 1)
a = create_A() # (count: 1)
exit # 'a' is released, SWIG unref 'a' called in the destructor wrapper (count: 0)
</pre>
</div>
<p>
Note that the user doesn't explicitly need to call 'a-&gt;ref()' nor 'a-&gt;unref()'
(and neither 'delete a'). Instead, SWIG takes cares of executing the "ref"
and "unref" calls as needed. If the user doesn't specify the
"ref/unref" feature for a type, SWIG will produce code equivalent to defining these
features:
</p>
<div class="code">
<pre>
%feature("ref") ""
%feature("unref") "delete $this;"
</pre>
</div>
<p>
In other words, SWIG will not do anything special when a new object
is passed to python, and it will always 'delete' the underlying object when
python releases the proxy instance.
</p>
<p>
The <a href="Customization.html#Customization_ownership">%newobject feature</a> is designed to indicate to
the target language that it should take ownership of the returned object.
When used in conjunction with a type that has the "ref" feature associated with it, it additionally emits the
code in the "ref" feature into the C++ wrapper.
Consider wrapping the following factory function in addition to the above:
</p>
<div class="code">
<pre>
%newobject AFactory;
A *AFactory() {
return new A();
}
</pre>
</div>
<p>
The <tt>AFactory</tt> function now acts much like a call to the <tt>A</tt> constructor with respect to memory handling:
</p>
<div class="targetlang">
<pre>
a = AFactory() # SWIG ref 'a' due to %newobject (count: 1)
exit # 'a' is released, SWIG unref 'a' called in the destructor wrapper (count: 0)
</pre>
</div>
<H2><a name="SWIGPlus_nn35"></a>6.26 Using declarations and inheritance</H2>
<p>
@ -4674,41 +4954,54 @@ public:
</div>
</ul>
<H2><a name="SWIGPlus_nested_classes"></a>6.26 Nested classes</H2>
<H2><a name="SWIGPlus_nested_classes"></a>6.27 Nested classes</H2>
<p>
There is limited support for nested structs and unions when wrapping C code, see <a href="SWIG.html#SWIG_nested_structs">Nested structures</a> for further details.
However, there is no nested class/struct/union support when wrapping C++ code (using the -c++ commandline option).
This may be added at a future date, however, until then some of the following workarounds can be applied.
There is some support for nested structs and unions when wrapping C code,
see <a href="SWIG.html#SWIG_nested_structs">Nested structures</a> for further details.
The added complexity of C++ compared to C means this approach does not work well for
C++ code (when using the -c++ command line option).
For C++, a nested class is treated much like an opaque pointer, so anything useful within the nested class, such as its
methods and variables, are not accessible from the target language.
True nested class support may be added to SWIG in the future, however,
until then some of the following workarounds can be applied to improve the situation.
</p>
<p>
It might be possible to use partial class information. Since
SWIG does not need the entire class specification to work, conditional
compilation can be used to comment out the problematic nested class definition, you might do this:
It might be possible to use partial class information as often you can accept that the nested class is not needed,
especially if it is not actually used in any methods you need from the target language.
Imagine you are wrapping the following <tt>Outer</tt> class which contains a nested class <tt>Inner</tt>.
The easiest thing to do is turn a blind eye to the warning that SWIG generates, or simply suppress it:
</p>
<div class="code">
<pre>
class Foo {
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner;
class Outer {
public:
#ifndef SWIG
class Bar {
public:
...
};
#endif
Foo();
~Foo();
...
class Inner {
public:
...
};
Inner getInner();
void useInner(const Inner&amp; inner);
...
};
</pre>
</div>
<p>
The next workaround assumes you cannot modify the source code as was done above and it provides a solution for methods that use nested class types.
Imagine we are wrapping the <tt>Outer</tt> class which contains a nested class <tt>Inner</tt>:
Note that if <tt>Inner</tt> can be used as an opaque type, the default wrapping approach suffices.
For example, if the nested class does not need to be created from the target language, but can be obtained via a method
call, such as the <tt>getInner()</tt> method above, the returned value can then be passed around, such as passed into the
<tt>useInner()</tt> method.
</p>
<p>
With some more effort the above situation can be improved somewhat and a nested class can be constructed and used
from the target language much like any other non-nested class. Assuming we have the <tt>Outer</tt> class in a header file:
</p>
<div class="code">
@ -4721,14 +5014,18 @@ public:
int var;
Inner(int v = 0) : var(v) {}
};
void method(Inner inner);
Inner getInner();
void useInner(const Inner&amp; inner);
};
</pre>
</div>
<p>
The following interface file works around SWIG nested class limitations by redefining the nested class as a global class.
A typedef for the compiler is also required in order for the generated wrappers to compile.
The following interface file works around the nested class limitations by redefining the nested class as a global class.
A typedef for the compiler and the <tt>nestedworkaround</tt>
<a href="Customization.html#Customization_feature_flags">feature flag</a> is also required in
order for the generated wrappers to compile. This flag simply removes all the type information from SWIG, so SWIG treats
the nested class as if it had not been parsed at all.
</p>
<div class="code">
@ -4736,9 +5033,6 @@ A typedef for the compiler is also required in order for the generated wrappers
// File : example.i
%module example
// Suppress SWIG warning
#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
// Redefine nested class in global scope in order for SWIG to generate
// a proxy class. Only SWIG parses this definition.
class Inner {
@ -4747,25 +5041,64 @@ class Inner {
Inner(int v = 0) : var(v) {}
};
%nestedworkaround Outer::Inner;
%{
#include "outer.h"
%}
%include "outer.h"
// We've fooled SWIG into thinking that Inner is a global class, so now we need
// to trick the C++ compiler into understanding this apparent global type.
%{
// SWIG thinks that Inner is a global class, so we need to trick the C++
// compiler into understanding this so called global type.
typedef Outer::Inner Inner;
%}
</pre>
</div>
<p>
The downside to this approach is having to maintain two definitions of <tt>Inner</tt>, the real one and the one in the interface file that SWIG parses.
The downside to this approach is a more complex interface file and having to maintain two definitions of <tt>Inner</tt>,
the real one and the one in the interface file that SWIG parses.
However, the upside is that all the methods/variables in the nested class are available from the target language
as a proxy class is generated instead of treating the nested class as an opaque type.
The proxy class can be constructed from the target language and passed into any methods accepting the nested class.
Also note that the original header file is parsed unmodified.
</p>
<H2><a name="SWIGPlus_nn37"></a>6.27 A brief rant about const-correctness</H2>
<p>
Finally, conditional compilation can be used as a workaround to comment out nested class definitions in the actual headers,
assuming you are able to modify them.
</p>
<div class="code">
<pre>
// File outer.h
class Outer {
public:
#ifndef SWIG
class Inner {
public:
...
};
#endif
...
};
</pre>
</div>
<p>
This workaround used to be common when SWIG could not deal with nested classes particulary well.
This should just be a last resort for unusual corner cases now as SWIG can parse nested classes and even handle nested template classes fairly well.
</p>
<p>
<b>Compatibility Note:</b> SWIG-1.3.40 and earlier versions did not have the <tt>nestedworkaround</tt> feature
and the generated code resulting from parsing nested classes did not always compile.
Nested class warnings could also not be suppressed using %warnfilter.
</p>
<H2><a name="SWIGPlus_const"></a>6.28 A brief rant about const-correctness</H2>
<p>
@ -4823,7 +5156,7 @@ using another tool if maintaining constness is the most important part
of your project.
</p>
<H2><a name="SWIGPlus_nn42"></a>6.28 Where to go for more information</H2>
<H2><a name="SWIGPlus_nn42"></a>6.29 Where to go for more information</H2>
<p>

View file

@ -1,23 +1,15 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG-1.3 Documentation</title>
<title>SWIG-2.0 Documentation</title>
</head>
<body bgcolor="#ffffff">
<H1><a name="Sections"></a>SWIG-1.3 Development Documentation</H1>
<H1><a name="Sections"></a>SWIG-2.0 Documentation</H1>
Last update : SWIG-2.0.0 (in progress)
Last update : SWIG-2.0.6 (in progress)
<H2>Sections</H2>
<p>
The SWIG documentation is being updated to reflect new SWIG
features and enhancements. However, this update process is not quite
finished--there is a lot of old SWIG-1.1 documentation and it is taking
some time to update all of it. Please pardon our dust (or volunteer
to help!).
</p>
<H3>SWIG Core Documentation</H3>
<ul>
<li><a href="Preface.html#Preface">Preface</a></li>
@ -27,7 +19,7 @@ to help!).
<li><a href="SWIG.html#SWIG">SWIG Basics</a> (Read this!)</li>
<li><a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a></li>
<li><a href="Preprocessor.html#Preprocessor">The SWIG preprocessor</a></li>
<li><a href="Library.html#Library">The SWIG Library</a></li>
<li><a href="Library.html#Library">The SWIG library</a></li>
<li><a href="Arguments.html#Arguments">Argument handling</a></li>
<li><a href="Typemaps.html#Typemaps">Typemaps</a></li>
<li><a href="Customization.html#Customization">Customization features</a></li>
@ -35,28 +27,32 @@ to help!).
<li><a href="Varargs.html#Varargs">Variable length arguments</a></li>
<li><a href="Warnings.html#Warnings">Warning messages</a></li>
<li><a href="Modules.html#Modules">Working with Modules</a></li>
<li><a href="CCache.html#CCache">Using SWIG with ccache</a></li>
</ul>
<H3>Language Module Documentation</H3>
<ul>
<li><a href="Allegrocl.html#Allegrocl_nn1">Allegro CL support</a></li>
<li><a href="Allegrocl.html#Allegrocl">Allegro Common Lisp support</a></li>
<li><a href="Android.html#Android">Android support</a></li>
<li><a href="CSharp.html#CSharp">C# support</a></li>
<li><a href="Chicken.html#Chicken">Chicken support</a></li>
<li><a href="D.html#D">D support</a></li>
<li><a href="Go.html#Go">Go support</a></li>
<li><a href="Guile.html#Guile">Guile support</a></li>
<li><a href="Java.html#Java">Java support</a></li>
<li><a href="Lua.html#Lua_nn1">Lua support</a></li>
<li><a href="Lisp.html#Lisp_nn1">Common Lisp support</a></li>
<li><a href="Lisp.html#Lisp">Common Lisp support</a></li>
<li><a href="Lua.html#Lua">Lua support</a></li>
<li><a href="Modula3.html#Modula3">Modula3 support</a></li>
<li><a href="Mzscheme.html#MzScheme">MzScheme support</a></li>
<li><a href="Mzscheme.html#Mzscheme">MzScheme/Racket support</a></li>
<li><a href="Ocaml.html#Ocaml">Ocaml support</a></li>
<li><a href="Octave.html#Octave">Octave support</a></li>
<li><a href="Perl5.html#Perl5">Perl5 support</a></li>
<li><a href="Php.html#Php">PHP support</a></li>
<li><a href="Pike.html#Pike">Pike support</a></li>
<li><a href="Python.html#Python">Python support</a></li>
<li><a href="Ruby.html#Ruby">Ruby support</a></li>
<li><a href="R.html#R">R support</a></li>
<li><a href="Ruby.html#Ruby">Ruby support</a></li>
<li><a href="Tcl.html#Tcl">Tcl support</a></li>
</ul>
@ -66,20 +62,5 @@ to help!).
<li><a href="Extending.html#Extending">Extending SWIG</a></li>
</ul>
<H3>Documentation that has not yet been updated</H3>
<p>
This documentation has not been completely updated from SWIG-1.1, but most of the topics
still apply to the current release. Make sure you read the
<a href="SWIG.html#SWIG">SWIG Basics</a> chapter before reading
any of these chapters. Also, SWIG-1.3.10 features extensive changes to the
implementation of typemaps. Make sure you read the <a href="Typemaps.html#Typemaps">Typemaps</a>
chapter above if you are using this feature.
</p>
<ul>
<li><a href="Advanced.html#Advanced">Advanced topics</a> (see <a href="Modules.html#Modules">Modules</a> for updated information).</li>
</ul>
</body>
</html>

View file

@ -6,7 +6,7 @@
</head>
<body bgcolor="#ffffff">
<H1><a name="Tcl"></a>32 SWIG and Tcl</H1>
<H1><a name="Tcl"></a>37 SWIG and Tcl</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
@ -66,6 +66,7 @@
<ul>
<li><a href="#Tcl_nn45">Proxy classes</a>
</ul>
<li><a href="#Tcl_nn46">Tcl/Tk Stubs</a>
</ul>
</div>
<!-- INDEX -->
@ -82,7 +83,7 @@ Tcl 8.0 or a later release. Earlier releases of SWIG supported Tcl 7.x, but
this is no longer supported.
</p>
<H2><a name="Tcl_nn2"></a>32.1 Preliminaries</H2>
<H2><a name="Tcl_nn2"></a>37.1 Preliminaries</H2>
<p>
@ -108,7 +109,7 @@ build a Tcl extension module. To finish building the module, you
need to compile this file and link it with the rest of your program.
</p>
<H3><a name="Tcl_nn3"></a>32.1.1 Getting the right header files</H3>
<H3><a name="Tcl_nn3"></a>37.1.1 Getting the right header files</H3>
<p>
@ -126,7 +127,7 @@ this is the case, you should probably make a symbolic link so that <tt>tcl.h</tt
header file.
</p>
<H3><a name="Tcl_nn4"></a>32.1.2 Compiling a dynamic module</H3>
<H3><a name="Tcl_nn4"></a>37.1.2 Compiling a dynamic module</H3>
<p>
@ -161,7 +162,7 @@ The name of the module is specified using the <tt>%module</tt> directive or the
<tt> -module</tt> command line option.
</p>
<H3><a name="Tcl_nn5"></a>32.1.3 Static linking</H3>
<H3><a name="Tcl_nn5"></a>37.1.3 Static linking</H3>
<p>
@ -190,7 +191,7 @@ extern int mod(int, int);
extern double My_variable;
%}
%include tclsh.i // Include code for rebuilding tclsh
%include "tclsh.i" // Include code for rebuilding tclsh
</pre></div>
@ -227,7 +228,7 @@ minimal in most situations (and quite frankly not worth the extra
hassle in the opinion of this author).
</p>
<H3><a name="Tcl_nn6"></a>32.1.4 Using your module</H3>
<H3><a name="Tcl_nn6"></a>37.1.4 Using your module</H3>
<p>
@ -355,7 +356,7 @@ to the default system configuration (this requires root access and you will need
the man pages).
</p>
<H3><a name="Tcl_nn7"></a>32.1.5 Compilation of C++ extensions</H3>
<H3><a name="Tcl_nn7"></a>37.1.5 Compilation of C++ extensions</H3>
<p>
@ -438,7 +439,7 @@ erratic program behavior. If working with lots of software components, you
might want to investigate using a more formal standard such as COM.
</p>
<H3><a name="Tcl_nn8"></a>32.1.6 Compiling for 64-bit platforms</H3>
<H3><a name="Tcl_nn8"></a>37.1.6 Compiling for 64-bit platforms</H3>
<p>
@ -465,7 +466,7 @@ also introduce problems on platforms that support more than one
linking standard (e.g., -o32 and -n32 on Irix).
</p>
<H3><a name="Tcl_nn9"></a>32.1.7 Setting a package prefix</H3>
<H3><a name="Tcl_nn9"></a>37.1.7 Setting a package prefix</H3>
<p>
@ -484,7 +485,7 @@ option will append the prefix to the name when creating a command and
call it "<tt>Foo_bar</tt>".
</p>
<H3><a name="Tcl_nn10"></a>32.1.8 Using namespaces</H3>
<H3><a name="Tcl_nn10"></a>37.1.8 Using namespaces</H3>
<p>
@ -506,7 +507,7 @@ When the<tt> -namespace</tt> option is used, objects in the module
are always accessed with the namespace name such as <tt>Foo::bar</tt>.
</p>
<H2><a name="Tcl_nn11"></a>32.2 Building Tcl/Tk Extensions under Windows 95/NT</H2>
<H2><a name="Tcl_nn11"></a>37.2 Building Tcl/Tk Extensions under Windows 95/NT</H2>
<p>
@ -517,7 +518,7 @@ covers the process of using SWIG with Microsoft Visual C++.
although the procedure may be similar with other compilers.
</p>
<H3><a name="Tcl_nn12"></a>32.2.1 Running SWIG from Developer Studio</H3>
<H3><a name="Tcl_nn12"></a>37.2.1 Running SWIG from Developer Studio</H3>
<p>
@ -575,7 +576,7 @@ MSDOS &gt; tclsh80
%
</pre></div>
<H3><a name="Tcl_nn13"></a>32.2.2 Using NMAKE</H3>
<H3><a name="Tcl_nn13"></a>37.2.2 Using NMAKE</H3>
<p>
@ -638,7 +639,7 @@ to get you started. With a little practice, you'll be making lots of
Tcl extensions.
</p>
<H2><a name="Tcl_nn14"></a>32.3 A tour of basic C/C++ wrapping</H2>
<H2><a name="Tcl_nn14"></a>37.3 A tour of basic C/C++ wrapping</H2>
<p>
@ -649,7 +650,7 @@ classes. This section briefly covers the essential aspects of this
wrapping.
</p>
<H3><a name="Tcl_nn15"></a>32.3.1 Modules</H3>
<H3><a name="Tcl_nn15"></a>37.3.1 Modules</H3>
<p>
@ -683,7 +684,7 @@ To fix this, supply an extra argument to <tt>load</tt> like this:
</pre>
</div>
<H3><a name="Tcl_nn16"></a>32.3.2 Functions</H3>
<H3><a name="Tcl_nn16"></a>37.3.2 Functions</H3>
<p>
@ -708,7 +709,7 @@ like you think it does:
%
</pre></div>
<H3><a name="Tcl_nn17"></a>32.3.3 Global variables</H3>
<H3><a name="Tcl_nn17"></a>37.3.3 Global variables</H3>
<p>
@ -788,7 +789,7 @@ extern char *path; // Read-only (due to %immutable)
</pre>
</div>
<H3><a name="Tcl_nn18"></a>32.3.4 Constants and enums</H3>
<H3><a name="Tcl_nn18"></a>37.3.4 Constants and enums</H3>
<p>
@ -872,7 +873,7 @@ When an identifier name is given, it is used to perform an implicit hash-table l
conversion. This allows the <tt>global</tt> statement to be omitted.
</p>
<H3><a name="Tcl_nn19"></a>32.3.5 Pointers</H3>
<H3><a name="Tcl_nn19"></a>37.3.5 Pointers</H3>
<p>
@ -968,7 +969,7 @@ C-style cast may return a bogus result whereas as the C++-style cast will return
<tt>None</tt> if the conversion can't be performed.
</p>
<H3><a name="Tcl_nn20"></a>32.3.6 Structures</H3>
<H3><a name="Tcl_nn20"></a>37.3.6 Structures</H3>
<p>
@ -1250,7 +1251,7 @@ Note: Tcl only destroys the underlying object if it has ownership. See the
memory management section that appears shortly.
</p>
<H3><a name="Tcl_nn21"></a>32.3.7 C++ classes</H3>
<H3><a name="Tcl_nn21"></a>37.3.7 C++ classes</H3>
<p>
@ -1317,7 +1318,7 @@ In Tcl, the static member is accessed as follows:
</pre>
</div>
<H3><a name="Tcl_nn22"></a>32.3.8 C++ inheritance</H3>
<H3><a name="Tcl_nn22"></a>37.3.8 C++ inheritance</H3>
<p>
@ -1366,7 +1367,7 @@ For instance:
It is safe to use multiple inheritance with SWIG.
</p>
<H3><a name="Tcl_nn23"></a>32.3.9 Pointers, references, values, and arrays</H3>
<H3><a name="Tcl_nn23"></a>37.3.9 Pointers, references, values, and arrays</H3>
<p>
@ -1420,7 +1421,7 @@ to hold the result and a pointer is returned (Tcl will release this memory
when the return value is garbage collected).
</p>
<H3><a name="Tcl_nn24"></a>32.3.10 C++ overloaded functions</H3>
<H3><a name="Tcl_nn24"></a>37.3.10 C++ overloaded functions</H3>
<p>
@ -1501,8 +1502,8 @@ If declarations such as these appear, you will get a warning message like this:
<div class="code">
<pre>
example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int)
at example.i:11.
example.i:12: Warning 509: Overloaded method spam(short) effectively ignored,
example.i:11: Warning 509: as it is shadowed by spam(int).
</pre>
</div>
@ -1543,7 +1544,7 @@ first declaration takes precedence.
Please refer to the "SWIG and C++" chapter for more information about overloading.
</p>
<H3><a name="Tcl_nn25"></a>32.3.11 C++ operators</H3>
<H3><a name="Tcl_nn25"></a>37.3.11 C++ operators</H3>
<p>
@ -1645,7 +1646,7 @@ There are ways to make this operator appear as part of the class using the <tt>%
Keep reading.
</p>
<H3><a name="Tcl_nn26"></a>32.3.12 C++ namespaces</H3>
<H3><a name="Tcl_nn26"></a>37.3.12 C++ namespaces</H3>
<p>
@ -1709,7 +1710,7 @@ utilizes thousands of small deeply nested namespaces each with
identical symbol names, well, then you get what you deserve.
</p>
<H3><a name="Tcl_nn27"></a>32.3.13 C++ templates</H3>
<H3><a name="Tcl_nn27"></a>37.3.13 C++ templates</H3>
<p>
@ -1761,7 +1762,7 @@ More details can be found in the <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</
examples will appear later.
</p>
<H3><a name="Tcl_nn28"></a>32.3.14 C++ Smart Pointers</H3>
<H3><a name="Tcl_nn28"></a>37.3.14 C++ Smart Pointers</H3>
<p>
@ -1845,7 +1846,7 @@ simply use the <tt>__deref__()</tt> method. For example:
</pre>
</div>
<H2><a name="Tcl_nn29"></a>32.4 Further details on the Tcl class interface</H2>
<H2><a name="Tcl_nn29"></a>37.4 Further details on the Tcl class interface</H2>
<p>
@ -1858,7 +1859,7 @@ of low-level details were omitted. This section provides a brief overview
of how the proxy classes work.
</p>
<H3><a name="Tcl_nn30"></a>32.4.1 Proxy classes</H3>
<H3><a name="Tcl_nn30"></a>37.4.1 Proxy classes</H3>
<p>
@ -1923,7 +1924,7 @@ function. This allows objects to be encapsulated objects that look a lot like
as shown in the last section.
</p>
<H3><a name="Tcl_nn31"></a>32.4.2 Memory management</H3>
<H3><a name="Tcl_nn31"></a>37.4.2 Memory management</H3>
<p>
@ -2111,7 +2112,7 @@ typemaps--an advanced topic discussed later.
</p>
<H2><a name="Tcl_nn32"></a>32.5 Input and output parameters</H2>
<H2><a name="Tcl_nn32"></a>37.5 Input and output parameters</H2>
<p>
@ -2299,7 +2300,7 @@ set c [lindex $dim 1]
</pre>
</div>
<H2><a name="Tcl_nn33"></a>32.6 Exception handling </H2>
<H2><a name="Tcl_nn33"></a>37.6 Exception handling </H2>
<p>
@ -2433,7 +2434,7 @@ Since SWIG's exception handling is user-definable, you are not limited to C++ ex
See the chapter on "<a href="Customization.html#Customization">Customization Features</a>" for more examples.
</p>
<H2><a name="Tcl_nn34"></a>32.7 Typemaps</H2>
<H2><a name="Tcl_nn34"></a>37.7 Typemaps</H2>
<p>
@ -2450,7 +2451,7 @@ Typemaps are only used if you want to change some aspect of the primitive
C-Tcl interface.
</p>
<H3><a name="Tcl_nn35"></a>32.7.1 What is a typemap?</H3>
<H3><a name="Tcl_nn35"></a>37.7.1 What is a typemap?</H3>
<p>
@ -2567,7 +2568,7 @@ parameter is omitted):
</pre>
</div>
<H3><a name="Tcl_nn36"></a>32.7.2 Tcl typemaps</H3>
<H3><a name="Tcl_nn36"></a>37.7.2 Tcl typemaps</H3>
<p>
@ -2705,7 +2706,7 @@ Initialize an argument to a value before any conversions occur.
Examples of these methods will appear shortly.
</p>
<H3><a name="Tcl_nn37"></a>32.7.3 Typemap variables</H3>
<H3><a name="Tcl_nn37"></a>37.7.3 Typemap variables</H3>
<p>
@ -2776,7 +2777,7 @@ properly assigned.
The Tcl name of the wrapper function being created.
</div>
<H3><a name="Tcl_nn38"></a>32.7.4 Converting a Tcl list to a char ** </H3>
<H3><a name="Tcl_nn38"></a>37.7.4 Converting a Tcl list to a char ** </H3>
<p>
@ -2822,7 +2823,7 @@ int print_args(char **argv) {
return i;
}
%}
%include tclsh.i
%include "tclsh.i"
</pre></div>
@ -2838,7 +2839,7 @@ argv[2] = Larry
3
</pre></div>
<H3><a name="Tcl_nn39"></a>32.7.5 Returning values in arguments</H3>
<H3><a name="Tcl_nn39"></a>37.7.5 Returning values in arguments</H3>
<p>
@ -2880,7 +2881,7 @@ result, a Tcl function using these typemaps will work like this :
%
</pre></div>
<H3><a name="Tcl_nn40"></a>32.7.6 Useful functions</H3>
<H3><a name="Tcl_nn40"></a>37.7.6 Useful functions</H3>
<p>
@ -2957,7 +2958,7 @@ int Tcl_IsShared(Tcl_Obj *obj);
</pre>
</div>
<H3><a name="Tcl_nn41"></a>32.7.7 Standard typemaps</H3>
<H3><a name="Tcl_nn41"></a>37.7.7 Standard typemaps</H3>
<p>
@ -3041,7 +3042,7 @@ work)
</pre>
</div>
<H3><a name="Tcl_nn42"></a>32.7.8 Pointer handling</H3>
<H3><a name="Tcl_nn42"></a>37.7.8 Pointer handling</H3>
<p>
@ -3117,7 +3118,7 @@ For example:
</pre>
</div>
<H2><a name="Tcl_nn43"></a>32.8 Turning a SWIG module into a Tcl Package.</H2>
<H2><a name="Tcl_nn43"></a>37.8 Turning a SWIG module into a Tcl Package.</H2>
<p>
@ -3189,7 +3190,7 @@ As a final note, most SWIG examples do not yet use the
to use the <tt>load</tt> command instead.
</p>
<H2><a name="Tcl_nn44"></a>32.9 Building new kinds of Tcl interfaces (in Tcl)</H2>
<H2><a name="Tcl_nn44"></a>37.9 Building new kinds of Tcl interfaces (in Tcl)</H2>
<p>
@ -3288,7 +3289,7 @@ danger of blowing something up (although it is easily accomplished
with an out of bounds array access).
</p>
<H3><a name="Tcl_nn45"></a>32.9.1 Proxy classes</H3>
<H3><a name="Tcl_nn45"></a>37.9.1 Proxy classes</H3>
<p>
@ -3409,5 +3410,27 @@ short, but clever Tcl script can be combined with SWIG to do many
interesting things.
</p>
<H2><a name="Tcl_nn46"></a>37.10 Tcl/Tk Stubs</H2>
<p>
For background information about the Tcl Stubs feature, see
<a href="http://www.tcl.tk/doc/howto/stubs.html">http://www.tcl.tk/doc/howto/stubs.html</a>.
</p>
<p>
As of SWIG 1.3.10, the generated C/C++ wrapper will use the Tcl Stubs
feature if compiled with <tt>-DUSE_TCL_STUBS</tt>.
</p>
<p>
As of SWIG 1.3.40, the generated C/C++ wrapper will use the Tk Stubs
feature if compiled with <tt>-DUSE_TK_STUBS</tt>. Also, you can override
the minimum version to support which is passed to <tt>Tcl_InitStubs()</tt>
and <tt>Tk_InitStubs()</tt> with <tt>-DSWIG_TCL_STUBS_VERSION="8.3"</tt>
or the version being compiled with using
<tt>-DSWIG_TCL_STUBS_VERSION=TCL_VERSION</tt>.
</p>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -270,21 +270,37 @@ traceprintf(arg1, NULL);
<p>
Arguably, this approach seems to defeat the whole point of variable length arguments. However,
this actually provides enough support for many simple kinds of varargs functions to still be useful. For
instance, you could make function calls like this (in Python):
this actually provides enough support for many simple kinds of varargs functions to still be useful, however it does come with a caveat.
For instance, you could make function calls like this (in Python):
</p>
<div class="targetlang">
<pre>
&gt;&gt;&gt; traceprintf("Hello World")
&gt;&gt;&gt; traceprintf("Hello %s. Your number is %d\n" % (name, num))
&gt;&gt;&gt; traceprintf("Your result is 90%%.")
</pre>
</div>
<p>
Notice how string formatting is being done in Python instead of C.
The caveat is the strings passed must be safe to use in C though.
For example if name was to contain a "%" it should be double escaped in order to avoid unpredictable
behaviour:
</p>
<div class="targetlang">
<pre>
&gt;&gt;&gt; traceprintf("Your result is 90%.\n") # unpredictable behaviour
&gt;&gt;&gt; traceprintf("Your result is 90%%.\n") # good
</pre>
</div>
<p>
Read on for further solutions.
</p>
<H2><a name="Varargs_nn5"></a>13.4 Argument replacement using %varargs</H2>
@ -315,33 +331,82 @@ int open(const char *path, int oflags, int mode = 0);
<p>
In this case, <tt>%varargs</tt> is simply providing more specific information about the
extra arguments that might be passed to a function.
If the parameters to a varargs function are of uniform type, <tt>%varargs</tt> can also
If the arguments to a varargs function are of uniform type, <tt>%varargs</tt> can also
accept a numerical argument count as follows:
</p>
<div class="code">
<pre>
%varargs(10,char *arg = NULL) execlp;
%varargs(3, char *str = NULL) execlp;
...
int execlp(const char *path, const char *arg1, ...);
int execlp(const char *path, const char *arg, ...);
</pre>
</div>
<p>
This would wrap <tt>execlp()</tt> as a function that accepted up to 10 optional arguments.
and is effectively seen as:
</p>
<div class="code">
<pre>
int execlp(const char *path, const char *arg,
char *str1 = NULL,
char *str2 = NULL,
char *str3 = NULL);
</pre>
</div>
<p>
This would wrap <tt>execlp()</tt> as a function that accepted up to 3 optional arguments.
Depending on the application, this may be more than enough for practical purposes.
</p>
<p>
Argument replacement is most appropriate in cases where the types of
the extra arguments is uniform and the maximum number of arguments is
known. When replicated argument replacement is used, at least one extra
argument is added to the end of the arguments when making the function call.
This argument serves as a sentinel to make sure the list is properly terminated.
It has the same value as that supplied to the <tt>%varargs</tt> directive.
The handling of <a href="SWIGPlus.html#SWIGPlus_default_args">default arguments</a> can be changed via the
<tt>compactdefaultargs</tt> feature. If this feature is used, for example
</p>
<div class="code">
<pre>
%feature("compactdefaultargs") execlp;
%varargs(3, char *str = NULL) execlp;
...
int execlp(const char *path, const char *arg, ...);
</pre>
</div>
<p>
a call from the target language which does not provide the maximum number of arguments, such as,
<tt>execlp("a", "b", "c")</tt>
will generate C code which includes the missing default values, that is, <tt>execlp("a", "b", "c", NULL, NULL)</tt>.
If <tt>compactdefaultargs</tt> is not used, then the generated code will be
<tt>execlp("a", "b", "c")</tt>. The former is useful for helping providing a sentinel to terminate the argument list.
However, this is not guaranteed, for example when a user passes a non-NULL value for all the parameters.
When using <tt>compactdefaultargs</tt> it is possible to guarantee the NULL sentinel is passed through the,
<tt>numinputs=0</tt> <a href="Typemaps.html#Typemaps_nn26">'in' typemap attribute</a>, naming the <b>last parameter</b>.
For example,
</p>
<div class="code">
<pre>
%feature("compactdefaultargs") execlp;
%varargs(3, char *str = NULL) execlp;
%typemap(in, numinputs=0) char *str3 ""
...
int execlp(const char *path, const char *arg, ...);
</pre>
</div>
<p>
Note that <tt>str3</tt> is the name of the last argument, as we have used <tt>%vargars</tt> with 3.
Now <tt>execlp("a", "b", "c", "d", "e")</tt> will result in an error as one too many arguments has been passed,
as now only 2 additional 'str' arguments can be passed with the 3rd one always using the specified default <tt>NULL</tt>.
</p>
<p>
Argument replacement is most appropriate in cases where the types of
the extra arguments are uniform and the maximum number of arguments are
known.
Argument replacement is not as useful when working with functions that accept
mixed argument types such as <tt>printf()</tt>. Providing general purpose
wrappers to such functions presents special problems (covered shortly).
@ -445,23 +510,36 @@ like this:
<div class="code">
<pre>
%typemap(in) (...)(char *args[10]) {
int i;
int argc;
for (i = 0; i &lt; 10; i++) args[i] = 0;
argc = PyTuple_Size(varargs);
if (argc &gt; 10) {
PyErr_SetString(PyExc_ValueError,"Too many arguments");
int i;
int argc;
for (i = 0; i &lt; 10; i++) args[i] = 0;
argc = PyTuple_Size(varargs);
if (argc &gt; 10) {
PyErr_SetString(PyExc_ValueError, "Too many arguments");
return NULL;
}
for (i = 0; i &lt; argc; i++) {
PyObject *pyobj = PyTuple_GetItem(varargs, i);
char *str = 0;
%#if PY_VERSION_HEX&gt;=0x03000000
PyObject *pystr;
if (!PyUnicode_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
return NULL;
}
for (i = 0; i &lt; argc; i++) {
PyObject *o = PyTuple_GetItem(varargs,i);
if (!PyString_Check(o)) {
PyErr_SetString(PyExc_ValueError,"Expected a string");
return NULL;
}
args[i] = PyString_AsString(o);
pystr = PyUnicode_AsUTF8String(pyobj);
str = PyBytes_AsString(pystr);
Py_XDECREF(pystr);
%#else
if (!PyString_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
return NULL;
}
$1 = (void *) args;
str = PyString_AsString(pyobj);
%#endif
args[i] = str;
}
$1 = (void *) args;
}
</pre>
</div>

View file

@ -25,7 +25,7 @@
<li><a href="#Warnings_nn12">C/C++ Parser (300-399)</a>
<li><a href="#Warnings_nn13">Types and typemaps (400-499) </a>
<li><a href="#Warnings_nn14">Code generation (500-599)</a>
<li><a href="#Warnings_nn15">Language module specific (800-899) </a>
<li><a href="#Warnings_nn15">Language module specific (700-899) </a>
<li><a href="#Warnings_nn16">User defined (900-999)</a>
</ul>
<li><a href="#Warnings_nn17">History</a>
@ -44,8 +44,8 @@ During compilation, SWIG may generate a variety of warning messages. For exampl
<div class="shell">
<pre>
example.i:16: Warning(501): Overloaded declaration ignored. bar(double)
example.i:15: Warning(501): Previous declaration is bar(int)
example.i:16: Warning 501: Overloaded declaration ignored. bar(double)
example.i:15: Warning 501: Previous declaration is bar(int)
</pre>
</div>
@ -102,7 +102,7 @@ int foo(double); // Silently ignored.
<p>
The <tt>%warnfilter</tt> directive has the same semantics as other declaration modifiers like
<tt>%rename</tt>, <tt>%ignore</tt> and <tt>%feature</tt>, see the
<a href="Customization.html#features">%feature directive</a> section. For example, if you wanted to
<a href="Customization.html#Customization_features">%feature directive</a> section. For example, if you wanted to
suppress a warning for a method in a class hierarchy, you could do this:
</p>
@ -257,16 +257,23 @@ Warning messages can be associated with typemaps using the
<div class="code">
<pre>
%typemap(in, warning="901:You are really going to regret this") blah * {
%typemap(in, warning="901:You are really going to regret this usage of $1_type $1_name") blah * {
...
}
</pre>
</div>
<p>
In this case, the warning message will be printed whenever the typemap is actually used.
In this case, the warning message will be printed whenever the typemap is actually used and the <a href="Typemaps.html#Typemaps_special_variables">special variables</a> will be expanded as appropriate, for example:
</p>
<div class="shell">
<pre>
example.i:23: Warning 901: You are really going to regret this usage of blah * self
example.i:24: Warning 901: You are really going to regret this usage of blah * stuff
</pre>
</div>
<H2><a name="Warnings_symbolic_symbols"></a>14.5 Symbolic symbols</H2>
@ -344,7 +351,7 @@ These can be overridden using command line options, for example:
$ swig -python -Fstandard example.i
example.i:4: Syntax error in input.
$ swig -python -Fmicrosoft example.i
example.i(4): Syntax error in input.
example.i(4) : Syntax error in input.
</pre></div>
<H2><a name="Warnings_nn9"></a>14.9 Warning number reference</H2>
@ -381,8 +388,12 @@ example.i(4): Syntax error in input.
<ul>
<li>201. Unable to find 'filename'.
<li>202. Could not evaluate 'expr'.
<li>201. Unable to find <em>filename</em>.
<li>202. Could not evaluate expression <em>expr</em>.
<li>203. Both includeall and importall are defined: using includeall.
<li>204. CPP #warning, "<em>warning</em>".
<li>205. CPP #error, "<em>error</em>".
<li>206. Unexpected tokens after #<em>directive</em> directive.
</ul>
<H3><a name="Warnings_nn12"></a>14.9.3 C/C++ Parser (300-399)</H3>
@ -399,18 +410,20 @@ example.i(4): Syntax error in input.
<li>308. Namespace alias '<em>name</em>' not allowed here. Assuming '<em>name</em>'
<li>309. [private | protected] inheritance ignored.
<li>310. Template '<em>name</em>' was already wrapped as '<em>name</em>' (ignored)
<li>311. Template partial specialization not supported.
<li>312. Nested classes not currently supported (ignored).
<li>312. Unnamed nested class not currently supported (ignored).
<li>313. Unrecognized extern type "<em>name</em>" (ignored).
<li>314. '<em>identifier</em>' is a <em>lang</em> keyword.
<li>315. Nothing known about '<em>identifier</em>'.
<li>316. Repeated %module directive.
<li>317. Specialization of non-template '<em>name</em>'.
<li>318. Instantiation of template <em>name</em> is ambiguous. Using <em>templ</em> at <em>file</em>:<em>line</em>
<li>318. Instantiation of template '<em>name</em>' is ambiguous, instantiation <em>templ</em> used, instantiation <em>templ</em> ignored.
<li>319. No access specifier given for base class <em>name</em> (ignored).
<li>320. Explicit template instantiation ignored.
<li>321. <em>identifier</em> conflicts with a built-in name.
<li>322. Redundant redeclaration of '<em>name</em>'.
<li>323. Recursive scope inheritance of '<em>name</em>'.
<li>324. Named nested template instantiations not supported. Processing as if no name was given to %template().
<li>325. Nested class not currently supported (<em>name</em> ignored).
<li>350. operator new ignored.
<li>351. operator delete ignored.
<li>352. operator+ ignored.
@ -482,8 +495,8 @@ example.i(4): Syntax error in input.
<li>469. No or improper directorin typemap defined for <em>type</em>
<li>470. Thread/reentrant unsafe wrapping, consider returning by value instead.
<li>471. Unable to use return type <em>type</em> in director method
<li>474. Method <em>method</em> usage of the optimal attribute in the out typemap at <em>file</em>:<em>line</em> ignored as the following cannot be used to generate optimal code: <em>code</em>
<li>475. Multiple calls to <em>method</em> might be generated due to optimal attribute usage in the out typemap at <em>file</em>:<em>line</em>.
<li>474. Method <em>method</em> usage of the optimal attribute ignored in the out typemap as the following cannot be used to generate optimal code: <em>code</em>
<li>475. Multiple calls to <em>method</em> might be generated due to optimal attribute usage in the out typemap.
</ul>
@ -492,28 +505,30 @@ example.i(4): Syntax error in input.
<ul>
<li>501. Overloaded declaration ignored. <em>decl</em>
<li>502. Overloaded constructor ignored. <em>decl</em>
<li>501. Overloaded declaration ignored. <em>decl</em>. Previous declaration is <em>decl</em>.
<li>502. Overloaded constructor ignored. <em>decl</em>. Previous declaration is <em>decl</em>.
<li>503. Can't wrap '<em>identifier</em>' unless renamed to a valid identifier.
<li>504. Function <em>name</em> must have a return type.
<li>504. Function <em>name</em> must have a return type. Ignored.
<li>505. Variable length arguments discarded.
<li>506. Can't wrap varargs with keyword arguments enabled.
<li>507. Adding native function <em>name</em> not supported (ignored).
<li>508. Declaration of '<em>name</em>' shadows declaration accessible via operator-&gt;() at <em>file:line</em>.
<li>509. Overloaded <em>declaration</em> is shadowed by <em>declaration</em> at <em>file</em>:<em>line</em>.
<li>508. Declaration of '<em>name</em>' shadows declaration accessible via operator-&gt;(), previous declaration of'<em>declaration</em>'.
<li>509. Overloaded method <em>declaration</em> effectively ignored, as it is shadowed by <em>declaration</em>.
<li>510. Friend function '<em>name</em>' ignored.
<li>511. Can't use keyword arguments with overloaded functions.
<li>512. Overloaded <em>declaration</em> const ignored. Non-const method at <em>file</em>:<em>line</em> used.
<li>512. Overloaded method <em>declaration</em> ignored, using non-const method <em>declaration</em> instead.
<li>513. Can't generate wrappers for unnamed struct/class.
<li>514.
<li>515.
<li>516. Overloaded method <em>declaration</em> ignored. Method <em>declaration</em> at <em>file</em>:<em>line</em> used.
<li>516. Overloaded method <em>declaration</em> ignored, using <em>declaration</em> instead.
<li>517.
<li>518. Portability warning: File <em>file1</em> will be overwritten by <em>file2</em> on case insensitive filesystems such as Windows' FAT32 and NTFS unless the class/module name is renamed.
<li>519. %template() contains no name. Template method ignored: <em>declaration</em>
<li>520. <em>Base/Derived</em> class '<em>classname1</em>' of '<em>classname2</em>' is not similarly marked as a smart pointer.
<li>521. Illegal destructor name <em>name</em>. Ignored.
</ul>
<H3><a name="Warnings_nn15"></a>14.9.6 Language module specific (800-899) </H3>
<H3><a name="Warnings_nn15"></a>14.9.6 Language module specific (700-899) </H3>
<ul>
@ -558,7 +573,7 @@ example.i(4): Syntax error in input.
</ul>
<ul>
<li>870. Warning for <em>classname</em>: Base <em>baseclass</em> ignored. Multiple inheritance is not supported in Php4. (Php).
<li>870. Warning for <em>classname</em>: Base <em>baseclass</em> ignored. Multiple inheritance is not supported in PHP.
<li>871. Unrecognized pragma <em>pragma</em>. (Php).
</ul>

View file

@ -67,7 +67,7 @@ SWIG does not come with the usual Windows type installation program, however it
<p>
The swigwin distribution contains the SWIG Windows executable, swig.exe, which will run on 32 bit versions of Windows, ie Windows 95/98/ME/NT/2000/XP.
The swigwin distribution contains the SWIG Windows executable, swig.exe, which will run on 32 bit versions of Windows, ie Windows 95 and later.
If you want to build your own swig.exe have a look at <a href="#Windows_swig_exe">Building swig.exe on Windows</a>.
</p>
@ -78,7 +78,7 @@ If you want to build your own swig.exe have a look at <a href="#Windows_swig_exe
<p>
Using Microsoft Visual C++ is the most common approach to compiling and linking SWIG's output.
The Examples directory has a few Visual C++ project files (.dsp files).
These were produced by Visual C++ 6, although they should also work in Visual C++ 5.
These were produced by Visual C++ 6.
Later versions of Visual Studio should also be able to open and convert these project files.
The C# examples come with .NET 2003 solution (.sln) and project files instead of Visual C++ 6 project files.
The project files have been set up to execute SWIG in a custom build rule for the SWIG interface (.i) file.
@ -248,7 +248,7 @@ Execute the steps in the order shown and don't use spaces in path names. In fact
<ol>
<li>
Download the following packages from the <a href="http://www.mingw.org/download.shtml">MinGW download page</a>
or <a href="http://sourceforge.net/project/showfiles.php?group_id=2435">MinGW SourceForge download page</a>.
or <a href="http://sourceforge.net/projects/mingw/files/">MinGW SourceForge download page</a>.
Note that at the time of writing, the majority of these are in the Current
release list and some are in the Snapshot or Previous release list.
<ul>
@ -272,7 +272,7 @@ Execute the steps in the order shown and don't use spaces in path names. In fact
<ul>
<li>Answer y to the "do you wish to continue with the post install?"</li>
<li>Answer y to the "do you have MinGW installed?"</li>
<li>Type in the the folder in which you installed MinGW (C:/MinGW is default)</li>
<li>Type in the folder in which you installed MinGW (C:/MinGW is default)</li>
</ul>
</li>
@ -281,7 +281,7 @@ Execute the steps in the order shown and don't use spaces in path names. In fact
</li>
<li>
Copy the followig to the MSYS install folder (C:\msys\1.0 is default):
Copy the following to the MSYS install folder (C:\msys\1.0 is default):
<ul>
<li>msys-automake-1.8.2.tar.bz2</li>
<li>msys-autoconf-2.59.tar.bz2</li>
@ -313,6 +313,18 @@ If you want to check out SWIG to a different folder to the proposed
the autotools will fail miserably on those.
</li>
<li>
The PCRE third party library needs to be built next.
Download the latest PCRE source tarball, such as <tt>pcre-8.10.tar.bz2</tt>, from
<a href=http://www.pcre.org>PCRE</a> and place in the <tt>/usr/src/swig</tt> directory.
Build PCRE as a static library using the Tools/pcre-build.sh script as follows:
<div class="shell"><pre>
cd /usr/src/swig
Tools/pcre-build.sh
</pre></div>
</li>
<li>
You are now ready to build SWIG. Execute the following commands to build swig.exe:
<div class="shell"><pre>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

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